@thupham/volley-mcp 1.0.1

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.
Files changed (61) hide show
  1. package/dist/collections.d.ts +50 -0
  2. package/dist/collections.js +125 -0
  3. package/dist/collections.js.map +1 -0
  4. package/dist/curl.d.ts +14 -0
  5. package/dist/curl.js +90 -0
  6. package/dist/curl.js.map +1 -0
  7. package/dist/format.d.ts +10 -0
  8. package/dist/format.js +70 -0
  9. package/dist/format.js.map +1 -0
  10. package/dist/importers.d.ts +75 -0
  11. package/dist/importers.js +164 -0
  12. package/dist/importers.js.map +1 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.js +40 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/junit.d.ts +5 -0
  17. package/dist/junit.js +30 -0
  18. package/dist/junit.js.map +1 -0
  19. package/dist/native.d.ts +56 -0
  20. package/dist/native.js +44 -0
  21. package/dist/native.js.map +1 -0
  22. package/dist/session.d.ts +52 -0
  23. package/dist/session.js +135 -0
  24. package/dist/session.js.map +1 -0
  25. package/dist/tools/collections.d.ts +3 -0
  26. package/dist/tools/collections.js +50 -0
  27. package/dist/tools/collections.js.map +1 -0
  28. package/dist/tools/env.d.ts +3 -0
  29. package/dist/tools/env.js +33 -0
  30. package/dist/tools/env.js.map +1 -0
  31. package/dist/tools/graphql.d.ts +3 -0
  32. package/dist/tools/graphql.js +44 -0
  33. package/dist/tools/graphql.js.map +1 -0
  34. package/dist/tools/importCurl.d.ts +3 -0
  35. package/dist/tools/importCurl.js +36 -0
  36. package/dist/tools/importCurl.js.map +1 -0
  37. package/dist/tools/importers.d.ts +2 -0
  38. package/dist/tools/importers.js +62 -0
  39. package/dist/tools/importers.js.map +1 -0
  40. package/dist/tools/inspect.d.ts +3 -0
  41. package/dist/tools/inspect.js +102 -0
  42. package/dist/tools/inspect.js.map +1 -0
  43. package/dist/tools/ping.d.ts +6 -0
  44. package/dist/tools/ping.js +29 -0
  45. package/dist/tools/ping.js.map +1 -0
  46. package/dist/tools/policy.d.ts +3 -0
  47. package/dist/tools/policy.js +28 -0
  48. package/dist/tools/policy.js.map +1 -0
  49. package/dist/tools/request.d.ts +3 -0
  50. package/dist/tools/request.js +111 -0
  51. package/dist/tools/request.js.map +1 -0
  52. package/dist/tools/save.d.ts +3 -0
  53. package/dist/tools/save.js +67 -0
  54. package/dist/tools/save.js.map +1 -0
  55. package/dist/tools/stream.d.ts +3 -0
  56. package/dist/tools/stream.js +76 -0
  57. package/dist/tools/stream.js.map +1 -0
  58. package/dist/tools/ws.d.ts +3 -0
  59. package/dist/tools/ws.js +68 -0
  60. package/dist/tools/ws.js.map +1 -0
  61. package/package.json +38 -0
@@ -0,0 +1,62 @@
1
+ import { z } from "zod";
2
+ import { writeFileSync } from "node:fs";
3
+ import { extname } from "node:path";
4
+ import { stringify as stringifyYaml } from "yaml";
5
+ import { loadOpenApi, openApiToCollection, loadHar, harToCollection } from "../importers.js";
6
+ function serialize(col, path) {
7
+ if (extname(path) === ".json")
8
+ return JSON.stringify(col, null, 2);
9
+ return stringifyYaml(col);
10
+ }
11
+ export function registerImporterTools(server) {
12
+ server.registerTool("import_openapi", {
13
+ title: "Import OpenAPI to collection",
14
+ description: "Parse OpenAPI/Swagger (JSON/YAML) → Volley collection. One step per operation with 2xx assertion.",
15
+ inputSchema: {
16
+ path: z.string().describe("Path to the OpenAPI/Swagger file."),
17
+ out: z.string().optional().describe("Write the resulting collection to this path (.yaml/.yml/.json)."),
18
+ includeTags: z.array(z.string()).optional().describe("Only import operations with any of these tags."),
19
+ maxSteps: z.number().int().positive().optional().describe("Cap the number of generated steps (default 200)."),
20
+ },
21
+ }, async (args) => {
22
+ const doc = loadOpenApi(args.path);
23
+ const col = openApiToCollection(doc, { includeTags: args.includeTags, maxSteps: args.maxSteps });
24
+ if (args.out)
25
+ writeFileSync(args.out, serialize(col, args.out), "utf8");
26
+ return {
27
+ content: [
28
+ {
29
+ type: "text",
30
+ text: JSON.stringify({ imported: true, name: col.name, steps: col.steps?.length ?? 0, writtenTo: args.out ?? null }, null, 2),
31
+ },
32
+ ],
33
+ };
34
+ });
35
+ server.registerTool("import_har", {
36
+ title: "Import HAR to collection",
37
+ description: "Parse HAR file → Volley collection. Splits query/headers/body. Optional 2xx filter.",
38
+ inputSchema: {
39
+ path: z.string().describe("Path to the HAR file (.json)."),
40
+ out: z.string().optional().describe("Write the resulting collection to this path (.yaml/.yml/.json)."),
41
+ maxSteps: z.number().int().positive().optional().describe("Cap the number of generated steps (default 200)."),
42
+ only2xx: z.boolean().optional().describe("Only include requests that returned a 2xx response."),
43
+ },
44
+ }, async (args) => {
45
+ const har = loadHar(args.path);
46
+ const col = harToCollection(har, {
47
+ maxSteps: args.maxSteps,
48
+ filter: args.only2xx ? (e) => (e.response?.status ?? 0) >= 200 && (e.response?.status ?? 0) < 300 : undefined,
49
+ });
50
+ if (args.out)
51
+ writeFileSync(args.out, serialize(col, args.out), "utf8");
52
+ return {
53
+ content: [
54
+ {
55
+ type: "text",
56
+ text: JSON.stringify({ imported: true, name: col.name, steps: col.steps?.length ?? 0, writtenTo: args.out ?? null }, null, 2),
57
+ },
58
+ ],
59
+ };
60
+ });
61
+ }
62
+ //# sourceMappingURL=importers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importers.js","sourceRoot":"","sources":["../../src/tools/importers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { Session } from "../session.js";
3
+ export declare function registerInspectTool(server: McpServer, session: Session): void;
@@ -0,0 +1,102 @@
1
+ import { z } from "zod";
2
+ import { jsonQuery } from "../native.js";
3
+ /** Truncate arrays to maxItems, adding a truncation marker. Strings are capped at maxStr chars. */
4
+ function truncate(value, maxItems, maxStr) {
5
+ if (Array.isArray(value)) {
6
+ if (value.length <= maxItems)
7
+ return { value, truncated: false };
8
+ return {
9
+ value: [...value.slice(0, maxItems), `…(+${value.length - maxItems} more, use a narrower jsonpath)`],
10
+ truncated: true,
11
+ };
12
+ }
13
+ if (typeof value === "string" && value.length > maxStr) {
14
+ return { value: value.slice(0, maxStr) + `…(+${value.length - maxStr} chars)`, truncated: true };
15
+ }
16
+ if (value && typeof value === "object") {
17
+ const obj = value;
18
+ let anyTruncated = false;
19
+ const out = {};
20
+ for (const [k, v] of Object.entries(obj)) {
21
+ const r = truncate(v, maxItems, maxStr);
22
+ if (r.truncated)
23
+ anyTruncated = true;
24
+ out[k] = r.value;
25
+ }
26
+ return { value: out, truncated: anyTruncated };
27
+ }
28
+ return { value, truncated: false };
29
+ }
30
+ export function registerInspectTool(server, session) {
31
+ server.registerTool("inspect_response", {
32
+ title: "Inspect a stored response",
33
+ description: "Drill into a stored response by handle without re-running the request. " +
34
+ "Use jsonpath to pull only the slice you need. Supports RFC 9535 filters " +
35
+ "($.items[?@.id==1]) and slices ($.items[0:5]). Use double quotes in filters.",
36
+ inputSchema: {
37
+ handle: z.string().describe("responseHandle from a prior tool call."),
38
+ jsonpath: z
39
+ .string()
40
+ .optional()
41
+ .describe("RFC 9535 JSONPath. Filters need double quotes: [?@.name==\"x\"]. Omit for full body."),
42
+ maxItems: z
43
+ .number()
44
+ .int()
45
+ .positive()
46
+ .optional()
47
+ .describe("Cap array elements returned (default 50). Excess shown as truncation marker."),
48
+ maxStr: z
49
+ .number()
50
+ .int()
51
+ .positive()
52
+ .optional()
53
+ .describe("Cap string length in chars (default 2000)."),
54
+ },
55
+ }, async ({ handle, jsonpath, maxItems, maxStr }) => {
56
+ const stored = session.getStored(handle);
57
+ if (!stored) {
58
+ return {
59
+ isError: true,
60
+ content: [{ type: "text", text: `unknown handle: ${handle}` }],
61
+ };
62
+ }
63
+ // For introspect results, prefer the enriched `schema` field over raw `bodyJson`
64
+ // so the agent can query $.queries, $.mutations, $.inputTypes directly.
65
+ const body = stored.schema ??
66
+ stored.bodyJson ??
67
+ stored.bodyText ??
68
+ stored.frames ??
69
+ stored.events ??
70
+ null;
71
+ if (jsonpath) {
72
+ const result = jsonQuery(body, jsonpath);
73
+ if (result.error) {
74
+ return {
75
+ isError: true,
76
+ content: [{ type: "text", text: `jsonpath error: ${result.error}` }],
77
+ };
78
+ }
79
+ if (!result.found) {
80
+ return {
81
+ content: [{ type: "text", text: JSON.stringify({ found: false, hint: "path matched nothing" }) }],
82
+ };
83
+ }
84
+ const cap = maxItems ?? 50;
85
+ const strCap = maxStr ?? 2000;
86
+ const { value, truncated } = truncate(result.value, cap, strCap);
87
+ const out = { found: true, value };
88
+ if (truncated)
89
+ out.truncated = true;
90
+ return { content: [{ type: "text", text: JSON.stringify(session.redact(out), null, 2) }] };
91
+ }
92
+ // No jsonpath: return full body, but still cap arrays/strings.
93
+ const cap = maxItems ?? 50;
94
+ const strCap = maxStr ?? 2000;
95
+ const { value, truncated } = truncate(body, cap, strCap);
96
+ const out = { found: true, value };
97
+ if (truncated)
98
+ out.truncated = true;
99
+ return { content: [{ type: "text", text: JSON.stringify(session.redact(out), null, 2) }] };
100
+ });
101
+ }
102
+ //# sourceMappingURL=inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../src/tools/inspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ /**
3
+ * Phase 0 smoke-test tool. Proves the full round trip:
4
+ * MCP client -> TS server -> napi-rs -> Rust core -> back.
5
+ */
6
+ export declare function registerPingTool(server: McpServer): void;
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ import { ping } from "../native.js";
3
+ /**
4
+ * Phase 0 smoke-test tool. Proves the full round trip:
5
+ * MCP client -> TS server -> napi-rs -> Rust core -> back.
6
+ */
7
+ export function registerPingTool(server) {
8
+ server.registerTool("ping", {
9
+ title: "Ping the core",
10
+ description: "Round-trip smoke test that calls into the Rust core engine and returns a pong. " +
11
+ "Use to verify the MCP server and native addon are wired up correctly.",
12
+ inputSchema: {
13
+ message: z.string().describe("Text to echo back through the Rust core."),
14
+ delayMs: z
15
+ .number()
16
+ .int()
17
+ .min(0)
18
+ .max(10000)
19
+ .optional()
20
+ .describe("Optional async delay in the core, to exercise the async FFI path."),
21
+ },
22
+ }, async ({ message, delayMs }) => {
23
+ const result = await ping({ message, delayMs });
24
+ return {
25
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
26
+ };
27
+ });
28
+ }
29
+ //# sourceMappingURL=ping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ping.js","sourceRoot":"","sources":["../../src/tools/ping.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,MAAM,CAAC,YAAY,CACjB,MAAM,EACN;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,iFAAiF;YACjF,uEAAuE;QACzE,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YACxE,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,KAAK,CAAC;iBACV,QAAQ,EAAE;iBACV,QAAQ,CAAC,mEAAmE,CAAC;SACjF;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { Session } from "../session.js";
3
+ export declare function registerPolicyTool(server: McpServer, session: Session): void;
@@ -0,0 +1,28 @@
1
+ import { z } from "zod";
2
+ export function registerPolicyTool(server, session) {
3
+ server.registerTool("set_policy", {
4
+ title: "Set request policy",
5
+ description: "Configure host allow/deny lists + dry-run mode. Glob patterns: *, *.example.com.",
6
+ inputSchema: {
7
+ allow: z.array(z.string()).optional().describe("Allowed host patterns. Empty = allow any non-denied host."),
8
+ deny: z.array(z.string()).optional().describe("Denied host patterns; takes precedence over allow."),
9
+ dryRun: z.boolean().optional().describe("If true, validate requests but do not send them."),
10
+ },
11
+ }, async (args) => {
12
+ if (args.allow !== undefined)
13
+ session.policy.allow = args.allow;
14
+ if (args.deny !== undefined)
15
+ session.policy.deny = args.deny;
16
+ if (args.dryRun !== undefined)
17
+ session.policy.dryRun = args.dryRun;
18
+ return {
19
+ content: [
20
+ {
21
+ type: "text",
22
+ text: JSON.stringify({ policy: { allow: session.policy.allow, deny: session.policy.deny, dryRun: session.policy.dryRun } }, null, 2),
23
+ },
24
+ ],
25
+ };
26
+ });
27
+ }
28
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/tools/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,OAAgB;IACpE,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EAAE,kFAAkF;QAC/F,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2DAA2D,CAAC;YAC3G,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;YACnG,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC;SAC5F;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAChE,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAC7D,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACnE,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,EACrG,IAAI,EACJ,CAAC,CACF;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { Session } from "../session.js";
3
+ export declare function registerRequestTools(server: McpServer, session: Session): void;
@@ -0,0 +1,111 @@
1
+ import { z } from "zod";
2
+ import { httpRequest, graphqlRequest } from "../native.js";
3
+ import { formatHttp } from "../format.js";
4
+ const verbosity = z
5
+ .enum(["summary", "headers", "full"])
6
+ .optional()
7
+ .describe("summary (default, token-efficient), headers, or full. Auto-downgraded to summary when extract is set.");
8
+ const authSchema = z
9
+ .object({
10
+ type: z.enum(["bearer", "basic", "apikey"]),
11
+ token: z.string().optional(),
12
+ username: z.string().optional(),
13
+ password: z.string().optional(),
14
+ key: z.string().optional(),
15
+ value: z.string().optional(),
16
+ in: z.enum(["header", "query"]).optional(),
17
+ })
18
+ .optional();
19
+ const assertSchema = z
20
+ .array(z.record(z.string(), z.any()))
21
+ .optional()
22
+ .describe("e.g. [{status:200},{jsonpath:'$.x',equals:1},{timeMs:{lt:500}}].");
23
+ function textResult(session, obj) {
24
+ return { content: [{ type: "text", text: JSON.stringify(session.redact(obj), null, 2) }] };
25
+ }
26
+ /** Auto-downgrade full→summary when extract is set (extracted values already contain the needed data). */
27
+ function effectiveVerbosity(v, hasExtract) {
28
+ const verbosity = v ?? "summary";
29
+ if (hasExtract && verbosity === "full")
30
+ return "summary";
31
+ return verbosity;
32
+ }
33
+ export function registerRequestTools(server, session) {
34
+ server.registerTool("http_request", {
35
+ title: "HTTP request",
36
+ description: "REST/HTTP request with auth, assertions, {{var}} extraction. Returns token-efficient summary.",
37
+ inputSchema: {
38
+ method: z.string().optional().describe("HTTP method (default GET)."),
39
+ url: z.string().describe("Full URL. May contain {{variables}}."),
40
+ headers: z.record(z.string(), z.any()).optional(),
41
+ query: z.record(z.string(), z.any()).optional(),
42
+ body: z.any().optional().describe("Request body (object=json, string=text)."),
43
+ bodyType: z.enum(["json", "form", "text", "raw"]).optional().describe("Default json."),
44
+ auth: authSchema,
45
+ assert: assertSchema,
46
+ extract: z
47
+ .record(z.string(), z.string())
48
+ .optional()
49
+ .describe("Capture vars: { token: '$.token' }. Use via {{token}} later."),
50
+ env: z.string().optional().describe("Environment name for variable resolution."),
51
+ timeoutMs: z.number().int().positive().optional(),
52
+ followRedirects: z.boolean().optional(),
53
+ verbosity,
54
+ },
55
+ }, async (args) => {
56
+ const { env, verbosity, ...rest } = args;
57
+ const spec = { ...rest, vars: session.mergedVars(env) };
58
+ const url = String(rest.url ?? "");
59
+ const policy = session.checkPolicy(url);
60
+ if (policy && "blocked" in policy) {
61
+ return textResult(session, { ok: false, error: policy.error });
62
+ }
63
+ const hasExtract = !!rest.extract && Object.keys(rest.extract).length > 0;
64
+ const vb = effectiveVerbosity(verbosity, hasExtract);
65
+ session.recordRequest("http", rest, rest.assert, rest.extract);
66
+ if (policy && "dryRun" in policy) {
67
+ const handle = session.storeResponse(policy.result);
68
+ return textResult(session, formatHttp(policy.result, vb, handle));
69
+ }
70
+ const result = await httpRequest(spec);
71
+ session.applyExtracted(result.extracted);
72
+ const handle = session.storeResponse(result);
73
+ return textResult(session, formatHttp(result, vb, handle));
74
+ });
75
+ server.registerTool("graphql_request", {
76
+ title: "GraphQL request",
77
+ description: "GraphQL query/mutation over HTTP. Separates errors from status. Supports {{var}} extraction.",
78
+ inputSchema: {
79
+ url: z.string().describe("GraphQL endpoint URL."),
80
+ query: z.string().describe("GraphQL query/mutation document."),
81
+ variables: z.record(z.string(), z.any()).optional(),
82
+ headers: z.record(z.string(), z.any()).optional(),
83
+ auth: authSchema,
84
+ assert: assertSchema,
85
+ extract: z.record(z.string(), z.string()).optional().describe("Capture vars: { token: '$.data.login.accessToken' }."),
86
+ env: z.string().optional(),
87
+ timeoutMs: z.number().int().positive().optional(),
88
+ verbosity,
89
+ },
90
+ }, async (args) => {
91
+ const { env, verbosity, ...rest } = args;
92
+ const spec = { ...rest, vars: session.mergedVars(env) };
93
+ const url = String(rest.url ?? "");
94
+ const policy = session.checkPolicy(url);
95
+ if (policy && "blocked" in policy) {
96
+ return textResult(session, { ok: false, error: policy.error });
97
+ }
98
+ const hasExtract = !!rest.extract && Object.keys(rest.extract).length > 0;
99
+ const vb = effectiveVerbosity(verbosity, hasExtract);
100
+ session.recordRequest("graphql", rest, rest.assert, rest.extract);
101
+ if (policy && "dryRun" in policy) {
102
+ const handle = session.storeResponse(policy.result);
103
+ return textResult(session, formatHttp(policy.result, vb, handle));
104
+ }
105
+ const result = await graphqlRequest(spec);
106
+ session.applyExtracted(result.extracted);
107
+ const handle = session.storeResponse(result);
108
+ return textResult(session, formatHttp(result, vb, handle));
109
+ });
110
+ }
111
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/tools/request.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { Session } from "../session.js";
3
+ export declare function registerSaveTool(server: McpServer, session: Session): void;
@@ -0,0 +1,67 @@
1
+ import { z } from "zod";
2
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
3
+ import { extname } from "node:path";
4
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
5
+ function loadExisting(path) {
6
+ if (!existsSync(path))
7
+ return { steps: [] };
8
+ const text = readFileSync(path, "utf8");
9
+ if (extname(path) === ".json")
10
+ return JSON.parse(text);
11
+ return parseYaml(text);
12
+ }
13
+ function serialize(col, path) {
14
+ if (extname(path) === ".json")
15
+ return JSON.stringify(col, null, 2);
16
+ return stringifyYaml(col);
17
+ }
18
+ export function registerSaveTool(server, session) {
19
+ server.registerTool("save_request", {
20
+ title: "Save request to collection",
21
+ description: "Persist last ad-hoc request (or explicit spec) as a new step in a collection file.",
22
+ inputSchema: {
23
+ path: z.string().describe("Collection file path (.yaml/.yml/.json)."),
24
+ id: z.string().optional().describe("Step id. Defaults to a generated one."),
25
+ type: z.enum(["http", "graphql", "ws", "sse"]).optional().describe("Step type; defaults to the last request's type."),
26
+ request: z.record(z.string(), z.any()).optional().describe("Explicit request spec. Defaults to the last call's request."),
27
+ assert: z.array(z.record(z.string(), z.any())).optional(),
28
+ extract: z.record(z.string(), z.string()).optional(),
29
+ tags: z.array(z.string()).optional(),
30
+ name: z.string().optional().describe("Set/replace the collection name."),
31
+ },
32
+ }, async (args) => {
33
+ const last = session.consumeLastRequest();
34
+ const type = (args.type ?? last?.type ?? "http");
35
+ const request = (args.request ?? last?.request ?? {});
36
+ if (Object.keys(request).length === 0) {
37
+ return {
38
+ isError: true,
39
+ content: [{ type: "text", text: "save_request: no prior request recorded and no explicit request provided." }],
40
+ };
41
+ }
42
+ const col = loadExisting(args.path);
43
+ if (args.name)
44
+ col.name = args.name;
45
+ col.steps ??= [];
46
+ const id = args.id ?? `step-${col.steps.length + 1}`;
47
+ const step = {
48
+ id,
49
+ type,
50
+ request,
51
+ assert: args.assert ?? last?.assert,
52
+ extract: args.extract ?? last?.extract,
53
+ tags: args.tags,
54
+ };
55
+ col.steps.push(step);
56
+ writeFileSync(args.path, serialize(col, args.path), "utf8");
57
+ return {
58
+ content: [
59
+ {
60
+ type: "text",
61
+ text: JSON.stringify({ saved: true, path: args.path, stepId: id, stepCount: col.steps.length }, null, 2),
62
+ },
63
+ ],
64
+ };
65
+ });
66
+ }
67
+ //# sourceMappingURL=save.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save.js","sourceRoot":"","sources":["../../src/tools/save.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,MAAM,CAAC;AAoBtE,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC5C,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC;IACrE,OAAO,SAAS,CAAC,IAAI,CAAe,CAAC;AACvC,CAAC;AAED,SAAS,SAAS,CAAC,GAAe,EAAE,IAAY;IAC9C,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACnE,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,OAAgB;IAClE,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,4BAA4B;QACnC,WAAW,EAAE,oFAAoF;QACjG,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YACrE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;YAC3E,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;YACrH,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6DAA6D,CAAC;YACzH,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE;YACzD,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACpD,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACpC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;SACzE;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,MAAM,CAAsC,CAAC;QACtF,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,OAAO,IAAI,EAAE,CAA4B,CAAC;QACjF,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtC,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,2EAA2E,EAAE,CAAC;aACxH,CAAC;QACJ,CAAC;QAED,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACpC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC;QACjB,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,QAAQ,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,GAAS;YACjB,EAAE;YACF,IAAI;YACJ,OAAO;YACP,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,MAAM;YACnC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,OAAO;YACtC,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC;QACF,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5D,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;iBACzG;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { Session } from "../session.js";
3
+ export declare function registerStreamTools(server: McpServer, session: Session): void;
@@ -0,0 +1,76 @@
1
+ import { z } from "zod";
2
+ import { wsSession, sseSession } from "../native.js";
3
+ import { formatWs, formatSse } from "../format.js";
4
+ const verbosity = z.enum(["summary", "headers", "full"]).optional();
5
+ function textResult(session, obj) {
6
+ return { content: [{ type: "text", text: JSON.stringify(session.redact(obj), null, 2) }] };
7
+ }
8
+ export function registerStreamTools(server, session) {
9
+ server.registerTool("ws_session", {
10
+ title: "WebSocket session (bounded)",
11
+ description: "Connect WS, send messages, collect frames until stop condition. Returns summarized batch.",
12
+ inputSchema: {
13
+ url: z.string().describe("ws:// or wss:// URL."),
14
+ headers: z.record(z.string(), z.any()).optional(),
15
+ subprotocols: z.array(z.string()).optional(),
16
+ send: z
17
+ .array(z.object({ json: z.any().optional(), text: z.string().optional() }))
18
+ .optional()
19
+ .describe("Messages to send after connecting."),
20
+ collect: z
21
+ .object({
22
+ maxMessages: z.number().int().positive().optional(),
23
+ maxDurationMs: z.number().int().positive().optional(),
24
+ until: z.record(z.string(), z.any()).optional().describe("Stop when a frame matches, e.g. {jsonpath:'$.type',equals:'done'}."),
25
+ })
26
+ .optional(),
27
+ assert: z.array(z.record(z.string(), z.any())).optional().describe("e.g. [{anyFrame:{jsonpath:'$.type',equals:'ack'}},{frameCount:{gte:1}}]"),
28
+ env: z.string().optional(),
29
+ verbosity,
30
+ },
31
+ }, async (args) => {
32
+ const spec = { ...args, vars: session.mergedVars(args.env) };
33
+ const policy = session.checkPolicy(String(args.url ?? ""));
34
+ if (policy && "blocked" in policy) {
35
+ return textResult(session, { ok: false, connected: false, error: policy.error });
36
+ }
37
+ if (policy && "dryRun" in policy) {
38
+ const handle = session.storeResponse(policy.result);
39
+ return textResult(session, formatWs(policy.result, args.verbosity ?? "summary", handle));
40
+ }
41
+ const result = await wsSession(spec);
42
+ const handle = session.storeResponse(result);
43
+ return textResult(session, formatWs(result, args.verbosity ?? "summary", handle));
44
+ });
45
+ server.registerTool("sse_session", {
46
+ title: "SSE session (bounded)",
47
+ description: "Subscribe to SSE, collect events until stop condition. Returns summarized batch with assertions.",
48
+ inputSchema: {
49
+ url: z.string().describe("SSE endpoint URL."),
50
+ headers: z.record(z.string(), z.any()).optional(),
51
+ collect: z
52
+ .object({
53
+ maxEvents: z.number().int().positive().optional(),
54
+ maxDurationMs: z.number().int().positive().optional(),
55
+ })
56
+ .optional(),
57
+ assert: z.array(z.record(z.string(), z.any())).optional().describe("e.g. [{anyEvent:{jsonpath:'$.type',equals:'tick'}},{eventCount:{gte:1}}]"),
58
+ env: z.string().optional(),
59
+ verbosity,
60
+ },
61
+ }, async (args) => {
62
+ const spec = { ...args, vars: session.mergedVars(args.env) };
63
+ const policy = session.checkPolicy(String(args.url ?? ""));
64
+ if (policy && "blocked" in policy) {
65
+ return textResult(session, { ok: false, connected: false, error: policy.error });
66
+ }
67
+ if (policy && "dryRun" in policy) {
68
+ const handle = session.storeResponse(policy.result);
69
+ return textResult(session, formatSse(policy.result, args.verbosity ?? "summary", handle));
70
+ }
71
+ const result = await sseSession(spec);
72
+ const handle = session.storeResponse(result);
73
+ return textResult(session, formatSse(result, args.verbosity ?? "summary", handle));
74
+ });
75
+ }
76
+ //# sourceMappingURL=stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/tools/stream.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { Session } from "../session.js";
3
+ export declare function registerWsTools(server: McpServer, session: Session): void;