Connecting an AI Assistant via MCP
Blocx exposes a Model Context Protocol server at https://api.otterblocx.com/mcp. Any MCP-compatible client — Claude Desktop, Claude.ai, Cursor, custom agents — can connect with an API key and read your tenant's brands, campaigns, phone numbers, and balance history through a small set of typed tools.
The MCP endpoint is read-only and scoped to the tenant that owns the API key. There is no way for an assistant to reach another organization's data through it.
Endpoint
POST https://api.otterblocx.com/mcp
The endpoint speaks the Streamable HTTP transport in stateless JSON mode. One request, one JSON-RPC response — no SSE stream, no session IDs to manage.
Authentication
Create an API key at API Keys (see Managing API Keys) and pass it as a single Bearer token:
Authorization: Bearer <accessKeyId>:<secretAccessKey>
The two parts are separated by a colon. Most MCP clients only let you set one header, which is why this composite form exists. If your client gives you full header control you can use the API-key pair instead:
x-access-key-id: <accessKeyId>
x-secret-access-key: <secretAccessKey>
Both forms work identically. Scope the key with a permission set if you only want the assistant to see a subset of resources.
Available tools
| Tool | What it returns |
|---|---|
whoami |
The tenant the session is bound to: id, name, balance, email-enabled state, auto-recharge state |
brand_list |
Recent brands, newest first |
brand_get |
One brand by id, including identity verification state and any registration error |
campaign_list |
Recent campaigns, filterable by provisioning status (PENDING, ACTIVE, REJECTED, SUSPENDED, EXPIRED) |
campaign_get |
One campaign by id, including sharing state and any rejection or suspension context |
phone_number_list |
Phone numbers, filterable by status (UNASSIGNED, ASSIGNED, ACTIVE, RELEASED) |
balance_recent_actions |
Recent credit/debit balance actions; amounts are in micro-USD (1_000_000 = $1) |
All tools are read-only. There is no *_create, *_update, or *_delete — to make changes use the REST API.
Quick check with curl
initialize then tools/list:
curl -s -X POST https://api.otterblocx.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $BLOCX_ACCESS_KEY_ID:$BLOCX_SECRET_ACCESS_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": { "name": "curl", "version": "0" }
}
}'
curl -s -X POST https://api.otterblocx.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $BLOCX_ACCESS_KEY_ID:$BLOCX_SECRET_ACCESS_KEY" \
-d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }'
Call whoami:
curl -s -X POST https://api.otterblocx.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $BLOCX_ACCESS_KEY_ID:$BLOCX_SECRET_ACCESS_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": { "name": "whoami", "arguments": {} }
}'
Claude Desktop
Add the server to your Claude Desktop claude_desktop_config.json using the mcp-remote proxy (Claude Desktop only speaks stdio natively, so the proxy bridges to HTTP):
{
"mcpServers": {
"blocx": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.otterblocx.com/mcp",
"--header",
"Authorization: Bearer ${BLOCX_ACCESS_KEY_ID}:${BLOCX_SECRET_ACCESS_KEY}"
],
"env": {
"BLOCX_ACCESS_KEY_ID": "<your access key id>",
"BLOCX_SECRET_ACCESS_KEY": "<your secret>"
}
}
}
}
Restart Claude Desktop. The Blocx tools appear in the tool picker and Claude can call them.
Cursor and other Streamable-HTTP clients
Clients that natively speak Streamable HTTP can point at the endpoint directly. In Cursor, add to your MCP settings:
{
"mcpServers": {
"blocx": {
"url": "https://api.otterblocx.com/mcp",
"headers": {
"Authorization": "Bearer <accessKeyId>:<secretAccessKey>"
}
}
}
}
What an assistant can do for you
A few examples that work out of the box:
- "Which of my campaigns are still pending?" —
campaign_listwithprovisioningStatus: PENDING. - "Show me the last 10 charges on my account." —
balance_recent_actionswithtype: DEBIT. - "What's the identity status of every brand I have?" —
brand_list, thenbrand_getfor the rejected ones. - "How many active phone numbers do I have?" —
phone_number_listwithstatus: ACTIVE.
For anything that requires writing — registering a brand, sending a message, topping up — the assistant will tell you to use the dashboard or the REST API directly.
Safety notes
- Tenant isolation is enforced server-side. Every tool query is filtered by the tenant id the API key resolves to. There is no
tenantIdargument an assistant can pass. - Treat the API key like a password. Anyone with the key can see everything the assistant sees. Use a permission set to narrow scope further.
- Rotate the key if you ever paste it into a chat window with an assistant you don't control. See Managing API Keys.