MCP protocol
The JSON-RPC envelope, the methods we implement, and the error shapes you'll see.
Transport
ShipMCP endpoints speak Model Context Protocol over HTTP. Every interaction is a POST to /mcp with a JSON-RPC 2.0
body and a Bearer token in the Authorization header.
POST https://mcp.shipmcp.io/<slug>/mcp
Authorization: Bearer smcp_...
Content-Type: application/json Tokens come from one of two paths: pasted from the dashboard (Claude Desktop config, curl, custom scripts), or auto-issued via the OAuth 2.0 flow (Claude.ai web, Cursor, MCP Inspector). See OAuth 2.0 for the full discovery + DCR story.
Envelope
Every request and response follows JSON-RPC 2.0:
// Request
{ "jsonrpc": "2.0", "id": 1, "method": "<name>", "params": { … } }
// Success
{ "jsonrpc": "2.0", "id": 1, "result": { … } }
// Error
{ "jsonrpc": "2.0", "id": 1,
"error": { "code": -32601, "message": "Method not found" } } Methods
ShipMCP implements initialize, tools/list, tools/call, resources/list, resources/read, resources/templates/list,
and ping. Anything else returns -32601 Method not found.
initialize
The handshake. Returns the server's capabilities, name, and the all-important instructions field. Our instructions points the agent at
the public llms.txt, so any compliant client gets your endpoint's full
schema and tool catalog as part of its system context.
// Response
{
"protocolVersion": "2024-11-05",
"serverInfo": { "name": "shipmcp", "version": "1.0.0" },
"capabilities": { "tools": {} },
"instructions": "Schema and tool docs: https://shipmcp.io/<slug>/llms.txt"
} tools/list
Returns every generated tool with its name, description, and input JSON Schema.
Agents call this once after initialize and may re-call it if your
endpoint's schema changes (e.g. after an append).
// Response
{
"tools": [
{
"name": "search_products",
"description": "Full-text search across products. Searches: name, description.",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string" },
"limit": { "type": "integer", "default": 50 }
},
"required": ["query"]
}
}
/* … more tools … */
]
} tools/call
Invokes a tool by name. The arguments must match the tool's inputSchema;
ShipMCP validates them before running the underlying SQL. Results come back as MCP
content blocks — typically a single JSON block with the rows.
// Request
{
"method": "tools/call",
"params": {
"name": "filter_products",
"arguments": { "category": "books", "price_max": 30 }
}
}
// Response
{
"content": [
{
"type": "text",
"text": "[{\"id\":1,\"name\":\"…\",\"price\":24.99}, …]"
}
]
} resources/list
Lists archived original-file resources for the endpoint (when keep_originals is on, default for new endpoints). Each resource is keyed by a shipmcp://<slug>/<documentId> URI and carries name, mimeType,
size. Paginated via opaque cursor.
resources/read
Fetches the bytes for one resource. Files ≤ 4 MB inline as base64 in the response; larger files come back as a text block with a 120-second signed URL the agent can follow with a plain GET. See Data ingestion for what's archived.
resources/templates/list
Returns an empty array. We don't expose any URI templates today — every resource
is a concrete URI listed by resources/list. Some clients (MCP Inspector)
treat a missing implementation as a fatal error rather than a feature-detect signal,
so we serve the empty response.
Errors
| Code | Meaning |
|---|---|
-32600 | Invalid request envelope |
-32601 | Unknown method |
-32602 | Invalid arguments — failed JSON Schema validation against inputSchema |
-32603 | Internal error — typically a Postgres failure; check the dashboard for the endpoint's last error message |
-32001 | Endpoint missing — the slug doesn't resolve to an active endpoint. Returned inside an HTTP 200 (rather than a bare 404) so OAuth-aware clients don't misread it as auth failure. |
HTTP-level errors
Before the JSON-RPC layer, the edge worker can return:
401— missing or invalid bearer token. Response includes aWWW-Authenticate: Bearer realm="ShipMCP", resource_metadata="..."header so OAuth-aware clients can auto-discover the authorization server. See OAuth 2.0.403— token is valid but doesn't grant access to the slug (e.g. owned by a different tenant), or token has read-only scope and the call is a write tool.429— rate-limit exceeded; honorRetry-After.503— endpoint is still provisioning; retry in 30s.
Discoverability
See llms.txt for how agents can fetch the
full schema and tool catalog without auth, before they decide whether to connect.