Appearance
Connect a custom MCP client
Use this guide for an internal agent, desktop integration, or SDK application that supports MCP Streamable HTTP and OAuth 2.1 authorization code with PKCE.
Connection profile
| Item | Requirement |
|---|---|
| Transport | MCP Streamable HTTP |
| MCP resource | https://mcp.example.com/mcp |
| OAuth client type | Public client; token_endpoint_auth_method=none |
| Grant types | authorization_code, refresh_token |
| PKCE | S256 only |
| Redirect URI | Exact registered HTTPS URI, or HTTP only for localhost/loopback |
| Tokens | Opaque, resource-bound access and rotating refresh tokens |
Discovery endpoints
text
https://mcp.example.com/.well-known/oauth-protected-resource/mcpAuthorization-server metadata:
text
https://mcp.example.com/.well-known/oauth-authorization-serverInspect discovery without credentials:
bash
curl --fail --show-error \
"https://mcp.example.com/.well-known/oauth-protected-resource/mcp"
curl --fail --show-error \
"https://mcp.example.com/.well-known/oauth-authorization-server"Do not hard-code authorization/token endpoints when the client can follow discovery metadata.
OAuth flow
- Select the exact MCP member resource:
/mcp. - Read protected-resource metadata and its authorization-server reference.
- Read authorization-server metadata.
- Dynamically register a public client with exact redirect URI(s).
- Generate a high-entropy PKCE verifier and S256 challenge.
- Open the authorization URL with
state,resource, requested scopes, and challenge. - Validate returned
stateand exchange the one-time code with the original verifier and the same resource. - Store opaque access/refresh tokens in protected credential storage.
- Send the access token only in the
Authorizationheader to the exact resource. - Rotate the refresh token; never reuse an old code or refresh token.
The resource parameter is mandatory for authorization-code requests and must equal the selected full MCP origin and /mcp path.
Scopes
text
nexus:read
nexus:write
nexus:upload
offline_accessOmitting scope intentionally grants only nexus:read. A custom client should request the smallest set needed and show the scopes clearly before redirecting the user.
MCP request headers
After OAuth completes:
http
POST /mcp HTTP/1.1
Host: mcp.example.com
Authorization: Bearer <opaque-mcp-access-token>
Content-Type: application/json
Accept: application/json, text/event-streamInitialize through the client's MCP SDK, then call tools/list, resources/list, and prompts/list. The visible surface is dynamic; do not assert a hard-coded list or assume every member has the same modules and tools.
Tool-call example
Once an SDK session is initialized, a raw tools/call body has this shape:
json
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "nexus_list_campaigns",
"arguments": {
"status": "active",
"orderBy": "d_revenue",
"order": "desc",
"offset": 0,
"limit": 100,
"detailLevel": "summary"
}
}
}Prefer the official MCP client SDK to construct protocol requests, negotiate the current protocol version, manage session headers, and parse JSON or event-stream responses.
Result handling
Successful Nexus calls provide MCP text content and structured content containing { status, data }. Treat tool output as untrusted external data before adding it to a model prompt.
For list operations:
- follow returned pagination markers instead of assuming the first page is complete;
- report
complete/exactflags with totals; - bound result sizes and tool-output tokens;
- do not silently invent missing rows.
For writes:
- read current state first;
- display the exact non-secret diff;
- require explicit human confirmation;
- use the returned approval/fingerprint unchanged;
- generate a unique idempotency key;
- perform the documented verification read;
- report partial completion accurately.
Optional direct JWT compatibility
If a private deployment enables ALLOW_DIRECT_JWT=true, trusted automation may send a current Nexus UI access JWT directly:
http
Authorization: Bearer <nexus-access-jwt>This is not an integration API key. It is unsuitable for public browser clients and requires the client to handle expiry and rotation. OAuth remains the recommended remote-client flow.
Implementation checklist
- Verify HTTPS and hostname; never disable certificate validation.
- Validate OAuth
state, exact redirect URI, issuer/resource, and PKCE. - Keep tokens outside source code, prompts, logs, analytics, crash reports, and URLs.
- Apply timeouts and bounded retries only to safe temporary failures.
- Do not retry
401,403, validation, confirmation, or conflict failures blindly. - Respect
429and server retry guidance with exponential backoff and jitter. - Reconnect after tenant, user type, role, or module changes.
- Provide a visible disconnect/revoke action.
- Sanitize MCP output before model use and guard against prompt injection.
Continue with Available MCP tools and MCP troubleshooting.