Claude Code instructions for the ShipStatic MCP Server.
@shipstatic/mcp — MCP server that exposes the ShipStatic SDK to AI agents via stdio. Thin wrapper over @shipstatic/ship. Published to the MCP Registry as com.shipstatic/mcp. Maturity: v0.4.x — Deployments + Domains (15 tools).
src/
├── index.ts # Entry: env validation, Ship construction, stdio transport
├── server.ts # createServer(ship) — pure factory, all 15 tools
└── call.ts # call() wrapper + error mapping
pnpm build # TypeScript → dist/
pnpm test --run # All tests (30 tests, ~500ms)Every MCP tool maps 1:1 to a single @shipstatic/ship SDK method. The MCP layer handles only:
- Tool registration (name, schema, description)
- Response formatting (
call()— JSON.stringify for data, "Done." for void) - Error mapping (ShipError →
{ content, isError: true }with auth hints)
No HTTP calls, no auth logic, no domain validation. The SDK handles everything.
resource_action — matches SDK's ship.resource.action() and CLI's ship resource action.
Every tool handler is a one-liner that delegates to the SDK through call():
server.registerTool('deployments_get', {
description: 'Get deployment details including URL, status, file count, size, and labels.',
inputSchema: { deployment: z.string().describe('Deployment ID (e.g. "happy-cat-abc1234")') },
}, ({ deployment }) => call(() => ship.deployments.get(deployment)));call() handles try/catch, JSON serialization, void→"Done.", and ShipError→MCP error conversion.
index.ts owns the process: validates SHIP_API_KEY, constructs new Ship({ apiKey }), passes it to createServer(ship). The factory never touches process.env or constructs its own dependencies. Tests pass a mock directly.
SHIP_API_KEY is required — the server exits with a clear error if missing. The API key is passed explicitly to the Ship constructor, bypassing the SDK's file-based config resolution (~/.shiprc). This prevents credential leakage from locally installed CLI credentials.
deployments_upload sets via: 'mcp' — matching CLI's via: 'cli' for origin tracking.
tests/
├── call.test.ts # call() + error mapping (8 tests)
└── server.test.ts # Registration + wiring for all 15 tools (22 tests)
The CI workflow (.github/workflows/npm-publish.yml) publishes to both npm and the MCP Registry on every push to main. package.json is the single source of truth for the version — CI patches server.json with jq before registry publish. DNS authentication uses an Ed25519 key on shipstatic.com.
server.json — MCP Registry metadata. mcpName in package.json must match name in server.json (com.shipstatic/mcp).
- Add
server.registerTool()inserver.ts - Handler is a one-liner:
(args) => call(() => ship.resource.action(args)) - Add wiring test in
server.test.ts
{
"mcpServers": {
"shipstatic": {
"command": "npx",
"args": ["@shipstatic/mcp"],
"env": { "SHIP_API_KEY": "ship-..." }
}
}
}This file provides Claude Code guidance. User-facing documentation lives in README.md.