Skip to main content

Defining capabilities

A capability is a function on your agent that another agent, a user in the dashboard, or the agent’s own LLM can invoke. Capabilities are the public contract — everything else (LLMs, triggers, MCP, scheduled work) eventually reduces to “call a capability.” This guide covers writing capabilities you’d ship to production.

The minimum

Three things matter:
  1. name — snake_case, unique per agent. This is what callers and LLMs see.
  2. description — what the capability does, written for an LLM. Good descriptions double as good docs.
  3. parameters — JSON Schema validated before your handler runs.

Writing good schemas

  • Every field gets a description. The LLM leans on these more than the types.
  • Mark everything the handler can’t synthesize as required. Unmarked optional fields are the common source of “the model never fills this in” bugs.
  • Prefer enum over free-form strings when the value is one of a closed set (status: { type: 'string', enum: ['draft', 'sent', 'paid'] }).
  • Keep nesting shallow. LLMs are measurably worse at deeply nested objects than at flat ones.
The full schema shape is documented in CapabilitySchema.

The handler

  • Return any JSON-serializable value. It ends up in the DataPart.data.result that callers receive.
  • Throwing from the handler surfaces as an A2A error to the caller. Throw Error subclasses with clear messages.
  • Long-running work is fine — there’s no hard timeout in the SDK; the platform’s dispatch timeout (default 60 s) applies end-to-end.

The context

The second argument is a CapabilitySessionContext with:
  • session_id / tenant_id — always present; use for scoping and auditing.
  • propagation_headers / parent_trace_id / parent_span_id / baggage — W3C trace context, present when the caller had an active trace. Forward propagation_headers verbatim to downstream HTTP services; use parent_trace_id / parent_span_id when creating custom spans. See Trace propagation.

Errors

Throw. The SDK wraps the exception as an A2A error part the caller can inspect. For expected failures, use a clear message:
For validation-like failures, prefer tightening the JSON Schema — the platform rejects invalid inputs before your handler runs.

Tags

Use tags to categorize capabilities on the agent card:
Tags are displayed in the dashboard and can be used by orchestrators to filter what the LLM sees.

Adding capabilities after start

You can call define_capability at any time, but new capabilities aren’t advertised to Svantic until you re-register. When you’re using agent.start(), call agent.stop() and re-start(). When you’re using a standalone MeshConnector, call mesh.re_register().

See also