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.