Connecting
Connecting
Endpoint
POST https://api.dtpr.io/mcp
| Header | Value | Required |
|---|---|---|
Content-Type | application/json | yes |
Accept | application/json | recommended |
mcp-session-id | Any opaque string chosen by the client | yes for render_datachain → resources/read |
GET /mcp returns 405 Method Not Allowed. Server-initiated streams are not supported.
Protocol version
The server advertises protocol version 2025-06-18 in the initialize response. The initialize handshake is optional — you can call tools/list or tools/call directly — but clients that implement it will receive the capability set.
Supported methods
| Method | Response shape |
|---|---|
initialize | { protocolVersion, serverInfo, capabilities } |
notifications/initialized | no response (notification) |
initialized | no response (unprefixed alias) |
tools/list | { tools: ToolDescriptor[] } |
tools/call | { structuredContent, content, isError? } |
resources/list | { resources: ResourceDescriptor[] } |
resources/read | { contents: [{ uri, mimeType, text }] } |
ping | {} |
Unknown methods return JSON-RPC error -32601 Method not found.
Sessions
mcp-session-id isolates cross-call state per session. Its only current use is the render_datachain → resources/read ui://dtpr/datachain/view.html handshake: the HTML produced by a tool call lands in a per-session slot and is returned verbatim to the resources/read on the same session id.
Clients that omit the header share a single fallback slot (__dtpr_default_session__). Concurrent callers that both omit the header can read each other's last-rendered HTML — set mcp-session-id to a per-session value to avoid that.
Batch requests
A JSON array of JSON-RPC requests is processed sequentially; responses are returned in a matching array. Per JSON-RPC 2.0 §6, a batch containing only notifications produces no response body — the server returns HTTP 204 No Content instead of an empty array.
Wire format
POST /mcp HTTP/1.1
Host: api.dtpr.io
Content-Type: application/json
Accept: application/json
mcp-session-id: 01HR...
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"serverInfo": { "name": "dtpr-api", "version": "0.1.0" },
"capabilities": { "tools": {}, "resources": {} }
}
}
Example: initialize + list tools
curl -s https://api.dtpr.io/mcp \
-H 'content-type: application/json' \
-H 'mcp-session-id: demo-session' \
--data '[
{"jsonrpc":"2.0","id":1,"method":"initialize"},
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
]'
[
{ "jsonrpc": "2.0", "id": 1, "method": "initialize" },
{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }
]
Notes
- No SSE. A single POST returns a single JSON response. If your MCP client insists on
text/event-stream, use a Streamable-HTTP-aware transport that falls through to JSON. - JSON-RPC 2.0 strictness.
jsonrpcmust be exactly"2.0"; other values return-32600 Invalid Request. - Why hand-rolled. The
@modelcontextprotocol/sdkserver transport pulls CJS-onlyAjv, which workerd'snodejs_compatcannot load. Seeapi/docs/mcp-fallback.mdfor the full rationale.