stoq-api-v2
v2.0.0-betaSTOQ'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.
searchfinds 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_writethen call the concretemethod+pathfrom a search result, with real ids substituted for any:placeholdersegment. - Two domains. Preorders (offers, orders, product variants, reports) and Back in Stock (signups,
notifications, settings, reports) — both searchable from the same
searchtool. - 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/helpis the canonical machine-readable manifest. The full agent guide lives atGET /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-Tokenheader — 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-onlyidempotentSearch 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
querystringrequiredargumentKeyword(s) to search for. Empty string browses everything.
methodstringGETPOSTPATCHDELETEargumentOptional: restrict results to one HTTP method.
limitintegerargumentMax results to return. Default 20.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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
}){
"content": [
{
"type": "text",
"text": "..."
}
]
}execute_read
read-onlyidempotentopen-worldCall 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
methodstringGETrequiredargumentHTTP method — must be GET.
pathstringrequiredargumentConcrete action path from search, e.g. "/preorders/offers/123/widget" (real ids in place of any :placeholder).
paramsobjectargumentRequest body for this action (see the request_schema from search).
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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": {}
}){
"content": [
{
"type": "text",
"text": "..."
}
]
}execute_write
destructiveopen-worldCall 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
methodstringPOSTPATCHDELETErequiredargumentHTTP method — must be POST or PATCH or DELETE.
pathstringrequiredargumentConcrete action path from search, e.g. "/preorders/offers/123/widget" (real ids in place of any :placeholder).
paramsobjectargumentRequest body for this action (see the request_schema from search).
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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": {}
}){
"content": [
{
"type": "text",
"text": "..."
}
]
}generate_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
surfacestringsdkthemeargumentsdk = headless/Hydrogen via @artossoftware/stoq-sdk. theme = Shopify theme with the STOQ app embed (window._RestockRocket API + Liquid). Default sdk.
widgetstringpreordernotify_meproduct_pageeventsrequiredargumentWhich snippet to generate. events = analytics listeners for the stoq:* events.
formatstringcustom-elementscript-tagreactargumentFor surface=sdk only. Output flavor; default custom-element. Ignored for surface=theme.
variant_idstringargumentShopify variant id to embed (optional).
product_idstringargumentShopify product id — required for notify-me.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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"
}){
"content": [
{
"type": "text",
"text": "..."
}
]
}