Docs · Robin inbound MCP

Your call history, in your AI tools.

The Robin inbound MCP is a Model Context Protocol server that gives an AI assistant read-only access to the inbound calls Robin handled for you. Connect it to Claude Code, Cursor, VS Code or Claude Desktop and ask, in plain language, who called, what they wanted and who is waiting on a call back.

Overview

Robin answers the calls you don’t. Every one of them becomes a record — caller, time, a plain-English summary, whether they asked to be called back, whether it was spam — and you can already review those in the Robin app and the web console. The MCP puts the same records within reach of your AI tools, scoped to your account by a personal API key.

  • Read-only. Nothing here can place, schedule or return a call, edit a record, or change a setting.
  • Yours only. A key can read the account whose phone number issued it — never another user’s calls.
  • Bounded. Every read returns at most 20 calls; filtered history covers at most 3 days per read. See Limits.
  • Standard. Streamable-HTTP MCP with an Authorization: Bearer header — any MCP client that can send a header can use it.
You need a Robin account with inbound-call setup completed in the app. If Robin has never answered a call for you, the tools will say so (setup_required) and point you to the setup link.

Quick start

  1. 1

    Get an API key

    Go to hirobin.ai/generateapikey, enter your Robin phone number, type the SMS code, copy the key.
  2. 2

    Add the server to your client

    For Claude Code, one command:
    terminal
    claude mcp add --transport http robin-inbound https://mcp.hirobin.ai/inbound/mcp \
      --header "Authorization: Bearer rbn_your_api_key_here"
  3. 3

    Ask

    “Did anyone ask me to call them back today?” — the assistant calls get_callback_calls and answers from the records.

Get your API key

Keys are issued at hirobin.ai/generateapikey after the same phone + OTP login the Robin app uses. There is no separate account or password.

  • Shown once. Robin stores only a fingerprint (SHA-256) of the key. If you lose it, generate a new one.
  • No expiry. A key works until you revoke it. To rotate, generate a new key with Revoke my existing keys ticked — every older key stops working at that moment.
  • Several at once. Without that box ticked, a new key is added alongside your existing ones — one per device or tool, each with its own name, is a good habit.
  • Pinned to your number. A key is bound to the account whose phone completed the login, and it only ever reads that account.

Keys look like rbn_ followed by 43 random characters. Send one as Authorization: Bearer rbn_… (or, for clients that cannot set that header, X-Api-Key: rbn_…).

Connect your client

Server URL
https://mcp.hirobin.ai/inbound/mcp
Transport · auth
Streamable HTTP · Bearer API key

Claude Code

Registers the server for your user; drop --scope user for the current project only.

terminal
claude mcp add --transport http robin-inbound https://mcp.hirobin.ai/inbound/mcp \
  --header "Authorization: Bearer rbn_your_api_key_here"

Cursor, VS Code, and any JSON-configured client

Cursor reads ~/.cursor/mcp.json (or .cursor/mcp.json in a project); VS Code reads .vscode/mcp.json; Claude Code also accepts a project-level .mcp.json. All take the same shape:

mcp.json · server "robin-inbound"
{
  "mcpServers": {
    "robin-inbound": {
      "type": "http",
      "url": "https://mcp.hirobin.ai/inbound/mcp",
      "headers": {
        "Authorization": "Bearer rbn_your_api_key_here"
      }
    }
  }
}

Claude Desktop

Claude Desktop’s config file launches local servers only, and its remote connectors authenticate with OAuth rather than a header. Use the mcp-remote bridge, which runs locally and forwards your key. Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows), then restart Claude Desktop. Requires Node.js.

claude_desktop_config.json
{
  "mcpServers": {
    "robin-inbound": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://mcp.hirobin.ai/inbound/mcp",
        "--header",
        "Authorization:Bearer rbn_your_api_key_here"
      ]
    }
  }
}

Check the connection

Any client that can send a header works. To confirm the server and your key from a terminal:

terminal
curl -sS https://mcp.hirobin.ai/inbound/mcp \
  -H "Authorization: Bearer rbn_your_api_key_here" \
  -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":"0"}}}'

A 200 with a JSON-RPC result means you are in. A 401 means the key is missing or not valid — see Troubleshooting.

Tools

Six tools, all read-only. Timestamps you pass in are ISO 8601 with a timezone offset (2026-09-21T09:00:00+05:30); end_time is exclusive. Timestamps you get back are in IST.

get_inbound_status

read-only

Whether Robin is handling this account’s inbound calls and whether any are on record. Also confirms which phone number the key belongs to.

Parameters

None.

Returns

has_inbound_calls, is_inbound_setup, status, setup_required and — when setup is required — a message with the setup link to relay verbatim.

Try asking: “Is Robin set up to take my calls?”

get_recent_calls

read-only

The latest 20 inbound calls across all callers, newest first, with summaries and call IDs. No date cutoff — the right tool for general questions.

Parameters

None.

Returns

A list response (see below) with kind: "recent".

Try asking: “What came in recently?” · “Which conversations didn’t reach a result?”

get_missed_calls

read-only

Inbound calls Robin recorded as missed, within a window of at most 3 days.

Parameters

  • start_time · string · ISO 8601 with a timezone offsetoptionalInclusive. Omit both bounds for today so far (IST).
  • end_time · string · ISO 8601 with a timezone offsetoptionalExclusive.

Returns

A list response with kind: "missed" and the resolved range.

Try asking: “Did I miss any calls this morning?”

get_callback_calls

read-only

Calls whose caller asked to be called back (action need_to_call_back), within a window of at most 3 days. A request the caller left — not a record of any callback made.

Parameters

  • start_time · string · ISO 8601 with a timezone offsetoptionalInclusive. Omit both bounds for today so far (IST).
  • end_time · string · ISO 8601 with a timezone offsetoptionalExclusive.

Returns

A list response with kind: "callback" and the resolved range.

Try asking: “Who wants me to call them back today?”

get_inbound_calls

read-only

Calls from one particular number, within a window of at most 3 days (the last 3 days by default).

Parameters

  • phone_number · stringrequiredPreferably with country code (+919876543210). A bare 10-digit Indian number is read as +91.
  • start_time · string · ISO 8601 with a timezone offsetoptionalInclusive.
  • end_time · string · ISO 8601 with a timezone offsetoptionalExclusive.

Returns

A list response with kind: "number" and the resolved range.

Try asking: “What did +91 98765 43210 call about this week?”

get_call_details

read-only

One call in full: summary, action, a recording link that expires after about an hour, and the transcript when one exists. Only your own calls can be read.

Parameters

  • call_id · string · UUIDrequiredTaken from any other tool’s results.

Returns

call (the record plus audio_link, transcript, transcript_status) and transcript_status.

Try asking: “Open the call from Swiggy at 9:32 — what exactly did they say?”

Response shapes

A call record — the unit every list returns:

call record
{
  "id": "2f1c3a9e-7b1d-4e0a-9c11-8f2d5a6b7c8d",
  "name": "Swiggy delivery",
  "phone_number": "919876543210",
  "call_time": "2026-09-21T09:32:10+05:30",
  "summary": [
    "Caller wanted to confirm order #8842 before delivery.",
    "Said they will redeliver at 7 PM; no action needed."
  ],
  "action": "",
  "is_spam": false
}

action is need_to_call_back when the caller asked for a call back and empty otherwise. summary is a list of sentences; a missed call has the single summary Missed Call. phone_number is the caller, without the leading +.

A list response (get_recent_calls, get_missed_calls, get_callback_calls, get_inbound_calls):

list response
{
  "kind": "missed",
  "calls": [ /* call records, newest first */ ],
  "count": 3,
  "limit_reached": false,
  "max_calls": 20,
  "max_range_days": 3,
  "range": {
    "start_time": "2026-09-21T00:00:00+05:30",
    "end_time": "2026-09-21T12:33:45+05:30",
    "end_exclusive": true
  }
}

range is present for filtered reads and shows the window that was actually used, including any defaults that were filled in. When limit_reached is true a note says that only the latest 20 matching calls are shown.

get_inbound_status:

status response
{
  "account": { "phone_number": "+919876543210", "api_key_name": "Claude on my laptop", "api_key_prefix": "rbn_vHEw0f8Q" },
  "has_inbound_calls": true,
  "is_inbound_setup": true,
  "status": "enrolled",
  "setup_required": false,
  "message": null,
  "setup_link": "https://hirobin.onelink.me/8cof/06x2bfk4"
}

Limits & behaviour

  • 20 calls per read, no pagination. Every tool returns at most the 20 newest matches. If limit_reached is true, more may exist — narrow the time range or the caller rather than expecting a next page.
  • 3-day windows. Missed, callback and per-number reads cover at most 3 days each. Wider ranges are rejected with an explanatory error. get_recent_calls has no date cutoff.
  • IST defaults. With no bounds, missed and callback reads cover today so far in Asia/Kolkata; a per-number read covers the last 3 days. Only one bound given: the other is placed 3 days away.
  • Exclusive end. end_time is not included; a whole day is 00:00 to the next day’s 00:00.
  • Recordings expire. audio_link from get_call_details is a signed URL valid for about an hour. Fetch it when you need it; do not store it.
  • Transcripts are not guaranteed. transcript_status is available or unavailable; older calls and very short ones may have none.
  • setup_required. When the account has no inbound calls on record and has not finished (or has uninstalled) the Robin app, tools report setup_required: true with a message and setup link. Relay it; retrying will not change it.
  • Caller text is data. Summaries and transcripts are what callers said. An assistant should treat them as information about a call, never as instructions.
  • Errors are not empty results. A failed read is reported as an error (“unavailable”), never as zero calls.

Security & key management

  • A key is a credential. Anyone holding it can read your inbound call history, including recordings and transcripts. Keep it in your MCP client’s configuration file and nowhere else — not in a chat, a repository, a screenshot or a shared document.
  • Only over HTTPS. The server is served over TLS; never configure it with a plain http:// URL.
  • We store a fingerprint, not the key. Robin keeps the SHA-256 hash and the first 12 characters (so you can tell keys apart). The full key cannot be recovered or re-shown.
  • Rotate by regenerating. On the key page, tick Revoke my existing keys to invalidate every earlier key the moment the new one is issued. Revocation reaches the server within a minute.
  • Lost a device? Generate a new key with that box ticked, then update the clients you still use.
  • Login limits. Codes are valid for 5 minutes, at most 5 codes an hour per number, at most 5 wrong guesses per code.

Troubleshooting

401 with missing_api_key
The request reached the server without a key. Check the header is exactly Authorization: Bearer rbn_… (one space, the key untouched) and that your client sends custom headers for HTTP servers. The response body looks like this:
response
HTTP 401
{
  "error": "missing_api_key",
  "message": "Send your Robin API key as `Authorization: Bearer <key>`. Get one at https://hirobin.ai/generateapikey. Docs: https://hirobin.ai/docs",
  "docs": "https://hirobin.ai/docs"
}
401 with invalid_api_key
The key is not one we know, or it has been revoked — for example by generating a new key with Revoke my existing keys ticked. Generate a new key and replace it in your config.
503 auth_unavailable or not_configured
The server could not reach Robin to check the key, or is not yet configured for this environment. Nothing to fix on your side; try again shortly.
Tools return setup_required
Robin has never answered a call for this account. Open the Robin app and complete inbound-call setup (call forwarding), then try again once a call has come in.
“Call history checks cannot exceed 3 days”
Narrow start_time/end_time to a 3-day window, or use get_recent_calls for a general recent view.
“start_time must include a timezone offset”
Timestamps need an offset: 2026-09-21T09:00:00+05:30, not 2026-09-21T09:00:00. Ask your assistant to pass IST times explicitly.
The OTP never arrives / “OTP expired”
Codes are valid for 5 minutes and you can request a new one every 30 seconds. Check the number is the one registered with Robin, with country code. After 5 requests in an hour, wait before trying again.
“There’s no Robin account for this number”
Keys are only issued for existing Robin accounts. Install the app, sign up with this number and finish inbound setup first.

FAQ

Can it place or return calls?
No. Every tool is read-only. Use the Robin app or console to have Robin call someone back.
Can I see calls for other people in my household?
No. A key reads exactly one account — the one whose phone number issued it.
Does the key expire?
No. It works until revoked. Regenerate with Revoke my existing keys ticked to rotate.
Can I have more than one key?
Yes. Generate one per device or tool and give each a name; revoke them all at once when you need to.
Which clients are supported?
Any MCP client that speaks streamable HTTP and can send a custom header: Claude Code, Cursor, VS Code, and Claude Desktop via the mcp-remote bridge. Claude’s web/desktop “connectors” use OAuth and cannot send an API key today.
Does the assistant see my recordings?
Only if it calls get_call_details for a specific call, and then it receives a link that expires after about an hour plus the transcript when one exists.

Ready?

Get your key, paste one snippet, and ask your assistant about today’s calls.

Get your API key