dropper

Docs
Documentation

    Overview

    REST API

    CLI

    Coding agents

    MCP server

MCP server

Dropper ships a Model Context Protocol server, so Claude and any other MCP client can publish and manage drops as tools. One binary, two transports: add the hosted endpoint as a custom connector and sign in with your Dropper account, or spawn it locally over stdio with a personal API key.

Option A — add it as a custom connector (hosted)

The hosted server speaks Streamable HTTP at /mcp and authenticates with OAuth — nothing to copy, paste, or store. Dropper identifies the connector either from Anthropic's hosted client metadata document (the recommended default: the client id is an HTTPS URL Dropper fetches and validates) or from an automatic RFC 7591 registration — both work. You then sign in the same way you sign in to the dashboard, and you approve the connection once.

Server URL
https://dropp.sh/mcp
  1. In Claude, open Settings → Connectors → Add custom connector.
  2. Paste https://dropp.sh/mcp as the server URL and add it. Leave "Use Anthropic's hosted client metadata (Recommended)" selected — Dropper reads Anthropic's published client metadata document and identifies the connector from it. "No client ID — register one automatically" works too; that is the older RFC 7591 registration path, and Dropper still offers it.
  3. Click Connect. Dropper sends you to Authelia to sign in (locally, the dev login stands in), then shows a one-time consent screen naming the connector and the single "drops" scope it is asking for.
  4. Approve, and the eleven tools below show up in the client. Access is granted to your Dropper account, so every drop the connector makes lands in your own namespace.
  5. The dashboard’s API Keys page lists the connection afterwards under “Connected apps”. Disconnecting there ends the connector’s access — it must ask for your approval again — though an access token it already holds keeps working until it expires, within the hour. Your drops and API keys are untouched.

Access tokens are short-lived and audience-bound to this server's MCP resource; the client refreshes them silently. The REST drop routes accept them too, the account routes never do. Personal API keys are not accepted here — they stay the credential for the REST API, the local stdio server below, and the CLI in scripts and CI.

Remote callers have no filesystem, so content is sent inline: html for a single page, or files for a multi-file site (utf8 or base64 entries, zipped server-side). Images need no inline bytes at all: add_drop_asset hands the server a public https URL to download straight into an existing drop.

# Any MCP client that implements the OAuth flow points at the same URL — no header, no key.
claude mcp add --transport http dropper https://dropp.sh/mcp

# Then run /mcp in Claude Code and authenticate; the browser flow is the same
# sign-in + consent as the connector UI.
Option B — run locally (stdio)

The local server can read your filesystem, so tools accept a path input — drop an .html or .md file, or a whole directory, straight from disk. Configuration comes from the same env vars or ~/.config/dropper/config.json the CLI uses; the token slot holds a personal API key minted on the dashboard's API Keys page (sign in with Authelia to get there). It takes an API key only: a dropper login in that file does not sign the stdio server in, and never moves the "url" its key goes to.

git clone https://gitlab.tolbbox.com/tolbnet/dropper.git
cd dropper/mcp
npm ci && npm run build

# register with Claude Code (any MCP client works the same way)
# DROPPER_TOKEN holds your personal API key from the dashboard's API Keys page;
# the stdio server takes a key only, never a dropper login
claude mcp add dropper \
  -e DROPPER_URL=https://dropp.sh \
  -e DROPPER_TOKEN=your-api-key \
  -- node /path/to/dropper/mcp/dist/index.js
Using it

Once registered, the eleven tools below show up automatically — just ask for what you want:

> Publish this report as a page on my dropper and protect it with a generated password.

# Claude calls create_drop with html (or files) + generate_password,
# then replies with the public URL and the passphrase.

> Put the photo at https://example.com/canyon.jpg into my utah-trip drop and use it on the page.

# Claude calls add_drop_asset (the server downloads the file — no image bytes pass through
# the model), then read_drop_file + write_drop_file to reference images/canyon.jpg from index.html.

Generated passphrases are returned in the tool result, and list_drops and get_drop read them back on your own drops later. Blank passwords are rejected rather than silently clearing protection — clearing is an explicit flag.

create_drop
tool

Publish a static page or site and get its public URL.

Provide exactly one content source. Local paths work only when the server runs locally over stdio; remote (HTTP) callers use html, markdown or files.

NameTypeRequiredDescription
htmlstringoptional

Inline HTML for a single-page drop

markdownstringoptional

Inline Markdown for a single-page drop, rendered as a styled page at the drop URL; ?raw=1 serves the source

filesarrayoptional

Inline multi-file site: { path, content, encoding? } entries; must include an index.html, index.md or README.md at the root — the page the drop URL serves

pathstringoptional

Local .html or .md file, or a directory (zipped automatically) — stdio only

slugstringoptional

Custom slug; random 8 chars when omitted

namestringoptional

Display name — shown in the drops list and used as the title of a rendered Markdown page (a trailing .md is dropped). Defaults to the uploaded filename

passwordstringoptional

Protect the drop with this access code

generate_passwordbooleanoptional

Protect with a generated passphrase, returned in the result

publicbooleanoptional

List the drop in the cross-user gallery (default private). Discoverability only — never affects URL access or passwords

descriptionstringoptional

Short summary, at most 200 characters — shown under the name, and on the gallery when the drop is public

labelsarrayoptional

Label paths naming the project the drop belongs to, e.g. ["acme/website"]. Up to three lowercase names joined by "/" (project/area/topic); a sublabel implies its parents, a missing label is created on the spot, at most 20 per drop

list_drops
tool

List your drops, newest first, with public URLs plus protection and gallery flags.

Your own rows carry their label paths in labels, and any row its description when set.

NameTypeRequiredDescription
publicbooleanoptional

When true, list every user’s gallery-public drops instead of your own

labelstringoptional

A label path, e.g. "acme": only your drops carrying it or one of its sublabels. Not with public

list_labels
tool

List your labels in tree order, each with its path, colour and drop count (sublabels counted in).

Check it before labelling a drop and reuse the path a project already has. Labels come into being by labelling a drop; rename, move, recolour and delete them in the dashboard or with the CLI’s dropper labels.

No arguments.
get_drop
tool

Look up a single drop by slug — name, description, labels, kind, size, protection, public URL.

NameTypeRequiredDescription
slugstring
required

The drop slug

list_drop_files
tool

List the files inside a drop with sizes and content types.

Works on protected drops — owning them grants read-back without a viewer unlock.

NameTypeRequiredDescription
slugstring
required

The drop slug

read_drop_file
tool

Read one file from a drop — fetch current content before editing it with write_drop_file (one file) or update_drop (the whole drop).

Text files return utf8 content; binaries return base64. This returns the stored source: the styled page a browser sees for a .md file exists only at the drop’s /d/ URL. Files over 1 MiB are refused (fetch them via the API instead). Works on protected drops.

NameTypeRequiredDescription
slugstring
required

The drop slug

pathstringoptional

File path inside the drop; defaults to index.html — a Markdown drop keeps its page at index.md

write_drop_file
tool

Write one file into an existing drop from inline content — create it or replace it in place — leaving every other file untouched.

For small text and assets (HTML, CSS, JS, SVG, JSON, tiny icons): inline bytes travel through the model as tokens, so real images and photos belong to add_drop_asset. To edit text, read_drop_file first and write the whole file back. Nested paths create their directories; the drop’s name, description, labels, password and gallery visibility are unchanged, and a drop left holding more than one file becomes kind "zip". Base64 is checked (standard alphabet, padding) before a request is made; the API caps a file at 20 MB and the drop at 200 MB and 2000 files. A .md file written into a drop renders as a styled page at its own /d/ URL when a browser opens it — table of contents, highlighted code, Mermaid diagrams — while the same URL still returns the stored bytes to anything that does not ask for HTML, and to ?raw=1. To replace a whole drop at once, use update_drop with html or files instead.

NameTypeRequiredDescription
slugstring
required

Slug of the drop to edit

pathstring
required

Relative path inside the drop, e.g. "index.html" or "images/logo.svg"

contentstring
required

File content: text, or base64 with encoding "base64"

encodingstringoptional

How content is encoded: "utf8" (default) or "base64"

add_drop_asset
tool

Add an image or other binary to an existing drop by having the server download it from a public https URL — the token-free way to put real images in a drop.

The bytes go straight from the source into the drop and never pass through the model (no base64, no tokens). The URL must be a public https:// address that answers 200 with the file itself: redirects are not followed, so give the final asset URL rather than a page, a shortener or a signed-redirect link; 20 MB at most; private, loopback and internal hosts are refused. Creates or replaces exactly one file at path — the served content type comes from its extension — and the drop becomes kind "zip" once it holds more than one file. Reference it from the HTML by relative path, e.g. <img src="images/photo.jpg">; hotlinked images rot when their source changes, ingested copies do not. To replace the whole drop at once, use update_drop with files instead; this tool adds or replaces one file.

NameTypeRequiredDescription
slugstring
required

Slug of the drop to add the asset to

pathstring
required

Where to store it inside the drop, e.g. "images/photo.jpg" — the extension sets the served type

urlstring
required

Public https:// URL of the file, served directly (200, no redirect), up to 20 MB

delete_drop_file
tool

Delete one file from an existing drop, pruning any directories it leaves empty; the rest of the drop is untouched.

The drop’s entry page — index.html, index.md or README.md, whichever the drop root serves — cannot be deleted; replace it with write_drop_file instead (a nested index.html is fine). To remove the whole drop, use delete_drop.

NameTypeRequiredDescription
slugstring
required

Slug of the drop to edit

pathstring
required

Path of the file to delete, e.g. "images/old.jpg"; use list_drop_files for the available paths

update_drop
tool

Edit an existing drop: rename, change its description or labels, change protection, toggle gallery visibility, or replace content — combinable in one call.

Renaming changes the public URL; changing or clearing the password revokes every viewer unlock. Replacement content uses the same html / markdown / files / path rules as create_drop and replaces the whole drop — to touch one file, use write_drop_file, add_drop_asset or delete_drop_file.

NameTypeRequiredDescription
slugstring
required

Slug of the drop to edit

new_slugstringoptional

Rename the drop

passwordstringoptional

Set this access code

clear_passwordbooleanoptional

Remove protection

generate_passwordbooleanoptional

Set a generated passphrase, returned in the result

publicbooleanoptional

true lists the drop in the cross-user gallery, false delists it; omitted leaves visibility unchanged

namestringoptional

Set the display name — shown in the drops list and used as the title of a rendered Markdown page (a trailing .md is dropped) — on its own, or alongside replacement content, which never renames the drop by itself

descriptionstringoptional

New description, at most 200 characters; "" removes it, omitted keeps it

labelsarrayoptional

The drop’s whole new label set, as paths (same rules as create_drop); [] removes them all, omitted keeps them

html / markdown / files / pathcontentoptional

Replacement content — same rules as create_drop

delete_drop
tool

Delete a drop; its public URL stops working immediately and the slug frees up right away.

Recoverable: the drop goes to your trash and stays restorable for 30 days from the dashboard (Profile → Deleted drops) or POST /api/trash/<id>. Only the API’s permanent=1 deletes outright, and this tool never sends it.

NameTypeRequiredDescription
slugstring
required

The drop slug

Docsopenapi.jsoninstall.shskill.mdcli/manifest.json