@shipstatic/mcp
Deploy static websites, landing pages, and prototypes instantly from AI agents. Start with the hosted endpoint at mcp.shipstatic.com (no install, no signup, no API key), or install this package to deploy folders from your own machine. The same fifteen too
npm · fingerprint 8435186ee388228e416e18f5 · repository · RSS
What changed
Changed 2026-10-14 11:43 UTC
1 schema or annotation change with the description left byte-identical.
--- pinned/deployments_upload +++ observed/deployments_upload { "annotations": { "destructiveHint": false, - "description": "Labels for organizing deployments (e.g. [\"production\", \"v1.2\"]). Lowercase, 3-25 chars, allows . _ - separators. Up to 10.", + "description": "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.", "items": { "type": "string" },
Changed 2026-10-13 14:06 UTC
1 description rewritten, 2 schema or annotation changes with the description left byte-identical.
--- pinned/deployments_upload +++ observed/deployments_upload { "annotations": { "destructiveHint": false, - "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.", + "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 any domain: deploy without one if the site needs a domain.", "type": "number" } },
--- pinned/domains_set +++ observed/domains_set { "annotations": { "destructiveHint": true, - "title": "Connect Custom Domain" + "title": "Set Domain" }, - "description": "Create or update a custom domain. Can reserve a name (omit deployment), link it to a deployment, switch deployments, or update labels. domains_records then returns the DNS records to configure.", + "description": "Create or update a domain: a ShipStatic domain (e.g. \"yourname.shipstatic.com\"), live as soon as a deployment is linked, or a custom domain (e.g. \"www.example.com\"), which needs DNS records first. Can reserve a name (omit deployment), link it to a deployment, switch deployments, or update labels. For a custom domain, domains_records then returns the DNS records to configure.", "execution": { "taskSupport": "forbidden" }, - "description": "Domain name (e.g. \"www.example.com\" or \"blog.example.com\")", + "description": "Domain name: a ShipStatic domain (e.g. \"yourname.shipstatic.com\") or a custom domain (e.g. \"www.example.com\")", "type": "string" }, "labels": { - "title": "Connect Custom Domain" + "title": "Set Domain" }
--- pinned/domains_validate +++ observed/domains_validate { "annotations": { "destructiveHint": false, - "description": "Domain name to check (e.g. \"www.example.com\"). Call before domains_set to check availability.", + "description": "Domain name to check (e.g. \"yourname.shipstatic.com\" or \"www.example.com\"). Call before domains_set to check availability.", "type": "string" } },
Changed 2026-10-11 12:36 UTC
1 schema or annotation change with the description left byte-identical.
--- pinned/whoami +++ observed/whoami { "annotations": { "destructiveHint": false, - "description": "What the account is allowed to hold: the same keys as usage, so the pair divides.", + "description": "What the account is allowed to hold, under usage's cap keys, so the pair divides. A pending invitation takes a member place, so it counts against members.", "properties": { "customDomains": { "description": "Hostnames the customer owns, paused ones included.", - "description": "Members of the account, the owner included; a pending invitation is not one.", + "description": "Member places: as caps, how many people the plan allows, the owner included; as usage, the members the account has.", "maximum": 9007199254740991, "minimum": 0, "type": "integer" - "description": "What the account currently holds.", + "description": "What the account currently holds: every cap, and the pending invitations beside them.", "properties": { "customDomains": { "description": "Hostnames the customer owns, paused ones included.", + "invitations": { + "description": "Invitations still open: pending and not yet expired. Each takes a member place beside the members, against the members cap.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, "members": { - "description": "Members of the account, the owner included; a pending invitation is not one.", + "description": "Member places: as caps, how many people the plan allows, the owner included; as usage, the members the account has.", "maximum": 9007199254740991, "minimum": 0, "type": "integer" - "members" + "members", + "invitations" ], "type": "object" }
Changed 2026-10-06 13:15 UTC
1 description rewritten, 3 schema or annotation changes with the description left byte-identical.
--- pinned/domains_get +++ observed/domains_get { "annotations": { "destructiveHint": false, - "description": "How far DNS verification has got: \"pending\" is the site's CNAME not pointing here, \"partial\" is a www domain's CNAME pointing here without its apex A record (the redirect), \"verified\" is every required record. The diagnostic under \"unverified\"; platform domains are born verified. One of: pending, partial, verified.", + "description": "How far DNS verification has got: \"pending\" is the site's CNAME not pointing here, \"partial\" is a www domain's CNAME pointing here without its apex A record (the redirect), \"verified\" is every required record. The diagnostic under \"unverified\"; ShipStatic domains are born verified. One of: pending, partial, verified.", "type": "string" }, "verifications": {
--- pinned/domains_list +++ observed/domains_list { "annotations": { "destructiveHint": false, - "description": "How far DNS verification has got: \"pending\" is the site's CNAME not pointing here, \"partial\" is a www domain's CNAME pointing here without its apex A record (the redirect), \"verified\" is every required record. The diagnostic under \"unverified\"; platform domains are born verified. One of: pending, partial, verified.", + "description": "How far DNS verification has got: \"pending\" is the site's CNAME not pointing here, \"partial\" is a www domain's CNAME pointing here without its apex A record (the redirect), \"verified\" is every required record. The diagnostic under \"unverified\"; ShipStatic domains are born verified. One of: pending, partial, verified.", "type": "string" }, "verifications": {
--- pinned/domains_records +++ observed/domains_records { "annotations": { "destructiveHint": false, - "description": "Returns the DNS records to configure at the domain's DNS provider. Call after domains_set. Custom domains only: a platform subdomain has no records to configure.", + "description": "Returns the DNS records to configure at the domain's DNS provider. Call after domains_set. Custom domains only: a ShipStatic domain has no records to configure.", "execution": { "taskSupport": "forbidden" },
--- pinned/domains_set +++ observed/domains_set { "annotations": { "destructiveHint": true, - "description": "How far DNS verification has got: \"pending\" is the site's CNAME not pointing here, \"partial\" is a www domain's CNAME pointing here without its apex A record (the redirect), \"verified\" is every required record. The diagnostic under \"unverified\"; platform domains are born verified. One of: pending, partial, verified.", + "description": "How far DNS verification has got: \"pending\" is the site's CNAME not pointing here, \"partial\" is a www domain's CNAME pointing here without its apex A record (the redirect), \"verified\" is every required record. The diagnostic under \"unverified\"; ShipStatic domains are born verified. One of: pending, partial, verified.", "type": "string" }, "verifications": {
Changed 2026-10-05 14:20 UTC
11 descriptions rewritten, 4 schema or annotation changes with the description left byte-identical.
--- pinned/deployments_delete +++ observed/deployments_delete { "annotations": { "destructiveHint": true, - "description": "Permanently delete a deployment and its files. You MUST confirm with the user before calling this tool, referencing the deployment.", + "description": "Permanently deletes a deployment and its files.", "execution": { "taskSupport": "forbidden" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "deployment": { + "description": "The deployment hostname that was marked for removal.", + "type": "string" + }, + "status": { + "description": "The state the deployment is in while background cleanup runs. One of: pending, success, failed, deleting.", + "type": "string" + } + }, + "required": [ + "deployment", + "status" + ], + "type": "object" + }, "title": "Delete Deployment" }
--- pinned/deployments_get +++ observed/deployments_get { "annotations": { "destructiveHint": false, - "idempotentHint": true, - "openWorldHint": true, + "openWorldHint": false, "readOnlyHint": true, "title": "Get Deployment" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "config": { + "description": "True if the deployment includes a ship.json routing config.", + "type": "boolean" + }, + "created": { + "description": "Unix timestamp (seconds) when the deployment was created.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "deployment": { + "description": "Deployment hostname, e.g. \"happy-cat-abc1234.shipstatic.com\".", + "type": "string" + }, + "expires": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "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." + }, + "files": { + "description": "Number of files in the deployment.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "labels": { + "description": "Labels attached to the deployment; empty when none.", + "items": { + "type": "string" + }, + "type": "array" + }, + "password": { + "description": "True if the deployment is password-protected.", + "type": "boolean" + }, + "screenshot": { + "description": "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.", + "format": "uri", + "type": "string" + }, + "size": { + "description": "Total deployment size in bytes.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "status": { + "description": "Deployment lifecycle state; \"success\" means the site is live. One of: pending, success, failed, deleting.", + "type": "string" + }, + "url": { + "description": "Full URL to the live deployment.", + "format": "uri", + "type": "string" + }, + "via": { + "description": "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.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "deployment", + "url", + "files", + "size", + "status", + "config", + "password", + "labels", + "via", + "created", + "expires", + "screenshot" + ], + "type": "object" + }, "title": "Get Deployment" }
--- pinned/deployments_list +++ observed/deployments_list { "annotations": { "destructiveHint": false, - "idempotentHint": true, - "openWorldHint": true, + "openWorldHint": false, "readOnlyHint": true, "title": "List Deployments" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cursor": { + "description": "Opaque cursor for the next page; null on the last page. The whole has-more signal.", + "type": [ + "string", + "null" + ] + }, + "deployments": { + "description": "The deployments on this page.", + "items": { + "additionalProperties": false, + "properties": { + "config": { + "description": "True if the deployment includes a ship.json routing config.", + "type": "boolean" + }, + "created": { + "description": "Unix timestamp (seconds) when the deployment was created.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "deployment": { + "description": "Deployment hostname, e.g. \"happy-cat-abc1234.shipstatic.com\".", + "type": "string" + }, + "expires": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "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." + }, + "files": { + "description": "Number of files in the deployment.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "labels": { + "description": "Labels attached to the deployment; empty when none.", + "items": { + "type": "string" + }, + "type": "array" + }, + "password": { + "description": "True if the deployment is password-protected.", + "type": "boolean" + }, + "screenshot": { + "description": "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.", + "format": "uri", + "type": "string" + }, + "size": { + "description": "Total deployment size in bytes.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "status": { + "description": "Deployment lifecycle state; \"success\" means the site is live. One of: pending, success, failed, deleting.", + "type": "string" + }, + "url": { + "description": "Full URL to the live deployment.", + "format": "uri", + "type": "string" + }, + "via": { + "description": "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.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "deployment", + "url", + "files", + "size", + "status", + "config", + "password", + "labels", + "via", + "created", + "expires", + "screenshot" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "cursor", + "deployments" + ], + "type": "object" + }, "title": "List Deployments" }
--- pinned/deployments_set +++ observed/deployments_set { "annotations": { - "destructiveHint": false, - "idempotentHint": true, - "openWorldHint": true, + "destructiveHint": true, + "openWorldHint": false, "readOnlyHint": false, "title": "Update Deployment Labels" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "config": { + "description": "True if the deployment includes a ship.json routing config.", + "type": "boolean" + }, + "created": { + "description": "Unix timestamp (seconds) when the deployment was created.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "deployment": { + "description": "Deployment hostname, e.g. \"happy-cat-abc1234.shipstatic.com\".", + "type": "string" + }, + "expires": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "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." + }, + "files": { + "description": "Number of files in the deployment.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "labels": { + "description": "Labels attached to the deployment; empty when none.", + "items": { + "type": "string" + }, + "type": "array" + }, + "password": { + "description": "True if the deployment is password-protected.", + "type": "boolean" + }, + "screenshot": { + "description": "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.", + "format": "uri", + "type": "string" + }, + "size": { + "description": "Total deployment size in bytes.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "status": { + "description": "Deployment lifecycle state; \"success\" means the site is live. One of: pending, success, failed, deleting.", + "type": "string" + }, + "url": { + "description": "Full URL to the live deployment.", + "format": "uri", + "type": "string" + }, + "via": { + "description": "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.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "deployment", + "url", + "files", + "size", + "status", + "config", + "password", + "labels", + "via", + "created", + "expires", + "screenshot" + ], + "type": "object" + }, "title": "Update Deployment Labels" }
--- pinned/deployments_upload +++ observed/deployments_upload { "annotations": { "destructiveHint": false, - "description": "Deploy a static site instantly — free, no account or API key required. Returns the live URL, file count, and size. Without SHIP_TOKEN, the response includes a claim URL (site expires in 3 days) — always show both the deployment URL and claim URL to the user. To make the site private, pass `password`; always show the password to the user if you set one.", + "description": "Deploy a static site instantly: free, no account or API key required. Returns the live URL, file count, and size. Without SHIP_TOKEN, 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.", "execution": { "taskSupport": "forbidden" }, + "outputSchema": { + "$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; absent when the deploy was made with a connected account.", + "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.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "deployment": { + "description": "Deployment hostname, e.g. \"happy-cat-abc1234.shipstatic.com\".", + "type": "string" + }, + "expires": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "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." + }, + "files": { + "description": "Number of files in the deployment.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "labels": { + "description": "Labels attached to the deployment; empty when none.", + "items": { + "type": "string" + }, + "type": "array" + }, + "password": { + "description": "True if the deployment is password-protected.", + "type": "boolean" + }, + "screenshot": { + "description": "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.", + "format": "uri", + "type": "string" + }, + "size": { + "description": "Total deployment size in bytes.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "status": { + "description": "Deployment lifecycle state; \"success\" means the site is live. One of: pending, success, failed, deleting.", + "type": "string" + }, + "url": { + "description": "Full URL to the live deployment.", + "format": "uri", + "type": "string" + }, + "via": { + "description": "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.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "deployment", + "url", + "files", + "size", + "status", + "config", + "password", + "labels", + "via", + "created", + "expires", + "screenshot" + ], + "type": "object" + }, "title": "Deploy Static Site" }
--- pinned/domains_delete +++ observed/domains_delete { "annotations": { "destructiveHint": true, - "description": "Permanently delete a domain. You MUST confirm with the user before calling this tool, referencing the domain name.", + "description": "Permanently deletes a domain.", "execution": { "taskSupport": "forbidden" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "domain": { + "description": "The domain name that was removed, normalized.", + "type": "string" + } + }, + "required": [ + "domain" + ], + "type": "object" + }, "title": "Delete Domain" }
--- pinned/domains_dns +++ observed/domains_dns { "annotations": { "destructiveHint": false, - "idempotentHint": true, - "openWorldHint": true, + "openWorldHint": false, "readOnlyHint": true, - "title": "Look Up DNS Provider" + "title": "Get DNS Provider" }, - "description": "Look up the DNS provider for a domain (e.g. Cloudflare, Namecheap). Helps the user know where to configure their DNS records.", + "description": "Returns the DNS provider recorded for the domain, if known (e.g. Cloudflare, Namecheap): where its DNS records are configured. Custom domains only, and only while the domain is unverified; once its DNS is right there is nothing left to locate.", "execution": { "taskSupport": "forbidden" }, - "description": "Domain name to look up DNS provider for (e.g. \"www.example.com\")", + "description": "Domain name (e.g. \"www.example.com\"). Must be a domain previously created with domains_set.", "type": "string" } }, - "title": "Look Up DNS Provider" + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "dns": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "provider": { + "additionalProperties": false, + "description": "The provider serving this domain's DNS; absent when unidentified.", + "properties": { + "name": { + "description": "Provider name, e.g. \"Cloudflare\"; null if unknown.", + "type": [ + "string", + "null" + ] + }, + "url": { + "anyOf": [ + { + "format": "uri", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The provider's DNS dashboard, where the records get added; null or absent when unknown." + } + }, + "required": [ + "name" + ], + "type": "object" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "What the platform recorded about the domain's DNS provider when the domain was created; null if nothing was recorded." + }, + "domain": { + "description": "The domain name.", + "type": "string" + } + }, + "required": [ + "domain", + "dns" + ], + "type": "object" + }, + "title": "Get DNS Provider" }
--- pinned/domains_get +++ observed/domains_get { "annotations": { "destructiveHint": false, - "idempotentHint": true, - "openWorldHint": true, + "openWorldHint": false, "readOnlyHint": true, "title": "Get Domain" }, - "description": "Get domain details including URL, linked deployment, verification status, and labels.", + "description": "Get domain details including URL, linked deployment, labels, and `status`: the one word saying what the domain needs from its owner (`unverified`, `unlinked`, `live`, `paused`).", "execution": { "taskSupport": "forbidden" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "created": { + "description": "Unix timestamp (seconds) when the domain was created.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "deployment": { + "description": "The deployment hostname this domain points to; null when reserved but not yet linked.", + "type": [ + "string", + "null" + ] + }, + "domain": { + "description": "The domain name, e.g. \"www.example.com\".", + "type": "string" + }, + "labels": { + "description": "Labels attached to the domain; empty when none.", + "items": { + "type": "string" + }, + "type": "array" + }, + "linked": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Unix timestamp (seconds) when a deployment was last linked; null if never linked." + }, + "links": { + "description": "How many times a deployment has been linked to this domain.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "paused": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Unix timestamp (seconds) when plan enforcement paused serving; null while the plan has room for it." + }, + "status": { + "description": "What this domain needs from its owner, derived: \"live\" serves the linked deployment and needs nothing; \"unlinked\" is verified with nothing published there, so link a deployment; \"unverified\" needs its DNS records configured; \"paused\" means the plan no longer has room for it. Read this word rather than recomputing it. One of: live, unlinked, unverified, paused.", + "type": "string" + }, + "url": { + "description": "Full URL to the domain.", + "format": "uri", + "type": "string" + }, + "verification": { + "description": "How far DNS verification has got: \"pending\" is the site's CNAME not pointing here, \"partial\" is a www domain's CNAME pointing here without its apex A record (the redirect), \"verified\" is every required record. The diagnostic under \"unverified\"; platform domains are born verified. One of: pending, partial, verified.", + "type": "string" + }, + "verifications": { + "description": "How many DNS verification attempts this domain has had.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "verified": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "When DNS last became verified; null if it never has, and never cleared, so a domain whose records moved away keeps it. Read `verification` for whether DNS is right now." + } + }, + "required": [ + "domain", + "url", + "status", + "deployment", + "linked", + "links", + "verification", + "verified", + "verifications", + "paused", + "labels", + "created" + ], + "type": "object" + }, "title": "Get Domain" }
--- pinned/domains_list +++ observed/domains_list { "annotations": { "destructiveHint": false, - "idempotentHint": true, - "openWorldHint": true, + "openWorldHint": false, "readOnlyHint": true, "title": "List Domains" }, - "description": "List all domains with their URLs, linked deployment, and verification status. The response's `cursor` is null on the last page; pass it back as `cursor` to fetch the next.", + "description": "List all domains with their URLs, linked deployment, and `status`. The response's `cursor` is null on the last page; pass it back as `cursor` to fetch the next.", "execution": { "taskSupport": "forbidden" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cursor": { + "description": "Opaque cursor for the next page; null on the last page. The whole has-more signal.", + "type": [ + "string", + "null" + ] + }, + "domains": { + "description": "The domains on this page.", + "items": { + "additionalProperties": false, + "properties": { + "created": { + "description": "Unix timestamp (seconds) when the domain was created.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "deployment": { + "description": "The deployment hostname this domain points to; null when reserved but not yet linked.", + "type": [ + "string", + "null" + ] + }, + "domain": { + "description": "The domain name, e.g. \"www.example.com\".", + "type": "string" + }, + "labels": { + "description": "Labels attached to the domain; empty when none.", + "items": { + "type": "string" + }, + "type": "array" + }, + "linked": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Unix timestamp (seconds) when a deployment was last linked; null if never linked." + }, + "links": { + "description": "How many times a deployment has been linked to this domain.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "paused": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Unix timestamp (seconds) when plan enforcement paused serving; null while the plan has room for it." + }, + "status": { + "description": "What this domain needs from its owner, derived: \"live\" serves the linked deployment and needs nothing; \"unlinked\" is verified with nothing published there, so link a deployment; \"unverified\" needs its DNS records configured; \"paused\" means the plan no longer has room for it. Read this word rather than recomputing it. One of: live, unlinked, unverified, paused.", + "type": "string" + }, + "url": { + "description": "Full URL to the domain.", + "format": "uri", + "type": "string" + }, + "verification": { + "description": "How far DNS verification has got: \"pending\" is the site's CNAME not pointing here, \"partial\" is a www domain's CNAME pointing here without its apex A record (the redirect), \"verified\" is every required record. The diagnostic under \"unverified\"; platform domains are born verified. One of: pending, partial, verified.", + "type": "string" + }, + "verifications": { + "description": "How many DNS verification attempts this domain has had.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "verified": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "When DNS last became verified; null if it never has, and never cleared, so a domain whose records moved away keeps it. Read `verification` for whether DNS is right now." + } + }, + "required": [ + "domain", + "url", + "status", + "deployment", + "linked", + "links", + "verification", + "verified", + "verifications", + "paused", + "labels", + "created" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "cursor", + "domains" + ], + "type": "object" + }, "title": "List Domains" }
--- pinned/domains_records +++ observed/domains_records { "annotations": { "destructiveHint": false, - "idempotentHint": true, - "openWorldHint": true, + "openWorldHint": false, "readOnlyHint": true, "title": "Get DNS Records" }, - "description": "Get the DNS records the user needs to configure at their DNS provider. Call after domains_set. You MUST show the returned records to the user.", + "description": "Returns the DNS records to configure at the domain's DNS provider. Call after domains_set. Custom domains only: a platform subdomain has no records to configure.", "execution": { "taskSupport": "forbidden" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "apex": { + "description": "The apex (registered) domain where DNS records are managed.", + "type": "string" + }, + "domain": { + "description": "The domain the records are for.", + "type": "string" + }, + "records": { + "description": "The records to configure at the DNS provider, in the order to add them.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "The DNS name to configure.", + "type": "string" + }, + "type": { + "description": "Record type: A for the apex redirect, CNAME for the hosted subdomain.", + "enum": [ + "A", + "CNAME" + ], + "type": "string" + }, + "value": { + "description": "The value to set: an IP for A, a hostname for CNAME.", + "type": "string" + } + }, + "required": [ + "type", + "name", + "value" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "domain", + "apex", + "records" + ], + "type": "object" + }, "title": "Get DNS Records" }
--- pinned/domains_set +++ observed/domains_set { "annotations": { - "destructiveHint": false, - "idempotentHint": true, + "destructiveHint": true, "openWorldHint": true, "readOnlyHint": false, "title": "Connect Custom Domain" - "description": "Create or update a custom domain. Can reserve a name (omit deployment), link it to a deployment, switch deployments, or update labels. After creating, call domains_records and show the DNS records to the user.", + "description": "Create or update a custom domain. Can reserve a name (omit deployment), link it to a deployment, switch deployments, or update labels. domains_records then returns the DNS records to configure.", "execution": { "taskSupport": "forbidden" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "created": { + "description": "Unix timestamp (seconds) when the domain was created.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "deployment": { + "description": "The deployment hostname this domain points to; null when reserved but not yet linked.", + "type": [ + "string", + "null" + ] + }, + "domain": { + "description": "The domain name, e.g. \"www.example.com\".", + "type": "string" + }, + "isCreate": { + "description": "True when this call created the domain; false when it updated an existing one.", + "type": "boolean" + }, + "labels": { + "description": "Labels attached to the domain; empty when none.", + "items": { + "type": "string" + }, + "type": "array" + }, + "linked": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Unix timestamp (seconds) when a deployment was last linked; null if never linked." + }, + "links": { + "description": "How many times a deployment has been linked to this domain.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "paused": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Unix timestamp (seconds) when plan enforcement paused serving; null while the plan has room for it." + }, + "status": { + "description": "What this domain needs from its owner, derived: \"live\" serves the linked deployment and needs nothing; \"unlinked\" is verified with nothing published there, so link a deployment; \"unverified\" needs its DNS records configured; \"paused\" means the plan no longer has room for it. Read this word rather than recomputing it. One of: live, unlinked, unverified, paused.", + "type": "string" + }, + "url": { + "description": "Full URL to the domain.", + "format": "uri", + "type": "string" + }, + "verification": { + "description": "How far DNS verification has got: \"pending\" is the site's CNAME not pointing here, \"partial\" is a www domain's CNAME pointing here without its apex A record (the redirect), \"verified\" is every required record. The diagnostic under \"unverified\"; platform domains are born verified. One of: pending, partial, verified.", + "type": "string" + }, + "verifications": { + "description": "How many DNS verification attempts this domain has had.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "verified": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "When DNS last became verified; null if it never has, and never cleared, so a domain whose records moved away keeps it. Read `verification` for whether DNS is right now." + } + }, + "required": [ + "domain", + "url", + "status", + "deployment", + "linked", + "links", + "verification", + "verified", + "verifications", + "paused", + "labels", + "created", + "isCreate" + ], + "type": "object" + }, "title": "Connect Custom Domain" }
--- pinned/domains_share +++ observed/domains_share { "annotations": { "destructiveHint": false, - "idempotentHint": true, - "openWorldHint": true, + "openWorldHint": false, "readOnlyHint": true, "title": "Share DNS Setup" }, - "description": "Get a shareable DNS setup link for a domain. Share the link with the user so they, or whoever manages their DNS, can view the required records without needing an API key.", + "description": "Returns a shareable DNS setup URL that needs no API key, for whoever manages the domain's DNS. Custom domains only, and only while the domain is unverified; a verified domain has no setup left to share.", "execution": { "taskSupport": "forbidden" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "domain": { + "description": "The domain the setup link is for.", + "type": "string" + }, + "url": { + "description": "The shareable DNS setup URL; whoever opens it sees the records to configure, with no API key.", + "format": "uri", + "type": "string" + } + }, + "required": [ + "domain", + "url" + ], + "type": "object" + }, "title": "Share DNS Setup" }
--- pinned/domains_validate +++ observed/domains_validate { "annotations": { "destructiveHint": false, - "idempotentHint": true, - "openWorldHint": true, + "openWorldHint": false, "readOnlyHint": true, "title": "Check Domain Availability" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "available": { + "description": "Whether nobody has registered the name yet; null when invalid. Creating it would be new; re-pointing your own domain is a write, not a create.", + "type": [ + "boolean", + "null" + ] + }, + "normalized": { + "description": "The normalized domain name; null when invalid.", + "type": [ + "string", + "null" + ] + }, + "reason": { + "description": "Why the name is unusable, for display; null when it is usable.", + "type": [ + "string", + "null" + ] + }, + "valid": { + "description": "Whether the domain's shape is usable.", + "type": "boolean" + } + }, + "required": [ + "valid", + "normalized", + "available", + "reason" + ], + "type": "object" + }, "title": "Check Domain Availability" }
--- pinned/domains_verify +++ observed/domains_verify { "annotations": { "destructiveHint": false, - "idempotentHint": true, "openWorldHint": true, "readOnlyHint": false, "title": "Verify Domain DNS" - "description": "Trigger DNS verification for a custom domain. Call after the user has configured DNS records from domains_records. Verification is asynchronous — the domain status updates once DNS propagates.", + "description": "Trigger DNS verification for a custom domain. Call after the user has configured DNS records from domains_records. Custom domains only, and refused once the domain is verified: read domains_get instead. Verification is asynchronous: read the domain again with domains_get to learn the verdict, since its `status` has not moved yet when this returns. A verified domain serves nothing until a deployment is linked with domains_set.", "execution": { "taskSupport": "forbidden" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "domain": { + "description": "The domain whose DNS verification was queued, normalized. The check runs asynchronously; the domain's `verification` and `status` update once DNS propagates, so read the domain again rather than trusting this acknowledgement for a verdict.", + "type": "string" + } + }, + "required": [ + "domain" + ], + "type": "object" + }, "title": "Verify Domain DNS" }
--- pinned/whoami +++ observed/whoami { "annotations": { "destructiveHint": false, - "idempotentHint": true, - "openWorldHint": true, + "openWorldHint": false, "readOnlyHint": true, "title": "Show Account" }, - "description": "Show authenticated account details including email, plan, and usage.", + "description": "Returns your email and name, and the account's plan, usage and caps.", "execution": { "taskSupport": "forbidden" }, + "outputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caps": { + "additionalProperties": false, + "description": "What the account is allowed to hold: the same keys as usage, so the pair divides.", + "properties": { + "customDomains": { + "description": "Hostnames the customer owns, paused ones included.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "deployments": { + "description": "Deployments, every row whatever its status.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "members": { + "description": "Members of the account, the owner included; a pending invitation is not one.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "platformDomains": { + "description": "Names chosen under the platform's own suffix, e.g. \"my-app.shipstatic.com\".", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "deployments", + "platformDomains", + "customDomains", + "members" + ], + "type": "object" + }, + "email": { + "description": "The account email address.", + "type": "string" + }, + "name": { + "description": "Display name; null if not set.", + "type": [ + "string", + "null" + ] + }, + "plan": { + "description": "The plan the account is on. One of: free, pro, team, scale, sponsored.", + "type": "string" + }, + "usage": { + "additionalProperties": false, + "description": "What the account currently holds.", + "properties": { + "customDomains": { + "description": "Hostnames the customer owns, paused ones included.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "deployments": { + "description": "Deployments, every row whatever its status.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "members": { + "description": "Members of the account, the owner included; a pending invitation is not one.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "platformDomains": { + "description": "Names chosen under the platform's own suffix, e.g. \"my-app.shipstatic.com\".", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "deployments", + "platformDomains", + "customDomains", + "members" + ], + "type": "object" + } + }, + "required": [ + "email", + "name", + "plan", + "usage", + "caps" + ], + "type": "object" + }, "title": "Show Account" }
Current tools
Show all 15 tool fingerprints
Watch this server yourself
If you run this server, put the proxy in front of it. It pins these exact fingerprints on first connect and stops the session if they move.
npx -y mcp-pin@0.2.3 -- <your @shipstatic/mcp command>
Or subscribe to this page's RSS feed to be told when it changes.
Badge
The badge states one fact about time and nothing else. It never claims a server is safe.
[](https://mcp-pin.gautamkhosla.com/servers/8d4a5f133d7138e2.html)