Agent Card Configuration
The Agent Card is your agent's identity document. Published at /.well-known/agent.json, it tells clients what your agent does, what skills it offers, how to authenticate, and what payment is required.
Agent Card Structure
Here's the complete Agent Card from the GitHub Repo Analyzer reference agent:
{
"name": "GitHub Repo Analyzer",
"description": "Analyzes GitHub repositories for code complexity, dependencies, and security vulnerabilities.",
"protocolVersion": "0.3.0",
"version": "1.0.0",
"url": "http://localhost:3000/api/a2a",
"securitySchemes": {
"github_oauth": {
"type": "oauth2",
"description": "GitHub OAuth2 Device Flow authentication.",
"flows": {
"deviceCode": {
"deviceAuthorizationUrl": "http://localhost:3000/auth/device",
"tokenUrl": "http://localhost:3000/auth/token"
}
}
}
},
"security": [{ "github_oauth": [] }],
"skills": [
{
"id": "analyze-repo",
"name": "Analyze Repository",
"description": "Analyzes a GitHub repository and returns a structured report covering code complexity, language distribution, dependencies, and security issues.",
"tags": ["github", "analysis", "security", "dependencies"],
"inputModes": ["text/plain"],
"outputModes": ["text/plain"]
}
],
"capabilities": {
"streaming": true,
"extensions": [
{
"uri": "https://github.com/google-agentic-commerce/a2a-x402/blob/main/spec/v0.2",
"required": true
}
]
},
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/plain"]
}Required Fields
| Field | Type | Description |
|---|---|---|
name | string | Human-readable agent name. Keep it concise and descriptive. |
description | string | What the agent does. Clients (and the Agent Registry) use this for discovery. |
protocolVersion | string | A2A protocol version. Currently "0.3.0". |
version | string | Your agent's version. Follow semver. |
url | string | The A2A endpoint URL where JSON-RPC requests are sent. |
skills | Skill[] | Array of skills the agent offers. At least one is required. |
capabilities | object | Agent capabilities including streaming and extensions. |
Skills Definition
Skills describe what your agent can do. Each skill has an ID, name, description, and supported MIME types.
{
"id": "analyze-repo",
"name": "Analyze Repository",
"description": "Analyzes a GitHub repository and returns a structured report.",
"tags": ["github", "analysis", "security"],
"inputModes": ["text/plain"],
"outputModes": ["text/plain"]
}| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the skill. Use kebab-case. |
name | string | Human-readable skill name. |
description | string | Clear description of what the skill does. Clients use this to decide whether to call your agent. |
tags | string[] | Searchable tags for discovery. |
inputModes | string[] | MIME types the skill accepts as input. |
outputModes | string[] | MIME types the skill produces as output. |
Tip
Capabilities and X402 Extension
The capabilities object declares what protocol features your agent supports.
Streaming
{
"capabilities": {
"streaming": true
}
}Set streaming: true if your agent supports the message/stream method for real-time SSE responses.
X402 Extension Declaration
To enable paid services, declare the X402 extension:
{
"capabilities": {
"extensions": [
{
"uri": "https://github.com/google-agentic-commerce/a2a-x402/blob/main/spec/v0.2",
"description": "Supports payments using the x402 protocol for on-chain settlement.",
"required": true
}
]
}
}| Field | Description |
|---|---|
uri | The canonical extension URI. Must match exactly. |
description | Optional human-readable description. |
required | If true, clients must implement X402 to use this agent. Recommended for paid agents. |
Supported MIME Types
Define what content types your agent accepts and produces:
| MIME Type | Use Case |
|---|---|
text/plain | Plain text messages (most common) |
application/json | Structured JSON data |
image/png, image/jpeg | Image generation or analysis |
application/pdf | Document processing |
The defaultInputModes and defaultOutputModes at the agent level serve as defaults when a skill doesn't specify its own:
{
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/plain"]
}Dynamic URL Injection
Hard-coding localhost:3000in the Agent Card won't work in production. Use dynamic URL injection to set the correct URLs at runtime based on the NEXT_PUBLIC_BASE_URL environment variable.
import type { AgentCard } from '@a2a-js/sdk';
import agentCardJson from './agent-card.json';
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL ?? 'http://localhost:3000';
export const agentCard: AgentCard = {
...(agentCardJson as Omit<AgentCard, 'url'>),
url: `${BASE_URL}/api/a2a`,
securitySchemes: {
github_oauth: {
type: 'oauth2',
description: agentCardJson.securitySchemes.github_oauth.description,
flows: {
deviceCode: {
deviceAuthorizationUrl: `${BASE_URL}/auth/device`,
tokenUrl: `${BASE_URL}/auth/token`,
},
},
},
},
security: [{ github_oauth: [] }],
};This pattern:
- Keeps the static JSON file as the source of truth for non-URL fields
- Injects the correct URLs at runtime based on the environment
- Works seamlessly across development (
localhost:3000) and production (your-agent.fly.dev)
Then serve it from the well-known endpoint:
// src/app/.well-known/agent.json/route.ts
import { NextResponse } from 'next/server';
import { agentCard } from '@/lib/a2a/a2a-handler';
export async function GET() {
return NextResponse.json(agentCard);
}Multi-Skill Agent Configuration
An agent can expose multiple skills. Each skill can have different input/output modes:
{
"skills": [
{
"id": "analyze-repo",
"name": "Analyze Repository",
"description": "Analyzes a GitHub repository for complexity and security issues.",
"tags": ["github", "analysis", "security"],
"inputModes": ["text/plain"],
"outputModes": ["text/plain"]
},
{
"id": "generate-report",
"name": "Generate PDF Report",
"description": "Generates a downloadable PDF report from analysis results.",
"tags": ["report", "pdf"],
"inputModes": ["application/json"],
"outputModes": ["application/pdf"]
}
]
}Note
Security Schemes
Define how clients authenticate with your agent:
{
"securitySchemes": {
"github_oauth": {
"type": "oauth2",
"description": "GitHub OAuth2 Device Flow authentication.",
"flows": {
"deviceCode": {
"deviceAuthorizationUrl": "http://localhost:3000/auth/device",
"tokenUrl": "http://localhost:3000/auth/token"
}
}
}
},
"security": [{ "github_oauth": [] }]
}The securityarray lists which schemes are required. The GitHub Device Flow is recommended for CLI-based clients (like the A2X CLI) because it doesn't require a browser redirect.
Validation Checklist
Before deploying your agent, verify:
nameis set and descriptivedescriptionclearly explains what the agent doesprotocolVersionmatches"0.3.0"urlpoints to your A2A endpoint (will be overridden by dynamic URL injection)skillshas at least one skill withid,name,descriptioninputModes/outputModesare correct for each skillcapabilities.extensionsincludes the X402 URI if your agent is paidsecuritySchemesis configured if authentication is required/.well-known/agent.jsonreturns the correct card with dynamic URLs/.well-known/agent-card.jsonalso returns the card (alias endpoint)- Agent Card is valid JSON with no trailing commas or syntax errors
- All URLs use the correct protocol (
https://in production)