fetchsandbox-mcp 0.3.4 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # fetchsandbox-mcp
2
2
 
3
+ <a href="https://www.producthunt.com/products/fetchsandbox?embed=true&utm_source=badge-featured&utm_medium=badge&utm_campaign=badge-fetchsandbox" target="_blank" rel="noopener noreferrer"><img alt="FetchSandbox - Runnable API integrations for developers and AI agents | Product Hunt" width="250" height="54" src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1175731&theme=light"></a>
4
+
5
+
3
6
  Turn any OpenAPI spec into a working sandbox your AI agent can use, right from your IDE.
4
7
 
5
8
  This is the Model Context Protocol (MCP) server for [FetchSandbox](https://fetchsandbox.com). It exposes three tools that let any MCP-compatible agent ingest an OpenAPI spec, list its workflows, and run them — with realistic, schema-validated responses for every endpoint.
@@ -131,39 +134,59 @@ If your agent speaks MCP, it accepts a stdio command. Use:
131
134
 
132
135
  ## Try it now
133
136
 
134
- After restarting your agent, paste any of these prompts. Each hits a hand-curated workflow with realistic IDs and real state transitions.
135
-
136
- ### Stripe accept a payment
137
+ After restarting your agent, paste any of these prompts. Every prompt
138
+ starts with the `./fetchsandbox` dispatch prefix — that's the routing
139
+ signal. The brain matches your symptom to a workflow + scenario,
140
+ reproduces it deterministically, and returns a public receipt URL as
141
+ proof. **Variant prefixes also accepted:** `/fetchsandbox`,
142
+ `@fetchsandbox`, `fs:`.
137
143
 
138
- > Use fetchsandbox to import the Stripe spec from `https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json` and run the `accept_payment` workflow. Show me the trace.
144
+ ### Stripe investigate a webhook bug
139
145
 
140
- The agent imports 587 endpoints, matches the bundled curated Stripe sandbox, and runs a 6-step workflow: create customer (`cus_…`) → create PaymentIntent (`pi_…`, `$49.99 USD`, `requires_payment_method`) confirm (`requires_capture`) → capture (`succeeded`) → retrieve → verify webhooks (`payment_intent.created`, `payment_intent.succeeded`).
146
+ > `./fetchsandbox stripe webhook bug in prod payments getting marked paid 2-3 times. fix it with proof.`
141
147
 
142
- ### Twilio send an SMS
148
+ The brain matches the `webhook_duplicate_side_effect` pattern. The
149
+ agent reproduces the bug via `accept_payment` + `webhook_retries`
150
+ scenario, applies the fix from the brain's `fix_pattern`, re-runs to
151
+ confirm, and surfaces the brain's `check_for` items as the audit list.
152
+ Receipt URL is the proof artifact.
143
153
 
144
- > Use fetchsandbox to import the Twilio Messaging spec from `https://raw.githubusercontent.com/twilio/twilio-oai/main/spec/yaml/twilio_messaging_v1.yaml` and run the `send_sms` workflow.
154
+ ### Stripe silent card decline
145
155
 
146
- The agent imports the messaging API and runs a curated send-and-verify flow with realistic Twilio-formatted message SIDs (`SM…`).
156
+ > `./fetchsandbox stripe checkout fails silently when cards are declined investigate and fix.`
147
157
 
148
- ### GitHub issue lifecycle
158
+ Brain matches `card_decline_not_handled` reproduces via
159
+ `payment_declined` scenario → recommends the wrap-in-try/except fix
160
+ pattern with `decline_code` surfacing.
149
161
 
150
- > Use fetchsandbox to import the GitHub REST API from `https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json` and run the `issue_lifecycle` workflow.
162
+ ### Stripe webhook signature security
151
163
 
152
- The agent walks the create comment close reopen flow against a real-shaped GitHub sandbox.
164
+ > `./fetchsandbox stripe webhook security audit failed anyone can post to the endpoint. fix it.`
153
165
 
154
- ### Paddle paste-content variant
166
+ Brain matches `webhook_signature_unverified` reproduces via
167
+ `auth_failure` scenario → recommends the `stripe.Webhook.construct_event`
168
+ fix with `STRIPE_WEBHOOK_SECRET` env sourcing.
155
169
 
156
- If a vendor doesn't publish their spec at a stable URL (Paddle, Notion, Linear), paste the content directly:
170
+ ### Build a new integration
157
171
 
158
- > Here's the Paddle Billing OpenAPI spec — `<paste JSON or YAML>`. Use fetchsandbox to import it and run the `subscriptions_canceled` workflow.
172
+ > `./fetchsandbox help me integrate resend for transactional email`
159
173
 
160
- Same engine path; same curated quality if the spec's `info.title` matches a bundled config.
174
+ Brain surfaces Resend's discovery questions (SPF/DKIM, bounce
175
+ handling, etc.), routes to the right send-email workflow, and walks
176
+ the implementation against a curated Resend sandbox.
161
177
 
162
178
  ### Any other API
163
179
 
164
- > Use fetchsandbox to import `<your OpenAPI URL>` list the workflows and tell me which is most interesting.
180
+ > `./fetchsandbox <your question or bug report about any API>`
165
181
 
166
- For specs we don't have curated configs for, the engine auto-enumerates `create + verify` workflows for every detected resource. Honest about what it shows: UUIDs instead of vendor-style IDs, generic enum values instead of API-specific ones — but the request/response shape and template substitution between steps still work.
182
+ For Stripe, Resend, Clerk, Privy, Surge, AgentMail, Twilio, PayPal,
183
+ Paddle, GitHub, OpenAI, Pinecone, Datadog, and 19 others, the brain
184
+ routes via curated knowledge. For specs we don't have curated configs
185
+ for, the engine auto-enumerates `create + verify` workflows for every
186
+ detected resource. Honest about what it shows: UUIDs instead of
187
+ vendor-style IDs, generic enum values instead of API-specific ones —
188
+ but the request/response shape and template substitution between steps
189
+ still work.
167
190
 
168
191
  ## Tools
169
192
 
@@ -1,6 +1,7 @@
1
1
  export interface RunWorkflowInput {
2
2
  sandbox_id: string;
3
3
  workflow_name: string;
4
+ scenario?: string;
4
5
  }
5
6
  interface BackendStepResult {
6
7
  name?: string;
@@ -18,6 +19,9 @@ export interface NormalizedRunResult {
18
19
  steps_passed: number;
19
20
  steps_total: number;
20
21
  steps: BackendStepResult[];
22
+ share_url?: string;
23
+ flow_run_id?: string;
24
+ sandbox_id?: string;
21
25
  }
22
26
  export declare const runWorkflowTool: {
23
27
  readonly name: "run_workflow";
@@ -33,6 +37,10 @@ export declare const runWorkflowTool: {
33
37
  readonly type: "string";
34
38
  readonly description: string;
35
39
  };
40
+ readonly scenario: {
41
+ readonly type: "string";
42
+ readonly description: string;
43
+ };
36
44
  };
37
45
  readonly required: readonly ["sandbox_id", "workflow_name"];
38
46
  readonly additionalProperties: false;
@@ -1,7 +1,13 @@
1
1
  import { postJson, ToolError } from "../client.js";
2
2
  export const runWorkflowTool = {
3
3
  name: "run_workflow",
4
- description: "Execute ONE specific workflow by name and return its step-by-step trace. " +
4
+ description: "Execute ONE specific workflow by name and return its step-by-step trace " +
5
+ "PLUS a `share_url` — a public, replayable proof URL that renders the " +
6
+ "full timeline (every request, response, webhook event) for this run. " +
7
+ "The share_url is the canonical 'here's what happened' artifact: surface " +
8
+ "it verbatim in any reply that needs evidence (PR comments, Slack " +
9
+ "threads, blog posts, X replies). Do NOT substitute a docs URL or any " +
10
+ "other link as the proof — the share_url is the only valid receipt. " +
5
11
  "Use ONLY when the user explicitly names a single workflow to run (e.g., " +
6
12
  "\"run accept_payment\", \"just check the refund workflow\"). For ANY " +
7
13
  "validation-style request — \"validate stripe\", \"check coverage\", \"run " +
@@ -22,6 +28,14 @@ export const runWorkflowTool = {
22
28
  description: "Workflow id or name from list_workflows. Case-insensitive; dashes and " +
23
29
  "underscores are interchangeable.",
24
30
  },
31
+ scenario: {
32
+ type: "string",
33
+ description: "OPTIONAL failure scenario to exercise (e.g. payment_declined, " +
34
+ "insufficient_funds, fraud_hold). Toggles the sandbox engine's " +
35
+ "scenario for the duration of the run, then restores. Use this for " +
36
+ "'test with declined card' / 'simulate failure X' intents. Omit " +
37
+ "for the happy path.",
38
+ },
25
39
  },
26
40
  required: ["sandbox_id", "workflow_name"],
27
41
  additionalProperties: false,
@@ -33,7 +47,11 @@ export async function runRunWorkflow(input) {
33
47
  if (!input.workflow_name)
34
48
  throw new ToolError("workflow_name is required.");
35
49
  const path = `/api/sandboxes/${encodeURIComponent(input.sandbox_id)}/workflows/${encodeURIComponent(input.workflow_name)}/run`;
36
- const raw = await postJson(path, {});
50
+ const body = {};
51
+ if (input.scenario && input.scenario.trim()) {
52
+ body.scenario = input.scenario.trim();
53
+ }
54
+ const raw = await postJson(path, body);
37
55
  const steps = raw.steps ?? [];
38
56
  const passedSteps = steps.filter((s) => s.status === "passed").length;
39
57
  return {
@@ -44,6 +62,9 @@ export async function runRunWorkflow(input) {
44
62
  steps_passed: passedSteps,
45
63
  steps_total: steps.length,
46
64
  steps,
65
+ share_url: raw.share_url,
66
+ flow_run_id: raw.flow_run_id,
67
+ sandbox_id: raw.sandbox_id ?? input.sandbox_id,
47
68
  };
48
69
  }
49
70
  //# sourceMappingURL=run_workflow.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run_workflow.js","sourceRoot":"","sources":["../../src/tools/run_workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAmCnD,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,2EAA2E;QAC3E,0EAA0E;QAC1E,uEAAuE;QACvE,4EAA4E;QAC5E,wEAAwE;QACxE,2DAA2D;QAC3D,yEAAyE;QACzE,yEAAyE;QACzE,qBAAqB;IACvB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yCAAyC;aACvD;YACD,aAAa,EAAE;gBACb,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,wEAAwE;oBACxE,kCAAkC;aACrC;SACF;QACD,QAAQ,EAAE,CAAC,YAAY,EAAE,eAAe,CAAC;QACzC,oBAAoB,EAAE,KAAK;KAC5B;CACO,CAAC;AAEX,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAuB;IAC1D,IAAI,CAAC,KAAK,CAAC,UAAU;QAAE,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACtE,IAAI,CAAC,KAAK,CAAC,aAAa;QAAE,MAAM,IAAI,SAAS,CAAC,4BAA4B,CAAC,CAAC;IAC5E,MAAM,IAAI,GAAG,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc,kBAAkB,CACjG,KAAK,CAAC,aAAa,CACpB,MAAM,CAAC;IACR,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAmB,IAAI,EAAE,EAAE,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;IACtE,OAAO;QACL,aAAa,EAAE,GAAG,CAAC,SAAS,IAAI,KAAK,CAAC,aAAa;QACnD,WAAW,EAAE,GAAG,CAAC,gBAAgB,IAAI,EAAE;QACvC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QACpC,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,IAAI,CAAC;QAC7C,YAAY,EAAE,WAAW;QACzB,WAAW,EAAE,KAAK,CAAC,MAAM;QACzB,KAAK;KACN,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"run_workflow.js","sourceRoot":"","sources":["../../src/tools/run_workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAiDnD,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,0EAA0E;QAC1E,uEAAuE;QACvE,uEAAuE;QACvE,0EAA0E;QAC1E,mEAAmE;QACnE,uEAAuE;QACvE,qEAAqE;QACrE,0EAA0E;QAC1E,uEAAuE;QACvE,4EAA4E;QAC5E,wEAAwE;QACxE,2DAA2D;QAC3D,yEAAyE;QACzE,yEAAyE;QACzE,qBAAqB;IACvB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yCAAyC;aACvD;YACD,aAAa,EAAE;gBACb,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,wEAAwE;oBACxE,kCAAkC;aACrC;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,gEAAgE;oBAChE,gEAAgE;oBAChE,oEAAoE;oBACpE,iEAAiE;oBACjE,qBAAqB;aACxB;SACF;QACD,QAAQ,EAAE,CAAC,YAAY,EAAE,eAAe,CAAC;QACzC,oBAAoB,EAAE,KAAK;KAC5B;CACO,CAAC;AAEX,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAuB;IAC1D,IAAI,CAAC,KAAK,CAAC,UAAU;QAAE,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACtE,IAAI,CAAC,KAAK,CAAC,aAAa;QAAE,MAAM,IAAI,SAAS,CAAC,4BAA4B,CAAC,CAAC;IAC5E,MAAM,IAAI,GAAG,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc,kBAAkB,CACjG,KAAK,CAAC,aAAa,CACpB,MAAM,CAAC;IACR,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5C,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxC,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAmB,IAAI,EAAE,IAAI,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;IACtE,OAAO;QACL,aAAa,EAAE,GAAG,CAAC,SAAS,IAAI,KAAK,CAAC,aAAa;QACnD,WAAW,EAAE,GAAG,CAAC,gBAAgB,IAAI,EAAE;QACvC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QACpC,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,IAAI,CAAC;QAC7C,YAAY,EAAE,WAAW;QACzB,WAAW,EAAE,KAAK,CAAC,MAAM;QACzB,KAAK;QACL,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU;KAC/C,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fetchsandbox-mcp",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "mcpName": "io.github.fetchsandbox/mcp",
5
5
  "description": "Turn any OpenAPI spec into a working sandbox your AI agent can use. MCP server for Claude Code, Cursor, and any other MCP-compatible LLM IDE.",
6
6
  "license": "MIT",