Manifest Auto-Attach

The simplest way to give an agent access to MCP tools is to declare the servers in its manifest. agentd attaches them automatically at spawn time, with no separate ash mcp attach command needed.

Declaring servers in a manifest

Add a mcp_servers list to spec:

apiVersion: scarab/v1
kind: AgentManifest
metadata:
  name: research-agent
  version: 1.0.0
spec:
  trust_level: trusted
  capabilities:
    - tool.invoke:lm.complete
    - tool.invoke:mcp.github.*
    - tool.invoke:mcp.search.*
  mcp_servers:
    - name: github
      transport: Stdio
      command: /usr/local/bin/github-mcp
      args: ["--read-only"]
      env_template:
        - ["GITHUB_TOKEN", "{{secret:github-token}}"]
      description: "GitHub read-only MCP tools"
    - name: search
      transport: Http
      url: https://search-mcp.internal/api
      description: "Internal search server"

mcp_servers fields

FieldTypeDescription
namestringUnique server name; tools are namespaced as mcp.<name>.<tool>
transportStdio | HttpConnection mechanism
commandstring (Stdio)Path to executable
argsstring[] (Stdio)Arguments passed to the executable
urlstring (Http)Base URL for the HTTP endpoint
env_template[[key, value]]Environment variables; values may use {{secret:<name>}}
descriptionstringOptional human-readable description

Capabilities and MCP tools

An agent must declare tool.invoke:mcp.<server-name>.* (or a specific tool pattern) in its capabilities to call the attached tools.

capabilities:
  - tool.invoke:mcp.github.list_prs    # specific tool
  - tool.invoke:mcp.search.*           # all tools from a server
  - tool.invoke:mcp.*                  # all MCP tools (broad)

Without the matching tool.invoke capability, the agent can see the tools in ToolList but invocation is denied.

Spawn sequence with auto-attach

When agentd spawns an agent from a manifest containing mcp_servers:

  1. Agent process is created and enters the Init state.
  2. For each entry in mcp_servers, agentd runs the attach sequence:
    • Stdio: spawns subprocess, completes JSON-RPC handshake, calls tools/list.
    • HTTP: connects, completes handshake, calls tools/list.
  3. Discovered tools are registered as mcp.<name>.<tool> in the agent's ToolRegistry.
  4. Agent transitions to Plan.

If an MCP server fails to attach at spawn time, the error is recorded in the audit log and the agent continues without those tools.

Pre-approval policy for secrets in env_template

If env_template references secrets, a matching pre-approval policy must exist:

spec:
  secret_policy:
    - label: "GitHub token for MCP"
      secret_pattern: "github-token"
      tool_pattern: "*"            # resolved at attach, not per tool-invoke

Or register the policy at runtime before spawning:

ash secrets policy add \
  --label "GitHub MCP" \
  --secret "github-token" \
  --tool "*"

Using auto-attached tools in agent code

Auto-attached tools are available as soon as the agent starts. Use the standard invoke_tool API:

#![allow(unused)]
fn main() {
let result = agent.invoke_tool(
    "mcp.github.list_prs",
    serde_json::json!({ "repo": "anomalyco/opencode", "state": "open" }),
).await?;
}