Quickstart
Mint an API key, make your first call, and connect your first MCP client.
Three steps: get a key, call the API, then point an AI client at it.
1. Create an API key
Open the SuperBooks app and go to Settings → Developer (app.superbooks.io/settings/developer), then create a key.
Pick the narrowest preset that does the job. Read Only is the right choice for anything that only reads — reporting, dashboards, exploration — and it is the safest way to start.
The key is shown once and stored hashed, so copy it now. If you lose it, delete the key and mint a new one.
Keep it in an environment variable rather than in your source:
export SUPERBOOKS_API_KEY="sb_your_api_key_here"2. Make your first request
The API is a single MCP endpoint at https://app.superbooks.io/mcp speaking
JSON-RPC over Streamable HTTP, running in Code Mode: tools/list always
returns exactly two tools, search_tools and execute_typescript, and an AI
assistant uses them to find and call the real SuperBooks tools through Code
Mode. Two calls get you there: initialize to open a session, then
tools/list.
Open a session. The response carries an Mcp-Session-Id header — capture it,
because every later call must send it back.
protocolVersion is the version your client speaks; the server negotiates and
replies with the version it selected, so use whichever your MCP client
implements.
curl -sS -D headers.txt -o initialize.json https://app.superbooks.io/mcp \
-H "Authorization: Bearer $SUPERBOOKS_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": { "name": "curl", "version": "1.0.0" }
}
}'
SESSION_ID=$(grep -i '^mcp-session-id:' headers.txt | tr -d '\r' | awk '{print $2}')Then tell the server the handshake is done. This is a notification, so it has no
id and the server answers 202 with an empty body:
curl -sS https://app.superbooks.io/mcp \
-H "Authorization: Bearer $SUPERBOOKS_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{ "jsonrpc": "2.0", "method": "notifications/initialized" }'Now list the tools (this always returns exactly search_tools and
execute_typescript — see What a client sees):
curl -sS https://app.superbooks.io/mcp \
-H "Authorization: Bearer $SUPERBOOKS_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }'Calling a tool is a two-step round trip through Code Mode: search_tools
returns the external_* declaration, and execute_typescript runs a short
program that calls it. First, find the declaration:
curl -sS https://app.superbooks.io/mcp \
-H "Authorization: Bearer $SUPERBOOKS_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search_tools",
"arguments": { "query": "transactions" }
}
}'Then call it:
curl -sS https://app.superbooks.io/mcp \
-H "Authorization: Bearer $SUPERBOOKS_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "execute_typescript",
"arguments": {
"code": "return await external_transactions_list({ limit: 10 });"
}
}
}'What you should see
tools/list always returns exactly search_tools and execute_typescript —
that never changes with your key's scopes. Scopes instead gate what
search_tools declares and what execute_typescript will actually run: a
Read Only key's search_tools call lists the read tier only, so write and
destructive tools are simply absent from its declarations rather than
present-and-failing. If search_tools returns fewer operations than you
expected, that is scopes doing their job; see How scopes gate the tool
surface.
A 401 means the credential was missing or not recognised. Check that the
header is Authorization: Bearer sb_... and that the key has not been deleted.
3. Connect an AI client
The same endpoint and the same key work directly in Claude Code:
claude mcp add --transport http superbooks https://app.superbooks.io/mcp \
--header "Authorization: Bearer sb_your_api_key_here"Claude Desktop, Cursor, and Windsurf each want their own configuration file, and Claude can also sign in with OAuth instead of a key — no key handling at all. Connecting AI clients covers each one.