deed.page

Publish static sites to permanent URLs in one call: no account, email code, or claim link. Seven MCP tools for publish, update, and manage.

Hosted MCP Server

npx add-mcp 'https://deed.page/mcp'

Installs into Claude Code, Codex, Cursor and more

Documentation

deed.page docs

Publish a deed: one request turns files into a permanent public URL. Built for agents; no human step anywhere.

Publish a folder or a few files to a live, permanent HTTPS URL with one PUT or POST. No account, no email code, no claim link, no 24-hour expiry. The agent chooses the slug. Use when asked to "publish this", "host this", "deploy this", "share this on the web", "make a website", "put this online", "create a webpage", or "generate a URL", or when a 24-hour anonymous link is not enough.

base_url: https://deed.page openapi: https://deed.page/openapi.json mcp: https://deed.page/mcp skill: https://deed.page/skill.md

Quick start

echo '<!doctype html><h1>Hello</h1>' > index.html
curl -T index.html "https://deed.page/v1/sites?slug=hello"

Response (201 on create, 200 on update):

{"ok":true,"url":"https://hello.deed.page/","path_url":"https://deed.page/s/hello/","slug":"hello","version":"v1","unchanged":false,"permanent":true,"expires_at":null,"bytes":31,"files":1,"plan":"free","token":"deed_tok_...","token_note":"Shown once..."}

url is the subdomain form when you publish through deed.page; path_url (/s/{slug}/) always works.

Authentication

  • None to publish. No account, email code, or claim link.
  • The first publish without a token mints one and returns it once as token. Save it (for example export DEEDPAGE_TOKEN=deed_tok_...).
  • Send Authorization: Bearer $DEEDPAGE_TOKEN to update, list, delete, or upgrade. Publishing new slugs with the same token keeps them under one owner.
  • Lose the token and you cannot update that slug. There is no recovery by email because we never collect one.

Publishing

PUT and POST are the same operation on /v1/sites and /v1/sites/{slug} (also under /api/v1/).

Bodies:

  • gzip tarball or plain tar (curl -T site.tar.gz). One wrapper directory is stripped.
  • a single HTML file (curl -T index.html) becomes index.html.
  • multipart/form-data: one archive, or many files (field filename = path).
  • application/json: {"files":{"index.html":"<h1>hi</h1>","logo.png":{"base64":"iVBOR..."}}}

Headers (or query params):

HeaderQueryMeaning
X-SlugslugSlug to publish to (1-63 chars, a-z 0-9 -). Random if omitted.
AuthorizationBearer token for updates.
X-Mergemerge1 = add these files to the current version instead of replacing it.
X-Spaspa1 = serve index.html for unknown paths.
X-TtlttlSeconds until the site expires. Omit for permanent.
Idempotency-KeyReplays the same response for retries.
X-ClientYour harness name (cursor, claude-code, codex...).

Directory tarball:

tar -C ./site -czf /tmp/site.tar.gz .
curl -T /tmp/site.tar.gz "https://deed.page/v1/sites?slug=my-app" -H "Authorization: Bearer $DEEDPAGE_TOKEN"

JSON:

curl -X POST "https://deed.page/v1/sites" -H 'content-type: application/json' \
  -d '{"slug":"my-app","files":{"index.html":"<!doctype html><h1>hi</h1>"}}'

Large sites

Each request body is capped at 4 MB (a serverless platform limit). Send the first chunk normally, then the rest with X-Merge: 1 and your token; each merge publish adds or overwrites paths and bumps the version. Total size per site is set by your plan.

Serving

  • https://{slug}.deed.page/ and https://deed.page/s/{slug}/
  • / serves index.html; /about tries about, about.html, about/index.html.
  • 404.html at the root is used for misses. SPA mode serves index.html instead.
  • A folder without index.html shows a file listing.

Endpoints

MethodPathAuthWhat
PUT/POST/v1/sitesoptionalPublish (slug via header/query/body)
PUT/POST/v1/sites/{slug}optionalPublish to slug
GET/v1/sitesBearerList your sites
GET/v1/sites/{slug}nonePublic site metadata
DELETE/v1/sites/{slug}BearerDelete your site
GET/v1/whoamioptionalPlan and limits
POST/api/v1/billing/checkoutBearerStripe Checkout URL for hobby or pro
POST/api/v1/billing/portalBearerStripe billing portal URL
GET/api/v1/healthnoneHealth check
POST/mcpoptionalMCP (JSON-RPC over Streamable HTTP)

MCP

Endpoint: https://deed.page/mcp (Streamable HTTP, JSON responses, no SSE). Tools: publish_site, update_site, get_site, list_sites, delete_site, whoami, get_upgrade_link. Pass your token as an Authorization: Bearer header or as the token argument.

Claude Code:

claude mcp add --transport http deed-page https://deed.page/mcp

Cursor / generic JSON config:

{"mcpServers":{"deed-page":{"url":"https://deed.page/mcp"}}}

Errors

Every error is JSON: {"code","message","retry_after","docs_url","suggestion?"}.

CodeStatusMeaning
slug_taken409Someone else owns it; suggestion has a free slug.
slug_invalid / slug_reserved400Pick another slug.
unauthorized401Missing or unknown token.
forbidden403Token does not own that slug.
quota_sites403Plan site limit reached.
quota_bytes413Site bigger than your plan allows.
request_too_large413Body over 4 MB; use X-Merge.
rate_limited429See retry_after seconds.
invalid_archive / empty_site / bad_request400Fix the body.

Limits and plans

PlanPriceSitesPer sitePublishes/hour
Free$02525 MB60
Hobby$3/mo250100 MB300
Pro$15/mo2,500500 MB1,200

Every plan: permanent sites, no email, no claim link, MCP, subdomain and path URLs. Paid plans are billed monthly by Stripe; cancel any time in the billing portal.

Content rules

Public static files only. No malware, phishing, credential harvesting, or illegal content. We remove slugs that break these rules. Report abuse to ops@avatar33.com.

Install the skill

mkdir -p ~/.claude/skills/deed-page && curl -fsSL https://deed.page/skill.md -o ~/.claude/skills/deed-page/SKILL.md

Operator

deed.page is operated by Avatar 8 LLC. Contact: ops@avatar33.com.