A2A AgentSkill: Describing What an Agent Can Do

A2A AgentSkill: Describing What an Agent Can Do

An AgentSkill is one entry in the skills array of an Agent Card . It describes one thing the agent can do: a name, a description, some tags, and optionally example prompts, media types, and security requirements. In v1.0 skills is a required field of the card.

The proto definition is blunt about what a skill is: “largely a descriptive concept”, a focused set of behaviors the agent is likely to succeed at.

A skill is a description, not an endpoint

No A2A operation selects a skill. SendMessageRequest carries only tenant, message, configuration, and metadata, and SendMessageConfiguration has no skill field either. A client sends an ordinary Message and the agent decides how to handle it.

So skills exist for the reader of the card. A client agent, or a person browsing a registry, uses them to judge whether this agent suits a task and which media types to send.

Fields

FieldRequiredMeaning
idYesUnique identifier of the skill
nameYesHuman-readable name
descriptionYesDetailed description of the skill
tagsYesKeywords describing the skill’s capabilities
examplesNoExample prompts or scenarios the skill can handle
inputModesNoSupported input media types for this skill, overriding the agent’s defaults
outputModesNoSupported output media types for this skill, overriding the agent’s defaults
securityRequirementsNoSecurity schemes necessary for this skill

The specification says arrays marked as required MUST contain at least one element (section 5.7). By that rule a card with an empty skills list is invalid, and so is a skill with no tags.

An example from the specification

This is the first skill of the specification’s sample Agent Card (the GeoSpatial Route Planner Agent):

{
  "id": "route-optimizer-traffic",
  "name": "Traffic-Aware Route Optimizer",
  "description": "Calculates the optimal driving route between two or more locations, taking into account real-time traffic conditions, road closures, and user preferences (e.g., avoid tolls, prefer highways).",
  "tags": ["maps", "routing", "navigation", "directions", "traffic"],
  "examples": [
    "Plan a route from '1600 Amphitheatre Parkway, Mountain View, CA' to 'San Francisco International Airport' avoiding tolls.",
    "{\"origin\": {\"lat\": 37.422, \"lng\": -122.084}, \"destination\": {\"lat\": 37.7749, \"lng\": -122.4194}, \"preferences\": [\"avoid_ferries\"]}"
  ],
  "inputModes": ["application/json", "text/plain"],
  "outputModes": ["application/json", "application/vnd.geo+json", "text/html"]
}

examples is a list of strings. The second example is a JSON object serialized into a string, which matches the application/json entry in inputModes: an example is whatever a client would put in a request, not only natural language.

Per-skill input and output modes

defaultInputModes and defaultOutputModes on the card are required and apply to every skill. A skill’s own inputModes and outputModes replace them for that skill. The sample card shows both directions:

inputModesoutputModes
Card defaultsapplication/json, text/plainapplication/json, image/png
route-optimizer-trafficapplication/json, text/plainapplication/json, application/vnd.geo+json, text/html
custom-map-generatorapplication/jsonimage/png, image/jpeg, application/json, text/html

The second skill narrows its input to JSON only, and the first lists output types that are not among the card defaults. Declare these accurately: the specification describes ContentTypeNotSupportedError as raised when a media type in the request is not supported “by the agent or the specific skill being invoked”. See A2A Error Codes .

On the request side, a client can also say which media types it accepts back through acceptedOutputModes in SendMessageConfiguration.

Per-skill security requirements

A skill can carry its own securityRequirements, with the same structure as the card-level field: each entry maps scheme names, defined in the card’s securitySchemes, to a list of scopes. The specification’s sample card does not set one on a skill. This snippet reuses the card-level requirement from the same sample, only to show where the field goes:

{
  "id": "route-optimizer-traffic",
  "securityRequirements": [{ "schemes": { "google": { "list": ["openid"] } } }]
}

How the schemes themselves are declared is covered in A2A SecurityScheme .

Coming from v0.3?

Per the proto definitions, AgentSkill kept its field numbers 1 to 7 and the meaning of those fields. One field changed:

v0.3.0v1.0.1
security (field 8), type Securitysecurity_requirements (field 8), type SecurityRequirement, so the JSON key is securityRequirements

The structure of the message is the same (map<string, StringList> schemes); only the names changed. The official migration guide does not list this rename; the proto files of the two releases show it. The same rename applies to AgentCard.security (field 9). See Agent Card Proto Field Numbers: v0.3.0 vs v1.0.1 .

Related pages

  • Agent Card : where skills sits, with capabilities and supportedInterfaces.
  • Part : how media types are carried in a message.
  • Data Structures : every Agent Card object in one table.

Source: A2A official specification: AgentSkill and Sample Agent Card ; a2a.proto at v1.0.1 and v0.3.0