Connecting over MCP
The endpoint
The MCP server is at /mcp on the origin you are reading this from. It speaks
Streamable HTTP. POST /mcp carries the JSON-RPC messages; GET and DELETE
are answered with a JSON-RPC "method not allowed" error.
Reach exactly /mcp, with no trailing slash. A token is issued for that exact
resource, and its audience is checked against it.
The credential
/mcp accepts one credential: an OAuth access token issued for it, sent as
Authorization: Bearer <access-token>. An API key is not accepted here; it is
for the API. A token issued for any other audience is refused, and no
token is passed through to anything else.
Discovery
A request with no token, or a token that is refused, is answered 401 with a
WWW-Authenticate header that points at the protected resource metadata
(RFC 9728):
WWW-Authenticate: Bearer resource_metadata="<origin>/.well-known/oauth-protected-resource/mcp"
A client follows it:
/.well-known/oauth-protected-resource/mcpnames the resource and the authorization server that issues tokens for it./.well-known/oauth-authorization-servernames that server's authorization, token and registration endpoints and its key set (RFC 8414).
Authorization: OAuth 2.1 with PKCE
A client that supports MCP authorization runs this on its own:
- Read the protected resource metadata, then the authorization server's.
- Register: by dynamic client registration, or with a client ID metadata document. Both are in authentication.
- Run the authorization-code flow with PKCE (
S256, required), with theresourceparameter (RFC 8707) set to the MCP endpoint, so the token is bound to it. - A person signs in, or signs up, and approves the client on the consent page.
- Exchange the code for an access token, and call
/mcpwith it. Use the refresh token when the access token expires.
A tool call that needs a scope the token lacks is answered 403 with an
insufficient_scope challenge naming the scopes. Authorize again asking for
them.
Calling the server
With a token, negotiate with initialize, list tools with tools/list and
call one with tools/call.
- Start with
help_exploreand no arguments. It returns the top help page: every service with its status for your account, a quick start for each one you have on, and a table of help pages with their ids. Call it again with{"helpPageId": "<id>"}from that table to read a page. An id you were not shown answers not found. services_listshows every service and whether it is on.services_enablewith"trial": truestarts a free trial.- A service's own tools are reached through toolsets:
toolsets_listshows the toolsets you have on,toolsets_opengives a toolset's tools and their schemas, and the call tool that a tool'scallWithnames calls it:toolsets_calltool_read,toolsets_calltool_writeortoolsets_calltool.
Testing the connection
List the tools with curl. Set ORIGIN to the origin you are reading this
from and TOKEN to an access token issued for /mcp:
curl -X POST "$ORIGIN/mcp" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }'
Without a token, the same call shows the 401 and its WWW-Authenticate
header. The MCP Inspector (npx @modelcontextprotocol/inspector) runs the
whole flow, from discovery to a tool call, against /mcp.