Skip to content

MCP Clients

Nodexa exposes MCP-compatible tools through the admin interface. MCP clients connect to the admin origin, not directly to the backend.

Endpoint

Use this endpoint for the built-in Nodexa tools:

https://your-admin.example.com/mcp-gateway/nodexa

For local testing:

http://localhost:4000/mcp-gateway/nodexa

Do not add /api to this path. The admin interface proxies /mcp-gateway/* to the backend and keeps the backend URL private.

Authentication

MCP clients authenticate with standard OAuth bearer tokens. The gateway publishes OAuth Protected Resource Metadata at:

https://your-admin.example.com/mcp-gateway/nodexa/.well-known/oauth-protected-resource

The Keycloak client used by MCP clients is:

nodexa-mcp

This client should be a public OAuth client using Authorization Code + PKCE.

Keycloak Setup

Create the MCP OAuth client in the same Keycloak realm used by the Nodexa backend.

For Nodexa Cloud, the realm issuer is:

https://auth.nodexa.cloud/realms/nodexa-cloud

In Keycloak Admin Console:

  1. Select the nodexa-cloud realm.
  2. Open Clients.
  3. Create or update a client with Client ID nodexa-mcp.
  4. Use OpenID Connect.
  5. Set Client authentication to Off. This must be a public client.
  6. Enable Standard flow.
  7. Disable Direct access grants for production.
  8. Set PKCE Code Challenge Method to S256.
  9. Add valid redirect URIs:
http://localhost:*
http://127.0.0.1:*

For local Claude Code testing, the redirect URI uses a random localhost port, for example:

http://localhost:55042/callback

The wildcard redirect above allows those dynamic callback ports.

If Keycloak still rejects the redirect during testing, add the exact callback URI shown in the browser error, for example:

http://localhost:56963/callback

Set Web origins to:

+

or explicitly:

http://localhost:*
http://127.0.0.1:*

Protocol Mappers

The access token issued to MCP clients must contain the same organization and audience claims that the backend validates.

Add a Group Membership mapper:

Setting Value
Mapper type Group Membership
Token claim name groups
Add to access token On
Full group path On

This lets the backend derive the organization from group paths such as:

/nanndoj

Add an Audience mapper so tokens issued to nodexa-mcp are accepted by the backend:

Setting Value
Mapper type Audience
Included Client Audience nodexa-cloud-backend
Add to access token On

The backend should also accept the MCP client as an additional audience:

OIDC_CLIENT_ID=nodexa-cloud-backend
OIDC_EXTRA_AUDIENCES=nodexa-mcp
OIDC_VALIDATE_AUDIENCE=true
OIDC_GROUPS_CLAIM=groups

If your backend client ID is different, use that client ID in both the audience mapper and OIDC_CLIENT_ID.

Claude Code

Remove any old Nodexa MCP server entry, then add the new gateway endpoint:

claude mcp remove nodexa -s local
claude mcp add-json nodexa '{"type":"http","url":"http://localhost:4000/mcp-gateway/nodexa","oauth":{"clientId":"nodexa-mcp"}}' -s local

For production, replace the URL with your admin origin:

claude mcp add-json nodexa '{"type":"http","url":"https://your-admin.example.com/mcp-gateway/nodexa","oauth":{"clientId":"nodexa-mcp"}}' -s local

Verify the configured URL:

claude mcp get nodexa

On first use, Claude Code should start the OAuth flow and redirect you to Keycloak.

Quick HTTP Check

Without a token, the endpoint should return 401 Unauthorized and include a WWW-Authenticate header pointing to the metadata URL:

curl -i -X POST http://localhost:4000/mcp-gateway/nodexa \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'

Troubleshooting

Keycloak shows client not found

This means Keycloak could not find an enabled client with:

client_id=nodexa-mcp

in the configured realm. Check that the client exists in the nodexa-cloud realm and that the client ID is exactly nodexa-mcp.

Keycloak shows invalid redirect_uri

Add the callback URI used by the MCP client. Claude Code uses a random localhost port:

http://localhost:*
http://127.0.0.1:*

If you previously configured http://localhost:*/callback, replace it with http://localhost:*. Keycloak wildcard matching is safest when the * is at the end of the URI pattern. You can also add the exact URI from the error page temporarily, for example http://localhost:56963/callback.

The backend rejects the token

Check the access token claims. It must include:

  • groups, with the user's organization group path
  • an audience accepted by the backend, usually nodexa-cloud-backend and/or nodexa-mcp

Decode the token locally:

echo "$TOKEN" | jq -R 'split(".")[1] | @base64d | fromjson | {aud, azp, groups}'

OAuth metadata points to the wrong host

The metadata response should use the admin origin, not the backend origin:

{
  "resource": "http://localhost:4000/mcp-gateway/nodexa"
}

If it shows localhost:3001, the request is reaching the backend directly instead of the admin proxy.