Skip to content

MCP server

Endpoint: POST https://api.protogrid.dev/mcp, streamable HTTP, stateless (no sessions, plain JSON responses). It speaks the 2026-07-28 protocol (server/discover, the tool list cacheable for an hour) and still answers clients that open with the older initialize handshake, with the same tools. No authentication required (the registry’s own server is R0). An optional API key in X-API-Key raises the limits. The same limits as REST apply per HTTP request. GET and DELETE on /mcp answer 405.

tool arguments returns
search q, limit?, class?[], transport?, category?, min_trust?, flags?[], exclude_flags?[] the /v1/search body
get_server name, schemas? the descriptor
list_tools name, limit?, cursor? the /v1/servers/{name}/tools body
get_connection name, target? the /v1/servers/{name}/connection body
check_server url?, id?, wait? the /v1/check body: pass url to check a server (waits up to 25 s by default), or id to read an earlier check

Results are returned twice: as structuredContent and as one text content block with the same JSON. When the REST status would be 400 or above the result has isError: true and the body carries error plus next_actions. next_actions[].action is a tool name and next_actions[].arguments can be passed straight back.

Claude Code:

Terminal window
claude mcp add --transport http -s user protogrid https://api.protogrid.dev/mcp

Codex (~/.codex/config.toml):

[mcp_servers.protogrid]
url = "https://api.protogrid.dev/mcp"

OpenCode (opencode.json):

{ "mcp": { "protogrid": { "type": "remote", "url": "https://api.protogrid.dev/mcp", "enabled": true } } }

Any client that reads mcpServers:

{ "mcpServers": { "protogrid": { "type": "http", "url": "https://api.protogrid.dev/mcp" } } }

Cursor, VS Code and the rest are in Getting started.

Terminal window
curl -s https://api.protogrid.dev/mcp \
-H 'content-type: application/json' -H 'accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search","arguments":{"q":"send an email","class":["R0","R1"],"limit":3}}}'

Stateless mode means no initialize handshake is required for a single call, though standard clients still perform one.

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://api.protogrid.dev/mcp")));
const found = await client.callTool({ name: "search", arguments: { q: "query postgres", class: ["R0", "R1"] } });
const first = found.structuredContent.results[0];
const conn = await client.callTool({ name: "get_connection", arguments: { name: first.name } });
// conn.structuredContent.connection is the mcpServers block with ${SECRET} placeholders

The server’s instructions (sent on initialize) summarize the flow and the connection classes for agents that read them.