Claude Code
Use this guide to connect Claude Code to the Calculator server you secured in Secure Your MCP Server, using Dynamic Client Registration (DCR) so Claude Code registers itself as an OAuth client automatically.
What You Will Learn
- Connect Claude Code to the scope-protected Calculator server
- Enable Dynamic Client Registration so Claude Code registers its own OAuth client
- See scope enforcement from Claude Code's seat
Prerequisites
- About 5 minutes
- Completed Secure Your MCP Server: the Calculator server registered and runnable, and
thunderid.certexported
- Claude Code installed
Run ThunderID and the Calculator Server
This guide continues directly from Secure Your MCP Server. If ThunderID and the Calculator server from that guide are not already running, start them again.
Run ThunderID with the method you chose there, then start the Calculator server from the same directory as server.py:
uv run server.py
The server listens at http://localhost:8000/mcp.
Enable Dynamic Client Registration
MCP Inspector connected with the Client ID of an application you registered in the Console. Claude Code registers its own OAuth client automatically through Dynamic Client Registration (DCR) instead, so enable DCR before connecting it. Add the following to deployment.yaml in your ThunderID distribution:
oauth:
dcr:
enabled: true
insecure: true
insecure: true lets anyone who can reach the server register OAuth clients without authentication. Use it for local development only.
Restart ThunderID after saving the file.
Optionally, confirm DCR is live before connecting Claude Code by registering a throwaway public client directly:
curl -sk -i -X POST https://localhost:8090/oauth2/dcr/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "dcr-probe",
"redirect_uris": ["http://localhost:52344/callback"],
"grant_types": ["authorization_code"],
"response_types": ["code"],
"token_endpoint_auth_method": "none"
}'
HTTP/1.1 201 Created
{
"app_id": "019fa36e-6b16-7908-9bc9-d848c00db406",
"client_id": "ZjWMmW04V6ZCl1xKR70FuQ",
"client_name": "dcr-probe",
"client_secret_expires_at": 0,
"grant_types": ["authorization_code"],
"redirect_uris": ["http://localhost:52344/callback"],
"response_types": ["code"],
"token_endpoint_auth_method": "none"
}
A 201 response with a client_id and no client_secret confirms DCR accepted the registration. Before you set insecure: true, the same request returns 401 unauthorized_client. The dcr-probe client this creates appears in Applications.
Running the command again returns a 400 error because an application named dcr-probe already exists; delete it in the Console to repeat the check.
Connect Claude Code
Add the Calculator server, from the same directory as server.py:
claude mcp add --transport http calculator http://localhost:8000/mcp
Start Claude Code, reusing the exported certificate so its Node.js runtime trusts ThunderID's TLS connection:
NODE_EXTRA_CA_CERTS=./thunderid.cert claude
-
Inside Claude Code, run
/mcp. -
Choose the
calculatorserver and authenticate. -
A browser tab opens with ThunderID's sign-in page. Sign in with your test user.
-
Back in Claude Code, ask it to run both tools:
"Add 7 and 5, then divide 10 by 4."
Claude Code calls the
addanddividetools and returns the results.
You never registered an application for Claude Code in the Console. DCR did that automatically the moment Claude Code first connected: open Applications and you find the client Claude Code registered, alongside Calculator Inspector.
Claude Code only sees the tools your token's scopes allow, the same as Inspector. Try it: in the Console, open the Calculator role, remove the divide permission, then run /mcp in Claude Code again and re-authenticate. Ask Claude to divide two numbers again: it can no longer call the tool, because your token no longer carries the divide scope.
What's Next
Check out the complete Calculator MCP Sample in the ThunderID repository.