@quantakrypto/mcp 0.4.1 → 0.4.3

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/HOSTING.md CHANGED
@@ -19,13 +19,17 @@ hosted endpoint is reachable by untrusted peers. Out of the box `node dist/http.
19
19
  must carry `Authorization: Bearer <token>`; auth is checked *before* the body
20
20
  is read or dispatched. Missing/invalid token → `401` with `WWW-Authenticate: Bearer`.
21
21
  `GET /health` is unauthenticated.
22
- - **Gates the filesystem tools off by default.** `scan_path`, `inventory_crypto`
23
- and `generate_cbom` take a client-supplied path straight into `core.scan` and
24
- would otherwise be an arbitrary-directory reader (`/etc`, `/root/.ssh`, …) with
25
- matched-line snippets echoed back. Over HTTP they are registered **only when
26
- `QUANTAKRYPTO_MCP_ALLOW_FS=1`**, so both `tools/list` and `tools/call` reflect the
27
- gate. The knowledge tools (`explain_finding`, `suggest_hybrid`, `list_rules`)
28
- are pure and always exposed. The gating is a pure function (`gateHttpTools`),
22
+ - **Gates the filesystem tools off by default.** `scan_path`, `inventory_crypto`,
23
+ `generate_cbom` and `plan_migration` take a client-supplied path straight into
24
+ `core.scan` and would otherwise be an arbitrary-directory reader (`/etc`,
25
+ `/root/.ssh`, …) with matched-line snippets echoed back. Over HTTP they are
26
+ registered **only when `QUANTAKRYPTO_MCP_ALLOW_FS=1`**, so both `tools/list` and
27
+ `tools/call` reflect the gate. The remaining tools take no path and are pure, so
28
+ they are always exposed: the knowledge tools (`explain_finding`,
29
+ `suggest_hybrid`, `list_rules`, `get_fix_examples`), the copilot helpers
30
+ (`verify_fix`, `check_dependency`, `score_delta`), and the offline, key-free
31
+ BYOK triage/remediation request tools (`triage_findings`, `apply_triage`,
32
+ `remediate_findings`). The gating is a pure function (`gateHttpTools`),
29
33
  unit-tested in `test/http.test.ts`.
30
34
  - **Confines the filesystem tools to a root allow-list.** When the FS tools are
31
35
  enabled, every scanned path must resolve inside `QUANTAKRYPTO_MCP_ROOT`
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2026 quantakrypto / Dandelion Labs JSC
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
@@ -55,6 +55,16 @@ export type PathDecision = {
55
55
  ok: false;
56
56
  reason: string;
57
57
  };
58
+ /**
59
+ * Re-verify containment against the REAL (symlink-resolved) paths. The lexical
60
+ * check in {@link resolveScanPath} trusts path strings, but a symlink planted
61
+ * inside an allowed root can point outside it (`<root>/link -> /etc`), and the
62
+ * walker `stat`s through symlinks. Resolving both the target and the roots with
63
+ * `realpath` closes that escape (audit: mcp #1). Falls back to the lexical path
64
+ * when `realpath` fails (e.g. the path doesn't exist yet) — the scan then fails
65
+ * with ENOENT as before, never reads out of root.
66
+ */
67
+ export declare function realpathInsideRoots(resolved: string, config: FsConfig): Promise<boolean>;
58
68
  /**
59
69
  * Validate and resolve a caller-supplied scan path against the allow-list.
60
70
  *
@@ -1 +1 @@
1
- {"version":3,"file":"fsconfig.d.ts","sourceRoot":"","sources":["../src/fsconfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH,iEAAiE;AACjE,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEvD,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC,mEAAmE;AACnE,eAAO,MAAM,aAAa,SAAU,CAAC;AAErC,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,QAAoB,CAAC;AAEnD,iFAAiF;AACjF,eAAO,MAAM,aAAa,QAAyB,CAAC;AAEpD,mFAAmF;AACnF,MAAM,WAAW,QAAQ;IACvB;;;OAGG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;CAClB;AA8BD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,GAAE,MAAsB,GAAG,QAAQ,CAMjF;AAED,0EAA0E;AAC1E,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAUtF;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAsBjF"}
1
+ {"version":3,"file":"fsconfig.d.ts","sourceRoot":"","sources":["../src/fsconfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,iEAAiE;AACjE,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEvD,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC,mEAAmE;AACnE,eAAO,MAAM,aAAa,SAAU,CAAC;AAErC,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,QAAoB,CAAC;AAEnD,iFAAiF;AACjF,eAAO,MAAM,aAAa,QAAyB,CAAC;AAEpD,mFAAmF;AACnF,MAAM,WAAW,QAAQ;IACvB;;;OAGG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;CAClB;AA8BD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,GAAE,MAAsB,GAAG,QAAQ,CAMjF;AAED,0EAA0E;AAC1E,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAUtF;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAI9F;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAsBjF"}
package/dist/fsconfig.js CHANGED
@@ -22,6 +22,7 @@
22
22
  */
23
23
  import * as path from "node:path";
24
24
  import process from "node:process";
25
+ import { realpath } from "node:fs/promises";
25
26
  /** Default file-count budget for a single FS tool call. */
26
27
  export const DEFAULT_MAX_FILES = 25_000;
27
28
  /** Hard cap on the file-count budget, even when raised via env. */
@@ -77,6 +78,20 @@ function isInsideRoot(child, root) {
77
78
  // `rel` starting with ".." (or being absolute) means `child` escapes `root`.
78
79
  return rel.length > 0 && !rel.startsWith("..") && !path.isAbsolute(rel);
79
80
  }
81
+ /**
82
+ * Re-verify containment against the REAL (symlink-resolved) paths. The lexical
83
+ * check in {@link resolveScanPath} trusts path strings, but a symlink planted
84
+ * inside an allowed root can point outside it (`<root>/link -> /etc`), and the
85
+ * walker `stat`s through symlinks. Resolving both the target and the roots with
86
+ * `realpath` closes that escape (audit: mcp #1). Falls back to the lexical path
87
+ * when `realpath` fails (e.g. the path doesn't exist yet) — the scan then fails
88
+ * with ENOENT as before, never reads out of root.
89
+ */
90
+ export async function realpathInsideRoots(resolved, config) {
91
+ const real = await realpath(resolved).catch(() => resolved);
92
+ const realRoots = await Promise.all(config.roots.map((r) => realpath(r).catch(() => r)));
93
+ return realRoots.some((root) => isInsideRoot(real, root));
94
+ }
80
95
  /**
81
96
  * Validate and resolve a caller-supplied scan path against the allow-list.
82
97
  *
@@ -1 +1 @@
1
- {"version":3,"file":"fsconfig.js","sourceRoot":"","sources":["../src/fsconfig.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fsconfig.js","sourceRoot":"","sources":["../src/fsconfig.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Filesystem-tool safety policy for the quantakrypto MCP (P0 — FS confinement\n * and work budgets).\n *\n * The FS-backed tools (`scan_path`, `inventory_crypto`, `generate_cbom`) pass a\n * caller-supplied `path` straight into `@quantakrypto/core`'s `scan()`. With the\n * filesystem tools enabled (`QUANTAKRYPTO_MCP_ALLOW_FS=1`) that turns the server\n * into an arbitrary-file-read oracle: `path` could be `/etc/passwd` or any tree\n * on the host (SECURITY.md warns about exactly this). This module turns that\n * warning into enforced policy:\n *\n * - **Root allow-list** (`QUANTAKRYPTO_MCP_ROOT`, `:`-separated): every scanned\n * path must resolve inside one of the configured roots. When unset, the\n * process CWD is the single implicit root.\n * - **`..` traversal rejection**: a resolved path that escapes every root is\n * refused, even if the literal string contained no `..`.\n * - **Work budgets** (`maxFiles` / `maxBytes`): bounded by default and capped,\n * so a single `scan_path` cannot exhaust host resources.\n *\n * Everything here is a pure function of an env snapshot + the requested path so\n * it is fully unit-testable; only {@link resolveFsConfig} reads `process.env`.\n */\n\nimport * as path from \"node:path\";\nimport process from \"node:process\";\nimport { realpath } from \"node:fs/promises\";\n\n/** Minimal env shape so the resolver stays pure and testable. */\nexport type FsEnv = Record<string, string | undefined>;\n\n/** Default file-count budget for a single FS tool call. */\nexport const DEFAULT_MAX_FILES = 25_000;\n\n/** Hard cap on the file-count budget, even when raised via env. */\nexport const MAX_MAX_FILES = 250_000;\n\n/** Default cumulative-bytes budget for a single FS tool call (256 MiB). */\nexport const DEFAULT_MAX_BYTES = 256 * 1024 * 1024;\n\n/** Hard cap on the cumulative-bytes budget, even when raised via env (2 GiB). */\nexport const MAX_MAX_BYTES = 2 * 1024 * 1024 * 1024;\n\n/** Resolved FS-tool policy: where scans may read and how much work they may do. */\nexport interface FsConfig {\n /**\n * Absolute, normalized roots a scan may read inside. Always non-empty; defaults\n * to `[process.cwd()]` when `QUANTAKRYPTO_MCP_ROOT` is unset.\n */\n roots: string[];\n /** Max files a single scan may read before {@link BudgetExceededError}. */\n maxFiles: number;\n /** Max cumulative bytes a single scan may read before {@link BudgetExceededError}. */\n maxBytes: number;\n}\n\n/** Parse a positive integer from an env string, clamped to `[1, cap]`. */\nfunction toBudget(value: string | undefined, fallback: number, cap: number): number {\n if (value === undefined) return Math.min(fallback, cap);\n const n = Number(value);\n if (!Number.isFinite(n) || n <= 0) return Math.min(fallback, cap);\n return Math.min(Math.floor(n), cap);\n}\n\n/** Split the `:`-separated root allow-list, dropping empty segments. */\nfunction parseRoots(value: string | undefined, cwd: string): string[] {\n const raw = (value ?? \"\")\n .split(path.delimiter)\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n const list = raw.length > 0 ? raw : [cwd];\n // Normalize to absolute, de-duplicated roots.\n const seen = new Set<string>();\n const roots: string[] = [];\n for (const r of list) {\n const abs = path.resolve(cwd, r);\n if (!seen.has(abs)) {\n seen.add(abs);\n roots.push(abs);\n }\n }\n return roots;\n}\n\n/**\n * Resolve the FS-tool policy from an env snapshot. Pure aside from the supplied\n * `cwd` default (so callers/tests can pin it).\n */\nexport function resolveFsConfig(env: FsEnv, cwd: string = process.cwd()): FsConfig {\n return {\n roots: parseRoots(env.QUANTAKRYPTO_MCP_ROOT, cwd),\n maxFiles: toBudget(env.QUANTAKRYPTO_MCP_MAX_FILES, DEFAULT_MAX_FILES, MAX_MAX_FILES),\n maxBytes: toBudget(env.QUANTAKRYPTO_MCP_MAX_BYTES, DEFAULT_MAX_BYTES, MAX_MAX_BYTES),\n };\n}\n\n/** Outcome of validating a requested path against the root allow-list. */\nexport type PathDecision = { ok: true; path: string } | { ok: false; reason: string };\n\n/** True when `child` is `root` itself or lives beneath it (no `..` escape). */\nfunction isInsideRoot(child: string, root: string): boolean {\n if (child === root) return true;\n const rel = path.relative(root, child);\n // `rel` starting with \"..\" (or being absolute) means `child` escapes `root`.\n return rel.length > 0 && !rel.startsWith(\"..\") && !path.isAbsolute(rel);\n}\n\n/**\n * Re-verify containment against the REAL (symlink-resolved) paths. The lexical\n * check in {@link resolveScanPath} trusts path strings, but a symlink planted\n * inside an allowed root can point outside it (`<root>/link -> /etc`), and the\n * walker `stat`s through symlinks. Resolving both the target and the roots with\n * `realpath` closes that escape (audit: mcp #1). Falls back to the lexical path\n * when `realpath` fails (e.g. the path doesn't exist yet) — the scan then fails\n * with ENOENT as before, never reads out of root.\n */\nexport async function realpathInsideRoots(resolved: string, config: FsConfig): Promise<boolean> {\n const real = await realpath(resolved).catch(() => resolved);\n const realRoots = await Promise.all(config.roots.map((r) => realpath(r).catch(() => r)));\n return realRoots.some((root) => isInsideRoot(real, root));\n}\n\n/**\n * Validate and resolve a caller-supplied scan path against the allow-list.\n *\n * Relative paths are resolved against the FIRST configured root (the primary\n * scan root), not the process CWD, so a relative request can never reach outside\n * the allow-list. Absolute paths must already sit inside a configured root. Any\n * path that resolves outside every root — whether via an absolute path or a\n * `..` traversal — is rejected. Pure: does no filesystem I/O (it does not follow\n * symlinks; the allow-list is the trust boundary).\n */\nexport function resolveScanPath(config: FsConfig, requested: string): PathDecision {\n const trimmed = requested.trim();\n if (trimmed.length === 0) {\n return { ok: false, reason: \"path must be a non-empty string\" };\n }\n\n const primaryRoot = config.roots[0];\n const resolved = path.isAbsolute(trimmed)\n ? path.resolve(trimmed)\n : path.resolve(primaryRoot, trimmed);\n\n for (const root of config.roots) {\n if (isInsideRoot(resolved, root)) {\n return { ok: true, path: resolved };\n }\n }\n return {\n ok: false,\n reason:\n \"path is outside the configured scan root(s). \" +\n \"Set QUANTAKRYPTO_MCP_ROOT to allow-list the directories the MCP may scan.\",\n };\n}\n"]}
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * quantakrypto MCP — hostable HTTP transport (Streamable-HTTP-style JSON-RPC).\n *\n * A zero-dependency {@link node:http} server that exposes the same\n * {@link McpServer} over HTTP so the quantakrypto MCP can run as a remote service:\n *\n * POST /mcp — body is a single JSON-RPC 2.0 message; the JSON-RPC\n * response is returned as the 200 response body\n * (`application/json`). Notifications get HTTP 202 with no body.\n * GET /health — liveness probe, returns `{ status: \"ok\", ... }`.\n *\n * This is the minimal-but-working core of the MCP Streamable HTTP transport.\n * The full spec also supports an SSE response (`text/event-stream`) for\n * server-initiated messages; this server speaks the JSON request/response half,\n * which is sufficient for stateless tool calls. See HOSTING.md for the\n * production design (auth, multi-tenant sessions, rate limiting, scaling).\n *\n * SAFE-BY-DEFAULT POSTURE (P0-1). Unlike the stdio transport — which trusts the\n * local user and stays fully featured — the HTTP transport is hardened because a\n * hosted endpoint is reachable by untrusted peers:\n *\n * - Binds to 127.0.0.1 by default (NOT 0.0.0.0). Override with QUANTAKRYPTO_MCP_HOST.\n * - Bearer-token auth: when QUANTAKRYPTO_MCP_TOKEN is set, every /mcp request must\n * send `Authorization: Bearer <token>` (else 401). Binding to a non-loopback\n * host WITHOUT a token is refused at startup (it would be an open relay).\n * - The filesystem tools (scan_path, inventory_crypto, generate_cbom) read\n * arbitrary server paths and are DISABLED over HTTP unless QUANTAKRYPTO_MCP_ALLOW_FS=1\n * (security audit Q-01). The knowledge tools (explain_finding, suggest_hybrid,\n * list_rules) are always available. Gating is enforced by registering only the\n * permitted tools, so tools/list and tools/call both reflect it.\n * - Per-request timeout (QUANTAKRYPTO_MCP_TIMEOUT_MS) and a response-size cap\n * (QUANTAKRYPTO_MCP_MAX_RESPONSE_BYTES), in addition to the 1 MiB request-body cap.\n *\n * Run with `node dist/http.js` (PORT/QUANTAKRYPTO_MCP_* from env).\n */\n\nimport { createServer } from \"node:http\";\nimport type { IncomingMessage, Server, ServerResponse } from \"node:http\";\nimport { createHash, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport process from \"node:process\";\n\nimport { createQuantakryptoServer } from \"./index.js\";\nimport { ErrorCode, makeFailure } from \"./protocol.js\";\nimport type { JsonRpcResponse, ToolDefinition } from \"./protocol.js\";\nimport { quantakryptoTools, FS_TOOL_NAMES } from \"./tools.js\";\nimport type { McpServer } from \"./server.js\";\n\n/** Header carrying the MCP session id (per the Streamable HTTP transport). */\nexport const SESSION_HEADER = \"mcp-session-id\";\n\n/** Maximum accepted request body size (1 MiB) — a basic abuse guard. */\nconst MAX_BODY_BYTES = 1024 * 1024;\n\n/** Default per-request tool-execution deadline (ms). */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/** Default cap on the serialized response body (4 MiB). */\nconst DEFAULT_MAX_RESPONSE_BYTES = 4 * 1024 * 1024;\n\n/** Loopback hosts that are safe to bind without authentication. */\nconst LOOPBACK_HOSTS = new Set([\"127.0.0.1\", \"::1\", \"localhost\"]);\n\nexport interface HttpServerOptions {\n /** Port to listen on. Defaults to env PORT or 3000. */\n port?: number;\n /** Host/interface to bind. Defaults to QUANTAKRYPTO_MCP_HOST / HOST or \"127.0.0.1\". */\n host?: string;\n /** Bearer token required on /mcp. Defaults to QUANTAKRYPTO_MCP_TOKEN (empty = none). */\n token?: string;\n /** Expose the filesystem tools over HTTP. Defaults to QUANTAKRYPTO_MCP_ALLOW_FS=1. */\n allowFs?: boolean;\n /** Per-request tool-execution timeout (ms). Defaults to QUANTAKRYPTO_MCP_TIMEOUT_MS. */\n timeoutMs?: number;\n /** Response-body size cap (bytes). Defaults to QUANTAKRYPTO_MCP_MAX_RESPONSE_BYTES. */\n maxResponseBytes?: number;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Pure policy (P0-1) — host/auth/tool-gating decisions, fully unit-testable. */\n/* -------------------------------------------------------------------------- */\n\n/** A minimal env shape so the config resolver is pure and testable. */\nexport type HttpEnv = Record<string, string | undefined>;\n\n/** Resolved, validated HTTP transport configuration. */\nexport interface HttpConfig {\n host: string;\n port: number;\n /** The bearer token, or \"\" when auth is disabled. */\n token: string;\n /** Whether the filesystem tools are exposed over HTTP. */\n allowFs: boolean;\n timeoutMs: number;\n maxResponseBytes: number;\n /** True when the host is a loopback interface (safe without auth). */\n loopback: boolean;\n /**\n * Extra origin hosts to allow on `POST /mcp` (lower-cased hostnames), beyond\n * the implicit loopback set and the bind host. From QUANTAKRYPTO_MCP_ALLOW_ORIGIN.\n */\n allowedOrigins: string[];\n}\n\n/**\n * Resolve the HTTP transport config from env + explicit overrides. Pure: does\n * no I/O and never reads `process` directly. Overrides win over env.\n */\nexport function resolveHttpConfig(env: HttpEnv, options: HttpServerOptions = {}): HttpConfig {\n const host = options.host ?? env.QUANTAKRYPTO_MCP_HOST ?? env.HOST ?? \"127.0.0.1\";\n const port = options.port ?? toInt(env.PORT, 3000);\n const token = (options.token ?? env.QUANTAKRYPTO_MCP_TOKEN ?? \"\").trim();\n const allowFs =\n options.allowFs ??\n (env.QUANTAKRYPTO_MCP_ALLOW_FS === \"1\" || env.QUANTAKRYPTO_MCP_ALLOW_FS === \"true\");\n const timeoutMs = options.timeoutMs ?? toInt(env.QUANTAKRYPTO_MCP_TIMEOUT_MS, DEFAULT_TIMEOUT_MS);\n const maxResponseBytes =\n options.maxResponseBytes ??\n toInt(env.QUANTAKRYPTO_MCP_MAX_RESPONSE_BYTES, DEFAULT_MAX_RESPONSE_BYTES);\n const allowedOrigins = parseOriginList(env.QUANTAKRYPTO_MCP_ALLOW_ORIGIN);\n return {\n host,\n port,\n token,\n allowFs,\n timeoutMs,\n maxResponseBytes,\n loopback: isLoopbackHost(host),\n allowedOrigins,\n };\n}\n\n/**\n * Parse the comma-separated origin allow-list into lower-cased hostnames. Each\n * entry may be a bare host or a full origin URL; either way only the hostname is\n * retained (the value compared against `new URL(Origin).hostname`).\n */\nfunction parseOriginList(value: string | undefined): string[] {\n const out = new Set<string>();\n for (const raw of (value ?? \"\").split(\",\")) {\n const entry = raw.trim().toLowerCase();\n if (entry.length === 0) continue;\n try {\n out.add(new URL(entry).hostname);\n } catch {\n out.add(entry); // bare hostname (no scheme).\n }\n }\n return [...out];\n}\n\n/** Parse a positive integer from an env string, falling back on bad input. */\nfunction toInt(value: string | undefined, fallback: number): number {\n if (value === undefined) return fallback;\n const n = Number(value);\n return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;\n}\n\n/** True when binding to `host` keeps the server private to this machine. */\nexport function isLoopbackHost(host: string): boolean {\n return LOOPBACK_HOSTS.has(host.trim().toLowerCase());\n}\n\n/**\n * Decide whether a non-loopback bind is permitted. A server reachable from the\n * network MUST require auth; binding wide-open without a token would be an open,\n * unauthenticated arbitrary-tool relay. Pure decision used at startup.\n */\nexport function startupDecision(config: HttpConfig): {\n ok: boolean;\n reason?: string;\n} {\n if (!config.loopback && config.token.length === 0) {\n return {\n ok: false,\n reason:\n `refusing to bind to non-loopback host \"${config.host}\" without a token. ` +\n `Set QUANTAKRYPTO_MCP_TOKEN to require Bearer auth, or bind to 127.0.0.1.`,\n };\n }\n return { ok: true };\n}\n\n/**\n * Decide whether a request's `Origin` / `Host` is acceptable, to defend the\n * default no-token loopback config against DNS-rebinding and localhost-CSRF: a\n * malicious web page can POST to `http://127.0.0.1:<port>/mcp`, but the browser\n * stamps a foreign `Origin` we can reject. Pure and testable.\n *\n * Policy:\n * - No `Origin` header (curl, a native MCP client, same-origin GET) → allow;\n * the header is a browser artifact and absence is not an attack signal here.\n * - An `Origin` present → its host must be a configured loopback host (or a\n * host explicitly added to the allow-list). A foreign origin is rejected.\n * - When the server itself binds a non-loopback interface, a token is already\n * mandatory (see {@link startupDecision}); the loopback allow-list still\n * applies but auth is the primary control there.\n */\nexport function originDecision(\n allowedHosts: ReadonlySet<string>,\n originHeader: string | undefined,\n): { ok: boolean; reason?: string } {\n const origin = (originHeader ?? \"\").trim();\n if (origin.length === 0) return { ok: true }; // non-browser client; nothing to check.\n if (origin.toLowerCase() === \"null\") {\n return { ok: false, reason: \"opaque/null Origin is not allowed\" };\n }\n let host: string;\n try {\n host = new URL(origin).hostname.toLowerCase();\n } catch {\n return { ok: false, reason: \"malformed Origin header\" };\n }\n if (allowedHosts.has(host)) return { ok: true };\n return { ok: false, reason: `Origin host \"${host}\" is not in the allow-list` };\n}\n\n/** The hosts an `Origin` may name. Loopback by default, plus the bind host. */\nexport function allowedOriginHosts(config: HttpConfig): Set<string> {\n const hosts = new Set<string>([\"127.0.0.1\", \"::1\", \"localhost\"]);\n // Allow the interface the server is actually bound to (e.g. a LAN address with\n // a token), so a same-host browser client keeps working.\n hosts.add(config.host.trim().toLowerCase());\n for (const extra of config.allowedOrigins) hosts.add(extra);\n return hosts;\n}\n\n/** A request-authorization outcome. */\nexport interface AuthDecision {\n authorized: boolean;\n /** HTTP status to use when not authorized. */\n status?: number;\n message?: string;\n}\n\n/**\n * Decide whether a request is authorized given the configured token and the\n * incoming Authorization header. When no token is configured, all requests are\n * allowed (the loopback / trusted-edge case). Pure and testable.\n */\nexport function authorizeRequest(\n token: string,\n authorizationHeader: string | undefined,\n): AuthDecision {\n if (token.length === 0) return { authorized: true };\n const header = (authorizationHeader ?? \"\").trim();\n const match = /^Bearer\\s+(.+)$/i.exec(header);\n const presented = match?.[1]?.trim();\n if (!presented) {\n return { authorized: false, status: 401, message: \"missing bearer token\" };\n }\n if (!timingSafeEqualStr(presented, token)) {\n return { authorized: false, status: 401, message: \"invalid bearer token\" };\n }\n return { authorized: true };\n}\n\n/**\n * Constant-time string compare. Both inputs are hashed with the same algorithm\n * to fixed-length digests before {@link timingSafeEqual}, so the comparison runs\n * over equal-length buffers and the early length-mismatch return (which leaked\n * the configured token's length) is gone. The hashing is a domain-separation /\n * length-equalization step, not a secrecy measure: `timingSafeEqual` still does\n * the constant-time work and rejects unequal digests.\n */\nexport function timingSafeEqualStr(a: string, b: string): boolean {\n const ha = createHash(\"sha256\").update(a, \"utf8\").digest();\n const hb = createHash(\"sha256\").update(b, \"utf8\").digest();\n // Same algorithm ⇒ identical digest length ⇒ timingSafeEqual never throws.\n return timingSafeEqual(ha, hb);\n}\n\n/**\n * Select the tools to expose over HTTP for a given policy. The knowledge tools\n * are always returned; the filesystem tools are included only when\n * `allowFs` is true. Pure function of its inputs — the single source of truth\n * for HTTP tool gating, so tools/list and tools/call stay consistent.\n */\nexport function gateHttpTools(\n tools: readonly ToolDefinition[],\n allowFs: boolean,\n): ToolDefinition[] {\n const fsNames = new Set(FS_TOOL_NAMES);\n return tools.filter((t) => allowFs || !fsNames.has(t.name));\n}\n\n/* -------------------------------------------------------------------------- */\n/* HTTP plumbing */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Error thrown by {@link readBody} when the request body exceeds the size cap.\n * Distinguished from a transport/I/O error so the caller can map it to HTTP 413\n * specifically, while genuine read failures map to 400/500 (M1).\n */\nexport class BodyTooLargeError extends Error {\n override readonly name = \"BodyTooLargeError\";\n constructor(message = \"request body too large\") {\n super(message);\n }\n}\n\n/**\n * Read a request body fully, enforcing the size cap. Resolves to the raw string.\n * Rejects with a {@link BodyTooLargeError} when the cap is exceeded, and with the\n * original transport error (an I/O failure) otherwise — the two are mapped to\n * different HTTP statuses by the caller (M1).\n */\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n let size = 0;\n let done = false;\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk: Buffer) => {\n if (done) return;\n size += chunk.length;\n if (size > MAX_BODY_BYTES) {\n // Stop consuming and reject. We deliberately do NOT destroy the socket\n // here: the caller still needs to flush a 413 response, so it owns the\n // teardown (resume-and-drain) once that response is written.\n done = true;\n req.pause();\n reject(new BodyTooLargeError());\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => {\n if (!done) resolve(Buffer.concat(chunks).toString(\"utf8\"));\n });\n req.on(\"error\", (err: Error) => {\n if (!done) {\n done = true;\n reject(err);\n }\n });\n });\n}\n\n/** Write a JSON response with the given status and optional extra headers. */\nfunction sendJson(\n res: ServerResponse,\n status: number,\n body: unknown,\n headers: Record<string, string> = {},\n): void {\n const payload = JSON.stringify(body);\n res.writeHead(status, {\n \"content-type\": \"application/json; charset=utf-8\",\n \"content-length\": Buffer.byteLength(payload).toString(),\n ...headers,\n });\n res.end(payload);\n}\n\n/** Error raised by {@link withTimeout} when the request deadline elapses. */\nexport class RequestTimeoutError extends Error {\n override readonly name = \"RequestTimeoutError\";\n constructor(message = \"request timed out\") {\n super(message);\n }\n}\n\n/**\n * Race a handler against a deadline. On timeout the returned promise rejects with\n * a {@link RequestTimeoutError} AND the supplied {@link AbortController} is\n * aborted, so the in-flight work (a `scan()` wired to `controller.signal`) stops\n * cooperatively instead of running unbounded in the background after the 504.\n *\n * The controller is always aborted once the race settles (success, failure, or\n * timeout) so no scan keeps running past its response.\n */\nfunction withTimeout<T>(promise: Promise<T>, ms: number, controller: AbortController): Promise<T> {\n if (!(ms > 0)) return promise;\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n controller.abort(); // cancel the underlying scan — no leaked background work.\n reject(new RequestTimeoutError());\n }, ms);\n timer.unref?.();\n promise.then(\n (value) => {\n clearTimeout(timer);\n controller.abort(); // settle the signal so nothing lingers post-response.\n resolve(value);\n },\n (err: unknown) => {\n clearTimeout(timer);\n controller.abort();\n reject(err instanceof Error ? err : new Error(String(err)));\n },\n );\n });\n}\n\n/**\n * Build (but do not start) the HTTP server wrapping an {@link McpServer}.\n * Exposed for testing and for embedding in a larger process. The `config`\n * carries the resolved auth / timeout / response-cap policy.\n */\nexport function createHttpServer(server: McpServer, config: HttpConfig): Server {\n return createServer((req, res) => {\n void handleRequest(server, config, req, res).catch((err: unknown) => {\n // Last-resort handler: log the detail locally, return a generic message so\n // a remote caller never sees server internals (paths, stack traces).\n logServerError(\"unhandled request error\", err);\n if (!res.headersSent) {\n sendJson(res, 500, makeFailure(null, ErrorCode.InternalError, \"internal error\"));\n } else {\n res.end();\n }\n });\n });\n}\n\n/** Log a server-side error detail to stderr (never sent to the remote caller). */\nfunction logServerError(context: string, err: unknown): void {\n const detail = err instanceof Error ? (err.stack ?? err.message) : String(err);\n process.stderr.write(`quantakrypto MCP (http): ${context}: ${detail}\\n`);\n}\n\n/** Extract the (single) `Origin` request header, if present. */\nfunction originHeader(req: IncomingMessage): string | undefined {\n const value = req.headers.origin;\n return Array.isArray(value) ? value[0] : value;\n}\n\n/** Route and handle a single HTTP request. */\nasync function handleRequest(\n server: McpServer,\n config: HttpConfig,\n req: IncomingMessage,\n res: ServerResponse,\n): Promise<void> {\n const url = req.url ?? \"/\";\n const method = req.method ?? \"GET\";\n const path = url.split(\"?\")[0];\n\n if (method === \"GET\" && path === \"/health\") {\n sendJson(res, 200, { status: \"ok\", server: \"quantakrypto\", transport: \"http\" });\n return;\n }\n\n if (path === \"/mcp\") {\n if (method !== \"POST\") {\n // The full transport also allows GET for an SSE stream; we don't here.\n sendJson(res, 405, makeFailure(null, ErrorCode.InvalidRequest, \"method not allowed\"), {\n allow: \"POST\",\n });\n return;\n }\n // DNS-rebinding / localhost-CSRF guard: reject a foreign browser Origin\n // BEFORE auth/body, so the default no-token loopback config is not a\n // confused deputy for a malicious web page. (P0 — origin validation.)\n const origin = originDecision(allowedOriginHosts(config), originHeader(req));\n if (!origin.ok) {\n sendJson(\n res,\n 403,\n makeFailure(null, ErrorCode.InvalidRequest, origin.reason ?? \"forbidden origin\"),\n );\n return;\n }\n // Authenticate BEFORE reading the body or dispatching (Q-02).\n const auth = authorizeRequest(config.token, req.headers.authorization);\n if (!auth.authorized) {\n sendJson(\n res,\n auth.status ?? 401,\n makeFailure(null, ErrorCode.InvalidRequest, auth.message ?? \"unauthorized\"),\n { \"www-authenticate\": \"Bearer\" },\n );\n return;\n }\n await handleMcpPost(server, config, req, res);\n return;\n }\n\n sendJson(res, 404, makeFailure(null, ErrorCode.MethodNotFound, \"not found\"));\n}\n\n/** Handle `POST /mcp`: parse one JSON-RPC message, dispatch, return the result. */\nasync function handleMcpPost(\n server: McpServer,\n config: HttpConfig,\n req: IncomingMessage,\n res: ServerResponse,\n): Promise<void> {\n // Session handling (stateless here): echo a provided session id, else mint one.\n // A production server would look this up in a session store — see HOSTING.md.\n const incomingSession = req.headers[SESSION_HEADER];\n const sessionId =\n (Array.isArray(incomingSession) ? incomingSession[0] : incomingSession) ?? randomUUID();\n const sessionHeaders = { [SESSION_HEADER]: sessionId };\n\n let raw: string;\n try {\n raw = await readBody(req);\n } catch (err) {\n // M1: only the size-cap rejection is a 413. A genuine transport/I/O error\n // (the client aborted, a socket reset) is a 400 — it is the request that\n // failed, not a server fault — and never echoes the raw error text.\n if (err instanceof BodyTooLargeError) {\n // Flush the 413 first, then tear down the connection so a still-uploading\n // client stops sending. Destroying on `finish` guarantees the response is\n // written before the socket goes away (avoids a connection-reset race).\n res.on(\"finish\", () => req.destroy());\n sendJson(res, 413, makeFailure(null, ErrorCode.InvalidRequest, \"request body too large\"), {\n ...sessionHeaders,\n connection: \"close\",\n });\n } else {\n logServerError(\"error reading request body\", err);\n sendJson(\n res,\n 400,\n makeFailure(null, ErrorCode.InvalidRequest, \"error reading request body\"),\n sessionHeaders,\n );\n }\n return;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n sendJson(res, 400, makeFailure(null, ErrorCode.ParseError, \"parse error\"), sessionHeaders);\n return;\n }\n\n // Cancellation: the controller's signal is threaded into the tool handler (and\n // thus into `scan()`); withTimeout aborts it on deadline so a timed-out\n // request stops the underlying work instead of leaking it (P0 — timeout/abort).\n const controller = new AbortController();\n let response: JsonRpcResponse | null;\n try {\n response = await withTimeout(\n server.handle(parsed, { signal: controller.signal }),\n config.timeoutMs,\n controller,\n );\n } catch (err) {\n if (err instanceof RequestTimeoutError) {\n sendJson(\n res,\n 504,\n makeFailure(null, ErrorCode.InternalError, \"request timed out\"),\n sessionHeaders,\n );\n } else {\n // server.handle never rejects in practice (it catches internally), but be\n // defensive and never leak a raw message.\n logServerError(\"error dispatching request\", err);\n sendJson(\n res,\n 500,\n makeFailure(null, ErrorCode.InternalError, \"internal error\"),\n sessionHeaders,\n );\n }\n return;\n }\n\n if (response === null) {\n // Notification — acknowledge with 202 and no body.\n res.writeHead(202, sessionHeaders);\n res.end();\n return;\n }\n\n // Enforce the response-size cap (Q-03): never stream back an unbounded body.\n const serialized = JSON.stringify(response);\n if (Buffer.byteLength(serialized) > config.maxResponseBytes) {\n sendJson(\n res,\n 500,\n makeFailure(null, ErrorCode.InternalError, \"response too large\"),\n sessionHeaders,\n );\n return;\n }\n sendJson(res, 200, response, sessionHeaders);\n}\n\n/**\n * Build the HTTP-facing {@link McpServer}: the same server used over stdio but\n * with the filesystem tools gated per policy. Exposed for tests.\n */\nexport function createHttpMcpServer(config: HttpConfig): McpServer {\n return createQuantakryptoServer({ tools: gateHttpTools(quantakryptoTools, config.allowFs) });\n}\n\n/** Start the HTTP server, resolving once it is listening. */\nexport function startHttpServer(options: HttpServerOptions = {}): Promise<Server> {\n const config = resolveHttpConfig(process.env, options);\n\n const decision = startupDecision(config);\n if (!decision.ok) {\n return Promise.reject(new Error(decision.reason ?? \"refusing to start\"));\n }\n if (!config.loopback) {\n process.stderr.write(\n `quantakrypto MCP (http): WARNING binding to non-loopback host ${config.host}; ` +\n `Bearer auth is required and active.\\n`,\n );\n }\n\n const mcp = createHttpMcpServer(config);\n const httpServer = createHttpServer(mcp, config);\n return new Promise((resolve) => {\n httpServer.listen(config.port, config.host, () => {\n const auth = config.token ? \"bearer-auth\" : \"no-auth\";\n const fs = config.allowFs ? \"fs-tools:on\" : \"fs-tools:off\";\n process.stderr.write(\n `quantakrypto MCP server (http) listening on http://${config.host}:${config.port} ` +\n `[${auth}, ${fs}]\\n`,\n );\n process.stderr.write(\n ` POST http://${config.host}:${config.port}/mcp ` +\n `GET http://${config.host}:${config.port}/health\\n`,\n );\n resolve(httpServer);\n });\n });\n}\n\n/** Entry point when run directly. */\nfunction main(): void {\n startHttpServer().catch((err: unknown) => {\n const messageText = err instanceof Error ? err.message : String(err);\n process.stderr.write(`quantakrypto MCP (http) failed to start: ${messageText}\\n`);\n process.exitCode = 1;\n });\n}\n\n/** True when this module is the program's entry point (handles symlinks). */\nfunction isMainModule(): boolean {\n const argv1 = process.argv[1];\n if (!argv1) return false;\n const thisPath = fileURLToPath(import.meta.url);\n try {\n return realpathSync(argv1) === realpathSync(thisPath);\n } catch {\n return argv1 === thisPath;\n }\n}\n\n// Only auto-run when invoked as a script, not when imported by tests.\nif (isMainModule()) {\n main();\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -16,7 +16,7 @@ export type { JsonRpcRequest, JsonRpcResponse, JsonRpcSuccess, JsonRpcFailure, T
16
16
  /** The MCP server name advertised to clients. */
17
17
  export declare const SERVER_NAME = "quantakrypto";
18
18
  /** The version reported by the server (kept in sync with @quantakrypto/core). */
19
- export declare const SERVER_VERSION = "0.4.1";
19
+ export declare const SERVER_VERSION = "0.4.3";
20
20
  export interface CreateServerOptions {
21
21
  /** Override the advertised server version (defaults to @quantakrypto/core VERSION). */
22
22
  version?: string;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,SAAS,EACT,QAAQ,EACR,UAAU,EACV,WAAW,GACZ,MAAM,eAAe,CAAC;AAcvB,iDAAiD;AACjD,MAAM,CAAC,MAAM,WAAW,GAAG,cAAc,CAAC;AAE1C,iFAAiF;AACjF,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAStC;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CAAC,UAA+B,EAAE;IACxE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,cAAc,EAAE;QACvE,YAAY,EACV,8EAA8E;YAC9E,0EAA0E;YAC1E,oEAAoE;YACpE,0CAA0C;KAC7C,CAAC,CAAC;IACH,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,IAAI,iBAAiB,EAAE,CAAC;QACtD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,SAAS,EACT,QAAQ,EACR,UAAU,EACV,WAAW,GACZ,MAAM,eAAe,CAAC;AAcvB,iDAAiD;AACjD,MAAM,CAAC,MAAM,WAAW,GAAG,cAAc,CAAC;AAE1C,iFAAiF;AACjF,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAStC;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CAAC,UAA+B,EAAE;IACxE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,cAAc,EAAE;QACvE,YAAY,EACV,8EAA8E;YAC9E,0EAA0E;YAC1E,oEAAoE;YACpE,0CAA0C;KAC7C,CAAC,CAAC;IACH,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,IAAI,iBAAiB,EAAE,CAAC;QACtD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["/**\n * @quantakrypto/mcp — public API.\n *\n * Exports the transport-agnostic {@link McpServer}, the quantakrypto tool set, and a\n * {@link createQuantakryptoServer} factory that wires them together. Transports\n * (stdio, http) consume the factory; tests drive the server's `handle` method\n * directly.\n */\n\nimport { VERSION } from \"@quantakrypto/core\";\n\nimport { McpServer } from \"./server.js\";\nimport { quantakryptoTools } from \"./tools.js\";\n\nexport { McpServer } from \"./server.js\";\nexport type { McpServerOptions, ServerInfo } from \"./server.js\";\nexport { quantakryptoTools, CORE_VERSION } from \"./tools.js\";\nexport {\n MCP_PROTOCOL_VERSION,\n JSONRPC_VERSION,\n ErrorCode,\n RpcError,\n textResult,\n errorResult,\n} from \"./protocol.js\";\nexport type {\n JsonRpcRequest,\n JsonRpcResponse,\n JsonRpcSuccess,\n JsonRpcFailure,\n ToolDefinition,\n ToolDescriptor,\n ToolResult,\n Content,\n TextContent,\n JsonSchema,\n} from \"./protocol.js\";\n\n/** The MCP server name advertised to clients. */\nexport const SERVER_NAME = \"quantakrypto\";\n\n/** The version reported by the server (kept in sync with @quantakrypto/core). */\nexport const SERVER_VERSION = VERSION;\n\nexport interface CreateServerOptions {\n /** Override the advertised server version (defaults to @quantakrypto/core VERSION). */\n version?: string;\n /** Override or extend the registered tool set (defaults to all quantakrypto tools). */\n tools?: typeof quantakryptoTools;\n}\n\n/**\n * Create a fully-wired quantakrypto {@link McpServer} with all tools registered.\n *\n * @example\n * ```ts\n * const server = createQuantakryptoServer();\n * const res = await server.handle({ jsonrpc: \"2.0\", id: 1, method: \"tools/list\" });\n * ```\n */\nexport function createQuantakryptoServer(options: CreateServerOptions = {}): McpServer {\n const server = new McpServer({\n info: { name: SERVER_NAME, version: options.version ?? SERVER_VERSION },\n instructions:\n \"quantakrypto checks code for quantum-vulnerable cryptography and recommends \" +\n \"post-quantum (NIST PQC) migrations. Use scan_path / inventory_crypto to \" +\n \"assess a path, list_rules to see detectors, and explain_finding / \" +\n \"suggest_hybrid for remediation guidance.\",\n });\n for (const tool of options.tools ?? quantakryptoTools) {\n server.registerTool(tool);\n }\n return server;\n}\n"]}
@@ -56,6 +56,8 @@ export declare const ErrorCode: {
56
56
  readonly MethodNotFound: -32601;
57
57
  readonly InvalidParams: -32602;
58
58
  readonly InternalError: -32603;
59
+ /** MCP: resource not found (`resources/read` for an unknown URI). */
60
+ readonly ResourceNotFound: -32002;
59
61
  };
60
62
  /** An error that carries a JSON-RPC error code, thrown by tool handlers/dispatch. */
61
63
  export declare class RpcError extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
package/dist/protocol.js CHANGED
@@ -23,6 +23,8 @@ export const ErrorCode = {
23
23
  MethodNotFound: -32601,
24
24
  InvalidParams: -32602,
25
25
  InternalError: -32603,
26
+ /** MCP: resource not found (`resources/read` for an unknown URI). */
27
+ ResourceNotFound: -32002,
26
28
  };
27
29
  /** An error that carries a JSON-RPC error code, thrown by tool handlers/dispatch. */
28
30
  export class RpcError extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAc,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAqB,CAAC;AA8C1D,gEAAgE;AAChE,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,UAAU,EAAE,CAAC,KAAK;IAClB,cAAc,EAAE,CAAC,KAAK;IACtB,cAAc,EAAE,CAAC,KAAK;IACtB,aAAa,EAAE,CAAC,KAAK;IACrB,aAAa,EAAE,CAAC,KAAK;CACb,CAAC;AAEX,qFAAqF;AACrF,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAS;IACb,IAAI,CAAW;IACxB,YAAY,IAAY,EAAE,OAAe,EAAE,IAAc;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,4CAA4C;AAC5C,MAAM,UAAU,WAAW,CAAC,EAAa,EAAE,MAAe;IACxD,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;AAClD,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,WAAW,CACzB,EAAa,EACb,IAAY,EACZ,OAAe,EACf,IAAc;IAEd,MAAM,KAAK,GAAuB,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACpD,IAAI,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IAC1C,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;AACjD,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,OAAO,CAAC,CAAC,OAAO,KAAK,eAAe,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;AACvE,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,cAAc,CAAC,GAAmB;IAChD,OAAO,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC;AAChD,CAAC;AA4DD,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CAAC,GAAG,KAAe;IAC3C,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;AACpE,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAc,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAqB,CAAC;AA8C1D,gEAAgE;AAChE,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,UAAU,EAAE,CAAC,KAAK;IAClB,cAAc,EAAE,CAAC,KAAK;IACtB,cAAc,EAAE,CAAC,KAAK;IACtB,aAAa,EAAE,CAAC,KAAK;IACrB,aAAa,EAAE,CAAC,KAAK;IACrB,qEAAqE;IACrE,gBAAgB,EAAE,CAAC,KAAK;CAChB,CAAC;AAEX,qFAAqF;AACrF,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAS;IACb,IAAI,CAAW;IACxB,YAAY,IAAY,EAAE,OAAe,EAAE,IAAc;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,4CAA4C;AAC5C,MAAM,UAAU,WAAW,CAAC,EAAa,EAAE,MAAe;IACxD,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;AAClD,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,WAAW,CACzB,EAAa,EACb,IAAY,EACZ,OAAe,EACf,IAAc;IAEd,MAAM,KAAK,GAAuB,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACpD,IAAI,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IAC1C,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;AACjD,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,OAAO,CAAC,CAAC,OAAO,KAAK,eAAe,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;AACvE,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,cAAc,CAAC,GAAmB;IAChD,OAAO,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC;AAChD,CAAC;AA4DD,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CAAC,GAAG,KAAe;IAC3C,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;AACpE,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC9D,CAAC","sourcesContent":["/**\n * JSON-RPC 2.0 + Model Context Protocol (MCP) wire types.\n *\n * This module is pure type/shape definitions plus a few small helpers for\n * constructing valid JSON-RPC responses and errors. It has no runtime\n * dependencies and no I/O — the transport layers (stdio, http) and the\n * {@link McpServer} build on top of it.\n *\n * Reference: JSON-RPC 2.0 (https://www.jsonrpc.org/specification) and the\n * Model Context Protocol specification (https://modelcontextprotocol.io).\n */\n\n/** The fixed JSON-RPC protocol marker. */\nexport const JSONRPC_VERSION = \"2.0\" as const;\n\n/**\n * MCP protocol revision this server speaks. The `initialize` handshake echoes\n * the client's requested version when we support it, otherwise advertises this.\n */\nexport const MCP_PROTOCOL_VERSION = \"2025-06-18\" as const;\n\n/** A JSON-RPC id: string or number per spec (we never originate notifications). */\nexport type JsonRpcId = string | number | null;\n\n/** Any JSON value. Kept structural rather than `any` for strict mode. */\nexport type JsonValue =\n | null\n | boolean\n | number\n | string\n | JsonValue[]\n | { [key: string]: JsonValue };\n\n/** A JSON-RPC 2.0 request or notification (notifications omit `id`). */\nexport interface JsonRpcRequest {\n jsonrpc: typeof JSONRPC_VERSION;\n /** Absent for notifications. */\n id?: JsonRpcId;\n method: string;\n params?: Record<string, unknown> | unknown[];\n}\n\n/** A successful JSON-RPC response. */\nexport interface JsonRpcSuccess {\n jsonrpc: typeof JSONRPC_VERSION;\n id: JsonRpcId;\n result: unknown;\n}\n\n/** A JSON-RPC error object. */\nexport interface JsonRpcErrorObject {\n code: number;\n message: string;\n data?: unknown;\n}\n\n/** A failed JSON-RPC response. */\nexport interface JsonRpcFailure {\n jsonrpc: typeof JSONRPC_VERSION;\n id: JsonRpcId;\n error: JsonRpcErrorObject;\n}\n\nexport type JsonRpcResponse = JsonRpcSuccess | JsonRpcFailure;\n\n/** Standard JSON-RPC 2.0 error codes (plus MCP conventions). */\nexport const ErrorCode = {\n ParseError: -32700,\n InvalidRequest: -32600,\n MethodNotFound: -32601,\n InvalidParams: -32602,\n InternalError: -32603,\n /** MCP: resource not found (`resources/read` for an unknown URI). */\n ResourceNotFound: -32002,\n} as const;\n\n/** An error that carries a JSON-RPC error code, thrown by tool handlers/dispatch. */\nexport class RpcError extends Error {\n readonly code: number;\n readonly data?: unknown;\n constructor(code: number, message: string, data?: unknown) {\n super(message);\n this.name = \"RpcError\";\n this.code = code;\n this.data = data;\n }\n}\n\n/** Build a successful response envelope. */\nexport function makeSuccess(id: JsonRpcId, result: unknown): JsonRpcSuccess {\n return { jsonrpc: JSONRPC_VERSION, id, result };\n}\n\n/** Build a failure response envelope. */\nexport function makeFailure(\n id: JsonRpcId,\n code: number,\n message: string,\n data?: unknown,\n): JsonRpcFailure {\n const error: JsonRpcErrorObject = { code, message };\n if (data !== undefined) error.data = data;\n return { jsonrpc: JSONRPC_VERSION, id, error };\n}\n\n/** Narrow an unknown parsed value to something request-shaped enough to dispatch. */\nexport function isJsonRpcRequestLike(value: unknown): value is JsonRpcRequest {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n return v.jsonrpc === JSONRPC_VERSION && typeof v.method === \"string\";\n}\n\n/** True when a request is a notification (no `id` field present). */\nexport function isNotification(req: JsonRpcRequest): boolean {\n return !(\"id\" in req) || req.id === undefined;\n}\n\n// ---------------------------------------------------------------------------\n// MCP content + tool shapes\n// ---------------------------------------------------------------------------\n\n/** A single piece of MCP content. We only emit text content in this server. */\nexport interface TextContent {\n type: \"text\";\n text: string;\n}\n\nexport type Content = TextContent;\n\n/** The result envelope returned by a `tools/call`. */\nexport interface ToolResult {\n content: Content[];\n /** True when the tool ran but produced an error result (vs. a protocol error). */\n isError?: boolean;\n}\n\n/** A minimal JSON Schema object describing a tool's input. */\nexport interface JsonSchema {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n [key: string]: unknown;\n}\n\n/** The public descriptor of a tool, as returned by `tools/list`. */\nexport interface ToolDescriptor {\n name: string;\n description: string;\n inputSchema: JsonSchema;\n}\n\n/**\n * Per-call context threaded from the transport into a tool handler. Carries the\n * cooperative-cancellation signal so a long-running tool (e.g. a filesystem\n * scan) can be aborted when the transport's request deadline fires, instead of\n * leaking unbounded background work after a 504/timeout.\n */\nexport interface ToolContext {\n /** Fires when the caller's request deadline elapses; abort in-flight work. */\n signal?: AbortSignal;\n}\n\n/** A registered tool: descriptor plus its async handler. */\nexport interface ToolDefinition extends ToolDescriptor {\n /**\n * Executes the tool with already-parsed arguments and an optional per-call\n * {@link ToolContext} (e.g. an `AbortSignal` for the request deadline).\n */\n handler: (\n args: Record<string, unknown>,\n context?: ToolContext,\n ) => Promise<ToolResult> | ToolResult;\n}\n\n/** Convenience: wrap one or more strings as a non-error text tool result. */\nexport function textResult(...parts: string[]): ToolResult {\n return { content: parts.map((text) => ({ type: \"text\", text })) };\n}\n\n/** Convenience: wrap a string as an error text tool result. */\nexport function errorResult(text: string): ToolResult {\n return { content: [{ type: \"text\", text }], isError: true };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAUvE,MAAM,CAAC,MAAM,SAAS,GAAyB;IAC7C;QACE,GAAG,EAAE,sBAAsB;QAC3B,IAAI,EAAE,2BAA2B;QACjC,WAAW,EACT,gGAAgG;QAClG,QAAQ,EAAE,kBAAkB;KAC7B;IACD;QACE,GAAG,EAAE,gCAAgC;QACrC,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,kFAAkF;QAC/F,QAAQ,EAAE,eAAe;KAC1B;CACF,CAAC;AAEF,MAAM,eAAe,GAAG;;;;;;;;;;;;;;EActB,gBAAgB;CACjB,CAAC;AAEF,oEAAoE;AACpE,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,GAAG,KAAK,sBAAsB,EAAE,CAAC;QACnC,OAAO;YACL,GAAG;YACH,QAAQ,EAAE,kBAAkB;YAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;SAC7D,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,KAAK,gCAAgC,EAAE,CAAC;QAC7C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AASD,MAAM,CAAC,MAAM,OAAO,GAAuB;IACzC;QACE,IAAI,EAAE,SAAS;QACf,WAAW,EACT,mFAAmF;QACrF,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,2BAA2B,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;KACzF;CACF,CAAC;AAQF,0DAA0D;AAC1D,MAAM,UAAU,SAAS,CACvB,IAAY,EACZ,IAA6B;IAE7B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1E,MAAM,IAAI,GACR,WAAW,IAAI,sEAAsE;QACrF,yBAAyB,IAAI,MAAM;QACnC,sFAAsF;QACtF,uFAAuF;QACvF,0EAA0E;QAC1E,sFAAsF,CAAC;IACzF,OAAO;QACL,WAAW,EAAE,0CAA0C;QACvD,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;KAC9D,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAUvE,MAAM,CAAC,MAAM,SAAS,GAAyB;IAC7C;QACE,GAAG,EAAE,sBAAsB;QAC3B,IAAI,EAAE,2BAA2B;QACjC,WAAW,EACT,gGAAgG;QAClG,QAAQ,EAAE,kBAAkB;KAC7B;IACD;QACE,GAAG,EAAE,gCAAgC;QACrC,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,kFAAkF;QAC/F,QAAQ,EAAE,eAAe;KAC1B;CACF,CAAC;AAEF,MAAM,eAAe,GAAG;;;;;;;;;;;;;;EActB,gBAAgB;CACjB,CAAC;AAEF,oEAAoE;AACpE,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,GAAG,KAAK,sBAAsB,EAAE,CAAC;QACnC,OAAO;YACL,GAAG;YACH,QAAQ,EAAE,kBAAkB;YAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;SAC7D,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,KAAK,gCAAgC,EAAE,CAAC;QAC7C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AASD,MAAM,CAAC,MAAM,OAAO,GAAuB;IACzC;QACE,IAAI,EAAE,SAAS;QACf,WAAW,EACT,mFAAmF;QACrF,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,2BAA2B,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;KACzF;CACF,CAAC;AAQF,0DAA0D;AAC1D,MAAM,UAAU,SAAS,CACvB,IAAY,EACZ,IAA6B;IAE7B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1E,MAAM,IAAI,GACR,WAAW,IAAI,sEAAsE;QACrF,yBAAyB,IAAI,MAAM;QACnC,sFAAsF;QACtF,uFAAuF;QACvF,0EAA0E;QAC1E,sFAAsF,CAAC;IACzF,OAAO;QACL,WAAW,EAAE,0CAA0C;QACvD,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;KAC9D,CAAC;AACJ,CAAC","sourcesContent":["/**\n * MCP resources + prompts. Resources expose read-only reference data (the full\n * rule catalog + a migration guide); the prompt gives a client a one-call\n * \"migrate this path\" workflow that drives the deterministic tools. All offline\n * and static — no filesystem, no network, no key.\n */\nimport { defaultRegistry, REMEDIATE_RUBRIC } from \"@quantakrypto/core\";\n\n/** A resource descriptor for `resources/list`. */\nexport interface ResourceDescriptor {\n uri: string;\n name: string;\n description: string;\n mimeType: string;\n}\n\nexport const RESOURCES: ResourceDescriptor[] = [\n {\n uri: \"quantakrypto://rules\",\n name: \"Quantakrypto rule catalog\",\n description:\n \"Every detection rule quantakrypto can emit (id, title, severity, category, HNDL, remediation).\",\n mimeType: \"application/json\",\n },\n {\n uri: \"quantakrypto://guide/migration\",\n name: \"PQC migration guide\",\n description: \"How to migrate quantum-vulnerable cryptography using the quantakrypto MCP tools.\",\n mimeType: \"text/markdown\",\n },\n];\n\nconst MIGRATION_GUIDE = `# Post-Quantum Migration with quantakrypto\n\nA safe, deterministic loop (\"the model proposes, the engine disposes\"):\n\n1. **Inventory** — call \\`scan_path\\` on the target to list quantum-vulnerable findings.\n2. **Triage** — call \\`triage_findings\\` for the bundle, decide an exposure verdict per\n finding, then \\`apply_triage\\` to rank them (harvest-now-decrypt-later first).\n3. **Remediate** — call \\`remediate_findings\\`; for each finding propose the corrected\n full file, then \\`verify_fix\\` on your result. Keep ONLY fixes that clear the finding\n and introduce no new one. Skip any file containing secrets.\n4. Open a **draft** PR for review. Never auto-merge.\n\n## Remediation rubric\n\n${REMEDIATE_RUBRIC}\n`;\n\n/** Read a resource body by URI, or null when the URI is unknown. */\nexport function readResource(uri: string): { uri: string; mimeType: string; text: string } | null {\n if (uri === \"quantakrypto://rules\") {\n return {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify(defaultRegistry.ruleCatalog(), null, 2),\n };\n }\n if (uri === \"quantakrypto://guide/migration\") {\n return { uri, mimeType: \"text/markdown\", text: MIGRATION_GUIDE };\n }\n return null;\n}\n\n/** A prompt descriptor for `prompts/list`. */\nexport interface PromptDescriptor {\n name: string;\n description: string;\n arguments?: { name: string; description: string; required?: boolean }[];\n}\n\nexport const PROMPTS: PromptDescriptor[] = [\n {\n name: \"migrate\",\n description:\n \"Plan and apply a post-quantum migration for a path using the deterministic tools.\",\n arguments: [{ name: \"path\", description: \"Path to scan (default: .)\", required: false }],\n },\n];\n\n/** A prompt message (MCP `prompts/get` shape). */\nexport interface PromptMessage {\n role: \"user\";\n content: { type: \"text\"; text: string };\n}\n\n/** Materialize a prompt by name, or null when unknown. */\nexport function getPrompt(\n name: string,\n args: Record<string, unknown>,\n): { description: string; messages: PromptMessage[] } | null {\n if (name !== \"migrate\") return null;\n const path = typeof args.path === \"string\" && args.path ? args.path : \".\";\n const text =\n `Migrate ${path} off quantum-vulnerable cryptography using the quantakrypto tools.\\n` +\n `1) Call scan_path on \"${path}\".\\n` +\n `2) Call triage_findings, decide exposure verdicts, then apply_triage to rank them.\\n` +\n `3) For each finding: call remediate_findings, propose the corrected full file, then\\n` +\n ` verify_fix on your result — keep only fixes that clear the finding.\\n` +\n `Never touch files containing secrets; never auto-merge — open a draft PR for review.`;\n return {\n description: \"Plan and apply a post-quantum migration.\",\n messages: [{ role: \"user\", content: { type: \"text\", text } }],\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAY,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9E,8EAA8E;AAC9E,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,QAAQ,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,oEAAoE;IACpE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,uEAAuE;IACvE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,iEAAiE;IACjE,GAAG,EAAE,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,YAAY,CAAC;CACxD;AAyBD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAwDxD;AAED,mFAAmF;AACnF,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EASxC,CAAC"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAY,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9E,8EAA8E;AAC9E,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,QAAQ,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,oEAAoE;IACpE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,uEAAuE;IACvE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,iEAAiE;IACjE,GAAG,EAAE,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,YAAY,CAAC;CACxD;AAyBD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAyDxD;AAED,mFAAmF;AACnF,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EASxC,CAAC"}
package/dist/rules.js CHANGED
@@ -74,8 +74,9 @@ export function resolveRule(ruleId) {
74
74
  via: "index",
75
75
  };
76
76
  }
77
- // 2. Non-detector supplement (dependency scanner, …).
78
- const extra = EXTRA_RULES[id];
77
+ // 2. Non-detector supplement (dependency scanner, …). `hasOwn` guards against
78
+ // a rule id like `__proto__`/`constructor` resolving to an Object.prototype member.
79
+ const extra = Object.hasOwn(EXTRA_RULES, id) ? EXTRA_RULES[id] : undefined;
79
80
  if (extra) {
80
81
  return { ruleId: id, algorithm: extra.algorithm, via: "index" };
81
82
  }
package/dist/rules.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAiBhE;;;;GAIG;AACH,MAAM,WAAW,GAAmD;IAClE,gBAAgB,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE;CAC3C,CAAC;AAEF,mFAAmF;AACnF,SAAS,WAAW;IAClB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE;QAChB,IAAI,CAAC;YACH,OAAO,eAAe,CAAC,GAAG,EAAE,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IACL,KAAK,MAAM,CAAC,IAAI,GAAG;QAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAEzB,qEAAqE;IACrE,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE;QAClB,IAAI,CAAC;YACH,OAAO,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IACL,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;YACL,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE;YAC5E,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,SAAS;YAC5C,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,GAAG,EAAE,OAAO;SACb,CAAC;IACJ,CAAC;IAED,sDAAsD;IACtD,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAClE,CAAC;IAED,MAAM,aAAa,GAAG,WAAW,EAAE,CAAC;IAEpC,wBAAwB;IACxB,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;YACL,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE;YAC1D,GAAG,EAAE,aAAa;SACnB,CAAC;IACJ,CAAC;IAED,0EAA0E;IAC1E,IAAI,IAA0B,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;QACzC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM;gBAAE,IAAI,GAAG,GAAG,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,IAAI,IAAI,EAAE,CAAC;QACT,OAAO;YACL,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;YACxD,GAAG,EAAE,QAAQ;SACd,CAAC;IACJ,CAAC;IAED,iBAAiB;IACjB,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;AAC3C,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,MAAM,cAAc,GAAsB,CAAC,GAAG,EAAE;IACrD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,KAAK,MAAM,CAAC,IAAI,eAAe,CAAC,WAAW,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,qEAAqE;IACvE,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC,CAAC,EAAE,CAAC"}
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Rule resolution for {@link explain_finding}.\n *\n * Core's detectors are coarse-grained: a single {@link Detector} (e.g. the\n * `crypto-libs` detector) emits many distinct `ruleId`s (`forge-rsa-keygen`,\n * `elliptic-ec`, `node-rsa`, …) that do NOT share the detector's `id` as a\n * prefix. The old MCP `explain_finding` matched `ruleId` against `detector.id`\n * by prefix and therefore returned \"no matching detector\" for every real\n * library finding (P0-5).\n *\n * This module resolves a finding's `ruleId` against core's rule catalog\n * ({@link defaultRegistry.ruleCatalog}) — the single source of truth declared by\n * the detectors themselves. There is no hand-curated table to keep in sync: the\n * ruleId → { detector, algorithm } mapping is derived from the catalog at load\n * time, so a new rule added in core is resolvable here the moment it ships. The\n * one non-detector rule (`dep-vulnerable`, produced by the manifest scanner\n * rather than a {@link Detector}) is supplemented explicitly. Unknown rules fall\n * back to a prefix match against the detector id space, then to unresolved.\n * Pure and synchronous — no I/O — so it is directly unit-testable.\n */\n\nimport { defaultRegistry, detectors } from \"@quantakrypto/core\";\nimport type { AlgorithmFamily, Detector, RuleMeta } from \"@quantakrypto/core\";\n\n/** A resolved rule: the detector it belongs to (if any) and its algorithm. */\nexport interface ResolvedRule {\n /** The rule id that was looked up (echoed for convenience). */\n ruleId: string;\n /** The detector that emits this rule, when one could be resolved. */\n detector?: { id: string; description: string };\n /** The classical algorithm family the rule concerns, when known. */\n algorithm?: AlgorithmFamily;\n /** The catalog metadata for the rule, when it is a known core rule. */\n meta?: RuleMeta;\n /** How the match was made — useful for tests and diagnostics. */\n via: \"index\" | \"detector-id\" | \"prefix\" | \"unresolved\";\n}\n\n/**\n * Rules that are NOT emitted by a {@link Detector} and so are absent from the\n * catalog, but are still canonical core ruleIds. Today that is only the\n * dependency-manifest scanner's `dep-vulnerable` rule.\n */\nconst EXTRA_RULES: Record<string, { algorithm: AlgorithmFamily }> = {\n \"dep-vulnerable\": { algorithm: \"unknown\" },\n};\n\n/** Build an id → Detector lookup over the active detector set (registry first). */\nfunction detectorMap(): Map<string, Detector> {\n const map = new Map<string, Detector>();\n const all = (() => {\n try {\n return defaultRegistry.all();\n } catch {\n return detectors;\n }\n })();\n for (const d of all) map.set(d.id, d);\n return map;\n}\n\n/**\n * Resolve a finding's `ruleId` to its detector and algorithm.\n *\n * Resolution order:\n * 1. The core rule catalog — the authoritative path for every detector rule.\n * 2. The {@link EXTRA_RULES} supplement (non-detector rules, e.g. dependencies).\n * 3. Exact detector id (a rule that IS a detector id, e.g. a future 1:1 rule).\n * 4. Prefix against the detector id space (`node-crypto-*`, `pem-*`, …).\n * 5. Unresolved — caller falls back to the algorithm remediation.\n *\n * Pure: depends only on its argument and the static core detector set.\n */\nexport function resolveRule(ruleId: string): ResolvedRule {\n const id = ruleId.trim();\n\n // 1. Catalog — the authoritative path for known core detector rules.\n const entry = (() => {\n try {\n return defaultRegistry.forRule(id);\n } catch {\n return undefined;\n }\n })();\n if (entry) {\n return {\n ruleId: id,\n detector: { id: entry.detector.id, description: entry.detector.description },\n algorithm: entry.rule.algorithm ?? \"unknown\",\n meta: entry.rule,\n via: \"index\",\n };\n }\n\n // 2. Non-detector supplement (dependency scanner, …). `hasOwn` guards against\n // a rule id like `__proto__`/`constructor` resolving to an Object.prototype member.\n const extra = Object.hasOwn(EXTRA_RULES, id) ? EXTRA_RULES[id] : undefined;\n if (extra) {\n return { ruleId: id, algorithm: extra.algorithm, via: \"index\" };\n }\n\n const detectorsById = detectorMap();\n\n // 3. Exact detector id.\n const exact = detectorsById.get(id);\n if (exact) {\n return {\n ruleId: id,\n detector: { id: exact.id, description: exact.description },\n via: \"detector-id\",\n };\n }\n\n // 4. Longest-prefix detector id (e.g. `node-crypto-foo` → `node-crypto`).\n let best: Detector | undefined;\n for (const det of detectorsById.values()) {\n if (id === det.id || id.startsWith(`${det.id}-`)) {\n if (!best || det.id.length > best.id.length) best = det;\n }\n }\n if (best) {\n return {\n ruleId: id,\n detector: { id: best.id, description: best.description },\n via: \"prefix\",\n };\n }\n\n // 5. Unresolved.\n return { ruleId: id, via: \"unresolved\" };\n}\n\n/** Exposed for tests: the set of canonical rule ids resolvable via the catalog. */\nexport const KNOWN_RULE_IDS: readonly string[] = (() => {\n const ids: string[] = [];\n try {\n for (const r of defaultRegistry.ruleCatalog()) ids.push(r.id);\n } catch {\n // ignore — an empty/broken catalog just yields the supplement below.\n }\n ids.push(...Object.keys(EXTRA_RULES));\n return ids;\n})();\n"]}