mcp.astrasync.ai/mcp
One MCP endpoint that lets every platform agent (Claude, ChatGPT, Gemini, Cursor) transact with every AstraSync-registered merchant. The bridge handles protocol normalisation (ACP / AP2 / UCP / x402), forwards the inbound agent's AstraSync identity to the merchant's policy engine, and surfaces structured denials when PDLSS boundaries don't allow a request.
Bridge is transport, merchant is policy
The bridge does not enforce its own trust floor on transactional tools. Every call triggers verify-access against the merchant's endpoint with the inbound agent's credentials forwarded — the merchant decides what to accept. Agents the merchant would happily transact with directly are never blocked at the bridge layer.
No direct merchant HTTP checkout, no CSRF handshake. The bridge is a discovery + identity-handshake layer: start_checkout and confirm_purchase call AstraSync's own verify-access and mint a scoped session — they do not POST to your merchant checkout endpoint. So merchants do not need to expose a CSRF token to the bridge or special-case CSRF for bridge-mediated flows; CSRF protection on your own checkout routes is unaffected. (Direct merchant checkout forwarding is a separate, not-yet-shipped capability — when it lands, any CSRF handshake will be handled by the bridge, never by the agent.)
Tool surface
Nine tools on one MCP server: identity registration (register_agent, request_registration, poll_registration), doc search (search_docs), verify-access (verify_agent), and commerce (list_merchants, discover_catalog, start_checkout, confirm_purchase). The four commerce tools are documented below; identity + verify tools follow standard MCP conventions — see /docs/agent-access for those.
register_agent
Thin wrapper over the verification-gateway SDK's AstraSync.register(). Pass any of the SDK's auth modes — { apiKey } (owner step-up email), { email, password } (synchronous active), { apiKey, privateKey }(synchronous signed) — plus the standard RegisterOptions (name, pdlss, model, framework, protocols). Returns SDK's RegisterResult verbatim: { status: "active", agent } or { status: "pending_approval", requestId, pollUrl }.
No-creds calls return a structured guidance envelope (registrationUrl, steps[]) mirroring the same shape the SDK's verify path emits for unauthenticated callers.
poll_registration
Thin wrapper over AstraSync.pollRegistration(requestId). Returns { state: "pending" | "approved" | "denied" | "expired", astraId?, agent?, reason? }. Use the requestId returned by register_agent. The skill defines two polling patterns: conversational agents poll once on user-confirmation; autonomous agents poll every 5–10s with a 5-minute timeout.
list_merchants
Discovery surface. Returns AstraSync-registered merchants that opted into platform-agent discoverability. No authentication required.
{
"merchants": [
{
"astraeId": "ASTRAE-shop42",
"name": "ExampleShop",
"surface": "website",
"jurisdictions": ["AU", "NZ"],
"supportedProtocols": ["acp", "ap2"],
"skillUrl": "https://shop.example/mcp/skill.md",
"catalogUrl": "https://shop.example/api/catalog"
}
]
}Finding the merchant's MCP endpoint: the response does not surface mcpUrlas a first-class field today. Agents needing to reach the merchant's MCP server should fetch the skillUrl above and read the endpoints.mcp field from the returned skill document. A first-class mcpUrl on the merchant entry is on the roadmap; in the interim, fetch-the-skill is the supported path.
discover_catalog
Fetches the merchant's registered catalogUrl (not /.well-known/*, which gateways skip-path and always return the public view). Forwards inbound _meta.astrasync credentials so tiered catalogs serve the correct tier. Anonymous responses are cached; verified callers always bypass cache.
Canonical catalog shape
{
"merchantAstraeId": "ASTRAE-shop42",
"name": "ExampleShop",
"supportedProtocols": ["acp", "ap2"],
"skus": [
{
"id": "sku-001",
"title": "Widget",
"description": "Best-in-class widget",
"price": { "amount": "25.00", "currency": "USD" },
"availability": "in_stock",
"protocol": "acp",
"raw": { /* merchant's native shape, untouched */ }
}
],
"fetchedAt": "2026-05-15T10:00:00.000Z",
"cached": false,
"tier": "verified"
}The rawfield on each SKU is the merchant's native protocol shape, preserved verbatim. Drop down to it when the canonical fields elide something protocol-specific.
start_checkout
Initiates a checkout against a merchant. Calls verify-access with purpose: "shopping.purchase"against the merchant's endpoint. Returns a sessionId + intent mandate on grant; a structured denial otherwise.
{
"success": true,
"sessionId": "cks_…",
"merchantAstraeId": "ASTRAE-shop42",
"intentMandate": {
"agentId": "ASTRA-XYZ…",
"merchant": "ASTRAE-shop42",
"items": [{ "sku": "sku-001", "quantity": 2 }],
"totalValue": 50,
"currency": "USD",
"issuedAt": "...",
"expiresAt": "..."
},
"requiredScopes": ["shopping.purchase"],
"tokenLifetime": 1800000,
"accessLevel": "standard"
}confirm_purchase
Completes a session. Re-validates trust + scope against the merchant via verify-access with purpose: "shopping.purchase" (same canonical purpose token as start_checkout— checkout-create and checkout-confirm are two phases of one shopping intent), plus the commerce-pipeline's payment-mandate checks server-side.
{
"success": true,
"verificationResult": {
"identityVerified": true,
"policyAllowed": true,
"accessLevel": "standard",
"recommendation": "grant",
"correlationId": "cor_…"
},
"txHash": "astrasync-placeholder:cor_…",
"txHashKind": "astrasync-correlation-placeholder",
"receiptUrl": "https://astrasync.ai/receipts/cor_…",
"merchantAstraeId": "ASTRAE-shop42",
"items": [...],
"totalValue": 50,
"currency": "USD"
}txHash is a placeholder until v2. The txHashKind: "astrasync-correlation-placeholder" discriminator tells you not to verify it on a public blockchain. Use receiptUrl for confirmation today. Blockchain commit lands in a separate v2 PR.
Purpose tokens the bridge emits
When the bridge calls verify-access on your behalf (Path B), it passes a canonical PDLSS purpose token. The vocabulary stays disjoint from transport tokens (no mcp_invoke) and reuses the existing PDLSS shopping / identity / discovery namespaces — so your endpoint's PDLSS scope allowlist doesn't have to grow a new sub-namespace just to support bridge traffic.
When declaring an agent's allowedActions or scope.resources, MCP traffic uses <method>:<toolName> action encoding and mcp:tool/<name> resource encoding — see Declaring allowedActions and scope.resources for MCP traffic on the agent-access docs for the worked example.
| Bridge tool | Purpose | Action | When fired |
|---|---|---|---|
| discover_catalog | shopping | shopping.search | Catalog browse, merchant filtering, SKU search. |
| start_checkout | shopping | shopping.purchase | Cart → checkout transition (intent mandate issued). |
| confirm_purchase | shopping | shopping.purchase | Final purchase confirmation (same purpose — checkout-create and checkout-confirm are two phases of one shopping intent). |
| verify_agent | identity | caller-supplied | Verify-access check (allowed/denied + trust score). Pass an optional purpose (bare category; defaults to identity) and a required dotted-verb action. |
| list_merchants | discovery | discovery.read | Bridge-discoverable merchant listing. |
| search_docs | discovery | discovery.read | Docs / FAQ search. |
Path B merchants: route allowedPurposes take the bare category nouns; agents enumerate the dotted actions in their allowedActions. If an agent declares shopping.purchase but not shopping.search, it gets a successful start_checkout but a denied discover_catalog — declare the granularity that fits.
| Purpose category (bare noun) | Actions (dotted verbs) | Covers |
|---|---|---|
| shopping | shopping.search, shopping.purchase | Catalog browse/search; checkout create + confirm (one purchase intent) |
| identity | identity.verify, identity.lookup | Trust/score verification; identity resolution |
| discovery | discovery.read | Merchant listing, docs search |
| data | data.read, data.write, data.delete | Generic API access — the fallback pair for unmapped routes (data.execute is reserved) |
| custom (e.g. trading, accounting) | trading.execute, accounting.read, … | Any bare noun + dotted verbs under it — first-class, not second-class |
allowedActionsis required (min 1) — the evaluator is fail-closed on actions.categoriesis derived from the dotted-action prefixes; supply extras only to widen.- MCP tool names (
list_products) are valid enumerated actions; they derive no category, so add an explicit one if all your actions are dotless. - Transport verbs (GET/POST) never travel as actions — HTTP senders map them through the pinned table (GET → data.read, POST/PUT/PATCH → data.write, DELETE → data.delete).
- Retired gen-1 tokens (
read_data,write_data,execute_action) are rejected at registration — use thedatacategory.
Structured denial shape
When start_checkout or confirm_purchasedenies a request, the response uses the same envelope as the platform's verify-access route (so a single parser handles bridge + direct verify-access responses interchangeably).
{
"success": true,
"access": {
"allowed": false,
"reason": "Caller did not present an AstraSync agent identity",
"failures": [
{
"code": "agent_missing",
"message": "No _meta.astrasync.agentId provided.",
"dimension": "agent.missing"
}
],
"requiresStepUp": false,
"requiresApproval": false
},
"recommendation": "deny",
"recommendationReasons": ["..."],
"correlationId": "cor_..."
}The failures[].dimension field is the literal string to switch on for error handlers. Vocabulary below.
Deny propagation today:when a Path B merchant's PDLSS denies a bridge request, the bridge propagates the merchant's deny verbatim as a JSON-RPC error. There is no anonymous step-down behaviour today — agents whose PDLSS scope conflicts with merchant policy see the merchant's deny shape directly. Anonymous step-down (bridge re-fetching the restricted-tier catalog and returning it with a tier: "stepped_down" indicator) is on the roadmap as a later-round bridge enhancement.
failures[].dimension vocabulary
| dimension | Example reason |
|---|---|
| agent.missing | No _meta.astrasync provided (transactional tools only) |
| agent.lookup | agentId provided but not registered with AstraSync |
| agent.status | Agent deactivated or revoked |
| pdlss.purpose | Merchant policy doesn't allow commerce.checkout.create for this agent |
| pdlss.limits | Cart total exceeds the agent's autonomous threshold |
| pdlss.scope | Merchant URL outside the agent's allowed scope list |
| counterparty.allowlist | Merchant requires allowlist + caller not on it |
| counterparty.trust | Caller's trust score below merchant's floor |
| attestation.type | Payment-mandate type not accepted by merchant |
| endpoint.deactivated | Merchant endpoint deactivated |
| upstream.validation_failed | Platform reached but rejected the request as invalid — fix the input, then retry |
| upstream.auth_failed | Platform rejected the bridge credentials (authentication) |
| upstream.access_denied | Platform reached but denied access for this call (authorization) |
| upstream.unexpected_status | Platform returned an unexpected 4xx — inspect the body before retrying |
| system.platform_unreachable | MCP bridge couldn't reach the AstraSync platform (5xx/network/DNS/timeout — retry, and check ASTRASYNC_API_URL uses the canonical apex form https://astrasync.ai/api) |
Discovery + skill
Discovery doc: https://mcp.astrasync.ai/.well-known/mcp.json
Anthropic Skill: https://mcp.astrasync.ai/skill.md
The skill markdown covers two tracks: tool-capable agents (the default modern chat surface) call register_agent on the MCP server directly, with conversational or autonomous polling patterns; tool-less chat agents are advised to switch to a client with tool access. All 10 tools — identity registration, agent lookup, doc search, verify-access, and commerce — live on the single /mcp surface.
Opt your endpoint into the bridge
In your AstraSync dashboard under Endpoints → [your endpoint] → Platform-Agent Bridge, set Discoverability: Discoverable and register a Catalog URL (gateway-evaluated path for tiered content; not /.well-known/*). Optionally add a Skill URL pointing at your own merchant-specific MCP server or Anthropic Skill.
