Home

stoq-api-v2

v2.0.0-beta

STOQ's MCP server exposes the full v2 API — over 200 preorder and back-in-stock actions — through just three tools: search, execute_read, execute_write. Instead of loading a schema per action up front, an agent searches for the action it needs, then calls it by method + path.

How the API works

  • search, execute_read, execute_write — not one tool per action. search finds actions by keyword (matches path, description, aliases, notes); results narrow enough (3 or fewer) come back with the full request JSON Schema. execute_read/execute_write then call the concrete method + path from a search result, with real ids substituted for any :placeholder segment.
  • Two domains. Preorders (offers, orders, product variants, reports) and Back in Stock (signups, notifications, settings, reports) — both searchable from the same search tool.
  • Named actions carry side effects; PATCH actions are deep-partial for settings and toggles — only the fields you send change.
  • Results. Reads return the resource; writes return the updated resource or { job_id } for bulk/async work (search for the matching jobs action and execute_read it to poll). Failures return { success: false, status, errors: [...] }; status: "conflict" means an invalid lifecycle transition — read the error, don't retry blindly.
  • More discovery. GET /api/v2/external/help is the canonical machine-readable manifest. The full agent guide lives at GET /api/v2/external/skill.md (and /preorders/skill.md, /back_in_stock/skill.md).

Connect

  • Endpoint: https://app.stoqapp.com/api/v2/external/mcp (JSON-RPC over HTTP)
  • Auth: send your STOQ API key in the X-Auth-Token header — find it in the STOQ app under Settings → Integrations → API Key.

Most MCP clients take a remote server URL plus headers. Generic config:

{
  "mcpServers": {
    "stoq": {
      "url": "https://app.stoqapp.com/api/v2/external/mcp",
      "headers": { "X-Auth-Token": "YOUR_STOQ_API_KEY" }
    }
  }
}

Test the connection

List the available tools with a JSON-RPC tools/list call — you should get back the four tools documented below (search, execute_read, execute_write, generate_storefront_widget):

curl -X POST https://app.stoqapp.com/api/v2/external/mcp \
  -H "X-Auth-Token: $STOQ_API_KEY" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Then search for an action and call it — e.g. list your preorder offers:

# 1. Find the action
curl -X POST https://app.stoqapp.com/api/v2/external/mcp \
  -H "X-Auth-Token: $STOQ_API_KEY" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
      "params":{"name":"search","arguments":{"query":"list offers"}}}'
# → { method: "GET", path: "/preorders/offers", ... }

# 2. Call it
curl -X POST https://app.stoqapp.com/api/v2/external/mcp \
  -H "X-Auth-Token: $STOQ_API_KEY" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
      "params":{"name":"execute_read","arguments":{"method":"GET","path":"/preorders/offers","params":{}}}}'

Full API guide for agents: GET /api/v2/external/preorders/skill.md.

Tools

search

read-onlyidempotent
TOOLsearch

Search the Stoq API v2 action catalog by keyword — matches path, description, aliases, and notes (e.g. "deposit", "widget button color", "cancel order", "back in stock signup"). Returns method + path + description for each match. A search that narrows to 3 or fewer actions also includes the full request JSON Schema for each, so you know exactly what params execute_read/execute_write expect. Call with an empty query to browse the full catalog.

Parameters

querystringrequiredargument

Keyword(s) to search for. Empty string browses everything.

methodstringGETPOSTPATCHDELETEargument

Optional: restrict results to one HTTP method.

limitintegerargument

Max results to return. Default 20.

Returns

Returns MCP content array (text, image, or embedded resource).

search
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "search",
    "arguments": {
        "query": "string",
        "method": "GET",
        "limit": 0
      }
  }
}
const result = await client.callTool("search", {
  "query": "string",
  "method": "GET",
  "limit": 0
});
result = await session.call_tool("search", arguments={
  "query": "string",
  "method": "GET",
  "limit": 0
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

execute_read

read-onlyidempotentopen-world
TOOLexecute_read

Call a read (GET) action from the Stoq API v2 catalog. Use search first to find the right method + path and see what params it expects. path must be concrete — substitute real ids for any :placeholder segment. An unregistered path, or one registered under a different method, returns a structured error rather than raising.

Parameters

methodstringGETrequiredargument

HTTP method — must be GET.

pathstringrequiredargument

Concrete action path from search, e.g. "/preorders/offers/123/widget" (real ids in place of any :placeholder).

paramsobjectargument

Request body for this action (see the request_schema from search).

Returns

Returns MCP content array (text, image, or embedded resource).

execute_read
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "execute_read",
    "arguments": {
        "method": "GET",
        "path": "string",
        "params": {}
      }
  }
}
const result = await client.callTool("execute_read", {
  "method": "GET",
  "path": "string",
  "params": {}
});
result = await session.call_tool("execute_read", arguments={
  "method": "GET",
  "path": "string",
  "params": {}
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

execute_write

destructiveopen-world
TOOLexecute_write

Call a write (POST/PATCH/DELETE) action from the Stoq API v2 catalog. Use search first to find the right method + path and see what params it expects. path must be concrete — substitute real ids for any :placeholder segment. An unregistered path, or one registered under a different method, returns a structured error rather than raising.

Parameters

methodstringPOSTPATCHDELETErequiredargument

HTTP method — must be POST or PATCH or DELETE.

pathstringrequiredargument

Concrete action path from search, e.g. "/preorders/offers/123/widget" (real ids in place of any :placeholder).

paramsobjectargument

Request body for this action (see the request_schema from search).

Returns

Returns MCP content array (text, image, or embedded resource).

execute_write
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "execute_write",
    "arguments": {
        "method": "POST",
        "path": "string",
        "params": {}
      }
  }
}
const result = await client.callTool("execute_write", {
  "method": "POST",
  "path": "string",
  "params": {}
});
result = await session.call_tool("execute_write", arguments={
  "method": "POST",
  "path": "string",
  "params": {}
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

generate_storefront_widget

TOOLgenerate_storefront_widget

Generate a ready-to-paste STOQ storefront widget snippet for a variant — a preorder widget/button, a notify-me (back-in-stock) form, or event-tracking listeners. Two surfaces: surface=sdk for headless/Hydrogen (@artossoftware/stoq-sdk), surface=theme for a Shopify theme running the STOQ app embed (window._RestockRocket + Liquid). Aliases: generate widget, scaffold preorder button, create notify-me snippet, give me the embed code, theme javascript snippet, headless preorder code, hydrogen example. Returns code, not an API call.

Parameters

surfacestringsdkthemeargument

sdk = headless/Hydrogen via @artossoftware/stoq-sdk. theme = Shopify theme with the STOQ app embed (window._RestockRocket API + Liquid). Default sdk.

widgetstringpreordernotify_meproduct_pageeventsrequiredargument

Which snippet to generate. events = analytics listeners for the stoq:* events.

formatstringcustom-elementscript-tagreactargument

For surface=sdk only. Output flavor; default custom-element. Ignored for surface=theme.

variant_idstringargument

Shopify variant id to embed (optional).

product_idstringargument

Shopify product id — required for notify-me.

Returns

Returns MCP content array (text, image, or embedded resource).

generate_storefront_widget
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "generate_storefront_widget",
    "arguments": {
        "surface": "sdk",
        "widget": "preorder",
        "format": "custom-element",
        "variant_id": "string",
        "product_id": "string"
      }
  }
}
const result = await client.callTool("generate_storefront_widget", {
  "surface": "sdk",
  "widget": "preorder",
  "format": "custom-element",
  "variant_id": "string",
  "product_id": "string"
});
result = await session.call_tool("generate_storefront_widget", arguments={
  "surface": "sdk",
  "widget": "preorder",
  "format": "custom-element",
  "variant_id": "string",
  "product_id": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}