Skip to content

spec: AI card and AI catalog draft proposal#4

Open
mindpower wants to merge 24 commits intoAgent-Card:mainfrom
mindpower:jbu/ai-card
Open

spec: AI card and AI catalog draft proposal#4
mindpower wants to merge 24 commits intoAgent-Card:mainfrom
mindpower:jbu/ai-card

Conversation

@mindpower
Copy link
Collaborator

@mindpower mindpower commented Nov 5, 2025

Initial Draft of AI Card & AI Catalog Specifications

Note: This PR has been updated to reflect the converged schema architecture co-authored and designed in collaboration with @muscariello .
Key Architecture Decisions:

  • Separation of Concerns: Core identity and trust remain at the root.
  • Isolated Namespaces: Live API interactions are routed through the protocols map (e.g., protocols.a2a, protocols.mcp).
  • Static Assets: File downloads are handled via the artifacts array.

Summary

This PR introduces the foundational draft for the AI Card and AI Catalog specifications, creating a unified framework for describing and discovering AI services.

Key Changes

  1. Unified AI Card Schema (ai-card-cddl.md):

    • Core Abstraction: Establishes a generic ai card format for "AI Service" entity, consolidating metadata like id, name, description, and publisher at the top level.
    • Extensible Interfaces: Defines an interfaces map, keyed by protocol type (e.g., "a2a", "mcp"). This allows a single card to describe multiple interaction protocols, with protocol-specific details encapsulated in a protocolSpecific block.
    • Trust & Identity:
      • The trust section is optional, including fields for privacyPolicyUrl and termsOfServiceUrl.
      • Introduces Attestation field using a reference pattern (uri, mediaType, digest) for both publisher identity proofs and compliance evidence, supporting remote and inline credentials.
    • Additional Metadata:
      • Includes maturity to indicate lifecycle stages ("preview", "stable", "deprecated").
      • Includes an optional signature field for card integrity (detached JWS).
      • Includes identityType hints for id fields (e.g., "did", "spiffe").
  2. AI Catalog for Discovery (ai-catalog-cddl.md):

    • Introduces a lightweight catalog format, designed to be served from a well-known URL (/.well-known/ai-catalog.json).
    • Defines HostInfo for catalog metadata and AIServiceEntry objects for lightweight service discovery, linking to full AI Cards via cardUrl.
  3. Examples and Documentation:

    • Includes ai-card-example.md and ai-catalog-example.md provide complete JSON examples, showcasing dual-protocol agents and catalog files.
    • A comparison.md table maps fields from previous A2A and MCP card proposals to the unified structure, emphasizing the "lift common fields, delegate protocol specifics" design.

Summary

This PR proposes a comprehensive, extensible, and trust-oriented foundation for an interoperable AI service ecosystem. It unifies metadata standards, simplifies multi-protocol support, and introduces a discovery mechanism to streamline integration workflows.

This table below shows how the fields from A2A and MCP map to the unified AI Card structure, based on A2A/MCP:

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

AI-catalog example:

{
  "$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",
      "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"
    }
  ]
}

AI-card example

{
  "$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"
}

@mindpower mindpower changed the title feat: Initial AI card draft proposal feat: Initial AI card and AI catalog draft proposal Nov 5, 2025
@mindpower mindpower changed the title feat: Initial AI card and AI catalog draft proposal feat: AI card and AI catalog draft proposal Nov 5, 2025
@mindpower
Copy link
Collaborator Author

@ToddSegal @dsp-ant Please review and let me know if you have any concerns or questions :-)

@Fannon
Copy link

Fannon commented Nov 18, 2025

@mindpower thanks for writing this up!

I have a question: Will there then still be a standalone MCP Server Card (related modelcontextprotocol/modelcontextprotocol#1649) or would we then always use the AI Card to describe an MCP Server in full?

With A2A it seems to work differently, because A2A already has a standalone A2A Card format, which may best be linked and not repeated?

"scheme": "bearer",
"bearerFormat": "JWT"
},
"protocolSpecific": {
Copy link

Choose a reason for hiding this comment

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

Will this then be identical to MCP Server Card or replace it?
Some information are now on the non protocol specific side.
If there is still an MCP Server card, could it be linked instead?

Copy link
Collaborator Author

@mindpower mindpower Nov 18, 2025

Choose a reason for hiding this comment

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

The auth part will be identical to the MCP card. But we can further discuss the auth for A2A and MCP and other protocol. If it's hard to merge, we can keep them separately as protocol specific.

If there is still an MCP Server card, could it be linked instead?

The MCP (and also A2A) protocol specific definition are not part of the core ai card and should be defined by each spec (A2A, or MCP). But ai-card.json should include all the data, like the following, with service declare the service (A2A, MCP) specific properties:

+ <common ai-card fields>
+ <service interfaces>
     + <service 1>
     + <service 2>
     + <service 3>       

"bearerFormat": "JWT"
},
"protocolSpecific": {
"protocolVersion": "2025-06-18",
Copy link

Choose a reason for hiding this comment

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

Shouldn't this be an array, to match how it works with MCP Server.json from registry spec?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Which specific MCP server field do you think need to be an array here?

The services here is an array which will supports multiple service interfaces. Also the ai catalog will support multiple agent declaration as well.

Copy link

Choose a reason for hiding this comment

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

ProtocolVersions. It's supportedProtocolVersions in the MCP Registry spec I think.

Reason is that one server can (and has to) support multiple protocol versions at the same time to keep compatibility with clients.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I see. Thanks @Fannon for the clarification. Yes we can update the example to supportedProtocolVersions. Here is just to give an example of the protocol specification. It's up to MCP to decide any required fields.

@mindpower
Copy link
Collaborator Author

Thanks @Fannon for the review. Please see the reply above.

Regarding the standalone MCP server card, yes that will be defined separately (not the core ai card spec), but the data will be included in the ai-card.json.

@mindpower thanks for writing this up!

I have a question: Will there then still be a standalone MCP Server Card (related modelcontextprotocol/modelcontextprotocol#1649) or would we then always use the AI Card to describe an MCP Server in full?

With A2A it seems to work differently, because A2A already has a standalone A2A Card format, which may best be linked and not repeated?

@darrelmiller
Copy link

darrelmiller commented Nov 19, 2025

With A2A it seems to work differently, because A2A already has a standalone A2A Card format, which may best be linked and not repeated?

It would be my expectation that we will remove elements from the A2A card that appear in the common area of the AI Card.

@ognis1205
Copy link

I may not have fully grasped the exact intent of this project yet, but based on the README, wouldn't the AICard schema also serve the role that the AICatalog in this PR is trying to fulfill? In other words, I thought the scope of AICard includes server-specific metadata, such as the list of endpoints that expose AgentCards, effectively providing the identities of AI services, rather than just defining a common schema for AgentCard or MCPServerCard (which corresponds to the AICatalog in this PR).

/**
* A direct URL to the agent's logo image.
*/
logoUrl?: string;

Choose a reason for hiding this comment

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

It is not uncommon to have a requirement for multiple logo/icons. One for list views and a larger one for detail pages. Not sure how flexible we would want to be.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks @darrelmiller !

To keep the V1 spec lightweight and easy to parse, it might be better to stick with a single logoUrl string for now? If we find that distinct aspect ratios or multiple formats are a blocker for adoption, we can upgrade this field to support the full W3C ImageResource array structure in a future version like following:

// --8<-- [start:ImageResource]
/**
* Defines an image resource (icon/logo) for the agent.
* Based on the W3C ImageResource specification used in Web App Manifests.
*/
export interface ImageResource {
/**
* The source of the image.
* * SECURITY NOTE: We strongly recommend using **Data URLs** (RFC 2397)
* (e.g., "data:image/png;base64,...") to embed the image binary directly.
*/
src: string;

/**
* A hint as to the media type of the image.
* e.g., "image/png", "image/svg+xml"
*/
type?: string;

/**
* A string containing space-separated image dimensions.
* e.g., "144x144", "512x512", "any" (for SVG)
*/
sizes?: string;

/**
* The purpose of the image, for context.
* e.g., "monochrome", "maskable", "any"
*/
purpose?: string;
}

/**
* A list of icons/logos for the agent.
* Replaces the legacy 'logoUrl' field to support multiple sizes and Data URIs.
*/
logoIcons?: ImageResource[];

/**
* The version of the AI Card specification itself.
*/
specVersion: string;

Choose a reason for hiding this comment

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

If we are going to make $schema required, is there also a need for a specVersion? Is it likely that one would change but the other would not?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's a great question. While they seem redundant, they serve distinct needs:

  1. $schema is for automated validators. It points to the definition file location. Typically, these URLs are 'pinned' to a major version (e.g., .../v1/schema.json) to avoid breaking clients on minor, non-breaking updates.
  2. specVersion is for client logic. It allows a client to easily check for specific feature support (e.g., if version >= '1.2') without having to regex parse a URL string.
  3. Decoupling. Keeping specVersion separates the logical version of the standard from the physical hosting location of the schema file, making the system more robust over time.

For example, the MCP card proposal(modelcontextprotocol/modelcontextprotocol#1649) also includes both a schema and a version field (protocolVersion) or (protocolVersions) as discussed above, acknowledging that clients need an easy way to check for feature matching without parsing schema URLs:

/**
* The primary verifiable ID for the agent (e.g., DID).
*/
id: string;

Choose a reason for hiding this comment

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

Is it a requirement that this is "verifiable" or would that just be a recommendation?

Copy link
Collaborator Author

@mindpower mindpower Nov 24, 2025

Choose a reason for hiding this comment

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

That is a great clarification. The schema only requires id to be a string, so strictly speaking, it is a recommendation for the format.

However, we strongly recommend using a verifiable format (like did, spiffe) rather than a simple UUID or name. While a simple string is valid JSON, it prevents the agent from participating in high-trust workflows (like automated compliance verification) because there is no mechanism to prove ownership of a generic string.

Updated the spec for more clarification.

/**
* The identity string itself.
*/
id: string;

Choose a reason for hiding this comment

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

What is the difference between this id and the id at the root?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch on the potential redundancy. Here is the distinction:

  1. Root id: This is the canonical Agent ID (did, spiffe, etc) used for discovery, indexing, and database keys.
  2. trust.identity.id: This is the Verification Subject. While it must match the Root id, including it explicitly in the Identity object ensures that the security context is self-contained. This prevents 'context confusion' where a detached signature might be applied to the wrong parent object during parsing.
  3. Also, publisher.id: This is distinct. It identifies the Organization (e.g., Acme Corp) that owns the agent, whereas the Root id identifies the specific Agent instance (e.g., Finance Bot 3000).

I will add comments to the schema to explicitly define these relationships and the requirement that Root id and trust.identity.id must match.

* Add here if we want to standardize authentication across all services.
* Otherwise, each protocol would define its own.
*/
authentication: any;

Choose a reason for hiding this comment

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

I think it is going to be challenging to get alignment on authentication mechanisms across all protocols. Unless we assume that everything is going to use HTTP based auth. Even then it is going to be hard.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That is a very pragmatic point. You are right. Getting 100% alignment across all possible future protocols (especially non-HTTP ones) is likely impossible and brittle.

To address this, I propose we treat the top-level authentication field as a recommended standard specifically for HTTP-based interactions (like A2A and MCP), based on the OpenAPI specification.

  • For standard HTTP protocols: We recommend declaring auth using same openAPI spec here. This allows generic clients (like a registry dashboard) to handle common flows like OAuth2 or API Keys without needing deep knowledge of every specific protocol.
  • For non-standard/exotic protocols: They can simply omit this field and define their bespoke authentication requirements entirely within their protocolSpecific payload.

This gives us the benefit of standardization for the vast majority of web-based agents without constraining innovation for other transports. I am also OK that we just remove this for initial version if that make things simple.

Choose a reason for hiding this comment

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

That's am interesting proposal. We will probably need some words to clarify what should happen if there is a contradiction between the top level authentication property and the protocol specific auth details.

@mindpower
Copy link
Collaborator Author

mindpower commented Dec 2, 2025

Sorry for the delayed response and thank you for the detailed rationale @mindpower !

I agree with the separation of AICatalog for a single server (a base URL with scheme + host + port) managing an index of endpoints for the identities of AI Agent-related services (A2A or MCP servers). Your explanation makes sense and I support this design.

What I was trying to clarify, however, is the specific scope of the specification managed in this repository. In other words, I wanted to understand clearly what the AICard is intended to define and achieve.

The current README leaves some ambiguity in terminology and scope. For example:

  • When the README mentions "server," is it referring to an A2A or MCP server, or to a single web resource identified by a base URL (scheme + host + port)?

  • Under Core AI Card Features, it says the schema "may include":

    • Common server metadata (publishing company, documentation links, description, icon, server version)
    • Verifiable metadata (accreditations, certifications, reputational scores, badges)
    • Identity metadata (DID or SPIFFE)
    • Custom data defined by producers or consumers

The term "common server metadata" in the README actually made me feel that what is proposed as the AICatalog in this PR is exactly what the AICard was intended to be. Furthermore, the repository being named ai-card while containing AICatalog functionality may also contribute to this confusion.

My question is really about clarifying the intended goal and scope of AI Card itself.

@ognis1205 Thanks for the follow-up! You hit the nail on the head. I think the term 'server' is doing a lot of heavy lifting in the current README, covering both the Agent itself and the Host infrastructure. That dual meaning effectively created the ambiguity here.

To clarify the specific scope:

1. The Terminology Ambiguity
When the README mentions 'server metadata' or 'server,' it was loosely referring to the Agent (e.g., the 'Travel Agent'), which acts as a server in protocols like MCP/A2A. It was not referring to the Host Infrastructure (e.g., www.example.com/agents/travel-agent) or the collection of agents.

2. The Distinct Scopes

  • AICard (The Core Artifact): Its scope is Identity & Capability Definition. It defines one logical entity (the Agent). It answers: 'Who is this Agent? Who owns it? What protocols does it speak? Is it compliant?'
  • AICatalog (The Discovery Mechanism): Its scope is Host Inventory. It defines what entities are available at a specific network location.

3. Naming & Repo
The repo is named ai-card because the Card is the primary standardized artifact we are defining (the atomic unit of identity). The Catalog is a necessary utility to make those Cards discoverable at scale.

Action Plan:
I will update the README to be precise:

  • Replace generic 'server' references with 'Agent' to distinguish them from the Host.
  • Explicitly define the two scopes: AICard for Identity/Metadata vs. AICatalog for Discovery/Indexing.

Does that distinction make sense?

@mindpower
Copy link
Collaborator Author

mindpower commented Dec 2, 2025

Hi, I think this PR adds a lot at once, and it would be better to defer details on technical structure especially security related structures to smaller PRs.

There are a lot of deployment considerations which are impacted by security decisions, such as DIDs.

If you are going to mention DIDs, you need to describe at least one mandatory to implement method, and that will bring its own set of deployment considerations.

Otherwise, you are essentially just mandating a URN, with some undefined security properties for an undefined resolution procedure.

I'd recommend constraining id to be a URI, and requiring that is be globally unique (if thats the requirement). I'd also recommend avoiding attestation language absent a single mandatory to implement widely adopted standard. If your goal is to just use W3C DIDs and W3C VCs, just say that up front... it will impact the design of the card, and you can lean into the full feature set of JSON-LD for the use case.

If the goal is to define a JSON identity document format, that is based on JOSE / OAuth... that seems like a more reasonable starting point.

@OR13 Thanks for the feedback. You raise a valid point about scope! We don't want to inadvertently mandate a complex PKI or specific DID method in the base schema PR.

I agree we should defer the normative security implementation details to a later PR or a specific "Security Profile" document.

To address your concerns and unblock the structural definition:

  1. ID Constraint: I will update the spec to constrain id simply to be a Globally Unique URI (per RFC 3986). This allows DIDs (did:method:...) but also supports standard URLs (https://...) or URNs (urn:uuid:...) without mandating a specific resolution mechanics yet.
  2. Trust & Attestation: I will clarify that the trust structure is intended to carry JOSE-based artifacts (JWS/JWT), which aligns with your suggestion for a reasonable starting point. I will soften the language to make it clear that while the fields (signature, attestations) exist to hold these tokens, the specific validation logic (e.g., DID resolution vs. x509 chain) is defined by the specific implementation or security profile, not this base schema.
  3. To support gradual adoption and simple use cases (like internal dev tools), I will make the entire trust object optional.
  • Simple Agents: Can just define id, name, and services.
  • Verified Agents: Can optionally add trust and signature to prove identity and compliance.
    This allows us to define the structure for security without mandating a heavy security infrastructure for every single user."

The goal is to reserve the "slots" in the JSON for identity and security (so the schema is stable) without forcing a specific complex deployment model in V1.

Does that decoupling sound like the right approach?

@mindpower
Copy link
Collaborator Author

mindpower commented Dec 2, 2025

Updated the pr based recent discussions. Here is the latest ai card in CDDL format:

; ============================================================================
; AI Card Specification (v1)
; A unified metadata format for AI Agents
; ============================================================================

AICard = {
  $schema: text,              ; URI to the JSON schema (e.g. "https://...")
  specVersion: text,          ; Major.Minor version (e.g. "1.0")
  
  ; --- Identity (Subject) ---
  id: 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.

  ; --- Metadata ---
  name: text,                 ; Human-readable name for the agent
  description: text,          ; Short description of the agent'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 agent

  ; --- Ownership & Trust ---
  publisher: Publisher,       ; Information about the entity that owns this agent
  ? trust: Trust,               ; Security and compliance proofs
  ? signature: text,          ; Detached JWS signing the card content
  
  ; --- Protocols ---
  ; Map of supported protocols (e.g. "a2a" => Service, "mcp" => Service)
  services: { * ServiceType => BaseService }, 

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

; Enum for maturity
MaturityLevel = "preview" / "stable" / "deprecated"

; Service type choices (Standard + Custom)
ServiceType = "mcp" / "a2a" / text

; --- Core Components ---

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

Trust = {
  ; Identity is now implicit (matches Root id)
  ? attestations: [* Attestation], ; List of compliance credentials (SOC2, HIPAA, etc.)
  ? privacyPolicyUrl: text,   ; URL to the privacy policy
  ? termsOfServiceUrl: text   ; URL to the terms of service
}

Attestation = {
  type: text,                 ; Type of proof (e.g. "SOC2-Type2", "HIPAA-Audit")
  
  ; Verifiable credentials (High-Trust)
  ? credentialUrl: text,      ; Remote URL to a signed credential (e.g. JWT/PDF)
  ? credentialValue: text     ; Embedded base64-encoded credential (e.g. JWT)
}

; --- Interaction Services ---

BaseService = {
  type: ServiceType,          ; Protocol ID (matches key in services map)
  ? name: text,               ; Human-readable label (e.g. "Primary Interface")
  
  ; The "Black Box" for protocol-specific data
  ; Endpoints, Auth, and Skills are defined INSIDE here by the protocol spec.
  protocolSpecific: { * text => any } 
}

@ognis1205
Copy link

Thanks @mindpower , really appreciate the clarification and the discussion!

The distinction you described between AICard = "identity/capabilities" and AICatalog = "host-level discovery" makes perfect sense, and I strongly agree with documenting those scopes explicitly.

Regarding the terminology, though:

Replace generic 'server' references with 'Agent' to distinguish them from the Host.

I think using Agent instead of Server may still cause confusion, especially because there are cases like MCP servers used strictly as tooling rather than Agents themselves. So instead of using Agent as the replacement term, I suggest using AI Protocol Server as the umbrella term for "the entity that implements MCP/A2A/etc." I also raised this exact concern earlier here:

#6

So it would be great if you could take that into account as well.

And again, I fully support clearly documenting the two scopes:

  • AICard -> Entity identity + capabilities
  • AICatalog -> Host-level inventory of available entities

These distinctions will make the spec much easier for implementers to follow.

@OR13
Copy link

OR13 commented Dec 2, 2025

@mindpower regarding: #4 (comment)

IMO Yes.

If the goal is secure the card contents, consider https://a2a-protocol.org/latest/specification/#447-agentcardsignature

If the goal is to advertise other signatures related to the card, consider some simple inline and by reference example, using media types and URLs.

You don't really want a "card verifier" to end up having to implement a bunch of different crypto to understand cards, so its better to recommend some mandatory to support basics, and then leave the option for non standard / less well used stuff to be used by the folks that want to use it.

Consider just including URI, Media Type, Size, and Hash, instead of mandating the format of related security assertions, see:

https://helm.sh/blog/helm-oci-mediatypes/

@mindpower
Copy link
Collaborator Author

Regarding: #4 (comment)

Thanks @ognis1205 ! That is an excellent nuance.

You are absolutely right that 'Agent' is too narrow, as it implies autonomy that a simple MCP tool server might not have. Using 'AI Service' or 'AI Protocol Server' as the umbrella term is much more precise. It correctly encompasses:

  • Autonomous Agents (A2A)
  • Tool/Context Servers (MCP)
  • Inference Endpoints (OpenAPI or any other protocol)

I will adopt the suggested 'AI Protocol Server' in the definitions to ensure we don't exclude tool-centric implementations.

I'll proceed with updating the README to reflect: (Please see: #8)

  • The Terminology Shift: 'AI Service/Entity' instead of 'Agent' or generic 'Server'.
  • The Scope Split: AICard (Identity/Capability) vs AICatalog (Host Inventory).

Thanks again for helping clarify these definitions. It will make the spec much more robust for implementers.

@mindpower
Copy link
Collaborator Author

mindpower commented Dec 4, 2025

Thanks @OR13! Regarding: #4 (comment)

This is excellent advice. I strongly agree that we want to avoid forcing every 'card verifier' to implement a kitchen sink of crypto libraries just to parse the document.

1. Card Integrity (signature) Agreed. For the root signature field (integrity of the card itself), we will stick to the A2A AgentCardSignature standard (JWS), as it provides a single, mandatory-to-support baseline for tamper-proofing.

2. External Trust (trust.attestations) I really like your suggestion to use a URI + Media Type + Hash pattern here. It decouples the format of the proof (JWT, PDF, C2PA, etc.) from the structure of the card.

Instead of defining specific fields like credentialValue vs credentialUrl, we can simplify the Attestation object to be a standard Reference as below:

Attestation = {
  type: text,                 ; The semantic type (e.g. "SOC2-Type2", "HIPAA-Audit")
  uri: text,                  ; Location of the credential. Supports both:
                              ; - Remote: "https://trust.example.com/report.pdf"
                              ; - Inline data: "data:application/jwt;base64,eyJ..."
  mediaType: text,            ; The format (e.g. "application/jwt", "application/pdf")
                              ; Tells the verifier which parser to use.
  ? digest: text              ; Optional integrity check (e.g. "sha256:...")
                              ; Critical for remote URLs to ensure content hasn't changed.
  ? size: uint,               ; Size in bytes.
                              ; Helps clients decide whether to download.
  ? description: text         ; Human-readable label (e.g. "2025 Security Audit")}
}

I can see the benefit that this allows:

  • Simple Verifiers: Can just check the digest(hash) and ignore formats they don't understand.
  • Complex Verifiers: Can use the mediaType to dispatch to the correct parser (e.g., verify a JWT or check a PDF signature).

I will update the spec to reflect this cleaner 'Reference' model.

Copy link

@ognis1205 ognis1205 left a comment

Choose a reason for hiding this comment

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

I focused my review primarily on the boundary between AICatalog and AICard and how their responsibilities relate. I hope the discussion helps clarify the intended role of the AICard in particular, since making that boundary explicit will strengthen the overall design.

```ini
; ============================================================================
; AI Card Specification (v1)
; A unified metadata format for AI Agents

Choose a reason for hiding this comment

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

As we discussed previously, I'm wondering if we should update the wording from "AI Agents" to "AI Protocol Servers."
What do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Please see the other reply below.


; --- Protocols ---
; Map of supported protocols (e.g. "a2a" => Service, "mcp" => Service)
services: { * ServiceType => BaseService },

Choose a reason for hiding this comment

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

I would like to add one point that has been on my mind regarding the services field and the conceptual model of the AICard.

The A2A specification and the current MCP card proposal/draft both describe their cards as a "business card for a AI protocol server", meaning a protocol-specific identity document.

But if an AICard contains multiple protocol entries under services (e.g., "a2a", "mcp", etc.), then the card no longer represents the business card of anything in particular, I guess. It effectively becomes a meta-card, a directory or an index that aggregates protocol-specific service descriptors.

This ambiguity is actually one of the reasons why I felt that what is proposed as the AICatalog in this PR is very close to what the AICard itself was implicitly trying to become. If a single card can represent multiple protocols, then in practice it behaves like a catalog rather than a protocol-scoped identity document. Even though, in this PR, each protocol is allowed to have only a single descriptor, the structural direction still points toward a catalog-like aggregation rather than a strictly scoped card.

To me, this raises an open design question:

  • Should an AICard remain a protocol-specific business card (1 protocol = 1 card)?
  • Or should the AICard explicitly become a meta-card, and the AICatalog contain protocol-specific cards?

I think clarifying this distinction explicitly would help solidify the semantics of both AICard and AICatalog.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

These are excellent architectural questions. Here is how I see the scope of AICard.
Regarding the "meta-card" concern: I view the AICard as an Identity Document for a logical entity, rather than just a config file for a protocol.

The Analogy: Think of a human Business Card. It lists a Phone Number, an Email Address, and a Slack Handle.

  • It supports "multiple protocols" (Voice, SMTP, Chat).

It does not become a "directory" or "phone book" because of this. It is still a single card describing one person.

The Benefit: By grouping A2A and MCP interfaces under one AICard, we allow Single Verification. A client verifies the Agent's DID once (checking the signature/compliance), and that trust automatically extends to all its interfaces (A2A and MCP). If we enforced "1 Protocol = 1 Card," we would fragment the identity, forcing clients to perform redundant trust checks for every single endpoint, which is brittle and computationally expensive.

Choose a reason for hiding this comment

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

Thanks @mindpower ! I completely agree with both points:

Regarding the "meta-card" concern: I view the AICard as an Identity Document for a logical entity, rather than just a config file for a protocol.
The Benefit: By grouping A2A and MCP interfaces under one AICard, we allow Single Verification.

I think the overall direction makes sense.

That said, I still feel we need to explore the question of what exactly this "logical entity" corresponds to in real deployments. For example, is an AIService always expected to expose exactly one MCP server or one A2A server? Or could a single AIService operate multiple MCP endpoints (e.g., one for tools and one for workflows) or multiple A2A servers (e.g., different domains or capabilities)?

If such patterns are valid, and I suspect they might be in production settings, then the mapping between the "single logical entity" and the underlying protocol servers becomes less clear. In that case, it would be important to clarify whether the AICard is representing:

  1. a single agent instance,
  2. a product-level service composed of multiple protocol servers, or
  3. a higher-level organizational identity grouping many protocol endpoints.

Here is a concrete example:

A company exposes an "AI Document Assistant" as one logical service. Internally, it runs

  • two MCP servers (one for document-editing tools, one for knowledge-base queries),
  • one A2A server for agent-to-agent orchestration,
    all representing the same "AIService" to clients.

This doesn't seem far-fetched, but it would complicate assumptions about "one logical entity -> one server per protocol." So I agree with the single-verification direction, but I also believe we need a bit more clarity on the expected granularity of an AIService and how it maps to real-world multi-endpoint setups.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Please see comments below (#4 (comment))

$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
agents: [* AICardEntry] ; The list of available agents

Choose a reason for hiding this comment

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

In earlier discussions, we noted that the term "agent" is specific to A2A, and does not cleanly apply to other protocols such as MCP, where the entity is a server, tool host, or protocol endpoint, but not necessarily an "agent."

Because the AICatalog is intended to be protocol-agnostic, naming the collection agents creates the wrong abstraction layer. This is arguably the place where a more neutral term like services fits better.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree that 'Agent' is too narrow (too A2A-specific), but I also find 'AI Protocol Server' a bit clunky. It risks confusion with physical hosting infrastructure. I also thought of 'entries' but that felt too generic.

Counter-Proposal: 'AI Service' + 'Interfaces'

I propose we use 'AI Service' as the standard term for the logical entity. It naturally covers both Agents (active) and Tools (passive) without implying infrastructure.

To avoid the naming collision you mentioned (having a services list inside an AI Service), I propose renaming the protocol map in the AICard from services to interfaces.

This aligns well with A2A's existing supportedInterfaces concept and creates a very clean hierarchy::

  • AICatalog: Lists available services (The Entities/AI Services).

  • AICard: Describes one AI Service (The Identity).

  • interfaces: Defines the A2A/MCP endpoints (The Connectivity).

I will update the README, Catalog, and Card specs to reflect this 'AI Service' terminology. Does this structure work for you?

Choose a reason for hiding this comment

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

The points you raised are absolutely correct.

I agree that AI Service and interfaces are much better aligned with a protocol-agnostic design. Thank you for the thoughtful suggestion. I fully support adopting this terminology!

Copy link

@ognis1205 ognis1205 Dec 7, 2025

Choose a reason for hiding this comment

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

I previously posted a short comment expressing support for AI Service and interfaces. After reflecting on it further, I'd like to expand that position with a few more detailed thoughts.

I'm thinking of using the following terminology:
- AICatalog -> services
- AICard -> interfaces (or possibly protocols, if that better captures the behavior/contract)

The goal is to keep the catalog focused on what is available, and the card focused on how to interact with it.
I'd be interested in your thoughts on whether "interfaces" or "protocols" is the better fit.

Here's why I believe interfaces for the AICard and services for the AICatalog map most cleanly to the conceptual model we're shaping.

### Why interfaces/protocols fits the AICard

The AICard is essentially the business card of a logical entity (the AIService). What it lists are the connectivity points:
- A2A endpoint
- MCP endpoint
- Endpoints for any other supported protocol

One additional point is the alignment with the A2A specification’s abstraction of AgentInterface
(https://a2a-protocol.org/latest/specification/#446-agentinterface).

In A2A, an interface represents a concrete connectivity surface for interacting with an agent, a strongly protocol-scoped endpoint definition. Structurally and semantically, this maps perfectly to what an AICard is supposed to describe:

These are all "surfaces through which the service can be interacted with," which aligns naturally with the term interfaces. So interfaces/protocls provides the right abstraction and keeps the meaning precise.

### Why services fits the AICatalog

There are two reasons this wording feels right:
- The catalog enumerates AIServices
- It aligns with established terminology

Framing the catalog as a directory of services fits naturally into that ecosystem.

I reviewed the PR again and realized that the terminology had already been updated to services and interfaces, sorry for missing that earlier. With that in mind, I'd like to propose considering protocols instead of interfaces.

The main reason is that, when looking at the abstraction defined in A2A (especially the AgentInterface in the spec), the term interface becomes a bit overloaded. What we are actually describing here feels closer to a communication or interaction protocol, rather than an API-shaped interface.

Would love to hear your thoughts on whether this framing makes sense.

Copy link
Collaborator Author

@mindpower mindpower Dec 10, 2025

Choose a reason for hiding this comment

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

Thanks @ognis1205 . That's excellent feedback, and I completely agree. I was worrying that interface could be still confusing but was not able to come with the best name. The term protocols is more accurate, least ambiguous choice. It aligns perfectly with the keys of the map ("a2a", "mcp") and avoids the collision with the existing A2A AgentInterface and the TypeScript keyword interface.

Here is the final, consistent hierarchy this change establishes (hopefully!)

  1. AICatalog lists AI Services (The Entities).
  2. AICard describes one AI Service (The Identity).
  3. protocols defines the specific communication layers (The Connectivity/Doors).

I will make this final renaming (interfaces -> protocols) across the CDDL, JSON, and TypeScript definitions if the above looks good.

Thanks for spotting that necessary clarification!

Choose a reason for hiding this comment

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

Thanks for adopting my suggestion about using the term protocols @mindpower ! I think this naming change moves the spec in a much clearer and more consistent direction. Overall, I believe the structure is evolving in a very good way.

At the same time, as I mentioned in

#4 (comment)

I still feel the logical unit represented by a single AICard (AI Service) remains a bit ambiguous. In particular, it may be worth discussing whether a single AI Service is expected to have multiple server infrastructures for the same protocol (e.g., multiple MCP or A2A endpoints under one card), and how the model should represent such cases.

Copy link
Collaborator Author

@mindpower mindpower Dec 12, 2025

Choose a reason for hiding this comment

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

Thanks @ognis1205. You are right that real-world production AI services could be composed of multiple distributed endpoints (e.g., separate tool vs. workflow endpoints, or regional shards).

To handle this robustly, we can update the protocols map so the protocols values are Arrays (Protocol[]) rather than single objects.

The schema definition would be: protocols: { * ProtocolType => [* AIProtocol] }

This allows a single AICard (the Logical Service Identity) to expose multiple physical interfaces for the same protocol. This structure maintains the integrity of the Single Verification principle (verifying the card verifies all endpoints - I think this is the key here) while accommodating complex composite infrastructure.

Copy link

@ognis1205 ognis1205 Dec 12, 2025

Choose a reason for hiding this comment

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

Thanks @mindpower ! This change makes sense to me.

Here's a possible naming refinement:

Since the value now represents the concrete information for each protocol, it might be clearer to rename:

  • AIProtocol -> ProtocolDetail

If so, the key would naturally become:

  • ProtocolType -> ProtocolName

This is just a naming suggestion; overall I agree with the direction of the change.

Copy link
Collaborator Author

@mindpower mindpower Dec 12, 2025

Choose a reason for hiding this comment

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

Thanks for the suggestion!

  1. ProtocolDetail: I like this rename for the object type. It clearly signals 'This object holds the details for one specific protocol binding.' I will adopt that.
  2. Naming the type field: I prefer to keep the field inside the object as type (instead of protocolName).
  • Reason: type is the standard convention for discriminators in JSON schemas. Using protocolName might get confused with the human-readable name field right next to it.
  • Illustration: Imagine the confusion if we had protocolName (the enum) next to name (the label) in the ProtocolDetail structure below
// Map
protocols: Record<ProtocolType, ProtocolDetail[]>

// Object
interface ProtocolDetail {
  type: string; // "a2a"
  name?: string; // "Primary Interface"
  protocolSpecific: ...
}
  1. Human-Readable Labels: You raised a good point about how these look to users. Now I wonder how developer set the name values inside the map protocolDetail for each of the protocol they define.
  • For example, For the ai card called "Finance Agent", should the name for A2A protocolDetail be called as : "Finance Agent A2A Protocol"? this sounds very robotic. Similarly for MCP, should its name be called "Finance Agent MCP Protocol", also too robotic

  • We have a semantic conflict between the Technical Architecture (Protocol) and the User Experience (Service/Interface). we (correctly) renamed the schema field to protocols to be technically precise, but that makes the English label feel awkward.

  • Suggestion: The Human-Readable Name (name) does not need to use the word Protocol or Service. It should describe the Function.

  • Example: "name": "Finance Agent Interface" or "name": "Finance Agent MCP workflow service"

  • We can leave the name field flexible for developers to describe the function of that interface (e.g., 'Primary', 'Backup', 'Tools') rather than just repeating the protocol name.

Choose a reason for hiding this comment

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

Thanks for the clarification, I'm aligned with this direction. Looks good to proceed with this change!

@mindpower mindpower changed the title feat: AI card and AI catalog draft proposal spec: AI card and AI catalog draft proposal Dec 5, 2025
@mindpower
Copy link
Collaborator Author

mindpower commented Dec 5, 2025

Just updated ai-card and ai-catalog specs and examples in this PR based on all the discussions so far:

Also created PR #8 for the README change to clarify all the terminology, scopes, and architecture models. And updated the description above for this PR.

@ognis1205
Copy link

Just updated ai-card and ai-catalog specs and examples in this PR based on all the discussions so far:

Also created PR #8 for the README change to clarify all the terminology, scopes, and architecture models. And updated the description above for this PR.

Thanks for pulling all of this together, appreciate the updates to both the specs and examples.
I'll review the README changes in PR #8 as well.

@mindpower mindpower requested a review from ognis1205 December 26, 2025 19:36
…in AI Card specification, updated comparison.md
/**
* Information about the host/publisher of the entire catalog.
*/
host: HostInfo;
Copy link

Choose a reason for hiding this comment

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

Can host be optional? I think many MCP use cases would not care to populate this, so not sure we want this to be a required field.

/**
* The full, absolute URL to this AI service's complete `ai-card.json` file.
*/
cardUrl: string;
Copy link

@tadasant tadasant Mar 5, 2026

Choose a reason for hiding this comment

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

Could we consider allowing pointing to an MCP Server Card (or A2A Agent Card) directly here?

This is probably tied to the uncertainty around "do we definitely want/need an envelope AI card format". If we were to adopt the shared extension approach @ToddSegal brought up in the first call, we wouldn't need the AI card intermediating here.

From my POV, for much of what MCP wants out of discovery:

  • It would be sufficient to have a .well-known location where ai-catalog.json can be found
  • We want a way to get from ai-catalog.json to an instance of an MCP Server Card
  • So if this cardUrl can be an MCP Server Card (perhaps with an additional protocol field of some sort), I think that's likely to work for us, and we accomplish our shared goal of having a unified discovery layer.

This current model requires an extra hop, to go ai-catalog.json -> AI Card -> MCP Server Card. And the current proposal for AI Card has shapes/duplication of values we intend to (additionally?) store in MCP Server Card, and I'm not sure we'd want to combine governance of those fields to be in the critical path of discovery.

Copy link

Choose a reason for hiding this comment

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

Pushing for alignment on all of AI Card's current scope will be a long road, I think. For example, I think tags, maturity, logoUrl, etc all require discussion that we've discussed at length in various ways within the MCP ecosystem. And if we strip out all the controversial things that require alignment, I worry we end up with a very thin AI Card layer (in which case why not sidestep all that coordination and just link to MCP Server Cards / A2A Agent Cards directly here)?

Choose a reason for hiding this comment

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

@tadasant I think the main value proposition is getting a consistent identity/versioning and trust story. I am not too worried about metadata stuff like tags/logoUrl. It is going to be painful if we can't align those security/identity issues between A2A and MCP.

Copy link

Choose a reason for hiding this comment

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

@darrelmiller in the first meeting (which I know you were not on), MCP's perspective (via David and Caitie) was that MCP is keen to keep things simple at this time. Identity (beyond web-based DNS) and trust will likely be important at some point, but MCP isn't ready to lock in assumptions about how it should work.

Where there is alignment is in first collaborating on the discovery story. If the group feels that the concerns are inherently coupled and we cannot proceed with a shared discovery approach without aligning on identity/trust, then I think we need to take a step back and revisit the scope first before workshopping the details.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@tadasant I agree with your approach for discovery. We do not want to force an extra hop, nor do we want to force MCP into an envelope that contains governance/trust fields you aren't ready for today. The ai-catalog should simply be a discovery list that can point directly to native MCP Server Cards. Please see my comments below for more details about that.

…update naming from PR Agent-Card#18

Co-authored-by: Luca Muscariello <lumuscar@cisco.com>
Copy link

@darrelmiller darrelmiller left a comment

Choose a reason for hiding this comment

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

I am approving this, not because I think everything is right, but I think we need a baseline in the main branch that we can debate and iterate over. Working in all these different PRs is making us go in circles.

Copy link

@muscariello muscariello left a comment

Choose a reason for hiding this comment

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

Approving to make progress based on all the comments.

"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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants