Build a Custom MCP Client

Connect a custom client to the Demandbase Model Context Protocol (MCP) server using OAuth Dynamic Client Registration (DCR), the Authorization Code flow with PKCE, and MCP Streamable HTTP.

The configuration is language agnostic. You can implement it with any HTTP client, JSON parser, browser launcher, hosted HTTPS redirect handler, and secure token store.


Prerequisites for Connecting a Custom Client to Demandbase MCP

Before you connect a custom client to Demandbase MCP, make sure you have:

  • A valid Demandbase user account.
  • A hosted HTTPS redirect URI for your application.
  • A secure location to store OAuth client credentials and access tokens.
  • Demandbase MCP enabled for your organization. Contact your Demandbase Account Team or Demandbase Support if Demandbase MCP is not enabled.

Important: During configuration, Demandbase Support must allowlist the exact redirect URI for your client_id (application ID).


Demandbase MCP Endpoints for Custom Clients

Use the following public Demandbase MCP endpoints to configure your custom client:

EndpointURL
MCP serverhttps://gateway.demandbase.com/mcp/servers/db-mcp
Protected resource metadatahttps://gateway.demandbase.com/.well-known/oauth-protected-resource

Important: Do not hardcode the authorization or token endpoints. Discover them from the OAuth metadata.


Step 1: Configure an HTTPS Redirect URI

Configure the HTTPS redirect URI that Demandbase uses to return the user to your application after authorization.

Example:

https://your-app.example.com/oauth/demandbase/callback

The redirect URI must match exactly. The scheme, host, path, and trailing slash are all significant.

For example, the following are different redirect URIs:

https://your-app.example.com/oauth/demandbase/callback
https://your-app.example.com/oauth/demandbase/callback/

Step 2: Discover the Demandbase OAuth Metadata

  1. Fetch the protected resource metadata:
GET https://gateway.demandbase.com/.well-known/oauth-protected-resource
Accept: application/json
  1. Retrieve the following values:
  • resource
  • authorization_servers
  • scopes_supported
  1. Request the authorization server metadata using the advertised authorization server.

    Current metadata endpoint:
GET https://gateway.demandbase.com/.well-known/oauth-authorization-server
Accept: application/json
  1. Retrieve the following values:
  • issuer
    Important: Store client registrations and tokens using the issuer as the key.
  • authorization_endpoint
  • token_endpoint
  • registration_endpoint
  • token_endpoint_auth_methods_supported
  • scopes_supported

Step 3: Register the Custom Client

Register your application using the discovered registration_endpoint to obtain a client_id, which serves as the application ID.

Example:

POST {registration_endpoint}
Accept: application/json
Content-Type: application/json

{
  "client_name": "Your MCP Client",
  "application_type": "web",
  "redirect_uris": ["https://your-app.example.com/oauth/demandbase/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none",
  "scope": "openid profile email offline_access"
}

Example response:

The registration response includes the values required to identify and authenticate the client.

{
  "client_id": "0oaexampleclientid",
  "redirect_uris": ["https://your-app.example.com/oauth/demandbase/callback"],
  "token_endpoint_auth_method": "none",
  "scope": "openid profile email offline_access"
}

Store the following values securely:

  • client_id
  • redirect_uris
  • token_endpoint_auth_method
  • scope
  • client_secret (if issued)

Step 4: Allowlist the OAuth Redirect URI

Ask Demandbase Support to allowlist your redirect URI before testing authentication.

Provide Demandbase Support with:

  • Your client_id (application ID)
  • Your exact HTTPS redirect URI

Important: The OAuth flow cannot succeed until Demandbase Support allowlists the redirect URI for your application.

Step 5: Authenticate with PKCE

  1. Generate the PKCE values:
code_verifier = high_entropy_random_string
code_challenge = base64url(sha256(code_verifier))
code_challenge_method = S256
  1. Generate and store a random state value with the code_verifier.
  2. Build the authorization URL:
{authorization_endpoint}
  ?response_type=code
  &client_id={client_id}
  &redirect_uri={url_encoded_redirect_uri}
  &scope=openid%20profile%20email%20offline_access
  &state={state}
  &code_challenge={code_challenge}
  &code_challenge_method=S256
  &resource={url_encoded_resource}
  1. Open the authorization URL in the user's browser.

Step 6: Handle the OAuth Callback

After authentication, Demandbase redirects the browser to your hosted redirect URI:

{redirect_uri}?code={authorization_code}&state={state}

Complete the following actions:

  1. Validate the state value.
  2. Reject OAuth error responses.
  3. Extract the authorization code.
  4. Exchange the authorization code immediately.
  5. Discard the temporary state and code_verifier after the exchange.

Step 7: Exchange the Authorization Code for Tokens

Exchange the authorization code for OAuth tokens using the discoveredtoken_endpoint:

POST {token_endpoint}
Accept: application/json
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code={authorization_code}&
redirect_uri={exact_redirect_uri}&
client_id={client_id}&
code_verifier={code_verifier}

Store the following values securely:

  • access_token
  • refresh_token, if returned
  • expires_at
  • scope
  • issuer
  • client_id

When the access token expires, send the refresh token to the same discovered token_endpoint:

POST {token_endpoint}
Accept: application/json
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&
refresh_token={refresh_token}&
client_id={client_id}

Refresh tokens may rotate. If the response includes a new refresh token, replace the previous one.

Step 8: Send Requests to the Demandbase MCP Server

Send authenticated JSON-RPC requests to the Demandbase MCP server:

https://gateway.demandbase.com/mcp/servers/db-mcp

Use the following headers:

Authorization: Bearer {access_token}
Content-Type: application/json
Accept: application/json, text/event-stream

If the server returns an MCP session ID during initialization, include it in subsequent requests.

Important: Always use tools/list as the authoritative source for current tool names, descriptions, and input schemas.

Initialize the MCP Connection

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {},
    "clientInfo": {
      "name": "your-mcp-client",
      "version": "1.0.0"
    }
  }
}

Retrieve the Available Demandbase MCP Tools

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list",
  "params": {}
}

Call a Demandbase MCP Tool

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "company_global_directory",
    "arguments": {
      "company_name": "Demandbase"
    }
  }
}

Step 9: Parse Demandbase MCP Responses

Parse each Demandbase MCP response based on the returned content type:

Content TypeResponseAction
application/jsonSingle JSON-RPC responseParse the response as JSON.
text/event-streamServer-Sent Events (SSE) containing JSON-RPC messagesCollect the data: lines for each event, parse the combined event data as JSON, and continue until the final JSON-RPC response is received.

Always check for a JSON-RPC error object, even when the HTTP status is 200 OK.

A successful implementation confirms that your custom client can authenticate an authorized Demandbase user and invoke available Demandbase MCP tools.


Troubleshoot a Custom Demandbase MCP Client

IssueResolution
Redirect URI errorVerify that Demandbase Support allowlisted the exact redirect URI for your client_id
DCR returns 401 or 403The registration endpoint may require additional authorization. Contact Demandbase Support.
Token exchange returns invalid_grantThe authorization code may have expired, already been used, or be associated with a different redirect URI or PKCE verifier. Restart the authentication flow.
MCP request returns 401Refresh the access token or re-authenticate.
MCP request returns 403Verify that Demandbase MCP is enabled for the account and user.
Tool validation errorRefresh the tool definition using tools/list and verify that the request matches the tool's inputSchema

References for Building a Custom Demandbase MCP Client


Did this page help you?