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: search
type: mcp
description: Search the web using Brave Search
def:
server: "@brave"
tool: brave_web_search {
"tools": [
{
"id": "search",
"type": "mcp",
"description": "Search the web using Brave Search",
"def": {
"server": "@brave",
"tool": "brave_web_search"
}
}
]
} Reference a server using @server-id and specify which tool from that server to expose.
Qualified Tool Names
When exposed via MCP, each tool receives a qualified name that combines the server ID and tool ID:
- MCP tools:
server_id.tool_id(e.g.,brave.search) - Command tools: plain
tool_id(e.g.,greet_user)
In skill requires arrays, reference MCP tools with the @server_id.tool_id format (e.g., @brave.search). Command tools use their plain ID. In the CLI, MCP tools map to capa sh server_id tool_id (e.g., capa sh brave search).
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. The tool's id should be a short, descriptive name — CAPA automatically qualifies it as server_id.tool_id when exposed via MCP:
# 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"
}
}
]
} These tools are exposed to MCP clients as filesystem.read_file and filesystem.write_file. In skill requires, reference them as @filesystem.read_file and @filesystem.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 agentrequired: 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"
}
}
]
} Default Arguments
MCP tools support an optional defaults map that provides pre-filled argument values. Parameters with defaults are exposed as optional in the MCP schema and in capa sh --help, so the AI (or CLI user) only needs to supply them when overriding. At call time, caller-supplied values take precedence over defaults.
tools:
- id: searchIssue
type: mcp
description: Search Jira issues
def:
server: "@atlassian"
tool: getJiraIssue
defaults:
cloudId: "abc123-def456" {
"tools": [
{
"id": "searchIssue",
"type": "mcp",
"description": "Search Jira issues",
"def": {
"server": "@atlassian",
"tool": "getJiraIssue",
"defaults": {
"cloudId": "abc123-def456"
}
}
}
]
} In this example, cloudId is always sent as "abc123-def456" unless the caller explicitly provides a different value. The parameter still appears in the schema (with its default shown) but is no longer required.
This is useful when:
- A parameter is always the same for a given project (e.g., cloud IDs, workspace names, project keys)
- You want to simplify the tool interface without losing the ability to override
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 Deploy a service to production
rollback-service Roll back a service to the previous version
Usage: capa sh deploy <subcommand> [--arg val]
capa sh deploy <subcommand> --help Show parameter details 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
description: Brave web search
def:
cmd: npx -y @modelcontextprotocol/server-brave-search
env:
BRAVE_API_KEY: ${BraveApiKey}
tools:
# MCP tool — exposed as brave.search
- id: search
type: mcp
description: Search the web using Brave Search
def:
server: "@brave"
tool: brave_web_search
# Command tool without init — exposed as hello_world
- id: hello_world
type: command
def:
run:
cmd: echo Hello, World!
args: []
# Command tool with init — exposed as scrape_web
- 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",
"description": "Brave web search",
"def": {
"cmd": "npx -y @modelcontextprotocol/server-brave-search",
"env": {
"BRAVE_API_KEY": "${BraveApiKey}"
}
}
}
],
"tools": [
{
"id": "search",
"type": "mcp",
"description": "Search the web using Brave Search",
"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 short and clear (e.g.,
search, nots). For MCP tools, the server ID is prepended automatically (e.g.,brave.search) - 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
- Servers - Define MCP servers for tools
- Skills - Teach agents how to use tools
- Capabilities File - Overall structure
- capa sh - Run tools directly from the command line