fetchsandbox-mcp 0.1.1 → 0.3.0
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 +130 -17
- package/dist/client.js +1 -1
- package/dist/index.js +31 -2
- package/dist/index.js.map +1 -1
- package/dist/tools/import_spec.js +13 -12
- package/dist/tools/import_spec.js.map +1 -1
- package/dist/tools/list_runs.d.ts +39 -0
- package/dist/tools/list_runs.js +51 -0
- package/dist/tools/list_runs.js.map +1 -0
- package/dist/tools/list_specs.d.ts +30 -0
- package/dist/tools/list_specs.js +58 -0
- package/dist/tools/list_specs.js.map +1 -0
- package/dist/tools/list_workflows.js +8 -6
- package/dist/tools/list_workflows.js.map +1 -1
- package/dist/tools/run_all_workflows.d.ts +61 -0
- package/dist/tools/run_all_workflows.js +62 -0
- package/dist/tools/run_all_workflows.js.map +1 -0
- package/dist/tools/run_workflow.js +9 -7
- package/dist/tools/run_workflow.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Turn any OpenAPI spec into a working sandbox your AI agent can use, right from your IDE.
|
|
4
4
|
|
|
5
|
-
This is the Model Context Protocol (MCP) server for [FetchSandbox](https://fetchsandbox.com). It exposes three tools that let
|
|
5
|
+
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.
|
|
6
6
|
|
|
7
7
|
## Why
|
|
8
8
|
|
|
@@ -10,11 +10,13 @@ Agents read raw OpenAPI specs and hallucinate. They guess field names, invent ID
|
|
|
10
10
|
|
|
11
11
|
Plug it into your IDE once, and any time you ask your agent "let me try the Stripe API" or "show me the GitHub issue lifecycle," it can do that — for real, end-to-end.
|
|
12
12
|
|
|
13
|
-
## Install
|
|
13
|
+
## Install — by agent
|
|
14
14
|
|
|
15
|
-
The MCP runs as a stdio process spawned by your IDE. There's nothing to install globally — `npx` runs the latest published version on demand.
|
|
15
|
+
The MCP runs as a stdio process spawned by your IDE. There's nothing to install globally — `npx` runs the latest published version on demand. Pick your tool below, paste the snippet, restart.
|
|
16
16
|
|
|
17
|
-
### Claude
|
|
17
|
+
### Claude Desktop
|
|
18
|
+
|
|
19
|
+
File: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows)
|
|
18
20
|
|
|
19
21
|
```json
|
|
20
22
|
{
|
|
@@ -27,7 +29,28 @@ The MCP runs as a stdio process spawned by your IDE. There's nothing to install
|
|
|
27
29
|
}
|
|
28
30
|
```
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
Quit and reopen Claude Desktop (Cmd+Q, then reopen — not just close window).
|
|
33
|
+
|
|
34
|
+
### Claude Code
|
|
35
|
+
|
|
36
|
+
User-level (all projects): `~/.claude/settings.json`. Or project-level: `.mcp.json` in the repo root.
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"mcpServers": {
|
|
41
|
+
"fetchsandbox": {
|
|
42
|
+
"command": "npx",
|
|
43
|
+
"args": ["-y", "fetchsandbox-mcp"]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Restart the Claude Code session.
|
|
50
|
+
|
|
51
|
+
### Cursor
|
|
52
|
+
|
|
53
|
+
File: `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project)
|
|
31
54
|
|
|
32
55
|
```json
|
|
33
56
|
{
|
|
@@ -40,7 +63,107 @@ The MCP runs as a stdio process spawned by your IDE. There's nothing to install
|
|
|
40
63
|
}
|
|
41
64
|
```
|
|
42
65
|
|
|
43
|
-
Restart
|
|
66
|
+
Restart Cursor.
|
|
67
|
+
|
|
68
|
+
### Cline (VS Code extension)
|
|
69
|
+
|
|
70
|
+
Open the Cline panel → settings cog → MCP Servers → add a new server with:
|
|
71
|
+
|
|
72
|
+
- Command: `npx`
|
|
73
|
+
- Args: `-y fetchsandbox-mcp`
|
|
74
|
+
|
|
75
|
+
Reload the VS Code window.
|
|
76
|
+
|
|
77
|
+
### Continue.dev
|
|
78
|
+
|
|
79
|
+
File: `~/.continue/config.yaml`
|
|
80
|
+
|
|
81
|
+
```yaml
|
|
82
|
+
mcpServers:
|
|
83
|
+
- name: fetchsandbox
|
|
84
|
+
command: npx
|
|
85
|
+
args:
|
|
86
|
+
- -y
|
|
87
|
+
- fetchsandbox-mcp
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Restart your IDE.
|
|
91
|
+
|
|
92
|
+
### Codex CLI (OpenAI)
|
|
93
|
+
|
|
94
|
+
File: `~/.codex/config.toml`
|
|
95
|
+
|
|
96
|
+
```toml
|
|
97
|
+
[mcp_servers.fetchsandbox]
|
|
98
|
+
command = "npx"
|
|
99
|
+
args = ["-y", "fetchsandbox-mcp"]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Restart Codex.
|
|
103
|
+
|
|
104
|
+
### Zed
|
|
105
|
+
|
|
106
|
+
File: `~/.config/zed/settings.json`
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"context_servers": {
|
|
111
|
+
"fetchsandbox": {
|
|
112
|
+
"command": {
|
|
113
|
+
"path": "npx",
|
|
114
|
+
"args": ["-y", "fetchsandbox-mcp"]
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### GitHub Copilot
|
|
122
|
+
|
|
123
|
+
GitHub Copilot doesn't currently support the Model Context Protocol. Track [github/copilot#feedback](https://github.com/orgs/community/discussions) for updates. In the meantime, run any MCP-compatible chat (Claude Code, Cursor, Cline) alongside Copilot.
|
|
124
|
+
|
|
125
|
+
### Anything else (Roo, Goose, etc.)
|
|
126
|
+
|
|
127
|
+
If your agent speaks MCP, it accepts a stdio command. Use:
|
|
128
|
+
|
|
129
|
+
- Command: `npx`
|
|
130
|
+
- Args: `["-y", "fetchsandbox-mcp"]`
|
|
131
|
+
|
|
132
|
+
## Try it now
|
|
133
|
+
|
|
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
|
+
|
|
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.
|
|
139
|
+
|
|
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`).
|
|
141
|
+
|
|
142
|
+
### Twilio — send an SMS
|
|
143
|
+
|
|
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.
|
|
145
|
+
|
|
146
|
+
The agent imports the messaging API and runs a curated send-and-verify flow with realistic Twilio-formatted message SIDs (`SM…`).
|
|
147
|
+
|
|
148
|
+
### GitHub — issue lifecycle
|
|
149
|
+
|
|
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.
|
|
151
|
+
|
|
152
|
+
The agent walks the create → comment → close → reopen flow against a real-shaped GitHub sandbox.
|
|
153
|
+
|
|
154
|
+
### Paddle — paste-content variant
|
|
155
|
+
|
|
156
|
+
If a vendor doesn't publish their spec at a stable URL (Paddle, Notion, Linear), paste the content directly:
|
|
157
|
+
|
|
158
|
+
> Here's the Paddle Billing OpenAPI spec — `<paste JSON or YAML>`. Use fetchsandbox to import it and run the `subscriptions_canceled` workflow.
|
|
159
|
+
|
|
160
|
+
Same engine path; same curated quality if the spec's `info.title` matches a bundled config.
|
|
161
|
+
|
|
162
|
+
### Any other API
|
|
163
|
+
|
|
164
|
+
> Use fetchsandbox to import `<your OpenAPI URL>` — list the workflows and tell me which is most interesting.
|
|
165
|
+
|
|
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.
|
|
44
167
|
|
|
45
168
|
## Tools
|
|
46
169
|
|
|
@@ -54,7 +177,7 @@ content: "<paste OpenAPI JSON or YAML here>"
|
|
|
54
177
|
name: "Optional friendly name"
|
|
55
178
|
```
|
|
56
179
|
|
|
57
|
-
Returns `spec_id`, `sandbox_id`, `base_url` (proxy that serves real-shaped responses),
|
|
180
|
+
Returns `spec_id`, `sandbox_id`, `base_url` (proxy that serves real-shaped responses), `workflows_preview` (first 10), `matched_bundled` (true if we matched a curated config), and a `dashboard_url` to view everything in the browser.
|
|
58
181
|
|
|
59
182
|
### `list_workflows`
|
|
60
183
|
|
|
@@ -90,16 +213,6 @@ To opt out:
|
|
|
90
213
|
export FETCHSANDBOX_TELEMETRY=0
|
|
91
214
|
```
|
|
92
215
|
|
|
93
|
-
## Example session
|
|
94
|
-
|
|
95
|
-
> **You:** Try the Stripe API. Use this spec: https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json
|
|
96
|
-
>
|
|
97
|
-
> **Agent:** *(calls `import_spec`)* Imported. 471 endpoints, 12 workflows including customer-create, subscription-lifecycle, refund-flow.
|
|
98
|
-
>
|
|
99
|
-
> **You:** Run the subscription-lifecycle one.
|
|
100
|
-
>
|
|
101
|
-
> **Agent:** *(calls `run_workflow`)* All 5 steps passed: created customer (cus_LJ4nQ...), attached payment method (pm_8K2...), created subscription (sub_R6F...), updated to a different price (sub.items.0 swap), canceled subscription. Here's the trace: ...
|
|
102
|
-
|
|
103
216
|
## License
|
|
104
217
|
|
|
105
218
|
MIT — see [LICENSE](LICENSE).
|
package/dist/client.js
CHANGED
|
@@ -28,7 +28,7 @@ export function getBaseUrl() {
|
|
|
28
28
|
}
|
|
29
29
|
function buildHeaders(extra) {
|
|
30
30
|
const headers = {
|
|
31
|
-
"user-agent": `fetchsandbox-mcp/0.
|
|
31
|
+
"user-agent": `fetchsandbox-mcp/0.3.0 (node ${process.version})`,
|
|
32
32
|
accept: "application/json",
|
|
33
33
|
...(extra ?? {}),
|
|
34
34
|
};
|
package/dist/index.js
CHANGED
|
@@ -17,12 +17,22 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
17
17
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
18
18
|
import { ToolError, getBaseUrl } from "./client.js";
|
|
19
19
|
import { importSpecTool, runImportSpec } from "./tools/import_spec.js";
|
|
20
|
+
import { listSpecsTool, runListSpecs } from "./tools/list_specs.js";
|
|
20
21
|
import { listWorkflowsTool, runListWorkflows } from "./tools/list_workflows.js";
|
|
22
|
+
import { listRunsTool, runListRuns } from "./tools/list_runs.js";
|
|
21
23
|
import { runRunWorkflow, runWorkflowTool } from "./tools/run_workflow.js";
|
|
22
|
-
|
|
24
|
+
import { runRunAllWorkflows, runAllWorkflowsTool } from "./tools/run_all_workflows.js";
|
|
25
|
+
const VERSION = "0.3.0";
|
|
23
26
|
const server = new Server({ name: "fetchsandbox", version: VERSION }, { capabilities: { tools: {} } });
|
|
24
27
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
25
|
-
tools: [
|
|
28
|
+
tools: [
|
|
29
|
+
listSpecsTool,
|
|
30
|
+
importSpecTool,
|
|
31
|
+
listWorkflowsTool,
|
|
32
|
+
runAllWorkflowsTool,
|
|
33
|
+
runWorkflowTool,
|
|
34
|
+
listRunsTool,
|
|
35
|
+
],
|
|
26
36
|
}));
|
|
27
37
|
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
28
38
|
const { name, arguments: args } = req.params;
|
|
@@ -30,6 +40,11 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
30
40
|
let result;
|
|
31
41
|
const a = (args ?? {});
|
|
32
42
|
switch (name) {
|
|
43
|
+
case listSpecsTool.name:
|
|
44
|
+
result = await runListSpecs({
|
|
45
|
+
filter: typeof a.filter === "string" ? a.filter : undefined,
|
|
46
|
+
});
|
|
47
|
+
break;
|
|
33
48
|
case importSpecTool.name:
|
|
34
49
|
result = await runImportSpec({
|
|
35
50
|
url: typeof a.url === "string" ? a.url : undefined,
|
|
@@ -42,12 +57,26 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
42
57
|
spec_id: typeof a.spec_id === "string" ? a.spec_id : "",
|
|
43
58
|
});
|
|
44
59
|
break;
|
|
60
|
+
case listRunsTool.name:
|
|
61
|
+
result = await runListRuns({
|
|
62
|
+
sandbox_id: typeof a.sandbox_id === "string" ? a.sandbox_id : "",
|
|
63
|
+
limit: typeof a.limit === "number" ? a.limit : undefined,
|
|
64
|
+
});
|
|
65
|
+
break;
|
|
45
66
|
case runWorkflowTool.name:
|
|
46
67
|
result = await runRunWorkflow({
|
|
47
68
|
sandbox_id: typeof a.sandbox_id === "string" ? a.sandbox_id : "",
|
|
48
69
|
workflow_name: typeof a.workflow_name === "string" ? a.workflow_name : "",
|
|
49
70
|
});
|
|
50
71
|
break;
|
|
72
|
+
case runAllWorkflowsTool.name:
|
|
73
|
+
result = await runRunAllWorkflows({
|
|
74
|
+
sandbox_id: typeof a.sandbox_id === "string" ? a.sandbox_id : "",
|
|
75
|
+
workflow_names: Array.isArray(a.workflow_names)
|
|
76
|
+
? a.workflow_names.filter((x) => typeof x === "string")
|
|
77
|
+
: undefined,
|
|
78
|
+
});
|
|
79
|
+
break;
|
|
51
80
|
default:
|
|
52
81
|
throw new ToolError(`Unknown tool: ${name}`);
|
|
53
82
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,16 +2,16 @@ import { postJson, ToolError } from "../client.js";
|
|
|
2
2
|
export const importSpecTool = {
|
|
3
3
|
name: "import_spec",
|
|
4
4
|
description: "Ingest an OpenAPI spec and get a working sandbox you can call immediately. " +
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
5
|
+
"REQUIRED: pass EITHER `url` OR `content` — never just `name` alone (name is " +
|
|
6
|
+
"a display label, not a lookup). If the user mentions a popular API by name " +
|
|
7
|
+
"(Stripe, GitHub, Twilio, Notion, OpenAI, etc.), FIRST call `list_specs` " +
|
|
8
|
+
"with a filter to confirm it's in the catalog, then call import_spec with " +
|
|
9
|
+
"that vendor's public OpenAPI URL (e.g. Stripe: " +
|
|
10
|
+
"https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json). " +
|
|
11
|
+
"The backend content-hashes the spec and auto-matches to the bundled sandbox " +
|
|
12
|
+
"when applicable. Returns sandbox_id, workflows_preview, and a base_url that " +
|
|
13
|
+
"proxies schema-validated responses. Private URLs (localhost, 10.x, 192.168.x) " +
|
|
14
|
+
"are rejected by the backend — use `content` to paste those inline.",
|
|
15
15
|
inputSchema: {
|
|
16
16
|
type: "object",
|
|
17
17
|
properties: {
|
|
@@ -27,8 +27,9 @@ export const importSpecTool = {
|
|
|
27
27
|
},
|
|
28
28
|
name: {
|
|
29
29
|
type: "string",
|
|
30
|
-
description: "Optional
|
|
31
|
-
"
|
|
30
|
+
description: "Optional DISPLAY label only — NOT a lookup key. Defaults to " +
|
|
31
|
+
"info.title from the spec. To resolve a known API by name " +
|
|
32
|
+
"(\"Stripe\", \"GitHub\"), call list_specs first.",
|
|
32
33
|
},
|
|
33
34
|
},
|
|
34
35
|
additionalProperties: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import_spec.js","sourceRoot":"","sources":["../../src/tools/import_spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA8BnD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,6EAA6E;QAC7E
|
|
1
|
+
{"version":3,"file":"import_spec.js","sourceRoot":"","sources":["../../src/tools/import_spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA8BnD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,6EAA6E;QAC7E,8EAA8E;QAC9E,6EAA6E;QAC7E,0EAA0E;QAC1E,2EAA2E;QAC3E,iDAAiD;QACjD,+EAA+E;QAC/E,8EAA8E;QAC9E,8EAA8E;QAC9E,gFAAgF;QAChF,oEAAoE;IACtE,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,GAAG,EAAE;gBACH,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,qEAAqE;oBACrE,wEAAwE;aAC3E;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,qEAAqE;oBACrE,yEAAyE;aAC5E;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,8DAA8D;oBAC9D,2DAA2D;oBAC3D,kDAAkD;aACrD;SACF;QACD,oBAAoB,EAAE,KAAK;KAC5B;CACO,CAAC;AAEX,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAsB;IACxD,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAC/B,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,QAAQ,CAAqB,sBAAsB,EAAE,KAAK,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface ListRunsInput {
|
|
2
|
+
sandbox_id: string;
|
|
3
|
+
limit?: number;
|
|
4
|
+
}
|
|
5
|
+
export interface RunSummary {
|
|
6
|
+
flow_run_id: string;
|
|
7
|
+
workflow_name: string;
|
|
8
|
+
status: string;
|
|
9
|
+
started_at: string;
|
|
10
|
+
last_activity_at: string;
|
|
11
|
+
request_count: number;
|
|
12
|
+
webhook_count: number;
|
|
13
|
+
share_url: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ListRunsResponse {
|
|
16
|
+
sandbox_id: string;
|
|
17
|
+
total: number;
|
|
18
|
+
runs: RunSummary[];
|
|
19
|
+
}
|
|
20
|
+
export declare const listRunsTool: {
|
|
21
|
+
readonly name: "list_runs";
|
|
22
|
+
readonly description: string;
|
|
23
|
+
readonly inputSchema: {
|
|
24
|
+
readonly type: "object";
|
|
25
|
+
readonly properties: {
|
|
26
|
+
readonly sandbox_id: {
|
|
27
|
+
readonly type: "string";
|
|
28
|
+
readonly description: "The sandbox_id returned by import_spec.";
|
|
29
|
+
};
|
|
30
|
+
readonly limit: {
|
|
31
|
+
readonly type: "number";
|
|
32
|
+
readonly description: "Max number of runs to return (default 20, server may cap).";
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
readonly required: readonly ["sandbox_id"];
|
|
36
|
+
readonly additionalProperties: false;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export declare function runListRuns(input: ListRunsInput): Promise<ListRunsResponse>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { getJson, ToolError } from "../client.js";
|
|
2
|
+
export const listRunsTool = {
|
|
3
|
+
name: "list_runs",
|
|
4
|
+
description: "List recent workflow runs (and ad-hoc traffic) for a sandbox, newest " +
|
|
5
|
+
"first. Use when the user asks 'what did I run', 'show me recent " +
|
|
6
|
+
"validation runs', 'did the stripe test pass earlier', or wants to " +
|
|
7
|
+
"find a previous run to share or re-inspect. Each run includes its " +
|
|
8
|
+
"shareable timeline URL (fetchsandbox.com/runs/<sandbox_id>) so the " +
|
|
9
|
+
"user can open the visual trace in a browser or drop it in Slack / a " +
|
|
10
|
+
"PR comment. Requires sandbox_id (from import_spec).",
|
|
11
|
+
inputSchema: {
|
|
12
|
+
type: "object",
|
|
13
|
+
properties: {
|
|
14
|
+
sandbox_id: {
|
|
15
|
+
type: "string",
|
|
16
|
+
description: "The sandbox_id returned by import_spec.",
|
|
17
|
+
},
|
|
18
|
+
limit: {
|
|
19
|
+
type: "number",
|
|
20
|
+
description: "Max number of runs to return (default 20, server may cap).",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
required: ["sandbox_id"],
|
|
24
|
+
additionalProperties: false,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
export async function runListRuns(input) {
|
|
28
|
+
if (!input.sandbox_id)
|
|
29
|
+
throw new ToolError("sandbox_id is required.");
|
|
30
|
+
const limit = Math.min(Math.max(input.limit ?? 20, 1), 100);
|
|
31
|
+
const path = `/api/sandboxes/${encodeURIComponent(input.sandbox_id)}/flows?limit=${limit}`;
|
|
32
|
+
const raw = await getJson(path);
|
|
33
|
+
const flows = Array.isArray(raw.flows) ? raw.flows : [];
|
|
34
|
+
const shareBase = `https://fetchsandbox.com/runs/${encodeURIComponent(input.sandbox_id)}`;
|
|
35
|
+
const runs = flows.map((f) => ({
|
|
36
|
+
flow_run_id: f.flow_run_id,
|
|
37
|
+
workflow_name: f.workflow?.name || f.workflow?.id || "(ad-hoc)",
|
|
38
|
+
status: f.status || "unknown",
|
|
39
|
+
started_at: f.started_at || "",
|
|
40
|
+
last_activity_at: f.last_activity_at || "",
|
|
41
|
+
request_count: f.event_counts?.request ?? 0,
|
|
42
|
+
webhook_count: f.event_counts?.webhook ?? 0,
|
|
43
|
+
share_url: `${shareBase}#${encodeURIComponent(f.flow_run_id)}`,
|
|
44
|
+
}));
|
|
45
|
+
return {
|
|
46
|
+
sandbox_id: input.sandbox_id,
|
|
47
|
+
total: raw.total_count ?? runs.length,
|
|
48
|
+
runs,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=list_runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list_runs.js","sourceRoot":"","sources":["../../src/tools/list_runs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAsClD,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,WAAW;IACjB,WAAW,EACT,uEAAuE;QACvE,kEAAkE;QAClE,oEAAoE;QACpE,oEAAoE;QACpE,qEAAqE;QACrE,sEAAsE;QACtE,qDAAqD;IACvD,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yCAAyC;aACvD;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,4DAA4D;aAC/D;SACF;QACD,QAAQ,EAAE,CAAC,YAAY,CAAC;QACxB,oBAAoB,EAAE,KAAK;KAC5B;CACO,CAAC;AAEX,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAAoB;IAEpB,IAAI,CAAC,KAAK,CAAC,UAAU;QAAE,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,gBAAgB,KAAK,EAAE,CAAC;IAC3F,MAAM,GAAG,GAAG,MAAM,OAAO,CAAuB,IAAI,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,MAAM,SAAS,GAAG,iCAAiC,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;IAC1F,MAAM,IAAI,GAAiB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3C,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,aAAa,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,IAAI,UAAU;QAC/D,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,SAAS;QAC7B,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE;QAC9B,gBAAgB,EAAE,CAAC,CAAC,gBAAgB,IAAI,EAAE;QAC1C,aAAa,EAAE,CAAC,CAAC,YAAY,EAAE,OAAO,IAAI,CAAC;QAC3C,aAAa,EAAE,CAAC,CAAC,YAAY,EAAE,OAAO,IAAI,CAAC;QAC3C,SAAS,EAAE,GAAG,SAAS,IAAI,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE;KAC/D,CAAC,CAAC,CAAC;IACJ,OAAO;QACL,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,KAAK,EAAE,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM;QACrC,IAAI;KACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface ListSpecsInput {
|
|
2
|
+
filter?: string;
|
|
3
|
+
}
|
|
4
|
+
export interface SpecSummary {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
slug: string;
|
|
8
|
+
description: string;
|
|
9
|
+
endpoints_count: number;
|
|
10
|
+
tags: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface ListSpecsResponse {
|
|
13
|
+
total: number;
|
|
14
|
+
specs: SpecSummary[];
|
|
15
|
+
}
|
|
16
|
+
export declare const listSpecsTool: {
|
|
17
|
+
readonly name: "list_specs";
|
|
18
|
+
readonly description: string;
|
|
19
|
+
readonly inputSchema: {
|
|
20
|
+
readonly type: "object";
|
|
21
|
+
readonly properties: {
|
|
22
|
+
readonly filter: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
readonly description: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
readonly additionalProperties: false;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export declare function runListSpecs(input: ListSpecsInput): Promise<ListSpecsResponse>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getJson, ToolError } from "../client.js";
|
|
2
|
+
export const listSpecsTool = {
|
|
3
|
+
name: "list_specs",
|
|
4
|
+
description: "Browse the FetchSandbox spec catalog — every API (Stripe, GitHub, " +
|
|
5
|
+
"Twilio, Notion, OpenAI, Polar, GitLab, and 40+ more) that has a " +
|
|
6
|
+
"ready-to-use sandbox with curated workflows. Use when the user asks " +
|
|
7
|
+
"'what APIs do you support?', 'what specs are available?', 'show me " +
|
|
8
|
+
"the catalog', 'do you have <X>?', or wants to explore before " +
|
|
9
|
+
"committing to one. Returns each spec's slug (use as `name` arg to " +
|
|
10
|
+
"import_spec), description, endpoint count, and tags. Pass `filter` to " +
|
|
11
|
+
"narrow by substring (e.g., filter='pay' returns Stripe, Paddle, " +
|
|
12
|
+
"Polar).",
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {
|
|
16
|
+
filter: {
|
|
17
|
+
type: "string",
|
|
18
|
+
description: "Optional case-insensitive substring filter. Matches against " +
|
|
19
|
+
"spec name, slug, description, and tags. Omit to return the full " +
|
|
20
|
+
"catalog.",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
additionalProperties: false,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export async function runListSpecs(input) {
|
|
27
|
+
const raw = await getJson("/api/specs");
|
|
28
|
+
if (!Array.isArray(raw)) {
|
|
29
|
+
throw new ToolError("Backend returned unexpected shape for /api/specs.");
|
|
30
|
+
}
|
|
31
|
+
const all = raw.map((s) => ({
|
|
32
|
+
id: s.id,
|
|
33
|
+
name: s.name || s.slug || s.id,
|
|
34
|
+
slug: s.slug || "",
|
|
35
|
+
description: s.description || "",
|
|
36
|
+
endpoints_count: s.endpoints_count ?? 0,
|
|
37
|
+
tags: Array.isArray(s.tags) ? s.tags.slice(0, 12) : [],
|
|
38
|
+
}));
|
|
39
|
+
const filter = (input.filter || "").trim().toLowerCase();
|
|
40
|
+
const specs = filter
|
|
41
|
+
? all.filter((s) => {
|
|
42
|
+
const hay = [
|
|
43
|
+
s.name,
|
|
44
|
+
s.slug,
|
|
45
|
+
s.description,
|
|
46
|
+
...s.tags,
|
|
47
|
+
]
|
|
48
|
+
.join(" ")
|
|
49
|
+
.toLowerCase();
|
|
50
|
+
return hay.includes(filter);
|
|
51
|
+
})
|
|
52
|
+
: all;
|
|
53
|
+
return {
|
|
54
|
+
total: specs.length,
|
|
55
|
+
specs,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=list_specs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list_specs.js","sourceRoot":"","sources":["../../src/tools/list_specs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA+BlD,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,YAAY;IAClB,WAAW,EACT,oEAAoE;QACpE,kEAAkE;QAClE,sEAAsE;QACtE,qEAAqE;QACrE,+DAA+D;QAC/D,oEAAoE;QACpE,wEAAwE;QACxE,kEAAkE;QAClE,SAAS;IACX,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,8DAA8D;oBAC9D,kEAAkE;oBAClE,UAAU;aACb;SACF;QACD,oBAAoB,EAAE,KAAK;KAC5B;CACO,CAAC;AAEX,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAqB;IAErB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAgB,YAAY,CAAC,CAAC;IACvD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,GAAG,GAAkB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzC,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE;QAC9B,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;QAClB,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;QAChC,eAAe,EAAE,CAAC,CAAC,eAAe,IAAI,CAAC;QACvC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;KACvD,CAAC,CAAC,CAAC;IACJ,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzD,MAAM,KAAK,GAAG,MAAM;QAClB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACf,MAAM,GAAG,GAAG;gBACV,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,WAAW;gBACb,GAAG,CAAC,CAAC,IAAI;aACV;iBACE,IAAI,CAAC,GAAG,CAAC;iBACT,WAAW,EAAE,CAAC;YACjB,OAAO,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC,CAAC;QACJ,CAAC,CAAC,GAAG,CAAC;IACR,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,KAAK;KACN,CAAC;AACJ,CAAC"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { getJson, ToolError } from "../client.js";
|
|
2
2
|
export const listWorkflowsTool = {
|
|
3
3
|
name: "list_workflows",
|
|
4
|
-
description: "List the named, runnable workflows
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
4
|
+
description: "List the named, runnable workflows for a previously-imported spec. " +
|
|
5
|
+
"Workflows are realistic multi-step API journeys (e.g. 'create customer " +
|
|
6
|
+
"→ attach payment method → create subscription'). Use this after " +
|
|
7
|
+
"import_spec for exploration (\"what can I do?\", \"show me the flows\") " +
|
|
8
|
+
"OR before run_all_workflows when the user wants a SCOPED validation: " +
|
|
9
|
+
"list, filter by user intent (\"checkout\", \"webhooks\"), then pass the " +
|
|
10
|
+
"matching ids as `workflow_names` to run_all_workflows. " +
|
|
11
|
+
"Returns: id, name, description, and step count per workflow.",
|
|
10
12
|
inputSchema: {
|
|
11
13
|
type: "object",
|
|
12
14
|
properties: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list_workflows.js","sourceRoot":"","sources":["../../src/tools/list_workflows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA2BlD,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,0EAA0E;QAC1E,
|
|
1
|
+
{"version":3,"file":"list_workflows.js","sourceRoot":"","sources":["../../src/tools/list_workflows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA2BlD,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,qEAAqE;QACrE,yEAAyE;QACzE,kEAAkE;QAClE,0EAA0E;QAC1E,uEAAuE;QACvE,0EAA0E;QAC1E,yDAAyD;QACzD,8DAA8D;IAChE,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,sCAAsC;aACpD;SACF;QACD,QAAQ,EAAE,CAAC,SAAS,CAAC;QACrB,oBAAoB,EAAE,KAAK;KAC5B;CACO,CAAC;AAEX,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAyB;IAC9D,IAAI,CAAC,KAAK,CAAC,OAAO;QAAE,MAAM,IAAI,SAAS,CAAC,sBAAsB,CAAC,CAAC;IAChE,MAAM,GAAG,GAAG,MAAM,OAAO,CACvB,cAAc,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAC5D,CAAC;IACF,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,SAAS,EAAE,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3C,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE;YACxB,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE;YAC1B,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;YAChC,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;SACzD,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export interface RunAllWorkflowsInput {
|
|
2
|
+
sandbox_id: string;
|
|
3
|
+
workflow_names?: string[];
|
|
4
|
+
}
|
|
5
|
+
interface BatchStepResult {
|
|
6
|
+
name?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
status?: string;
|
|
9
|
+
detail?: string;
|
|
10
|
+
duration_ms?: number;
|
|
11
|
+
data?: unknown;
|
|
12
|
+
}
|
|
13
|
+
interface BatchWorkflowResult {
|
|
14
|
+
workflow_id: string;
|
|
15
|
+
name?: string;
|
|
16
|
+
passed: boolean;
|
|
17
|
+
steps_total?: number;
|
|
18
|
+
steps_passed?: number;
|
|
19
|
+
total_duration_ms?: number;
|
|
20
|
+
steps?: BatchStepResult[];
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface NormalizedBatchResult {
|
|
24
|
+
sandbox_id: string;
|
|
25
|
+
total: number;
|
|
26
|
+
passed: number;
|
|
27
|
+
failed: number;
|
|
28
|
+
duration_ms: number;
|
|
29
|
+
summary: Array<{
|
|
30
|
+
workflow_id: string;
|
|
31
|
+
status: "pass" | "fail";
|
|
32
|
+
steps_passed: number;
|
|
33
|
+
steps_total: number;
|
|
34
|
+
duration_ms: number;
|
|
35
|
+
}>;
|
|
36
|
+
results: BatchWorkflowResult[];
|
|
37
|
+
}
|
|
38
|
+
export declare const runAllWorkflowsTool: {
|
|
39
|
+
readonly name: "run_all_workflows";
|
|
40
|
+
readonly description: string;
|
|
41
|
+
readonly inputSchema: {
|
|
42
|
+
readonly type: "object";
|
|
43
|
+
readonly properties: {
|
|
44
|
+
readonly sandbox_id: {
|
|
45
|
+
readonly type: "string";
|
|
46
|
+
readonly description: "The sandbox_id returned by import_spec.";
|
|
47
|
+
};
|
|
48
|
+
readonly workflow_names: {
|
|
49
|
+
readonly type: "array";
|
|
50
|
+
readonly items: {
|
|
51
|
+
readonly type: "string";
|
|
52
|
+
};
|
|
53
|
+
readonly description: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
readonly required: readonly ["sandbox_id"];
|
|
57
|
+
readonly additionalProperties: false;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
export declare function runRunAllWorkflows(input: RunAllWorkflowsInput): Promise<NormalizedBatchResult>;
|
|
61
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { postJson, ToolError } from "../client.js";
|
|
2
|
+
export const runAllWorkflowsTool = {
|
|
3
|
+
name: "run_all_workflows",
|
|
4
|
+
description: "Execute EVERY workflow (or a scoped subset) for a sandbox in ONE call. " +
|
|
5
|
+
"Use this — NOT a loop of run_workflow — for any validation-style request: " +
|
|
6
|
+
"\"validate this integration\", \"run all workflows\", \"check coverage\", " +
|
|
7
|
+
"\"test stripe checkout\", \"fs validate\". IDEs (Cursor, Claude Code) " +
|
|
8
|
+
"approve each MCP call individually, so 18 workflows via run_workflow = " +
|
|
9
|
+
"18 clicks. This tool = 1 click, total. " +
|
|
10
|
+
"Scope via `workflow_names`: pass an array of workflow ids to run a " +
|
|
11
|
+
"subset (e.g., user says \"validate stripe CHECKOUT\" → pass " +
|
|
12
|
+
"[\"create_checkout_session\", \"checkout_complete\"]). Names are " +
|
|
13
|
+
"case-insensitive; dashes and underscores interchangeable. " +
|
|
14
|
+
"Returns: summary (pass/fail counts, totals) + full step trace per " +
|
|
15
|
+
"workflow. After running, the user can visit " +
|
|
16
|
+
"fetchsandbox.com/runs/<sandbox_id> for a shareable visual timeline.",
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
sandbox_id: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "The sandbox_id returned by import_spec.",
|
|
23
|
+
},
|
|
24
|
+
workflow_names: {
|
|
25
|
+
type: "array",
|
|
26
|
+
items: { type: "string" },
|
|
27
|
+
description: "Optional list of workflow ids/names to run. Case-insensitive; " +
|
|
28
|
+
"dashes and underscores are interchangeable. Omit to run every " +
|
|
29
|
+
"workflow for the spec.",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
required: ["sandbox_id"],
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
export async function runRunAllWorkflows(input) {
|
|
37
|
+
if (!input.sandbox_id)
|
|
38
|
+
throw new ToolError("sandbox_id is required.");
|
|
39
|
+
const path = `/api/sandboxes/${encodeURIComponent(input.sandbox_id)}/workflows/run-all`;
|
|
40
|
+
const body = {};
|
|
41
|
+
if (input.workflow_names && input.workflow_names.length > 0) {
|
|
42
|
+
body.workflow_names = input.workflow_names;
|
|
43
|
+
}
|
|
44
|
+
const raw = await postJson(path, body);
|
|
45
|
+
const summary = (raw.results ?? []).map((r) => ({
|
|
46
|
+
workflow_id: r.workflow_id,
|
|
47
|
+
status: r.passed ? "pass" : "fail",
|
|
48
|
+
steps_passed: r.steps_passed ?? 0,
|
|
49
|
+
steps_total: r.steps_total ?? 0,
|
|
50
|
+
duration_ms: r.total_duration_ms ?? 0,
|
|
51
|
+
}));
|
|
52
|
+
return {
|
|
53
|
+
sandbox_id: raw.sandbox_id,
|
|
54
|
+
total: raw.total,
|
|
55
|
+
passed: raw.passed,
|
|
56
|
+
failed: raw.failed,
|
|
57
|
+
duration_ms: raw.duration_ms,
|
|
58
|
+
summary,
|
|
59
|
+
results: raw.results ?? [],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=run_all_workflows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run_all_workflows.js","sourceRoot":"","sources":["../../src/tools/run_all_workflows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAqDnD,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,mBAAmB;IACzB,WAAW,EACT,yEAAyE;QACzE,4EAA4E;QAC5E,4EAA4E;QAC5E,wEAAwE;QACxE,yEAAyE;QACzE,yCAAyC;QACzC,qEAAqE;QACrE,8DAA8D;QAC9D,mEAAmE;QACnE,4DAA4D;QAC5D,oEAAoE;QACpE,8CAA8C;QAC9C,qEAAqE;IACvE,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yCAAyC;aACvD;YACD,cAAc,EAAE;gBACd,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,WAAW,EACT,gEAAgE;oBAChE,gEAAgE;oBAChE,wBAAwB;aAC3B;SACF;QACD,QAAQ,EAAE,CAAC,YAAY,CAAC;QACxB,oBAAoB,EAAE,KAAK;KAC5B;CACO,CAAC;AAEX,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAA2B;IAE3B,IAAI,CAAC,KAAK,CAAC,UAAU;QAAE,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACtE,MAAM,IAAI,GAAG,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,oBAAoB,CAAC;IACxF,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC;IAC7C,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAuB,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9C,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAE,MAAgB,CAAC,CAAC,CAAE,MAAgB;QACxD,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,CAAC;QACjC,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC;QAC/B,WAAW,EAAE,CAAC,CAAC,iBAAiB,IAAI,CAAC;KACtC,CAAC,CAAC,CAAC;IACJ,OAAO;QACL,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,OAAO;QACP,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { postJson, ToolError } from "../client.js";
|
|
2
2
|
export const runWorkflowTool = {
|
|
3
3
|
name: "run_workflow",
|
|
4
|
-
description: "Execute
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
4
|
+
description: "Execute ONE specific workflow by name and return its step-by-step trace. " +
|
|
5
|
+
"Use ONLY when the user explicitly names a single workflow to run (e.g., " +
|
|
6
|
+
"\"run accept_payment\", \"just check the refund workflow\"). For ANY " +
|
|
7
|
+
"validation-style request — \"validate stripe\", \"check coverage\", \"run " +
|
|
8
|
+
"all workflows\", \"test this integration\", or even \"validate stripe " +
|
|
9
|
+
"checkout\" (multiple workflows match \"checkout\") — use " +
|
|
10
|
+
"`run_all_workflows` instead. The batch tool collapses N approvals to 1 " +
|
|
11
|
+
"and supports a workflow_names filter for scope. Calling this in a loop " +
|
|
12
|
+
"is an anti-pattern.",
|
|
11
13
|
inputSchema: {
|
|
12
14
|
type: "object",
|
|
13
15
|
properties: {
|
|
@@ -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,
|
|
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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fetchsandbox-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"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.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "FetchSandbox",
|