Skip to content

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

ItemRequirement
TransportMCP Streamable HTTP
MCP resourcehttps://mcp.example.com/mcp
OAuth client typePublic client; token_endpoint_auth_method=none
Grant typesauthorization_code, refresh_token
PKCES256 only
Redirect URIExact registered HTTPS URI, or HTTP only for localhost/loopback
TokensOpaque, resource-bound access and rotating refresh tokens

Discovery endpoints

text
https://mcp.example.com/.well-known/oauth-protected-resource/mcp

Authorization-server metadata:

text
https://mcp.example.com/.well-known/oauth-authorization-server

Inspect 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

  1. Select the exact MCP member resource: /mcp.
  2. Read protected-resource metadata and its authorization-server reference.
  3. Read authorization-server metadata.
  4. Dynamically register a public client with exact redirect URI(s).
  5. Generate a high-entropy PKCE verifier and S256 challenge.
  6. Open the authorization URL with state, resource, requested scopes, and challenge.
  7. Validate returned state and exchange the one-time code with the original verifier and the same resource.
  8. Store opaque access/refresh tokens in protected credential storage.
  9. Send the access token only in the Authorization header to the exact resource.
  10. 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_access

Omitting 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-stream

Initialize 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/exact flags 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 429 and 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.

White-label Nexus API documentation