Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/_data/nav.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
url: /tools/model-picker/
- title: OpenAPI
url: /tools/openapi/
- title: MCP
url: /tools/mcp/
- title: A2A
url: /tools/a2a/

Expand Down
2 changes: 1 addition & 1 deletion docs/configuration/tools/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ toolsets:

## MCP Tools

Extend agents with external tools via the [Model Context Protocol](https://modelcontextprotocol.io/).
Extend agents with external tools via the [Model Context Protocol](https://modelcontextprotocol.io/). For a standalone overview of the `mcp` toolset see the [MCP tool page]({{ '/tools/mcp/' | relative_url }}).

<div class="callout callout-tip" markdown="1">
<div class="callout-title">Reusable MCP definitions
Expand Down
272 changes: 272 additions & 0 deletions docs/tools/mcp/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
---
title: "MCP Tool"
description: "Extend agents with external tools via the Model Context Protocol."
permalink: /tools/mcp/
---

# MCP Tool

_Extend agents with external tools via the Model Context Protocol (MCP)._

## Overview

The `mcp` toolset connects your agent to any MCP server — a process or remote service that exposes tools, resources, and prompts over the [Model Context Protocol](https://modelcontextprotocol.io/). Three flavours are supported:

| Flavour | Transport | Best for |
| --- | --- | --- |
| **Docker MCP** | Container via the [MCP Gateway](https://github.com/docker/mcp-gateway) | Curated, sandboxed servers from the [Docker MCP Catalog](https://hub.docker.com/u/mcp) |
| **Local stdio** | Subprocess over stdin/stdout | Custom or community MCP servers run from a binary or `npx`/`pip` package |
| **Remote** | SSE or Streamable HTTP | Cloud services with hosted MCP endpoints (Linear, GitHub, Vercel, …) |

<div class="callout callout-info" markdown="1">
<div class="callout-title">What is MCP?
</div>
<p>The <a href="https://modelcontextprotocol.io/">Model Context Protocol</a> is an open standard for connecting AI tools. Docker Agent can both <em>use</em> MCP servers (this page) and <em>expose</em> agents as MCP servers — see <a href="{{ '/features/mcp-mode/' | relative_url }}">MCP Mode</a>.</p>
</div>

## Docker MCP (Recommended)

Run MCP servers as secure Docker containers via the MCP Gateway. The `ref: docker:<name>` syntax pulls a curated definition from the Docker MCP Catalog:

```yaml
toolsets:
- type: mcp
ref: docker:duckduckgo # web search
- type: mcp
ref: docker:github-official # GitHub integration
tools: ["list_issues", "create_issue"]
```

Browse available servers at the [Docker MCP Catalog](https://hub.docker.com/u/mcp).

| Property | Type | Description |
| ------------- | ------ | ---------------------------------------------------------------- |
| `ref` | string | Docker MCP reference (`docker:name`) or a name from the [reusable `mcps:`]({{ '/configuration/overview/#reusable-mcp-servers-mcps' | relative_url }}) block. |
| `tools` | array | Optional whitelist — only expose these tools to the model. |
| `instruction` | string | Custom instructions injected into the agent's context. |
| `config` | any | MCP server-specific configuration passed during initialization. |
| `working_dir` | string | Working directory for the MCP gateway subprocess. Only applies when the catalog entry runs as a local process (not remote). Relative paths are resolved against the agent's working directory. Supports `~` and shell-style `$VAR`/`${VAR}` expansion ([details]({{ '/configuration/overview/#variable-expansion-in-config-fields' | relative_url }})). |

## Local MCP (stdio)

Run MCP servers as local processes communicating over stdin/stdout:

```yaml
toolsets:
- type: mcp
command: python
args: ["-m", "mcp_server"]
tools: ["search", "fetch"]
env:
API_KEY: value
```

| Property | Type | Description |
| ------------- | ------ | ----------- |
| `command` | string | Command to execute the MCP server. |
| `args` | array | Command arguments. |
| `tools` | array | Optional whitelist — only expose these tools. |
| `env` | object | Environment variables (key-value pairs). |
| `working_dir` | string | Working directory for the MCP server process. Relative paths are resolved against the agent's working directory. Defaults to the agent's working directory when omitted. Supports `~` and shell-style `$VAR`/`${VAR}` expansion ([details]({{ '/configuration/overview/#variable-expansion-in-config-fields' | relative_url }})). |
| `instruction` | string | Custom instructions injected into the agent's context. |
| `version` | string | Package reference for [auto-installing]({{ '/configuration/tools/#auto-installing-tools' | relative_url }}) the command binary. |

<div class="callout callout-tip" markdown="1">
<div class="callout-title">Auto-installation
</div>
<p>If the <code>command</code> is not in your <code>PATH</code>, docker-agent looks it up in the <a href="https://github.com/aquaproj/aqua-registry">aqua registry</a> and installs it for you. Use <code>version: "false"</code> to opt out, or set <code>DOCKER_AGENT_AUTO_INSTALL=false</code> globally. See <a href="{{ '/configuration/tools/#auto-installing-tools' | relative_url }}">Auto-Installing Tools</a>.</p>
</div>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Should fix (STYLE.md): Same product-name violation as in the Remote MCP section. docker-agent in prose should be Docker Agent.

docker-agent looks it upDocker Agent looks it up


## Remote MCP (SSE / Streamable HTTP)

Connect to MCP servers over the network. OAuth flows (including [Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591)) are handled automatically — docker-agent opens your browser when authentication is required and caches tokens for subsequent sessions.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Should fix (STYLE.md): docker-agent is a command/binary name. When referring to the product in prose, use Docker Agent.

docker-agent opens your browserDocker Agent opens your browser

```yaml
toolsets:
- type: mcp
remote:
url: "https://mcp.linear.app/sse"
transport_type: "sse" # or "streamable"
headers:
Authorization: "Bearer ${LINEAR_TOKEN}"
# Optional: allow OAuth helper requests to reach private/internal IPs.
allow_private_ips: false
tools: ["search_issues", "create_issue"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Suggestion: allow_private_ips: false is the default value. Showing it explicitly alongside # Optional is confusing — why would a reader set an option to its default? The existing configuration/tools/ page shows allow_private_ips: true (the meaningful override case). Recommend removing this line or changing it to true.

```

| Property | Type | Description |
| ----------------------- | ------- | ----------- |
| `remote.url` | string | Base URL of the MCP server. |
| `remote.transport_type` | string | `sse` or `streamable`. |
| `remote.headers` | object | HTTP headers (typically for static auth tokens). |
| `remote.oauth` | object | Explicit OAuth client credentials for servers that don't support DCR. See [Remote MCP Servers]({{ '/features/remote-mcp/' | relative_url }}#oauth-for-servers-without-dynamic-client-registration). |
| `allow_private_ips` | boolean | Permit remote MCP OAuth helper requests to dial non-public IP addresses. Use only for trusted internal servers. |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Suggestion: The remote.oauth entry is correct to delegate to the feature page. A brief parenthetical listing the accepted sub-fields (clientId, clientSecret, callbackPort, scopes, callbackRedirectURL) would save readers a round-trip for a quick reminder.


For a curated list of public remote MCP endpoints (Linear, GitHub, Vercel, Notion, …) and full OAuth configuration details, see [Remote MCP Servers]({{ '/features/remote-mcp/' | relative_url }}).

## Reusable Definitions (`mcps:`)

Repeated MCP server configurations can be hoisted into the top-level `mcps:` section and referenced by name with `{type: mcp, ref: <name>}`:

```yaml
mcps:
github:
remote:
url: https://api.githubcopilot.com/mcp
transport_type: sse
playwright:
command: npx
args: ["-y", "@modelcontextprotocol/server-playwright"]

agents:
root:
model: openai/gpt-5-mini
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM] Documentation example uses openai/gpt-5-mini — likely a non-existent model name

The "Reusable Definitions" example uses model: openai/gpt-5-mini, but gpt-5-mini is not a publicly available OpenAI model. The same PR uses openai/gpt-4o-mini in the per-toolset model routing example (line 197), which is likely the intended model here as well.

While gpt-5-mini is registered in the codebase's internal model recogniser (modelinfo_test.go), it is not publicly available on OpenAI's API, so users copy-pasting this example will get an error. Consider replacing with openai/gpt-4o-mini (or another real available model) to keep the documentation example immediately runnable.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM] Incorrect model name openai/gpt-5-mini — should be openai/gpt-4o-mini

The Reusable Definitions YAML example uses model: openai/gpt-5-mini, but gpt-5-mini is not a real OpenAI model. The correct name for OpenAI's small/efficient model is gpt-4o-mini.

This is inconsistent with the rest of the file: line 197 of this same new page already uses the correct openai/gpt-4o-mini, and the existing authoritative reference at docs/configuration/tools/index.md (line 326) also uses openai/gpt-4o-mini as the canonical example.

Readers who copy-paste this example will get a runtime error when the agent tries to use the non-existent model.

Suggested fix:

  root:
    model: openai/gpt-4o-mini

toolsets:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Suggestion (STYLE.md): The canonical example model per STYLE.md is anthropic/claude-sonnet-4-5. openai/gpt-5-mini here is not illustrating a model-specific feature. The Combined Example at the bottom of this page already uses the correct canonical model — this mid-page snippet should match.

- type: mcp
ref: github
- type: mcp
ref: playwright
```

See [Reusable MCP Servers]({{ '/configuration/overview/#reusable-mcp-servers-mcps' | relative_url }}) for the full reference.

## Common Options

These properties apply to every MCP toolset regardless of flavour:

### Tool filtering

```yaml
toolsets:
- type: mcp
ref: docker:github-official
tools: ["list_issues", "create_issue", "get_pull_request"]
```

Whitelisting tools improves model accuracy — fewer choices means less confusion.

### Deferred loading

Skip the toolset's startup cost until its tools are actually called:

```yaml
toolsets:
- type: mcp
ref: docker:github-official
defer: true
# Or defer specific tools within a toolset:
- type: mcp
ref: docker:slack
defer: ["list_channels", "search_messages"]
```

### Custom instructions

```yaml
toolsets:
- type: mcp
ref: docker:github-official
instruction: |
Use these tools to manage GitHub issues.
Always check for existing issues before creating new ones.
Label new issues with 'triage' by default.
```

### TOON-encoded outputs

Re-encode verbose JSON outputs as the compact [TOON](https://github.com/alpkeskin/gotoon) format to save context budget. Typically yields 30–60% smaller payloads on list/search tools:

```yaml
toolsets:
- type: mcp
ref: docker:github-official
toon: ".*" # toonify every tool from this server
- type: mcp
command: my-server
toon: "list_.*,get_.*" # only toonify list_/get_ tools
```

### Per-toolset model routing

Process tool results from this toolset with a different (typically cheaper / faster) model. The override is one-shot — subsequent turns return to the agent's primary model:

```yaml
toolsets:
- type: mcp
ref: docker:github-official
model: openai/gpt-4o-mini
```

See [Per-Toolset Model Routing]({{ '/configuration/tools/#per-toolset-model-routing' | relative_url }}).

### Lifecycle (auto-restart, profiles)

Local stdio and remote MCP servers are supervised: crashed servers reconnect automatically with exponential backoff. Tune the policy with the `lifecycle` block:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Should fix: Lifecycle supervision applies to all three MCP flavours, not just stdio and remote. The lifecycle: examples on this very page already show ref: docker:duckduckgo with a lifecycle profile.

Suggested replacement:

All MCP toolsets (Docker, stdio, and remote) are supervised: crashed servers reconnect automatically with exponential backoff.

```yaml
toolsets:
- type: mcp
ref: docker:duckduckgo
lifecycle:
profile: resilient # default; auto-restart with backoff
- type: mcp
command: docker
args: ["mcp", "gateway"]
lifecycle:
profile: strict # fail-fast: required, no retries
```

See [Toolset Lifecycle]({{ '/configuration/tools/#toolset-lifecycle' | relative_url }}) for all profiles and tuning knobs, and [`/toolset-restart`]({{ '/features/tui/' | relative_url }}) to force a reconnect from the TUI.

## Combined Example

```yaml
mcps:
github:
remote:
url: https://api.githubcopilot.com/mcp
transport_type: sse

agents:
root:
model: anthropic/claude-sonnet-4-5
description: Full-featured developer assistant
instruction: You are an expert developer.
toolsets:
# Docker MCP catalog entry
- type: mcp
ref: docker:duckduckgo

# Reusable definition from the top-level mcps: block
- type: mcp
ref: github
tools: ["list_issues", "create_issue"]
toon: "list_.*"

# Local stdio server with auto-install
- type: mcp
command: gopls
version: "golang/tools@v0.21.0"
args: ["mcp"]

# Remote MCP with OAuth (handled automatically)
- type: mcp
remote:
url: "https://mcp.linear.app/sse"
transport_type: "sse"
instruction: Use Linear for issue tracking.
```

<div class="callout callout-warning" markdown="1">
<div class="callout-title">Toolset order matters
</div>
<p>If multiple toolsets provide a tool with the same name, the first one wins. Order your toolsets intentionally.</p>
</div>

## See Also

- [Tool Configuration]({{ '/configuration/tools/' | relative_url }}) — full reference for every toolset type, plus shared options (lifecycle, TOON, model routing, …).
- [Reusable MCP Servers]({{ '/configuration/overview/#reusable-mcp-servers-mcps' | relative_url }}) — the top-level `mcps:` block.
- [Remote MCP Servers]({{ '/features/remote-mcp/' | relative_url }}) — catalog of public remote MCP endpoints + OAuth recipes.
- [MCP Mode]({{ '/features/mcp-mode/' | relative_url }}) — expose your own agents as MCP tools to Claude Desktop, Claude Code, etc.
- [Auto-Installing Tools]({{ '/configuration/tools/#auto-installing-tools' | relative_url }}) — automatic installation of MCP server binaries.
Loading