MCP Setup

Connect AI agents to sharedrop using the Model Context Protocol.

What is MCP?

The Model Context Protocol (MCP) is an open standard for connecting AI agents to external tools and data sources. sharedrop implements an MCP server that lets agents upload HTML, list pages, and share them -- all through the standard MCP tool interface.

The simplest way to connect is using sharedrop's hosted remote MCP endpoint. No installation needed.

Configuration

Most MCP clients (Claude Desktop, Claude Code, Cursor, Windsurf) sign in through the browser -- add the server with just the URL, and approve the sign-in on first connect. No API key to create or paste:

{
  "mcpServers": {
    "sharedrop": {
      "url": "https://sharedrop.cloud/api/mcp"
    }
  }
}

Client without OAuth, or running headless (CI, a remote box)? Add a Bearer API key in a headers block instead:

{
  "mcpServers": {
    "sharedrop": {
      "url": "https://sharedrop.cloud/api/mcp",
      "headers": {
        "Authorization": "Bearer sd_your_api_key_here"
      }
    }
  }
}

Replace sd_your_api_key_here with your actual API key. See Authentication for how to create one.

Benefits

  • No installation or setup
  • Always up to date
  • Works with any MCP client that supports remote servers
  • Same rate limits as the REST API

Remote-only

The sharedrop MCP server is hosted -- there is no local/stdio package to install or keep alive. If your client doesn't support remote MCP servers, use the REST API or the CLI instead.

Pair the connection with the agent skill so your agent also knows when to reach for sharedrop and which defaults to use.

Available Tools

The MCP server exposes the following tools. Every file, including HTML, uses the same streamed upload pipeline. Supply page_id when replacing an existing page.

Uploading a large or opaque file (a database dump, a build tarball, anything over 30 MB)? On Pro and Team accounts the server also exposes create_archive_upload, sign_archive_parts, complete_archive, and abort_archive for streaming download-only archives up to 10 GB. See the Archives guide for the agent flow.

create_upload

Phase 15 direct-streamed upload, step 1 of 2. Reserves an object_key, runs the tier + storage gate, and mints a 5-minute HS256 upload token. The agent then streams the body out-of-band with curl -T, and calls finalize_upload to sanitise and publish.

Use create_upload + finalize_upload for files of any kind (HTML, image, PDF, Markdown, MHTML, JSON, JSONL) -- there is no 4.5 MB Vercel function-body cap on this path because the body never flows through the Vercel function. This is the only upload path: raw bytes are never base64-encoded into the MCP envelope.

Parameters:

NameTypeRequiredDescription
filenamestringYesFilename including extension (e.g. report.pdf)
content_typestringYesMIME type (e.g. application/pdf)
size_bytesnumberYesExact body size in bytes -- must match the Content-Length of the subsequent PUT
workspacestringNoWorkspace ID. Ignored on workspace-scoped API keys
reservation_idstringNoClaim a reserved address (from create_reservation). The finished upload becomes a NEW page at the reserved URL. Mutually exclusive with page_id. See Reserved addresses

Returns: upload_url (the https://uploads.sharedrop.cloud/<object_key> endpoint the agent PUTs to), upload_token (the 5-min HS256 JWT to put in the Authorization: Bearer ... header), finalize_url, object_key.

Recommended out-of-band PUT:

curl -X PUT "$UPLOAD_URL" \
  -H "Authorization: Bearer $UPLOAD_TOKEN" \
  -H "Content-Type: application/pdf" \
  -H "Content-Length: $(stat -f%z report.pdf)" \
  --data-binary @report.pdf

The upload token expires 5 minutes after issuance. If the PUT fails after expiry, call create_upload again to mint a fresh token (the previous object_key is abandoned and gets garbage-collected by the bucket's 24-hour lifecycle rule).

finalize_upload

Phase 15 direct-streamed upload, step 2 of 2. Validates the upload token, re-reads the quarantine object, runs the kind-dispatched sanitiser (DOMPurify for HTML, sharp for images, pdf-lib for PDFs), promotes the sanitised bytes to the public bucket, and creates the page row.

Parameters:

NameTypeRequiredDescription
object_keystringYesThe object_key returned by create_upload
upload_tokenstringYesThe upload_token returned by create_upload
titlestringNoPage title. Defaults to the document title (HTML/PDF) or filename stem
visibilitystringNoprivate (default), shared, or public
modestringNoHTML only: static or interactive (default: your account's default upload mode, initially interactive; configure in Settings; overrides the account default when set). Ignored for non-HTML kinds
workspace_idstringNoWorkspace ID. Ignored on workspace-scoped API keys
page_idstringNoExisting page ID for re-upload (URL stays stable, version recorded)
folder_idstringNoTarget folder ID for placement. New uploads only (Pro and above); ignored on re-upload
folder_pathstringNoTarget folder by path (e.g. reports/2026), auto-creating any missing segments. New uploads only (Pro and above). folder_id wins if both are set
slidesbooleanNoHTML only: publish as a slide deck with fullscreen Present mode. Equivalent to a <meta name="sharedrop:kind" content="slides"> marker in the file. Ignored for non-HTML kinds

Returns: Page URL, page ID, slug, mode, visibility, kind, contentType.

Example agent flow (PDF, no base64 in the LLM token stream):

1. AGENT: create_upload({ filename: "report.pdf", content_type: "application/pdf", size_bytes: 482190 })
   → { upload_url, upload_token, finalize_url, object_key }

2. AGENT shell: curl -T report.pdf -H "Authorization: Bearer $TOKEN" "$UPLOAD_URL"
   → 201 { ok: true, object_key, bytes: 482190 }

3. AGENT: finalize_upload({ object_key, upload_token, visibility: "public" })
   → { url: "https://sharedrop.cloud/agent/x8vh3p", page_id, ... }

4. AGENT to user: Here is your report: https://sharedrop.cloud/agent/x8vh3p

Notice that no base64 of the PDF was ever placed in the LLM context -- the body flows out-of-band, only the URL + small JSON envelopes flow through the model.

Supported file types

create_upload + finalize_upload accept every supported kind, HTML included. The file extension is authoritative; the content_type parameter is treated as a hint.

KindExtensionsMIME type(s)
HTML.html, .htmtext/html
MHTML web archives.mhtml, .mhtmultipart/related, application/x-mimearchive
Markdown.md, .markdowntext/markdown
PDF.pdfapplication/pdf
JSON.jsonapplication/json
JSONL.jsonlapplication/jsonl
Image (broad support).png, .jpg, .jpeg, .webp, .gif, .avif, .bmp, .ico, .apng, .svgimage/png, image/jpeg, image/webp, image/gif, image/avif, image/bmp, image/x-icon, image/apng, image/svg+xml
Image (limited browser support).heic, .heif, .tif, .tiffimage/heic, image/heif, image/tiff

HTML has one variant: pass slides: true (or include the in-file marker) and the page publishes as a slide deck with fullscreen Present mode instead of an ordinary page.

Slide decks and Present mode

When you generate a presentation rather than a document, publish it as a deck so the user can put it straight on a TV or a projector. Structure the HTML as top-level <section> elements, one per slide, then either add <meta name="sharedrop:kind" content="slides"> to the file or pass slides: true to finalize_upload. The response comes back with "kind": "slides".

The user presents it by clicking Present in the dashboard, or by opening the page URL with ?present=1. On Pro you can also hand them a link that lands straight in Present mode:

// create_ephemeral_link
{ "page_id": "...", "expires_in_seconds": 14400, "present_only": true }

Give the user the returned url verbatim, since that is the copy carrying &present=1. present_only works on decks only and requires Pro. Full details, including the keyboard controls and kiosk autoplay, are in the slide decks guide.

Upload and re-upload

There are two business operations, and both run the identical create_upload then PUT then finalize_upload sequence:

  • Upload creates a new page. Omit page_id.
  • Re-upload replaces an existing page. Pass the same page_id to create_upload (it is bound into the signed token) and to finalize_upload. The URL, slug, version history, shares, and folder placement are all preserved, and a new version is recorded.

list_pages

List your uploaded pages.

Parameters:

NameTypeRequiredDescription
limitnumberNoResults per page (default: 50)
cursorstringNoPagination cursor

Returns: Array of page metadata with pagination.

fetch_page

Pull a page's raw content into the agent's context -- its own page, a public one, or one shared to it. Returns a short-lived signed fetch_url plus metadata; the agent then HTTP GETs fetch_url (no auth header -- the token is in the URL) to read the raw bytes. This is the content path; get_page stays metadata-only. Not a zip, not the sandboxed viewer wrapper. Available on every tier (entitlements.fetch in whoami).

Parameters:

NameTypeRequiredDescription
page_idstringYesPage ID to fetch

Returns: fetch_url, expires_at, content_type, mode, and size. GET fetch_url within ~5 minutes to stream the raw bytes.

share_page

Share a page with someone by email.

Parameters:

NameTypeRequiredDescription
page_idstringYesPage ID to share
emailstringYesEmail address to share with

Returns: Access grant details.

Reserved addresses

Reserve a stable sharedrop.cloud address before any content exists, so you can hand out the final URL up front and fill it in later. See the Reserved addresses guide for the full flow and the placeholder/expiry behavior.

create_reservation

Reserve an address and get back the final URL plus a one-time claim token. The claim_token (an sdr_ credential) is shown exactly once and can never be retrieved again, so store it now and hand it to the agent over a secure channel.

Parameters: all optional.

NameTypeRequiredDescription
titlestringNoPage title shown once the address is claimed (default Untitled)
descriptionstringNoOptional description for your own reference
intended_agent_namestringNoName of the agent this address is held for (shown in the dashboard)
visibilitystringNoprivate (default), shared, or public. The claimed page inherits it
modestringNoHTML render mode the claimed page takes: static or interactive
expires_atstringNoISO 8601 datetime after which an unclaimed reservation expires. Omit to keep it until claimed or revoked
folder_idstringNoPro folder to file the claimed page into

Returns: the serialized reservation (with the final url) plus the one-time claim_token. Over your plan's cap (Free 2, Pro 25, Team unlimited) the call returns a billing error you can relay to the user.

Claim the address: call create_upload with reservation_id set to the reservation's id (instead of page_id), then PUT the bytes and call finalize_upload. The first upload becomes a live page at the reserved URL, inheriting the visibility, mode, and folder chosen at reserve time. Subsequent updates use page_id as normal.

list_reservations

List your reserved addresses. Each entry shows its status (reserved, claimed, expired, or revoked), the final URL, and the metadata chosen at reserve time. Claim tokens are one-time and shown only by create_reservation, so they never appear here.

Parameters:

NameTypeRequiredDescription
limitnumberNoResults per page (default: 50)
cursorstringNoPagination cursor

revoke_reservation

Revoke a reservation. The row is kept (status flips to revoked) and the sdr_ claim token is permanently invalidated.

Parameters:

NameTypeRequiredDescription
reservation_idstringYesID of the reservation to revoke (from create_reservation or list_reservations)

Example Workflow

Here is what a typical AI agent interaction looks like with sharedrop MCP:

  1. Agent generates HTML -- Creates a report, dashboard, or visualization
  2. Agent streams the upload -- Calls create_upload, PUTs the raw HTML to the signed URL, then calls finalize_upload with a title
  3. Agent receives URL -- Gets back a shareable sharedrop.cloud link
  4. Agent shares the link -- Sends the URL to the user in chat, or calls share_page to grant email access
User: "Generate a sales dashboard for Q1 2026"

Agent: I'll create that dashboard and share it with you.

[Agent generates HTML dashboard]
[Agent calls create_upload, PUTs the HTML, then finalize_upload]
[Agent receives https://sharedrop.cloud/agent/abc123]

Agent: Here's your Q1 2026 sales dashboard:
https://sharedrop.cloud/agent/abc123

Troubleshooting

"UNAUTHORIZED" Error

Your API key is missing or invalid. Verify:

  • The key starts with sd_ or sdw_
  • The key hasn't been revoked
  • The Authorization header format is Bearer <key>

"RATE_LIMIT_EXCEEDED" Error

You've hit the rate limit for your plan tier. Wait for the rate limit window to reset (60 seconds) or upgrade your plan for higher limits.

Connection Timeout

Ensure your network can reach https://sharedrop.cloud.