Skip to content

Tool exposure

Set options.toolExposure in your capabilities file to control what MCP clients see after capa install. The mode changes both tools/list and whether capa writes project-local MCP config files.

options:
toolExposure: search # expose-all | on-demand | search | none

capa init writes toolExposure: search into new capabilities files. If the option is omitted, capa falls back to expose-all.

ModeWhat tools/list returnsMCP config filesHow the agent calls tools
expose-all (default when omitted)Every tool required by any active skill, plus every tool a server exposes through its expose policy (full schemas)Written (main capa entry + sub-agent entries as needed)Direct MCP tools/call
on-demandOnly meta-tools setup_tools and call_toolWritten (same as expose-all)Call setup_tools(['<skill>']) or setup_tools(['@<server>']), then call_tool(name, data)
search (written by capa init)Only meta-tools search and call_toolWritten (same as expose-all)Call search('<what you need to do>'), then call_tool(name, data)
noneEmpty listNot written: capa skips .mcp.json / .cursor/mcp.json / Codex MCP entries and removes previously written onesInvoke via capa sh <group> <tool>

Use search when servers expose many tools. The agent finds tools by the task at hand, for example search('open a pull request'), and only the matches enter its context. This is the default for new projects.

Use expose-all when you want the client to discover every tool up front. Best for small toolsets and interactive IDE agents.

Use on-demand when you want tools grouped by skill. The agent activates a skill (or a whole server with @server) when needed; setup_tools returns compact signatures.

Use none when policy forbids per-project MCP config edits, or you prefer shell-driven invocation. The capa HTTP server still runs; tools/list stays empty so MCP clients do not harvest the full tool list, while capa sh continues to execute tools.

In on-demand and search, invalid call_tool arguments return the tool’s full input schema so the agent can retry.

  • search matches a tool’s id, remote name, server or group, and description. Plain term matching, no embeddings.
  • It returns the best matches (default 10, limit up to 50) as compact signatures with descriptions. An empty query lists tools alphabetically.
  • Matches become callable right away and stay callable for the session, so searches accumulate.
  • Every tool in the project is searchable. Skill requires: has no effect in this mode, and the Web UI hides it.
  • setup_tools is not available; calling it returns a pointer to search.

Each MCP server decides which of its live tools become capa tools with expose. You do not need one tools: entry per remote tool.

exposeTools capa exposes
all (default when omitted)Every tool the server advertises
exceptEvery tool except the names in the server’s tools list
exactlyOnly the names in the server’s tools list
noneNothing from the policy; only explicit tools: entries
servers:
- id: github
type: mcp
expose: except
tools: [delete_repo, force_push] # remote tool names, not capa ids
def:
url: https://example.com/mcp
  • The server’s tools list holds remote tool names. It is required for except and exactly, and not allowed with all or none.
  • Exposed tools keep their remote names (for example github.create_issue) and are callable without a skill requires: entry.
  • Declaring tools yourself turns the policy off. Once any top-level tools: entry points at a server, those entries are the whole set for that server and its expose is ignored (install prints a warning).
  • capa lists the server’s tools when it configures the project on capa install. They are never written back to the capabilities file. Names in except / exactly that the server does not advertise produce install warnings.
  • capa registers its MCP entry for a project even when all its tools come from server policies.