DMC-12 Mark Miller Subaru / dmc-12 guide
endpoint live · DMC-12 v0.6 · 11 tools

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 — CarEdge, Cox / Dealer.com, a broker, or an OEM agent — from discovery to a completed deal hand-off against the live Mark Miller Subaru endpoint.

What's live right now DMC-12 v0.6.0 · 11 tools on MM's deployment (negotiation is defined in the spec but off here — every quote is at asking price). Five scopes: inventory:read, quote:write, reservation:write, deal:handoff, pricing:read.

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 the live MM service base MCP_BASE = https://mm-inventory-mcp-572952183767.us-central1.run.app. A2A calls go to MCP_BASE/a2a/, MCP to MCP_BASE/mcp/, and the well-knowns to MCP_BASE/.well-known/…. (Prefer discovering the endpoint from the dealer's published /.well-known/ucp rather than hard-coding 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 live, 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 MM can correlate a complaint with the 90-day audit log.

3. Discovery — check the well-knowns

Every claim about this deployment 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 v0.6, 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 Auth0 tenant mmbrain-prod.us.auth0.com, audience mm-inventory-mcp. Mint an RS256 access token (1-hour TTL), cache it for ~55 minutes, and send it as a Bearer token on every /a2a/ call. Your effective permissions are the intersection of the scopes seeded on your agent row and the scopes in your token. Onboarding is an email to Ben — see Partner onboarding for the full credential bundle, the mint command, rate limits, and the 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": number, "currency": string }amount is a decimal in major units (dollars, 2-dp cents), currency is ISO-4217 ^[A-Z]{3}$. Never a bare number.{ "amount": 445.0, "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 off at MM 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. They are not registered on this deployment and the quote:negotiate scope is not issued. Every quote is at the listed asking price. Other dealers forking the open spec can enable them.
copied