Remote MCP Servers
Connect Docker Agent to cloud services via remote MCP servers with built-in OAuth authentication.
Overview
Docker Agent supports connecting to remote MCP servers over Streamable HTTP, SSE (Server-Sent Events), and Unix domain sockets. Streamable HTTP is the current recommended transport for most hosted MCP servers. Many popular services offer MCP endpoints with OAuth — Docker Agent handles the authentication flow automatically.
toolsets:
- type: mcp
remote:
url: "https://mcp.linear.app/mcp"
transport_type: "streamable"
Unix Domain Sockets
Use a unix:// URL to connect to an MCP server listening on a local Unix socket. This is useful when running Docker Agent inside a container and exposing an MCP server from the host via a bind-mounted socket:
toolsets:
- type: mcp
remote:
url: "unix:///tmp/mcp-notify.sock"
transport_type: "streamable"
The path after unix:// is the absolute path to the socket file. Configured headers are forwarded over the socket connection. OAuth discovery is not supported for Unix socket URLs.
When you connect to a remote MCP server that requires OAuth, Docker Agent opens your browser automatically for authentication. Tokens are cached for subsequent sessions.
If you dismiss the OAuth authorization dialog, the request is cancelled cleanly — no repeated prompts appear. The agent will report that authorization was declined. To try again, simply re-enable the server or repeat the request that triggered the flow.
Configuration
toolsets:
- type: mcp
remote:
url: "https://mcp.example.com/mcp"
transport_type: "streamable" # or "sse" for legacy servers
headers:
Authorization: "Bearer ${env.MY_TOKEN}" # resolved per request
# Optional: use only for trusted internal/private MCP or OAuth endpoints.
allow_private_ips: true
For full configuration details, see the Tool Config page.
Set allow_private_ips: true on a remote MCP toolset only when the MCP server or its OAuth registration/token endpoints intentionally resolve to private, loopback, or link-local addresses. The default blocks those OAuth helper requests to reduce SSRF risk.
Configured headers are forwarded to OAuth protected-resource-metadata discovery requests directed at the MCP server's own host — not to third-party authorization servers. This allows services like Grafana Cloud that require a routing header (e.g. X-Grafana-URL) on the discovery request to scope the OAuth flow correctly. Headers are never sent to a different host than the one in remote.url.
Header values in remote.headers support ${env.VAR} and ${headers.NAME} placeholders. Both are resolved on every outbound HTTP request (not just once at initialization), so short-lived credentials and forwarded caller headers always reflect the latest values:
${env.VAR}— reads the named environment variable. Useful for credentials stored in a secret manager that rotates them in-process.${headers.NAME}— forwards the named header from the caller's incoming HTTP request. Only meaningful when Docker Agent is running as an API server (docker agent serve api) and a client passes authentication headers that the upstream MCP server also accepts.
Remote MCP connections (Streamable HTTP / SSE) automatically reconnect after the server closes an idle connection — no configuration needed. Services like Notion and Linear close idle connections periodically; Docker Agent detects the clean close and reconnects with exponential backoff. To tune reconnect behaviour or disable reconnection entirely, use the lifecycle block.
If a remote MCP server rejects the cached token with a 401 invalid_token error (for example, because the token was revoked or rotated server-side), Docker Agent handles the failure automatically:
- Silent refresh: when a refresh token is available, Docker Agent silently exchanges it for a new access token and replays the request — no user interaction required.
- Re-authentication prompt: when the refresh token is absent or has also expired, the toolset transitions to a "needs re-auth" state and surfaces an OAuth prompt on your next message (exactly like the first-time flow).
Either way, the agent never burns 5 reconnect attempts on an auth failure — it fails fast and either refreshes silently or defers to interactive re-auth. If you want to trigger re-auth immediately without waiting for the next message, run /toolset-restart <name> from the TUI.
OAuth for servers without Dynamic Client Registration
Most remote MCP servers that require OAuth support Dynamic Client Registration (RFC 7591) — no configuration is needed, Docker Agent handles the flow for you.
For servers that do not support DCR, Docker Agent falls back automatically:
- Interactive credential prompt: Docker Agent presents a dialog asking for your
client_id(required) and optionally aclient_secret. This covers servers that require pre-registered app credentials but don't advertise them via DCR. - Explicit
oauth:block (recommended when you know the credentials in advance): add the block described below to skip the interactive prompt and supply credentials directly in config.
toolsets:
- type: mcp
remote:
url: "https://mcp.example.com/mcp"
transport_type: "streamable"
oauth:
clientId: "my-app-client-id"
clientSecret: "my-app-client-secret" # optional (public clients may omit)
callbackPort: 8765 # optional; picks a free port otherwise
scopes: # optional; server-specific
- read
- write
| Field | Type | Required | Description |
|---|---|---|---|
clientId |
string | ✗ | OAuth client ID registered with the remote MCP server. When omitted, Docker Agent uses Dynamic Client Registration or prompts interactively. |
clientSecret |
string | ✗ | OAuth client secret. Requires clientId. Omit for public clients using PKCE. |
callbackPort |
integer | ✗ | Local port to receive the OAuth redirect. If omitted, Docker Agent picks a random free port. |
scopes |
array[string] | ✗ | Scopes to request during the authorization step. Values are server-specific. |
callbackRedirectURL |
string | ✗ | Custom OAuth redirect URI. Useful when the auth server requires HTTPS or a pre-registered URL. The literal placeholder ${callbackPort} is replaced with the actual local callback port. See below. |
Secrets should be stored in a credential helper or environment variable rather than committed — see Secrets for interpolation patterns.
The oauth: block also works without clientId. Use it to pin the callback port, request specific scopes, or set a custom redirect URL while still letting Docker Agent obtain the client ID via Dynamic Client Registration (or the interactive prompt).
Custom redirect URI (callbackRedirectURL)
Some authorization servers require the OAuth redirect_uri to be HTTPS or to match a URL that was pre-registered during app creation — neither of which plays nicely with a locally-bound loopback address such as http://127.0.0.1:8765/callback.
To work around this, set callbackRedirectURL to a public URL that redirects back to the local callback server. The literal placeholder ${callbackPort} is substituted with the actual port the local callback server is listening on (either callbackPort when set, or the randomly-assigned port otherwise).
toolsets:
- type: mcp
remote:
url: "https://mcp.example.com/mcp"
transport_type: "streamable"
oauth:
clientId: "my-app-client-id"
callbackPort: 8765
# Advertise this URL to the authorization server. The external
# service at redirect.example.com is expected to 302-redirect the
# browser to http://127.0.0.1:8765/callback preserving the query
# string (code, state, …).
callbackRedirectURL: "https://redirect.example.com/cb?port=${callbackPort}"
The local callback server still listens on the loopback interface on callbackPort; only the redirect_uri advertised to the authorization server changes.
Validation rules:
- The URL must be absolute (scheme + host) once
${callbackPort}has been substituted. - Only
httpandhttpsschemes are accepted. httpis only allowed when the host is a loopback address (127.0.0.1,::1,localhost); any other host must usehttpsto avoid exposing the authorizationcodeon the wire (RFC 8252 §7.3).
Unmanaged OAuth flow (server mode)
When running docker agent serve api (no local browser, no callback server), the runtime delegates the OAuth dance to the connected client via an MCP elicitation. There are two sub-behaviors, selected by the --mcp-oauth-redirect-uri flag:
-
--mcp-oauth-redirect-uri=<URL>set (recommended for hosts like Docker Desktop): the runtime generatesstate+ PKCE + (optional) Dynamic Client Registration in-process, builds the full authorize URL, and emits an elicitation whoseMetaincludes:Key Value docker-agent/type"oauth_flow"docker-agent/server_urlThe MCP server URL (for display / favicon) docker-agent/authorize_urlThe full URL the client should open in the user's browser docker-agent/stateThe statevalue the client must echo back when replyingauth_serverIssuer of the authorization server auth_server_metadataRFC 8414 authorization-server metadata document resource_metadataRFC 9728 protected-resource metadata document The client opens the browser at the URL provided in the
docker-agent/authorize_urlmeta field, receives the OAuth callback at whatever endpoint the configuredredirect_uriresolves to (typically a host-controlled bouncer that 302s into a deeplink), and replies to the elicitation withacceptandContent = {"code": "...", "state": "..."}. The runtime verifies thestate, exchanges thecodeat the token endpoint (using the sameredirect_urifor RFC 6749 §4.1.3 binding), stores the token, and replays the original MCP request withAuthorization: Bearer .... -
Flag not set (client-driven): the runtime emits the elicitation meta below and expects the client to drive the OAuth flow itself (PKCE, DCR, token exchange) and reply with
Content = {"access_token": "...", "refresh_token": "...", ...}:Key Value docker-agent/type"oauth_flow"docker-agent/server_urlThe MCP server URL (for display / favicon) auth_serverIssuer of the authorization server auth_server_metadataRFC 8414 authorization-server metadata document resource_metadataRFC 9728 protected-resource metadata document
The client-driven {access_token, ...} reply shape is still accepted on the --mcp-oauth-redirect-uri path too: a client that prefers to do the exchange itself can ignore the docker-agent/authorize_url/docker-agent/state keys.
A per-toolset callbackRedirectURL (in the YAML) overrides the runtime-wide --mcp-oauth-redirect-uri for that toolset.
The POST /api/mcp-oauth/callback route is open by default (no auth required) when --auth-token is unset. State values are 128-bit opaque tokens, so brute-force is infeasible, but a state value that leaks (e.g. via debug logs or a compromised host) could be exploited by an attacker to inject a code. Set --auth-token when docker agent serve api listens on a network-reachable interface. When set, --auth-token enforces Bearer-token authentication on all API routes including this callback endpoint.
Project Management & Collaboration
| Service | URL | Transport | Description |
|---|---|---|---|
| Asana | https://mcp.asana.com/sse |
sse | Task and project management |
| Atlassian | https://mcp.atlassian.com/v1/mcp/authv2 |
streamable | Jira, Confluence integration |
| Linear | https://mcp.linear.app/mcp |
streamable | Issue tracking and project management |
| Monday.com | https://mcp.monday.com/sse |
sse | Work management platform |
| Intercom | https://mcp.intercom.com/sse |
sse | Customer communication platform |
Development & Infrastructure
| Service | URL | Transport | Description |
|---|---|---|---|
| GitHub | https://api.githubcopilot.com/mcp |
sse | Version control and collaboration |
| Buildkite | https://mcp.buildkite.com/mcp |
streamable | CI/CD platform |
| Netlify | https://netlify-mcp.netlify.app/mcp |
streamable | Web hosting and deployment |
| Vercel | https://mcp.vercel.com/ |
sse | Web deployment platform |
| Cloudflare Bindings | https://bindings.mcp.cloudflare.com/sse |
sse | Edge computing resources |
| Cloudflare Observability | https://observability.mcp.cloudflare.com/sse |
sse | Monitoring and analytics |
| Grafbase | https://api.grafbase.com/mcp |
streamable | GraphQL backend platform |
| Neon | https://mcp.neon.tech/sse |
sse | Serverless Postgres database |
| Prisma | https://mcp.prisma.io/mcp |
streamable | Database ORM and toolkit |
| Sentry | https://mcp.sentry.dev/sse |
sse | Error tracking and monitoring |
Content & Media
| Service | URL | Transport | Description |
|---|---|---|---|
| Canva | https://mcp.canva.com/mcp |
streamable | Design and graphics platform |
| Miro | https://mcp.miro.com/ |
streamable | Collaborative whiteboard platform (Enterprise plan required; see official docs) |
| Cloudinary | https://asset-management.mcp.cloudinary.com/sse |
sse | Media management and optimization |
| InVideo | https://mcp.invideo.io/sse |
sse | Video creation platform |
| Webflow | https://mcp.webflow.com/sse |
sse | Website builder and CMS |
| Wix | https://mcp.wix.com/sse |
sse | Website builder platform |
| Notion | https://mcp.notion.com/mcp |
streamable | Documentation and knowledge base |
Communication & Voice
| Service | URL | Transport | Description |
|---|---|---|---|
| Fireflies | https://api.fireflies.ai/mcp |
streamable | Meeting transcription |
| Listenetic | https://mcp.listenetic.com/v1/mcp |
streamable | Audio intelligence platform |
| Carbonvoice | https://mcp.carbonvoice.app |
sse | Voice communication tools |
| Telnyx | https://api.telnyx.com/v2/mcp |
streamable | Communications platform |
| Dialer | https://getdialer.app/sse |
sse | Phone communication tools |
Storage & File Management
| Service | URL | Transport | Description |
|---|---|---|---|
| Box | https://mcp.box.com |
sse | Cloud content management |
| Egnyte | https://mcp-server.egnyte.com/sse |
sse | Enterprise file sharing |
Business & Finance
| Service | URL | Transport | Description |
|---|---|---|---|
| PayPal | https://mcp.paypal.com/sse |
sse | Payment processing |
| Plaid | https://api.dashboard.plaid.com/mcp/sse |
sse | Financial data integration |
| Square | https://mcp.squareup.com/sse |
sse | Payment processing |
| Close | https://mcp.close.com/mcp |
streamable | CRM platform |
| Dodo Payments | https://mcp.dodopayments.com/sse |
sse | Payment processing |
Analytics & Data
| Service | URL | Transport | Description |
|---|---|---|---|
| ThoughtSpot | https://agent.thoughtspot.app/mcp |
streamable | Analytics and BI platform |
| Meta Ads | https://mcp.pipeboard.co/meta-ads-mcp |
streamable | Facebook advertising analytics |
Utilities & Tools
| Service | URL | Transport | Description |
|---|---|---|---|
| Apify | https://mcp.apify.com |
sse | Web scraping and automation |
| SimpleScraper | https://mcp.simplescraper.io/mcp |
streamable | Web scraping tool |
| GlobalPing | https://mcp.globalping.dev/sse |
sse | Network diagnostics |
| Jam | https://mcp.jam.dev/mcp |
streamable | Bug reporting and collaboration |
Example: Multi-Service Agent
Combine multiple remote MCP servers in a single agent:
agents:
root:
model: anthropic/claude-sonnet-4-5
instruction: |
You help manage projects and deployments.
toolsets:
- type: mcp
remote:
url: "https://mcp.linear.app/mcp"
transport_type: "streamable"
instruction: Use Linear for issue tracking.
- type: mcp
remote:
url: "https://api.githubcopilot.com/mcp"
transport_type: "sse"
instruction: Use GitHub for code and PRs.
- type: mcp
remote:
url: "https://mcp.vercel.com/"
transport_type: "sse"
instruction: Use Vercel for deployments.
This list is updated as more services add MCP support. If a service you use isn't listed, check their documentation — many providers are adding MCP endpoints regularly.