MCP API
The Model Context Protocol transport and its OAuth 2.1 authorization server. See the MCP Servers guide for concepts.
These endpoints are served at the site root (not under /api).
Endpoint
POST /mcp/{repo}/{branch}/{slug}
One JSON-RPC 2.0 message per request body. {slug} resolves a raisin:McpServer node in the mcp workspace; {branch} selects the branch served.
Headers
| Header | Notes |
|---|---|
Content-Type: application/json | Required. |
Authorization: Bearer <token> | Required unless the server (or tool) is public. Accepts a user/API-key token or an OAuth resource token. |
Responses
- A request (with
id) returns a JSON-RPC response (HTTP200); errors are carried in the JSON-RPCerrorfield. - A notification (no
id) returns202with no body. resources/subscribereturns atext/event-stream(SSE) of update notifications.
Methods
initialize
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"cli","version":"1.0"}}}
Response:
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{"listChanged":false},"resources":{"subscribe":true,"listChanged":false}},"serverInfo":{"name":"Catalog","version":"1.0.0"},"instructions":"Query the product catalog."}}
tools/list
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
Returns only the tools the caller's scopes permit. Each entry: { "name", "description", "inputSchema" }.
tools/call
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_node","arguments":{"workspace":"products","path":"/widgets/acme"}}}
Response (isError: true marks a function/tool-level failure, distinct from a JSON-RPC error):
{"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"json","json":{ "...": "..." }}],"isError":false}}
resources/list · resources/read · resources/subscribe
Available when the server's data.resources is true. Resources are addressed as raisin://{workspace}/{path}.
{"jsonrpc":"2.0","id":4,"method":"resources/read","params":{"uri":"raisin://products/widgets/acme"}}
resources/subscribe upgrades to SSE and streams notifications/resources/updated frames as nodes change.
Error codes
| Code | Meaning |
|---|---|
-32700 | Parse error (malformed JSON). |
-32600 | Invalid request. |
-32601 | Method or tool not found / server slug not found. |
-32602 | Invalid params. |
-32001 | Unauthorized (missing scopes, or authentication required for a non-public server). |
OAuth 2.1 authorization server
Interactive clients discover and use these automatically. All are served at the site root.
Discovery metadata
GET /.well-known/oauth-authorization-server # RFC 8414
GET /.well-known/oauth-protected-resource/mcp/{repo}/{branch}/{slug} # RFC 9728
The protected-resource document's resource is the canonical MCP URL; authorization_servers points back to this issuer. code_challenge_methods_supported is ["S256"].
Dynamic client registration (RFC 7591)
POST /register
Request:
{"client_name":"my-agent","redirect_uris":["https://app.example.com/cb"],"token_endpoint_auth_method":"none","grant_types":["authorization_code"],"response_types":["code"]}
Response includes client_id (and client_secret for confidential clients).
Authorization (RFC 6749 §4.1, PKCE S256)
GET /authorize?response_type=code&client_id=…&redirect_uri=…&code_challenge=…&code_challenge_method=S256&scope=…&resource=…
POST /authorize # login + consent form submission
GET renders the login + consent form. POST authenticates the resource owner against the identity store and redirects to redirect_uri?code=…&state=…. resource is the MCP endpoint URL the token will target (RFC 8707).
Token
POST /token
Form body: grant_type=authorization_code, code, redirect_uri, client_id, code_verifier.
Response:
{"access_token":"…","token_type":"Bearer","expires_in":3600,"scope":"catalog:read"}
The access token is audience-bound to the requested MCP resource and carries the consented scopes (the intersection of requested scopes and the user's roles/groups). Present it as Authorization: Bearer <token> on the MCP endpoint.
Configuration
Behind a reverse proxy, set RAISINDB_BASE_URL to the canonical external origin so issuer and token audiences stay fixed. X-Forwarded-* headers are honoured only when RAISINDB_TRUST_FORWARDED_HEADERS=1. See the authentication guide.