Use capability tags to control which tools an agent is allowed to invoke.
Capabilities decide which tools an agent is permitted to call. Each tool declares the capability tags it requires, and the agent declares the tags it holds. A tool is callable only when the agent holds every tag the tool requires. This guide shows how to set that up. For the underlying idea, see Tools and capabilities.
Capabilities only gate tool invocation. They do not change what the runtime libraries expose to guest code. That environment is shared across components and is described at Runtime libraries.
Add a capabilities list to each tool that should be gated. The convention is namespace::operation,
but the tags are arbitrary strings you choose:
tool "adder" {
kind = "javascript"
source = "./tools/math"
capabilities = ["math::add"]
}
tool "get_weather" {
kind = "python"
source = "./tools/weather"
capabilities = ["weather::get"]
}A tool with no capabilities is always available. Grant tags only to the tools you want to gate, and
leave freely available tools untagged.
The agent's capabilities list declares what it holds. Matching is prefix-based over the ::
namespace, so granting math satisfies any tool requiring math::add or math::subtract, while
granting math::add satisfies only that one:
agent "assistant" {
graph {
type = "react"
}
capabilities = ["math", "weather::get"]
model {
provider = "anthropic"
name = "claude-haiku-4-5"
}
}Here the agent can call any math tool and the specific weather::get tool, but not a tool requiring,
say, filesystem::write.
By default the agent's capability set is fixed to the manifest. The capability_policy field controls
whether a client may change it for a single session:
agent "assistant" {
graph {
type = "react"
}
capabilities = ["math", "weather::get"]
capability_policy = "extensible"
model {
provider = "anthropic"
name = "claude-haiku-4-5"
}
}locked, the default, ignores any capability override a client sends. extensible lets a client add
to the set, or replace it, for that session. Use extensible when different callers should reach
different tools; keep locked when the manifest is the sole authority. Untagged tools stay available
under either policy.
Skills are exposed to the agent through built-in skill tools, which are gated like any other tool. For
an agent to use skills at all, grant it the skills capability:
capabilities = ["skills", "math"]An A2A tool block creates four operation tools for one downstream agent. The capabilities list on
the block gates all four operations together:
tool "planner" {
kind = "a2a"
url = runtime("PLANNER_A2A_URL")
capabilities = ["a2a::planner"]
}Grant the agent that capability when it is allowed to delegate work to the planner:
capabilities = ["a2a::planner"]capabilities and capability_policy fields.capabilities field on each tool kind.© 2026 pogue.dev. All rights reserved.
CC BY 4.0Search the agentc documentation