Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5f869fa
feat: initial draft of core unified AI card schema definition
mindpower Nov 4, 2025
774c17e
feat: updated the initial ai card schema to include only the core fie…
mindpower Nov 4, 2025
5f7a399
feat: initial ai card - updated comments
mindpower Nov 5, 2025
9d97587
feat: updated the ai-card-example
mindpower Nov 5, 2025
a334ccf
feat: updated ai card based on latest MCP specific proposal, added ai…
mindpower Nov 5, 2025
999a93c
feat: updated ai-card-example.md
mindpower Nov 5, 2025
473da26
feat: updated ai-card and ai-catalog spec based on feedbacks
mindpower Nov 24, 2025
772816b
feat: Updated spec: support multiple endpont, add notes for .well-kno…
mindpower Nov 24, 2025
16112e2
feat: add policy and TOS url field
mindpower Nov 24, 2025
7d55a04
feat: added maturity, signature to ai card spec and also use map for …
mindpower Nov 24, 2025
123070f
feat: updated ai-card-example.md
mindpower Nov 24, 2025
879fcf8
feat: use service-type for services as key, also add CDDL spec format
mindpower Nov 25, 2025
3b75476
feat: updated ai-card.md descriptions
mindpower Nov 25, 2025
d19b2ea
feat: renamed ai-card.md to ai-card-cddl.md, same for ai-catalog.md
mindpower Nov 25, 2025
7b69e6c
feat: updated ai card spec based on feedbacks
mindpower Dec 1, 2025
8ea75bd
feat: make trust field optional so dev/internal agents can choose to …
mindpower Dec 2, 2025
c0dcf3e
feat: clarify that the id field can be any globally unique URI
mindpower Dec 2, 2025
ba9e104
updated comparison table
mindpower Dec 2, 2025
c8c2bef
spec: Rename 'services' to 'interfaces', adopt 'AI Service' terminolo…
mindpower Dec 5, 2025
ed1c4aa
spec: updated spec's type script format based on latest discussion
mindpower Dec 5, 2025
f84259a
updated .gitignore
mindpower Dec 12, 2025
49c50f3
updated the field name from interfaces to protocols for supported pro…
mindpower Dec 12, 2025
a47e2d2
refactor: rename Protocol to ProtocolDetail and update related types …
mindpower Dec 26, 2025
b309353
Merge converged changes from PR #17, added artifacts, also update nam…
mindpower Mar 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.DS_Store
node_modules/
tsconfig.json
type/*.md
specification/json/
package-lock.json
package.json
98 changes: 98 additions & 0 deletions specification/cddl/ai-card.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
### AI Card Specification in CDDL format
```ini
; ============================================================================
; AI Card Specification (v1)
; A unified metadata format for AI Services (Agents/Tools)
; ============================================================================

AICard = {
$schema: text, ; URI to the JSON schema (e.g. "https://...")
specVersion: text, ; Major.Minor version (e.g. "1.0")

identifier: text, ; agent global unqiue identifier in URN format (see: https://github.com/Agent-Card/ai-card/pull/18)
; --- Metadata ---
displayName: text, ; Human-readable name for the AI service
description: text, ; Short description of the AI service's purpose
? logoUrl: text, ; URL to logo. Data URL (RFC 2397) recommended for privacy
? tags: [* text], ; List of keywords to aid in discovery
? maturity: MaturityLevel, ; Lifecycle stage of the AI service

; --- Ownership & Trust ---
publisher: Publisher, ; Information about the entity that owns this AI service
? trust: Trust, ; Security and compliance proofs (Optional)
? signature: text, ; Detached JWS signing the card content (Integrity)

; --- Protocols ---
; Map of supported protocol interfaces (e.g. "a2a" => Interface, "mcp" => Interface)
protocols: { * ProtocolType => ProtocolDetail },

; --- Housekeeping ---
createdAt: tdate, ; ISO 8601 Date when the AI service was first created
updatedAt: tdate, ; ISO 8601 Date when this card was last modified
? metadata: { * text => any } ; Open slot for custom/non-standard metadata
}

MaturityLevel = "preview" / "stable" / "deprecated"
ProtocolType = "mcp" / "a2a" / text

; --- Core Components ---

Publisher = {
id: text, ; Verifiable ID of the publisher organization
name: text, ; Human-readable name of the publisher
? identityType: text, ; Type hint (e.g. "did", "dns")
? attestation: Attestation ; Proof of the publisher's identity
}

Trust = {
; --- Identity (Subject) ---
identity: text, ; The Primary Key / Subject of this card, Globally Unique URI (per RFC 3986), (DID, SPIFFE, or URL)
? identityType: text, ; Type hint (e.g. "did", "spiffe"). Optional if clear from ID.

? trustSchema: TrustSchema,
? attestations: [* Attestation], ; List of compliance credentials (SOC2, HIPAA, etc.)
? provenance: [* ProvenanceLink],
? privacyPolicyUrl: text, ; URL to the privacy policy
? termsOfServiceUrl: text ; URL to the terms of service
}

TrustSchema = {
id: text,
version: text,
? governanceUri: text,
? verificationMethods: [* text]
}

ProvenanceLink = {
relation: text,
sourceId: text,
? sourceDigest: text,
? registryUri: text,
? statementUri: text,
? signatureRef: text
}

Attestation = {
type: text, ; Type of proof (e.g. "SOC2-Type2", "HIPAA-Audit")

; Reference Pattern (Generic for Remote or Inline)
uri: text, ; remote location: "https://..." or inline "data:..."
mediaType: text, ; Format: "application/pdf", "application/jwt"

? digest: text, ; Hash for integrity (e.g. "sha256:...")
? size: uint, ; Size in bytes
? description: text ; Human-readable label
}

; --- Interaction Protocol ---

ProtocolDetail = {
type: ProtocolType, ; Protocol ID (matches key in protocols map)
? name: text, ; Human-readable label (e.g. "Fiance Agent A2A")

; The "Black Box" for protocol-specific data
; Endpoints, Auth, and Skills are defined INSIDE here by the protocol spec.
protocolSpecific: { * text => any }
}

```
30 changes: 30 additions & 0 deletions specification/cddl/ai-cddl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
### AI Catalog Specification in CDDL format
```ini
; ============================================================================
; AI Catalog Specification (v1)
; The "Index" file served at /.well-known/ai-catalog.json
; ============================================================================

AICatalog = {
$schema: text, ; URI to the JSON schema
specVersion: text, ; Version of the Catalog spec (e.g. "1.0.0")
? host: HostInfo, ; Who runs this server/registry
entry: [* CatalogEntry] ; The list of available AI services
}

HostInfo = {
name: text, ; The human-readable name of the host (e.g., the company name)
? id: text, ; Host Identity (DID)
? documentationUrl: text, ; A URL to the host's main documentation
? logoUrl: text ; A URL to the host's logo
}

CatalogEntry = {
id: text, ; Must match the id in the linked AI Service Card
name: text, ; Human-readable name for the AI Service
description: text, ; Short description
? tags: [* text], ; A list of tags for filtering and discovery
cardUrl: text, ; URL to the full ai-card.json
updatedAt: tdate ; Last modified time of the AI Card (for crawler optimization)
}
```
20 changes: 20 additions & 0 deletions specification/cddl/comparison.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Comparison of Card Structures

The unified AI Card defines core AI Card Features that's common in both (or more) protocols. It works by:
- "Lifting" all common fields (id, name, description, publisher, authentication, trust, etc) to the top level.
- "Plugging in" all protocol-specific fields (skills for A2A, capabilities for MCP) into the protocolSpecific payload.

This table shows how the fields from A2A and MCP map to the unified AI Card structure.
| Concept | A2A `AgentCard` (Spec) | MCP `Server Card` (Proposal) | **Unified `AI Card` (V1)** |
| :--- | :--- | :--- | :--- |
| **Identity (Subject)** | Implied by Host | `serverInfo.name` | **`id`** (Root URI) + `identityType` |
| **Name** | `name` | `serverInfo.title` | **`name`** |
| **Description** | `description` | `description` | **`description`** |
| **Logo** | `icon_url` | `iconUrl` | **`logoUrl`** (Rec: Data URI) |
| **Publisher** | `provider` (Object) | `serverInfo` | **`publisher`** (Object with `id`, `name`) |
| **Trust / Security** | `signatures` (Optional) | Not Defined | **`trust`** (Optional Object: Proofs, Policies) |
| **Protocol Support** | Implied (A2A Only) | Implied (MCP Only) | **`protocols`** (Map: `"a2a": {...}`, `"mcp": {...}`) |
| **Endpoint URL** | `url` | `transport.endpoint` | `protocols[x].protocolSpecific` (**Delegated**) |
| **Authentication** | `securitySchemes` | `authentication` | `protocols[x].protocolSpecific` (**Delegated**) |
| **Capabilities** | `skills` | `tools`, `resources` | `protocols[x].protocolSpecific` (**Delegated**) |
| **Versioning** | `version` | `serverInfo.version` | **`specVersion`** (Card Ver) + `updatedAt` |
33 changes: 33 additions & 0 deletions specification/examples/ai-catalog.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"$schema": "https://agent-card.github.io/spec/sep-0015/catalog-schema.json",
"specVersion": "1.0",
"host": {
"name": "Acme Services Inc.",
"id": "did:example:org-acme-corp",
"documentationUrl": "https://docs.acme-corp.com/agents"
},
"records": [
{
"id": "did:example:agent-finance-001",
"name": "Acme Finance Agent",
"description": "Multi-protocol finance agent.",
"tags": [
"finance",
"trading"
],
"cardUrl": "https://api.acme-corp.com/cards/acme-finance-agent.json",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do I know if this is an MCP Server Card or an A2A Card or something else?

Copy link
Collaborator Author

@mindpower mindpower Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ToddSegal We have two clean options. We could implicitly hint via the card's filename (e.g., agent.json-> A2A, mcp.json -> MCP, ai-card.json -> Unified card). However, the more robust approach is for the catalog entries to simply use an explicit type discriminator alongside the URL. For example:

{ "type": "mcp-server", "url": "https://.../mcp-card.json" }
{ "type": "a2a-agent", "url": "https://.../agent-card.json" }

This gives us a unified discovery layer immediately, while MCP can keep its native card and allowing A2A to use the heavier ai-card envelope (which requires identity, tags, and trust metadata for autonomous routing) (which also will become the unified card when mcp is ready to migrate)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't the cardUrl always be an instance of AI Card url in the catalog?

"updatedAt": "2026-02-22T16:30:00Z"
},
{
"id": "urn:example:data:market-dataset-2026q1",
"name": "Market Dataset Q1 2026",
"description": "Artifact-focused card for training and evaluation.",
"tags": [
"dataset",
"finance"
],
"cardUrl": "https://api.acme-corp.com/cards/market-dataset-2026q1.json",
"updatedAt": "2026-02-22T16:00:00Z"
}
]
}
55 changes: 55 additions & 0 deletions specification/examples/data-asset-card.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"$schema": "https://agent-card.github.io/spec/sep-0015/schema.json",
"specVersion": "1.0",
"cardVersion": "2026.02.22",
"identifier": "urn:example:data:market-dataset-2026q1",
"displayName": "Market Dataset Q1 2026",
"description": "Historical market data prepared for model training and evaluation.",
"publisher": {
"id": "did:example:org-acme",
"identityType": "did",
"name": "Acme Financial Corp"
},
"artifacts": {
"dataset": {
"id": "artifact/dataset",
"version": "1.0.0",
"data": {
"format": "parquet",
"artifacts": [
{
"uri": "oci://registry.example.com/ai-data/market-dataset:2026q1",
"mediaType": "application/parquet",
"digest": "sha256:9999888877776666555544443333222211110000aaaabbbbccccddddeeeeffff",
"size": 24599124,
"description": "Primary dataset artifact"
}
]
}
}
},
"trust": {
"identity": "did:example:data:market-dataset-2026q1",
"identityType": "did",
"trustSchema": {
"id": "https://trust.acme-finance.com/schemas/ai-card-trust-profile",
"version": "1.0",
"governanceUri": "https://trust.acme-finance.com/policies/ai-card-trust",
"verificationMethods": [
"did",
"x509"
]
},
"provenance": [
{
"relation": "publishedFrom",
"sourceId": "oci://registry.example.com/ai-data/market-dataset:2026q1",
"sourceDigest": "sha256:9999888877776666555544443333222211110000aaaabbbbccccddddeeeeffff",
"registryUri": "oci://registry.example.com/ai-data/market-dataset@sha256:9999888877776666555544443333222211110000aaaabbbbccccddddeeeeffff",
"statementUri": "https://trust.acme-finance.com/provenance/market-dataset-2026q1.dsse.json"
}
]
},
"createdAt": "2026-02-22T16:00:00Z",
"updatedAt": "2026-02-22T16:00:00Z"
}
100 changes: 100 additions & 0 deletions specification/examples/live-service-card.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{
"$schema": "https://agent-card.github.io/spec/sep-0015/schema.json",
"specVersion": "1.0",
"cardVersion": "2026.02.22",
"identifier": "urn:example:agent-finance-001",
"displayName": "Acme Finance Agent",
"description": "Executes finance workflows through multiple protocol adapters.",
"publisher": {
"id": "did:example:org-acme",
"name": "Acme Financial Corp",
"identityType": "did"
},
"protocols": {
"a2a": {
"id": "protocol/a2a",
"version": "0.1.0",
"required": true,
"data": {
"protocolVersion": "0.3.0",
"locators": [
{
"type": "https",
"role": "api",
"uri": "https://api.acme-finance.com/a2a/v1"
}
],
"skills": [
{
"id": "skill-stock-analysis",
"name": "Run Stock Analysis"
}
]
}
},
"mcp": {
"id": "protocol/mcp",
"version": "0.1.0",
"required": true,
"data": {
"protocolVersion": "2025-06-18",
"locators": [
{
"type": "https",
"role": "api",
"uri": "https://api.acme-finance.com/mcp/v1"
}
],
"capabilities": {
"tools": {
"listChanged": true
}
}
}
}
},
"trust": {
"id": "did:example:agent-finance-001",
"identityType": "did",
"trustSchema": {
"id": "https://trust.acme-finance.com/schemas/ai-card-trust-profile",
"version": "1.0",
"governanceUri": "https://trust.acme-finance.com/policies/ai-card-trust",
"verificationMethods": [
"did",
"x509",
"dns-01"
]
},
"privacyPolicyUrl": "https://acme-finance.com/legal/privacy",
"termsOfServiceUrl": "https://acme-finance.com/legal/terms",
"provenance": [
{
"relation": "materializedFrom",
"sourceId": "urn:example:data:market-dataset-2026q1",
"sourceDigest": "sha256:9999888877776666555544443333222211110000aaaabbbbccccddddeeeeffff",
"registryUri": "oci://registry.example.com/ai-data/market-dataset@sha256:9999888877776666555544443333222211110000aaaabbbbccccddddeeeeffff",
"statementUri": "https://trust.acme-finance.com/provenance/finance-agent-runtime-20260222.dsse.json",
"signatureRef": "did:example:org-acme#keys-1"
}
],
"attestations": [
{
"type": "SOC2-Type2",
"uri": "https://trust.acme-finance.com/reports/soc2-latest.pdf",
"mediaType": "application/pdf",
"digest": "sha256:a1b2c3d4"
}
]
},
"signatures": [
{
"format": "jws-compact",
"keyId": "did:example:org-acme#keys-1",
"createdAt": "2026-02-22T16:30:00Z",
"value": "eyJhbGciOiJFUzI1NiJ9..detached-signature"
}
],
"createdAt": "2026-02-22T16:00:00Z",
"updatedAt": "2026-02-22T16:30:00Z"
}