Skip to main content
Glama

Deploy Static Site

deployments_upload

Deploy a static site to a live URL: free, no account or API key required.

File content is plain text by default. Pass HTML/CSS/JS/JSON/SVG/etc. directly in each file's content as a regular string. Only set encoding: "base64" per-file for binary content (images, fonts) — do not base64-encode text.

Returns the live URL. Without a connected account, the response also includes a one-time claim URL, and the site expires in 3 days unless claimed. Pass password to make the site private.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "files": "<files>"
    },
    "name": "deployments_upload"
  }
}

Input Schema

NameRequiredDescriptionDefault
ttlNoSeconds until this deployment expires and the platform reclaims it; omit for one that never does. Only for authenticated deploys — an anonymous deployment already expires on the platform's schedule, and a requested ttl on one is refused. A deployment carrying a ttl cannot be linked to any domain: deploy without one if the site needs a domain.
filesYesFiles that make up the site. The site root is implied by these paths.
labelsNoLabels for organizing deployments (e.g. ["env:production", "v1.2"]). Each is a word, or a key and a value split by one ":". Lowercase, 3-63 chars, allows . _ - inside a word. Up to 10.
passwordNoOptional password to gate the deployment behind an unlock prompt (6–128 characters; whitespace significant). Visitors must enter this password before viewing the site, including on any custom domains pointing at it.
idempotencyKeyNoMakes this deploy replayable instead of repeatable. A deploy is not naturally idempotent: if a call times out you cannot tell "it never landed" from "it landed and the response was lost", and retrying creates a second deployment. Send the same key on the retry and you get back the deployment the first try made, if it went live in the last 24 hours. A key works only within the account that sent it: without an account it is ignored, and a retry deploys again. Key the ATTEMPT (a run id, a commit sha, a uuid minted before the first try), never one minted fresh on each retry, which would defeat the point.

Output Schema

NameRequiredDescriptionDefault
urlYesFull URL to the live deployment.
viaYesHow the deployment was created, as shown in deployment history (today one of: web, sdk, cli, mcp, git, n8n, gpt, vsc, cld, crs, gmn, api). Null on deployments older than the tag.
sizeYesTotal deployment size in bytes.
claimNoOne-time URL that claims this anonymous deployment to a free account, making it permanent. Only present on anonymous deploys; absent when the deploy was made with a connected account.
filesYesNumber of files in the deployment.
configYesTrue if the deployment includes a ship.json routing config.
labelsYesLabels attached to the deployment; empty when none.
statusYesDeployment lifecycle state; "success" means the site is live. One of: pending, success, failed, deleting.
createdYesUnix timestamp (seconds) when the deployment was created.
expiresYesUnix timestamp (seconds) when the deployment expires; null when permanent. Anonymous deployments expire 3 days after creation unless claimed; an authenticated deployment carries one only when it requested a ttl.
passwordYesTrue if the deployment is password-protected.
deploymentYesDeployment hostname, e.g. "happy-cat-abc1234.shipstatic.com".
screenshotYesFull URL to the deployment screenshot. Rendered on the first request for it, so the URL is returned immediately and the first request takes a few seconds; every request after that is served immediately.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / idempotencyKey / description
      Previous value: -"Makes this deploy replayable instead of repeatable. A deploy is not naturally idempotent: if a call times out you cannot tell \"it never landed\" from \"it landed and the response was lost\", and retrying creates a second deployment. Send the same key on the retry and the original deployment is replayed instead (within 24 hours). Key the ATTEMPT — a run id, a commit sha, a uuid minted before the first try — never one minted fresh on each retry, which would defeat the point. Only for a connected account: without one the key is ignored and a retry deploys again."New value: +"Makes this deploy replayable instead of repeatable. A deploy is not naturally idempotent: if a call times out you cannot tell \"it never landed\" from \"it landed and the response was lost\", and retrying creates a second deployment. Send the same key on the retry and you get back the deployment the first try made, if it went live in the last 24 hours. A key works only within the account that sent it: without an account it is ignored, and a retry deploys again. Key the ATTEMPT (a run id, a commit sha, a uuid minted before the first try), never one minted fresh on each retry, which would defeat the point."
  2. Changed1 schema field changed
    • changedInput schema / properties / labels / description
      Previous value: -"Labels for organizing deployments (e.g. [\"production\", \"v1.2\"]). Lowercase, 3-25 chars, allows . _ - separators. Up to 10."New value: +"Labels for organizing deployments (e.g. [\"env:production\", \"v1.2\"]). Each is a word, or a key and a value split by one \":\". Lowercase, 3-63 chars, allows . _ - inside a word. Up to 10."
  3. Changed1 schema field changed
    • changedInput schema / properties / ttl / description
      Previous value: -"Seconds until this deployment expires and the platform reclaims it; omit for one that never does. Only for authenticated deploys — an anonymous deployment already expires on the platform's schedule, and a requested ttl on one is refused. A deployment carrying a ttl cannot be linked to a custom domain: deploy without one if the site needs a domain."New value: +"Seconds until this deployment expires and the platform reclaims it; omit for one that never does. Only for authenticated deploys — an anonymous deployment already expires on the platform's schedule, and a requested ttl on one is refused. A deployment carrying a ttl cannot be linked to any domain: deploy without one if the site needs a domain."
  4. Changed1 schema field changed
    • changedInput schema / properties / idempotencyKey / description
      Previous value: -"Makes this deploy replayable instead of repeatable. A deploy is not naturally idempotent: if a call times out you cannot tell \"it never landed\" from \"it landed and the response was lost\", and retrying creates a second deployment. Send the same key on the retry and the original deployment is replayed instead (within 24 hours). Key the ATTEMPT — a run id, a commit sha, a uuid minted before the first try — never one minted fresh on each retry, which would defeat the point."New value: +"Makes this deploy replayable instead of repeatable. A deploy is not naturally idempotent: if a call times out you cannot tell \"it never landed\" from \"it landed and the response was lost\", and retrying creates a second deployment. Send the same key on the retry and the original deployment is replayed instead (within 24 hours). Key the ATTEMPT — a run id, a commit sha, a uuid minted before the first try — never one minted fresh on each retry, which would defeat the point. Only for a connected account: without one the key is ignored and a retry deploys again."
  5. Changed2 schema fields changed
    • removedOutput schema / properties / via / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / via / type
      Added value: +[
      +  "string",
      +  "null"
      +]
  6. Changed1 schema field changed
    • changedOutput schema / properties / screenshot / description
      Previous value: -"Full URL to the deployment screenshot. Captured asynchronously after deploy; the URL is returned immediately but the image may take a few seconds to become available."New value: +"Full URL to the deployment screenshot. Rendered on the first request for it, so the URL is returned immediately and the first request takes a few seconds; every request after that is served immediately."
  7. Changed7 schema fields changed
    • changedOutput schema / properties / claim / description
      Previous value: -"One-time URL that claims this anonymous deployment to a free account, making it permanent. Only present on anonymous deploys — absent when the deploy was made with a connected account."New value: +"One-time URL that claims this anonymous deployment to a free account, making it permanent. Only present on anonymous deploys; absent when the deploy was made with a connected account."
    • changedOutput schema / properties / config / description
      Previous value: -"True if the deployment includes a `ship.json` routing config."New value: +"True if the deployment includes a ship.json routing config."
    • changedOutput schema / properties / expires / description
      Previous value: -"Unix timestamp (seconds) when the deployment expires; null when permanent. Anonymous deploys through the hosted MCP expire 3 days after creation unless claimed; an authenticated deploy carries one only when it requested a ttl."New value: +"Unix timestamp (seconds) when the deployment expires; null when permanent. Anonymous deployments expire 3 days after creation unless claimed; an authenticated deployment carries one only when it requested a ttl."
    • changedOutput schema / properties / labels / description
      Previous value: -"Labels attached to the deployment."New value: +"Labels attached to the deployment; empty when none."
    • changedOutput schema / properties / status / description
      Previous value: -"Deployment lifecycle state. `success` means the site is live."New value: +"Deployment lifecycle state; \"success\" means the site is live. One of: pending, success, failed, deleting."
    • removedOutput schema / properties / status / enum
      Removed value: -[
      -  "pending",
      -  "success",
      -  "failed",
      -  "deleting"
      -]
    • changedOutput schema / properties / via / description
      Previous value: -"How the deployment was created, as shown in deployment history. Null on deployments older than the tag."New value: +"How the deployment was created, as shown in deployment history (today one of: web, sdk, cli, mcp, git, n8n, gpt, vsc, cld, crs, gmn, api). Null on deployments older than the tag."
  8. Changed1 schema field changed
    • changedOutput schema / properties / via / description
      Previous value: -"Origin tag for analytics (e.g. \"gpt\", \"mcp\", \"cli\", \"web\"). Null on legacy deployments uploaded before tagging existed."New value: +"How the deployment was created, as shown in deployment history. Null on deployments older than the tag."
  9. Changed2 schema fields changed
    • addedInput schema / properties / ttl
      Added value: +{
      +  "description": "Seconds until this deployment expires and the platform reclaims it; omit for one that never does. Only for authenticated deploys — an anonymous deployment already expires on the platform's schedule, and a requested ttl on one is refused. A deployment carrying a ttl cannot be linked to a custom domain: deploy without one if the site needs a domain.",
      +  "type": "number"
      +}
    • changedOutput schema / properties / expires / description
      Previous value: -"Unix timestamp (seconds) when the deployment expires; null when permanent. Anonymous deploys through the hosted MCP expire 3 days after creation unless claimed."New value: +"Unix timestamp (seconds) when the deployment expires; null when permanent. Anonymous deploys through the hosted MCP expire 3 days after creation unless claimed; an authenticated deploy carries one only when it requested a ttl."
  10. Changed12 schema fields changed
    • removedInput schema / additionalProperties
      Removed value: -false
    • removedInput schema / properties / files / items / additionalProperties
      Removed value: -false
    • addedInput schema / properties / idempotencyKey
      Added value: +{
      +  "description": "Makes this deploy replayable instead of repeatable. A deploy is not naturally idempotent: if a call times out you cannot tell \"it never landed\" from \"it landed and the response was lost\", and retrying creates a second deployment. Send the same key on the retry and the original deployment is replayed instead (within 24 hours). Key the ATTEMPT — a run id, a commit sha, a uuid minted before the first try — never one minted fresh on each retry, which would defeat the point.",
      +  "type": "string"
      +}
    • changedInput schema / properties / labels / description
      Previous value: -"Labels for organizing deployments (e.g. [\"production\", \"v1.2\"]). Lowercase, 3-25 chars, allows . _ - separators."New value: +"Labels for organizing deployments (e.g. [\"production\", \"v1.2\"]). Lowercase, 3-25 chars, allows . _ - separators. Up to 10."
    • changedOutput schema / properties / claim / description
      Previous value: -"One-time URL that claims this anonymous deployment to a free account, making it permanent. Only present on anonymous deploys (this hosted MCP is anonymous-only)."New value: +"One-time URL that claims this anonymous deployment to a free account, making it permanent. Only present on anonymous deploys — absent when the deploy was made with a connected account."
    • addedOutput schema / properties / created / maximum
      Added value: +9007199254740991
    • addedOutput schema / properties / created / minimum
      Added value: +-9007199254740991
    • changedOutput schema / properties / expires / anyOf
      Previous value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "maximum": 9007199254740991,
      +    "minimum": -9007199254740991,
      +    "type": "integer"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedOutput schema / properties / files / maximum
      Added value: +9007199254740991
    • addedOutput schema / properties / size / maximum
      Added value: +9007199254740991
    • addedOutput schema / properties / via / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / via / type
      Removed value: -[
      -  "string",
      -  "null"
      -]
  11. Changed2 schema fields changed
    • changedInput schema / properties / files / items / properties / content / description
      Previous value: -"Base64-encoded file contents."New value: +"File content as a plain text string. For HTML, CSS, JS, JSON, SVG, plain text — pass directly with no encoding step. For binary files (images, fonts) ONLY, set this entry's `encoding: \"base64\"` and pass base64-encoded bytes."
    • addedInput schema / properties / files / items / properties / encoding
      Added value: +{
      +  "description": "Defaults to `\"utf-8\"` (raw text). Set to `\"base64\"` ONLY for binary files. Never base64-encode text content — pass it as a plain string.",
      +  "enum": [
      +    "utf-8",
      +    "base64"
      +  ],
      +  "type": "string"
      +}
  12. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "claim": {
      +      "description": "One-time URL that claims this anonymous deployment to a free account, making it permanent. Only present on anonymous deploys (this hosted MCP is anonymous-only).",
      +      "format": "uri",
      +      "type": "string"
      +    },
      +    "config": {
      +      "description": "True if the deployment includes a `ship.json` routing config.",
      +      "type": "boolean"
      +    },
      +    "created": {
      +      "description": "Unix timestamp (seconds) when the deployment was created.",
      +      "type": "integer"
      +    },
      +    "deployment": {
      +      "description": "Deployment hostname, e.g. \"happy-cat-abc1234.shipstatic.com\".",
      +      "type": "string"
      +    },
      +    "expires": {
      +      "anyOf": [
      +        {
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "Unix timestamp (seconds) when the deployment expires; null when permanent. Anonymous deploys through the hosted MCP expire 3 days after creation unless claimed."
      +    },
      +    "files": {
      +      "description": "Number of files in the deployment.",
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "labels": {
      +      "description": "Labels attached to the deployment.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "password": {
      +      "description": "True if the deployment is password-protected.",
      +      "type": "boolean"
      +    },
      +    "screenshot": {
      +      "description": "Full URL to the deployment screenshot. Captured asynchronously after deploy; the URL is returned immediately but the image may take a few seconds to become available.",
      +      "format": "uri",
      +      "type": "string"
      +    },
      +    "size": {
      +      "description": "Total deployment size in bytes.",
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "status": {
      +      "description": "Deployment lifecycle state. `success` means the site is live.",
      +      "enum": [
      +        "pending",
      +        "success",
      +        "failed",
      +        "deleting"
      +      ],
      +      "type": "string"
      +    },
      +    "url": {
      +      "description": "Full URL to the live deployment.",
      +      "format": "uri",
      +      "type": "string"
      +    },
      +    "via": {
      +      "description": "Origin tag for analytics (e.g. \"gpt\", \"mcp\", \"cli\", \"web\"). Null on legacy deployments uploaded before tagging existed.",
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    }
      +  },
      +  "required": [
      +    "deployment",
      +    "url",
      +    "files",
      +    "size",
      +    "status",
      +    "config",
      +    "password",
      +    "labels",
      +    "via",
      +    "created",
      +    "expires",
      +    "screenshot"
      +  ],
      +  "type": "object"
      +}
  13. First observed

TDQS

A3.9/5.0
Behavior4/5

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

Annotations only give the safety profile (not read-only, open-world, non-destructive). The description adds genuinely useful behavioral context: the deploy is free/no-auth, returns a live URL, and anonymous deployments yield a one-time claim URL with a 3-day expiry. That lifecycle detail is exactly what annotations cannot convey.

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-loaded with the core action, then encoding guidance, then return/lifecycle behavior. Three short paragraphs with no filler, though the middle paragraph restates schema content at some length.

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

Completeness4/5

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

Output schema exists so return values needn't be spelled out, yet the description still covers the claim-URL/expiry and password behavior an agent must anticipate. For a 5-param tool with anonymous and authenticated paths, coverage is solid, though ttl-vs-domain constraints are left entirely to the schema.

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 all five parameters are already documented. The description reinforces the most error-prone rule (plain text by default, base64 only for binary), which is helpful emphasis but not new meaning beyond the schema. Baseline 3 applies.

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

Purpose5/5

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

States a specific verb and resource ('Deploy a static site to a live URL') and adds distinguishing context ('free, no account or API key required'). No sibling tool deploys a site, so this is unambiguous against deployments_get/list/set/delete.

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

Usage Guidelines3/5

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

Explains per-feature conditions well (use plain text unless binary, pass password to make private, anonymous deploys get a claim URL) but never frames when to choose this tool versus another path. Since no sibling overlaps, usage is largely implied rather than stated.

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.