Skip to content

Commit c0bfc6e

Browse files
committed
Support auto-downloading tools
Signed-off-by: David Gageot <david.gageot@docker.com>
1 parent 466d846 commit c0bfc6e

File tree

21 files changed

+2579
-5
lines changed

21 files changed

+2579
-5
lines changed

agent-schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,10 @@
848848
"items": {
849849
"type": "string"
850850
}
851+
},
852+
"version": {
853+
"type": "string",
854+
"description": "Package reference for auto-installation of MCP/LSP tool binaries. Format: 'owner/repo' or 'owner/repo@version'. Set to 'false' to disable auto-install for this toolset."
851855
}
852856
},
853857
"additionalProperties": false,

docs/configuration/overview/index.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ API keys and secrets are read from environment variables — never stored in con
146146
| `XAI_API_KEY` | xAI |
147147
| `NEBIUS_API_KEY` | Nebius |
148148

149+
**Tool Auto-Installation:**
150+
151+
| Variable | Description |
152+
| --------------------- | --------------------------------------------------------------- |
153+
| `DOCKER_AGENT_AUTO_INSTALL` | Set to `false` to disable automatic tool installation |
154+
| `DOCKER_AGENT_TOOLS_DIR` | Override the base directory for installed tools (default: `~/.cagent/tools/`) |
155+
149156
<div class="callout callout-warning">
150157
<div class="callout-title">⚠️ Important
151158
</div>

docs/configuration/tools/index.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ toolsets:
322322
| `tools` | array | Optional: only expose these tools |
323323
| `env` | array | Environment variables (`"KEY=value"` format) |
324324
| `instruction` | string | Custom instructions injected into the agent's context |
325+
| `version` | string | Package reference for [auto-installing](#auto-installing-tools) the command binary |
325326

326327
### Remote MCP (SSE / Streamable HTTP)
327328

@@ -344,6 +345,81 @@ toolsets:
344345
| `remote.transport_type` | string | `sse` or `streamable` |
345346
| `remote.headers` | object | HTTP headers (typically for auth) |
346347

348+
## Auto-Installing Tools
349+
350+
When configuring MCP or LSP tools that require a binary command, cagent can **automatically download and install** the command if it's not already available on your system. This uses the [aqua registry](https://github.com/aquaproj/aqua-registry) — a curated index of CLI tool packages.
351+
352+
### How It Works
353+
354+
1. When a toolset with a `command` is loaded, cagent checks if the command is available in your `PATH`
355+
2. If not found, it checks the cagent tools directory (`~/.cagent/tools/bin/`)
356+
3. If still not found, it looks up the command in the aqua registry and installs it automatically
357+
358+
### Explicit Package Reference
359+
360+
Use the `version` property to specify exactly which package to install:
361+
362+
```yaml
363+
toolsets:
364+
- type: mcp
365+
command: gopls
366+
version: "golang/tools@v0.25.0"
367+
args: ["mcp"]
368+
- type: lsp
369+
command: rust-analyzer
370+
version: "rust-lang/rust-analyzer@2024-01-01"
371+
file_types: [".rs"]
372+
```
373+
374+
The format is `owner/repo` or `owner/repo@version`. When a version is omitted, the latest release is used.
375+
376+
### Automatic Detection
377+
378+
If the `version` property is not set, cagent tries to auto-detect the package from the command name by searching the aqua registry:
379+
380+
```yaml
381+
toolsets:
382+
- type: mcp
383+
command: gopls # auto-detected as golang/tools
384+
args: ["mcp"]
385+
```
386+
387+
### Disabling Auto-Install
388+
389+
You can disable auto-installation in two ways:
390+
391+
**Per toolset** — set `version` to `"false"` or `"off"`:
392+
393+
```yaml
394+
toolsets:
395+
- type: mcp
396+
command: my-custom-server
397+
version: "false"
398+
```
399+
400+
**Globally** — set the `DOCKER_AGENT_AUTO_INSTALL` environment variable:
401+
402+
```bash
403+
export DOCKER_AGENT_AUTO_INSTALL=false
404+
```
405+
406+
### Environment Variables
407+
408+
| Variable | Default | Description |
409+
| --------------------- | ---------------------- | ------------------------------------------------ |
410+
| `DOCKER_AGENT_AUTO_INSTALL` | (enabled) | Set to `false` to disable all auto-installation |
411+
| `DOCKER_AGENT_TOOLS_DIR` | `~/.cagent/tools/` | Base directory for installed tools |
412+
| `GITHUB_TOKEN` | — | GitHub token to raise API rate limits (optional) |
413+
414+
Installed binaries are placed in `~/.cagent/tools/bin/` and cached so they are only downloaded once.
415+
416+
<div class="callout callout-tip">
417+
<div class="callout-title">💡 Tip
418+
</div>
419+
<p>Auto-install supports both Go packages (via <code>go install</code>) and GitHub release binaries (via archive download). The aqua registry metadata determines which method is used.</p>
420+
421+
</div>
422+
347423
## Tool Filtering
348424

349425
Toolsets may expose many tools. Use the `tools` property to whitelist only the ones your agent needs. This works for any toolset type — not just MCP:

docs/tools/lsp/index.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ agents:
4444
| `args` | array | ✗ | Command-line arguments for the LSP server |
4545
| `env` | object | ✗ | Environment variables for the LSP process |
4646
| `file_types` | array | ✗ | File extensions this LSP handles (e.g., `[".go", ".mod"]`) |
47+
| `version` | string | ✗ | Package reference for [auto-installing](/configuration/tools/#auto-installing-tools) the command binary (e.g., `"golang/tools@v0.25.0"`) |
4748

4849
## Available Tools
4950

@@ -77,6 +78,7 @@ Here are configurations for popular languages:
7778
toolsets:
7879
- type: lsp
7980
command: gopls
81+
version: "golang/tools@v0.25.0" # optional: auto-install if not in PATH
8082
file_types: [".go"]
8183
```
8284

@@ -196,9 +198,9 @@ All LSP tools use **1-based** line and character positions:
196198
}
197199
```
198200

199-
<div class="callout callout-warning">
200-
<div class="callout-title">⚠️ Server Installation
201+
<div class="callout callout-tip">
202+
<div class="callout-title">💡 Auto-Installation
201203
</div>
202-
<p>The LSP server must be installed and available in the system PATH. docker-agent does not install LSP servers automatically. Install them using your language's package manager (e.g., <code>go install golang.org/x/tools/gopls@latest</code>).</p>
204+
<p>docker-agent can automatically download and install LSP servers if they are not found in your PATH. Use the <code>version</code> property to specify a package, or let docker-agent auto-detect it from the command name. See <a href="/configuration/tools/#auto-installing-tools">Auto-Installing Tools</a> for details.</p>
203205

204206
</div>

examples/elicitation/demo.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@ agents:
3737
toolsets:
3838
- type: mcp
3939
command: uvx
40+
version: "astral-sh/uv"
4041
args:
4142
["--with", "mcp[cli]", "mcp", "run", "examples/elicitation/server.py"]

examples/finance.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ agents:
5050
toolsets:
5151
- type: mcp
5252
command: uvx
53+
version: "astral-sh/uv"
5354
args: ["yfmcp"]
5455

5556
web_search_agent:

examples/gopher.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ agents:
6565
- type: todo
6666
- type: mcp
6767
command: gopls
68+
version: "golang/tools@v0.25.0"
6869
args: ["mcp"]
6970
commands:
7071
fix-lint:
@@ -164,6 +165,7 @@ agents:
164165
- type: shell
165166
- type: mcp
166167
command: gopls
168+
version: "golang/tools@v0.25.0"
167169
args: ["mcp"]
168170

169171
librarian:

examples/modernize-go-tests.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ agents:
8787
- type: todo
8888
- type: mcp
8989
command: gopls
90+
version: "golang/tools@v0.25.0"
9091
args: ["mcp"]
9192
tools:
9293
[

pkg/config/latest/types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,12 @@ type Toolset struct {
542542
Remote Remote `json:"remote"`
543543
Config any `json:"config,omitempty"`
544544

545+
// For `mcp` and `lsp` tools - version/package reference for auto-installation.
546+
// Format: "owner/repo" or "owner/repo@version"
547+
// When empty and auto-install is enabled, cagent auto-detects from the command name.
548+
// Set to "false" or "off" to disable auto-install for this toolset.
549+
Version string `json:"version,omitempty"`
550+
545551
// For the `a2a` and `openapi` tools
546552
Name string `json:"name,omitempty"`
547553
URL string `json:"url,omitempty"`

pkg/config/latest/validate.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ func (t *Toolset) validate() error {
8585
if t.Shared && t.Type != "todo" {
8686
return errors.New("shared can only be used with type 'todo'")
8787
}
88+
if t.Version != "" && t.Type != "mcp" && t.Type != "lsp" {
89+
return errors.New("version can only be used with type 'mcp' or 'lsp'")
90+
}
8891
if t.Command != "" && t.Type != "mcp" && t.Type != "lsp" {
8992
return errors.New("command can only be used with type 'mcp' or 'lsp'")
9093
}

0 commit comments

Comments
 (0)