@paretools/http 0.7.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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +11 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/curl-runner.d.ts +7 -0
  7. package/dist/lib/curl-runner.d.ts.map +1 -0
  8. package/dist/lib/curl-runner.js +9 -0
  9. package/dist/lib/curl-runner.js.map +1 -0
  10. package/dist/lib/formatters.d.ts +14 -0
  11. package/dist/lib/formatters.d.ts.map +1 -0
  12. package/dist/lib/formatters.js +66 -0
  13. package/dist/lib/formatters.js.map +1 -0
  14. package/dist/lib/parsers.d.ts +38 -0
  15. package/dist/lib/parsers.d.ts.map +1 -0
  16. package/dist/lib/parsers.js +131 -0
  17. package/dist/lib/parsers.js.map +1 -0
  18. package/dist/lib/url-validation.d.ts +11 -0
  19. package/dist/lib/url-validation.d.ts.map +1 -0
  20. package/dist/lib/url-validation.js +28 -0
  21. package/dist/lib/url-validation.js.map +1 -0
  22. package/dist/schemas/index.d.ts +53 -0
  23. package/dist/schemas/index.d.ts.map +1 -0
  24. package/dist/schemas/index.js +41 -0
  25. package/dist/schemas/index.js.map +1 -0
  26. package/dist/tools/get.d.ts +3 -0
  27. package/dist/tools/get.d.ts.map +1 -0
  28. package/dist/tools/get.js +62 -0
  29. package/dist/tools/get.js.map +1 -0
  30. package/dist/tools/head.d.ts +3 -0
  31. package/dist/tools/head.d.ts.map +1 -0
  32. package/dist/tools/head.js +62 -0
  33. package/dist/tools/head.js.map +1 -0
  34. package/dist/tools/index.d.ts +3 -0
  35. package/dist/tools/index.d.ts.map +1 -0
  36. package/dist/tools/index.js +17 -0
  37. package/dist/tools/index.js.map +1 -0
  38. package/dist/tools/post.d.ts +3 -0
  39. package/dist/tools/post.d.ts.map +1 -0
  40. package/dist/tools/post.js +75 -0
  41. package/dist/tools/post.js.map +1 -0
  42. package/dist/tools/request.d.ts +15 -0
  43. package/dist/tools/request.d.ts.map +1 -0
  44. package/dist/tools/request.js +109 -0
  45. package/dist/tools/request.js.map +1 -0
  46. package/package.json +68 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dave London
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { registerAllTools } from "./tools/index.js";
5
+ const server = new McpServer({ name: "@paretools/http", version: "0.7.0" }, {
6
+ instructions: "Structured HTTP request operations via curl (request, get, post, head). Use instead of running curl commands via bash. Returns typed JSON with status, headers, body, timing, and size.",
7
+ });
8
+ registerAllTools(server);
9
+ const transport = new StdioServerTransport();
10
+ await server.connect(transport);
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,EAAE,EAC7C;IACE,YAAY,EACV,yLAAyL;CAC5L,CACF,CAAC;AAEF,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAEzB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type RunResult } from "@paretools/shared";
2
+ /**
3
+ * Executes a curl command with the given arguments.
4
+ * Uses a generous timeout since HTTP requests can be slow.
5
+ */
6
+ export declare function curlCmd(args: string[], cwd?: string): Promise<RunResult>;
7
+ //# sourceMappingURL=curl-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"curl-runner.d.ts","sourceRoot":"","sources":["../../src/lib/curl-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;GAGG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAE9E"}
@@ -0,0 +1,9 @@
1
+ import { run } from "@paretools/shared";
2
+ /**
3
+ * Executes a curl command with the given arguments.
4
+ * Uses a generous timeout since HTTP requests can be slow.
5
+ */
6
+ export async function curlCmd(args, cwd) {
7
+ return run("curl", args, { cwd, timeout: 120_000 });
8
+ }
9
+ //# sourceMappingURL=curl-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"curl-runner.js","sourceRoot":"","sources":["../../src/lib/curl-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAkB,MAAM,mBAAmB,CAAC;AAExD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAc,EAAE,GAAY;IACxD,OAAO,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { HttpResponse, HttpHeadResponse, HttpResponseCompact, HttpHeadResponseCompact } from "../schemas/index.js";
2
+ /** Formats a full HTTP response into human-readable text. */
3
+ export declare function formatHttpResponse(data: HttpResponse): string;
4
+ /** Formats a HEAD response into human-readable text. */
5
+ export declare function formatHttpHeadResponse(data: HttpHeadResponse): string;
6
+ /** Maps full HTTP response to compact form (drop headers and body). */
7
+ export declare function compactResponseMap(data: HttpResponse): HttpResponseCompact;
8
+ /** Formats compact HTTP response. */
9
+ export declare function formatResponseCompact(data: HttpResponseCompact): string;
10
+ /** Maps full HEAD response to compact form (drop headers). */
11
+ export declare function compactHeadResponseMap(data: HttpHeadResponse): HttpHeadResponseCompact;
12
+ /** Formats compact HEAD response. */
13
+ export declare function formatHeadResponseCompact(data: HttpHeadResponseCompact): string;
14
+ //# sourceMappingURL=formatters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/lib/formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAE7B,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAyB7D;AAED,wDAAwD;AACxD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAmBrE;AAID,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,mBAAmB,CAQ1E;AAED,qCAAqC;AACrC,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAGvE;AAED,8DAA8D;AAC9D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,uBAAuB,CAOtF;AAED,qCAAqC;AACrC,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAG/E"}
@@ -0,0 +1,66 @@
1
+ /** Formats a full HTTP response into human-readable text. */
2
+ export function formatHttpResponse(data) {
3
+ const lines = [];
4
+ lines.push(`HTTP ${data.status} ${data.statusText}`);
5
+ if (data.contentType) {
6
+ lines.push(`Content-Type: ${data.contentType}`);
7
+ }
8
+ lines.push(`Size: ${data.size} bytes | Time: ${data.timing.total.toFixed(3)}s`);
9
+ const headerCount = Object.keys(data.headers).length;
10
+ lines.push(`Headers: ${headerCount}`);
11
+ for (const [key, value] of Object.entries(data.headers)) {
12
+ lines.push(` ${key}: ${value}`);
13
+ }
14
+ if (data.body) {
15
+ const bodyPreview = data.body.length > 500 ? data.body.substring(0, 500) + "..." : data.body;
16
+ lines.push("");
17
+ lines.push(bodyPreview);
18
+ }
19
+ return lines.join("\n");
20
+ }
21
+ /** Formats a HEAD response into human-readable text. */
22
+ export function formatHttpHeadResponse(data) {
23
+ const lines = [];
24
+ lines.push(`HTTP ${data.status} ${data.statusText}`);
25
+ if (data.contentType) {
26
+ lines.push(`Content-Type: ${data.contentType}`);
27
+ }
28
+ lines.push(`Time: ${data.timing.total.toFixed(3)}s`);
29
+ const headerCount = Object.keys(data.headers).length;
30
+ lines.push(`Headers: ${headerCount}`);
31
+ for (const [key, value] of Object.entries(data.headers)) {
32
+ lines.push(` ${key}: ${value}`);
33
+ }
34
+ return lines.join("\n");
35
+ }
36
+ // ── Compact types, mappers, and formatters ───────────────────────────
37
+ /** Maps full HTTP response to compact form (drop headers and body). */
38
+ export function compactResponseMap(data) {
39
+ return {
40
+ status: data.status,
41
+ statusText: data.statusText,
42
+ contentType: data.contentType,
43
+ size: data.size,
44
+ timing: data.timing,
45
+ };
46
+ }
47
+ /** Formats compact HTTP response. */
48
+ export function formatResponseCompact(data) {
49
+ const ct = data.contentType ? ` (${data.contentType})` : "";
50
+ return `HTTP ${data.status} ${data.statusText}${ct} | ${data.size} bytes | ${data.timing.total.toFixed(3)}s`;
51
+ }
52
+ /** Maps full HEAD response to compact form (drop headers). */
53
+ export function compactHeadResponseMap(data) {
54
+ return {
55
+ status: data.status,
56
+ statusText: data.statusText,
57
+ contentType: data.contentType,
58
+ timing: data.timing,
59
+ };
60
+ }
61
+ /** Formats compact HEAD response. */
62
+ export function formatHeadResponseCompact(data) {
63
+ const ct = data.contentType ? ` (${data.contentType})` : "";
64
+ return `HTTP ${data.status} ${data.statusText}${ct} | ${data.timing.total.toFixed(3)}s`;
65
+ }
66
+ //# sourceMappingURL=formatters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../src/lib/formatters.ts"],"names":[],"mappings":"AAOA,6DAA6D;AAC7D,MAAM,UAAU,kBAAkB,CAAC,IAAkB;IACnD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAErD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,kBAAkB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAEhF,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,YAAY,WAAW,EAAE,CAAC,CAAC;IAEtC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7F,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,sBAAsB,CAAC,IAAsB;IAC3D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAErD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAErD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,YAAY,WAAW,EAAE,CAAC,CAAC;IAEtC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,wEAAwE;AAExE,uEAAuE;AACvE,MAAM,UAAU,kBAAkB,CAAC,IAAkB;IACnD,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;AACJ,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,qBAAqB,CAAC,IAAyB;IAC7D,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,OAAO,QAAQ,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,GAAG,EAAE,MAAM,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AAC/G,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,sBAAsB,CAAC,IAAsB;IAC3D,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;AACJ,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,yBAAyB,CAAC,IAA6B;IACrE,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,OAAO,QAAQ,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,GAAG,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { HttpResponse, HttpHeadResponse } from "../schemas/index.js";
2
+ /** Sentinel appended via curl -w to separate body from metadata. */
3
+ export declare const PARE_META_SEPARATOR = "---PARE_HTTP_META---";
4
+ /**
5
+ * Parses the combined output from `curl -s -S -i -w '...' URL`.
6
+ *
7
+ * The output format is:
8
+ * HTTP/x.y STATUS STATUS_TEXT\r\n
9
+ * Header: value\r\n
10
+ * ...
11
+ * \r\n
12
+ * <body>
13
+ * \n---PARE_HTTP_META---\n
14
+ * <time_total> <size_download>
15
+ *
16
+ * When following redirects, multiple status+header blocks may appear.
17
+ * We parse the LAST one (the final response).
18
+ */
19
+ export declare function parseCurlOutput(stdout: string, _stderr: string, _exitCode: number): HttpResponse;
20
+ /**
21
+ * Parses curl output for HEAD requests (no body expected).
22
+ */
23
+ export declare function parseCurlHeadOutput(stdout: string, stderr: string, exitCode: number): HttpHeadResponse;
24
+ /**
25
+ * Splits raw curl `-i` output into separate HTTP response blocks.
26
+ * Each block starts with `HTTP/` (status line).
27
+ */
28
+ export declare function splitHttpBlocks(raw: string): string[];
29
+ /**
30
+ * Parses a single HTTP response block into status, headers, and body.
31
+ */
32
+ export declare function parseHttpBlock(block: string): {
33
+ status: number;
34
+ statusText: string;
35
+ headers: Record<string, string>;
36
+ body: string;
37
+ };
38
+ //# sourceMappingURL=parsers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parsers.d.ts","sourceRoot":"","sources":["../../src/lib/parsers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE1E,oEAAoE;AACpE,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAU1D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CA+BhG;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,gBAAgB,CAUlB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAsBrD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd,CA0CA"}
@@ -0,0 +1,131 @@
1
+ /** Sentinel appended via curl -w to separate body from metadata. */
2
+ export const PARE_META_SEPARATOR = "---PARE_HTTP_META---";
3
+ /**
4
+ * Parses the combined output from `curl -s -S -i -w '...' URL`.
5
+ *
6
+ * The output format is:
7
+ * HTTP/x.y STATUS STATUS_TEXT\r\n
8
+ * Header: value\r\n
9
+ * ...
10
+ * \r\n
11
+ * <body>
12
+ * \n---PARE_HTTP_META---\n
13
+ * <time_total> <size_download>
14
+ *
15
+ * When following redirects, multiple status+header blocks may appear.
16
+ * We parse the LAST one (the final response).
17
+ */
18
+ export function parseCurlOutput(stdout, _stderr, _exitCode) {
19
+ // Split off the meta section appended by -w
20
+ const metaSepIdx = stdout.lastIndexOf(PARE_META_SEPARATOR);
21
+ let metaSection = "";
22
+ let responsePart = stdout;
23
+ if (metaSepIdx !== -1) {
24
+ responsePart = stdout.substring(0, metaSepIdx);
25
+ metaSection = stdout.substring(metaSepIdx + PARE_META_SEPARATOR.length).trim();
26
+ }
27
+ const meta = parseMetaSection(metaSection);
28
+ // When following redirects, curl with -i outputs multiple response blocks.
29
+ // Each block starts with HTTP/. We want the LAST one.
30
+ const blocks = splitHttpBlocks(responsePart);
31
+ const lastBlock = blocks.length > 0 ? blocks[blocks.length - 1] : responsePart;
32
+ const { status, statusText, headers, body } = parseHttpBlock(lastBlock);
33
+ const contentType = headers["content-type"];
34
+ return {
35
+ status,
36
+ statusText,
37
+ headers,
38
+ body: body || undefined,
39
+ timing: { total: meta.time_total },
40
+ size: meta.size_download,
41
+ contentType,
42
+ };
43
+ }
44
+ /**
45
+ * Parses curl output for HEAD requests (no body expected).
46
+ */
47
+ export function parseCurlHeadOutput(stdout, stderr, exitCode) {
48
+ const full = parseCurlOutput(stdout, stderr, exitCode);
49
+ return {
50
+ status: full.status,
51
+ statusText: full.statusText,
52
+ headers: full.headers,
53
+ timing: full.timing,
54
+ contentType: full.contentType,
55
+ };
56
+ }
57
+ /**
58
+ * Splits raw curl `-i` output into separate HTTP response blocks.
59
+ * Each block starts with `HTTP/` (status line).
60
+ */
61
+ export function splitHttpBlocks(raw) {
62
+ const blocks = [];
63
+ // Match HTTP/ at the start of a line
64
+ const regex = /^HTTP\//gm;
65
+ const indices = [];
66
+ let match;
67
+ while ((match = regex.exec(raw)) !== null) {
68
+ indices.push(match.index);
69
+ }
70
+ if (indices.length === 0) {
71
+ return [raw];
72
+ }
73
+ for (let i = 0; i < indices.length; i++) {
74
+ const start = indices[i];
75
+ const end = i + 1 < indices.length ? indices[i + 1] : raw.length;
76
+ blocks.push(raw.substring(start, end));
77
+ }
78
+ return blocks;
79
+ }
80
+ /**
81
+ * Parses a single HTTP response block into status, headers, and body.
82
+ */
83
+ export function parseHttpBlock(block) {
84
+ // Normalize line endings: \r\n -> \n
85
+ const normalized = block.replace(/\r\n/g, "\n");
86
+ // Split on first double-newline to separate headers from body
87
+ const headerBodySplit = normalized.indexOf("\n\n");
88
+ let headerSection;
89
+ let body;
90
+ if (headerBodySplit !== -1) {
91
+ headerSection = normalized.substring(0, headerBodySplit);
92
+ body = normalized.substring(headerBodySplit + 2);
93
+ }
94
+ else {
95
+ // No body (e.g. HEAD request or empty response)
96
+ headerSection = normalized;
97
+ body = "";
98
+ }
99
+ const lines = headerSection.split("\n");
100
+ const statusLine = lines[0] || "";
101
+ // Parse status line: HTTP/1.1 200 OK
102
+ const statusMatch = statusLine.match(/^HTTP\/[\d.]+\s+(\d+)\s*(.*)/);
103
+ const status = statusMatch ? parseInt(statusMatch[1], 10) : 0;
104
+ const statusText = statusMatch ? statusMatch[2].trim() : "";
105
+ // Parse headers
106
+ const headers = {};
107
+ for (let i = 1; i < lines.length; i++) {
108
+ const line = lines[i];
109
+ const colonIdx = line.indexOf(":");
110
+ if (colonIdx > 0) {
111
+ const key = line.substring(0, colonIdx).trim().toLowerCase();
112
+ const value = line.substring(colonIdx + 1).trim();
113
+ headers[key] = value;
114
+ }
115
+ }
116
+ // Trim trailing whitespace from body
117
+ body = body.replace(/\n$/, "");
118
+ return { status, statusText, headers, body };
119
+ }
120
+ /**
121
+ * Parses the metadata section appended by curl's -w format string.
122
+ * Format: "<time_total> <size_download>"
123
+ */
124
+ function parseMetaSection(meta) {
125
+ const parts = meta.trim().split(/\s+/);
126
+ return {
127
+ time_total: parts[0] ? parseFloat(parts[0]) : 0,
128
+ size_download: parts[1] ? parseFloat(parts[1]) : 0,
129
+ };
130
+ }
131
+ //# sourceMappingURL=parsers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parsers.js","sourceRoot":"","sources":["../../src/lib/parsers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Validates that a URL uses only http:// or https:// schemes.
3
+ * Blocks dangerous schemes like file://, ftp://, gopher://, dict://, data:, javascript:, etc.
4
+ */
5
+ export declare function assertSafeUrl(url: string): void;
6
+ /**
7
+ * Validates that a header key or value does not contain newlines or control characters
8
+ * that could be used for header injection attacks.
9
+ */
10
+ export declare function assertSafeHeader(key: string, value: string): void;
11
+ //# sourceMappingURL=url-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-validation.d.ts","sourceRoot":"","sources":["../../src/lib/url-validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAY/C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAcjE"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Validates that a URL uses only http:// or https:// schemes.
3
+ * Blocks dangerous schemes like file://, ftp://, gopher://, dict://, data:, javascript:, etc.
4
+ */
5
+ export function assertSafeUrl(url) {
6
+ const trimmed = url.trim();
7
+ if (!trimmed) {
8
+ throw new Error("URL must not be empty.");
9
+ }
10
+ const lower = trimmed.toLowerCase();
11
+ if (!lower.startsWith("http://") && !lower.startsWith("https://")) {
12
+ throw new Error(`Unsafe URL scheme. Only http:// and https:// are allowed. Got: "${url}"`);
13
+ }
14
+ }
15
+ /**
16
+ * Validates that a header key or value does not contain newlines or control characters
17
+ * that could be used for header injection attacks.
18
+ */
19
+ export function assertSafeHeader(key, value) {
20
+ const UNSAFE_RE = /[\r\n\x00]/;
21
+ if (UNSAFE_RE.test(key)) {
22
+ throw new Error(`Invalid header key: "${key}". Header keys must not contain newlines or null bytes.`);
23
+ }
24
+ if (UNSAFE_RE.test(value)) {
25
+ throw new Error(`Invalid header value for "${key}". Header values must not contain newlines or null bytes.`);
26
+ }
27
+ }
28
+ //# sourceMappingURL=url-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-validation.js","sourceRoot":"","sources":["../../src/lib/url-validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAE3B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAEpC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,mEAAmE,GAAG,GAAG,CAAC,CAAC;IAC7F,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,KAAa;IACzD,MAAM,SAAS,GAAG,YAAY,CAAC;IAE/B,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,wBAAwB,GAAG,yDAAyD,CACrF,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,6BAA6B,GAAG,2DAA2D,CAC5F,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { z } from "zod";
2
+ /** Zod schema for a single HTTP header key-value pair as a record. */
3
+ export declare const HttpHeadersSchema: z.ZodRecord<z.ZodString, z.ZodString>;
4
+ /** Zod schema for HTTP timing information. */
5
+ export declare const HttpTimingSchema: z.ZodObject<{
6
+ total: z.ZodNumber;
7
+ }, z.core.$strip>;
8
+ /** Zod schema for the full HTTP response result (used by request, get, post). */
9
+ export declare const HttpResponseSchema: z.ZodObject<{
10
+ status: z.ZodNumber;
11
+ statusText: z.ZodString;
12
+ headers: z.ZodRecord<z.ZodString, z.ZodString>;
13
+ body: z.ZodOptional<z.ZodString>;
14
+ timing: z.ZodObject<{
15
+ total: z.ZodNumber;
16
+ }, z.core.$strip>;
17
+ size: z.ZodNumber;
18
+ contentType: z.ZodOptional<z.ZodString>;
19
+ }, z.core.$strip>;
20
+ export type HttpResponse = z.infer<typeof HttpResponseSchema>;
21
+ /** Zod schema for the HEAD-only HTTP response result (no body). */
22
+ export declare const HttpHeadResponseSchema: z.ZodObject<{
23
+ status: z.ZodNumber;
24
+ statusText: z.ZodString;
25
+ headers: z.ZodRecord<z.ZodString, z.ZodString>;
26
+ timing: z.ZodObject<{
27
+ total: z.ZodNumber;
28
+ }, z.core.$strip>;
29
+ contentType: z.ZodOptional<z.ZodString>;
30
+ }, z.core.$strip>;
31
+ export type HttpHeadResponse = z.infer<typeof HttpHeadResponseSchema>;
32
+ /** Compact response: status, timing, size. Drop headers and body. */
33
+ export declare const HttpResponseCompactSchema: z.ZodObject<{
34
+ status: z.ZodNumber;
35
+ statusText: z.ZodString;
36
+ contentType: z.ZodOptional<z.ZodString>;
37
+ size: z.ZodNumber;
38
+ timing: z.ZodObject<{
39
+ total: z.ZodNumber;
40
+ }, z.core.$strip>;
41
+ }, z.core.$strip>;
42
+ export type HttpResponseCompact = z.infer<typeof HttpResponseCompactSchema>;
43
+ /** Compact HEAD response: status and timing only. Drop headers. */
44
+ export declare const HttpHeadResponseCompactSchema: z.ZodObject<{
45
+ status: z.ZodNumber;
46
+ statusText: z.ZodString;
47
+ contentType: z.ZodOptional<z.ZodString>;
48
+ timing: z.ZodObject<{
49
+ total: z.ZodNumber;
50
+ }, z.core.$strip>;
51
+ }, z.core.$strip>;
52
+ export type HttpHeadResponseCompact = z.infer<typeof HttpHeadResponseCompactSchema>;
53
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,sEAAsE;AACtE,eAAO,MAAM,iBAAiB,uCAAmC,CAAC;AAElE,8CAA8C;AAC9C,eAAO,MAAM,gBAAgB;;iBAE3B,CAAC;AAEH,iFAAiF;AACjF,eAAO,MAAM,kBAAkB;;;;;;;;;;iBAQ7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,mEAAmE;AACnE,eAAO,MAAM,sBAAsB;;;;;;;;iBAMjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,qEAAqE;AACrE,eAAO,MAAM,yBAAyB;;;;;;;;iBAMpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,mEAAmE;AACnE,eAAO,MAAM,6BAA6B;;;;;;;iBAKxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ /** Zod schema for a single HTTP header key-value pair as a record. */
3
+ export const HttpHeadersSchema = z.record(z.string(), z.string());
4
+ /** Zod schema for HTTP timing information. */
5
+ export const HttpTimingSchema = z.object({
6
+ total: z.number(),
7
+ });
8
+ /** Zod schema for the full HTTP response result (used by request, get, post). */
9
+ export const HttpResponseSchema = z.object({
10
+ status: z.number(),
11
+ statusText: z.string(),
12
+ headers: HttpHeadersSchema,
13
+ body: z.string().optional(),
14
+ timing: HttpTimingSchema,
15
+ size: z.number(),
16
+ contentType: z.string().optional(),
17
+ });
18
+ /** Zod schema for the HEAD-only HTTP response result (no body). */
19
+ export const HttpHeadResponseSchema = z.object({
20
+ status: z.number(),
21
+ statusText: z.string(),
22
+ headers: HttpHeadersSchema,
23
+ timing: HttpTimingSchema,
24
+ contentType: z.string().optional(),
25
+ });
26
+ /** Compact response: status, timing, size. Drop headers and body. */
27
+ export const HttpResponseCompactSchema = z.object({
28
+ status: z.number(),
29
+ statusText: z.string(),
30
+ contentType: z.string().optional(),
31
+ size: z.number(),
32
+ timing: HttpTimingSchema,
33
+ });
34
+ /** Compact HEAD response: status and timing only. Drop headers. */
35
+ export const HttpHeadResponseCompactSchema = z.object({
36
+ status: z.number(),
37
+ statusText: z.string(),
38
+ contentType: z.string().optional(),
39
+ timing: HttpTimingSchema,
40
+ });
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,sEAAsE;AACtE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAElE,8CAA8C;AAC9C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC;AAEH,iFAAiF;AACjF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,OAAO,EAAE,iBAAiB;IAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,MAAM,EAAE,gBAAgB;IACxB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC;AAIH,mEAAmE;AACnE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,OAAO,EAAE,iBAAiB;IAC1B,MAAM,EAAE,gBAAgB;IACxB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC;AAIH,qEAAqE;AACrE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,gBAAgB;CACzB,CAAC,CAAC;AAIH,mEAAmE;AACnE,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,MAAM,EAAE,gBAAgB;CACzB,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerGetTool(server: McpServer): void;
3
+ //# sourceMappingURL=get.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../src/tools/get.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAazE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,QAwEhD"}
@@ -0,0 +1,62 @@
1
+ import { z } from "zod";
2
+ import { compactDualOutput, INPUT_LIMITS } from "@paretools/shared";
3
+ import { curlCmd } from "../lib/curl-runner.js";
4
+ import { parseCurlOutput } from "../lib/parsers.js";
5
+ import { formatHttpResponse, compactResponseMap, formatResponseCompact, } from "../lib/formatters.js";
6
+ import { HttpResponseSchema } from "../schemas/index.js";
7
+ import { assertSafeUrl } from "../lib/url-validation.js";
8
+ import { buildCurlArgs } from "./request.js";
9
+ export function registerGetTool(server) {
10
+ server.registerTool("get", {
11
+ title: "HTTP GET",
12
+ description: "Makes an HTTP GET request via curl and returns structured response data. Convenience wrapper for the request tool.",
13
+ inputSchema: {
14
+ url: z
15
+ .string()
16
+ .max(INPUT_LIMITS.STRING_MAX)
17
+ .describe("The URL to request (http:// or https:// only)"),
18
+ headers: z
19
+ .record(z.string().max(INPUT_LIMITS.SHORT_STRING_MAX), z.string().max(INPUT_LIMITS.STRING_MAX))
20
+ .optional()
21
+ .describe("Request headers as key-value pairs"),
22
+ timeout: z
23
+ .number()
24
+ .min(1)
25
+ .max(300)
26
+ .optional()
27
+ .default(30)
28
+ .describe("Request timeout in seconds (default: 30)"),
29
+ followRedirects: z
30
+ .boolean()
31
+ .optional()
32
+ .default(true)
33
+ .describe("Follow HTTP redirects (default: true)"),
34
+ compact: z
35
+ .boolean()
36
+ .optional()
37
+ .default(true)
38
+ .describe("Auto-compact when structured output exceeds raw CLI tokens. Set false to always get full schema."),
39
+ path: z
40
+ .string()
41
+ .max(INPUT_LIMITS.PATH_MAX)
42
+ .optional()
43
+ .describe("Working directory (default: cwd)"),
44
+ },
45
+ outputSchema: HttpResponseSchema,
46
+ }, async ({ url, headers, timeout, followRedirects, compact, path }) => {
47
+ assertSafeUrl(url);
48
+ const args = buildCurlArgs({
49
+ url,
50
+ method: "GET",
51
+ headers,
52
+ timeout: timeout ?? 30,
53
+ followRedirects: followRedirects ?? true,
54
+ });
55
+ const cwd = path || process.cwd();
56
+ const result = await curlCmd(args, cwd);
57
+ const data = parseCurlOutput(result.stdout, result.stderr, result.exitCode);
58
+ const rawOutput = (result.stdout + "\n" + result.stderr).trim();
59
+ return compactDualOutput(data, rawOutput, formatHttpResponse, compactResponseMap, formatResponseCompact, compact === false);
60
+ });
61
+ }
62
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/tools/get.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerHeadTool(server: McpServer): void;
3
+ //# sourceMappingURL=head.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../../src/tools/head.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAazE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,QAwEjD"}
@@ -0,0 +1,62 @@
1
+ import { z } from "zod";
2
+ import { compactDualOutput, INPUT_LIMITS } from "@paretools/shared";
3
+ import { curlCmd } from "../lib/curl-runner.js";
4
+ import { parseCurlHeadOutput } from "../lib/parsers.js";
5
+ import { formatHttpHeadResponse, compactHeadResponseMap, formatHeadResponseCompact, } from "../lib/formatters.js";
6
+ import { HttpHeadResponseSchema } from "../schemas/index.js";
7
+ import { assertSafeUrl } from "../lib/url-validation.js";
8
+ import { buildCurlArgs } from "./request.js";
9
+ export function registerHeadTool(server) {
10
+ server.registerTool("head", {
11
+ title: "HTTP HEAD",
12
+ description: "Makes an HTTP HEAD request via curl and returns structured response headers (no body). Use to check resource existence, content type, or cache headers.",
13
+ inputSchema: {
14
+ url: z
15
+ .string()
16
+ .max(INPUT_LIMITS.STRING_MAX)
17
+ .describe("The URL to request (http:// or https:// only)"),
18
+ headers: z
19
+ .record(z.string().max(INPUT_LIMITS.SHORT_STRING_MAX), z.string().max(INPUT_LIMITS.STRING_MAX))
20
+ .optional()
21
+ .describe("Request headers as key-value pairs"),
22
+ timeout: z
23
+ .number()
24
+ .min(1)
25
+ .max(300)
26
+ .optional()
27
+ .default(30)
28
+ .describe("Request timeout in seconds (default: 30)"),
29
+ followRedirects: z
30
+ .boolean()
31
+ .optional()
32
+ .default(true)
33
+ .describe("Follow HTTP redirects (default: true)"),
34
+ compact: z
35
+ .boolean()
36
+ .optional()
37
+ .default(true)
38
+ .describe("Auto-compact when structured output exceeds raw CLI tokens. Set false to always get full schema."),
39
+ path: z
40
+ .string()
41
+ .max(INPUT_LIMITS.PATH_MAX)
42
+ .optional()
43
+ .describe("Working directory (default: cwd)"),
44
+ },
45
+ outputSchema: HttpHeadResponseSchema,
46
+ }, async ({ url, headers, timeout, followRedirects, compact, path }) => {
47
+ assertSafeUrl(url);
48
+ const args = buildCurlArgs({
49
+ url,
50
+ method: "HEAD",
51
+ headers,
52
+ timeout: timeout ?? 30,
53
+ followRedirects: followRedirects ?? true,
54
+ });
55
+ const cwd = path || process.cwd();
56
+ const result = await curlCmd(args, cwd);
57
+ const data = parseCurlHeadOutput(result.stdout, result.stderr, result.exitCode);
58
+ const rawOutput = (result.stdout + "\n" + result.stderr).trim();
59
+ return compactDualOutput(data, rawOutput, formatHttpHeadResponse, compactHeadResponseMap, formatHeadResponseCompact, compact === false);
60
+ });
61
+ }
62
+ //# sourceMappingURL=head.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"head.js","sourceRoot":"","sources":["../../src/tools/head.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerAllTools(server: McpServer): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,QAMjD"}
@@ -0,0 +1,17 @@
1
+ import { shouldRegisterTool } from "@paretools/shared";
2
+ import { registerRequestTool } from "./request.js";
3
+ import { registerGetTool } from "./get.js";
4
+ import { registerPostTool } from "./post.js";
5
+ import { registerHeadTool } from "./head.js";
6
+ export function registerAllTools(server) {
7
+ const s = (name) => shouldRegisterTool("http", name);
8
+ if (s("request"))
9
+ registerRequestTool(server);
10
+ if (s("get"))
11
+ registerGetTool(server);
12
+ if (s("post"))
13
+ registerPostTool(server);
14
+ if (s("head"))
15
+ registerHeadTool(server);
16
+ }
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,MAAM,CAAC,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7D,IAAI,CAAC,CAAC,SAAS,CAAC;QAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,CAAC,CAAC,KAAK,CAAC;QAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,MAAM,CAAC;QAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC,MAAM,CAAC;QAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerPostTool(server: McpServer): void;
3
+ //# sourceMappingURL=post.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post.d.ts","sourceRoot":"","sources":["../../src/tools/post.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAazE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,QAsFjD"}
@@ -0,0 +1,75 @@
1
+ import { z } from "zod";
2
+ import { compactDualOutput, INPUT_LIMITS } from "@paretools/shared";
3
+ import { curlCmd } from "../lib/curl-runner.js";
4
+ import { parseCurlOutput } from "../lib/parsers.js";
5
+ import { formatHttpResponse, compactResponseMap, formatResponseCompact, } from "../lib/formatters.js";
6
+ import { HttpResponseSchema } from "../schemas/index.js";
7
+ import { assertSafeUrl } from "../lib/url-validation.js";
8
+ import { buildCurlArgs } from "./request.js";
9
+ export function registerPostTool(server) {
10
+ server.registerTool("post", {
11
+ title: "HTTP POST",
12
+ description: "Makes an HTTP POST request via curl and returns structured response data. Convenience wrapper for the request tool with required body.",
13
+ inputSchema: {
14
+ url: z
15
+ .string()
16
+ .max(INPUT_LIMITS.STRING_MAX)
17
+ .describe("The URL to request (http:// or https:// only)"),
18
+ body: z.string().max(INPUT_LIMITS.STRING_MAX).describe("Request body"),
19
+ headers: z
20
+ .record(z.string().max(INPUT_LIMITS.SHORT_STRING_MAX), z.string().max(INPUT_LIMITS.STRING_MAX))
21
+ .optional()
22
+ .describe("Request headers as key-value pairs"),
23
+ contentType: z
24
+ .string()
25
+ .max(INPUT_LIMITS.SHORT_STRING_MAX)
26
+ .optional()
27
+ .default("application/json")
28
+ .describe("Content-Type header (default: application/json)"),
29
+ timeout: z
30
+ .number()
31
+ .min(1)
32
+ .max(300)
33
+ .optional()
34
+ .default(30)
35
+ .describe("Request timeout in seconds (default: 30)"),
36
+ followRedirects: z
37
+ .boolean()
38
+ .optional()
39
+ .default(true)
40
+ .describe("Follow HTTP redirects (default: true)"),
41
+ compact: z
42
+ .boolean()
43
+ .optional()
44
+ .default(true)
45
+ .describe("Auto-compact when structured output exceeds raw CLI tokens. Set false to always get full schema."),
46
+ path: z
47
+ .string()
48
+ .max(INPUT_LIMITS.PATH_MAX)
49
+ .optional()
50
+ .describe("Working directory (default: cwd)"),
51
+ },
52
+ outputSchema: HttpResponseSchema,
53
+ }, async ({ url, body, headers, contentType, timeout, followRedirects, compact, path }) => {
54
+ assertSafeUrl(url);
55
+ // Merge content-type header with user-supplied headers
56
+ const mergedHeaders = {
57
+ "Content-Type": contentType ?? "application/json",
58
+ ...headers,
59
+ };
60
+ const args = buildCurlArgs({
61
+ url,
62
+ method: "POST",
63
+ headers: mergedHeaders,
64
+ body,
65
+ timeout: timeout ?? 30,
66
+ followRedirects: followRedirects ?? true,
67
+ });
68
+ const cwd = path || process.cwd();
69
+ const result = await curlCmd(args, cwd);
70
+ const data = parseCurlOutput(result.stdout, result.stderr, result.exitCode);
71
+ const rawOutput = (result.stdout + "\n" + result.stderr).trim();
72
+ return compactDualOutput(data, rawOutput, formatHttpResponse, compactResponseMap, formatResponseCompact, compact === false);
73
+ });
74
+ }
75
+ //# sourceMappingURL=post.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post.js","sourceRoot":"","sources":["../../src/tools/post.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerRequestTool(server: McpServer): void;
3
+ /**
4
+ * Builds the curl argument array from the request parameters.
5
+ * Exported for reuse in get/post/head tools.
6
+ */
7
+ export declare function buildCurlArgs(opts: {
8
+ url: string;
9
+ method: string;
10
+ headers?: Record<string, string>;
11
+ body?: string;
12
+ timeout: number;
13
+ followRedirects: boolean;
14
+ }): string[];
15
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/tools/request.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAczE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,QA+EpD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;CAC1B,GAAG,MAAM,EAAE,CA2CX"}
@@ -0,0 +1,109 @@
1
+ import { z } from "zod";
2
+ import { compactDualOutput, assertNoFlagInjection, INPUT_LIMITS } from "@paretools/shared";
3
+ import { curlCmd } from "../lib/curl-runner.js";
4
+ import { parseCurlOutput, PARE_META_SEPARATOR } from "../lib/parsers.js";
5
+ import { formatHttpResponse, compactResponseMap, formatResponseCompact, } from "../lib/formatters.js";
6
+ import { HttpResponseSchema } from "../schemas/index.js";
7
+ import { assertSafeUrl, assertSafeHeader } from "../lib/url-validation.js";
8
+ const METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
9
+ export function registerRequestTool(server) {
10
+ server.registerTool("request", {
11
+ title: "HTTP Request",
12
+ description: "Makes an HTTP request via curl and returns structured response data (status, headers, body, timing). Use instead of running `curl` in the terminal.",
13
+ inputSchema: {
14
+ url: z
15
+ .string()
16
+ .max(INPUT_LIMITS.STRING_MAX)
17
+ .describe("The URL to request (http:// or https:// only)"),
18
+ method: z.enum(METHODS).optional().default("GET").describe("HTTP method (default: GET)"),
19
+ headers: z
20
+ .record(z.string().max(INPUT_LIMITS.SHORT_STRING_MAX), z.string().max(INPUT_LIMITS.STRING_MAX))
21
+ .optional()
22
+ .describe("Request headers as key-value pairs"),
23
+ body: z
24
+ .string()
25
+ .max(INPUT_LIMITS.STRING_MAX)
26
+ .optional()
27
+ .describe("Request body (for POST, PUT, PATCH)"),
28
+ timeout: z
29
+ .number()
30
+ .min(1)
31
+ .max(300)
32
+ .optional()
33
+ .default(30)
34
+ .describe("Request timeout in seconds (default: 30)"),
35
+ followRedirects: z
36
+ .boolean()
37
+ .optional()
38
+ .default(true)
39
+ .describe("Follow HTTP redirects (default: true)"),
40
+ compact: z
41
+ .boolean()
42
+ .optional()
43
+ .default(true)
44
+ .describe("Auto-compact when structured output exceeds raw CLI tokens. Set false to always get full schema."),
45
+ path: z
46
+ .string()
47
+ .max(INPUT_LIMITS.PATH_MAX)
48
+ .optional()
49
+ .describe("Working directory (default: cwd)"),
50
+ },
51
+ outputSchema: HttpResponseSchema,
52
+ }, async ({ url, method, headers, body, timeout, followRedirects, compact, path }) => {
53
+ assertSafeUrl(url);
54
+ const args = buildCurlArgs({
55
+ url,
56
+ method: method ?? "GET",
57
+ headers,
58
+ body,
59
+ timeout: timeout ?? 30,
60
+ followRedirects: followRedirects ?? true,
61
+ });
62
+ const cwd = path || process.cwd();
63
+ const result = await curlCmd(args, cwd);
64
+ const data = parseCurlOutput(result.stdout, result.stderr, result.exitCode);
65
+ const rawOutput = (result.stdout + "\n" + result.stderr).trim();
66
+ return compactDualOutput(data, rawOutput, formatHttpResponse, compactResponseMap, formatResponseCompact, compact === false);
67
+ });
68
+ }
69
+ /**
70
+ * Builds the curl argument array from the request parameters.
71
+ * Exported for reuse in get/post/head tools.
72
+ */
73
+ export function buildCurlArgs(opts) {
74
+ const args = [
75
+ "-s", // Silent mode (no progress)
76
+ "-S", // Show errors
77
+ "-i", // Include response headers in output
78
+ ];
79
+ // Write-out format for timing and size metadata
80
+ const writeOut = `\n${PARE_META_SEPARATOR}\n%{time_total} %{size_download}`;
81
+ args.push("-w", writeOut);
82
+ // HTTP method
83
+ args.push("-X", opts.method);
84
+ // Timeout
85
+ args.push("--max-time", String(opts.timeout));
86
+ // Follow redirects
87
+ if (opts.followRedirects) {
88
+ args.push("-L");
89
+ // Limit redirect hops to prevent infinite loops
90
+ args.push("--max-redirs", "10");
91
+ }
92
+ // Custom headers
93
+ if (opts.headers) {
94
+ for (const [key, value] of Object.entries(opts.headers)) {
95
+ assertNoFlagInjection(key, "header key");
96
+ assertNoFlagInjection(value, "header value");
97
+ assertSafeHeader(key, value);
98
+ args.push("-H", `${key}: ${value}`);
99
+ }
100
+ }
101
+ // Request body
102
+ if (opts.body) {
103
+ args.push("--data-raw", opts.body);
104
+ }
105
+ // URL must be last
106
+ args.push(opts.url);
107
+ return args;
108
+ }
109
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/tools/request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC3F,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE3E,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAU,CAAC;AAEtF,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACjB,SAAS,EACT;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EACT,qJAAqJ;QACvJ,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC;iBAC5B,QAAQ,CAAC,+CAA+C,CAAC;YAC5D,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YACxF,OAAO,EAAE,CAAC;iBACP,MAAM,CACL,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,gBAAgB,CAAC,EAC7C,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,CACxC;iBACA,QAAQ,EAAE;iBACV,QAAQ,CAAC,oCAAoC,CAAC;YACjD,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC;iBAC5B,QAAQ,EAAE;iBACV,QAAQ,CAAC,qCAAqC,CAAC;YAClD,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,GAAG,CAAC;iBACR,QAAQ,EAAE;iBACV,OAAO,CAAC,EAAE,CAAC;iBACX,QAAQ,CAAC,0CAA0C,CAAC;YACvD,eAAe,EAAE,CAAC;iBACf,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,OAAO,CAAC,IAAI,CAAC;iBACb,QAAQ,CAAC,uCAAuC,CAAC;YACpD,OAAO,EAAE,CAAC;iBACP,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,OAAO,CAAC,IAAI,CAAC;iBACb,QAAQ,CACP,kGAAkG,CACnG;YACH,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC;iBAC1B,QAAQ,EAAE;iBACV,QAAQ,CAAC,kCAAkC,CAAC;SAChD;QACD,YAAY,EAAE,kBAAkB;KACjC,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QAChF,aAAa,CAAC,GAAG,CAAC,CAAC;QAEnB,MAAM,IAAI,GAAG,aAAa,CAAC;YACzB,GAAG;YACH,MAAM,EAAE,MAAM,IAAI,KAAK;YACvB,OAAO;YACP,IAAI;YACJ,OAAO,EAAE,OAAO,IAAI,EAAE;YACtB,eAAe,EAAE,eAAe,IAAI,IAAI;SACzC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5E,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAEhE,OAAO,iBAAiB,CACtB,IAAI,EACJ,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,OAAO,KAAK,KAAK,CAClB,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAO7B;IACC,MAAM,IAAI,GAAa;QACrB,IAAI,EAAE,4BAA4B;QAClC,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE,qCAAqC;KAC5C,CAAC;IAEF,gDAAgD;IAChD,MAAM,QAAQ,GAAG,KAAK,mBAAmB,kCAAkC,CAAC;IAC5E,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE1B,cAAc;IACd,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAE7B,UAAU;IACV,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9C,mBAAmB;IACnB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,gDAAgD;QAChD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,iBAAiB;IACjB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACxD,qBAAqB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YACzC,qBAAqB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;YAC7C,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,eAAe;IACf,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,mBAAmB;IACnB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEpB,OAAO,IAAI,CAAC;AACd,CAAC"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@paretools/http",
3
+ "version": "0.7.0",
4
+ "mcpName": "io.github.Dave-London/http",
5
+ "description": "MCP server for HTTP requests (curl) with structured, token-efficient output",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "mcp",
9
+ "mcp-server",
10
+ "model-context-protocol",
11
+ "structured-output",
12
+ "ai",
13
+ "ai-agent",
14
+ "claude",
15
+ "cursor",
16
+ "copilot",
17
+ "token-efficient",
18
+ "devtools",
19
+ "cli",
20
+ "http",
21
+ "curl",
22
+ "rest",
23
+ "api",
24
+ "request"
25
+ ],
26
+ "homepage": "https://github.com/Dave-London/Pare/tree/main/packages/server-http",
27
+ "engines": {
28
+ "node": ">=20"
29
+ },
30
+ "type": "module",
31
+ "bin": {
32
+ "pare-http": "./dist/index.js"
33
+ },
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.ts",
37
+ "default": "./dist/index.js"
38
+ }
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/Dave-London/Pare.git",
46
+ "directory": "packages/server-http"
47
+ },
48
+ "files": [
49
+ "dist"
50
+ ],
51
+ "dependencies": {
52
+ "@modelcontextprotocol/sdk": "^1.26.0",
53
+ "zod": "^4.3.6",
54
+ "@paretools/shared": "0.6.0"
55
+ },
56
+ "devDependencies": {
57
+ "@types/node": "^25.2.3",
58
+ "typescript": "^5.7.0",
59
+ "vitest": "^4.0.18",
60
+ "@paretools/tsconfig": "0.0.0"
61
+ },
62
+ "scripts": {
63
+ "build": "tsc",
64
+ "test": "vitest run",
65
+ "test:watch": "vitest",
66
+ "lint": "eslint src/"
67
+ }
68
+ }