Define execution responsibility when connecting tools and agents
Distinguish MCP tools, A2A tasks, SDK loops, and skill resources, then use a narrow read contract to check authorization, parameters, and responsibility for results.
Map agent execution responsibility and validate tool allowlists, resource scopes, and handling of unknown outcomes.
A note assistant is connecting an external tool provider and another organizing agent. Protocols define message exchange, while the application decides execution authority, resource scope, and durable results. Discovering a tool does not grant the model permission to use it.
The case permits reading only note N-1. An external agent may suggest categories or steps without expanding that scope. The offline contract runs no MCP server, A2A service, or Agent SDK.
Separate responsibilities within an action
A user provides intent, a model proposes an action, policy validates it, an executor acts, observation records the result, and durable state retains progress. Keep these responsibilities inspectable even in one process so model text cannot directly become a side effect.
Persist task IDs, steps, input versions, authorization scope, result references, and errors. Logs do not replace authoritative task state. After restart, distinguish completed actions, unknown outcomes, and retryable operations.
Define idempotency and confirmation for writes and external effects. A timeout can follow a committed action. Authorization must bind resources and actions; an external message claiming approval cannot expand it.
MCP connects capability providers
MCP specifies client-server exchange for tools, resources, and prompts. Tools expose names, descriptions, and input schemas for discovery and calls. Implement lifecycle, capability negotiation, and transport according to the selected version; a JSON object alone does not establish compatibility.
Schemas validate shape, not ownership. Servers need business authorization and clients control tool exposure. Authentication differs by transport, so one HTTP mechanism cannot be assumed for every local process connection.
The tool specification addresses invocation visibility and human control. Show what tools may do and present concrete actions when confirmation is needed. Read-only tools can still leak information or consume resources and therefore need scope and budgets.
A2A has task-collaboration boundaries
A2A describes agent capabilities, messages, and task interaction. Agent Cards can declare endpoints, skills, and authentication requirements. Declarations help discovery but establish neither trust nor user authorization. Identity, data scope, and result processing remain application decisions.
Long tasks have progress and completion states whose exact operations depend on the version. Remote success is a report requiring local validation of artifacts and requirements. Define unknown outcomes, cancellation, and late responses.
An agent can delegate through A2A while using narrow MCP tools. Neither provides universal compatibility across implementations. Distinguish task collaboration from tool execution and select the needed boundaries.
SDKs run loops; skills package material
Claude Agent SDK exposes an agent loop, tools, and context management programmatically. Its capabilities depend on current documentation. SDKs, model clients, CLIs, and hosted agent products assign execution responsibility differently.
Check session continuation, tool integration, permissions, interruption, and persistence. This lesson provides no untested SDK implementation and assumes no cross-framework permission defaults.
Skills package reusable instructions and resources and may include executable scripts. They are read or executed, not learned model weights. Review provenance, scripts, network access, and filesystem effects. Skill text cannot expand the user's authorization.
Validate a narrow execution contract
The example allows only read_note with exactly one string note_id in a trusted authorization set. The caller does not supply its own permissions.
tools = {"read_note": {"required": {"note_id"}}}
def accept(name, arguments, authorized_ids):
if not isinstance(name, str):
return False
contract = tools.get(name)
return (contract is not None and isinstance(arguments, dict)
and set(arguments) == contract["required"]
and isinstance(arguments["note_id"], str)
and arguments["note_id"] in authorized_ids)
assert accept("read_note", {"note_id": "N-1"}, {"N-1"})
assert not accept("delete_note", {"note_id": "N-1"}, {"N-1"})
assert not accept("read_note", {"note_id": "N-2"}, {"N-1"})
assert not accept("read_note", {"note_id": []}, {"N-1"})
print(accept("read_note", {"note_id": "N-1"}, {"N-1"}))
The actual output is True. Allowed reading passes; unknown tools, other notes, and malformed types fail. The function neither reads notes nor validates identity or implements a transport.
Real execution must account for revoked permissions, deleted resources, and races between checking and use. Filter outputs to allowed fields. A read-only label is a declaration; inspect whether implementation can write or communicate externally.
Correlate results, retries, and state
Stable task and call IDs should connect proposals, validation, results, and durable status. Retain necessary metadata and error categories without note bodies or credentials in general logs. Restrict observability access too.
Separate protocol errors, business denial, tool failure, and model misselection. Version mismatch needs negotiation or an update; denial requires stopping or newly authorized scope; temporary failure may permit bounded retries; wrong selection needs capability or task evaluation.
Historical authorization must not be reused indefinitely during replay. Recheck scope and conditions, especially changed parameters. External messages retain provenance and correlation but remain task data, not a local execution identity.
Tool definitions can change. If a client retains an old schema while the server adds required parameters, fail explicitly and rediscover capabilities instead of guessing a translation. Record negotiated protocol and tool-definition versions so rejection can be distinguished from a model error. The same version evidence helps reproduce a failed call without exposing its private payload.
Exercise: define boundaries before connecting
Document intent, discoverable capabilities, schemas, permissions, execution location, result states, and recovery. Design separate reading and deletion paths, binding any deletion confirmation to a specific object and effect.
Accept the design when unknown tools, extra fields, malformed types, and unauthorized objects are rejected. External messages cannot enlarge permission, and timeouts and late results have defined handling. Identify responsibilities belonging to MCP, A2A, the SDK, skills, and business code. Real interoperability requires pinned versions and separate protocol and business tests.
Sources & further reading
- Model Context Protocol — Tools
- Agent2Agent protocol specification
- Agent SDK overview
- Extend a coding tool with skills
Sources checked on 2026-11-10. Original engineering explanation; examples are teaching data, not production measurements.