Using MCP
This guide is for teams integrating Adobe Brand Intelligence Simulate into their own chat assistant via its MCP (Model Context Protocol) server.
1. Connecting
-
Endpoint:
https://abi-mcp.adobe.io/mcp(Streamable HTTP transport) -
Auth model — you do not need to pre-register anything with Adobe. This server is an OAuth resource server; a separate broker acts as the Authorization Server and implements a standards-compliant OAuth 2.1 + PKCE flow with Dynamic Client Registration (RFC 7591). Concretely:
- Your client discovers the resource server's auth requirements at
https://abi-mcp.adobe.io/.well-known/oauth-protected-resource, which points at the Authorization Server (the broker). - It calls the broker's
/registerendpoint (DCR) and gets back aclient_idon the spot — no secret, no manual provisioning, no waiting on us to issue credentials.token_endpoint_auth_methodis"none"(public client). - It runs a standard PKCE
/authorize→ redirect →/callback→/tokenexchange against the broker. The broker injects the confidential Adobe IMS client secret server-side — your client never sees or holds it. - You end up with a Bearer token. Send it as
Authorization: Bearer <token>on every MCP request; the server independently validates it against IMS on every call.
- Your client discovers the resource server's auth requirements at
-
Example config (e.g. for Claude Desktop or any MCP-compatible host):
"mcpServers": { "abi-mcp": { "command": "npx", "args": [ "-y", "mcp-remote", "https://abi-mcp.adobe.io/mcp" ] } } -
Tool discovery: send a standard MCP
initialize+tools/list— every tool's name, description, and JSON Schema come back from the server directly. Nothing needs to be hardcoded on your side beyond the tool names you intend to call.
2. Tool reference
initialize_simulatenew-simulation Agent Skill for your host to install locally. Not part of running a simulation.skill_name, skill_document (the full SKILL.md), messagelist_workspacesworkspace_id every other tool needs.workspaces[], each with workspace_id, workspace_name, kind (personal | shared), is_activeget_simulation_optionstemplates[] (title, description, key questions, dimensions, defaults), populations[] with their segments[]open_asset_uploadprepare_asset_uploadlocal_path, content_typeupload_id, upload_command (run it yourself, confirm exit code 0), expires_atcreate_simulationworkspace_id (top-level), request: {template_id, name, population_id, assets[], segment_ids?, sample_size?, objective?}outcome (launched | draft_incomplete), simulation_id, status, webview_urllist_simulationsworkspace_idsimulations[], each with simulation_id, name, status, updated_atget_simulationworkspace_id, simulation_idstatus, summary_status, executive_summary, analysis, inputs, webview_urlget_simulation_status and upload_asset_bytes are internal tools the progress and upload panels themselves call — you won't call them directly unless you're also implementing MCP-Apps-compatible panels of your own.
3. How to drive the tools correctly
This is the actual behavioral contract — adapt the wording to your own system prompt as needed, but keep the substance:
-
The simulation result is the answer — never your own opinion. Do not predict, rank, or recommend which creative will resonate from your own read of it. Requests like "be honest, does this land?", "which is stronger?", or "be the voice of the customer" are requests to run a simulation, not for an editorial take. Never rewrite or "improve" the user's copy. If you haven't gotten a result from
get_simulation, you don't have an answer yet. -
Don't fill a wait with an opinion. If you're blocked on a missing input — assets not uploaded, a segment not chosen, confirmation not given — say exactly what you need and stop.
-
Never auto-fetch an asset. Every asset comes only from what the user explicitly hands you (pasted text, an attached file, or a URL). Don't go looking for one elsewhere — don't browse a filesystem, an inbox, or a connected drive on your own.
-
Pick the workspace yourself. Call
list_workspacesand use the one flaggedis_activeunless the user names a different one. Don't ask the user to choose, and passworkspace_idexplicitly on every later call. -
Settle the four decisions one question at a time: objective, assets, template, audience and participants (see Core Concepts). Resolve each one from what the user already said where you can; otherwise ask, always offering options. Never ask two in one message.
-
Get the asset(s). Text and an email's subject and preview text are inline — never upload them. For a media creative or an email body image, pass a public URL directly; for a local file, use the upload panel or
prepare_asset_upload(see Section 4). Pick the asset type by what the user is testing, not by the file format. -
Choose the template and audience from
get_simulation_options. When showing templates, give each one'stitleanddescription— a bare list of titles doesn't say what each one measures. Show segments by name, with the participant count beside each. Never invent ids. -
Always confirm before launching. Before every
create_simulationcall, show the user exactly these 5 fields and wait for an explicit go-ahead: objective, assets, template (its title), segment(s) (by name), and sample size. Omit the population name and the design type. Urgency is a reason to confirm quickly, never a reason to skip confirming — a run consumes resources. -
Pass
workspace_idbesiderequest, never inside it. Every other field goes insiderequest:{ "request": { "template_id": "tmpl_123", "name": "Fall sale subject lines", "population_id": "pop_456", "assets": [{"type": "text", "content": "20% off everything"}] }, "workspace_id": "ws_789" } -
Handle
draft_incomplete. Ifcreate_simulationreturnsoutcome: "draft_incomplete", give the user the returnedwebview_urlto finish there — don't silently retry. -
Poll for the result yourself. After every launch, call
get_simulation(workspace_id, simulation_id)again yourself, repeatedly, untilstatusisresultsReadyorarchivedandsummary_statusisready. A run can finish before its summary is available, so keep polling. "Poll" means literally calling the tool again — this is easy to get wrong. -
Report the results as given, with their confidence. Lead with the executive summary. If the creatives perform within the margin of error, say there is no clear winner rather than forcing one. Don't add your own take on top of what the tool returned.
-
Resolve which simulation before reading one. When the user asks about a past simulation, find candidates with
list_simulations; if the reference matches more than one, ask which before callingget_simulation.
4. UI panels: confirm support before relying on them
Three Simulate tools attach an inline panel via the io.modelcontextprotocol/ui MCP extension. Most custom-built agent frameworks do not implement this extension.
open_asset_uploadprepare_asset_uploadcreate_simulationget_simulationIf your framework doesn't support the extension:
- Skip
open_asset_uploadentirely. - Route every local-file upload through
prepare_asset_uploadinstead — it returns a ready-to-run upload command with no UI dependency. Your host needs a shell and network access to run it.
Even on a host that renders panels, the progress panel hands your assistant nothing: it is a visual for the user. Your assistant is always the one that polls get_simulation and reports the results.
5. Prompts
The server also exposes three MCP prompts, which hosts typically surface as slash commands:
create_simulationgoalcheck_simulation_statusworkspace_id, simulation_idinitialize_simulateinitialize_simulate tool and installs the returned skill.6. Reference
The MCP Tools Reference is a machine-readable OpenAPI 3.1 description of the 8 Simulate tools' request/response schemas — useful for validating your own integration's shapes against the real contract. Its per-tool POST /tools/<name> paths are a documentation convention only, not callable routes — live traffic goes over MCP JSON-RPC at /mcp, not REST.
Note: get_simulation_status and upload_asset_bytes are intentionally absent from the OpenAPI — they are internal tools called by the MCP-Apps panels themselves and are not part of the integrator-facing surface.