Connect an AI Agent with MCP

The short version

  • The Delivr MCP server lets an AI agent work with your Delivr account through tools. Its URL is https://api.delivr.ai/mcp.
  • It uses the Streamable HTTP transport. It keeps no session, so any request can reach any server.
  • A person connects an agent with OAuth. The agent gets only the access the person approves, and never more than the person has.
  • A backend job can use an organization API key instead. That path is read-only.

Connect with OAuth

OAuth is the normal way to connect an agent that acts for a person. The person signs in to Delivr and approves a list of permissions. The agent never sees the person's password.

Claude

  1. In Claude, add a custom connector.
  2. Enter the URL https://api.delivr.ai/mcp.
  3. Select Connect. Claude opens the Delivr sign-in page.
  4. Sign in, review the permissions on the consent page, and approve.

Claude Desktop and the Claude mobile apps use the same connector as claude.ai.

Claude Code

Run this command:

claude mcp add --transport http delivr https://api.delivr.ai/mcp

Then run /mcp in Claude Code and select delivr to sign in. Claude Code opens a browser for the consent page.

Other clients

Any MCP client that supports OAuth 2.1 with PKCE can connect. The server does not offer dynamic client registration. A client identifies itself with a Client ID Metadata Document: its client_id is an HTTPS URL that returns the client's metadata. The server advertises this with client_id_metadata_document_supported.

A client finds the rest by itself:

  1. Send a request to https://api.delivr.ai/mcp without a credential. The server answers 401 with a WWW-Authenticate header. The header holds a resource_metadata URL.
  2. Read the protected resource document at https://api.delivr.ai/.well-known/oauth-protected-resource/mcp (RFC 9728). It names the authorization server https://auth.delivr.ai and lists scopes_supported.
  3. Read the authorization server document at https://auth.delivr.ai/.well-known/oauth-authorization-server (RFC 8414). It lists the authorization, token, and revocation endpoints.
  4. Send the person to the authorization endpoint with the code response type and a PKCE challenge. Only the S256 method is accepted. Name the scopes you need in scope. A request with no scope is refused.
  5. Exchange the code at the token endpoint. Send the PKCE verifier.
  6. Send the access token on each MCP request as Authorization: Bearer <token>.
SettingValue
Issuerhttps://auth.delivr.ai
Grant typesauthorization_code, refresh_token
PKCES256 only
Token endpoint authenticationnone, client_secret_basic, client_secret_post
Resourcehttps://api.delivr.ai/mcp

Tokens

An access token lasts 15 minutes. It is a signed JWT. Use the refresh token to get a new access token without a new sign-in. Refresh tokens are opaque and can be revoked.

To end a grant from code, send the token to the revocation endpoint (RFC 7009). An access token that was already issued works until it expires.

Permissions

The consent page lists the permissions the agent asks for. Each permission is a scope, such as audiences:read or audiences:write. The scopes_supported list in the discovery documents is the full set.

  • The agent can do only what the person approved. A tool the agent has no scope for is refused.
  • The agent can never do more than the person can do in the dashboard. Delivr applies the person's own memberships to every call.
  • The scopes are fixed when the person approves. If you add a tool that needs a new scope, the person must reconnect and approve again.
  • Some actions are never open to an agent, such as launching a campaign or connecting a new destination. The person does these in the dashboard.

Disconnect an agent

  1. In the dashboard, open Account > Apps.
  2. Find the agent under Connected agents. The row shows what it can see and change, and when it was last used.
  3. Select Disconnect and confirm.

Connect with an API key

A backend job with no person present can send an organization API key in the X-Api-Key header. Do not send it as a bearer token.

If the key requires its secret, send the secret in the X-Api-Secret header too. New keys require it by default. A key that requires its secret and arrives without it gets a 401 with api secret is required for this key. A secret that does not match the key gets a 401 with api secret does not match this key, even when the key does not require one. See Authentication for the key and secret pair.

curl -sS https://api.delivr.ai/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H "X-Api-Key: $DELIVR_API_KEY" \
  -H "X-Api-Secret: $DELIVR_API_SECRET" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'

An API key carries the identity:read and audiences:read scopes only. It cannot change anything. It cannot call a tool that needs another scope. Use OAuth for those tools.

A client must run the initialize handshake before any tools/call.

Start with these tools

After an OAuth connection:

  1. Call whoami to see which identity the credential resolves to.
  2. Call list_workspaces to list the projects the person can reach. Most tools need a project_id.
  3. Call list_audiences or get_audience to read audiences.

The server returns its full tool list in response to tools/list.

Troubleshooting

SymptomCause and fix
401 with no credential presentedThe request has no credential. Send a bearer token or the X-Api-Key header.
401 and the X-Api-Key header "arrived empty"The client sent the header with no value. Check the environment variable that fills it.
401 and the Authorization header "did not carry a token"The bearer value is not a Delivr access token. Do not put an API key in Authorization.
A tool is refused for a missing scopeThe credential lacks the scope. Reconnect with OAuth and approve it. An API key cannot hold it.
A tool returns no data for a projectThe person has no access to that project. Call list_workspaces to see the projects they can reach.
Access stops after 15 minutesThe client does not refresh its token. Make the client use the refresh token.

Did this page help you?