Your agent. Your flavor lab.
Connect a Streamable HTTP MCP client that supports custom headers. Use the same scoped API key as REST; no ChatGPT sign-in or OAuth connection is required.
URL: https://labs.deconfound.com/mcp Header: X-Deconfound-Api-Key: YOUR_DECONFOUND_API_KEY
Create a key in API keys. For the complete recipe and order flow, select ingredients:read, ideas:read, ideas:write, orders:read, and orders:write. Keep the key in your client's secret storage. A client that only supports OAuth needs the REST integration instead.
Quote → checkout → Ordered - Pending Lab
Only supported catalog recipes receive an orderable quote. Show the exact recipe, total and trial terms, then obtain agreement. Send checkout:{acceptQuote:true} in place_order to start checkout at that fixed price. No lab confirmation or second offer is needed. Finish payment through REST/browser; successful checkout returns orderStatus:ordered_pending_lab. Test mode captures no funds.
Verify the connection
Initialize once, send the initialized notification, then list or call tools. Send your key with each data call; discovery contains no private data. The endpoint is stateless, with no session header and no separate GET event stream. The examples use protocol 2025-11-25; honor the version returned at initialization.
curl 'https://labs.deconfound.com/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "X-Deconfound-Api-Key: $DECONFOUND_API_KEY" \
--data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"my-agent","version":"1.0"}}}'curl 'https://labs.deconfound.com/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-11-25' \
-H "X-Deconfound-Api-Key: $DECONFOUND_API_KEY" \
--data '{"jsonrpc":"2.0","method":"notifications/initialized"}'curl 'https://labs.deconfound.com/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-11-25' \
-H "X-Deconfound-Api-Key: $DECONFOUND_API_KEY" \
--data '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"search_ingredients","arguments":{"query":"lime","limit":5}}}'The following examples are the params for tools/call. Your MCP client normally supplies the JSON-RPC envelope.
Idea → recipe → quote → checkout
Save an idea
{
"name": "create_idea",
"arguments": {
"idempotencyKey": "lime-idea-001",
"request": {
"prompt": "A crisp lime beverage",
"batchMassG": 500
}
}
}Generate its recipe
{
"name": "generate_recipe",
"arguments": {
"ideaId": "<returned idea.id>",
"revision": 1,
"idempotencyKey": "lime-generation-001"
}
}Use the actual returned revision; 1 and 3 here are examples. Generation can take up to 240 seconds; use a 300-second timeout. After an interruption, use get_idea to recover the saved state. Proceed only when status is succeeded and idea.recipes contains your selected recipe. Each recipe includes services.quote.
Quote a test
{
"name": "quote_order",
"arguments": {
"recipe": {
"source": "idea",
"ideaId": "<returned idea.id>",
"ideaRevision": 3
}
}
}Show quote.totalCents / 100 as “Test Trial for $XX”, with its inclusions. A null total cannot be ordered. Explain the gap and propose a supported alternative. Add the selected variantId when needed; a proposed alternative needs user acceptance and acceptAlternative:true. Use the owned idea ID and its current revision, not its internal generation-attempt ID.
Request the approved test
{
"name": "place_order",
"arguments": {
"idempotencyKey": "lime-order-001",
"request": {
"selection": {
"recipe": {
"source": "idea",
"ideaId": "<returned idea.id>",
"ideaRevision": 3
}
},
"quoteHash": "<returned quote.scopeHash>",
"shareWithTeam": true,
"contactEmail": "customer@example.com",
"checkout": {"acceptQuote": true}
}
}
}Only place an order after the user authorizes the quote and sharing the recipe and contact details. Preserve the exact quoted selection and quote hash. A changed quote requires a fresh review. Submission takes no payment and schedules no preparation or shipment.
Finish checkout
After the requester confirms placement at the saved total, use REST POST /api/v2/orders/{id}/test-payment with {"outcome":"succeeded"} and a distinct stable key. Show Ordered - Pending Lab only after success. A failed or cancelled attempt still needs checkout. The current test mode charges no money.
Continue an older saved request
Read its saved quote and current revision. After agreement to its price, scope and trial terms, call prepare_order_checkout with {orderId,idempotencyKey,request:{revision,quoteHash,acceptQuote:true}}. This keeps the original price and initializes checkout without a lab offer. It cannot bypass a real revised offer on a historical order; that contract still needs explicit acceptance.
Read the report
{
"name": "get_order_results",
"arguments": {
"orderId": "<returned order.id>"
}
}Exact ingredients and method
Use recipe.source:"ingredients" inside quote_order, then place the unchanged selection through place_order. Supply name, catalogVersion, batchMassG, ingredients with ingredientId and sourceMassG, and optional ordered preparation.steps. Explicit water requires the ingredient masses to total the batch mass. Otherwise the server calculates the remaining water. Full recipe and ordering reference.
Results and recovery
get_order and list_orders return orderStatus and fulfillment status. Show ordered_pending_lab as Ordered - Pending Lab, and awaiting_checkout as Complete checkout. get_order_results returns published descriptions, photos and analysis in output; read this first. Advanced results may remain not_started after the simple report is complete. It also returns expected batches, actual quantities and lots, preparation, photos, observations, measurements, omissions, deviations, recommendations and correction history. Evidence remains missing until the operator records it. Reports are available in the customer workspace and REST; no automatic email is sent.
MCP returns these fields in structuredContent, alongside meta.httpStatus, meta.requestId and meta.replayed. Retry uncertain mutations with their original idempotency key and unchanged arguments. Creation, generation and ordering use distinct keys, each 8–128 letters, digits, hyphens, underscores, periods or colons.
Errors and access
Missing, expired or revoked keys return HTTP 401. A tool outside the key’s scopes returns INSUFFICIENT_SCOPE; another owner’s record remains unavailable. Business errors are returned in structuredContent.error with isError:true. Check meta.httpStatus and retry instructions; do not treat HTTP 200 around an MCP tool error as success. Native keys cannot grant operator approval, inventory access, measurement entry or key administration. There are no payment or dispatch tools.
Scope
Recipes are untested beverage or water-based flavor proposals. Supported orders go directly through checkout into the lab queue. Read the returned payment, fulfillment and delivery state; a simulated test payment is not real funds and a shipping estimate is not a shipment. The standard trial requests photos, actual mass, visual observations and one maker’s descriptive notes. Instrument testing is outside automatic ordering; supported shipping destinations receive an allowance within the quote. The private create_lab_order tool does not submit a customer service request; use quote_order and place_order for that.
REST API keys · REST reference · OpenAPI
Always offer a next step
When an idea cannot produce a complete recipe, show its alternatives[] proposal and what changes. After the requester selects a generate alternative, send its complete request unchanged to create_idea, then call generate_recipe with fresh operation keys. The request retains ingredient exclusions and selections; the new recipe receives its own quote. An edit alternative requires an explicit change to the request. Do not order the unsupported original or silently relax its restrictions.