| Internet-Draft | AgentCard | April 2026 |
| Tsoi | Expires 25 October 2026 | [Page] |
This document defines AgentCard, a lightweight JSON data format that enables autonomous software agents to declare their identity, capabilities, communication endpoints, and resource pricing in a framework-neutral manner. AgentCard is designed for agent-to-agent (A2A) communication scenarios where agents built with different frameworks — such as LangChain, CrewAI, AutoGen, or custom implementations — must interoperate without prior coordination.¶
An AgentCard is a pure data schema: it carries no execution logic and imposes no transport requirements. It is analogous to an HTTP response header set — a machine-parseable self-description that any compliant reader can interpret.¶
Key properties of AgentCard include a globally unique ULID-based agent identity, dot-namespaced capability identifiers compatible with OpenAI function-calling and Model Context Protocol (MCP) tool schemas, a physics-grounded energy pricing floor derived from Landauer's principle, and an extensible metadata namespace for framework-specific annotations.¶
Discussion of this document should take place on the GitHub repository at https://github.com/kwailapt/AgentCard/issues. The JSON Schema for AgentCard v1.0 is maintained at https://github.com/kwailapt/AgentCard/blob/main/schema.json.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 25 October 2026.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document.¶
The proliferation of autonomous AI agent frameworks has created a fragmentation problem: an agent built with LangChain cannot natively describe its capabilities to an AutoGen orchestrator; a CrewAI researcher agent cannot publish its endpoint in a form that a custom MCP server can consume without bespoke integration code. Each framework has invented its own internal identity representation, none of which is interoperable by default.¶
This situation is analogous to the pre-HTTP web, where each networked application defined its own message envelope format. The solution was not to mandate a single application protocol but to define a universal, lightweight header format (HTTP headers) that any application could attach to its messages.¶
AgentCard is the equivalent of HTTP headers for the agent web. It defines a minimal JSON document — the "card" — that any agent can produce and any peer can consume, independent of the agent's internal implementation, programming language, or hosting environment.¶
AgentCard does not specify:¶
These concerns are addressed by complementary protocols (e.g., OAuth 2.0 [RFC6749], WIMSE [I-D.ietf-wimse-arch], and MCP [MCP-SPEC]).¶
An AgentCard is a JSON object [RFC8259] containing
the fields defined in this section. The fields
agent_id, name, version,
capabilities, and endpoint are REQUIRED.
All other fields are OPTIONAL.¶
The normative JSON Schema for AgentCard v1.0, expressed in JSON Schema draft 2020-12 [JSON-SCHEMA], is maintained at the reference implementation repository [AGENTCARD-SPEC].¶
The agent_id field carries the agent's globally unique
identity as a ULID [ULID-SPEC]. A ULID encodes
a 48-bit millisecond-precision timestamp and 80 bits of
cryptographically random data into 128 bits total, then
serialises the result as a 26-character Crockford Base32
string.¶
ULIDs provide the following properties relevant to agent identity:¶
An agent MUST generate its agent_id using a
cryptographically secure random number generator for the
random component of the ULID. Predictable or sequential
random components are PROHIBITED.¶
Example:¶
"agent_id": "01HZQK3P8EMXR9V7T5N2W4J6C0"¶
A human-readable display name for the agent. The
name field is intended for presentation purposes
and SHOULD reflect the agent's primary function or role.
It is NOT required to be globally unique; uniqueness is
provided by agent_id.¶
"name": "WebSearchAgent"¶
The version of this AgentCard document. Implementations SHOULD increment the PATCH component when reissuing an AgentCard with corrected metadata. They SHOULD increment the MINOR component when new capabilities are added in a backward-compatible manner. They SHOULD increment the MAJOR component when capabilities are removed or endpoint URLs change incompatibly.¶
"version": "1.0.0"¶
An ordered array of capability declarations. Each entry describes one thing the agent can do. Entries SHOULD be ordered from most prominent to least prominent capability.¶
A dot-namespaced capability identifier. The identifier MUST begin with a lowercase letter or digit. Subsequent characters MAY be lowercase letters, digits, dots, underscores, or hyphens.¶
Convention for the dot-namespace:¶
text.* — natural language processing capabilities
(e.g., text.generate, text.summarise)¶
tool.* — executable tool wrappers
(e.g., tool.web_search, tool.python_repl)¶
data.* — data retrieval and transformation
(e.g., data.query_sql, data.fetch_csv)¶
fn.* — named function exposure compatible with
OpenAI function-calling schema
(e.g., fn.get_weather)¶
a2a.* — agent coordination capabilities
(e.g., a2a.delegate, a2a.negotiate)¶
Implementations SHOULD use the conventional namespaces above.
Private or experimental namespaces MAY use a reverse-domain
prefix (e.g., com.example.custom_capability).¶
The capabilities[].id is designed to be compatible
with the name field of an OpenAI-style function
schema and the name field of an MCP tool definition,
enabling zero-conversion interoperability.¶
A human-readable description of the capability for use in LLM prompts, API documentation, and agent discovery UIs. Implementations SHOULD provide this field. The description SHOULD be one to three sentences that describe what the capability does, what inputs it accepts, and what it returns.¶
Optional JSON Schema objects describing the expected input
parameters and output structure of the capability. When
provided, these schemas MUST conform to JSON Schema
[JSON-SCHEMA] and SHOULD be compatible with
the parameters object in OpenAI function-calling
format.¶
Example capabilities array:¶
"capabilities": [
{
"id": "text.summarise",
"description": "Summarise a document to a target length.",
"input_schema": {
"type": "object",
"properties": {
"text": { "type": "string" },
"max_words": { "type": "integer", "default": 200 }
},
"required": ["text"]
}
},
{
"id": "tool.web_search",
"description": "Search the public web and return top results.",
"tags": ["search", "retrieval"]
}
]
¶
Describes how to reach the agent. Contains two REQUIRED sub-fields and one OPTIONAL sub-field:¶
REQUIRED. MUST be one of: http, https,
grpc, stdio, or mcp.¶
The value mcp indicates that the agent is accessible
via the Model Context Protocol [MCP-SPEC].
The value stdio indicates an agent that communicates
over standard input/output streams (applicable to local
subprocess agents).¶
REQUIRED. A URI [RFC3986] identifying the
agent's communication endpoint. The URI MUST be consistent
with the declared protocol (e.g., an https endpoint
MUST begin with the scheme https://).¶
OPTIONAL. An object describing the authentication scheme
required to contact the endpoint. The auth.scheme
sub-field MUST be one of: none, bearer,
api_key, oauth2, or mtls.
The default value is none.¶
Presence of an auth object does not constitute
credential exchange; it is a declaration of the authentication
mechanism required. Actual credential negotiation is handled
by the transport layer.¶
Describes the resource cost of invoking the agent. All cost values are expressed in SI units: joules for energy.¶
The minimum energy cost per invocation in joules. If present, this value MUST be either exactly zero (the agent imposes no energy charge) or greater than or equal to the Landauer limit at 300 K:¶
L = k_B * T * ln(2) = 1.381e-23 J/K * 300 K * 0.693 = 2.854e-21 J¶
where k_B is the Boltzmann constant (1.380649 × 10^{-23} J/K, SI 2019 definition) and T is the ambient temperature in kelvin.¶
Landauer's principle [LANDAUER] establishes
that erasing one bit of information in a system at
temperature T dissipates at least k_B * T * ln(2) joules
as heat. Any real computation that modifies memory must
erase at least one bit; therefore no physical computation
can have a base energy cost strictly between zero and the
Landauer limit. A base_cost_joules value in the
open interval (0, 2.854e-21) is physically impossible and
MUST be rejected by conformant validators.¶
This constraint is not a billing requirement: it is a
physical plausibility check. Agents SHOULD set
base_cost_joules to a realistic estimate of
their per-invocation energy consumption. This enables
multi-agent economic systems to perform energy-accounting
without fraudulent zero-cost claims.¶
The additional energy cost per output token, in joules. If present, MUST be non-negative.¶
An open-ended object for framework- and application-specific annotations. Implementations MUST NOT reject an AgentCard because it contains unrecognised metadata keys.¶
Keys beginning with the prefix pacr: are reserved
for annotations derived from Physically Annotated Causal
Records (PACR) as defined in the Aevum Network specification.
Keys beginning with the prefix mcp: are reserved for
Model Context Protocol annotations. All other prefixes are
unregistered and available for private use.¶
The following pacr:-prefixed keys are defined in
this document:¶
pacr:trust_tieruntrusted,
basic, established, verified,
or banned. Absence of this field implies
untrusted.¶
pacr:substrate_scope"M1_Ultra", "UKBiobank").
This field is used to prevent data-bias ossification in
multi-agent systems that aggregate statistics across
heterogeneous agents.¶
"metadata": {
"pacr:trust_tier": "established",
"pacr:substrate_scope": "AWS_Graviton_c7g",
"framework": "crewai",
"created_at": "2026-04-23T00:00:00Z"
}
¶
An optional list of shared goals that this agent has subscribed to participate in. This field supports multi-agent coalition formation: an orchestrator can discover all agents that have subscribed to a given goal identifier and assemble a coalition without prior explicit configuration.¶
Each entry contains a REQUIRED goal_id string, an
OPTIONAL human-readable description, and an OPTIONAL
priority value in the range [0, 1] indicating the
agent's relative commitment to this goal.¶
"goal_subscriptions": [
{
"goal_id": "01HZQK3P8EMXR9V7T5N2W4J6C1",
"description": "Competitive analysis for Q3 2026",
"priority": 0.8
}
]
¶
An AgentCard MUST be serialised as a JSON object [RFC8259]. The canonical serialisation MUST use UTF-8 character encoding [RFC3629].¶
The RECOMMENDED media type for AgentCard documents is
application/agentcard+json (see
Section 9.1). Implementations SHOULD
also accept application/json for backward compatibility.¶
When an AgentCard is embedded in another document (e.g., an MCP tool response), the embedding format MAY serialize the AgentCard as a JSON string containing an escaped JSON object. Implementations MUST accept both embedded-string and direct- object forms.¶
An agent that serves its AgentCard at a well-known HTTP(S)
endpoint SHOULD publish it at the path
/.well-known/agentcard relative to the agent's base
URL (see Section 9.2).¶
For example, an agent at https://agents.example.com/
SHOULD publish its AgentCard at:¶
GET https://agents.example.com/.well-known/agentcard
Accept: application/agentcard+json
HTTP/1.1 200 OK
Content-Type: application/agentcard+json
Cache-Control: max-age=3600
{
"agent_id": "01HZQK3P8EMXR9V7T5N2W4J6C0",
"name": "ExampleAgent",
...
}
¶
The response SHOULD include a Cache-Control header.
AgentCards are relatively stable documents; a max-age of
3600 seconds (one hour) is RECOMMENDED. Validators and
registries SHOULD re-fetch at the cache expiry interval.¶
Agents that use the mcp protocol SHOULD also expose
their AgentCard via the AgentCard MCP server tools defined in
[AGENTCARD-MCP].¶
A conformant AgentCard validator MUST enforce the following rules. A document that fails any MUST rule is invalid and MUST be rejected.¶
agent_id MUST be exactly 26 characters drawn
from the Crockford Base32 alphabet
([0-9A-HJKMNP-TV-Z]).¶
version MUST conform to Semantic Versioning 2.0.0.
The regular expression is:
^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)
(?:-[0-9A-Za-z\-.]+)?(?:\+[0-9A-Za-z\-.]+)?$¶
capabilities MUST contain at least one entry.¶
capabilities[i].id MUST match
^[a-z0-9][a-z0-9._-]*$.¶
endpoint.protocol MUST be one of:
http, https, grpc,
stdio, mcp.¶
endpoint.url MUST be a valid URI
[RFC3986].¶
pricing.base_cost_joules is present and non-zero,
it MUST be greater than or equal to 2.854 × 10^{-21} joules
(the Landauer limit at 300 K).¶
pricing.per_token_joules is present, it MUST be
non-negative.¶
metadata.pacr:trust_tier, if present, MUST be one
of: untrusted, basic, established,
verified, banned.¶
OAuth 2.0 [RFC6749] and the emerging WIMSE framework [I-D.ietf-wimse-arch] address credential issuance, delegation, and workload authentication. AgentCard is complementary: it describes what an already- authenticated agent can do and how to reach it. An implementor SHOULD use WIMSE or OAuth for authentication and AgentCard for capability advertisement.¶
MCP [MCP-SPEC] defines a protocol for communication between language model hosts and tool servers. AgentCard defines a data format for self-description that MCP servers can publish. The two are orthogonal: an MCP server MAY publish an AgentCard; an AgentCard MAY reference an MCP endpoint.¶
The capabilities[].id dot-namespace convention
in AgentCard is intentionally compatible with MCP tool
name fields to minimise conversion overhead.¶
DID Documents [W3C-DID] provide verifiable,
self-sovereign identity using public-key cryptography.
AgentCard does not incorporate cryptographic binding by
design: requiring agents to manage key pairs introduces
deployment friction disproportionate to the use case of
framework-neutral capability advertisement. Implementors
requiring cryptographic agent identity SHOULD embed a DID
reference in the AgentCard metadata field and sign
the AgentCard using the DID's verification method.¶
OpenAPI [OPENAPI] and AsyncAPI describe
the full API surface of a service: paths, parameters,
response schemas, authentication flows, and server listings.
AgentCard is intentionally lighter: it declares what an
agent is and what it can do, not the complete HTTP API
surface. AgentCard and OpenAPI are complementary; an
AgentCard MAY reference a full OpenAPI document via the
metadata field.¶
{
"agent_id": "01HZQK3P8EMXR9V7T5N2W4J6C0",
"name": "ResearchAnalyst",
"version": "1.2.0",
"capabilities": [
{
"id": "text.summarise",
"description": "Summarise a document to a given word limit.",
"input_schema": {
"type": "object",
"properties": {
"text": { "type": "string" },
"max_words": { "type": "integer", "default": 200 }
},
"required": ["text"]
}
},
{
"id": "tool.web_search",
"description": "Search the public web and return top-k results.",
"tags": ["search", "retrieval"]
},
{
"id": "data.fetch_csv",
"description": "Fetch a CSV file from a URL and return parsed rows."
}
],
"endpoint": {
"protocol": "https",
"url": "https://agents.example.com/api/research-analyst",
"auth": { "scheme": "bearer" }
},
"pricing": {
"base_cost_joules": 2.854e-21,
"per_token_joules": 1.4e-24
},
"metadata": {
"pacr:trust_tier": "established",
"pacr:substrate_scope": "AWS_Graviton_c7g",
"framework": "crewai",
"created_at": "2026-04-23T00:00:00Z"
},
"goal_subscriptions": [
{
"goal_id": "01HZQK3P8EMXR9V7T5N2W4J6C1",
"description": "Competitive analysis for Q3 2026",
"priority": 0.8
}
]
}
¶
AgentCard does not authenticate the claims made in the
capabilities array. A malicious agent could
advertise capabilities it does not possess. Consumers MUST
NOT grant elevated privileges or trust solely on the basis
of declared capabilities. Operational trust SHOULD be
established through observed behaviour over time (e.g., via
a causal return rate as described in
Section 2.6).¶
ULID collision probability is approximately 2^{-80} per pair for randomly generated identifiers. Implementations MUST use a cryptographically secure random number generator for the 80-bit random component. Sequential or low-entropy random components permit identity prediction and MUST NOT be used in adversarial environments.¶
The Landauer floor check prevents trivially implausible
energy claims but does not prevent an agent from claiming
an energy cost far below its true cost. Multi-agent systems
that use pricing.base_cost_joules for economic
settlement SHOULD independently verify claimed costs against
observed latency and throughput.¶
The metadata.pacr:trust_tier field is self-declared.
A malicious agent could claim a high trust tier it has not
earned. Consumers SHOULD treat self-declared trust tiers
as advisory hints and MUST validate trust tier claims
against an independent record of the agent's interaction
history before acting on them.¶
If an agent's AgentCard is served over HTTP (not HTTPS),
an on-path attacker can substitute a malicious endpoint
URL. Agents SHOULD serve AgentCards exclusively over TLS
(https://). Consumers SHOULD reject AgentCards
whose endpoint URL scheme differs from the scheme used to
fetch the AgentCard.¶
AgentCard does not define any fields for personally
identifiable information (PII). Implementors MUST NOT
embed user data, operator names, or other PII in the
name, capabilities[].description,
or metadata fields unless the AgentCard is
served over a channel with appropriate access controls.¶
This document requests that IANA register the following media type in the "Media Types" registry [RFC6838]:¶
This document requests that IANA register the following well-known URI in the "Well-Known URIs" registry [RFC8615]:¶
The author thanks the Aevum Network community for feedback on the PACR-derived metadata fields, and the MCP ecosystem for validating the dot-namespaced capability identifier convention through practical implementation.¶
The Landauer pricing floor concept was first articulated in the context of multi-agent economic systems in the Aevum Network specification (2026). Its inclusion in AgentCard reflects the broader principle that computational resources are physically bounded and should be declared honestly.¶