Skip to main content
Glama

Update a site

update_site
DestructiveIdempotent

Replaces the files of a slug owned by the token, or, when merge is true, adds and overwrites only the paths sent. Inputs: slug, files, and optional spa, merge, expected_version, via, token, listed, category, tags, title, and description. Returns url, path_url, slug, listing, and a new version. When expected_version does not match the live version, the result is version_conflict and nothing is written. Two racing updates return version_conflict even without expected_version. listed defaults to false. Password-protected sites cannot be listed. A new version of a listed slug runs the gallery checks again. If the files total more than about 3.5 MB, do not call update_site. Call plan_upload, run commands in a shell, then finalize_upload. Or run node publish-large.mjs <dir> (https://deed.page/cli/publish-large.mjs).

Input Schema

NameRequiredDescriptionDefault
spaNoServe index.html for unknown paths.
viaNoOptional label stored with the publish. At most 80 characters. An IP address, a URL, or an email address is not stored. A non-empty value replaces the X-Via header.
slugYesSlug you own. Must match ^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$. Not rewritten. Reserved slugs are rejected.
tagsNoUp to 5 tags. Each tag is lowercase letters, digits, and hyphens, at most 32 characters.
filesYesPath map, or an array of {path, content} or {path, base64}. Paths are stored exactly as given (a single top-level directory is not removed). Text as a string, binary as {"base64":"..."}. Example: {"index.html":"<!doctype html><h1>Hi</h1>","img/logo.png":{"base64":"iVBOR..."}}. Any other array is rejected.
mergeNoKeep every path you do not send, and add or overwrite only these exact paths.
titleNoGallery title, at most 80 characters. Required when listed is true.
tokenNoBearer token returned by your first publish (deed_tok_...). Optional if the MCP client sends Authorization: Bearer.
listedNoOpt into the public gallery. Default false. false removes the slug immediately. Password-protected sites cannot be listed.
categoryNoGallery category. Required when listed is true.
descriptionNoGallery description, at most 300 characters. Required when listed is true.
idempotency_keyNoOptional retry key, 16-255 visible ASCII characters (a random UUID works). If this call fails with a connection reset, a timeout, or a 502 or 503, call it once more with the same arguments and the same idempotency_key: a publish that already went through is replayed (same slug, same version, same token, idempotent_replayed: true) instead of being written twice. The Idempotency-Key HTTP header works the same way.
expected_versionNoLive 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.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / idempotency_key
      Added value: +{
      +  "description": "Optional retry key, 16-255 visible ASCII characters (a random UUID works). If this call fails with a connection reset, a timeout, or a 502 or 503, call it once more with the same arguments and the same idempotency_key: a publish that already went through is replayed (same slug, same version, same token, idempotent_replayed: true) instead of being written twice. The Idempotency-Key HTTP header works the same way.",
      +  "type": "string"
      +}
  2. Changed5 schema fields changed
    • addedInput schema / properties / category
      Added value: +{
      +  "description": "Gallery category. Required when listed is true.",
      +  "enum": [
      +    "Apps & tools",
      +    "Games",
      +    "Business",
      +    "Portfolio",
      +    "Docs & guides",
      +    "Education",
      +    "Events",
      +    "Other"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / description
      Added value: +{
      +  "description": "Gallery description, at most 300 characters. Required when listed is true.",
      +  "maxLength": 300,
      +  "type": "string"
      +}
    • addedInput schema / properties / listed
      Added value: +{
      +  "description": "Opt into the public gallery. Default false. false removes the slug immediately. Password-protected sites cannot be listed.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / tags
      Added value: +{
      +  "description": "Up to 5 tags. Each tag is lowercase letters, digits, and hyphens, at most 32 characters.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "maxItems": 5,
      +  "type": "array"
      +}
    • addedInput schema / properties / title
      Added value: +{
      +  "description": "Gallery title, at most 80 characters. Required when listed is true.",
      +  "maxLength": 80,
      +  "type": "string"
      +}
  3. Changed1 schema field changed
    • addedInput schema / properties / via
      Added value: +{
      +  "description": "Optional label stored with the publish. At most 80 characters. An IP address, a URL, or an email address is not stored. A non-empty value replaces the X-Via header.",
      +  "type": "string"
      +}
  4. Changed1 schema field changed
    • changedInput schema / properties / files / description
      Previous value: -"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 {\"base64\":\"...\"}. Example: {\"index.html\":\"<!doctype html><h1>Hi</h1>\",\"img/logo.png\":{\"base64\":\"iVBOR...\"}}"New value: +"Path map, or an array of {path, content} or {path, base64}. Paths are stored exactly as given (a single top-level directory is not removed). Text as a string, binary as {\"base64\":\"...\"}. Example: {\"index.html\":\"<!doctype html><h1>Hi</h1>\",\"img/logo.png\":{\"base64\":\"iVBOR...\"}}. Any other array is rejected."
  5. Changed1 schema field changed
    • addedInput schema / properties / expected_version
      Added value: +{
      +  "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"
      +}
  6. Changed3 schema fields changed
    • changedInput schema / properties / files / description
      Previous value: -"Map of relative path to file contents. Text as a string, binary as {\"base64\":\"...\"}. Example: {\"index.html\":\"<!doctype html><h1>Hi</h1>\",\"img/logo.png\":{\"base64\":\"iVBOR...\"}}"New value: +"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 {\"base64\":\"...\"}. Example: {\"index.html\":\"<!doctype html><h1>Hi</h1>\",\"img/logo.png\":{\"base64\":\"iVBOR...\"}}"
    • changedInput schema / properties / merge / description
      Previous value: -"Keep existing files and add/overwrite only these paths."New value: +"Keep every path you do not send, and add or overwrite only these exact paths."
    • changedInput schema / properties / slug / description
      Previous value: -"Slug you own."New value: +"Slug you own. Must match ^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$. Not rewritten. Reserved slugs are rejected."
  7. First observed

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructive and idempotent, and the description earns credit on top by spelling out what actually happens on conflict: version_conflict with nothing written, race detection even without expected_version, gallery checks re-running on a new listed version, and listed=false removing the slug immediately. It also flags the password-protected listing restriction and the payload ceiling, none of which are derivable from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core replace/merge semantic before edge cases, and each constraint sentence (conflict, size limit, listing rules) carries real information. The 'Inputs: slug, files, and optional ...' clause is largely redundant with the schema and is the one paragraph that does not earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 13-parameter destructive write with a nested files object and no output schema, the description covers the return payload (url, path_url, slug, listing, new version), conflict and race behavior, listing constraints, and the large-payload escape hatch. Nothing an agent needs to call it safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description enumerates the parameter set and adds a few behavioral notes (listed defaults to false, password-protected sites can't be listed, expected_version conflict semantics), but the enumeration itself mostly restates the schema and it omits idempotency_key from the list of 13 parameters, so it does not add much net meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource and two precise modes: full replacement of a slug's files, or additive merge when merge is true. It never distinguishes itself from the sibling publish_site, which also targets a slug's files, so an agent must infer the boundary between first publish and update.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a hard when-not rule with a concrete alternative path: over ~3.5 MB, don't call this; use plan_upload -> shell `commands` -> finalize_upload, or the publish-large script with its URL. Also states the version_conflict precondition and that omitting expected_version is still safe under races. Only the publish_site vs update_site choice is left unaddressed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.