Every change Wellknown observed on this agent, newest first, with what it was before and what it became. Tool-surface changes carry the definition diff. Nothing here is edited after the fact.
Changed the definition of "publish_site"
⟨103 unchanged words⟩ credential-harvesting pages return content_rejected and are not stored. .bin is blocked by file type (it often has no MZ or ELF header). A raw octet-stream body is screened as one file.
Added "add_domain", "create_webhook", "delete_webhook" and 13 more; changed the definition of "delete_site", "publish_site", "update_site" and 1 more (7 tools before, 23 now)
⟨10 unchanged words⟩ a site down. Permanently removes the slug youown;owntheand detaches its custom hostnames. The slug becomes free.
⟨25 unchanged words⟩ slug. Paths are stored exactly. Returns {url, path_url, slug, version, token?}. On deed.page, url and path_url are both https://{slug}.deed.page/. The token appears only on the first anonymous publish; store it.ThereAislost token has no recoveryifunless
Changed the definition of "publish_site" and "update_site"
⟨18 unchanged words⟩ a live permanent URL at the chosen slug. Paths are stored exactly. Returns {url, slug, version, token?}. The token appears only on the first anonymous publish; storeitit.toThereupdateislater.no recovery if you lose it.
⟨16 unchanged words⟩ :"Map of relative path to file contents. Paths are stored exactly as given (a single top-level directory is not removed). Text as a string, binary as {\"
Certificate recorded, valid to 2026-12-28
Authorization not required
Unknown → Live
First tool surface recorded: 7 tools (server version 1.0.0)
https://deed.page/mcp (mcp_streamable_http) — from mcp_registry, with the record
Showing the latest 8 events. The API returns up to 500 and filters by kind: ?kind=tool_surface_changed
{"properties":{"expected_version":{"description":"Live version this write is based on, such as \"v3\", from the last publish or get_site. If the slug is no longer at that version, the call returns version_conflict and does not write. Racing publishes fail the same way even when this is omitted.","type":"string"},"files":{"additionalProperties":{"anyOf":[{" ⟨209 unchanged words⟩
⟨16 unchanged words⟩ own. Requires the token from the first publish.There is no restore-version call; send the previous filesToagainundo,tocallundo.restore_version. Returns the same shape as publish_site with a bumped version. Pass expected_version (the live vN) so a stale write returns version_conflict instead of overwriting. Two racing updates return version_conflict even without it; re-read and retry the one that lost.
{"properties":{"expected_version":{"description":"Live version this update is based on, such as \"v3\". If the site has moved on, the call returns version_conflict with no write. Omit it and a concurrent update still returns version_conflict rather than dropping files.","type":"string"},"files":{"additionalProperties":{"anyOf":[{" ⟨135 unchanged words⟩
Use this to read your plan, limits,andhow many sites your tokenowns.owns, and how many custom hostnames it has attached.
Attach a custom domain — Use this when the user wants their own hostname on a site they own. Adds the hostname to the project and returns dns_records to create: a CNAME for a subdomain, an A record or an ALIAS record for an apex (create one, not both), and every TXT record. Status starts at pending_dns until DNS and the certificate are ready. Free allows 1 hostname, Hobby 3, Pro 20. deed.page names are rejected. Call domain_status until status is active.
Register a webhook — Registers an http(s) URL for site.published, site.version_restored, site.deleted, site.taken_down, domain.active, and report.received. The HMAC secret is returned once. Free 1, Hobby 5, Pro 20. Private, internal, and localhost targets are rejected. Delivery is best-effort: 3 attempts, then stop.
Delete a webhook — Deletes one webhook by id from list_webhooks or create_webhook.
Check custom domain status — Use this after add_domain, once DNS might have propagated. Refreshes verification, DNS config, and certificate state. status is pending_dns, verifying, issuing_cert, active, or error. dns_records are the records to create. An error includes the reason.
Finalize a large upload — Use this after plan_upload, once every missing blob has been uploaded. Checks hashes, screens the new bytes, and commits one version under the slug lock. A stale expected version returns version_conflict and writes nothing. A bad hash returns hash_mismatch. An expired session returns session_expired.
Get a signed version manifest — Public. Returns the canonical manifest (paths, sha256, sizes, version, slug, created_at) and an Ed25519 signature, or signature null when the server has no signing key. Omit version for the live site. Verify with the keys at /.well-known/deed-signing-keys.json, then hash the files served at site_url.
List custom domains — Use this to list custom hostnames on one slug, or on every site your token owns when slug is omitted. Status is the last checked value. Call domain_status to refresh it.
List retained versions — Use this to see every retained version of a slug you own, newest first. Each entry has version, created_at, file_count, bytes, kind (publish, merge, or restore), restored_from, and a public permalink. Free keeps 10, Hobby 50, Pro unlimited.
List webhooks — Lists webhook URLs for your token. Secrets are not included.
Plan a large upload — Use this when the site is larger than about 4 MB, or when you already know each file's sha256. Send a manifest of {path, sha256, size, content_type?}. Returns which hashes are already stored and a direct upload URL for each missing hash. Upload those bytes, then call finalize_upload with the session id. Does not publish by itself. Per-site size limits are unchanged.
Remove a custom domain — Use this when the user wants a hostname detached. Removes it from the project so requests to that host no longer serve the site.
Restore a retained version — Use this to undo a publish. Creates a new version whose files equal the retained version, without re-uploading. Pass expected_version (the live vN). A mismatch returns version_conflict and does not write. The old permalink keeps serving until retention drops it.
Revoke an owner token — Use this when a token has leaked and you do not want a replacement yet. scope "current" (default) revokes the token you sent. scope "all" revokes every token for that principal, including any overlap window. A later call with a revoked token returns 401 token_revoked, not 403 suspended. Sites stay online. Without a recovery email they cannot be updated.
Rotate the owner token — Use this after a leak, or to retire a token an agent should stop using. Issues a new token for the same principal. Every site carries over. The previous token stops working immediately unless overlap_seconds is set (0 to 300). During that window both tokens work. After it, the previous token returns 401 token_revoked. The new token is shown once.
Set or clear a site password — Hobby and Pro only. Sets a password (8 to 200 characters) or clears it when password is null. The hash is scrypt. Visitors get a host-only HttpOnly Secure cookie. Version permalinks and custom domains of the site are gated too. Free returns plan_required. Clearing is allowed on every plan.
Site analytics — Owner-only cookieless counts for a slug: views per UTC day, top paths, top referrer hosts, and AI crawler counts by user-agent family. from and to are YYYY-MM-DD (default last 7 days, max 90). The accuracy field describes under-counting. No raw IP or full user agent is stored.
⟨16 unchanged words⟩ own. Requires the token from the first publish. There is no restore-version call; send the previous files again to undo. Returns the same shape as publish_site with a bumped version.
⟨16 unchanged words⟩ :"Map of relative path to file contents. Paths are stored exactly as given (a single top-level directory is not removed). Text as a string, binary as {\" ⟨17 unchanged words⟩ object"},"merge":{"description":"Keepexistingeveryfilespath you do not send, andadd/overwriteadd or overwrite only these exact paths.","type":"boolean"},"slug":{"description":"Slug you own. Must match ^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$. Not rewritten. Reserved slugs are rejected.","type":"string"},"spa":{ ⟨34 unchanged words⟩