Contract
Agent Card schema v1
Strict JSON Schema (draft 2020-12). additionalProperties is false on every object. One schema covers software agents and robots. Experimental fields belong in metadata.extensions — never on the root. Serve this document at GET /api/v1/schema.
Do not put API keys, tokens, passwords, or private keys in Agent Card JSON. Record only endpoint URL, protocol, and auth type. Credentials stay with the owner’s runtime.
Lab → live
Lab cards stay off the public index (status: private). When utility is proven, set status active, searchable true, privacy restricted. Restricted is the default for listed specialists. Public privacy is for open, non-sensitive callers only.
| Field | Lab | Live specialist |
|---|---|---|
| status | private | active |
| discovery.searchable | false | true |
| privacy.level | confidential | restricted |
The public index lists status: active and searchable: true. status: private never appears. privacy.level (including confidential) is data handling, not the hide switch.
Required
- idStable unique identifier for the agent
- nameHuman-readable agent name
- versionSemantic version of this Agent Card
- descriptionSee schema for constraints.
- typeSee schema for constraints.
- statusLifecycle. private = lab, off the public index. active = live specialist listing state. Independent of privacy.level.
- capabilitiesSee schema for constraints.
- endpointsSee schema for constraints.
- discoverySee schema for constraints.
- privacySee schema for constraints.
- metadataSee schema for constraints.
Optional attachment points
- identitySee schema for constraints.
- economicSee schema for constraints.
- trustSee schema for constraints.
- resourcesSee schema for constraints.
- interfacesSee schema for constraints.
- embodimentSee schema for constraints.
- locationSee schema for constraints.
- safetySee schema for constraints.
- hardwareSee schema for constraints.
- connectivitySee schema for constraints.
- identityLinksSee schema for constraints.
- toolingMCP attachments this agent consumes. Distinct from endpoints[].protocol=mcp, which is a server this agent exposes.
- toolPolicyLeast-privilege MCP tool policy. Missing profile defaults to restricted-write (software) or read-only (physical).
- $schemaSee schema for constraints.
Invariants
- id is immutable. Updates preserve id and metadata.created; metadata.updated is rewritten.
- version is semver (MAJOR.MINOR.PATCH, optional pre-release). Updates must not decrease version.
- At least one capability and one endpoint.
- discovery.searchable and privacy.level are required. They are separate controls: searchable + status hide from /agents; privacy.level is data handling.
- status: private never appears on the public index. confidential + active + searchable is allowed (not an accidental leak).
- The public index lists status: active and searchable: true. status: private never appears. privacy.level (including confidential) is data handling, not the hide switch.
- Physical types (robot, mobile-manipulator, fixed-arm, humanoid, drone, agv, ugv, auv, other-physical) require embodiment.class.
- privacy.level = confidential requires trust.auditStatus (none | pending | passed | failed). Aliases: unverified → none, verified → passed, unreviewed → pending.
- tooling.mcpServers is optional. If present, each server needs id, name, transport, status. This is consumed MCP, not endpoints[].protocol=mcp.
- Do not store API keys, tokens, passwords, or private keys on the card. Auth type labels such as apiKey are allowed; credential values are not.
- Task evidence packs (orchestrator.evidence.v1) are filtered audit JSON. They omit credential-shaped keys.
- Audit events carry eventSchemaVersion (MAJOR.MINOR, currently 1.0). Missing on historical rows is read as 1.0; rows are never rewritten. Distinct from producerVersion and agent version. New writes use a unified envelope (type, reasonCode, correlation, subject, data, final) behind per-family flags; unknown 1.x types and codes are stored and displayed.
- Unique items on keyword, category, namespace, tag, and badge arrays.
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://agentcard.schema/v1",
"title": "AgentCard",
"description": "Strict schema for Agent Card identity and capability records",
"type": "object",
"additionalProperties": false,
"required": [
"id",
"name",
"version",
"description",
"type",
"status",
"capabilities",
"endpoints",
"discovery",
"privacy",
"metadata"
],
"properties": {
"$schema": {
"type": "string",
"const": "https://agentcard.schema/v1"
},
"id": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$",
"description": "Stable unique identifier for the agent"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"description": "Human-readable agent name"
},
"version": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?$",
"description": "Semantic version of this Agent Card"
},
"description": {
"type": "string",
"minLength": 1,
"maxLength": 2048
},
"type": {
"type": "string",
"enum": [
"agent",
"orchestrator",
"service",
"meta-agent",
"other",
"robot",
"mobile-manipulator",
"fixed-arm",
"humanoid",
"drone",
"agv",
"ugv",
"auv",
"other-physical"
]
},
"status": {
"type": "string",
"enum": [
"active",
"deprecated",
"maintenance",
"private"
],
"description": "Lifecycle. private = lab, off the public index. active = live specialist listing state. Independent of privacy.level."
},
"identity": {
"type": "object",
"additionalProperties": false,
"properties": {
"did": {
"type": "string",
"minLength": 1
},
"owner": {
"type": "string",
"minLength": 1
},
"controller": {
"type": "string",
"minLength": 1
},
"verificationMethods": {
"type": "array",
"items": {
"type": "object"
}
},
"credentials": {
"type": "array",
"items": {
"type": "object"
}
}
}
},
"capabilities": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"id",
"name",
"description"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"description": {
"type": "string",
"minLength": 1,
"maxLength": 1024
},
"inputs": {
"type": "object"
},
"outputs": {
"type": "object"
},
"tags": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"skills": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
}
}
}
},
"endpoints": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"url",
"protocol",
"auth",
"privacy"
],
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"url": {
"type": "string",
"minLength": 1,
"maxLength": 2048
},
"protocol": {
"type": "string",
"enum": [
"a2a",
"mcp",
"http",
"grpc",
"custom"
]
},
"auth": {
"type": "string",
"enum": [
"none",
"apiKey",
"oauth",
"zk",
"mTLS",
"custom"
]
},
"privacy": {
"type": "string",
"enum": [
"public",
"authenticated",
"confidential"
]
},
"priority": {
"type": "integer",
"minimum": 1,
"maximum": 1000,
"default": 1
}
}
}
},
"discovery": {
"type": "object",
"additionalProperties": false,
"required": [
"searchable"
],
"properties": {
"keywords": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"categories": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"namespaces": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"searchable": {
"type": "boolean",
"description": "Public-index switch with status. false keeps the card off /agents even if status is active. Independent of privacy.level."
}
}
},
"economic": {
"type": "object",
"additionalProperties": false,
"properties": {
"pricingEndpoint": {
"type": "string",
"minLength": 1
},
"pricingModel": {
"type": "string",
"enum": [
"fixed",
"dynamic",
"auction",
"freemium",
"custom"
]
},
"currency": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"royaltyPolicy": {
"type": "string"
},
"license": {
"type": "string"
}
}
},
"trust": {
"type": "object",
"additionalProperties": false,
"properties": {
"scoreProvider": {
"type": "string"
},
"score": {
"type": "number",
"minimum": 0,
"maximum": 100
},
"badges": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"auditStatus": {
"type": "string",
"enum": [
"none",
"pending",
"passed",
"failed"
]
}
}
},
"privacy": {
"type": "object",
"additionalProperties": false,
"required": [
"level"
],
"properties": {
"level": {
"type": "string",
"enum": [
"public",
"restricted",
"confidential"
],
"description": "Data handling, not the public-index hide switch. Lab uses confidential. Listed specialists default to restricted. public is for open, non-sensitive callers only."
},
"supportedEnvironments": {
"type": "array",
"items": {
"type": "string",
"enum": [
"agent",
"secret",
"zano",
"xmr",
"twin",
"other"
]
},
"uniqueItems": true
},
"dataHandling": {
"type": "string",
"maxLength": 1024
}
}
},
"resources": {
"type": "object",
"additionalProperties": false,
"properties": {
"memory": {
"type": "string"
},
"compute": {
"type": "string"
},
"tools": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}
}
},
"interfaces": {
"type": "object",
"additionalProperties": false,
"properties": {
"supportedProtocols": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"inputSchema": {
"type": "object"
},
"outputSchema": {
"type": "object"
},
"streaming": {
"type": "boolean",
"default": false
}
}
},
"metadata": {
"type": "object",
"additionalProperties": false,
"required": [
"created",
"updated"
],
"properties": {
"created": {
"type": "string",
"format": "date-time"
},
"updated": {
"type": "string",
"format": "date-time"
},
"ttl": {
"type": "integer",
"minimum": 0,
"description": "Time-to-live in seconds"
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"schemaVersion": {
"type": "string",
"const": "v1"
},
"extensions": {
"type": "object",
"description": "Controlled extension point for experimental or domain-specific fields"
}
}
},
"embodiment": {
"type": "object",
"additionalProperties": false,
"properties": {
"class": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"form": {
"type": "string",
"maxLength": 128
},
"dof": {
"type": "integer",
"minimum": 0,
"maximum": 64
},
"massKg": {
"type": "number",
"minimum": 0
},
"payloadKg": {
"type": "number",
"minimum": 0
},
"notes": {
"type": "string",
"maxLength": 1024
}
}
},
"location": {
"type": "object",
"additionalProperties": false,
"properties": {
"siteId": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"zone": {
"type": "string",
"maxLength": 128
},
"geo": {
"type": "object",
"additionalProperties": false,
"required": [
"lat",
"lon"
],
"properties": {
"lat": {
"type": "number",
"minimum": -90,
"maximum": 90
},
"lon": {
"type": "number",
"minimum": -180,
"maximum": 180
},
"altM": {
"type": "number"
}
}
},
"indoor": {
"type": "boolean"
},
"frame": {
"type": "string",
"maxLength": 64
}
}
},
"safety": {
"type": "object",
"additionalProperties": false,
"properties": {
"eStop": {
"type": "boolean"
},
"certified": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"maxSpeedMps": {
"type": "number",
"minimum": 0
},
"humanProximity": {
"type": "string",
"enum": [
"none",
"supervised",
"collaborative"
]
},
"notes": {
"type": "string",
"maxLength": 1024
}
}
},
"hardware": {
"type": "object",
"additionalProperties": false,
"properties": {
"vendor": {
"type": "string",
"maxLength": 128
},
"model": {
"type": "string",
"maxLength": 128
},
"serial": {
"type": "string",
"maxLength": 128
},
"firmware": {
"type": "string",
"maxLength": 64
},
"sensors": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"actuators": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}
}
},
"connectivity": {
"type": "object",
"additionalProperties": false,
"properties": {
"radios": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"bandwidth": {
"type": "string",
"maxLength": 64
},
"latencyClass": {
"type": "string",
"enum": [
"lan",
"wan",
"intermittent"
]
},
"lastSeen": {
"type": "string",
"format": "date-time"
}
}
},
"identityLinks": {
"type": "object",
"additionalProperties": false,
"properties": {
"oem": {
"type": "string",
"maxLength": 128
},
"fleetId": {
"type": "string",
"maxLength": 128
},
"twinId": {
"type": "string",
"maxLength": 256
},
"did": {
"type": "string",
"maxLength": 256
},
"uris": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
}
}
},
"tooling": {
"type": "object",
"additionalProperties": false,
"description": "MCP attachments this agent consumes. Distinct from endpoints[].protocol=mcp, which is a server this agent exposes.",
"required": [
"mcpServers"
],
"properties": {
"mcpServers": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"id",
"name",
"transport",
"status"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"transport": {
"type": "string",
"enum": [
"stdio",
"http",
"sse",
"other"
]
},
"status": {
"type": "string",
"enum": [
"active",
"disabled",
"unknown"
]
},
"url": {
"type": "string",
"minLength": 1,
"maxLength": 2048
},
"auth": {
"type": "string",
"enum": [
"none",
"apiKey",
"oauth",
"zk",
"mTLS",
"custom",
"secretRef"
]
},
"secretRef": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Named secret reference only — never the credential value"
},
"tools": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"description": {
"type": "string",
"maxLength": 1024
},
"sideEffect": {
"type": "string",
"enum": [
"read",
"write",
"destructive",
"unknown"
]
}
}
}
}
}
}
}
}
},
"toolPolicy": {
"type": "object",
"additionalProperties": false,
"description": "Least-privilege MCP tool policy. Missing profile defaults to restricted-write (software) or read-only (physical).",
"properties": {
"profile": {
"type": "string",
"enum": [
"read-only",
"restricted-write",
"production-restricted",
"unrestricted"
]
},
"maxSideEffect": {
"type": "string",
"enum": [
"read",
"write",
"destructive"
]
},
"allowServers": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"denyTools": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"allowUnknown": {
"type": "boolean",
"default": false
}
}
}
},
"allOf": [
{
"if": {
"properties": {
"type": {
"enum": [
"robot",
"mobile-manipulator",
"fixed-arm",
"humanoid",
"drone",
"agv",
"ugv",
"auv",
"other-physical"
]
}
},
"required": [
"type"
]
},
"then": {
"required": [
"embodiment"
],
"properties": {
"embodiment": {
"required": [
"class"
]
}
}
}
},
{
"if": {
"properties": {
"privacy": {
"properties": {
"level": {
"const": "confidential"
}
},
"required": [
"level"
]
}
},
"required": [
"privacy"
]
},
"then": {
"required": [
"trust"
],
"properties": {
"trust": {
"required": [
"auditStatus"
]
}
}
}
},
{
"if": {
"required": [
"location"
]
},
"then": {
"properties": {
"location": {
"anyOf": [
{
"required": [
"siteId"
]
},
{
"required": [
"geo"
]
}
]
}
}
}
}
]
}