Adds a complete end-to-end walkthrough of the server connection CLI commands and A2A protocol facade, verified by the UAT system with real command outputs. Covers: - agents server --help, connect, status, serve commands - All output formats (rich, json, yaml, plain) - A2A JSON-RPC 2.0 wire format (A2aRequest, A2aResponse, A2aEvent) - A2aLocalFacade: 42 supported operations, stub mode, service wiring - get_facade() wired to real DI container - A2aVersionNegotiator: version negotiation and mismatch handling - ServerConnectionConfig: validation rules Also updates examples.json index with the new entry.
31 KiB
Server Connection and A2A Protocol Integration
Overview
CleverAgents ships with a server connection subsystem and an Agent-to-Agent (A2A) protocol facade that together form the foundation for distributed, multi-agent deployments. This example walks through the complete workflow: configuring a server endpoint, inspecting connection status, understanding the A2A JSON-RPC 2.0 wire format, and using the local-mode facade to dispatch operations directly to application services.
Prerequisites
- CleverAgents installed (
pip install cleveragents) - Python 3.12 or higher
What You'll Learn
- How to configure a server endpoint with
agents server connect - How to inspect server connection status with
agents server status - How to understand the A2A JSON-RPC 2.0 wire format (request/response/event models)
- How to use the A2A local-mode facade to dispatch operations programmatically
- How to wire real services into the facade via
get_facade()andregister_service() - How to handle version negotiation with
A2aVersionNegotiator - How to validate server configuration with
ServerConnectionConfig
Part 1: Server Connection CLI
Step 1: Explore the server subcommand
$ agents server --help
Output:
Usage: agents server [OPTIONS] COMMAND [ARGS]...
Server connection management (stub)
╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ───────────────────────────────────────────────────────────────────╮
│ connect Connect to a CleverAgents server (stub). │
│ status Show current server connection status. │
│ serve Run the CleverAgents ASGI server process. │
╰──────────────────────────────────────────────────────────────────────────────╯
What's Happening:
The server subcommand has three commands:
connect— registers a server URL in the configurationstatus— shows the current server mode and configured URLserve— launches the ASGI server process (for container/Kubernetes deployments)
Step 2: Check server status before configuration
$ agents server status
Output:
╭─────── Server Status ────────╮
│ Server Mode: disabled │
│ Server URL: (not configured) │
│ Namespace: default │
│ TLS Verify: True │
╰──────────────────────────────╯
Output (JSON format):
$ agents server status --format json
{
"command": "",
"status": "ok",
"exit_code": 0,
"data": {
"server_mode": "disabled",
"server_url": null,
"namespace": "default",
"tls_verify": true
},
"timing": {
"duration_ms": 0
},
"messages": [
{
"level": "ok",
"text": "ok"
}
]
}
What's Happening:
server_mode: "disabled" means no server URL has been configured. The system
operates in local mode — all operations are handled by in-process services.
Step 3: Connect to a server
$ agents server connect https://agents.example.com
Output:
╭────────────────────────── Server Connection (Stub) ──────────────────────────╮
│ Server URL: https://agents.example.com │
│ Namespace: default │
│ TLS Verify: True │
│ Status: stubbed │
│ │
│ Server connection is not yet implemented. The URL has been saved to │
│ configuration but no connection will be made. │
╰──────────────────────────────────────────────────────────────────────────────╯
Output (JSON format):
$ agents server connect https://agents.example.com --format json
{
"command": "",
"status": "ok",
"exit_code": 0,
"data": {
"server_url": "https://agents.example.com",
"namespace": "default",
"tls_verify": true,
"status": "stubbed",
"warning": "Server connection is not yet implemented. The URL has been saved to configuration but no connection will be made."
},
"timing": {
"duration_ms": 0
},
"messages": [
{
"level": "ok",
"text": "ok"
}
]
}
What's Happening:
The connect command validates the URL (must start with http:// or https://),
then persists three settings to ~/.cleveragents/config.toml:
server.url— the server endpointserver.namespace— the namespace (default:"default")server.tls-verify— whether to verify TLS certificates (default:true)
Each setting change emits a CONFIG_CHANGED audit event, ensuring a full audit
trail for these security-relevant settings.
Step 4: Connect with a custom namespace
$ agents server connect https://agents.example.com --namespace my-team --format json
Output:
{
"command": "",
"status": "ok",
"exit_code": 0,
"data": {
"server_url": "https://agents.example.com",
"namespace": "my-team",
"tls_verify": true,
"status": "stubbed",
"warning": "Server connection is not yet implemented. The URL has been saved to configuration but no connection will be made."
},
"timing": {
"duration_ms": 0
},
"messages": [
{
"level": "ok",
"text": "ok"
}
]
}
What's Happening:
The --namespace (or -n) flag sets the namespace on the server. Namespaces
allow multiple teams or projects to share a single CleverAgents server instance
with isolated resources.
Step 5: Connect to a local dev server (no TLS)
$ agents server connect http://localhost:8080 --no-tls-verify --format json
Output:
{
"command": "",
"status": "ok",
"exit_code": 0,
"data": {
"server_url": "http://localhost:8080",
"namespace": "default",
"tls_verify": false,
"status": "stubbed",
"warning": "Server connection is not yet implemented. The URL has been saved to configuration but no connection will be made."
},
"timing": {
"duration_ms": 0
},
"messages": [
{
"level": "ok",
"text": "ok"
}
]
}
What's Happening:
--no-tls-verify disables certificate verification — useful for local
development with self-signed certificates. Never use this in production.
Step 6: Check status after connecting
$ agents server status
Output:
╭──────────── Server Status ─────────────╮
│ Server Mode: stubbed │
│ Server URL: https://agents.example.com │
│ Namespace: default │
│ TLS Verify: True │
╰────────────────────────────────────────╯
Output (YAML format):
$ agents server status --format yaml
command: ''
status: ok
exit_code: 0
data:
server_mode: stubbed
server_url: https://agents.example.com
namespace: default
tls_verify: true
timing:
duration_ms: 0
messages:
- level: ok
text: ok
Output (plain format):
$ agents server status --format plain
server_mode: stubbed
server_url: https://agents.example.com
namespace: default
tls_verify: True
What's Happening:
server_mode: "stubbed" means a URL is configured but the actual network
client is not yet implemented. The two possible modes are:
| Mode | Meaning |
|---|---|
disabled |
No server URL configured — local mode only |
stubbed |
URL configured, but network client not yet implemented |
Step 7: Validation — invalid URL rejected
$ agents server connect not-a-url --format json
Output (exit code 1):
Invalid server configuration: 1 validation error for ServerConnectionConfig
server_url
Value error, server_url must start with http:// or https://
What's Happening:
The connect command validates the URL using ServerConnectionConfig (a
Pydantic model) before writing anything to disk. Invalid URLs are rejected
immediately with a clear error message and exit code 1.
Step 8: Explore the serve command options
$ agents server serve --help
Output:
Usage: agents server serve [OPTIONS]
Run the CleverAgents ASGI server process.
This command is used by container runtimes (Docker/Kubernetes) to launch
the server endpoint using the project CLI entrypoint (`python -m
cleveragents`).
╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --host TEXT Bind address for the ASGI │
│ server │
│ [default: 0.0.0.0] │
│ --port INTEGER RANGE [1<=x<=65535] Bind port for the ASGI │
│ server │
│ [default: 8000] │
│ --workers INTEGER RANGE [x>=1] Number of uvicorn worker │
│ processes │
│ [default: 1] │
│ --log-level TEXT Uvicorn log level │
│ [default: info] │
│ --app TEXT ASGI app import path │
│ (module:attribute) │
│ [default: │
│ cleveragents.a2a.asgi:app] │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────╯
What's Happening:
The serve command launches the ASGI server (via uvicorn) for container
deployments. The default app target is cleveragents.a2a.asgi:app, which
serves health/readiness probes at /live, /ready, /health, and /.
Part 2: A2A Protocol Facade
The A2A (Agent-to-Agent) protocol is CleverAgents' internal communication
protocol, based on JSON-RPC 2.0. In local mode, the A2aLocalFacade
routes operations directly to application services — no network, no
serialization overhead.
Step 9: Understand the wire format
from cleveragents.a2a.models import A2aRequest, A2aResponse, A2aErrorDetail, A2aEvent
# A2A request — JSON-RPC 2.0 envelope
req = A2aRequest(method="_cleveragents/health/check", params={"key": "value"})
print(req.model_dump())
Output:
{
"jsonrpc": "2.0",
"id": "01KNM6HBGXEZZ6RK37EXCB1AHM",
"method": "_cleveragents/health/check",
"params": {
"key": "value"
}
}
# Successful response
resp = A2aResponse(id=req.id, result={"status": "healthy", "services": {}})
print(resp.model_dump())
Output:
{
"jsonrpc": "2.0",
"id": "01KNM6HBGXEZZ6RK37EXCB1AHM",
"result": {
"status": "healthy",
"services": {}
},
"error": null
}
# Error response
err_resp = A2aResponse(
id=req.id,
error=A2aErrorDetail(code=-32601, message="Method not found")
)
print(err_resp.model_dump())
Output:
{
"jsonrpc": "2.0",
"id": "01KNM6HBGXEZZ6RK37EXCB1AHM",
"result": null,
"error": {
"code": -32601,
"message": "Method not found",
"data": {}
}
}
# Server-sent event (for plan progress streaming)
event = A2aEvent(
event_type="plan.progress",
plan_id="plan-123",
data={"phase": "running", "progress": 0.5}
)
print(event.model_dump())
Output:
{
"event_id": "01KNM6HBGXEZZ6RK37EXCB1AHN",
"event_type": "plan.progress",
"plan_id": "plan-123",
"data": {
"phase": "running",
"progress": 0.5
},
"timestamp": "2026-04-07T14:46:24.029773+00:00"
}
What's Happening:
The A2A wire format follows JSON-RPC 2.0:
jsonrpc: "2.0"— always present, validated on constructionid— auto-generated ULID if not provided (sortable, time-ordered)method— the operation name (e.g._cleveragents/plan/status)params— operation-specific parameters dictresultXORerror— exactly one must be set in responses
A2aEvent is used for server-sent events (SSE) during plan execution streaming.
Step 10: List all supported A2A operations
from cleveragents.a2a.facade import A2aLocalFacade
facade = A2aLocalFacade()
ops = facade.list_operations()
print(f"Total operations: {len(ops)}")
for op in ops:
print(f" {op}")
Output:
Total operations: 42
_cleveragents/plan/use
_cleveragents/plan/execute
_cleveragents/plan/apply
_cleveragents/plan/cancel
_cleveragents/plan/status
_cleveragents/plan/tree
_cleveragents/plan/explain
_cleveragents/plan/correct
_cleveragents/plan/diff
_cleveragents/plan/artifacts
_cleveragents/plan/prompt
_cleveragents/plan/rollback
_cleveragents/plan/list
_cleveragents/registry/tool/list
_cleveragents/registry/resource/list
_cleveragents/registry/actor/list
_cleveragents/registry/skill/list
_cleveragents/registry/action/list
_cleveragents/registry/project/list
_cleveragents/context/show
_cleveragents/context/inspect
_cleveragents/context/simulate
_cleveragents/context/set
_cleveragents/health/check
_cleveragents/diagnostics/run
_cleveragents/sync/pull
_cleveragents/sync/push
_cleveragents/sync/status
_cleveragents/namespace/list
_cleveragents/namespace/show
_cleveragents/namespace/members
session.create
session.close
plan.create
plan.execute
plan.status
plan.diff
plan.apply
registry.list_tools
registry.list_resources
context.get
event.subscribe
What's Happening:
The 42 operations fall into two groups:
_cleveragents/extension methods (31 ops) — spec-aligned ADR-047 names for the current API surface- Legacy proprietary names (11 ops) — deprecated names kept for backward
compatibility (e.g.
session.create,plan.execute)
The extension methods are organized into namespaces: plan/, registry/,
context/, health/, diagnostics/, sync/, and namespace/.
Step 11: Dispatch operations in stub mode (no services)
from cleveragents.a2a.facade import A2aLocalFacade
from cleveragents.a2a.models import A2aRequest
facade = A2aLocalFacade() # No services wired
def call(method, params=None):
req = A2aRequest(method=method, params=params or {})
return facade.dispatch(req)
# Health check
resp = call("_cleveragents/health/check")
print(resp.result)
# → {"status": "healthy", "services": {}}
# Plan list (stub — no service)
resp = call("_cleveragents/plan/list")
print(resp.result)
# → {"plans": [], "stub": true}
# Session create (stub — generates a ULID)
resp = call("session.create", {"actor_name": "test-actor"})
print(resp.result)
# → {"session_id": "01KNM6GE0WQ2TP4X3R0HAF03MJ", "status": "created"}
# Event subscribe (stub)
resp = call("event.subscribe")
print(resp.result)
# → {"subscription_id": "01KNM6GE0WQ2TP4X3R0HAF03MM", "status": "subscribed"}
What's Happening:
When no services are wired, the facade returns safe stub responses for every operation. This means:
- Operations never crash due to missing dependencies
- Tests can run without a full application container
- The facade is safe to use in minimal environments
Step 12: Dispatch plan lifecycle operations
# Plan create (stub)
resp = call("_cleveragents/plan/use", {"action_name": "my-action"})
print(resp.result)
# → {"plan_id": "01KNM6GYV01AMVWFD1B9YD04MM", "status": "created"}
# Plan status (stub)
resp = call("_cleveragents/plan/status", {"plan_id": "test-plan-123"})
print(resp.result)
# → {"plan_id": "test-plan-123", "phase": "unknown"}
# Plan cancel (stub)
resp = call("_cleveragents/plan/cancel", {"plan_id": "test-plan-123"})
print(resp.result)
# → {"plan_id": "test-plan-123", "status": "cancelled", "stub": true}
# Plan prompt — inject guidance mid-execution
resp = call("_cleveragents/plan/prompt", {
"plan_id": "test-plan-123",
"guidance": "Focus on security"
})
print(resp.result)
# → {"plan_id": "test-plan-123", "guidance": "Focus on security",
# "status": "guidance_injected", "stub": true}
# Plan rollback
resp = call("_cleveragents/plan/rollback", {"plan_id": "test-plan-123"})
print(resp.result)
# → {"plan_id": "test-plan-123", "status": "rolled_back", "stub": true}
What's Happening:
The plan lifecycle operations map to the full plan state machine:
use → execute → apply (or cancel/rollback). The prompt operation
allows injecting human guidance into a running plan mid-execution — a key
feature of the supervised automation model.
Step 13: Register real services and dispatch
from cleveragents.a2a.facade import A2aLocalFacade
from cleveragents.a2a.models import A2aRequest
facade = A2aLocalFacade()
# Register a mock tool registry
class MockToolRegistry:
def list_tools(self, namespace=None):
class Tool:
name = "bash"
description = "Run shell commands"
class Tool2:
name = "file_read"
description = "Read file contents"
return [Tool(), Tool2()]
facade.register_service("tool_registry", MockToolRegistry())
# Now tool list returns real data
req = A2aRequest(method="_cleveragents/registry/tool/list")
resp = facade.dispatch(req)
print(resp.result)
Output:
{
"tools": [
{"name": "bash", "description": "Run shell commands"},
{"name": "file_read", "description": "Read file contents"}
]
}
# Register a mock resource registry
class MockResourceRegistry:
def list_resources(self, type_name=None):
class R:
resource_id = "res-001"
name = "main-repo"
resource_type_name = "git_repository"
return [R()]
facade.register_service("resource_registry_service", MockResourceRegistry())
req2 = A2aRequest(method="_cleveragents/registry/resource/list")
resp2 = facade.dispatch(req2)
print(resp2.result)
Output:
{
"resources": [
{
"resource_id": "res-001",
"name": "main-repo",
"type_name": "git_repository"
}
]
}
What's Happening:
register_service() wires a named service into the facade. The handler map is
rebuilt on the next dispatch (cached for performance). This pattern allows
incremental wiring — start with no services and add them as they become
available.
Step 14: Use the fully-wired facade via get_facade()
from cleveragents.a2a.cli_bootstrap import get_facade
from cleveragents.a2a.models import A2aRequest
# get_facade() wires the facade to the real DI container
facade = get_facade()
print(f"Services wired: {list(facade._services.keys())}")
# → Services wired: ['plan_lifecycle_service', 'session_service',
# 'resource_registry_service']
# Health check
req = A2aRequest(method="_cleveragents/health/check")
resp = facade.dispatch(req)
print(resp.result)
# → {"status": "healthy", "services": {}}
# Plan list — returns real plans from the database
req2 = A2aRequest(method="_cleveragents/plan/list")
resp2 = facade.dispatch(req2)
print(resp2.result)
Output:
{
"plans": [
{"plan_id": "01KNKK0MQBWQ5NF0BZYKTF4WJP", "phase": "strategize"},
{"plan_id": "01KNKK0MKCDXGP8Z3PZ88S5GGZ", "phase": "strategize"},
{"plan_id": "01KNKJZ44ES00VT8JTRKX1HEQA", "phase": "strategize"},
{"plan_id": "01KNKJZ424C48388RWHW3KY5QZ", "phase": "strategize"}
],
"total": 4
}
What's Happening:
get_facade() is the production entry point. It:
- Calls
get_container()to obtain the DI container - Wires available services (suppressing errors for missing ones)
- Caches the facade for the process lifetime
The facade is process-scoped — multiple CLI invocations within the same Python
process share the same wired instance. Call reset_facade() to force a rebuild
(useful in tests).
Step 15: Handle unknown operations
from cleveragents.a2a.errors import A2aOperationNotFoundError
from cleveragents.a2a.models import A2aRequest
facade = A2aLocalFacade()
try:
req = A2aRequest(method="unknown/operation")
resp = facade.dispatch(req)
except A2aOperationNotFoundError as e:
print(f"A2aOperationNotFoundError: {e}")
# → A2aOperationNotFoundError: Unknown A2A method: unknown/operation
What's Happening:
A2aOperationNotFoundError is raised (not returned as an error response) for
truly unknown methods. This is intentional — the caller must handle routing
errors explicitly, while domain errors (e.g. plan not found) are returned as
A2aResponse.error payloads.
Part 3: Version Negotiation
Step 16: Negotiate A2A protocol versions
from cleveragents.a2a.versioning import A2aVersionNegotiator
neg = A2aVersionNegotiator()
print(f"Current version: {neg.get_current()}")
# → Current version: 2.0
print(f"Supported versions: {neg.SUPPORTED_VERSIONS}")
# → Supported versions: ('2.0',)
# Negotiate a supported version
result = neg.negotiate("2.0")
print(f"Negotiated: {result}")
# → Negotiated: 2.0
# Check support
print(f"2.0 supported: {neg.is_supported('2.0')}") # → True
print(f"1.0 supported: {neg.is_supported('1.0')}") # → False
# Unsupported version raises
try:
neg.negotiate("1.0")
except Exception as e:
print(f"Error: {type(e).__name__}: {e}")
# → Error: A2aVersionMismatchError: A2A version '1.0' is not supported
What's Happening:
A2aVersionNegotiator implements the version handshake for the A2A protocol.
Currently only "2.0" (JSON-RPC 2.0) is supported. When a client connects
with an incompatible version, A2aVersionMismatchError is raised with the
requested version and the list of supported versions — giving the client
enough information to downgrade gracefully.
Part 4: Server Configuration Model
Step 17: Validate server connection configuration
from cleveragents.a2a.server_config import ServerConnectionConfig
# Production HTTPS config
cfg = ServerConnectionConfig(
server_url="https://agents.example.com",
namespace="production"
)
print(cfg.model_dump())
# → {"server_url": "https://agents.example.com", "namespace": "production",
# "auth_token_ref": null, "tls_verify": true}
# Local dev config (HTTP, no TLS verification)
cfg2 = ServerConnectionConfig(
server_url="http://localhost:8080",
namespace="dev",
tls_verify=False
)
print(cfg2.model_dump())
# → {"server_url": "http://localhost:8080", "namespace": "dev",
# "auth_token_ref": null, "tls_verify": false}
# With auth token reference (env var name or secret store key)
cfg3 = ServerConnectionConfig(
server_url="https://agents.company.com",
namespace="team-alpha",
auth_token_ref="CLEVERAGENTS_AUTH_TOKEN",
tls_verify=True
)
print(cfg3.model_dump())
# → {"server_url": "https://agents.company.com", "namespace": "team-alpha",
# "auth_token_ref": "CLEVERAGENTS_AUTH_TOKEN", "tls_verify": true}
Validation errors:
# Empty URL
ServerConnectionConfig(server_url="")
# → ValueError: server_url must not be empty
# Missing scheme
ServerConnectionConfig(server_url="agents.example.com")
# → ValueError: server_url must start with http:// or https://
# Empty namespace
ServerConnectionConfig(server_url="https://agents.example.com", namespace="")
# → ValueError: namespace must not be empty
What's Happening:
ServerConnectionConfig is a frozen Pydantic model — immutable after creation.
The auth_token_ref field stores a reference to an auth token (e.g. an
environment variable name or secret store key), not the token itself. This
keeps secrets out of the configuration file.
Complete Interaction Log
Click to see the full verified command sequence
# 1. Explore server subcommand
$ agents server --help
# → 3 commands: connect, status, serve
# 2. Check initial status (no config)
$ agents server status
# → Server Mode: disabled, Server URL: (not configured)
$ agents server status --format json
# → {"server_mode": "disabled", "server_url": null, "namespace": "default", "tls_verify": true}
# 3. Connect to a server
$ agents server connect https://agents.example.com
# → Panel: Server URL, Namespace: default, TLS Verify: True, Status: stubbed
$ agents server connect https://agents.example.com --format json
# → {"server_url": "https://agents.example.com", "namespace": "default",
# "tls_verify": true, "status": "stubbed", "warning": "..."}
# 4. Connect with namespace
$ agents server connect https://agents.example.com --namespace my-team --format json
# → {"namespace": "my-team", ...}
# 5. Connect to local dev (no TLS)
$ agents server connect http://localhost:8080 --no-tls-verify --format json
# → {"server_url": "http://localhost:8080", "tls_verify": false, ...}
# 6. Check status after connecting
$ agents server status
# → Server Mode: stubbed, Server URL: https://agents.example.com
$ agents server status --format yaml
# → server_mode: stubbed, server_url: https://agents.example.com
$ agents server status --format plain
# → server_mode: stubbed
# 7. Validation: invalid URL
$ agents server connect not-a-url --format json
# → exit 1: "server_url must start with http:// or https://"
# 8. Explore serve command
$ agents server serve --help
# → --host, --port, --workers, --log-level, --app options
# Python A2A facade usage:
# 9. List 42 supported operations
# 10. Dispatch health check → {"status": "healthy", "services": {}}
# 11. Dispatch plan list (stub) → {"plans": [], "stub": true}
# 12. Dispatch session.create → {"session_id": "01K...", "status": "created"}
# 13. Dispatch plan/use → {"plan_id": "01K...", "status": "created"}
# 14. Dispatch plan/cancel → {"status": "cancelled", "stub": true}
# 15. Dispatch plan/prompt → {"status": "guidance_injected", "stub": true}
# 16. Register MockToolRegistry → tools: [bash, file_read]
# 17. Register MockResourceRegistry → resources: [main-repo]
# 18. get_facade() → wired to real container, plan list returns 4 real plans
# 19. Unknown operation → A2aOperationNotFoundError
# 20. Version negotiation: 2.0 → OK, 1.0 → A2aVersionMismatchError
# 21. ServerConnectionConfig validation: empty URL, no scheme, empty namespace
Key Takeaways
- Two server modes:
disabled(no URL configured) andstubbed(URL configured, network client pending). The mode is reflected in everyserver statusresponse. - Config is persisted via audit trail:
server connectusesset_value()(notwrite_config()) so every change emits aCONFIG_CHANGEDevent — important for security-relevant settings like server URL and TLS verification. - A2A uses JSON-RPC 2.0: The wire format is standard —
jsonrpc: "2.0", auto-generated ULIDid,method,params, andresultXORerror. - 42 operations in two groups:
_cleveragents/extension methods (spec- aligned, ADR-047) and legacy proprietary names (deprecated, kept for backward compatibility). - Stub-safe facade: When services are absent, every operation returns a safe stub response. The facade never crashes due to missing wiring.
get_facade()is the production entry point: It wires the facade to the real DI container and caches it for the process lifetime. Usereset_facade()in tests.A2aOperationNotFoundErroris raised, not returned: Unknown methods raise an exception; domain errors (plan not found, etc.) are returned asA2aResponse.errorpayloads.- Version negotiation is strict: Only
"2.0"is supported. Clients with incompatible versions receiveA2aVersionMismatchErrorwith enough context to downgrade.
Try It Yourself
# Check current server mode
$ agents server status --format json | jq '.data.server_mode'
# Connect to a server and immediately check status
$ agents server connect https://my-agents-server.com --namespace my-project
$ agents server status
# Reset server configuration
$ agents config set server.url "" --scope global
# List all A2A operations from Python
$ python -c "
from cleveragents.a2a.facade import A2aLocalFacade
f = A2aLocalFacade()
for op in f.list_operations():
print(op)
"
# Run a health check via the wired facade
$ python -c "
from cleveragents.a2a.cli_bootstrap import get_facade
from cleveragents.a2a.models import A2aRequest
import json
facade = get_facade()
resp = facade.dispatch(A2aRequest(method='_cleveragents/health/check'))
print(json.dumps(resp.result, indent=2))
"
# Launch the ASGI server for local testing (requires uvicorn)
$ agents server serve --host 127.0.0.1 --port 8080 --log-level debug
Related Examples
- See
config-and-automation-profiles.mdfor the full guide to configuration management and the five-level resolution chain - See
output-format-flags.mdfor the complete guide to--format json/yaml/plain/table/rich - See
docs/showcase/cli-tools/for more CLI tool examples
This example was automatically generated and verified by the CleverAgents UAT system. Feature area: Server and A2A integration | Test cycle: 1 | Generated: 2026-04-07
Automated by CleverAgents Bot Supervisor: UAT Testing | Agent: uat-tester