Connect
In productionAny MCP client connects to https://mcp.offersuite.io/mcp and sends the workspace's secret key as a bearer token on each request. The server forwards the key to the API on every call and never stores it.
68 tools
The production MCP server has 68 tools, one per operation in https://api.offersuite.io/openapi.json.
The server reads the API's OpenAPI document when it runs and builds one tool per operation, named after the operation in snake case (create_offer, publish_offer, get_offer_economics). The tools are always the deployed API's operations: a route added to the API becomes a tool without a change to the server, and a tool the API does not have cannot be listed. Operations that use GET are marked read-only.
MCP client configurationos_sk_… is your workspace secret key
{
"mcpServers": {
"offer-suite": {
"type": "http",
"url": "https://mcp.offersuite.io/mcp",
"headers": {
"Authorization": "Bearer os_sk_…"
}
}
}
}Both addresses, the MCP server and the OpenAPI document, are listed for crawlers and agents in llms.txt.
Offer Suite is not open yet: brands join the waitlist.
What agents get
In productionBeside the tools, the server hands an agent what it needs to write an offer from the schema alone, with no builder in between.
- An authoring guide, read as an MCP resource: the document's shape, how options, lines and pricing fit together, and how a publish proves them on a real cart.
- Three complete example offers, each with commentary on what to copy. They are the same documents the schema's own tests parse, so an example that stopped validating would fail the build.
- An error catalogue that a test keeps in sync with every error code the API can return and every schema validation message.
- A description on every field of the offer document, the resolve response and the event body, which agents read field by field in
create_offerandreplace_offer. A test fails any new field without one.
| Drafts first | create_offer and replace_offer store a draft version and never touch Shopify. The live version keeps serving until a publish. |
|---|---|
| Resolver first | lookup_offer takes an offer id, its code or a URL holding either, so an agent confirms which offer it has before any write. |
destructiveHint | Set on publish_offer, stop_experiment and void_cost, operations no later call undoes. MCP clients can use it to ask a person first. |
confirm: true | publish_offer refuses without it and does not call the API. |
1 call
In an internal test in September 2026, a fresh agent with only the MCP resources wrote a valid offer on its first create_offer call.
The API
In productionEverything the MCP tools do is plain HTTP underneath. The brand-facing API (offers, carts, costs, items, orders, experiments, events, stores, tenant and privacy) is described by an OpenAPI 3.1 document at api.offersuite.io/openapi.json. It is generated from the same Zod definitions that validate each request and linted on every change: the description and the validation are one definition.
Every error comes back in one shape, {error: {code, message, issues}}, with a stable code. A validation failure lists each field path that failed, so an agent can repair the document and send it again.
POST /offers with two deliberate mistakes400, dev API, captured 2 October 2026
{
"error": {
"code": "invalid_document",
"message": "The offer document is invalid",
"issues": [
{
"path": "options[4].lines[0].purchase.sellingPlanId",
"message": "a subscription purchase requires sellingPlanId"
},
{
"path": "defaultOptionKey",
"message": "defaultOptionKey \"ritual\" names no option in this document"
}
]
}
}A subscription line without its selling plan, and a default option that names no option: both refused, nothing stored.
Shopify-facing endpoints (webhooks, Sidekick and the App Home simulator) are outside the document. They serve Shopify, not your agents.
An example session
One conversation from a question to a running experiment: six production tools, and one explicit approval before the publish.
claude · offer-suite MCP6 tool calls · specimen data
You asked: Which kit makes us the most per order?
Tool call:
get_offer_economicsOF_DEV_KITS1.1sStarter Kit keeps the most on a first order: $20.38 (42.5%).
Ritual Set keeps the most on a renewal: $49.60 (62.0%).
You asked: Drop the frother from the Ritual Set gifts. Worth it?
Tool call:
simulate_offerOF_DEV_KITS · draft vs live v31.4sRitual Set first order: $18.94 → $25.14.
That is the frother's cost and one pick. The price is the same, so the fees don't move.
Nothing was stored.
You asked: Store it and publish it as an arm.
Tool call:
replace_offerOF_DEV_KITS · draft v40.9spublish_offer proves v4 on real carts as an arm.
Live traffic stays on v3 until an experiment splits it. Publish? (y/n)
You asked: y
Tool call:
publish_offerOF_DEV_KITS v4 · as arm · confirm1.2sQueued. run 8f2c1d04.
Tool call:
get_publish_runOF_DEV_KITS · run 8f2c1d042.1sEvery option matched. Charged $58.60, promised $58.60.
v4 is a verified arm.
You asked: Test it against live, fifty-fifty.
Tool call:
create_experimentOF_DEV_KITS · v3 50% · v4 50%1.0sRunning. 36,099 visitors per arm for a 10.0% lift.
Keys and roles
In production| Secret key | For servers and agents: every operation in the OpenAPI document. Keep it out of page source. |
|---|---|
| Public key | Goes in page source: resolve the live offer, price a selection, build a cart and record events. Nothing else. |
| Owner | Everything, and the only role that makes or removes an owner. A workspace always keeps at least one. |
|---|---|
| Admin | The team below owner, the API keys and the workspace's settings. |
| Member | The work: costs, verifying offers, imports and actual order costs. Never the keys, the team or the settings. |
| Read-only | Reads everything, writes nothing. |
- Keys and the team are managed in the dashboard only. They are not in the OpenAPI document, and an API key cannot call them.
- The full key is shown once, when it is created. Everyone in the workspace can see which keys exist.
- The API enforces roles on every dashboard call, not only the screens.
What it does not do yet
- Install happens only through Shopify: the MCP server and the API have no install tool.
- One store per workspace for now; a second store cannot join an existing workspace yet.
- No command-line client is offered. Not available yet
Questions
Which agents work?
Any MCP client that connects to a remote server over HTTP and can send an Authorization header gets one tool per API operation. Anything else that speaks HTTP calls the API directly with the same secret key, reading the OpenAPI document for every route and field.
Does the MCP server keep my key?
No. The key travels on each request, the server forwards it to the API for that call, and nothing is stored.
Can an agent publish without anyone approving?
Creating or replacing an offer only stores a draft. Over MCP, publish_offer refuses without confirm: true and is marked destructive, so an MCP client can ask a person before it runs. Over the HTTP API, the POST /offers/{id}/publish call is itself the approval. Either way, a version goes live only after every visible option matches on a real Shopify cart.