diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c28a1d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +node_modules/ +tsconfig.json +type/*.md +specification/json/ +package-lock.json +package.json \ No newline at end of file diff --git a/specification/cddl/ai-card.md b/specification/cddl/ai-card.md new file mode 100644 index 0000000..0f990dc --- /dev/null +++ b/specification/cddl/ai-card.md @@ -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 } +} + +``` \ No newline at end of file diff --git a/specification/cddl/ai-catalog.md b/specification/cddl/ai-catalog.md new file mode 100644 index 0000000..d575eec --- /dev/null +++ b/specification/cddl/ai-catalog.md @@ -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 + records: [* CatalogEntry] ; The list of available AI Catalog entries +} + +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 card (agent.json, mcp.json, ai-card.json, etc) + updatedAt: tdate ; Last modified time of the card (for crawler optimization) +} +``` \ No newline at end of file diff --git a/specification/cddl/comparison.md b/specification/cddl/comparison.md new file mode 100644 index 0000000..ad8314b --- /dev/null +++ b/specification/cddl/comparison.md @@ -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` | \ No newline at end of file diff --git a/specification/examples/ai-catalog.json b/specification/examples/ai-catalog.json new file mode 100644 index 0000000..efd1783 --- /dev/null +++ b/specification/examples/ai-catalog.json @@ -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", + "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" + } + ] +} \ No newline at end of file diff --git a/specification/examples/data-asset-card.json b/specification/examples/data-asset-card.json new file mode 100644 index 0000000..b5042de --- /dev/null +++ b/specification/examples/data-asset-card.json @@ -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" +} \ No newline at end of file diff --git a/specification/examples/live-service-card.json b/specification/examples/live-service-card.json new file mode 100644 index 0000000..c77471a --- /dev/null +++ b/specification/examples/live-service-card.json @@ -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" +} \ No newline at end of file