Skip to main content

MCP JSON-RPC Bridge

Alexandria acts as an MCP server for agents and human clients. The bridge accepts JSON-RPC 2.0 requests, enforces the caller's effective tool list, and dispatches to registered MCP servers or built-in tools.


POST /mcp

Unscoped JSON-RPC dispatch. Accepts either a user access token or an agent token in Authorization: Bearer. The token type determines which tools are accessible.

Agent tokens carry effective_tools baked in at mint time. User tokens have no agent-level filtering.

Supports X-Idempotency-Key header for idempotent tool calls.

Request

{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 1
}

Response 200 — JSON-RPC 2.0 response (always 200; errors are in the JSON body per JSON-RPC spec).

# List available tools
curl -s -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer $AGENT_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}' | jq .

# Call a tool
curl -s -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer $AGENT_TOKEN" \
-H 'Content-Type: application/json' \
-H 'X-Idempotency-Key: req-abc123' \
-d '{
"jsonrpc":"2.0",
"method":"tools/call",
"params":{"name":"web_search","arguments":{"query":"latest Go releases"}},
"id":2
}' | jq .

POST /mcp/agents/{name}

Agent-scoped JSON-RPC dispatch. The agent name from the URL path is cross-checked against the token's agent claim. This prevents one agent token from calling tools scoped to a different agent.

curl -s -X POST http://localhost:8080/mcp/agents/researcher \
-H "Authorization: Bearer $AGENT_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{...},"id":1}' | jq .

GET /v1/mcp/servers

List registered MCP servers. Requires human access token.

Response 200

[
{
"id": "01HXZ...",
"name": "github-tools",
"url": "https://mcp.internal/github",
"transport": "http",
"enabled": true,
"allowed_tools": ["create_issue", "list_prs"],
"created_at": "2026-01-10T09:00:00Z"
}
]

Admin MCP management

All write operations require admin authentication.

POST /admin/mcp

Register an MCP server. URL is SSRF-validated. Wildcard "*" is rejected in allowed_tools (ceilings use concrete names only).

{
"name": "github-tools",
"url": "https://mcp.internal/github",
"transport": "http",
"api_key": "ghp_...",
"allowed_tools": ["create_issue", "list_prs"]
}

transport options: http (default), sse, stdio.

POST /admin/mcp/discover

Probe a URL for MCP tools without registering it. Times out after 10 seconds. Useful for validating connectivity and discovering the tool manifest before committing.

{
"url": "https://mcp.internal/github",
"transport": "http"
}

Response 200

{
"tools": [
{ "name": "create_issue", "description": "Create a GitHub issue" },
{ "name": "list_prs", "description": "List open PRs" }
]
}

PATCH /admin/mcp/{name}

Update enabled flag and/or allowed_tools filter. Setting allowed_tools to [] clears the filter (exposes all tools from that server).

{
"enabled": false,
"allowed_tools": ["create_issue"]
}

DELETE /admin/mcp/{name}

Permanently remove an MCP server registration. Returns 204.


Permission approval flow

When an agent calls a tool that's in its approval_required_tools list, a permission request is created automatically. An admin must approve before the tool call proceeds.

See Permissions for the approval workflow.