Connecting Claude Code
PalmaPlan serves its MCP server over HTTP, with full OAuth 2.1 — Claude Code connects to it in one command, with no token prepared ahead of time:
claude mcp add --transport http palmaplan <address>/mcp
Replace <address> with your instance's — for example http://127.0.0.1:4785 locally, or a self-hosted instance's public address.
What follows is described step by step from a real trial: real Claude Code, against a real PalmaPlan server, on 2026-09-21 (sprint 14 journal, lot L0a). It isn't a theoretical description of the protocol — it's what actually happened, with the two caveats found along the way.
What happens, in order
- Claude Code registers itself. With no token supplied, the client detects it needs one and registers with the authorization server (
POST /oauth/register, RFC 7591) — this is dynamic registration: nothing to create by hand on PalmaPlan's side, each client (Claude Code, Claude Desktop, another agent) gets its ownclient_id. - Your browser opens on
GET /oauth/authorize, with PKCE (S256, mandatory) and the targeted resource (<address>/mcp). If you have no open session in that browser, PalmaPlan first takes you to the login page (/login?next=…) — sign in, or take ownership of the instance if this is its very first time (/setup); authorization then resumes exactly where it left off. - The "Authorize?" page — consent. It names the client ("Claude Code"), who you are, and the requested scopes (read, write, or both). Denying sends Claude Code back with
access_denied: nothing is created, no token exists. Authorizing issues a single-use code (ten minutes), which the browser redirects to the local port Claude Code is listening on. - Claude Code exchanges this code for a token (
POST /oauth/token, PKCE verified). The token received is a named token like any other — "MCP · Claude Code" — valid for thirty days, refreshing itself automatically for ninety (a single-use refresh, a fresh pair each time). It appears immediately under Settings › Connections and agents › Connected applications, revocable there exactly like a hand-created token; what this client writes is attributed to Claude (you). - Claude Code confirms: "Authentication successful. Connected to
<client-name>." — the/mcpsession is alive, the conversation can call the 98 model tools (Claude Code does not render MCP Apps views: the three view-only tools are not listed to it — see The embedded view).
With a token already created
If a named token already exists (created from Settings › Connections and agents › Advanced access, or by another session), Claude Code can take it directly rather than replaying OAuth:
claude mcp add --transport http --header "Authorization: Bearer pp_…" palmaplan <address>/mcp
This is the path stdio uses out of necessity (Claude Desktop); over HTTP it remains optional, a shortcut for anyone who prefers creating the token by hand rather than opening a browser.
When it stalls
- The server answers 401 without ever opening a browser:
POST /mcpwith no Bearer answers401withWWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource"— that's expected, it's what triggers OAuth discovery. If the browser still doesn't open, check that Claude Code is running in an environment that can launch a browser (not a purely remote, display-less session). redirect_urirefused: PalmaPlan only acceptshttps, orhttpto the loopback address (localhost,127.0.0.1,[::1]) — exactly what Claude Code uses for its callback port. If the error still appears, the address given in<address>likely doesn't matchPALMAPLAN_PUBLIC_URLas the server knows it.- The token no longer works: a token revoked from Settings › Connections and agents › Connected applications closes its
/mcpsession immediately (not only on the next call);claude mcp remove palmaplanthen a freshaddrecreates the relationship from scratch. - Two entries appear among registered clients: dynamic registration is open, and one extra round trip (a resumed attempt, a cancelled trial) can create a second
client_id— harmless, the hourly purge takes care of it; it isn't a duplicated token.
What the real trial found (and what has changed since)
Two caveats noted on 2026-09-21:
- The model calling tools through this exact session wasn't replayed on that occasion (the trial machine had no open Claude session) — the OAuth mechanics and the
/mcpsession itself, however, were. That point is covered elsewhere by the sprint 13 recette (a real SDK call). - Two additional RFC 8414 probes —
/.well-known/oauth-authorization-server/mcpand/.well-known/openid-configuration/mcp, the "path-suffixed" variants Claude Code queries before falling back to the root — received a404during that trial. This has been fixed since: the server now serves the same document at all three addresses (the root and the two suffixed variants), two fewer 404s on the real path.
The trial's third observation (two lines created among registered clients) isn't a defect: it's the normal noise of open dynamic registration, purged every hour.