Skip to main content
Connecting takes three things: the server URL, your API key, and a client that speaks MCP. This page covers the setup for the most common clients, how to confirm it worked, and what to do when it doesn’t.

Before you start

1

Get your API key

Go to Settings → Developer → API Keys and create a key, or follow How to get your API key. It looks like calid_ followed by a long string.
2

Copy the server URL

Every client uses the same endpoint:
3

Have your client ready

Install or open the app you want to connect, and find where it manages MCP servers or connectors.
In every example below, replace calid_xxx with your real key. Treat it like a password — don’t commit it to a repository or paste it into a shared document.

Set up your client

Open Settings → Developer (or Connectors), add a custom MCP server, and use this configuration:
Save, then restart Claude Desktop if the server doesn’t appear right away.
If the direct setup isn’t accepted, use the mcp-remote bridge instead. It runs a small local process that forwards to the hosted server:
The bridge needs Node.js installed.
Copy Authorization:${AUTH_HEADER} exactly — there is no space after the colon. It looks like a typo, and it isn’t. mcp-remote splits the --header value on the first colon, and on Windows and inside Cursor a space there breaks the argument, so the header never reaches the server.Two more things that go wrong here:
  • --header is the only way to send a header. There is no MCP_REMOTE_HEADER_AUTHORIZATION environment variable. If you set one, mcp-remote ignores it and connects unauthenticated — and the connection still looks healthy, because tools still list. See Verify the connection.
  • The env block is what keeps your key out of the process list. mcp-remote substitutes ${AUTH_HEADER} from env at launch. You can inline the key in args instead, but then it shows up in your shell history and process table.

Verify the connection

A connected server does not mean an accepted key. Cal ID does not check your credentials during initialize or tools/list. A completely made-up key gets a 200, gets a session ID, and gets all 58 tools listed back. Your client will show calid as connected, with a full tool list, whether or not your key is real.The key is only checked when a tool actually runs. So seeing the tools appear tells you the URL and transport are right — and nothing at all about your authentication.
The only real check is to call a tool. Use get_users_me: it reads your own profile, changes nothing, and needs no arguments. The quickest version is conversational: open a new chat and ask “Who am I in Cal ID?” If your own name and email come back, your key works. If the assistant reports an error from the tool, the key is the first thing to suspect.

Check it manually

Useful when a client fails silently, or when support asks what the server returned.
1

Open a session

The response identifies the server and returns a session ID in the mcp-session-id response header:
Copy the mcp-session-id value out of the response headers. This step succeeds with any key, including a fake one — it proves the endpoint is reachable, nothing more.
2

List the tools (optional)

Pass the session ID back to see what the server offers:
All 58 tools come back. This also succeeds with a fake key — skip it if all you want to know is whether you’re authenticated.
3

Call get_users_me — this is the real test

Your key works when the result object’s first content block reports a 200 and your profile follows in the second:
Your key is rejected when isError is true and the first content block reports a 401:
An auth failure arrives as a tool result, not as an HTTP error. The tools/call request itself returns 200 OK. The 401 is text inside the JSON-RPC result, flagged by isError: true. Anything that only inspects HTTP status codes — a health check, a retry wrapper, a client’s connection indicator — will read a rejected key as a success. Check isError and read content[0].
Responses stream as server-sent events, so each payload arrives on a line beginning with data: . That’s expected — it isn’t an error.

Troubleshooting

This is what a bad or missing key looks like — the server connects and lists all 58 tools, then rejects the first real call with HTTP 401 GET /users/me and isError: true.
  • Confirm the header is Authorization: Bearer calid_xxx — the word Bearer, one space, then the key.
  • Check for a trailing space or line break from copy-paste.
  • Confirm the key still exists under Settings → Developer → API Keys.
  • If you use mcp-remote, check that the key is passed with --header, not through an environment variable like MCP_REMOTE_HEADER_AUTHORIZATION. That variable does nothing, and the bridge will connect without any credentials at all. See the Claude Desktop tab.
  • Also with mcp-remote, check there is no space after the colon in Authorization:${AUTH_HEADER}.
Cal ID accepts the key only as a Bearer token. Appending ?apiKey= to the URL will not authenticate.
Usually the client hasn’t finished the MCP handshake, or it isn’t sending the Accept header the server requires.
  • Send Accept: application/json, text/event-stream. Both values are mandatory. Sending only application/json returns 406 with the message Client must accept both, and most clients surface that as an empty tool list rather than an error.
  • Restart the client fully, then reopen it.
  • Make sure the URL ends in /mcp, not / or /docs.
  • If your client needs stdio, switch to the mcp-remote bridge.
An empty tool list is never an authentication problem — auth is not checked until a tool runs.
Almost always JSON syntax — a missing comma, a stray trailing comma, or unbalanced braces. Paste the config into a JSON validator before saving.
eventTypeId is a string for get_slots and a number for create_booking, so the slots-then-book flow needs it converted in between: "106371" for slots, 106371 for the booking.If you’re prompting conversationally you’ll rarely hit this. If you’re calling tools directly, see the type gotchas.
Every write tool nests its arguments under a body object. Sending the fields at the top level fails validation before the request reaches the API. See the body wrapper.
You’re trying to book a time that isn’t actually on offer. You cannot calculate bookable times yourself — a slot that looks valid can still be rejected.Always call get_slots first and book one of the times it returns. See Booking through MCP.
Claude Desktop and Cursor have the broadest MCP support and are the easiest to get working. ChatGPT connectors depend on your plan and workspace permissions.
Still stuck? Ask the assistant on this site, or start a live chat from the widget in the corner. Include the get_users_me result from the manual check above — with your key redacted — since that’s the step that shows whether you’re authenticated.

MCP tools and API access

Tool reference

Every tool, what it maps to, and the gotchas worth knowing.

MCP overview

What MCP can and can’t do, and how permissions work.

Manage API keys

Rotate or revoke the key your assistant is using.

REST API reference

Call the same endpoints directly from your own code.