Agent skills and A2A
This block covers two ideas that often get mixed up with MCP. Agent skills give an agent knowledge it loads when needed. The Agent2Agent protocol (A2A) lets an agent hand work to another agent that you do not control.
Northwind has two needs. Support staff keep pasting the 30-step goodwill voucher policy into the prompt. And when a parcel is lost, someone has to open a claim with the carrier, which runs its own agent.
A shelf of binders
Your colleague on the phone has a shelf of binders with labels on the spines. At the start of the call they read only the spines. When a voucher question comes up, they take down that binder. If the binder says "for corporate accounts, see the appendix," they open the appendix.
That is a skill. On disk it is a folder with a SKILL.md file:
---
name: issuing-goodwill-vouchers
description: Applies Northwind's goodwill voucher policy, including amounts by delay, limits per customer and wording. Use when a customer complains about a late, damaged or lost order, even if they do not ask for compensation.
---
# Goodwill vouchers
1. Find the delay in days from the order.
2. Take the amount from the table in `references/amounts.md`.
3. Run `scripts/check_limit.py` before offering anything.Loading happens in levels. On Anthropic's platform it works like this:
Level | Content | When it loads |
|---|---|---|
1 | | At startup, about 100 tokens per skill |
2 | The body of | When the skill triggers, ideally under 5,000 tokens |
3 | Other files | When the model opens them; a script's code stays out, only its output comes in |
The format is published as an open specification at agentskills.io, and it requires name and description. How a skill gets registered and discovered varies by client.
A skill holds knowledge of how to do something. A tool performs an action. The voucher skill says when and how much, and issue_voucher is still a tool with checks in its code.
The main risk: nobody opens the binder
The description is the only thing the model has when it decides. The specification's guide says it carries the whole burden of triggering. An under-specified description means a skill that is never used, with no error anywhere. An over-broad one fires when it should not. Even a good description may not fire for a simple one-step request the agent can handle alone.
Triggering is not deterministic, so test it like this:
- Write about 20 realistic queries, half that should trigger and half that should not.
- Make the negatives near-misses. For the voucher skill, "what's your refund policy for gift cards" shares words and needs something else.
- Run each query several times and count the rate. The guide suggests 3 runs and a 0.5 threshold as a starting point.
A skill is instructions plus code that the agent will follow. Anthropic's advice is to use skills only from trusted sources, audit every bundled file, and treat installing one like installing software.
Calling another company
The carrier's claims desk is at another company. You cannot see their screens, and you do not know how they decide. You ring the number on their website, explain the case, and get a ticket number. Later they may ring back asking for the photo of the box.
That is A2A. As of 2026-11-10 the specification is at version 1.0: its site shows 1.0.0, and the latest GitHub release is the bug-fix v1.0.1. The other agent stays opaque: it collaborates without exposing its memory or its tools.
| MCP | A2A |
|---|---|---|
Connects | An agent to tools and data | An agent to another agent |
The other side | Functions with defined inputs | A system that reasons and may ask back |
Discovery | | An Agent Card |
Unit of work | One call and its result | A Task with a lifecycle |
Both can be in one system. Northwind's agent talks to the carrier over A2A, and inside each company the agent uses MCP for its own tools.
Discovery starts with the Agent Card, a JSON document usually at /.well-known/agent-card.json:
{
"name": "Carrier Claims Agent",
"description": "Opens and tracks claims for lost or damaged parcels.",
"version": "1.2.0",
"supportedInterfaces": [
{
"url": "https://claims.example.com/a2a/v1",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
],
"capabilities": {
"streaming": true,
"pushNotifications": false
},
"defaultInputModes": [
"text/plain"
],
"defaultOutputModes": [
"application/json"
],
"skills": [
{
"id": "open-claim",
"name": "Open a claim",
"description": "Opens a claim for a lost parcel.",
"tags": [
"claims",
"parcels"
]
}
]
}Note the word skills here. An A2A skill is an advertised capability on the card. It has nothing to do with a SKILL.md folder.
To start work, the client sends a message. A2A can run over several bindings, which are wire formats. In the HTTP+JSON binding that is POST /message:send, and in the JSON-RPC binding the method is SendMessage. The parameters are the same:
{
"message": {
"role": "ROLE_USER",
"messageId": "msg-5120-1",
"parts": [
{
"text": "Parcel for order 5120 is lost. Open a claim."
}
]
}
}The agent may answer with a plain message or with a Task, which has an id and a state:
When the carrier needs the photo, the Task enters TASK_STATE_INPUT_REQUIRED. Northwind's code sends another message with the same taskId and contextId, and the Task continues. For long work the client can stream with SendStreamingMessage, poll with GetTask, or register a webhook for push notifications if the card declares support.
Treat everything from the other agent as untrusted text, the same as a tool result. A2A requires encrypted transport in production, and clients should verify a card's signature when one is present. A valid signature says who published the card. It says nothing about whether the words in a Task are safe to obey.
Conclusion
- A skill is knowledge loaded in levels, and it fails silently if its description does not get it opened.
- MCP connects an agent to tools. A2A connects it to other agents, which stay opaque and work through Tasks.
- Text from a skill or from another agent can steer yours, so limit what it can reach.