> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useshareable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP server

> Connect Shareable's MCP server to Claude Code, Cursor, or any code client.

Shareable ships an [MCP](https://modelcontextprotocol.io) server so your agent can publish
and manage pages directly from your terminal or code editor.

<Note>
  Just want your **Claude, ChatGPT, or Gemini app** to publish for you — no terminal? See
  [Publish from Claude, ChatGPT & Gemini](/guides/publish-from-ai). This page is the
  developer setup (Claude Code, Cursor, scripts) plus the full tool reference.
</Note>

## Get your API key

In Shareable, open [**Settings → Developers**](https://useshareable.com/settings/developers)
and create a key — it starts with `sm_`. Use it as a bearer token (hosted server) or the
`SHAREABLE_API_KEY` env var (local server). The hosted server lives at one URL:

```
https://useshareable.com/api/mcp
```

## Hosted server (URL)

Nothing to install — add it as a remote (HTTP) server with the URL and your
[API key](/authentication) as a bearer token:

<Tabs>
  <Tab title="Claude Code">
    ```bash theme={null}
    claude mcp add --transport http shareable https://useshareable.com/api/mcp \
      --header "Authorization: Bearer sm_your_key"
    ```
  </Tab>

  <Tab title="Cursor / VS Code / Windsurf">
    Add a remote (HTTP) MCP server with the URL and an `Authorization` header, e.g. in `~/.cursor/mcp.json`:

    ```json theme={null}
    {
      "mcpServers": {
        "shareable": {
          "url": "https://useshareable.com/api/mcp",
          "headers": { "Authorization": "Bearer sm_your_key" }
        }
      }
    }
    ```
  </Tab>
</Tabs>

## Local server (npx)

Works in Claude Desktop, Claude Code, and Cursor. Add to your client's MCP config:

```json ~/.claude/mcp.json theme={null}
{
  "mcpServers": {
    "shareable": {
      "command": "npx",
      "args": ["-y", "@shareable/mcp"],
      "env": {
        "SHAREABLE_API_KEY": "sm_your_key",
        "SHAREABLE_API_URL": "https://useshareable.com"
      }
    }
  }
}
```

<Note>
  `SHAREABLE_API_URL` is optional and defaults to the hosted Shareable. Restart your MCP client after editing the config so it loads the server.
</Note>

## Tools

<ResponseField name="publish_page" type="html | html_base64 | html_url, sha256?, title?, access?, allowed_emails?, password?">
  Publish a self-contained HTML page and get a shareable URL. Goes live immediately. With `access: "password"`, pass a `password` (or one is generated and returned).

  Provide the HTML one of three ways: inline **`html`**, **`html_base64`** (base64 — ASCII, so it can't be mangled by the token stream; use it to avoid emoji/Unicode corruption), or **`html_url`** (a public https URL the server fetches the bytes from, SSRF-guarded — best for large HTML, so it never passes through the token stream). Optionally pass **`sha256`** (hex of the HTML bytes) for a byte-perfect integrity check.
</ResponseField>

<ResponseField name="publish_deck" type="files, assets?, entry?, title?, access?, allowed_emails?, password?">
  Publish a **multi-page deck** — several HTML files that link to each other (investor deck, docs site, sectioned report, clickable prototype) — under one shareable URL. `files` is an array of `{ path, html }`; link between pages with relative (`team.html`) or root-relative (`/team.html`) paths. Images, CSS, JS, and fonts the pages reference go in `assets` — `{ path, file_path }` to read a local file, or `{ path, data_base64 }` — no need to inline them. `entry` picks the landing page (defaults to `index.html`).
</ResponseField>

<ResponseField name="publish_file" type="file_base64 | file_url | path?, filename?, mime?, title?, access?, allowed_emails?, password?">
  Publish a **PDF or image** (PNG/JPG/WebP/GIF), shown inline — same access control + analytics as any page. The **hosted** server takes `file_base64` (≤ \~3 MB) or a public **`file_url`** (≤ 5 MB; internal/private hosts are blocked); the **local npx** server also takes a local `path` it reads from disk. SVG, Office docs, and spreadsheets aren't supported — export to PDF first.
</ResponseField>

<ResponseField name="get_page_html" type="id">
  Read back a page's **current full HTML** so you can make a small, surgical edit instead of rebuilding it from scratch — `html` for a single page, or every file's HTML for a deck. Returns the editable working copy (matches what's live unless there are unpublished changes). Typical flow: `get_page_html` → edit → `update_page` (or `update_deck`) → `publish_changes`.
</ResponseField>

<ResponseField name="update_page" type="id, html? | html_base64? | html_url?, sha256?, title?, access?, allowed_emails?, password?">
  Replace a single page's HTML as a **draft**. Call `publish_changes` to push it live. New HTML can be inline `html`, `html_base64`, or `html_url` (same byte-faithful / token-light options as `publish_page`), with an optional `sha256` integrity check. Read the current HTML first with `get_page_html` to patch it in place.
</ResponseField>

<ResponseField name="update_deck" type="id, files, entry?">
  Replace a **deck's** files as a draft. Pass the full set of `{ path, html }` — files not included are removed. Call `publish_changes` to push it live.
</ResponseField>

<ResponseField name="publish_changes" type="id">
  Publish a page or deck's current draft, updating the live URL.
</ResponseField>

<ResponseField name="unpublish_page" type="id">
  Take a page offline — its shared link stops working until you publish again.
</ResponseField>

<ResponseField name="list_pages" type="limit?, offset?">
  List the pages in your account (drafts and published), most recently edited first. `limit` (default 100, max 200)
  and `offset` page through a large account so an entire account isn't dumped into the model context.
</ResponseField>

<ResponseField name="list_versions" type="id">
  List a page or deck's saved versions (one is saved on each publish and each edit), newest first.
</ResponseField>

<ResponseField name="get_version" type="id, version, full?">
  Read a specific version's metadata and content (`html` for a page, `files[]` for a deck). Large content is truncated to a preview by default — pass `full: true` to return the entire untruncated content (e.g. to patch or diff an old version). To read the **current** page's HTML, use `get_page_html`.
</ResponseField>

<ResponseField name="restore_version" type="id, version, publish?">
  Restore a previous version into the draft. Pass `publish: true` to also push it live.
</ResponseField>

<ResponseField name="delete_page" type="id">
  Permanently delete a page.
</ResponseField>

## Example

Once connected, just ask in natural language:

```text theme={null}
"Publish my Q3 revenue dashboard and invite dana@acme.com and mira@acme.com."
```

Your agent calls `publish_page` with `access: "people"` and the two emails, then hands back the live link.
