DMC-12 dmc-12 / dmc-12 guide
UCP Merchant Binding · DMC-12 v1.0

Integrate an agent with DMC-12

This is the how-to companion to the dmc-12.ai overview and the machine-readable spec at dmc12.ai. It walks a partner agent — a buyer agent, a marketplace, a broker, or an OEM agent — from discovery to a completed deal hand-off against a deployment of the UCP Merchant Binding. This guide is static documentation: worked examples use the spec's fictional merchant (Aurora Motors Group), and real endpoints always come from a merchant's published /.well-known/ucp.

The binding at a glance DMC-12 v1.0.0 · 15 canonical tools (a deployment declares the subset it implements on its manifest — every quote is at asking price unless negotiation is declared). Six scopes: inventory:read, pricing:read, quote:write, reservation:write, quote:negotiate, deal:handoff.

1. The lifecycle

Every transaction-class flow is the same four steps. Reads (inventory, pricing disclosure) can happen at any point.

01 · read
search
Find a VIN with search_inventory / list_inventory, or look one up directly.
02 · quote:write
request_quote
Pin a 30-minute price at the listed asking price. Returns a quote_id.
03 · reservation:write
create_reservation
Convert the open quote into a 30-minute soft hold on the VIN. Non-binding.
04 · deal:handoff
initiate_deal_handoff
Hand the held VIN + consented customer contact to a live sales manager.

Quotes and reservations both carry a 30-minute TTL, so an agent should run the quote → reserve → hand-off tail back-to-back once the buyer has committed. The deep-dive pages cover each step: InventoryQuotesReservationsDeal hand-off.

2. Pick a rail: A2A or MCP

The same DMC-12 capabilities are served over two wires from one Cloud Run service. Choose by who your caller is.

Base URL Every path on this page is relative to a deployment base — the worked examples use the fictional MCP_BASE = https://mcp.auroramotors.example. A2A calls go to MCP_BASE/a2a/, MCP to MCP_BASE/mcp/, and the well-knowns to MCP_BASE/.well-known/…. Always discover the real endpoint from the merchant's published /.well-known/ucp — never hard-code it.
RailTransportWhoSurface
/a2a/ JSON-RPC 2.0 Named partner agents (machine-to-machine) Full write surface — read + quote + reservation + deal hand-off, scope-gated.
/mcp/ Streamable HTTP LLM clients (Claude, ChatGPT, Gemini) and your own MCP agent Public callers are read-only; partner-audience tokens get the write surface.

This guide uses the A2A rail for every worked example — it is the path partners integrate against. The wire envelope is a standard JSON-RPC tools/call:

POST /a2a/   Authorization: Bearer <token>

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_inventory",
    "arguments": { "query": "2024 Outback AWD under 35k", "limit": 5 }
  }
}

And tools/list (no params) returns the deployment's scope-filtered tool catalog. Every response is wrapped in a standard envelope:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "data": { /* the tool payload */ },
    "_metadata": {
      "trace_id": "trc_…",   // log this — it correlates to the audit row
      "tool": "search_inventory",
      "agent_id": "…@clients",
      "protocol": "a2a",
      "timestamp": "2026-05-27T18:04:11+00:00"
    }
  }
}
Data, not instructions Every payload is nested under data with a _metadata sidecar so a downstream LLM treats it as content, never as instructions. Always log _metadata.trace_id — it is the only way the merchant can correlate a complaint with its audit log.

3. Discovery — check the well-knowns

Every claim a deployment makes is backed by an unauthenticated, cacheable document at a canonical URL. Fetch these first; they are the source of truth for tool count, capability versions, scopes, and the auth server.

Agent Card A2A v1.0 — signed JWS; tools, scopes, policies
/.well-known/agent-card.json
MCP server card SEP-1960 — endpoints, transports, auth, scope split
/.well-known/mcp
UCP manifest UCP v1 — merchant, ai.dmc12.automotive 1.0.0, freshness
/.well-known/ucp
Protected-resource metadata RFC 9728 — scopes_supported, authorization server
/.well-known/oauth-protected-resource
Agent Card JWKS Public key to verify the Agent Card signature
/.well-known/jwks.json

What each one returns, in brief:

Well-knownReturnsShape (abridged)
agent-card.jsonA2A v1.0 Agent Card — display name, protocols, policies, the scope-filtered tools array, and authentication (issuer / audience / scopes). JWS-signed when signing is configured.{ schema_version, name, description, protocols:["a2a"], endpoints, tools:[…], authentication:{ type:"oauth2_client_credentials", issuer, audience, scopes:[…] } }
mcpSEP-1960 MCP Server Card — endpoint, transports, auth methods (OAuth + legacy shared-key), and the public/partner scope split.{ mcpVersion:"2025-11-25", name, endpoints:{ http }, transports:["streamable-http"], auth:{ sharedKey, oauth2 }, scopes:{ public:[…], partner:[…] } }
ucpUCP v1 manifest — merchant, capability list (ai.dmc12.automotive.* with versions + schema URLs), policies, and inventory freshness SLA.{ ucp:{ version, services, capabilities:[{ name, version, spec, schema }] }, merchant:{…}, policies:{…} }
oauth-protected-resourceRFC 9728 metadata — the resource identifier (must match token aud), scopes_supported, and the authorization server.{ resource, authorization_servers:[…], scopes_supported:[…], bearer_methods_supported:["header"] }
jwks.jsonThe public JWK set used to verify the Agent Card's JWS signature (not the IdP's JWKS).{ keys:[{ kty, kid, use:"sig", alg:"RS256", n, e }] }

4. Auth, in one paragraph

Partners authenticate with OAuth 2.1 client-credentials against the deployment's authorization server — its issuer and audience come from the deployment's RFC 9728 protected-resource metadata, never from documentation. Mint an access token, cache it for most of its TTL, and send it as a Bearer token on every /a2a/ call. Your effective permissions are the intersection of the scopes the deployment seeded for your agent and the scopes in your token. Onboarding is deployment-specific — see Deployment onboarding for the pattern (credential bundle, mint command, rate limits, scope matrix).

5. Data formats

Every DMC-12 field follows one of these conventions. The per-capability pages (Inventory, Quotes, Reservations, Deal hand-off) link back here rather than restating them. All enum values are lower-case and case-sensitiveavailable, not Available.

FormatRuleExample
VIN17 chars, ^[A-HJ-NPR-Z0-9]{17}$ — upper-case; letters I, O, Q are excluded (they look like 1 / 0).4S4BTGUD8R3201234
Money{ "amount": string, "currency": string } — as of v1.0, amount is an exact-decimal string with exactly two decimal places (^[0-9]+\.[0-9]{2}$), never a binary float; currency is ISO-4217 ^[A-Z]{3}$. Catalog prices (asking_price, msrp) stay JSON numbers.{ "amount": "445.00", "currency": "USD" }
TimestampISO-8601, UTC — either a trailing Z or +00:00. Always UTC, never a local offset.2026-05-27T18:04:11+00:00
PhoneE.164 — +, country code, national number, no spaces or punctuation (deal hand-off only).+18015551234
EmailStandard RFC-5322 address (deal hand-off only).buyer@example.com
EnumsLower-case, case-sensitive — status values, kind, payee, sort fields, error codes' lower portions. Send and compare exactly.available · vehicle_price · government
Opaque tokensquote_id, reservation_token, handoff_token are opaque strings — treat as black boxes; never parse or construct them.qte_8f1c… · rsv_… · hnd_…
Negotiation is a declarable subset The DMC-12 spec defines four negotiation tools (submit_offer, submit_counter_offer, accept_offer, reject_offer, scope quote:negotiate) that bring the canonical surface to 15. A deployment that does not declare them serves every quote at the listed asking price; check the merchant's manifest and conformance claim for the declared subset.
copied