Files
cleveragents-core/docs/api/protocols.md
T
HAL9000 236d1abd80
CI / push-validation (pull_request) Successful in 16s
CI / build (pull_request) Successful in 24s
CI / helm (pull_request) Successful in 28s
CI / quality (pull_request) Successful in 32s
CI / lint (pull_request) Successful in 34s
CI / typecheck (pull_request) Successful in 48s
CI / security (pull_request) Successful in 59s
CI / e2e_tests (pull_request) Successful in 3m3s
CI / integration_tests (pull_request) Successful in 3m54s
CI / unit_tests (pull_request) Successful in 5m0s
CI / docker (pull_request) Successful in 11s
CI / coverage (pull_request) Successful in 10m50s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m42s
docs: add API documentation (CLI reference, Python API, protocols) [AUTO-DOCS-2]
2026-04-13 05:09:31 +00:00

17 KiB

Protocols

CleverAgents deliberately adopts open, versioned protocols so that clients, tools, and skills can interoperate without bespoke integrations.

Protocol Role
A2A Versioned client-server contract (JSON-RPC 2.0)
MCP Tool discovery and invocation over a server boundary
LSP Language intelligence for actors and agents
AgentSkills.io Packaging instruction-driven, multi-step workflows

Guiding principles:

  1. Prefer open protocols — align with community standards to keep integrations portable.
  2. Keep adapters at the edge — standards map into stable internal domain models so core logic remains protocol-agnostic.

A2A — Agent-to-Agent Protocol

Standard: a2a-protocol.org
ADRs: ADR-026, ADR-047, ADR-048
Python API: cleveragents.a2a

Overview

A2A is the sole communication protocol for all client-server interaction in CleverAgents. It is built on JSON-RPC 2.0 and defines the fundamental boundary between the Presentation and Application layers. Every CLI command, TUI action, and IDE plugin operation flows through A2A regardless of deployment mode.

A2A is the successor to the Agent Client Protocol (ACP), which is now deprecated. A2A retains backward compatibility with ACP's JSON-RPC 2.0 foundation.

Wire Format

All A2A messages follow the JSON-RPC 2.0 specification:

// Request
{
  "jsonrpc": "2.0",
  "id": "req-001",
  "method": "session.create",
  "params": {
    "actor": "openai/gpt-4o"
  }
}

// Success response
{
  "jsonrpc": "2.0",
  "id": "req-001",
  "result": {
    "session_id": "sess-abc123",
    "actor": "openai/gpt-4o",
    "created_at": "2026-04-13T10:00:00Z"
  }
}

// Error response
{
  "jsonrpc": "2.0",
  "id": "req-001",
  "error": {
    "code": -32000,
    "message": "Actor not found: openai/gpt-4o",
    "data": {"actor": "openai/gpt-4o"}
  }
}

Breaking change (v3.7.0+): Fields were renamed to comply with JSON-RPC 2.0. a2a_versionjsonrpc, request_idid, operationmethod, dataresult. See the CHANGELOG for the full migration table.

Standard A2A Operations

Method Description
message/send Send a message to an agent
message/stream Stream a message response via SSE
tasks/get Get task status
tasks/cancel Cancel a running task
agent/authenticatedExtendedCard Retrieve the Agent Card (capability discovery)

CleverAgents Extension Methods

CleverAgents extends A2A with _cleveragents/-prefixed methods (declared via the A2A extension mechanism):

Method Description
session.create Create a new conversation session
session.close Close an existing session
plan.create Instantiate a plan from an action
plan.execute Execute a plan
plan.status Query plan status
plan.diff Retrieve the sandbox diff
plan.apply Apply the sandbox changeset
plan.correct Correct a decision
registry.list_tools List available tools
registry.list_resources List available resources
registry.list_actors List available actors
registry.list_skills List available skills
event.subscribe Subscribe to the event stream
diagnostics.run Run diagnostics

Deployment Modes

Mode Transport Description
Local stdio (JSON-RPC) Agent runs as a subprocess; A2A flows in-process via A2aLocalFacade
Server HTTP A2A flows over HTTP to the CleverAgents server
from cleveragents.a2a import A2aLocalFacade, A2aRequest

# Local mode — no network, no serialization overhead
facade = A2aLocalFacade(container)
response = await facade.dispatch(
    A2aRequest(method="session.create", params={"actor": "openai/gpt-4o"})
)
session_id = response.result["session_id"]

Agent Card Discovery

The A2A Agent Card (agent/authenticatedExtendedCard) exposes the platform's capabilities for ecosystem interoperability:

{
  "name": "CleverAgents",
  "version": "1.0.0",
  "description": "Unified AI agent orchestration platform",
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "stateTransitionHistory": true
  },
  "extensions": [
    {
      "uri": "https://cleverthis.com/a2a/extensions/plan-lifecycle",
      "methods": ["plan.create", "plan.execute", "plan.apply", "plan.diff", "plan.correct"]
    },
    {
      "uri": "https://cleverthis.com/a2a/extensions/registry",
      "methods": ["registry.list_tools", "registry.list_resources", "registry.list_actors"]
    }
  ]
}

Event Streaming

Subscribe to plan and session events via the A2A event stream:

from cleveragents.a2a import A2aEventQueue

queue = A2aEventQueue()
async for event in queue.subscribe("plan-01JXYZ..."):
    print(event.type, event.payload)
    if event.type == "plan.applied":
        break

queue.close()  # release resources on shutdown

Error Codes

Code Name Description
-32700 Parse error Invalid JSON
-32600 Invalid request Not a valid JSON-RPC 2.0 request
-32601 Method not found Unknown A2A method
-32602 Invalid params Invalid method parameters
-32603 Internal error Internal server error
-32000 Application error CleverAgents domain error
-32001 Not available Operation not available in current mode
-32002 Version mismatch Incompatible A2A protocol versions

MCP — Model Context Protocol

Standard: modelcontextprotocol.io
ADR: ADR-029
Python API: cleveragents.mcp

Overview

MCP is the standard for discovering and invoking external tools over a server boundary via JSON-RPC. CleverAgents bridges MCP servers into the Tool Registry via the MCPToolAdapter, giving actors plug-and-play access to a growing ecosystem of tool providers.

Supported Transports

Transport Description
stdio Spawn a subprocess and communicate over stdin/stdout
sse Server-Sent Events over HTTP
streamable-http Streamable HTTP (MCP 1.1+)

Connecting an MCP Server

from cleveragents.mcp import MCPToolAdapter, MCPServerConfig
from cleveragents.tool import ToolRegistry

# Configure the MCP server
config = MCPServerConfig(
    name="bash-tools",
    transport="stdio",
    command="uvx",
    args=["mcp-server-bash"],
)

# Connect and discover tools
adapter = MCPToolAdapter(config)
await adapter.connect()
tools = await adapter.discover_tools()

# Register tools into the CleverAgents Tool Registry
registry = ToolRegistry()
adapter.register_tools(registry)

# Invoke a tool
result = await adapter.invoke("bash", {"command": "ls -la"})
print(result.content)

await adapter.disconnect()

MCP Server Configuration Reference

Field Type Description
name str Server identifier (used as tool namespace prefix)
transport str "stdio" | "sse" | "streamable-http"
command str | None Spawn command (stdio only)
args list[str] Command-line arguments
env dict[str, str] Environment variables passed to the server process
url str | None Server URL (sse/http only)
headers dict[str, str] HTTP headers (sse/http only)

Tool Discovery

MCP tools are discovered via the tools/list method and registered in the Tool Registry with source="mcp". Each discovered tool becomes a MCPToolDescriptor:

class MCPToolDescriptor(BaseModel):
    name: str
    description: str
    input_schema: dict[str, Any]   # JSON Schema
    annotations: dict[str, Any]

Sandbox Path Rewriting

When running tools inside a sandbox, the SandboxPathRewriter rewrites absolute host paths in tool arguments and results to sandbox-relative paths, preventing path traversal outside the sandbox root:

from cleveragents.mcp import SandboxPathRewriter, SandboxPathRewriterConfig

rewriter = SandboxPathRewriter(
    SandboxPathRewriterConfig(
        sandbox_root="/sandbox",
        host_root="/home/user/project",
    )
)
rewritten_args = rewriter.rewrite_args(tool_args)

Skill Refresh Notifications

When an MCP server's tool list changes at runtime, MCPRefreshHook wires notifications/tools/list_changed events to SkillRegistry.refresh_all():

from cleveragents.mcp import MCPRefreshHook

hook = MCPRefreshHook(skill_registry)
adapter.on_tools_changed(hook.on_tools_changed)

MCP Client Lifecycle

STOPPED → STARTING → RUNNING → STOPPING → STOPPED
                              ↘ ERROR

The McpClient manages lazy start (server is only started when first needed) and auto-stop after a configurable idle timeout:

from cleveragents.mcp import McpClient, McpClientConfig

client_config = McpClientConfig(server=server_config, auto_stop_idle_secs=60)
client = McpClient(client_config)

async with client:
    tools = await client.list_tools()
    result = await client.call_tool("bash", {"command": "echo hello"})

LSP — Language Server Protocol

Standard: microsoft.github.io/language-server-protocol
ADR: ADR-027

Overview

LSP is the standard for attaching language intelligence to actors and agents. CleverAgents registers LSP servers in the global LSP Registry and binds them to actor graph nodes via YAML configuration. When an actor activates, the LSP Runtime starts the appropriate language servers for the actor's bound languages and workspace resources.

Capabilities Exposed to Actors

LSP capabilities are exposed to actors in two ways:

  1. As callable tools via LSPToolAdapter — actors can invoke LSP operations (diagnostics, completions, references, rename, code actions) as regular tool calls.
  2. As automatic context enrichment — diagnostics and type annotations are injected into the ACMS hot context automatically.
LSP Capability Tool Name Description
textDocument/diagnostic lsp.diagnostics Get diagnostics for a file
textDocument/hover lsp.hover Get type info and documentation at a position
textDocument/definition lsp.definition Go to definition
textDocument/references lsp.references Find all references
textDocument/completion lsp.completion Get completions at a position
textDocument/rename lsp.rename Rename a symbol
textDocument/codeAction lsp.code_action Get available code actions
textDocument/signatureHelp lsp.signature_help Get function signature help

Registering an LSP Server

# Register a Python LSP server
agents lsp add --config examples/lsp/pyright.yaml

# List registered LSP servers
agents lsp list --language python

# Show LSP server details
agents lsp show local/pyright

LSP server YAML configuration:

name: local/pyright
language: python
command: pyright-langserver
args: ["--stdio"]
env: {}
workspace_mapping: auto   # auto | explicit

Actor YAML Binding

Bind LSP servers to actor graph nodes in the actor YAML:

name: local/my-python-actor
entry_node: analyze
nodes:
  analyze:
    type: llm
    lsp_binding:
      language: python        # bind by language (auto-selects server)
      # or:
      server: local/pyright   # bind by explicit server name

Different nodes in an actor's graph can have different LSP bindings, enabling fine-grained control over which agents receive which language intelligence.

LSP Runtime

The LSP Runtime in the Infrastructure layer manages:

  • Server lifecycle — start, stop, health monitoring
  • Workspace mapping — maps project resources to LSP workspace folders
  • File synchronization — keeps LSP server in sync with resource changes
  • Capability negotiation — negotiates supported capabilities during initialization

Auto-Discovery

Actors can bind LSP servers automatically based on the languages detected in their project's resources:

lsp_binding:
  mode: auto   # detect languages from project resources

AgentSkills.io

Standard: AgentSkills.io
ADRs: ADR-028, ADR-030
Python API: cleveragents.skills

Overview

AgentSkills.io is the standard for packaging instruction-driven, multi-step workflows as SKILL.md files with progressive disclosure. Agent Skills complement MCP tools by teaching agents how to accomplish complex tasks rather than simply exposing callable functions.

Skill Bundle Structure

An AgentSkills-compatible skill bundle is a directory with the following layout:

my-skill/
├── SKILL.md          # Required: skill definition with progressive disclosure
├── scripts/          # Optional: executable scripts referenced by steps
│   └── deploy.sh
├── references/       # Optional: reference documents
│   └── api-spec.md
└── assets/           # Optional: static assets
    └── schema.json

SKILL.md Format

# Deploy to Staging

## Description
Deploys the application to the staging environment.

## Steps

### 1. Run tests
Execute the test suite and verify all tests pass.

```bash
scripts/run-tests.sh

2. Build artifacts

Build the deployment artifacts.

3. Deploy

Deploy to the staging environment using the deployment script.

scripts/deploy.sh --env staging

Definition of Done

  • All tests pass
  • Application is accessible at the staging URL
  • Health check returns 200

### Loading a Skill Bundle

```python
from pathlib import Path
from cleveragents.skills import AgentSkillLoader

loader = AgentSkillLoader.from_folder(Path("./skills/deploy-to-staging"))
spec = loader.load()

print(spec.name)     # "deploy-to-staging"
print(spec.version)  # "1.0.0"
for step in spec.steps:
    print(f"  Step: {step.title}")

Discovering Skills

from cleveragents.skills import discover_agent_skills, register_discovered_skills

result = discover_agent_skills([Path("./skills/")])
for skill in result.skills:
    print(f"Found: {skill.name} v{skill.version}")

# Register all discovered skills
register_discovered_skills(result, skill_registry)

Registering via CLI

# Register a skill from a YAML config
agents skill add --config examples/skills/deploy.yaml

# Or discover from a directory (set CLEVERAGENTS_SKILLS_PATH)
export CLEVERAGENTS_SKILLS_PATH=/path/to/skills:/another/path
agents skill list   # shows all discovered skills

Progressive Disclosure

AgentSkills.io uses a three-tier progressive disclosure model:

Tier Description
Discover Actor learns the skill exists and its high-level description
Activate Actor loads the full SKILL.md and step details
Deactivate Actor releases the skill when no longer needed

This keeps the actor's context window lean — skills are only fully loaded when the actor decides to use them.

AgentSkillSpec

The parsed representation of a skill bundle:

class AgentSkillSpec(BaseModel):
    name: str
    version: str
    steps: list[SkillStep]
    tools: list[AgentSkillToolDescriptor]
    resource_slots: list[AgentSkillResourceSlot]

Inline Executor

Skills can define steps as inline Python callables rather than external tool calls. The InlineToolExecutor handles these:

from cleveragents.skills import InlineToolExecutor

executor = InlineToolExecutor()
result = await executor.execute(step, context)

Skill Context

The SkillContext carries runtime state during skill execution:

class SkillContext:
    session_id: str
    plan_id: str
    bound_resources: list[BoundResource]
    cancellation_token: CancellationToken
    invocation_history: list[ToolInvocationRecord]

Protocol Interoperability

The four protocols work together in a layered fashion:

User / IDE / CI
      ↓
   A2A (JSON-RPC 2.0)          ← all client-server communication
      ↓
CleverAgents Application
      ↓
  ┌───────────────────────────────────────┐
  │  MCP Adapter   LSP Runtime   Skills  │  ← tool/intelligence/skill sources
  └───────────────────────────────────────┘
      ↓
  Tool Registry  ←  all tools unified here
      ↓
  Actor (LangGraph)  ←  executes plans using tools
  • A2A is the outer boundary — all clients speak A2A.
  • MCP brings external tools into the Tool Registry.
  • LSP brings language intelligence into actor context and as tools.
  • AgentSkills.io brings instruction-driven workflows as activatable skills.

All four integrate into the same internal domain model, so actors see a unified surface regardless of where a tool or skill originated.