Skip to main content

MCP Integration Guide

This guide covers both directions of ACP MCP integration: external MCP clients calling the unified Thyris MCP service, and ACP Engine registering downstream customer MCP servers. It is intended for application teams, agent-platform teams, and owners of tool services such as commerce, CRM, loyalty, support, or custom business systems.

Unified MCP Service​

ACP uses one mcp-service for two related responsibilities:

  • Public MCP JSON-RPC at POST / and POST /mcp.
  • Internal MCP server registration, discovery, routing, proxying, and execution behind ACP Engine routes under /api/v1/runtime/mcp/*.

The former standalone acp-mcp service has been merged into mcp-service. External MCP traffic can still use a dedicated hostname and ingress such as https://mcp.example.com/mcp, but it reaches the same service that owns the internal MCP domain.

Public JSON-RPC supports initialize, tools/list, and tools/call. Use a merchant API key for built-in Catalog tools:

Authorization: Bearer {{merchant_api_key}}

x-api-key: {{merchant_api_key}}, X-Catalog-API-Key: {{merchant_api_key}}, and the Merchant Services-compatible X-MCP-API-Key: {{merchant_api_key}} are also accepted. Auth validates a merchant key before initialize, tools/list, and tools/call. Invalid, expired, or revoked keys return HTTP 401 with JSON-RPC error code -32000.

For merchant-key connections, initialize reports the Merchant Services-compatible server identity and tools/list exposes only merchant-commerce tools. The current reference contract is catalog_search, catalog_get_product, catalog_get_product_details, cart_create, cart_get, cart_add_item, cart_update_item, cart_remove_item, cart_add_bundle, cart_update_bundle, cart_remove_bundle, cart_archive, cart_clear, cart_close, checkout_prepare, checkout_get, and checkout_cancel; legacy Catalog tool aliases remain available during migration. Direct attempts to call realm/ACP tools with a merchant key return Tool not found.

For realm-bound Engine tools, prefer an Engine Identities API key:

X-ACP-Realm-ID: {{realm_id}}
Authorization: Bearer {{engine_identity_api_key}}

x-api-key: {{engine_identity_api_key}} is equivalent. Separate X-ACP-Access-Key and X-ACP-Secret-Key headers remain available only for legacy service identities.

If the deployment configures MCP_SHARED_SECRET, send that transport secret as X-ACP-API-Key and continue sending the merchant key through Authorization, x-api-key, or X-Catalog-API-Key. The shared ingress secret does not replace the merchant key or realm-bound service identity required by the selected tool.

MCP Integration Model​

ACP Engine connects to customer MCP servers through registered server definitions. Once registered, a server can be:

  • Tested for connectivity.
  • Listed for available tools and schemas during registration and after later tool changes.
  • Attached to agents.
  • Used by routing rules.
  • Called directly through the proxy endpoint.
  • Used by runtime chat and flow execution.

Customer frontends should call ACP Engine, not downstream MCP servers directly. Compatible MCP hosts can call the public mcp-service endpoint. Both paths keep routing, permissions, usage reporting, and observability centralized.

Built-in ACP MCP Tools​

Call tools/list after initialization to read the active schemas. The unified service currently exposes these Engine tools:

ToolPurpose
acp_api_requestCall an allowed public /api/v1 Engine route. Absolute URLs and cross-realm parameters are rejected.
acp_mcp_authenticateValidate a realm-bound service identity and return token metadata.
acp_auth_registerRequest registration when registration is enabled in the target deployment.
acp_runtime_ai_chatSend a request to runtime AI chat.
acp_runtime_executeRun the versioned durable execution contract synchronously.
acp_runtime_create_executionQueue a durable execution.
acp_runtime_list_executions, acp_runtime_execution_getList executions or inspect one execution and its normalized result.
acp_runtime_execution_events, acp_runtime_execution_actionsRead progress events or replay actions without side effects.
acp_runtime_execution_cancel, acp_runtime_execution_retry, acp_runtime_execution_resumeControl eligible durable executions.
acp_runtime_approval_approve, acp_runtime_approval_denyDecide pending write-tool approvals.
acp_runtime_list_flowsList flows available to the authenticated realm.
acp_runtime_list_providersList customer-managed AI providers for the realm.
acp_runtime_mcp_execute_toolExecute an approved routed downstream MCP tool.
acp_usage_summaryRead realm usage summary data.
acp_configuration_schema, acp_configuration_exportRead the portable configuration contract or export a secret-free realm bundle.
acp_configuration_plan, acp_configuration_applyValidate/diff or transactionally apply reviewed configuration.
acp_data_record_event, acp_data_record_eventsRecord anonymous events after server-side PII removal and pseudonymization.
acp_data_query, acp_data_summaryQuery realm-scoped anonymous event data and aggregations.

The stateful Merchant Commerce reference contract is:

ToolSide effectPurpose
catalog_searchNoSearch products in stores accessible to the merchant key.
catalog_get_productNoRead one authorized product.
catalog_get_product_detailsNoRead complete product details and public merchant profile by ten-digit catalogId or another supported identifier, without a Flow.
cart_createYesCreate an open cart without preparing payment.
cart_getNoRead an authorized cart and its items.
cart_add_item, cart_update_item, cart_remove_itemYesMutate an open cart with an idempotency key.
cart_add_bundle, cart_update_bundle, cart_remove_bundleYesMutate several cart lines atomically with an idempotency key.
cart_archiveYesPermanently archive an eligible cart.
cart_clear, cart_closeYesClear or close an eligible cart with an idempotency key.
checkout_prepareYesFreeze the summary and return an opaque awaiting-payment handoff.
checkout_getNoRead an authorized prepared checkout.
checkout_cancelYesCancel a prepared checkout and reopen its cart.

Legacy catalog_list_stores, catalog_search_products, catalog_upsert_product, catalog_delete_product, catalog_create_cart, catalog_mutate_cart_items, catalog_archive_cart, catalog_clear_cart, and catalog_complete_order aliases remain available for migration compatibility. New journeys should use the stateful contract above. All write operations require a stable idempotency key. Procurement and payment-provider execution tools are not part of ACP's built-in merchant profile.

Published Flow Tools​

Realm-authenticated clients also receive one dynamic tool for each active published flow. Tool names are deterministic and versioned:

acp_flow_<normalized_flow_name>_v<version>

For example, version 3 of Product Discovery is exposed as acp_flow_product_discovery_v3. The tool's business properties and required fields come from the flow input schema; the output schema comes from the flow output schema. ACP adds optional agentId, sessionId, and idempotencyKey execution controls.

Calling a published-flow tool executes the same authenticated runtime path as REST orchestration. Agent profile resolution applies when agentId is omitted, and policy checks, approvals, retry limits, usage, and trace records are not bypassed. Run tools/list again after a flow is activated, deactivated, renamed, or versioned because the available tool name or schema may change.

Catalog tools use the merchant API key's merchant, store, merchant_network, or custom access scope. Merchant scope covers the current merchant's stores, store scope covers one store, merchant-network scope covers the merchant and direct sub-merchants, and custom scope covers only selected stores. Catalog rejects every store or merchant outside the introspected scope. Public tool names, descriptions, input schemas, validation errors, success results, and MCP error envelopes match Merchant Services Catalog MCP, so existing Catalog tool calls do not need an argument rewrite. Procurement tools are intentionally not part of ACP.

Call a Catalog Tool​

POST /mcp
Content-Type: application/json
Authorization: Bearer {{merchant_api_key}}

{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "catalog_search",
"arguments": {
"query": "black shoes",
"limit": 10,
"includeDraft": false
}
}
}

The result contains MCP text content. Catalog tools return the same serialized business result shape as Merchant Services:

{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "{\"success\":true,\"query\":\"black shoes\",\"count\":0,\"products\":[]}"
}
]
}
}

MCP Protocol Contract​

Customer MCP servers should expose a JSON-RPC 2.0 API that supports the standard MCP lifecycle:

  • initialize: confirms protocol support and server capabilities.
  • tools/list: returns available tool names, descriptions, and input schemas.
  • tools/call: executes a named tool with JSON arguments.

ACP Engine uses these methods for discovery and execution. Keep tool names and schemas stable across releases.

Registering an MCP Server​

POST /api/v1/runtime/mcp/servers
Content-Type: application/json
Authorization: Bearer {{token}}

{
"name": "Commerce MCP",
"url": "https://mcp.customer.example.com/mcp",
"type": "ecommerce",
"description": "Commerce tools for search, cart, checkout, and order operations.",
"api_key": "replace-with-mcp-api-key",
"is_active": true,
"auto_discover": true,
"capabilities": ["search", "cart", "checkout", "orders"]
}

Use clear names and capability tags. These values help integration teams understand routing behavior and operational ownership.

By default, ACP Engine calls the downstream server's tools/list method during registration and stores the discovered tool names, descriptions, input schemas, and metadata in its MCP tool registry. The response includes a discovery object with the discovery status and tool count. Send "auto_discover": false only when the server is not reachable yet or when you intentionally want to register connection metadata before discovering tools.

MCP Authentication​

MCP servers may require an API key header:

X-MCP-API-Key: replace-with-mcp-api-key

When an MCP server is registered in ACP Engine, the key is treated as a server-side integration secret. Browser clients should never receive or send MCP API keys directly.

ACP Engine sends a registered MCP credential as both Authorization: Bearer <key> and X-MCP-API-Key: <key>. This is compatible with Thyris Merchant MCP, which accepts the bearer header as the preferred form and keeps the MCP-specific header for compatibility.

Merchant Services Catalog Migration​

The built-in ACP Catalog tools do not require a downstream Merchant MCP registration. Existing Merchant Services integrations may continue using the legacy Catalog aliases while they move to the stateful Merchant Commerce contract. Change storeId only when migration did not preserve store UUIDs. Product galleries continue to use optional imageUrls, ordered with the primary image first and limited to 20 URLs.

Merchant MCP write tools can produce outbound webhooks. This is a business side effect of the downstream tool, not an ACP webhook:

Merchant MCP ToolOutbound EventsCurrent Event Source
catalog_upsert_productproduct.created or product.updatedmcp
catalog_delete_productproduct.deletedmcp
catalog_create_cartcart.created, and checkout.created when checkout is prepared immediatelymcp
catalog_mutate_cart_items, cart_add_item, cart_update_item, cart_remove_itemcart.item.* plus cart.updatedmcp
cart_add_bundle, cart_update_bundle, cart_remove_bundlecart.bundle.* plus cart.updatedmcp
catalog_archive_cart, cart_archivecart.archivedmcp
catalog_clear_cartcart.clearedmcp
catalog_complete_orderorder.created, order.completedmcp

Delivery occurs only when the merchant has configured an outbound destination subscribed to the event. The source label describes the downstream engine path and does not suppress delivery.

Testing Connectivity​

POST /api/v1/runtime/mcp/servers/{{mcp_server_id}}/test
Content-Type: application/json
Authorization: Bearer {{token}}

{
"timeout_ms": 5000,
"validate_tools": true
}

Run this test after initial registration, after credential rotation, and before production cutover.

Tool Listing​

POST /api/v1/runtime/mcp/servers/{{mcp_server_id}}/discover
Content-Type: application/json
Authorization: Bearer {{token}}

{
"refresh_cache": true,
"include_schemas": true
}

Tool listing is used to read the server's available tools and schemas. Run this endpoint whenever the customer MCP server adds, removes, or changes tools after the initial setup.

Tool listing refreshes the approved tool definitions and helps prevent stale tools from being used.

Listing Tools​

GET /api/v1/runtime/mcp/servers/{{mcp_server_id}}/tools
Authorization: Bearer {{token}}

Use this endpoint to confirm tool names before creating routing rules. ACP Engine returns the known approved tool list for the server.

Downstream MCP JSON-RPC Examples​

These examples describe the contract ACP uses when calling a registered downstream MCP server. They are distinct from the public unified MCP endpoint described earlier. In customer applications, call ACP Engine or the public MCP service rather than calling downstream servers from the browser.

Initialize​

{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {}
},
"clientInfo": {
"name": "acp-engine",
"version": "1.0.0"
}
}
}

List Tools​

{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}

Call Tool​

{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search_products",
"arguments": {
"query": "black shoes",
"limit": 25
}
}
}

Expected result format:

{
"jsonrpc": "2.0",
"id": 3,
"result": {
"toolResult": {
"content": [
{
"type": "text",
"text": "{\"products\":[],\"count\":0}"
}
],
"isError": false
}
}
}

The text payload can contain serialized JSON. ACP Engine can normalize the tool response before returning data to the frontend.

Direct Tool Proxy​

Direct proxy execution is useful for testing a specific MCP server and tool:

POST /api/v1/runtime/mcp/proxy
Content-Type: application/json
Authorization: Bearer {{token}}

{
"mcp_server_id": "{{mcp_server_id}}",
"tool_name": "search_products",
"session_id": "{{session_id}}",
"arguments": {
"query": "black shoes",
"limit": 25,
"filters": {
"max_price": 150
}
}
}

Use direct proxy calls for MCP validation. Use routed tool execution for normal customer runtime behavior.

Routing Rules​

Routing rules tell ACP Engine how to select an MCP server for a tool request:

POST /api/v1/runtime/mcp/routing/rules
Content-Type: application/json
Authorization: Bearer {{token}}

{
"name": "Commerce Search Routing",
"realm_id": "{{realm_id}}",
"flow_id": "{{flow_id}}",
"priority": 100,
"enabled": true,
"match": {
"intents": ["product_search", "recommendation"],
"tool_names": ["search_products", "list_products"],
"keywords": ["find", "search", "show"],
"capability_tags": ["commerce", "products"]
},
"target": {
"strategy": "first_healthy",
"mcp_server_ids": ["{{mcp_server_id}}"],
"fallback_provider_id": "{{provider_id}}"
},
"policies": {
"timeout_ms": 8000,
"retry_count": 1,
"cache_ttl_seconds": 60
}
}

Route Evaluation​

Before executing a tool, you can evaluate the selected route:

POST /api/v1/runtime/mcp/routing/preview
Content-Type: application/json
Authorization: Bearer {{token}}

{
"realm_id": "{{realm_id}}",
"agent_id": "{{agent_id}}",
"flow_id": "{{flow_id}}",
"session_id": "{{session_id}}",
"intent": "product_search",
"tool_name": "search_products",
"messages": [
{
"role": "user",
"content": "Find black running shoes under 150 USD."
}
],
"context": {
"locale": "en-US",
"channel": "web"
}
}

This is useful for onboarding and support because it explains which route is selected and why.

Routed Tool Execution​

POST /api/v1/runtime/mcp/tools/execute
Content-Type: application/json
Authorization: Bearer {{token}}

{
"session_id": "{{session_id}}",
"tool_name": "catalog_get_product_details",
"arguments": {
"catalogId": "1234567890"
},
"strategy": "first_healthy"
}

Use this when the protected BFF knows the tool name but ACP Engine should choose the MCP server. A deterministic example is a known product-details widget mapped server-side to catalog_get_product_details. If no explicit mcp_server_ids are supplied, ACP Engine looks up enabled tools in the discovered MCP tool registry and routes to the matching server. This endpoint does not run AI intent classification, select a Flow, or return a runtime action. Natural-language requests belong on /api/v1/runtime/ai/chat; use a product-details Flow through /api/v1/runtime/execute when the caller needs RENDER_PRODUCT_DETAILS.

Parallel Execution and Aggregation​

For multi-source scenarios, ACP Engine can execute tools across multiple MCP servers:

POST /api/v1/runtime/mcp/tools/execute-parallel
Content-Type: application/json
Authorization: Bearer {{token}}

{
"realm_id": "{{realm_id}}",
"agent_id": "{{agent_id}}",
"session_id": "{{session_id}}",
"executions": [
{
"mcp_server_id": "{{mcp_server_id}}",
"tool_name": "search_products",
"arguments": {
"query": "black shoes",
"limit": 10
}
}
],
"aggregation": {
"mode": "merge_by_sku",
"max_results": 20
}
}

This pattern is useful for multiple product sources, multiple brands, or multiple regional systems.

MCP Server Requirements​

Customer MCP servers should:

  • Be reachable by ACP Engine over the agreed network path.
  • Use HTTPS in production environments.
  • Expose stable tool names and schemas.
  • Return predictable JSON payloads.
  • Handle idempotency for operations where duplicate requests are possible.
  • Return friendly error objects when business validation fails.
  • Avoid returning secrets, private tokens, or unnecessary sensitive data.

Session-Aware Tool Guidance​

Some tools are stateless and can run with only their direct arguments:

  • Product or product search.
  • Product details.
  • Availability lookup.
  • Order status lookup.
  • Customer lookup.

Other tools need session continuity:

  • Add to cart.
  • Complete cart.
  • Checkout preparation.
  • Multi-step booking.
  • Payment handoff.
  • Stateful workflow automation.

Use session_id consistently through ACP Engine. If the downstream tool expects a sessionId argument, ACP Engine or the frontend backend can map the public session value into the tool argument shape.

Suggested Tool Naming​

Use clear action-oriented names:

  • search_products
  • get_product_details
  • add_to_cart
  • get_cart
  • start_checkout
  • complete_payment
  • get_order_status
  • search_customers
  • create_support_ticket

Stable tool names make routing rules easier to maintain.

MCP QA Checklist​

  • Public MCP initialize and tools/list succeed through the configured ingress.
  • Realm service credentials are rejected when the requested realm does not match for realm-bound Engine tools.
  • Merchant API keys return only the merchant stores allowed by their merchant, store, or custom scope.
  • Catalog write tools are exercised only in an approved UAT merchant and store.
  • Server registration succeeds.
  • Registration response includes a successful discovery object, or auto_discover was intentionally disabled.
  • Connectivity test succeeds.
  • Tool discovery/listing returns expected persisted tools.
  • Direct proxy call succeeds for at least one read-only tool.
  • Routing preview selects the expected server.
  • Routed execution succeeds.
  • Parallel execution behavior is validated when used.
  • Usage records are visible after tool execution.
  • Error responses are readable and safe to display or log.
  • For Thyris Merchant MCP, product galleries preserve order and use the first imageUrls entry as the primary image.
  • For Merchant MCP write tools, subscribed outbound webhook events arrive with the event/source values documented above.
  • Expired and revoked Merchant Services keys fail connectivity with 401, and rotating the registered key restores discovery and execution.