Problem
Plugins that need to make policy decisions about tool calls currently rely on tool name matching. This is brittle: tool names change, custom tools have unpredictable names, and the same policy logic ("block tools that send data externally") has to maintain a hardcoded list of tool names.
Proposal
Add an optional capabilities field to tool definitions that lets each tool self-declare what it does:
// Proposed addition to AnyAgentTool or tool metadata
capabilities?: {
readsExternalData?: boolean; // web_search, web_fetch, browser, email read
writesPersistentState?: boolean; // memory write, file write, cron create, config
sendsExternally?: boolean; // message send, email send, webhook
executesPrivileged?: boolean; // exec, elevated commands
createsAutonomousActions?: boolean; // cron job creation, scheduled tasks
};
Built-in tools self-declare. Plugin-registered tools can optionally declare. Undeclared capabilities default to undefined (unknown), not false (safe).
Use cases
- Policy engines can write rules against stable metadata instead of brittle tool name lists
- Permission defaults can use capabilities to suggest appropriate security posture during onboarding
- Documentation improves: openclaw tools list --capabilities shows what each tool does at a glance
- Audit logging can categorize tool calls by capability without maintaining a separate mapping
What exists today
Tools have name, description, and parameters. There is no structured metadata about what a tool does beyond its description string. before_tool_call hooks receive toolName and params but no capability metadata. A policy plugin that wants to block "tools that send data externally" has to maintain a hardcoded list of tool names. Every new tool or plugin breaks that list.
Trust model and undeclared capabilities
Three categories of tools exist in OpenClaw:
- Built-in tools (OpenClaw core): maintainers self-declare. Trustworthy because they are in the same codebase and subject to the same review process.
- Plugin-registered tools: third-party plugins declare their own capabilities. A malicious or sloppy plugin could misdeclare, but this follows the same trust model as plugin registration itself. If you install an untrusted plugin, it can already do anything the agent can do. Capability descriptors do not make that worse; they make it easier for auditors to spot mismatches.
- Undeclared tools: capabilities default to undefined (unknown), not false (safe). A policy engine should treat undeclared capabilities as untrusted by default. Absence of declaration is not clearance.
Connection to before_tool_call (#48503)
Capability descriptors become actionable when surfaced through the enriched before_tool_call event proposed in #48503. A policy plugin receives the tool call with both the declared capabilities and the input provenance, enabling rules like: "if capabilities.sendsExternally and provenance is inter_session, then block or request approval." Without capability descriptors, the same policy requires brittle tool name matching. Without the enriched hook, the descriptors have no enforcement surface.
Backward compatibility
All fields optional. Zero behavior change for existing tools. Plugin-registered tools that do not declare capabilities continue to work exactly as they do today. Policies that check capabilities on undeclared tools see undefined and can apply their own default (block, allow, or prompt).
Context: See Building a CaMeL Prototype for OpenClaw for full motivation and architectural analysis.
Problem
Plugins that need to make policy decisions about tool calls currently rely on tool name matching. This is brittle: tool names change, custom tools have unpredictable names, and the same policy logic ("block tools that send data externally") has to maintain a hardcoded list of tool names.
Proposal
Add an optional capabilities field to tool definitions that lets each tool self-declare what it does:
Built-in tools self-declare. Plugin-registered tools can optionally declare. Undeclared capabilities default to undefined (unknown), not false (safe).
Use cases
What exists today
Tools have name, description, and parameters. There is no structured metadata about what a tool does beyond its description string. before_tool_call hooks receive toolName and params but no capability metadata. A policy plugin that wants to block "tools that send data externally" has to maintain a hardcoded list of tool names. Every new tool or plugin breaks that list.
Trust model and undeclared capabilities
Three categories of tools exist in OpenClaw:
Connection to before_tool_call (#48503)
Capability descriptors become actionable when surfaced through the enriched before_tool_call event proposed in #48503. A policy plugin receives the tool call with both the declared capabilities and the input provenance, enabling rules like: "if capabilities.sendsExternally and provenance is inter_session, then block or request approval." Without capability descriptors, the same policy requires brittle tool name matching. Without the enriched hook, the descriptors have no enforcement surface.
Backward compatibility
All fields optional. Zero behavior change for existing tools. Plugin-registered tools that do not declare capabilities continue to work exactly as they do today. Policies that check capabilities on undeclared tools see undefined and can apply their own default (block, allow, or prompt).
Context: See Building a CaMeL Prototype for OpenClaw for full motivation and architectural analysis.