MCP server

Publish, update, and delete HTML pages from any MCP-compatible client.

Share HTML exposes a Model Context Protocol server with five tools - publish_page, get_page, update_page, delete_page, and list_pages. Each tool maps one-to-one onto a REST API operation, so clients that don't speak MCP can reach the same surface over HTTP. Clients namespace tools by server, so the names carry no share_html_ prefix.

Two transports are supported:

streamable http

Direct HTTP#

For clients that speak the streamable-HTTP transport natively - Claude Code today. Endpoint: https://mcp.share-html.com/mcp.

stdio bridge

stdio clients#

For clients that only speak stdio - Cursor, Claude Desktop, Codex. Use the @share-html/mcp npm package.

Connect over streamable HTTP#

Claude Code supports the streamable-HTTP transport natively. Add the server with a single command:

claude mcp add --transport http share-html https://mcp.share-html.com/mcp

The endpoint accepts GET, POST, and DELETE requests and follows the streamable-HTTP transport defined by the MCP specification.

Connect through the stdio bridge#

The @share-html/mcp package wraps the hosted endpoint and exposes it over stdio. Install on demand with npx; no global install is required.

Claude Code#

claude mcp add share-html npx -- -y @share-html/mcp

Cursor#

Add the following to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "share-html": {
      "command": "npx",
      "args": ["-y", "@share-html/mcp"]
    }
  }
}

Claude Desktop, Codex, and other stdio clients#

Any client that launches an MCP server as a stdio subprocess works with the same invocation. The command is npx -y @share-html/mcp; the package takes no additional flags.

Configure the bridge#

The bridge requires SHARE_HTML_API_KEY. Without it the bridge prints a setup error and exits.

{
  "mcpServers": {
    "share-html": {
      "command": "npx",
      "args": ["-y", "@share-html/mcp"],
      "env": { "SHARE_HTML_API_KEY": "sh_live_…" }
    }
  }
}
Environment variableDefaultRequiredPurpose
SHARE_HTML_API_KEY-yesBearer token. Sent as Authorization: Bearer … on every request.
SHARE_HTML_URLhttps://mcp.share-html.comnoOverride the base URL. The bridge appends /mcp.

Authentication#

The hosted endpoint is not anonymous. There are two ways to authenticate:

OAuth 2.1 (browser-capable clients)#

Claude Code and any other MCP client that speaks the streamable-HTTP transport with OAuth handles the flow automatically. On first call, a browser tab opens for consent; on approval, the client stores an access token and refresh token. Subsequent calls send Authorization: Bearer <access_token> and the OAuth provider validates against OAUTH_KV.

To manage active grants, sign in at share-html.com/app/connections and revoke any client. The next call from that client will trigger a fresh OAuth flow.

Authorization: Bearer sh_live_… (stdio bridge)#

The stdio bridge (@share-html/mcp) wraps streamable HTTP for clients that only speak stdio (Cursor, Claude Desktop, Codex). It sends Authorization: Bearer ${SHARE_HTML_API_KEY} on every request. The MCP Worker's dual-accept shim recognizes sh_live_<48 hex> tokens, bcrypt-verifies against the api_keys table, and dispatches to the MCP agent with the user's identity.

Create an API key at share-html.com/app/keys.

No credentials are passed in tool arguments. The hosted endpoint rejects any request without a valid bearer token (401 invalid_token).

Publish HTML#

Publishes an HTML document and returns its public URL. Maps to POST /api/v1/pages.

toolpublish_page

Input#

FieldTypeRequiredDescription
htmlstringyesFull HTML document. Up to 5 MB.
slugstringnoCustom slug. 4 to 40 characters, lowercase alphanumeric plus -. Defaults to an 8-character slug from an alphabet that excludes ambiguous characters (no 0, 1, i, l, o).
ttlenumno"24h", "7d", "30d", or "never". Defaults to "never".
passwordstringnoPassword gate. 1 to 128 characters.

Output#

{
  "url": "https://pages.share-html.com/launch-notes",
  "slug": "launch-notes"
}

Update a page#

Updates one or more fields on a page you own - HTML, TTL, password, or visibility. Maps to PATCH /api/v1/pages/{slug}. At least one mutable field is required.

toolupdate_page

Input#

FieldTypeRequiredDescription
slugstringyesThe slug returned by publish_page.
htmlstringnoReplacement HTML document. Up to 5 MB.
ttlenumno"24h", "7d", "30d", or "never".
passwordstring | nullnoNew password (1 to 128 characters), or null to clear an existing password.
discoverablebooleannoWhether the page is included in search indexing hints.

Output#

{
  "url": "https://pages.share-html.com/launch-notes",
  "slug": "launch-notes"
}

Delete a page#

Permanently deletes a page you own. The URL returns 404 immediately after this call; there is no soft-delete or restore window. Maps to DELETE /api/v1/pages/{slug}.

tooldelete_page

Input#

FieldTypeRequiredDescription
slugstringyesThe slug to delete.

Output#

{ "ok": true }

Read page metadata#

Returns non-secret metadata for a published page. Maps to GET /api/v1/pages/{slug}. Read-only; no authentication required.

toolget_page

Input#

FieldTypeRequiredDescription
slugstringyesThe slug to inspect.

Output#

{
  "slug": "launch-notes",
  "url": "https://pages.share-html.com/launch-notes",
  "title": "Launch notes",
  "owner": "user",
  "size_bytes": 4217,
  "has_password": false,
  "discoverable": false,
  "view_count": 132,
  "expires_at": null,
  "created_at": "2026-05-12T09:31:00.000Z",
  "updated_at": "2026-05-19T14:02:00.000Z"
}

owner is "user" for pages associated with an account, "anonymous" otherwise. title is extracted from the HTML at publish time and may be null. expires_at is null when the page has no TTL.

List my pages#

Lists pages owned by the authenticated user. Maps to GET /api/v1/me/pages.

toollist_pages

Input#

FieldTypeRequiredDescription
limitintegernoPage size, 1 to 100. Defaults to 20.
offsetintegernoNumber of items to skip. Defaults to 0.

Output#

{
  "data": [
    {
      "slug": "launch-notes",
      "url": "https://pages.share-html.com/launch-notes",
      "title": "Launch notes",
      "owner": "user",
      "size_bytes": 4217,
      "has_password": false,
      "discoverable": false,
      "view_count": 132,
      "expires_at": null,
      "created_at": "2026-05-12T09:31:00.000Z",
      "updated_at": "2026-05-19T14:02:00.000Z"
    }
  ],
  "pagination": {
    "limit": 20,
    "offset": 0,
    "total": 47,
    "has_more": true,
    "next_offset": 20
  }
}

Each item is the canonical page shape, identical to get_page. next_offset is present only when has_more is true. Requires either an OAuth access token or sh_live_… API key - there is no anonymous variant.

Discovery#