Build an integration
Connect your app to Gummble MCP on behalf of your users with OAuth 2.1, DCR, PKCE, and refresh tokens.
This guide is for developers building an app that calls Gummble's MCP server on behalf of their users. Each user authorizes with their own Gummble account, and your app makes MCP requests using that user's access token.
If you just want to connect an existing MCP client like Claude, Cursor, or Windsurf, start with MCP Overview.
Requirements
Your users need a Gummble Pro, Team, or Enterprise plan. There is no separate fee for integrators.
Use an MCP SDK when possible. Modern SDKs can handle discovery, Dynamic Client Registration, PKCE, token refresh, and MCP request retry behavior for you.
Endpoints
| Endpoint | Purpose |
|---|---|
https://mcp.gummble.com/.well-known/oauth-protected-resource/mcp | Protected Resource Metadata |
https://api.gummble.com/.well-known/oauth-authorization-server | Authorization Server Metadata |
https://api.gummble.com/oauth/register | Dynamic Client Registration |
https://api.gummble.com/oauth/authorize | User authorization and consent |
https://api.gummble.com/oauth/token | Authorization code and refresh token exchange |
https://api.gummble.com/oauth/revoke | Refresh token revocation |
https://mcp.gummble.com/mcp | Streamable HTTP MCP endpoint |
Setup
1. Discover the protected resource
Fetch Gummble's Protected Resource Metadata to discover the authorization server and supported scopes:
curl https://mcp.gummble.com/.well-known/oauth-protected-resource/mcpThe response includes:
{
"resource": "https://mcp.gummble.com/mcp",
"authorization_servers": ["https://api.gummble.com"],
"bearer_methods_supported": ["header"],
"resource_signing_alg_values_supported": ["RS256"],
"resource_documentation": "https://docs.gummble.com/docs/mcp/build-integration",
"scopes_supported": ["mcp:read", "mcp:tools"]
}2. Discover OAuth endpoints
Fetch the authorization server metadata:
curl https://api.gummble.com/.well-known/oauth-authorization-serverUse the returned authorization_endpoint, token_endpoint,
registration_endpoint, revocation_endpoint, and jwks_uri.
3. Register your app
Gummble supports Dynamic Client Registration, so you do not need manual client provisioning or redirect URI whitelisting.
curl -X POST https://api.gummble.com/oauth/register \
-H "content-type: application/json" \
-d '{
"client_name": "Example App",
"redirect_uris": ["https://example.com/oauth/gummble/callback"],
"application_type": "web",
"token_endpoint_auth_method": "none",
"scope": "mcp:read mcp:tools"
}'Store the returned client_id. Gummble MCP clients are public OAuth
clients, so there is no client_secret.
4. Redirect the user with PKCE
Generate a PKCE verifier and S256 challenge. Redirect the user to the authorization endpoint:
https://api.gummble.com/oauth/authorize?
response_type=code&
client_id=<client_id>&
redirect_uri=https%3A%2F%2Fexample.com%2Foauth%2Fgummble%2Fcallback&
state=<random_state>&
code_challenge=<s256_challenge>&
code_challenge_method=S256&
resource=https%3A%2F%2Fmcp.gummble.com%2Fmcp&
scope=mcp%3Aread%20mcp%3AtoolsThe user signs in on Gummble, reviews the consent screen, and is
redirected back to your redirect_uri with code and state.
5. Exchange the code for tokens
curl -X POST https://api.gummble.com/oauth/token \
-H "content-type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=<client_id>" \
-d "code=<authorization_code>" \
-d "redirect_uri=https://example.com/oauth/gummble/callback" \
-d "code_verifier=<pkce_verifier>" \
-d "resource=https://mcp.gummble.com/mcp"The response includes a short-lived MCP access token and a rotating refresh token:
{
"access_token": "...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "...",
"scope": "mcp:read mcp:tools"
}6. Call the MCP server
Send MCP JSON-RPC requests to the Streamable HTTP endpoint with the user's access token:
curl -X POST https://mcp.gummble.com/mcp \
-H "authorization: Bearer <access_token>" \
-H "content-type: application/json" \
-H "accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'7. Refresh access
Access tokens expire after 15 minutes. Use the refresh token to obtain a new access token:
curl -X POST https://api.gummble.com/oauth/token \
-H "content-type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "client_id=<client_id>" \
-d "refresh_token=<refresh_token>" \
-d "resource=https://mcp.gummble.com/mcp"Refresh tokens rotate on every use. Persist the newest refresh_token
returned by the token endpoint and discard the old one.
Token storage
Store tokens per Gummble user and per MCP resource. Do not share tokens across users or workspaces.
Recommended fields:
| Field | Notes |
|---|---|
gummble_user_id | Your internal mapping to the connected user |
client_id | DCR client identifier |
resource | https://mcp.gummble.com/mcp |
access_token | Short-lived Bearer token |
access_token_expires_at | Refresh before expiry |
refresh_token | Rotating token, encrypted at rest |
scope | Granted scope string |
Revoke access
When a user disconnects Gummble from your app, revoke the refresh token:
curl -X POST https://api.gummble.com/oauth/revoke \
-H "content-type: application/json" \
-d '{
"token": "<refresh_token>",
"token_type_hint": "refresh_token"
}'Error handling
| Status | Meaning |
|---|---|
401 from mcp.gummble.com | Token missing, expired, invalid, or wrong audience |
403 from mcp.gummble.com | Token lacks required scope or entitlement |
400 invalid_grant from /oauth/token | Code expired, PKCE failed, refresh token reused, or resource mismatch |
400 invalid_scope | Requested scope is not supported |
On 401, refresh the access token and retry once. On invalid_grant,
send the user through authorization again.
SDKs
Use an MCP SDK with OAuth support when possible. Your integration usually only needs to provide:
- The MCP server URL:
https://mcp.gummble.com/mcp - A redirect URI
- A token storage hook
- A way to resume after the OAuth callback
For lower-level protocol details, see OAuth Dance.