---
adr_number: 11
title: Tool System
status_history:
- - '2026-02-16'
  - Proposed
  - Jeffrey Phillips Freeman
- - '2026-02-16'
  - Accepted
  - Jeffrey Phillips Freeman
tier: 2
authors:
- Jeffrey Phillips Freeman
superseded_by: null
related_adrs:
- number: 2
  title: Namespace System
  relationship: Tools use namespaced identifiers for discovery and conflict resolution
- number: 4
  title: Data Validation
  relationship: Tool input/output schemas are Pydantic models with JSON Schema generation
- number: 8
  title: Resource System
  relationship: Tools declare resource bindings that determine which resources they operate on
- number: 10
  title: Actor and Agent Architecture
  relationship: Tools serve as atomic execution nodes within actor graphs
- number: 12
  title: Skill System
  relationship: Skills compose tools into reusable collections for actor assignment
- number: 13
  title: Validation Abstraction
  relationship: Validations are a specialized Tool subtype with structured pass/fail semantics
- number: 15
  title: Sandbox and Checkpoint
  relationship: Tool invocations create checkpoints for rollback and recovery
- number: 28
  title: Agent Skills Standard (AgentSkills.io)
  relationship: Agent Skills are a tool source (`agent_skill`) integrated into the Tool Registry
- number: 29
  title: Model Context Protocol (MCP) Adoption
  relationship: MCP tools are registered as Tool records and follow the four-stage tool lifecycle
- number: 30
  title: Skill Abstraction Definition
  relationship: Tools are the atomic operations that skills collect and present to actors
- number: 37
  title: Tool Reachability and Access Projection
  relationship: Extends resource bindings with transitive reachability, access projection, and read/write routing
acceptance:
  votes_for:
  - voter: Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com>
    comment: The four-stage lifecycle with dual role as skill component and graph node is a clean unification
  votes_against: []
  abstentions: []
---
## Context

CleverAgents must integrate tools from multiple sources — built-in file/git operations, MCP server-hosted tools, Agent Skills (SKILL.md-based instructions), and custom user-defined tools. Each source has different discovery mechanisms, execution protocols, and capability characteristics. The system needs a uniform tool abstraction that normalizes these differences while preserving source-specific capabilities like checkpointing, resource binding, and sandbox awareness.

## Decision Drivers

- Must integrate tools from four distinct sources (built-in, MCP servers, Agent Skills, custom) with different discovery and execution protocols
- Tools must serve a dual role: as LLM tool-calling targets within skills and as deterministic graph nodes in actor workflows
- Resource bindings must decouple tools from specific resources, enabling portability across projects
- Need a uniform four-stage lifecycle (discover, activate, execute, deactivate) to normalize source-specific differences
- Change tracking must be driven by tool invocations, not by parsing LLM output, to ensure reliable auditable changesets
- Capability metadata (read-only, checkpointable, side effects) must be declared per tool to enable safety enforcement at runtime

## Decision

A **tool** is the atomic unit of execution — the smallest piece of functionality that can read, write, or transform resources. Tools are namespaced, independently registered, and follow a **four-stage lifecycle** (discover, activate, execute, deactivate). Every tool has a uniform interface regardless of source, and plays a **dual role**: as a component of a skill (available for LLM tool-calling) and as a tool node in an actor graph (deterministic, non-LLM execution step).

## Design

### Tool Identity and Registration

Tools follow the namespace system (`[[server:]namespace/]name`). They are defined in YAML, registered via `agents tool add --config <FILE>`, and stored in the persistent **Tool Registry**. The registry stores: name, description, source, config path, input/output schemas (JSON Schema), capability metadata, resource slots, and implementation code or server reference.

### Tool Sources

| Source | Discovery | Execution | Examples |
|--------|-----------|-----------|---------|
| **Built-in** | Hardcoded descriptors | Native Python calls | `read_file`, `write_file`, `edit_file`, `search_files` |
| **MCP** | MCP server `tools/list` | JSON-RPC `tools/call` | Any MCP-compliant server tool |
| **Agent Skill** | SKILL.md frontmatter parsing | Agent-mediated instruction following | Instruction-based tools from SKILL.md files |
| **Custom** | YAML registration | User-defined implementation | User-created tools |

### Four-Stage Lifecycle

**discover()**: Find and catalog the tool. Built-in: return hardcoded descriptors. MCP: spawn server, `initialize` handshake, `tools/list`. Agent Skill: parse SKILL.md frontmatter (~50-100 tokens). Custom: parse YAML definition.

**activate()**: Prepare the tool for use. Built-in: no-op. MCP: ensure server running, register for `notifications/tools/list_changed`. Agent Skill: load full SKILL.md body into agent context. Custom: load implementation.

**execute(params, ctx)**: Run the tool. Built-in: call native Python. MCP: translate to `tools/call` JSON-RPC, rewrite sandbox paths, validate params, record changes. Agent Skill: agent-mediated execution following instructions. Custom: user-defined execution.

**deactivate()**: Clean up. MCP: clean server shutdown. Agent Skill: remove instructions from context. Others: no-op.

### Dual Role

**As a skill component**: When an actor references a skill, all tools in that skill become available for LLM tool-calling. The LLM generates tool call requests, and the Tool Router validates and dispatches them.

**As an actor graph node**: `type: tool` nodes in actor graphs execute deterministically without LLM involvement. Can reference a named registered tool or define an anonymous inline tool.

### Tool Interface

```
Tool:
  Identity: name, qualified_name, source (mcp | agent_skill | builtin | custom)
  Schema: input_schema (JSONSchema), output_schema (JSONSchema)
  CapabilityMetadata: read_only, writes, write_scope, idempotent,
                      checkpointable, checkpoint_scope, side_effects,
                      cost_profile, human_approval_required
  ResourceBindings: slots (Map<String, ResourceSlot>)
  Lifecycle: discover(), activate(), execute(params, ctx), deactivate()
```

### Tool Adapter Layer

Each source has an adapter that translates to the uniform interface:

- **MCPToolAdapter**: Manages MCP server lifecycle, JSON-RPC communication, sandbox path rewriting, and capability inference from tool names.
- **AgentSkillAdapter**: Three-tier progressive disclosure (metadata ~50-100 tokens → instructions < 5000 tokens → resources variable).
- **BuiltinToolAdapter**: Direct native Python execution with hardcoded capability metadata.
- **CustomToolAdapter**: User-defined implementation with manually declared capabilities.

### Resource Bindings

Tools declare **resource slots** — named slots specifying what resource type and access mode is needed. Three binding modes:

- **Contextual** (default): Resolved from the plan's project at activation time.
- **Static**: Hardcoded to a specific resource by name via `bind` field.
- **Parameter**: Passed as argument at invocation time via `from_param` field.

Built-in tool groups have implicit resource slots (e.g., `file_operations` implicitly binds a `directory` slot of type `fs-directory` or `git-checkout`).

### Capability Metadata

Every tool declares capabilities: `read_only`, `writes`, `write_scope` (file paths, resource slots, environment), `idempotent`, `checkpointable`, `checkpoint_scope` (file, transaction, commit, snapshot), `side_effects`, `cost_profile`, and `human_approval_required`.

Metadata origin varies by source: built-in (hardcoded, not overridable), MCP (inferred + overrides), Agent Skill (SKILL.md frontmatter + overrides), custom (manually declared).

### Metadata Overrides

When referencing a named tool in a skill or actor graph, `capability` and `description` fields can be overridden at the point of use. Overrides are shallow-merged, never persist back to the registry, and cannot override schema or built-in metadata.

### Anonymous Tools

Inline tool definitions in skill YAML or actor graph nodes. Same format as named tools but unregistered, unnamespaced, and scoped only to their defining context.

### Tool Execution Flow

Six-step pipeline: LLM generates call → Tool Router validates → Resource binding resolution and sandbox setup → Adapter-specific execution → Change recording → Result return.

### Change Tracking

The changeset is built from tool invocations, not by parsing LLM output. Each tool execution receives a `ToolExecutionContext` with sandbox, plan, resources, and a changes recorder. Write operations record their changes directly.

## Constraints

- Tools must not parse LLM output to extract code or changes. All resource modification happens through tool invocations.
- `read_only: true` actions can only use tools where `read_only: true`. Enforced at runtime.
- Tool input/output schemas are JSON Schema, generated from Pydantic models where applicable.
- Anonymous tools share the same format as named tools but are scoped only to their defining skill or actor graph.
- Maximum tool calls per actor step is controlled by `plan.tool.max-calls-per-step` (default: 25).
- Maximum retries for transient failures is controlled by `plan.tool.max-retries` (default: 3).

## Consequences

### Positive
- A single tool interface normalizes four different sources (built-in, MCP, Agent Skill, custom) behind the same lifecycle and capability model.
- The dual role (skill component + graph node) maximizes tool reuse across LLM-driven and deterministic execution.
- Resource bindings decouple tools from specific resources, enabling portability across projects.
- Change tracking from tool invocations ensures reliable, auditable changesets.

### Negative
- The adapter layer adds complexity — each source requires its own adapter implementation with source-specific behavior.
- Capability inference for MCP tools (from tool names) is heuristic and may be inaccurate.
- The four-stage lifecycle adds overhead for simple tools that need no activation or deactivation.

### Risks
- MCP server availability is an external dependency. Server crashes or network failures during execution require retry and recovery logic.
- Agent Skill tools depend on LLM instruction-following quality, which is less reliable than programmatic execution.
- The capability metadata for custom and MCP tools is self-declared and may be inaccurate.

## Alternatives Considered

None — specification-driven requirement. The tool system with its four-stage lifecycle, dual role, adapter layer, and resource binding model is prescribed by the specification.

## Compliance

- **Adapter conformance tests**: Each adapter (MCP, Agent Skill, Built-in, Custom) has tests verifying correct lifecycle behavior across all four stages.
- **Resource binding tests**: Tests verify all three binding modes with correct resolution and error handling for missing bindings.
- **Capability enforcement tests**: Tests verify that `read_only` actions reject tools with `writes: true`, and that `human_approval_required` tools trigger approval gates.
- **Change tracking tests**: Tests verify that the changeset accurately reflects all tool invocations and contains no changes from LLM output parsing.
- **Schema validation**: Tool registration validates input/output schemas against JSON Schema specification.
