Tools

Tools are executable capabilities that agents can call. CAPA supports two types of tools: MCP tools and command tools.

Tool Types

MCP Tools

Proxy tools from MCP servers:

tools:
  - id: brave_search
    type: mcp
    def:
      server: "@brave"
      tool: brave_web_search
{
  "tools": [
    {
      "id": "brave_search",
      "type": "mcp",
      "def": {
        "server": "@brave",
        "tool": "brave_web_search"
      }
    }
  ]
}

Reference a server using @server-id and specify which tool from that server to expose.

Command Tools

Execute shell commands:

tools:
  - id: greet_user
    type: command
    def:
      run:
        cmd: echo Hello, {name}!
        args:
          - name: name
            type: string
            description: The name to greet
            required: true
{
  "tools": [
    {
      "id": "greet_user",
      "type": "command",
      "def": {
        "run": {
          "cmd": "echo Hello, {name}!",
          "args": [
            {
              "name": "name",
              "type": "string",
              "description": "The name to greet",
              "required": true
            }
          ]
        }
      }
    }
  ]
}

MCP Tool Definition

MCP tools proxy an existing tool from an MCP server:

# First, define the server
servers:
  - id: filesystem
    type: mcp
    def:
      cmd: npx -y @modelcontextprotocol/server-filesystem
      args:
        - /path/to/directory

# Then, define tools from that server
tools:
  - id: read_file
    type: mcp
    def:
      server: "@filesystem"
      tool: read_file
  
  - id: write_file
    type: mcp
    def:
      server: "@filesystem"
      tool: write_file
{
  "servers": [
    {
      "id": "filesystem",
      "type": "mcp",
      "def": {
        "cmd": "npx -y @modelcontextprotocol/server-filesystem",
        "args": ["/path/to/directory"]
      }
    }
  ],
  "tools": [
    {
      "id": "read_file",
      "type": "mcp",
      "def": {
        "server": "@filesystem",
        "tool": "read_file"
      }
    },
    {
      "id": "write_file",
      "type": "mcp",
      "def": {
        "server": "@filesystem",
        "tool": "write_file"
      }
    }
  ]
}

Command Tool Definition

Command tools execute shell commands with parameters:

tools:
  - id: get_weather
    type: command
    def:
      run:
        cmd: curl "https://wttr.in/{city}?format=%C+%t"
        args:
          - name: city
            type: string
            description: City name
            required: true
{
  "tools": [
    {
      "id": "get_weather",
      "type": "command",
      "def": {
        "run": {
          "cmd": "curl \"https://wttr.in/{city}?format=%C+%t\"",
          "args": [
            {
              "name": "city",
              "type": "string",
              "description": "City name",
              "required": true
            }
          ]
        }
      }
    }
  ]
}

Command Arguments

Each argument in a command tool can have:

  • name: Argument name (used in {name} substitution)
  • type: Argument type (string, number, boolean)
  • description: Description shown to the agent
  • required: Whether the argument is required

Tool Description

Both MCP tools and command tools support an optional top-level description field. This text is shown in capa sh and is used as the tool's description when the schema is sent to MCP clients. For command tools, CAPA falls back to "Command tool: <id>" when the field is absent.

tools:
  - id: find_skills
    type: command
    description: Search the skills.sh ecosystem for reusable agent skills
    def:
      run:
        cmd: npx skills find {query}
        args:
          - name: query
            type: string
            description: Search query
            required: true

  - id: atlassian_search
    type: mcp
    description: Search Jira and Confluence using Rovo Search
    def:
      server: "@atlassian"
      tool: search
{
  "tools": [
    {
      "id": "find_skills",
      "type": "command",
      "description": "Search the skills.sh ecosystem for reusable agent skills",
      "def": {
        "run": {
          "cmd": "npx skills find {query}",
          "args": [
            {
              "name": "query",
              "type": "string",
              "description": "Search query",
              "required": true
            }
          ]
        }
      }
    },
    {
      "id": "atlassian_search",
      "type": "mcp",
      "description": "Search Jira and Confluence using Rovo Search",
      "def": {
        "server": "@atlassian",
        "tool": "search"
      }
    }
  ]
}

Grouping Command Tools

Command tools can be nested under a shared parent group in capa sh using the optional group field. Tools that share the same group value are listed together under that group name:

tools:
  - id: deploy_service
    type: command
    group: deploy
    description: Deploy a service to production
    def:
      run:
        cmd: ./deploy.sh {service}
        args:
          - name: service
            type: string
            required: true

  - id: rollback_service
    type: command
    group: deploy
    description: Roll back a service to the previous version
    def:
      run:
        cmd: ./rollback.sh {service}
        args:
          - name: service
            type: string
            required: true
{
  "tools": [
    {
      "id": "deploy_service",
      "type": "command",
      "group": "deploy",
      "description": "Deploy a service to production",
      "def": {
        "run": {
          "cmd": "./deploy.sh {service}",
          "args": [{ "name": "service", "type": "string", "required": true }]
        }
      }
    },
    {
      "id": "rollback_service",
      "type": "command",
      "group": "deploy",
      "description": "Roll back a service to the previous version",
      "def": {
        "run": {
          "cmd": "./rollback.sh {service}",
          "args": [{ "name": "service", "type": "string", "required": true }]
        }
      }
    }
  ]
}

In capa sh this produces:

$ capa sh deploy

deploy - subcommands:

  deploy-service  [--service*]   — Deploy a service to production
  rollback-service  [--service*] — Roll back a service to the previous version

Single-subcommand promotion: If only one tool belongs to a group, that tool is shown at the top level directly — the extra nesting is skipped.

Initialization Block

Command tools can have an optional init block that runs once before first use:

tools:
  - id: pandas_query
    type: command
    def:
      init:
        cmd: pip install pandas
      run:
        cmd: python -c "import pandas as pd; df = pd.read_csv('{file}'); print(df.query('{query}'))"
        args:
          - name: file
            type: string
            required: true
          - name: query
            type: string
            required: true
{
  "tools": [
    {
      "id": "pandas_query",
      "type": "command",
      "def": {
        "init": {
          "cmd": "pip install pandas"
        },
        "run": {
          "cmd": "python -c \"import pandas as pd; df = pd.read_csv('{file}'); print(df.query('{query}'))\"",
          "args": [
            {
              "name": "file",
              "type": "string",
              "required": true
            },
            {
              "name": "query",
              "type": "string",
              "required": true
            }
          ]
        }
      }
    }
  ]
}

The init command runs only once, before the first execution of the tool. This is useful for:

  • Installing dependencies
  • Setting up environments
  • Downloading required files

Complete Example

servers:
  - id: brave
    type: mcp
    def:
      cmd: npx -y @modelcontextprotocol/server-brave-search
      env:
        BRAVE_API_KEY: ${BraveApiKey}

tools:
  # MCP tool
  - id: brave_search
    type: mcp
    def:
      server: "@brave"
      tool: brave_web_search
  
  # Command tool without init
  - id: hello_world
    type: command
    def:
      run:
        cmd: echo Hello, World!
        args: []
  
  # Command tool with init
  - id: scrape_web
    type: command
    def:
      init:
        cmd: pip install beautifulsoup4 requests
      run:
        cmd: python -c "import requests; from bs4 import BeautifulSoup; print(BeautifulSoup(requests.get('{url}').text, 'html.parser').get_text())"
        args:
          - name: url
            type: string
            description: URL to scrape
            required: true
{
  "servers": [
    {
      "id": "brave",
      "type": "mcp",
      "def": {
        "cmd": "npx -y @modelcontextprotocol/server-brave-search",
        "env": {
          "BRAVE_API_KEY": "${BraveApiKey}"
        }
      }
    }
  ],
  "tools": [
    {
      "id": "brave_search",
      "type": "mcp",
      "def": {
        "server": "@brave",
        "tool": "brave_web_search"
      }
    },
    {
      "id": "hello_world",
      "type": "command",
      "def": {
        "run": {
          "cmd": "echo Hello, World!",
          "args": []
        }
      }
    },
    {
      "id": "scrape_web",
      "type": "command",
      "def": {
        "init": {
          "cmd": "pip install beautifulsoup4 requests"
        },
        "run": {
          "cmd": "python -c \"import requests; from bs4 import BeautifulSoup; print(BeautifulSoup(requests.get('{url}').text, 'html.parser').get_text())\"",
          "args": [
            {
              "name": "url",
              "type": "string",
              "description": "URL to scrape",
              "required": true
            }
          ]
        }
      }
    }
  ]
}

Best Practices

  • Use descriptive IDs: Tool IDs should be clear (e.g., brave_search, not bs)
  • Provide good descriptions: Help the agent understand what each tool does
  • Test commands independently: Verify command tools work in your shell first
  • Handle errors: Consider adding error handling to command tools
  • Use init wisely: Only use init for one-time setup, not for every execution

Related Documentation