@quantakrypto/mcp 0.5.0 → 0.5.2
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 +15 -1
- package/README.md +15 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +6 -0
- package/dist/server.js.map +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +78 -5
- package/dist/tools.js.map +1 -1
- package/package.json +2 -1
package/HOSTING.md
CHANGED
|
@@ -5,6 +5,17 @@ service rather than a per-user local stdio process. The shipped `src/http.ts` is
|
|
|
5
5
|
the minimal, working core of this design; everything below is the path from that
|
|
6
6
|
scaffold to production.
|
|
7
7
|
|
|
8
|
+
> **A production reference implementation of this design now exists — and it's
|
|
9
|
+
> live.** [`quantakrypto/mcp-gateway`](https://github.com/quantakrypto/mcp-gateway)
|
|
10
|
+
> runs at **`https://mcp.quantakrypto.com/mcp`** and realises §2–§7 below:
|
|
11
|
+
> [Better Auth](https://better-auth.com) as the **OAuth 2.1** provider (§3, Google
|
|
12
|
+
> + GitHub + email, 30-day tokens), accounts/sessions/tokens in Postgres (§2), and
|
|
13
|
+
> the filesystem/network tools withheld over HTTP (§0). Connect a client with
|
|
14
|
+
> `claude mcp add --transport http quantakrypto https://mcp.quantakrypto.com/mcp`.
|
|
15
|
+
> Read that repo as the worked example of everything described here; the sections
|
|
16
|
+
> below remain the reference for *why* each control exists (and for running your
|
|
17
|
+
> own).
|
|
18
|
+
|
|
8
19
|
## 0. Safe-by-default posture (what `src/http.ts` enforces today)
|
|
9
20
|
|
|
10
21
|
The stdio transport trusts the local user and is fully featured. The HTTP
|
|
@@ -142,7 +153,10 @@ stdio trusts the local user; a hosted endpoint must not.
|
|
|
142
153
|
- **OAuth 2.1.** The MCP spec defines an OAuth flow for HTTP transports
|
|
143
154
|
(Protected Resource Metadata + Authorization Server). For first-party clients,
|
|
144
155
|
scoped API keys are simpler; add OAuth when third-party clients must connect on
|
|
145
|
-
a user's behalf.
|
|
156
|
+
a user's behalf. **This is what the hosted [`mcp-gateway`](https://github.com/quantakrypto/mcp-gateway)
|
|
157
|
+
does** — Better Auth publishes the discovery metadata and runs the
|
|
158
|
+
authorize/token endpoints, and the `/mcp` route validates the Bearer token in
|
|
159
|
+
the same process via `withMcpAuth`.
|
|
146
160
|
- **mTLS / network policy.** For internal/enterprise deployments, terminate mTLS
|
|
147
161
|
at the gateway and keep `/mcp` private.
|
|
148
162
|
- Never log request bodies that may contain source code; treat scanned content
|
package/README.md
CHANGED
|
@@ -10,7 +10,9 @@ cryptography and recommends NIST post-quantum / hybrid migrations, all backed by
|
|
|
10
10
|
The only dependency is `@quantakrypto/core`.
|
|
11
11
|
- **Two transports.** A `stdio` transport (the `quantakrypto-mcp` bin) for local agents
|
|
12
12
|
like Claude, and a hostable `http` transport for running quantakrypto as a remote
|
|
13
|
-
service (see [HOSTING.md](./HOSTING.md)).
|
|
13
|
+
service (see [HOSTING.md](./HOSTING.md)). quantakrypto also runs a **hosted,
|
|
14
|
+
OAuth-gated instance at [`mcp.quantakrypto.com`](https://mcp.quantakrypto.com/mcp)**
|
|
15
|
+
you can connect to directly — see [Hosted HTTP server](#hosted-http-server-safe-by-default).
|
|
14
16
|
- **Transport-agnostic core.** All protocol logic lives in a pure, unit-tested
|
|
15
17
|
`McpServer` class; transports only do I/O.
|
|
16
18
|
|
|
@@ -191,6 +193,18 @@ the `initialize` capabilities, all offline/static):
|
|
|
191
193
|
|
|
192
194
|
## Hosted HTTP server (safe-by-default)
|
|
193
195
|
|
|
196
|
+
> **Just want to use it?** quantakrypto runs a hosted, **OAuth-gated** instance at
|
|
197
|
+
> **`https://mcp.quantakrypto.com/mcp`** — no install, no token to manage:
|
|
198
|
+
> ```bash
|
|
199
|
+
> claude mcp add --transport http quantakrypto https://mcp.quantakrypto.com/mcp
|
|
200
|
+
> ```
|
|
201
|
+
> It signs you in (Google / GitHub / email) and issues a 30-day token. Being
|
|
202
|
+
> multi-tenant, it exposes only the content-based tools — the filesystem/network
|
|
203
|
+
> tools (`scan_path`, `inventory_crypto`, `generate_cbom`, `plan_migration`,
|
|
204
|
+
> `probe_endpoint`) are withheld; run the MCP **locally** for those. Source and
|
|
205
|
+
> ops: [`quantakrypto/mcp-gateway`](https://github.com/quantakrypto/mcp-gateway).
|
|
206
|
+
> The rest of this section is for running the **package's own** `http.ts` yourself.
|
|
207
|
+
|
|
194
208
|
The same `McpServer` can be served over HTTP (a Streamable-HTTP-style JSON-RPC
|
|
195
209
|
endpoint) for remote deployments. The stdio transport trusts the local user and
|
|
196
210
|
is fully featured; the **HTTP transport is hardened**, because a hosted endpoint
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAaH,OAAO,KAAK,EAEV,eAAe,EACf,WAAW,EACX,cAAc,EACd,cAAc,EAEf,MAAM,eAAe,CAAC;AAGvB,kEAAkE;AAClE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,IAAI,EAAE,UAAU,CAAC;IACjB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAC3D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,mEAAmE;IACnE,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,EAAE,gBAAgB;IAKrC,2EAA2E;IAC3E,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAQxC,uEAAuE;IACvE,SAAS,IAAI,cAAc,EAAE;IAM7B,wDAAwD;IACxD,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED;;;;;;;;;OASG;IACG,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IA8BtF,gFAAgF;YAClE,QAAQ;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAaH,OAAO,KAAK,EAEV,eAAe,EACf,WAAW,EACX,cAAc,EACd,cAAc,EAEf,MAAM,eAAe,CAAC;AAGvB,kEAAkE;AAClE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,IAAI,EAAE,UAAU,CAAC;IACjB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAC3D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,mEAAmE;IACnE,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,EAAE,gBAAgB;IAKrC,2EAA2E;IAC3E,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAQxC,uEAAuE;IACvE,SAAS,IAAI,cAAc,EAAE;IAM7B,wDAAwD;IACxD,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED;;;;;;;;;OASG;IACG,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IA8BtF,gFAAgF;YAClE,QAAQ;IAgCtB,kEAAkE;IAClE,OAAO,CAAC,eAAe;IAcvB,yEAAyE;IACzE,OAAO,CAAC,YAAY;IAiBpB,qCAAqC;IACrC,OAAO,CAAC,YAAY;IAgBpB,2DAA2D;YAC7C,WAAW;CAuB1B"}
|
package/dist/server.js
CHANGED
|
@@ -104,6 +104,12 @@ export class McpServer {
|
|
|
104
104
|
return this.onToolsCall(req.params, context);
|
|
105
105
|
case "resources/list":
|
|
106
106
|
return { resources: RESOURCES };
|
|
107
|
+
case "resources/templates/list":
|
|
108
|
+
// We advertise the `resources` capability, so spec-compliant clients
|
|
109
|
+
// (and MCP directory health checks) call this during discovery. We
|
|
110
|
+
// expose only fixed-URI resources, no URI templates → empty list, not a
|
|
111
|
+
// -32601 that trips those clients.
|
|
112
|
+
return { resourceTemplates: [] };
|
|
107
113
|
case "resources/read":
|
|
108
114
|
return this.onResourcesRead(req.params);
|
|
109
115
|
case "prompts/list":
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Transport-agnostic MCP server core.\n *\n * {@link McpServer} owns a tool registry and a single pure entry point,\n * {@link McpServer.handle}, that turns one JSON-RPC message into one JSON-RPC\n * response (or `null` for notifications, which get no reply). It performs no\n * I/O whatsoever — the stdio and http transports feed it parsed messages and\n * serialize whatever it returns. This makes the whole protocol surface\n * unit-testable by calling `handle` directly.\n *\n * The one concession to I/O is that unexpected (non-{@link RpcError}) throws are\n * logged to stderr with full detail and replaced with a generic message in the\n * response, so server internals (paths, ENOENT targets) never reach the remote\n * caller. The wire response remains a pure function of the inputs.\n */\n\nimport process from \"node:process\";\n\nimport {\n ErrorCode,\n MCP_PROTOCOL_VERSION,\n RpcError,\n isJsonRpcRequestLike,\n isNotification,\n makeFailure,\n makeSuccess,\n} from \"./protocol.js\";\nimport type {\n JsonRpcRequest,\n JsonRpcResponse,\n ToolContext,\n ToolDefinition,\n ToolDescriptor,\n ToolResult,\n} from \"./protocol.js\";\nimport { RESOURCES, PROMPTS, readResource, getPrompt } from \"./resources.js\";\n\n/** Identifying info advertised to clients during `initialize`. */\nexport interface ServerInfo {\n name: string;\n version: string;\n}\n\nexport interface McpServerOptions {\n /** Server identity returned in the `initialize` handshake. */\n info: ServerInfo;\n /** Optional human-readable instructions surfaced to the client. */\n instructions?: string;\n}\n\n/**\n * A minimal, spec-faithful MCP server. Register tools with {@link registerTool}\n * and drive it one message at a time with {@link handle}.\n */\nexport class McpServer {\n private readonly tools = new Map<string, ToolDefinition>();\n private readonly info: ServerInfo;\n private readonly instructions?: string;\n /** Set once `initialize` has been received; informational only. */\n private initialized = false;\n\n constructor(options: McpServerOptions) {\n this.info = options.info;\n this.instructions = options.instructions;\n }\n\n /** Register a tool. Throws if a tool with the same name already exists. */\n registerTool(tool: ToolDefinition): this {\n if (this.tools.has(tool.name)) {\n throw new Error(`duplicate tool registration: ${tool.name}`);\n }\n this.tools.set(tool.name, tool);\n return this;\n }\n\n /** The public descriptors of all registered tools (sorted by name). */\n listTools(): ToolDescriptor[] {\n return [...this.tools.values()]\n .map(({ name, description, inputSchema }) => ({ name, description, inputSchema }))\n .sort((a, b) => a.name.localeCompare(b.name));\n }\n\n /** Whether the `initialize` handshake has completed. */\n get isInitialized(): boolean {\n return this.initialized;\n }\n\n /**\n * Process a single JSON-RPC message.\n *\n * @param message An already-parsed JSON value (the transport handles framing\n * and `JSON.parse`). May be malformed; this method validates it.\n * @param context Optional per-call context (e.g. an `AbortSignal` for the\n * transport's request deadline) forwarded to the invoked tool handler.\n * @returns The response to send back, or `null` when no reply is due\n * (notifications, or an unparseable notification-shaped message).\n */\n async handle(message: unknown, context?: ToolContext): Promise<JsonRpcResponse | null> {\n if (!isJsonRpcRequestLike(message)) {\n // Not a valid request object. We can't know its id, so reply with null id.\n return makeFailure(null, ErrorCode.InvalidRequest, \"invalid JSON-RPC request\");\n }\n\n const req = message as JsonRpcRequest;\n const notification = isNotification(req);\n const id = notification ? null : (req.id ?? null);\n\n try {\n const result = await this.dispatch(req, context);\n // Notifications never receive a response, even on success.\n if (notification) return null;\n return makeSuccess(id, result);\n } catch (err) {\n if (notification) return null; // swallow errors from notifications\n if (err instanceof RpcError) {\n // RpcError messages are author-controlled validation strings, safe to return.\n return makeFailure(id, err.code, err.message, err.data);\n }\n // An unexpected throw may carry a server-side detail (a filesystem path, an\n // ENOENT for /etc/shadow, …). Log the detail locally; return a generic\n // message so the remote caller never learns server internals.\n const detail = err instanceof Error ? (err.stack ?? err.message) : String(err);\n process.stderr.write(`quantakrypto MCP: internal error handling request: ${detail}\\n`);\n return makeFailure(id, ErrorCode.InternalError, \"internal error\");\n }\n }\n\n /** Route a request to the right handler. Throws {@link RpcError} on failure. */\n private async dispatch(req: JsonRpcRequest, context?: ToolContext): Promise<unknown> {\n switch (req.method) {\n case \"initialize\":\n return this.onInitialize();\n case \"notifications/initialized\":\n this.initialized = true;\n return {}; // notification → result ignored by handle()\n case \"ping\":\n return {};\n case \"tools/list\":\n return { tools: this.listTools() };\n case \"tools/call\":\n return this.onToolsCall(req.params, context);\n case \"resources/list\":\n return { resources: RESOURCES };\n case \"resources/read\":\n return this.onResourcesRead(req.params);\n case \"prompts/list\":\n return { prompts: PROMPTS };\n case \"prompts/get\":\n return this.onPromptsGet(req.params);\n default:\n throw new RpcError(ErrorCode.MethodNotFound, `method not found: ${req.method}`);\n }\n }\n\n /** `resources/read`: return the body for a known resource URI. */\n private onResourcesRead(params: unknown): unknown {\n if (typeof params !== \"object\" || params === null || Array.isArray(params)) {\n throw new RpcError(ErrorCode.InvalidParams, \"resources/read requires an object params\");\n }\n const uri = (params as { uri?: unknown }).uri;\n if (typeof uri !== \"string\" || uri.length === 0) {\n throw new RpcError(ErrorCode.InvalidParams, \"resources/read requires a 'uri' string\");\n }\n const contents = readResource(uri);\n // MCP spec: unknown resource → -32002 (Resource not found), uri in data.\n if (!contents) throw new RpcError(ErrorCode.ResourceNotFound, \"Resource not found\", { uri });\n return { contents: [contents] };\n }\n\n /** `prompts/get`: materialize a named prompt with optional arguments. */\n private onPromptsGet(params: unknown): unknown {\n if (typeof params !== \"object\" || params === null || Array.isArray(params)) {\n throw new RpcError(ErrorCode.InvalidParams, \"prompts/get requires an object params\");\n }\n const { name, arguments: args } = params as { name?: unknown; arguments?: unknown };\n if (typeof name !== \"string\" || name.length === 0) {\n throw new RpcError(ErrorCode.InvalidParams, \"prompts/get requires a 'name' string\");\n }\n const promptArgs =\n args && typeof args === \"object\" && !Array.isArray(args)\n ? (args as Record<string, unknown>)\n : {};\n const prompt = getPrompt(name, promptArgs);\n if (!prompt) throw new RpcError(ErrorCode.InvalidParams, `unknown prompt: ${name}`);\n return prompt;\n }\n\n /** Build the `initialize` result. */\n private onInitialize(): unknown {\n this.initialized = true;\n const result: Record<string, unknown> = {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: {\n // Everything we expose is static, so listChanged is false throughout.\n tools: { listChanged: false },\n resources: { listChanged: false },\n prompts: { listChanged: false },\n },\n serverInfo: { name: this.info.name, version: this.info.version },\n };\n if (this.instructions) result.instructions = this.instructions;\n return result;\n }\n\n /** Validate params and execute a tool for `tools/call`. */\n private async onToolsCall(params: unknown, context?: ToolContext): Promise<ToolResult> {\n if (typeof params !== \"object\" || params === null || Array.isArray(params)) {\n throw new RpcError(ErrorCode.InvalidParams, \"tools/call requires an object params\");\n }\n const { name, arguments: args } = params as {\n name?: unknown;\n arguments?: unknown;\n };\n if (typeof name !== \"string\" || name.length === 0) {\n throw new RpcError(ErrorCode.InvalidParams, \"tools/call requires a 'name' string\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw new RpcError(ErrorCode.InvalidParams, `unknown tool: ${name}`);\n }\n if (args !== undefined && (typeof args !== \"object\" || args === null || Array.isArray(args))) {\n throw new RpcError(ErrorCode.InvalidParams, \"tool 'arguments' must be an object\");\n }\n const toolArgs = (args ?? {}) as Record<string, unknown>;\n // Tool-level failures are reported as isError results, not protocol errors,\n // so the model can read and react to them. Only unexpected throws bubble up.\n return tool.handler(toolArgs, context);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Transport-agnostic MCP server core.\n *\n * {@link McpServer} owns a tool registry and a single pure entry point,\n * {@link McpServer.handle}, that turns one JSON-RPC message into one JSON-RPC\n * response (or `null` for notifications, which get no reply). It performs no\n * I/O whatsoever — the stdio and http transports feed it parsed messages and\n * serialize whatever it returns. This makes the whole protocol surface\n * unit-testable by calling `handle` directly.\n *\n * The one concession to I/O is that unexpected (non-{@link RpcError}) throws are\n * logged to stderr with full detail and replaced with a generic message in the\n * response, so server internals (paths, ENOENT targets) never reach the remote\n * caller. The wire response remains a pure function of the inputs.\n */\n\nimport process from \"node:process\";\n\nimport {\n ErrorCode,\n MCP_PROTOCOL_VERSION,\n RpcError,\n isJsonRpcRequestLike,\n isNotification,\n makeFailure,\n makeSuccess,\n} from \"./protocol.js\";\nimport type {\n JsonRpcRequest,\n JsonRpcResponse,\n ToolContext,\n ToolDefinition,\n ToolDescriptor,\n ToolResult,\n} from \"./protocol.js\";\nimport { RESOURCES, PROMPTS, readResource, getPrompt } from \"./resources.js\";\n\n/** Identifying info advertised to clients during `initialize`. */\nexport interface ServerInfo {\n name: string;\n version: string;\n}\n\nexport interface McpServerOptions {\n /** Server identity returned in the `initialize` handshake. */\n info: ServerInfo;\n /** Optional human-readable instructions surfaced to the client. */\n instructions?: string;\n}\n\n/**\n * A minimal, spec-faithful MCP server. Register tools with {@link registerTool}\n * and drive it one message at a time with {@link handle}.\n */\nexport class McpServer {\n private readonly tools = new Map<string, ToolDefinition>();\n private readonly info: ServerInfo;\n private readonly instructions?: string;\n /** Set once `initialize` has been received; informational only. */\n private initialized = false;\n\n constructor(options: McpServerOptions) {\n this.info = options.info;\n this.instructions = options.instructions;\n }\n\n /** Register a tool. Throws if a tool with the same name already exists. */\n registerTool(tool: ToolDefinition): this {\n if (this.tools.has(tool.name)) {\n throw new Error(`duplicate tool registration: ${tool.name}`);\n }\n this.tools.set(tool.name, tool);\n return this;\n }\n\n /** The public descriptors of all registered tools (sorted by name). */\n listTools(): ToolDescriptor[] {\n return [...this.tools.values()]\n .map(({ name, description, inputSchema }) => ({ name, description, inputSchema }))\n .sort((a, b) => a.name.localeCompare(b.name));\n }\n\n /** Whether the `initialize` handshake has completed. */\n get isInitialized(): boolean {\n return this.initialized;\n }\n\n /**\n * Process a single JSON-RPC message.\n *\n * @param message An already-parsed JSON value (the transport handles framing\n * and `JSON.parse`). May be malformed; this method validates it.\n * @param context Optional per-call context (e.g. an `AbortSignal` for the\n * transport's request deadline) forwarded to the invoked tool handler.\n * @returns The response to send back, or `null` when no reply is due\n * (notifications, or an unparseable notification-shaped message).\n */\n async handle(message: unknown, context?: ToolContext): Promise<JsonRpcResponse | null> {\n if (!isJsonRpcRequestLike(message)) {\n // Not a valid request object. We can't know its id, so reply with null id.\n return makeFailure(null, ErrorCode.InvalidRequest, \"invalid JSON-RPC request\");\n }\n\n const req = message as JsonRpcRequest;\n const notification = isNotification(req);\n const id = notification ? null : (req.id ?? null);\n\n try {\n const result = await this.dispatch(req, context);\n // Notifications never receive a response, even on success.\n if (notification) return null;\n return makeSuccess(id, result);\n } catch (err) {\n if (notification) return null; // swallow errors from notifications\n if (err instanceof RpcError) {\n // RpcError messages are author-controlled validation strings, safe to return.\n return makeFailure(id, err.code, err.message, err.data);\n }\n // An unexpected throw may carry a server-side detail (a filesystem path, an\n // ENOENT for /etc/shadow, …). Log the detail locally; return a generic\n // message so the remote caller never learns server internals.\n const detail = err instanceof Error ? (err.stack ?? err.message) : String(err);\n process.stderr.write(`quantakrypto MCP: internal error handling request: ${detail}\\n`);\n return makeFailure(id, ErrorCode.InternalError, \"internal error\");\n }\n }\n\n /** Route a request to the right handler. Throws {@link RpcError} on failure. */\n private async dispatch(req: JsonRpcRequest, context?: ToolContext): Promise<unknown> {\n switch (req.method) {\n case \"initialize\":\n return this.onInitialize();\n case \"notifications/initialized\":\n this.initialized = true;\n return {}; // notification → result ignored by handle()\n case \"ping\":\n return {};\n case \"tools/list\":\n return { tools: this.listTools() };\n case \"tools/call\":\n return this.onToolsCall(req.params, context);\n case \"resources/list\":\n return { resources: RESOURCES };\n case \"resources/templates/list\":\n // We advertise the `resources` capability, so spec-compliant clients\n // (and MCP directory health checks) call this during discovery. We\n // expose only fixed-URI resources, no URI templates → empty list, not a\n // -32601 that trips those clients.\n return { resourceTemplates: [] };\n case \"resources/read\":\n return this.onResourcesRead(req.params);\n case \"prompts/list\":\n return { prompts: PROMPTS };\n case \"prompts/get\":\n return this.onPromptsGet(req.params);\n default:\n throw new RpcError(ErrorCode.MethodNotFound, `method not found: ${req.method}`);\n }\n }\n\n /** `resources/read`: return the body for a known resource URI. */\n private onResourcesRead(params: unknown): unknown {\n if (typeof params !== \"object\" || params === null || Array.isArray(params)) {\n throw new RpcError(ErrorCode.InvalidParams, \"resources/read requires an object params\");\n }\n const uri = (params as { uri?: unknown }).uri;\n if (typeof uri !== \"string\" || uri.length === 0) {\n throw new RpcError(ErrorCode.InvalidParams, \"resources/read requires a 'uri' string\");\n }\n const contents = readResource(uri);\n // MCP spec: unknown resource → -32002 (Resource not found), uri in data.\n if (!contents) throw new RpcError(ErrorCode.ResourceNotFound, \"Resource not found\", { uri });\n return { contents: [contents] };\n }\n\n /** `prompts/get`: materialize a named prompt with optional arguments. */\n private onPromptsGet(params: unknown): unknown {\n if (typeof params !== \"object\" || params === null || Array.isArray(params)) {\n throw new RpcError(ErrorCode.InvalidParams, \"prompts/get requires an object params\");\n }\n const { name, arguments: args } = params as { name?: unknown; arguments?: unknown };\n if (typeof name !== \"string\" || name.length === 0) {\n throw new RpcError(ErrorCode.InvalidParams, \"prompts/get requires a 'name' string\");\n }\n const promptArgs =\n args && typeof args === \"object\" && !Array.isArray(args)\n ? (args as Record<string, unknown>)\n : {};\n const prompt = getPrompt(name, promptArgs);\n if (!prompt) throw new RpcError(ErrorCode.InvalidParams, `unknown prompt: ${name}`);\n return prompt;\n }\n\n /** Build the `initialize` result. */\n private onInitialize(): unknown {\n this.initialized = true;\n const result: Record<string, unknown> = {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: {\n // Everything we expose is static, so listChanged is false throughout.\n tools: { listChanged: false },\n resources: { listChanged: false },\n prompts: { listChanged: false },\n },\n serverInfo: { name: this.info.name, version: this.info.version },\n };\n if (this.instructions) result.instructions = this.instructions;\n return result;\n }\n\n /** Validate params and execute a tool for `tools/call`. */\n private async onToolsCall(params: unknown, context?: ToolContext): Promise<ToolResult> {\n if (typeof params !== \"object\" || params === null || Array.isArray(params)) {\n throw new RpcError(ErrorCode.InvalidParams, \"tools/call requires an object params\");\n }\n const { name, arguments: args } = params as {\n name?: unknown;\n arguments?: unknown;\n };\n if (typeof name !== \"string\" || name.length === 0) {\n throw new RpcError(ErrorCode.InvalidParams, \"tools/call requires a 'name' string\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw new RpcError(ErrorCode.InvalidParams, `unknown tool: ${name}`);\n }\n if (args !== undefined && (typeof args !== \"object\" || args === null || Array.isArray(args))) {\n throw new RpcError(ErrorCode.InvalidParams, \"tool 'arguments' must be an object\");\n }\n const toolArgs = (args ?? {}) as Record<string, unknown>;\n // Tool-level failures are reported as isError results, not protocol errors,\n // so the model can read and react to them. Only unexpected throws bubble up.\n return tool.handler(toolArgs, context);\n }\n}\n"]}
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAyBH,OAAO,KAAK,EACV,eAAe,EAIf,WAAW,EACX,UAAU,EAGX,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAkB7E;;;;;;GAMG;AACH,iBAAS,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,CAS1D;AAkBD;;;;;;;;;GASG;AACH,iBAAe,gBAAgB,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,CAuBjF;AAED,6EAA6E;AAC7E,iBAAS,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAmB1D;AAED,gEAAgE;AAChE,iBAAS,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAmCjD;AAuQD,+EAA+E;AAC/E,iBAAS,kBAAkB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,EAAE,CA4BhE;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAyBH,OAAO,KAAK,EACV,eAAe,EAIf,WAAW,EACX,UAAU,EAGX,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAkB7E;;;;;;GAMG;AACH,iBAAS,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,CAS1D;AAkBD;;;;;;;;;GASG;AACH,iBAAe,gBAAgB,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,CAuBjF;AAED,6EAA6E;AAC7E,iBAAS,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAmB1D;AAED,gEAAgE;AAChE,iBAAS,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAmCjD;AAuQD,+EAA+E;AAC/E,iBAAS,kBAAkB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,EAAE,CA4BhE;AAy+BD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAK1C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAAuB,CAAC;AAExE,qDAAqD;AACrD,eAAO,MAAM,iBAAiB,EAAE,cAAc,EAoB7C,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,YAAY,UAAU,CAAC;AAEpC,8CAA8C;AAC9C,eAAO,MAAM,MAAM;;;;;;;cA58Be,MAAM;gBAAU,MAAM;eAAS,MAAM;;CAm9BtE,CAAC"}
|
package/dist/tools.js
CHANGED
|
@@ -824,6 +824,58 @@ const checkDependencyTool = {
|
|
|
824
824
|
};
|
|
825
825
|
},
|
|
826
826
|
};
|
|
827
|
+
/**
|
|
828
|
+
* JSON-schema shape of one finding from `scan_path --format json` (mirrors the
|
|
829
|
+
* core {@link Finding} type). Used as the `items` schema for every findings
|
|
830
|
+
* array below so MCP clients/inspectors get a described element shape instead of
|
|
831
|
+
* a bare `type: "array"`. Extra finding fields are allowed (no
|
|
832
|
+
* additionalProperties:false), only ruleId + location.file are required — which
|
|
833
|
+
* is exactly what {@link areFindings} enforces.
|
|
834
|
+
*/
|
|
835
|
+
const FINDING_ITEM_SCHEMA = {
|
|
836
|
+
type: "object",
|
|
837
|
+
description: "A single finding from `scan_path --format json`.",
|
|
838
|
+
properties: {
|
|
839
|
+
ruleId: { type: "string", description: 'Stable rule id, e.g. "rsa-keygen".' },
|
|
840
|
+
title: { type: "string" },
|
|
841
|
+
category: { type: "string" },
|
|
842
|
+
severity: { type: "string", description: "critical | high | medium | low | info." },
|
|
843
|
+
confidence: { type: "string" },
|
|
844
|
+
algorithm: { type: "string", description: "Classical algorithm family, when applicable." },
|
|
845
|
+
hndl: { type: "boolean", description: "Exposed to harvest-now-decrypt-later." },
|
|
846
|
+
message: { type: "string" },
|
|
847
|
+
remediation: { type: "string" },
|
|
848
|
+
cwe: { type: "string", description: 'e.g. "CWE-327".' },
|
|
849
|
+
location: {
|
|
850
|
+
type: "object",
|
|
851
|
+
description: "Where the finding is.",
|
|
852
|
+
properties: {
|
|
853
|
+
file: { type: "string" },
|
|
854
|
+
line: { type: "number" },
|
|
855
|
+
},
|
|
856
|
+
required: ["file"],
|
|
857
|
+
},
|
|
858
|
+
},
|
|
859
|
+
required: ["ruleId", "location"],
|
|
860
|
+
};
|
|
861
|
+
/** JSON-schema shape of one triage verdict for `apply_triage`. */
|
|
862
|
+
const VERDICT_ITEM_SCHEMA = {
|
|
863
|
+
type: "object",
|
|
864
|
+
description: "A triage verdict for one finding.",
|
|
865
|
+
properties: {
|
|
866
|
+
fingerprint: {
|
|
867
|
+
type: "string",
|
|
868
|
+
description: "Fingerprint of the finding this verdict applies to.",
|
|
869
|
+
},
|
|
870
|
+
exposureScore: {
|
|
871
|
+
type: "number",
|
|
872
|
+
description: "Real-world exposure (higher = more exposed).",
|
|
873
|
+
},
|
|
874
|
+
priority: { type: "string", enum: ["now", "soon", "later"] },
|
|
875
|
+
rationale: { type: "string", description: "Why this exposure score / priority." },
|
|
876
|
+
},
|
|
877
|
+
required: ["fingerprint", "exposureScore", "priority", "rationale"],
|
|
878
|
+
};
|
|
827
879
|
const scoreDeltaTool = {
|
|
828
880
|
name: "score_delta",
|
|
829
881
|
description: "Compute the readiness-score and HNDL change between two finding sets (e.g. before " +
|
|
@@ -834,9 +886,14 @@ const scoreDeltaTool = {
|
|
|
834
886
|
properties: {
|
|
835
887
|
before: {
|
|
836
888
|
type: "array",
|
|
889
|
+
items: FINDING_ITEM_SCHEMA,
|
|
837
890
|
description: "Findings before the change (from a scan's JSON findings).",
|
|
838
891
|
},
|
|
839
|
-
after: {
|
|
892
|
+
after: {
|
|
893
|
+
type: "array",
|
|
894
|
+
items: FINDING_ITEM_SCHEMA,
|
|
895
|
+
description: "Findings after the change.",
|
|
896
|
+
},
|
|
840
897
|
},
|
|
841
898
|
required: ["before", "after"],
|
|
842
899
|
additionalProperties: false,
|
|
@@ -918,7 +975,11 @@ const triageFindingsTool = {
|
|
|
918
975
|
inputSchema: {
|
|
919
976
|
type: "object",
|
|
920
977
|
properties: {
|
|
921
|
-
findings: {
|
|
978
|
+
findings: {
|
|
979
|
+
type: "array",
|
|
980
|
+
items: FINDING_ITEM_SCHEMA,
|
|
981
|
+
description: "Findings from a scan's JSON output.",
|
|
982
|
+
},
|
|
922
983
|
},
|
|
923
984
|
required: ["findings"],
|
|
924
985
|
additionalProperties: false,
|
|
@@ -988,8 +1049,16 @@ const applyTriageTool = {
|
|
|
988
1049
|
inputSchema: {
|
|
989
1050
|
type: "object",
|
|
990
1051
|
properties: {
|
|
991
|
-
findings: {
|
|
992
|
-
|
|
1052
|
+
findings: {
|
|
1053
|
+
type: "array",
|
|
1054
|
+
items: FINDING_ITEM_SCHEMA,
|
|
1055
|
+
description: "The findings that were triaged.",
|
|
1056
|
+
},
|
|
1057
|
+
verdicts: {
|
|
1058
|
+
type: "array",
|
|
1059
|
+
items: VERDICT_ITEM_SCHEMA,
|
|
1060
|
+
description: "One verdict per finding, keyed by fingerprint.",
|
|
1061
|
+
},
|
|
993
1062
|
},
|
|
994
1063
|
required: ["findings", "verdicts"],
|
|
995
1064
|
additionalProperties: false,
|
|
@@ -1053,7 +1122,11 @@ const remediateFindingsTool = {
|
|
|
1053
1122
|
inputSchema: {
|
|
1054
1123
|
type: "object",
|
|
1055
1124
|
properties: {
|
|
1056
|
-
findings: {
|
|
1125
|
+
findings: {
|
|
1126
|
+
type: "array",
|
|
1127
|
+
items: FINDING_ITEM_SCHEMA,
|
|
1128
|
+
description: "Findings from a scan's JSON output.",
|
|
1129
|
+
},
|
|
1057
1130
|
},
|
|
1058
1131
|
required: ["findings"],
|
|
1059
1132
|
additionalProperties: false,
|
package/dist/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * quantakrypto MCP tools, backed by {@link @quantakrypto/core}.\n *\n * Every tool returns an MCP {@link ToolResult} ({ content, isError? }). Each\n * handler runs core calls through {@link safe} so any runtime failure (a bad\n * path, a work-budget overflow, an unexpected error) surfaces as a readable\n * `isError` tool result with host details stripped, rather than a protocol-level\n * crash.\n */\n\nimport process from \"node:process\";\n\nimport {\n VERSION,\n AbortError,\n BudgetExceededError,\n buildInventory,\n buildRemediateRequest,\n buildTriageRequest,\n compareFindings,\n detectors,\n fingerprintFinding,\n isManifestFile,\n languageToExtension,\n remediateFindings,\n remediationFor,\n remediationForTier,\n scan,\n SEVERITY_ORDER,\n toCbom,\n verifyFix,\n vulnerableDependencies,\n} from \"@quantakrypto/core\";\nimport type {\n AlgorithmFamily,\n CryptoInventory,\n Finding,\n Remediation,\n ScanOptions,\n ScanResult,\n VerifyResult,\n VulnerableDependency,\n} from \"@quantakrypto/core\";\n\nimport { errorResult, textResult } from \"./protocol.js\";\nimport type { ToolContext, ToolDefinition, ToolResult } from \"./protocol.js\";\nimport { resolveRule } from \"./rules.js\";\nimport { realpathInsideRoots, resolveFsConfig, resolveScanPath } from \"./fsconfig.js\";\n\n/** All classical algorithm families we can advise on, used for validation/help. */\nconst ALGORITHM_FAMILIES: AlgorithmFamily[] = [\n \"RSA\",\n \"ECDH\",\n \"ECDSA\",\n \"EdDSA\",\n \"DH\",\n \"DSA\",\n \"X25519\",\n \"X448\",\n \"ECIES\",\n \"unknown\",\n];\n\n/**\n * Map a core failure to a caller-safe message. Cancellation and budget overflows\n * are intentional, expected outcomes — their messages are author-controlled and\n * carry no host detail, so they pass through. Every other error may embed a\n * server path (an `ENOENT … '/etc/shadow'`, a stack), so it is logged locally\n * and replaced with a generic string; the remote caller never sees internals.\n */\nfunction describeError(label: string, err: unknown): string {\n if (err instanceof AbortError) return `${label} was aborted (request timed out).`;\n if (err instanceof BudgetExceededError) {\n // Author-written, no host detail: \"maxFiles budget exceeded (limit: …)\".\n return `${label} failed: ${err.message}`;\n }\n const detail = err instanceof Error ? (err.stack ?? err.message) : String(err);\n process.stderr.write(`quantakrypto MCP: ${label} failed: ${detail}\\n`);\n return `${label} failed: an internal error occurred.`;\n}\n\n/**\n * Run a possibly-throwing core call, mapping any failure to an error tool\n * result. Returns either the value or a {@link ToolResult} sentinel. Error\n * messages are sanitized via {@link describeError} so server paths never leak.\n */\nasync function safe<T>(\n label: string,\n fn: () => T | Promise<T>,\n): Promise<{ ok: true; value: T } | { ok: false; result: ToolResult }> {\n try {\n return { ok: true, value: await fn() };\n } catch (err) {\n return { ok: false, result: errorResult(describeError(label, err)) };\n }\n}\n\n/**\n * Resolve the FS-tool policy (root allow-list + work budgets) once per call from\n * the live environment, then validate the caller's path against it and assemble\n * the {@link ScanOptions} for a confined, bounded, cancellable scan.\n *\n * Returns an `errorResult` when the path escapes the allow-list (a `..`\n * traversal or an out-of-root absolute path), so the FS tools can `return` it\n * directly. The `signal` from the transport's request deadline (when present) is\n * threaded in so a timed-out request actually aborts the underlying scan.\n */\nasync function buildScanOptions(\n requested: string,\n context?: ToolContext,\n): Promise<{ ok: true; options: ScanOptions } | { ok: false; result: ToolResult }> {\n const config = resolveFsConfig(process.env);\n const decision = resolveScanPath(config, requested);\n if (!decision.ok) {\n return { ok: false, result: errorResult(`scan rejected: ${decision.reason}`) };\n }\n // Symlink-escape hardening: re-verify containment against the real, resolved\n // paths so a symlink inside a root can't read outside it (audit: mcp #1).\n if (!(await realpathInsideRoots(decision.path, config))) {\n return {\n ok: false,\n result: errorResult(\"scan rejected: path resolves outside the configured root(s) (symlink).\"),\n };\n }\n return {\n ok: true,\n options: {\n root: decision.path,\n signal: context?.signal,\n maxFiles: config.maxFiles,\n maxBytes: config.maxBytes,\n },\n };\n}\n\n/** Map a free-text algorithm string onto a known {@link AlgorithmFamily}. */\nfunction normalizeAlgorithm(input: string): AlgorithmFamily {\n const cleaned = input\n .trim()\n .toUpperCase()\n .replace(/[\\s_-]+/g, \"\");\n for (const fam of ALGORITHM_FAMILIES) {\n if (fam.toUpperCase() === cleaned) return fam;\n }\n // Common aliases / families folded into the canonical set.\n if (cleaned.startsWith(\"RSA\")) return \"RSA\";\n if (cleaned.includes(\"ECDSA\")) return \"ECDSA\";\n if (cleaned.includes(\"ED25519\") || cleaned.includes(\"EDDSA\")) return \"EdDSA\";\n if (cleaned.includes(\"X448\") || cleaned.includes(\"CURVE448\")) return \"X448\";\n if (cleaned.includes(\"X25519\") || cleaned.includes(\"CURVE25519\")) return \"X25519\";\n if (cleaned.includes(\"ECDH\")) return \"ECDH\";\n if (cleaned.includes(\"ECIES\")) return \"ECIES\";\n if (cleaned === \"DH\" || cleaned.includes(\"DIFFIEHELLMAN\")) return \"DH\";\n if (cleaned === \"DSA\") return \"DSA\";\n return \"unknown\";\n}\n\n/** Render a scan result as a compact human-readable summary. */\nfunction summarizeScan(result: ScanResult): string {\n const inv = result.inventory;\n const lines: string[] = [];\n lines.push(`quantakrypto scan of ${result.root}`);\n lines.push(`Files scanned: ${result.filesScanned}`);\n lines.push(`Findings: ${result.findings.length}`);\n lines.push(`Readiness score: ${inv.readinessScore}/100`);\n lines.push(`Harvest-now-decrypt-later exposure: ${inv.hndlCount} finding(s)`);\n\n const sev = SEVERITY_ORDER.filter((s) => (inv.bySeverity[s] ?? 0) > 0)\n .map((s) => `${s}: ${inv.bySeverity[s]}`)\n .join(\", \");\n if (sev) lines.push(`By severity: ${sev}`);\n\n const algos = Object.entries(inv.byAlgorithm)\n .filter(([, n]) => (n ?? 0) > 0)\n .map(([a, n]) => `${a}: ${n}`)\n .join(\", \");\n if (algos) lines.push(`By algorithm: ${algos}`);\n\n if (result.findings.length > 0) {\n lines.push(\"\");\n lines.push(\"Top findings:\");\n const top = [...result.findings]\n .sort((a, b) => SEVERITY_ORDER.indexOf(a.severity) - SEVERITY_ORDER.indexOf(b.severity))\n .slice(0, 20);\n for (const f of top) {\n const loc = `${f.location.file}:${f.location.line}`;\n lines.push(`- [${f.severity}] ${f.ruleId} (${loc}) — ${f.message}`);\n }\n if (result.findings.length > top.length) {\n lines.push(`… and ${result.findings.length - top.length} more.`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Tool definitions\n// ---------------------------------------------------------------------------\n\nconst scanPathTool: ToolDefinition = {\n name: \"scan_path\",\n description:\n \"Scan a file or directory for classical (quantum-vulnerable) asymmetric \" +\n \"cryptography using quantakrypto. Returns a readiness summary and findings.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Absolute or relative path to a file or directory to scan.\",\n },\n format: {\n type: \"string\",\n enum: [\"summary\", \"json\"],\n description:\n \"Output format: 'summary' (default) for readable text, 'json' for the raw ScanResult.\",\n },\n },\n required: [\"path\"],\n additionalProperties: false,\n },\n async handler(args, context): Promise<ToolResult> {\n const path = args.path;\n if (typeof path !== \"string\" || path.length === 0) {\n return errorResult(\"scan_path requires a non-empty 'path' string.\");\n }\n const format = args.format === \"json\" ? \"json\" : \"summary\";\n const opts = await buildScanOptions(path, context);\n if (!opts.ok) return opts.result;\n const scanned = await safe(\"scan\", () => scan(opts.options));\n if (!scanned.ok) return scanned.result;\n const result = scanned.value;\n if (format === \"json\") {\n return textResult(JSON.stringify(result, null, 2));\n }\n return textResult(summarizeScan(result));\n },\n};\n\nconst inventoryCryptoTool: ToolDefinition = {\n name: \"inventory_crypto\",\n description:\n \"Produce a post-quantum readiness inventory for a path: a 0-100 readiness \" +\n \"score plus counts of cryptographic findings by algorithm, category, and severity.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Absolute or relative path to a file or directory to inventory.\",\n },\n },\n required: [\"path\"],\n additionalProperties: false,\n },\n async handler(args, context): Promise<ToolResult> {\n const path = args.path;\n if (typeof path !== \"string\" || path.length === 0) {\n return errorResult(\"inventory_crypto requires a non-empty 'path' string.\");\n }\n const opts = await buildScanOptions(path, context);\n if (!opts.ok) return opts.result;\n const scanned = await safe(\"scan\", () => scan(opts.options));\n if (!scanned.ok) return scanned.result;\n const result = scanned.value;\n\n // Prefer a freshly built inventory from findings; fall back to the scan's own.\n const built = await safe<CryptoInventory>(\"buildInventory\", () =>\n buildInventory(result.findings),\n );\n const inventory = built.ok ? built.value : result.inventory;\n\n const lines: string[] = [];\n lines.push(`Post-quantum readiness for ${result.root}`);\n lines.push(`Readiness score: ${inventory.readinessScore}/100`);\n lines.push(`HNDL exposure: ${inventory.hndlCount}`);\n lines.push(\"\");\n lines.push(\"By algorithm:\");\n for (const [algo, n] of Object.entries(inventory.byAlgorithm)) {\n if ((n ?? 0) > 0) lines.push(` ${algo}: ${n}`);\n }\n lines.push(\"By category:\");\n for (const [cat, n] of Object.entries(inventory.byCategory)) {\n if ((n ?? 0) > 0) lines.push(` ${cat}: ${n}`);\n }\n lines.push(\"By severity:\");\n for (const sev of SEVERITY_ORDER) {\n const n = inventory.bySeverity[sev] ?? 0;\n if (n > 0) lines.push(` ${sev}: ${n}`);\n }\n return {\n content: [\n { type: \"text\", text: lines.join(\"\\n\") },\n { type: \"text\", text: JSON.stringify(inventory, null, 2) },\n ],\n };\n },\n};\n\nconst explainFindingTool: ToolDefinition = {\n name: \"explain_finding\",\n description:\n \"Explain a quantakrypto finding and its post-quantum remediation. Provide a \" +\n \"ruleId (e.g. 'forge-rsa-keygen', 'elliptic-ec', 'node-rsa', 'pem-ec-private-key') \" +\n \"and/or an algorithm (e.g. 'RSA', 'ECDSA'). The ruleId is resolved against the \" +\n \"core detector set, so library and config rules explain correctly.\",\n inputSchema: {\n type: \"object\",\n properties: {\n ruleId: {\n type: \"string\",\n description: \"The finding's rule id, matching a detector id prefix.\",\n },\n algorithm: {\n type: \"string\",\n description: \"The classical algorithm family involved (e.g. RSA, ECDH, ECDSA).\",\n },\n },\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const ruleId = typeof args.ruleId === \"string\" ? args.ruleId.trim() : \"\";\n const algoInput = typeof args.algorithm === \"string\" ? args.algorithm.trim() : \"\";\n if (!ruleId && !algoInput) {\n return errorResult(\"explain_finding requires at least one of 'ruleId' or 'algorithm'.\");\n }\n\n const lines: string[] = [];\n\n // Resolve the rule against core's actual detector set/registry (P0-5),\n // not by a fragile id-prefix match. Library rules (forge-*, elliptic-ec,\n // node-rsa, …) resolve to their `crypto-libs` detector and carry their\n // algorithm, so they now explain correctly.\n let resolvedAlgorithm: AlgorithmFamily | undefined;\n if (ruleId) {\n const resolved = resolveRule(ruleId);\n resolvedAlgorithm = resolved.algorithm;\n const meta = resolved.meta;\n lines.push(`Rule: ${meta ? `${ruleId} — ${meta.title}` : ruleId}`);\n if (resolved.detector) {\n lines.push(`Detector: ${resolved.detector.id} — ${resolved.detector.description}`);\n } else if (resolved.via === \"unresolved\") {\n lines.push(\n \"No matching detector found in the catalog (rule may be unknown to this core version).\",\n );\n }\n // Rule catalog metadata (severity / category / HNDL / remediation) so the\n // explanation is actionable on its own, not just a detector pointer.\n if (meta) {\n lines.push(\n `Severity: ${meta.severity} · Category: ${meta.category} · HNDL-exposed: ${meta.hndl ? \"yes\" : \"no\"}`,\n );\n lines.push(`What it detects: ${meta.description ?? meta.message}`);\n if (meta.remediation) lines.push(`Rule remediation: ${meta.remediation}`);\n }\n }\n\n // Prefer an explicit algorithm; otherwise use the one the rule resolved to.\n const algorithm: AlgorithmFamily | undefined = algoInput\n ? normalizeAlgorithm(algoInput)\n : resolvedAlgorithm && resolvedAlgorithm !== \"unknown\"\n ? resolvedAlgorithm\n : undefined;\n\n if (algorithm) {\n if (lines.length) lines.push(\"\");\n lines.push(`Algorithm: ${algorithm}`);\n const rem = await safe<Remediation | undefined>(\"remediationFor\", () =>\n remediationFor(algorithm),\n );\n if (rem.ok && rem.value) {\n lines.push(\n `Why it matters: ${algorithm} relies on hardness assumptions (integer factorization / discrete log) that Shor's algorithm breaks on a cryptographically-relevant quantum computer.`,\n );\n lines.push(`Recommendation: ${rem.value.recommendation}`);\n lines.push(`Detail: ${rem.value.detail}`);\n } else if (rem.ok) {\n lines.push(\"No specific remediation is registered for this algorithm.\");\n } else {\n return rem.result;\n }\n }\n\n return textResult(lines.join(\"\\n\"));\n },\n};\n\nconst suggestHybridTool: ToolDefinition = {\n name: \"suggest_hybrid\",\n description:\n \"Recommend a post-quantum / hybrid migration. Provide an 'algorithm' \" +\n \"(e.g. RSA, ECDH, ECDSA) or free-text 'context' describing the usage. \" +\n \"Set 'tier' to 'category-5' for CNSA 2.0 / national-security systems.\",\n inputSchema: {\n type: \"object\",\n properties: {\n algorithm: {\n type: \"string\",\n description: \"Classical algorithm family to migrate away from.\",\n },\n context: {\n type: \"string\",\n description:\n \"Free-text description of the cryptographic usage (used when no algorithm is given).\",\n },\n tier: {\n type: \"string\",\n enum: [\"category-3\", \"category-5\"],\n description:\n \"Security tier: 'category-3' (default, commercial — ML-KEM-768 / ML-DSA-65) or \" +\n \"'category-5' (CNSA 2.0 / NSS, long-lived secrets — ML-KEM-1024 / ML-DSA-87).\",\n },\n },\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const algoInput = typeof args.algorithm === \"string\" ? args.algorithm.trim() : \"\";\n const context = typeof args.context === \"string\" ? args.context.trim() : \"\";\n if (!algoInput && !context) {\n return errorResult(\"suggest_hybrid requires either 'algorithm' or 'context'.\");\n }\n\n const algorithm = normalizeAlgorithm(algoInput || context);\n const tier =\n args.tier === \"category-5\"\n ? \"category-5\"\n : args.tier === \"category-3\"\n ? \"category-3\"\n : undefined;\n const lines: string[] = [];\n lines.push(`Migration guidance for: ${algoInput || context}`);\n lines.push(`Detected family: ${algorithm}`);\n if (tier) lines.push(`Security tier: ${tier}`);\n\n const rem = await safe<Remediation | undefined>(\"remediationFor\", () =>\n tier ? remediationForTier(algorithm, tier) : remediationFor(algorithm),\n );\n if (rem.ok && rem.value) {\n lines.push(`Recommended replacement: ${rem.value.recommendation}`);\n lines.push(`Rationale: ${rem.value.detail}`);\n } else {\n // Defensive fallback: core has a remediation for every known family, so\n // this only triggers if the lookup throws or the algorithm is unrecognised.\n lines.push(...staticHybridAdvice(algorithm));\n }\n\n lines.push(\"\");\n lines.push(\n \"Hybrid migrations combine a classical primitive with a NIST PQC algorithm \" +\n \"so security holds if either survives. Roll out hybrids first, then drop the \" +\n \"classical half once the PQC side is proven in your environment.\",\n );\n return textResult(lines.join(\"\\n\"));\n },\n};\n\n/** Built-in PQC guidance used when core's remediation table is unavailable. */\nfunction staticHybridAdvice(algorithm: AlgorithmFamily): string[] {\n switch (algorithm) {\n case \"RSA\":\n case \"ECIES\":\n return [\n \"Recommended replacement: ML-KEM-768 for key establishment (hybrid X25519MLKEM768).\",\n \"For signatures use ML-DSA-65 (Dilithium) or SLH-DSA (SPHINCS+) where statelessness matters.\",\n ];\n case \"ECDH\":\n case \"DH\":\n case \"X25519\":\n return [\n \"Recommended replacement: hybrid X25519MLKEM768 key exchange (ML-KEM-768 + X25519).\",\n \"Supported in modern TLS 1.3 stacks; prefer the hybrid named group over bare ML-KEM.\",\n ];\n case \"ECDSA\":\n case \"EdDSA\":\n case \"DSA\":\n return [\n \"Recommended replacement: ML-DSA-65 (Dilithium) for general signatures.\",\n \"Use SLH-DSA (SPHINCS+) for long-lived roots or where a stateless hash-based scheme is preferred.\",\n ];\n default:\n return [\n \"Recommended replacement: adopt NIST PQC — ML-KEM for key establishment, ML-DSA for signatures.\",\n \"Deploy as hybrids (classical + PQC) during transition.\",\n ];\n }\n}\n\nconst listRulesTool: ToolDefinition = {\n name: \"list_rules\",\n description: \"List the quantakrypto detector catalog: every detector id and what it looks for.\",\n inputSchema: {\n type: \"object\",\n properties: {},\n additionalProperties: false,\n },\n async handler(): Promise<ToolResult> {\n const detectorList = await safe(\"detectors\", () => detectors);\n if (!detectorList.ok) return detectorList.result;\n const catalog = detectorList.value.map((d) => ({ id: d.id, description: d.description }));\n if (catalog.length === 0) {\n return textResult(\n \"No detectors are registered in @quantakrypto/core yet (the catalog is empty).\",\n );\n }\n const human = catalog.map((d) => `- ${d.id}: ${d.description}`).join(\"\\n\");\n return {\n content: [\n {\n type: \"text\",\n text: `quantakrypto detector catalog (${catalog.length} rules):\\n${human}`,\n },\n { type: \"text\", text: JSON.stringify(catalog, null, 2) },\n ],\n };\n },\n};\n\nconst generateCbomTool: ToolDefinition = {\n name: \"generate_cbom\",\n description:\n \"Scan a path and emit a CycloneDX 1.6 Cryptographic Bill of Materials (CBOM) \" +\n \"of the classical cryptographic assets found, for compliance / supply-chain \" +\n \"tooling. Reads the filesystem, so it is gated like scan_path over HTTP.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Absolute or relative path to a file or directory to inventory.\",\n },\n },\n required: [\"path\"],\n additionalProperties: false,\n },\n async handler(args, context): Promise<ToolResult> {\n const path = args.path;\n if (typeof path !== \"string\" || path.length === 0) {\n return errorResult(\"generate_cbom requires a non-empty 'path' string.\");\n }\n const opts = await buildScanOptions(path, context);\n if (!opts.ok) return opts.result;\n const scanned = await safe(\"scan\", () => scan(opts.options));\n if (!scanned.ok) return scanned.result;\n const cbom = await safe(\"toCbom\", () => toCbom(scanned.value));\n if (!cbom.ok) return cbom.result;\n return textResult(JSON.stringify(cbom.value, null, 2));\n },\n};\n\n// ---------------------------------------------------------------------------\n// Copilot tools — let an AI coding agent migrate *through* the deterministic\n// engine (\"the model proposes, the engine disposes\"). plan_migration scans and\n// orders the work; get_fix_examples shows the code change; verify_fix re-runs\n// the detectors on the agent's edited code to confirm the classical crypto is\n// actually gone; check_dependency and score_delta quantify the work.\n// ---------------------------------------------------------------------------\n\n// `languageToExtension` + `verifyFix` now live in @quantakrypto/core so this tool and\n// the remediation pipeline share one definition of \"the fix is verified\".\n\n/** Before/after migration snippets per classical family. Static + deterministic. */\nconst FIX_EXAMPLES: Partial<\n Record<AlgorithmFamily, { note: string; before: string; after: string }>\n> = {\n RSA: {\n note: \"RSA key establishment → ML-KEM-768 (hybrid X25519MLKEM768). RSA signatures → ML-DSA-65.\",\n before:\n \"// key establishment\\nconst { publicKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 3072 });\\nconst enc = crypto.publicEncrypt(publicKey, data);\",\n after:\n \"// hybrid KEM (e.g. @noble/post-quantum or a TLS 1.3 hybrid group)\\nimport { MlKem768 } from 'mlkem';\\nconst kem = new MlKem768();\\nconst [encapsulated, sharedSecret] = await kem.encap(peerPublicKey); // pair with X25519 for hybrid\",\n },\n ECDH: {\n note: \"ECDH / DH key agreement → hybrid X25519MLKEM768 (ML-KEM-768 + X25519).\",\n before:\n \"const ecdh = crypto.createECDH('prime256v1');\\nconst shared = ecdh.computeSecret(peerKey);\",\n after:\n \"// TLS: negotiate the X25519MLKEM768 named group. In app code, combine ML-KEM-768\\n// with X25519 and KDF the concatenated secrets so security holds if either survives.\",\n },\n DH: {\n note: \"Finite-field DH → hybrid X25519MLKEM768.\",\n before: \"const dh = crypto.createDiffieHellman(2048);\",\n after: \"// Replace with ML-KEM-768 encapsulation, deployed as a hybrid with X25519.\",\n },\n X25519: {\n note: \"X25519 is modern but classical; wrap it in a hybrid X25519MLKEM768 rather than dropping it.\",\n before: \"const alice = crypto.generateKeyPairSync('x25519');\",\n after: \"// Keep X25519 AND add ML-KEM-768; derive the session key from both (hybrid).\",\n },\n ECDSA: {\n note: \"ECDSA signatures → ML-DSA-65 (Dilithium), or SLH-DSA where statelessness matters.\",\n before: \"const sig = crypto.sign('sha256', msg, ecPrivateKey);\",\n after:\n \"import { ml_dsa65 } from '@noble/post-quantum/ml-dsa';\\nconst sig = ml_dsa65.sign(mlDsaSecretKey, msg);\",\n },\n EdDSA: {\n note: \"Ed25519/Ed448 signatures → ML-DSA-65 (or a hybrid Ed25519+ML-DSA during transition).\",\n before: \"const sig = crypto.sign(null, msg, ed25519PrivateKey);\",\n after:\n \"import { ml_dsa65 } from '@noble/post-quantum/ml-dsa';\\nconst sig = ml_dsa65.sign(mlDsaSecretKey, msg);\",\n },\n DSA: {\n note: \"DSA is deprecated; rotate keys and migrate to ML-DSA-65.\",\n before: \"crypto.generateKeyPairSync('dsa', { modulusLength: 2048 });\",\n after:\n \"import { ml_dsa65 } from '@noble/post-quantum/ml-dsa';\\nconst keys = ml_dsa65.keygen();\",\n },\n};\n\nconst planMigrationTool: ToolDefinition = {\n name: \"plan_migration\",\n description:\n \"Scan a path and return a deterministic, prioritized post-quantum migration \" +\n \"plan: findings grouped by algorithm, ordered harvest-now-decrypt-later first, \" +\n \"each with its PQC target and the readiness-score impact. Reads the filesystem, \" +\n \"so it is gated like scan_path over HTTP.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Absolute or relative path to a file or directory to plan a migration for.\",\n },\n },\n required: [\"path\"],\n additionalProperties: false,\n },\n async handler(args, context): Promise<ToolResult> {\n const path = args.path;\n if (typeof path !== \"string\" || path.length === 0) {\n return errorResult(\"plan_migration requires a non-empty 'path' string.\");\n }\n const opts = await buildScanOptions(path, context);\n if (!opts.ok) return opts.result;\n const scanned = await safe(\"scan\", () => scan(opts.options));\n if (!scanned.ok) return scanned.result;\n const plan = await buildMigrationPlan(scanned.value);\n return {\n content: [\n { type: \"text\", text: plan.human },\n { type: \"text\", text: JSON.stringify(plan.structured, null, 2) },\n ],\n };\n },\n};\n\n/** Migration-phase buckets, ordered by urgency. */\ninterface PlanGroup {\n algorithm: AlgorithmFamily;\n count: number;\n hndlCount: number;\n remediation: string;\n locations: string[];\n}\ninterface PlanPhase {\n phase: number;\n title: string;\n rationale: string;\n groups: PlanGroup[];\n}\n\n/** Build a deterministic, prioritized migration plan from a scan result. */\nasync function buildMigrationPlan(\n result: ScanResult,\n): Promise<{ human: string; structured: Record<string, unknown> }> {\n const findings = result.findings;\n const byPhase: Record<number, Finding[]> = { 1: [], 2: [], 3: [] };\n for (const f of findings) {\n // Phase 1: HNDL-exposed confidentiality (harvest now, decrypt later) — most urgent.\n // Phase 2: forgeable signatures. Phase 3: transport / certificate config.\n if (f.hndl) byPhase[1].push(f);\n else if (f.category === \"tls\" || f.category === \"certificate\") byPhase[3].push(f);\n else byPhase[2].push(f);\n }\n\n const phaseMeta: Record<number, { title: string; rationale: string }> = {\n 1: {\n title: \"Harvest-now-decrypt-later (do first)\",\n rationale:\n \"Key exchange / public-key encryption. Traffic captured today is decryptable once a quantum computer exists — migrate these first.\",\n },\n 2: {\n title: \"Quantum-forgeable signatures\",\n rationale:\n \"Signatures are not retroactively broken, but become forgeable post-Q-day. Migrate before Q-day, prioritising long-lived keys.\",\n },\n 3: {\n title: \"Transport & certificate configuration\",\n rationale:\n \"TLS versions, cipher suites, and certificate signature algorithms. Adopt hybrid PQC named groups and plan PQC-capable CA re-issuance.\",\n },\n };\n\n async function groupsFor(list: Finding[]): Promise<PlanGroup[]> {\n const byAlgo = new Map<AlgorithmFamily, Finding[]>();\n for (const f of list) {\n const a = (f.algorithm ?? \"unknown\") as AlgorithmFamily;\n const arr = byAlgo.get(a) ?? [];\n arr.push(f);\n byAlgo.set(a, arr);\n }\n const groups: PlanGroup[] = [];\n for (const [algorithm, fs] of byAlgo) {\n const rem = await safe<Remediation | undefined>(\"remediationFor\", () =>\n remediationFor(algorithm),\n );\n groups.push({\n algorithm,\n count: fs.length,\n hndlCount: fs.filter((f) => f.hndl).length,\n remediation:\n rem.ok && rem.value ? rem.value.recommendation : \"Adopt NIST PQC (ML-KEM / ML-DSA).\",\n locations: fs.slice(0, 8).map((f) => `${f.location.file}:${f.location.line}`),\n });\n }\n // Largest groups first within a phase.\n groups.sort((a, b) => b.count - a.count);\n return groups;\n }\n\n const phases: PlanPhase[] = [];\n for (const p of [1, 2, 3]) {\n if (byPhase[p].length === 0) continue;\n phases.push({\n phase: p,\n title: phaseMeta[p].title,\n rationale: phaseMeta[p].rationale,\n groups: await groupsFor(byPhase[p]),\n });\n }\n\n const lines: string[] = [];\n lines.push(`Post-quantum migration plan for ${result.root}`);\n lines.push(\n `Readiness score: ${result.inventory.readinessScore}/100 · ${findings.length} finding(s) · ${result.inventory.hndlCount} HNDL-exposed`,\n );\n if (findings.length === 0) {\n lines.push(\"\");\n lines.push(\n result.analyzedFiles === 0\n ? \"No analyzable source was scanned — this plan does NOT cover unsupported languages.\"\n : \"No classical asymmetric cryptography found. Keep scanning in CI to hold the line.\",\n );\n return { human: lines.join(\"\\n\"), structured: { root: result.root, phases: [] } };\n }\n for (const ph of phases) {\n lines.push(\"\");\n lines.push(`Phase ${ph.phase}: ${ph.title}`);\n lines.push(` ${ph.rationale}`);\n for (const g of ph.groups) {\n lines.push(\n ` - ${g.algorithm} × ${g.count}${g.hndlCount ? ` (${g.hndlCount} HNDL)` : \"\"} → ${g.remediation}`,\n );\n lines.push(\n ` e.g. ${g.locations.join(\", \")}${g.count > g.locations.length ? \", …\" : \"\"}`,\n );\n }\n }\n lines.push(\"\");\n lines.push(\n \"Use get_fix_examples for per-algorithm code changes, then verify_fix to confirm each edit.\",\n );\n return {\n human: lines.join(\"\\n\"),\n structured: {\n root: result.root,\n readinessScore: result.inventory.readinessScore,\n totalFindings: findings.length,\n hndlExposed: result.inventory.hndlCount,\n phases,\n },\n };\n}\n\nconst getFixExamplesTool: ToolDefinition = {\n name: \"get_fix_examples\",\n description:\n \"Return before/after code examples for migrating a classical algorithm to a \" +\n \"post-quantum / hybrid replacement. Provide an 'algorithm' (RSA, ECDH, ECDSA, …) \" +\n \"or a 'ruleId' from a finding.\",\n inputSchema: {\n type: \"object\",\n properties: {\n algorithm: {\n type: \"string\",\n description: \"Classical algorithm family to migrate away from.\",\n },\n ruleId: { type: \"string\", description: \"A finding's ruleId (resolved to its algorithm).\" },\n },\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const algoInput = typeof args.algorithm === \"string\" ? args.algorithm.trim() : \"\";\n const ruleId = typeof args.ruleId === \"string\" ? args.ruleId.trim() : \"\";\n if (!algoInput && !ruleId) {\n return errorResult(\"get_fix_examples requires 'algorithm' or 'ruleId'.\");\n }\n let family: AlgorithmFamily;\n if (algoInput) {\n family = normalizeAlgorithm(algoInput);\n } else {\n const resolved = resolveRule(ruleId);\n family = resolved.meta?.algorithm ?? resolved.algorithm ?? \"unknown\";\n }\n // Fold families that share a fix onto the example we have.\n const key: AlgorithmFamily = family === \"ECIES\" ? \"RSA\" : family;\n const ex = FIX_EXAMPLES[key];\n if (!ex) {\n const rem = await safe<Remediation | undefined>(\"remediationFor\", () =>\n remediationFor(family),\n );\n return textResult(\n `No canned example for ${family}. ${\n rem.ok && rem.value\n ? rem.value.recommendation\n : \"Adopt NIST PQC (ML-KEM / ML-DSA), deployed as hybrids.\"\n }`,\n );\n }\n const text = [\n `Migration example — ${family}`,\n ex.note,\n \"\",\n \"BEFORE (classical):\",\n ex.before,\n \"\",\n \"AFTER (post-quantum / hybrid):\",\n ex.after,\n \"\",\n \"Deploy as a hybrid (classical + PQC) first; drop the classical half once the PQC side is proven.\",\n ].join(\"\\n\");\n return {\n content: [\n { type: \"text\", text },\n { type: \"text\", text: JSON.stringify({ algorithm: family, ...ex }, null, 2) },\n ],\n };\n },\n};\n\nconst verifyFixTool: ToolDefinition = {\n name: \"verify_fix\",\n description:\n \"Run the quantakrypto detectors over a code snippet (NOT the filesystem) and \" +\n \"report any classical crypto that remains. Use this to confirm an edit actually \" +\n \"removed the quantum-vulnerable usage. Provide 'code' plus a 'language' or 'filename'.\",\n inputSchema: {\n type: \"object\",\n properties: {\n code: { type: \"string\", description: \"The source code to check.\" },\n language: {\n type: \"string\",\n description: \"Language of the code (js, ts, python, go, java, csharp, rust, ruby, c, …).\",\n },\n filename: {\n type: \"string\",\n description:\n \"Optional filename; its extension selects the detectors (overrides 'language').\",\n },\n },\n required: [\"code\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const code = typeof args.code === \"string\" ? args.code : \"\";\n if (!code) return errorResult(\"verify_fix requires a non-empty 'code' string.\");\n const filename = typeof args.filename === \"string\" ? args.filename.trim() : \"\";\n const language = typeof args.language === \"string\" ? args.language.trim() : \"\";\n\n if (!filename && !language) {\n return errorResult(\n \"verify_fix requires a 'language' or a 'filename' to know which detectors to run.\",\n );\n }\n if (!filename && languageToExtension(language) === null) {\n return errorResult(\n `verify_fix: unknown language \"${language}\". Supported: js/ts, python, go, java, kotlin, csharp, rust, ruby, c/c++ — or pass a 'filename'.`,\n );\n }\n\n const res = await safe<VerifyResult>(\"verifyFix\", () =>\n verifyFix(code, { filename, language }),\n );\n if (!res.ok) return res.result;\n const { supported, findings } = res.value;\n if (findings.length === 0) {\n const caveat = supported\n ? \"Fix verified: no classical asymmetric cryptography detected in this snippet.\"\n : \"No classical crypto detected — but this language is NOT one the scanner analyzes, so this is not a verification. Use a supported language.\";\n return textResult(caveat);\n }\n const lines = [`Still ${findings.length} classical finding(s) — fix NOT complete:`];\n for (const f of findings) {\n lines.push(\n `- [${f.severity}] ${f.ruleId} (line ${f.location.line})${f.hndl ? \" (HNDL)\" : \"\"} — ${f.message}`,\n );\n }\n return {\n content: [\n { type: \"text\", text: lines.join(\"\\n\") },\n { type: \"text\", text: JSON.stringify(findings, null, 2) },\n ],\n };\n },\n};\n\nconst checkDependencyTool: ToolDefinition = {\n name: \"check_dependency\",\n description:\n \"Check whether a package is in quantakrypto's known quantum-vulnerable dependency \" +\n \"database (the classical crypto it exposes). Provide 'name' and optional 'ecosystem' (default npm).\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n description: \"Package name to look up (e.g. 'node-forge', 'jsonwebtoken').\",\n },\n ecosystem: { type: \"string\", description: \"Package ecosystem. Default: npm.\" },\n },\n required: [\"name\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const name = typeof args.name === \"string\" ? args.name.trim().toLowerCase() : \"\";\n if (!name) return errorResult(\"check_dependency requires a non-empty 'name'.\");\n const ecosystem =\n typeof args.ecosystem === \"string\" ? args.ecosystem.trim().toLowerCase() : \"npm\";\n\n const db = await safe<readonly VulnerableDependency[]>(\n \"vulnerableDependencies\",\n () => vulnerableDependencies,\n );\n if (!db.ok) return db.result;\n const hit = db.value.find(\n (d) => d.name.toLowerCase() === name && d.ecosystem.toLowerCase() === ecosystem,\n );\n if (!hit) {\n return textResult(\n `\"${name}\" (${ecosystem}) is NOT in the known quantum-vulnerable dependency database. ` +\n \"That is not proof it's safe — it may simply not be catalogued, or its crypto may be in your own code. Scan the source too.\",\n );\n }\n const rem = await safe<Remediation | undefined>(\"remediationFor\", () =>\n remediationFor(hit.algorithms[0] ?? \"unknown\"),\n );\n const text = [\n `${hit.name} (${hit.ecosystem}) — quantum-vulnerable [${hit.severity}]`,\n `Exposes: ${hit.algorithms.join(\", \")}`,\n `Why: ${hit.reason}`,\n rem.ok && rem.value\n ? `Migrate toward: ${rem.value.recommendation}`\n : \"Migrate toward NIST PQC (ML-KEM / ML-DSA).\",\n ].join(\"\\n\");\n return {\n content: [\n { type: \"text\", text },\n { type: \"text\", text: JSON.stringify(hit, null, 2) },\n ],\n };\n },\n};\n\nconst scoreDeltaTool: ToolDefinition = {\n name: \"score_delta\",\n description:\n \"Compute the readiness-score and HNDL change between two finding sets (e.g. before \" +\n \"and after a migration). Pass 'before' and 'after' as arrays of findings from \" +\n \"scan_path --format json.\",\n inputSchema: {\n type: \"object\",\n properties: {\n before: {\n type: \"array\",\n description: \"Findings before the change (from a scan's JSON findings).\",\n },\n after: { type: \"array\", description: \"Findings after the change.\" },\n },\n required: [\"before\", \"after\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n if (!Array.isArray(args.before) || !Array.isArray(args.after)) {\n return errorResult(\"score_delta requires 'before' and 'after' arrays of findings.\");\n }\n // Validate element shape too (mirrors triage/remediate) — a malformed\n // `severity` otherwise yields a NaN readiness score rendered as authoritative.\n if (!areFindings(args.before) || !areFindings(args.after)) {\n return errorResult(\"score_delta: 'before' and 'after' must be arrays of valid findings.\");\n }\n const before = args.before;\n const after = args.after;\n const invBefore = await safe<CryptoInventory>(\"buildInventory\", () => buildInventory(before));\n if (!invBefore.ok) return invBefore.result;\n const invAfter = await safe<CryptoInventory>(\"buildInventory\", () => buildInventory(after));\n if (!invAfter.ok) return invAfter.result;\n\n const dScore = invAfter.value.readinessScore - invBefore.value.readinessScore;\n const dHndl = invAfter.value.hndlCount - invBefore.value.hndlCount;\n const dCount = after.length - before.length;\n const sign = (n: number) => (n > 0 ? `+${n}` : `${n}`);\n const text = [\n \"Readiness delta\",\n `Score: ${invBefore.value.readinessScore} → ${invAfter.value.readinessScore} (${sign(dScore)})`,\n `Findings: ${before.length} → ${after.length} (${sign(dCount)})`,\n `HNDL: ${invBefore.value.hndlCount} → ${invAfter.value.hndlCount} (${sign(dHndl)})`,\n dScore > 0\n ? \"Progress: readiness improved.\"\n : dScore < 0\n ? \"Regression: readiness dropped — new classical crypto was introduced.\"\n : \"No net change in readiness.\",\n ].join(\"\\n\");\n return {\n content: [\n { type: \"text\", text },\n {\n type: \"text\",\n text: JSON.stringify(\n {\n before: {\n score: invBefore.value.readinessScore,\n findings: before.length,\n hndl: invBefore.value.hndlCount,\n },\n after: {\n score: invAfter.value.readinessScore,\n findings: after.length,\n hndl: invAfter.value.hndlCount,\n },\n delta: { score: dScore, findings: dCount, hndl: dHndl },\n },\n null,\n 2,\n ),\n },\n ],\n };\n },\n};\n\n/**\n * True when every element looks like a scan Finding (a string `ruleId` and a\n * `location.file`). Guards the triage/remediate tools so a malformed `findings`\n * element surfaces as a tool `isError` result rather than throwing a protocol\n * `-32603` internal error downstream (audit: mcp #4).\n */\nfunction areFindings(arr: readonly unknown[]): arr is Finding[] {\n return arr.every(\n (f) =>\n f !== null &&\n typeof f === \"object\" &&\n typeof (f as { ruleId?: unknown }).ruleId === \"string\" &&\n typeof (f as { location?: { file?: unknown } }).location?.file === \"string\",\n );\n}\n\nconst triageFindingsTool: ToolDefinition = {\n name: \"triage_findings\",\n description:\n \"Produce a deterministic triage REQUEST bundle (rubric + verdict schema + \" +\n \"per-finding metadata) for YOU (the host agent) to reason over. This tool does \" +\n \"NOT call any model and needs no API key. Assess each finding's real-world \" +\n \"exposure, then call apply_triage with your verdicts. Pass 'findings' as an \" +\n \"array from scan_path --format json.\",\n inputSchema: {\n type: \"object\",\n properties: {\n findings: { type: \"array\", description: \"Findings from a scan's JSON output.\" },\n },\n required: [\"findings\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n if (!Array.isArray(args.findings) || !areFindings(args.findings)) {\n return errorResult(\n \"triage_findings requires a 'findings' array of scan findings (each with a string ruleId and location.file).\",\n );\n }\n const findings = args.findings;\n const request = buildTriageRequest(findings, \"metadata\");\n // Pair each context with the finding fingerprint the verdict must echo back.\n const items = findings.map((f, i) => ({\n fingerprint: fingerprintFinding(f),\n context: request.contexts[i],\n }));\n // The verdict schema advertised to the agent MUST include `fingerprint`\n // (the instructions require it, and apply_triage keys on it) — core's\n // single-verdict schema doesn't, so extend it here (audit: mcp bundle).\n const props = (request.schema as { properties?: Record<string, unknown> }).properties ?? {};\n const schema = {\n type: \"object\",\n required: [\"fingerprint\", \"exposureScore\", \"priority\", \"rationale\"],\n properties: { fingerprint: { type: \"string\" }, ...props },\n };\n const bundle = { rubric: request.rubric, schema, items };\n return {\n content: [\n {\n type: \"text\",\n text:\n \"Triage request. For each item, decide {exposureScore 0-100, priority, rationale} \" +\n \"per the rubric, then call apply_triage with the same 'findings' and a 'verdicts' \" +\n \"array (each carrying the item's 'fingerprint'). You never suppress a finding.\",\n },\n { type: \"text\", text: JSON.stringify(bundle, null, 2) },\n ],\n };\n },\n};\n\n/** Validate one caller-supplied triage verdict. Returns null when malformed. */\nfunction parseVerdict(\n v: unknown,\n): { fingerprint: string; exposureScore: number; priority: string; rationale: string } | null {\n if (typeof v !== \"object\" || v === null) return null;\n const o = v as Record<string, unknown>;\n const fingerprint = o.fingerprint;\n const exposureScore = o.exposureScore;\n const priority = o.priority;\n const rationale = o.rationale;\n if (typeof fingerprint !== \"string\") return null;\n // `Number.isFinite` rejects NaN/Infinity — NaN passes both `< 0` and `> 100`\n // (they're false) and would poison the exposure sort comparator (audit: mcp #3).\n if (typeof exposureScore !== \"number\" || !Number.isFinite(exposureScore)) return null;\n if (exposureScore < 0 || exposureScore > 100) return null;\n if (priority !== \"now\" && priority !== \"soon\" && priority !== \"later\") return null;\n if (typeof rationale !== \"string\") return null;\n return { fingerprint, exposureScore, priority, rationale };\n}\n\nconst applyTriageTool: ToolDefinition = {\n name: \"apply_triage\",\n description:\n \"Deterministically attach your triage verdicts to their findings and re-sort by \" +\n \"exposure (highest first). Never suppresses. Pass the same 'findings' array you \" +\n \"triaged plus a 'verdicts' array of { fingerprint, exposureScore, priority, rationale }.\",\n inputSchema: {\n type: \"object\",\n properties: {\n findings: { type: \"array\", description: \"The findings that were triaged.\" },\n verdicts: { type: \"array\", description: \"One verdict per finding, keyed by fingerprint.\" },\n },\n required: [\"findings\", \"verdicts\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n if (!Array.isArray(args.findings) || !Array.isArray(args.verdicts)) {\n return errorResult(\"apply_triage requires 'findings' and 'verdicts' arrays.\");\n }\n if (!areFindings(args.findings)) {\n return errorResult(\n \"apply_triage: each 'findings' element needs a string ruleId and location.file.\",\n );\n }\n const findings = args.findings;\n const byFingerprint = new Map<string, ReturnType<typeof parseVerdict>>();\n let skipped = 0;\n for (const raw of args.verdicts) {\n const v = parseVerdict(raw);\n if (v) byFingerprint.set(v.fingerprint, v);\n else skipped++;\n }\n const annotated = findings.map((f) => {\n const v = byFingerprint.get(fingerprintFinding(f));\n return v\n ? {\n ...f,\n triage: {\n exposureScore: v.exposureScore,\n priority: v.priority as \"now\" | \"soon\" | \"later\",\n rationale: v.rationale,\n },\n }\n : f;\n });\n annotated.sort((a, b) => {\n const ea = a.triage?.exposureScore ?? -1;\n const eb = b.triage?.exposureScore ?? -1;\n if (eb !== ea) return eb - ea;\n return compareFindings(a, b);\n });\n const applied = annotated.filter((f) => f.triage).length;\n const head =\n `Triaged ${applied}/${findings.length} finding(s), re-sorted by exposure.` +\n (skipped ? ` ${skipped} malformed verdict(s) ignored.` : \"\");\n return {\n content: [\n { type: \"text\", text: head },\n { type: \"text\", text: JSON.stringify(annotated, null, 2) },\n ],\n };\n },\n};\n\nconst remediateFindingsTool: ToolDefinition = {\n name: \"remediate_findings\",\n description:\n \"Produce a deterministic remediation REQUEST bundle (rubric + fix schema + \" +\n \"per-finding metadata + fingerprints) for YOU (the host agent) to fix. This \" +\n \"tool calls no model and needs no key. For each finding, propose the corrected \" +\n \"FULL file content, then VERIFY with verify_fix and keep only fixes that clear \" +\n \"the finding. Never touch files with secrets; never auto-merge. Pass 'findings' \" +\n \"from scan_path --format json.\",\n inputSchema: {\n type: \"object\",\n properties: {\n findings: { type: \"array\", description: \"Findings from a scan's JSON output.\" },\n },\n required: [\"findings\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n if (!Array.isArray(args.findings) || !areFindings(args.findings)) {\n return errorResult(\n \"remediate_findings requires a 'findings' array of scan findings (each with a string ruleId and location.file).\",\n );\n }\n const findings = args.findings;\n const request = buildRemediateRequest(findings, \"metadata\");\n const items = findings.map((f, i) => ({\n fingerprint: fingerprintFinding(f),\n context: request.contexts[i],\n }));\n const bundle = { instructions: request.instructions, schema: request.schema, items };\n return {\n content: [\n {\n type: \"text\",\n text:\n \"Remediation request. For each item, propose {path, newContent, explanation} \" +\n \"(the FULL corrected file), call verify_fix on your newContent, and keep only \" +\n \"verified fixes. Skip any file containing secrets. This never merges anything.\",\n },\n { type: \"text\", text: JSON.stringify(bundle, null, 2) },\n ],\n };\n },\n};\n\nconst applyVerifiedPatchTool: ToolDefinition = {\n name: \"apply_verified_patch\",\n description:\n \"Deterministically VERIFY a proposed fix before writing it — runs the same \" +\n \"patch-policy + verify_fix + blast-radius gates as `qremediate` (offline, no \" +\n \"key, no network). Give the finding, the file's current content, and your \" +\n \"proposed FULL corrected content; returns approved:true only if the patch is \" +\n \"in-policy, clears the finding, adds no new finding, introduces no network/exec \" +\n \"sink, and is bounded in size. This does NOT write the file — you write it, \" +\n \"only when approved, and never auto-merge.\",\n inputSchema: {\n type: \"object\",\n properties: {\n finding: {\n type: \"object\",\n description: \"The scan finding being fixed (needs a string ruleId and location.file).\",\n },\n originalContent: { type: \"string\", description: \"The file's current full content.\" },\n newContent: { type: \"string\", description: \"Your proposed full corrected file content.\" },\n },\n required: [\"finding\", \"originalContent\", \"newContent\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const finding = args.finding as Finding;\n if (!finding || typeof finding !== \"object\" || !areFindings([finding])) {\n return errorResult(\n \"apply_verified_patch requires a 'finding' with a string ruleId and location.file.\",\n );\n }\n if (typeof args.originalContent !== \"string\" || typeof args.newContent !== \"string\") {\n return errorResult(\n \"apply_verified_patch requires string 'originalContent' and 'newContent'.\",\n );\n }\n const file = finding.location.file;\n const originalContent = args.originalContent;\n const patch = {\n path: file,\n newContent: args.newContent,\n ruleId: finding.ruleId,\n source: \"llm\" as const,\n };\n const res = await safe(\"apply_verified_patch\", () =>\n remediateFindings([finding], {\n readContent: () => originalContent,\n patchSource: () => patch,\n policy: {\n findingFiles: new Set([file]),\n manifestFiles: new Set(isManifestFile(file) ? [file] : []),\n },\n }),\n );\n if (!res.ok) return res.result;\n const approved = res.value.applied.length > 0;\n return textResult(\n JSON.stringify(\n {\n approved,\n path: file,\n ruleId: finding.ruleId,\n ...(approved ? {} : { reason: res.value.rejected[0]?.reason ?? \"rejected\" }),\n note: approved\n ? \"Cleared every deterministic gate — safe to write. Open a diff/PR for review; never auto-merge.\"\n : \"Rejected by the deterministic gates — do NOT write this patch.\",\n },\n null,\n 2,\n ),\n );\n },\n};\n\n/**\n * `probe_endpoint` — actively probe ONE live TLS/SSH endpoint the caller OWNS for\n * post-quantum readiness. This is the ONLY MCP tool that opens a network socket;\n * the qprobe plane is loaded via dynamic import so the server stays offline until\n * the tool is actually invoked, and the ownership attestation gate is enforced in\n * qProbe's `runProbe` before any connection. On the HTTP transport it is OFF by\n * default (see {@link NETWORK_TOOL_NAMES}) — a hosted endpoint should not probe\n * arbitrary hosts — but a trusted operator can opt in with\n * QUANTAKRYPTO_MCP_ALLOW_NETWORK=1.\n */\nconst probeEndpointTool: ToolDefinition = {\n name: \"probe_endpoint\",\n description:\n \"Actively probe ONE live TLS/SSH endpoint YOU OWN for post-quantum readiness \" +\n \"(PQC-hybrid key exchange X25519MLKEM768, classical certificate posture). REQUIRES \" +\n \"an ownership attestation: set i_own_this=true to confirm you are authorized to test \" +\n \"the target. Refuses CIDR ranges / wildcards / lists — one host at a time. Performs \" +\n \"only a benign, unauthenticated handshake and never modifies the endpoint. NOTE: this \" +\n \"is the ONLY quantakrypto MCP tool that opens a network connection; the server is \" +\n \"otherwise offline. Over HTTP it is disabled unless the operator sets \" +\n \"QUANTAKRYPTO_MCP_ALLOW_NETWORK=1.\",\n inputSchema: {\n type: \"object\",\n properties: {\n target: {\n type: \"string\",\n description: \"A single host or host:port you own (no ranges/CIDRs/wildcards).\",\n },\n mode: {\n type: \"string\",\n enum: [\"tls\", \"ssh\", \"auto\"],\n description: \"Probe mode (default: auto — SSH on :22, TLS otherwise).\",\n },\n i_own_this: {\n type: \"boolean\",\n description:\n \"Attestation that you are authorized to probe this endpoint. Must be true; the probe is refused otherwise.\",\n },\n timeout_ms: { type: \"number\", description: \"Per-connection timeout in ms (default 8000).\" },\n },\n required: [\"target\", \"i_own_this\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const target = args.target;\n if (typeof target !== \"string\" || target.length === 0) {\n return errorResult(\"probe_endpoint requires a non-empty 'target' string.\");\n }\n if (args.i_own_this !== true) {\n return errorResult(\n \"probe_endpoint refused: set i_own_this=true to attest you are authorized to probe this endpoint. Active probing of endpoints you do not own may be unlawful.\",\n );\n }\n const mode = args.mode === \"tls\" || args.mode === \"ssh\" ? args.mode : \"auto\";\n const timeoutMs = typeof args.timeout_ms === \"number\" ? args.timeout_ms : undefined;\n // Dynamic import keeps the networked qprobe plane out of the server process\n // until this tool is actually used; runProbe enforces the attestation gate.\n const qprobe = await import(\"@quantakrypto/qprobe\");\n // Parse the target explicitly so a CIDR/range/list refusal returns a helpful\n // message rather than a scrubbed internal error.\n let parsed;\n try {\n parsed = qprobe.parseTarget(target, mode === \"ssh\" ? 22 : 443);\n } catch (e) {\n return errorResult(`probe_endpoint: ${e instanceof Error ? e.message : String(e)}`);\n }\n const probed = await safe(\"probe_endpoint\", () =>\n qprobe.runProbe({ targets: [parsed], mode, attest: { iOwnThis: true }, timeoutMs }),\n );\n if (!probed.ok) return probed.result;\n const { reports, findings, inventory } = probed.value;\n const lines: string[] = [];\n let unreachable = 0;\n for (const r of reports) {\n lines.push(`${r.target.host}:${r.target.port} [${r.mode}]`);\n const err = r.ssh?.error ?? r.tls?.error ?? r.hybrid?.error;\n if (err && r.findings.length === 0) {\n unreachable++;\n // Do NOT let an unreachable/errored endpoint read as a clean 100/100.\n lines.push(` ⚠ probe error: ${err} — endpoint NOT assessed (not a clean result)`);\n }\n for (const p of r.positives) lines.push(` ✓ ${p}`);\n for (const f of r.findings) lines.push(` [${f.severity}] ${f.title} — ${f.message}`);\n }\n const note =\n unreachable > 0\n ? \" — NOTE: an endpoint could not be reached/handshaken, so this is NOT a clean bill of health\"\n : \"\";\n lines.push(\n `\\n${findings.length} finding${findings.length === 1 ? \"\" : \"s\"} · ${inventory.hndlCount} HNDL-exposed · readiness ${inventory.readinessScore}/100${note}`,\n );\n return {\n content: [\n { type: \"text\", text: lines.join(\"\\n\") },\n { type: \"text\", text: JSON.stringify({ findings, inventory }, null, 2) },\n ],\n };\n },\n};\n\n/**\n * Tools that read arbitrary filesystem paths. Disabled by default on the HTTP\n * transport (see {@link ./http.ts}) because a hosted endpoint must not be an\n * arbitrary-file-read oracle (security audit Q-01). The stdio transport, which\n * trusts the local user, always exposes them.\n */\nexport const FS_TOOL_NAMES: readonly string[] = [\n \"scan_path\",\n \"inventory_crypto\",\n \"generate_cbom\",\n \"plan_migration\",\n];\n\n/**\n * Tools that open network connections. On the HTTP transport they are OFF by\n * default — a hosted MCP should not probe arbitrary hosts — but a trusted operator\n * can opt in with QUANTAKRYPTO_MCP_ALLOW_NETWORK=1 (mirroring the FS-tools opt-in).\n * Always available on the local stdio transport, which trusts the local user.\n */\nexport const NETWORK_TOOL_NAMES: readonly string[] = [\"probe_endpoint\"];\n\n/** All quantakrypto MCP tools, in a stable order. */\nexport const quantakryptoTools: ToolDefinition[] = [\n scanPathTool,\n inventoryCryptoTool,\n explainFindingTool,\n suggestHybridTool,\n listRulesTool,\n generateCbomTool,\n // Copilot tools — migrate through the engine.\n planMigrationTool,\n getFixExamplesTool,\n verifyFixTool,\n checkDependencyTool,\n scoreDeltaTool,\n // BYOK triage + remediation — deterministic request/apply (host agent reasons; offline).\n triageFindingsTool,\n applyTriageTool,\n remediateFindingsTool,\n applyVerifiedPatchTool,\n // The only networked tool — offline until invoked; refused on the HTTP transport.\n probeEndpointTool,\n];\n\n/** The core version these tools are built against (re-exported for diagnostics). */\nexport const CORE_VERSION = VERSION;\n\n/** Exposed for tests and advanced callers. */\nexport const __test = {\n normalizeAlgorithm,\n summarizeScan,\n staticHybridAdvice,\n buildScanOptions,\n describeError,\n FIX_EXAMPLES,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * quantakrypto MCP tools, backed by {@link @quantakrypto/core}.\n *\n * Every tool returns an MCP {@link ToolResult} ({ content, isError? }). Each\n * handler runs core calls through {@link safe} so any runtime failure (a bad\n * path, a work-budget overflow, an unexpected error) surfaces as a readable\n * `isError` tool result with host details stripped, rather than a protocol-level\n * crash.\n */\n\nimport process from \"node:process\";\n\nimport {\n VERSION,\n AbortError,\n BudgetExceededError,\n buildInventory,\n buildRemediateRequest,\n buildTriageRequest,\n compareFindings,\n detectors,\n fingerprintFinding,\n isManifestFile,\n languageToExtension,\n remediateFindings,\n remediationFor,\n remediationForTier,\n scan,\n SEVERITY_ORDER,\n toCbom,\n verifyFix,\n vulnerableDependencies,\n} from \"@quantakrypto/core\";\nimport type {\n AlgorithmFamily,\n CryptoInventory,\n Finding,\n Remediation,\n ScanOptions,\n ScanResult,\n VerifyResult,\n VulnerableDependency,\n} from \"@quantakrypto/core\";\n\nimport { errorResult, textResult } from \"./protocol.js\";\nimport type { ToolContext, ToolDefinition, ToolResult } from \"./protocol.js\";\nimport { resolveRule } from \"./rules.js\";\nimport { realpathInsideRoots, resolveFsConfig, resolveScanPath } from \"./fsconfig.js\";\n\n/** All classical algorithm families we can advise on, used for validation/help. */\nconst ALGORITHM_FAMILIES: AlgorithmFamily[] = [\n \"RSA\",\n \"ECDH\",\n \"ECDSA\",\n \"EdDSA\",\n \"DH\",\n \"DSA\",\n \"X25519\",\n \"X448\",\n \"ECIES\",\n \"unknown\",\n];\n\n/**\n * Map a core failure to a caller-safe message. Cancellation and budget overflows\n * are intentional, expected outcomes — their messages are author-controlled and\n * carry no host detail, so they pass through. Every other error may embed a\n * server path (an `ENOENT … '/etc/shadow'`, a stack), so it is logged locally\n * and replaced with a generic string; the remote caller never sees internals.\n */\nfunction describeError(label: string, err: unknown): string {\n if (err instanceof AbortError) return `${label} was aborted (request timed out).`;\n if (err instanceof BudgetExceededError) {\n // Author-written, no host detail: \"maxFiles budget exceeded (limit: …)\".\n return `${label} failed: ${err.message}`;\n }\n const detail = err instanceof Error ? (err.stack ?? err.message) : String(err);\n process.stderr.write(`quantakrypto MCP: ${label} failed: ${detail}\\n`);\n return `${label} failed: an internal error occurred.`;\n}\n\n/**\n * Run a possibly-throwing core call, mapping any failure to an error tool\n * result. Returns either the value or a {@link ToolResult} sentinel. Error\n * messages are sanitized via {@link describeError} so server paths never leak.\n */\nasync function safe<T>(\n label: string,\n fn: () => T | Promise<T>,\n): Promise<{ ok: true; value: T } | { ok: false; result: ToolResult }> {\n try {\n return { ok: true, value: await fn() };\n } catch (err) {\n return { ok: false, result: errorResult(describeError(label, err)) };\n }\n}\n\n/**\n * Resolve the FS-tool policy (root allow-list + work budgets) once per call from\n * the live environment, then validate the caller's path against it and assemble\n * the {@link ScanOptions} for a confined, bounded, cancellable scan.\n *\n * Returns an `errorResult` when the path escapes the allow-list (a `..`\n * traversal or an out-of-root absolute path), so the FS tools can `return` it\n * directly. The `signal` from the transport's request deadline (when present) is\n * threaded in so a timed-out request actually aborts the underlying scan.\n */\nasync function buildScanOptions(\n requested: string,\n context?: ToolContext,\n): Promise<{ ok: true; options: ScanOptions } | { ok: false; result: ToolResult }> {\n const config = resolveFsConfig(process.env);\n const decision = resolveScanPath(config, requested);\n if (!decision.ok) {\n return { ok: false, result: errorResult(`scan rejected: ${decision.reason}`) };\n }\n // Symlink-escape hardening: re-verify containment against the real, resolved\n // paths so a symlink inside a root can't read outside it (audit: mcp #1).\n if (!(await realpathInsideRoots(decision.path, config))) {\n return {\n ok: false,\n result: errorResult(\"scan rejected: path resolves outside the configured root(s) (symlink).\"),\n };\n }\n return {\n ok: true,\n options: {\n root: decision.path,\n signal: context?.signal,\n maxFiles: config.maxFiles,\n maxBytes: config.maxBytes,\n },\n };\n}\n\n/** Map a free-text algorithm string onto a known {@link AlgorithmFamily}. */\nfunction normalizeAlgorithm(input: string): AlgorithmFamily {\n const cleaned = input\n .trim()\n .toUpperCase()\n .replace(/[\\s_-]+/g, \"\");\n for (const fam of ALGORITHM_FAMILIES) {\n if (fam.toUpperCase() === cleaned) return fam;\n }\n // Common aliases / families folded into the canonical set.\n if (cleaned.startsWith(\"RSA\")) return \"RSA\";\n if (cleaned.includes(\"ECDSA\")) return \"ECDSA\";\n if (cleaned.includes(\"ED25519\") || cleaned.includes(\"EDDSA\")) return \"EdDSA\";\n if (cleaned.includes(\"X448\") || cleaned.includes(\"CURVE448\")) return \"X448\";\n if (cleaned.includes(\"X25519\") || cleaned.includes(\"CURVE25519\")) return \"X25519\";\n if (cleaned.includes(\"ECDH\")) return \"ECDH\";\n if (cleaned.includes(\"ECIES\")) return \"ECIES\";\n if (cleaned === \"DH\" || cleaned.includes(\"DIFFIEHELLMAN\")) return \"DH\";\n if (cleaned === \"DSA\") return \"DSA\";\n return \"unknown\";\n}\n\n/** Render a scan result as a compact human-readable summary. */\nfunction summarizeScan(result: ScanResult): string {\n const inv = result.inventory;\n const lines: string[] = [];\n lines.push(`quantakrypto scan of ${result.root}`);\n lines.push(`Files scanned: ${result.filesScanned}`);\n lines.push(`Findings: ${result.findings.length}`);\n lines.push(`Readiness score: ${inv.readinessScore}/100`);\n lines.push(`Harvest-now-decrypt-later exposure: ${inv.hndlCount} finding(s)`);\n\n const sev = SEVERITY_ORDER.filter((s) => (inv.bySeverity[s] ?? 0) > 0)\n .map((s) => `${s}: ${inv.bySeverity[s]}`)\n .join(\", \");\n if (sev) lines.push(`By severity: ${sev}`);\n\n const algos = Object.entries(inv.byAlgorithm)\n .filter(([, n]) => (n ?? 0) > 0)\n .map(([a, n]) => `${a}: ${n}`)\n .join(\", \");\n if (algos) lines.push(`By algorithm: ${algos}`);\n\n if (result.findings.length > 0) {\n lines.push(\"\");\n lines.push(\"Top findings:\");\n const top = [...result.findings]\n .sort((a, b) => SEVERITY_ORDER.indexOf(a.severity) - SEVERITY_ORDER.indexOf(b.severity))\n .slice(0, 20);\n for (const f of top) {\n const loc = `${f.location.file}:${f.location.line}`;\n lines.push(`- [${f.severity}] ${f.ruleId} (${loc}) — ${f.message}`);\n }\n if (result.findings.length > top.length) {\n lines.push(`… and ${result.findings.length - top.length} more.`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Tool definitions\n// ---------------------------------------------------------------------------\n\nconst scanPathTool: ToolDefinition = {\n name: \"scan_path\",\n description:\n \"Scan a file or directory for classical (quantum-vulnerable) asymmetric \" +\n \"cryptography using quantakrypto. Returns a readiness summary and findings.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Absolute or relative path to a file or directory to scan.\",\n },\n format: {\n type: \"string\",\n enum: [\"summary\", \"json\"],\n description:\n \"Output format: 'summary' (default) for readable text, 'json' for the raw ScanResult.\",\n },\n },\n required: [\"path\"],\n additionalProperties: false,\n },\n async handler(args, context): Promise<ToolResult> {\n const path = args.path;\n if (typeof path !== \"string\" || path.length === 0) {\n return errorResult(\"scan_path requires a non-empty 'path' string.\");\n }\n const format = args.format === \"json\" ? \"json\" : \"summary\";\n const opts = await buildScanOptions(path, context);\n if (!opts.ok) return opts.result;\n const scanned = await safe(\"scan\", () => scan(opts.options));\n if (!scanned.ok) return scanned.result;\n const result = scanned.value;\n if (format === \"json\") {\n return textResult(JSON.stringify(result, null, 2));\n }\n return textResult(summarizeScan(result));\n },\n};\n\nconst inventoryCryptoTool: ToolDefinition = {\n name: \"inventory_crypto\",\n description:\n \"Produce a post-quantum readiness inventory for a path: a 0-100 readiness \" +\n \"score plus counts of cryptographic findings by algorithm, category, and severity.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Absolute or relative path to a file or directory to inventory.\",\n },\n },\n required: [\"path\"],\n additionalProperties: false,\n },\n async handler(args, context): Promise<ToolResult> {\n const path = args.path;\n if (typeof path !== \"string\" || path.length === 0) {\n return errorResult(\"inventory_crypto requires a non-empty 'path' string.\");\n }\n const opts = await buildScanOptions(path, context);\n if (!opts.ok) return opts.result;\n const scanned = await safe(\"scan\", () => scan(opts.options));\n if (!scanned.ok) return scanned.result;\n const result = scanned.value;\n\n // Prefer a freshly built inventory from findings; fall back to the scan's own.\n const built = await safe<CryptoInventory>(\"buildInventory\", () =>\n buildInventory(result.findings),\n );\n const inventory = built.ok ? built.value : result.inventory;\n\n const lines: string[] = [];\n lines.push(`Post-quantum readiness for ${result.root}`);\n lines.push(`Readiness score: ${inventory.readinessScore}/100`);\n lines.push(`HNDL exposure: ${inventory.hndlCount}`);\n lines.push(\"\");\n lines.push(\"By algorithm:\");\n for (const [algo, n] of Object.entries(inventory.byAlgorithm)) {\n if ((n ?? 0) > 0) lines.push(` ${algo}: ${n}`);\n }\n lines.push(\"By category:\");\n for (const [cat, n] of Object.entries(inventory.byCategory)) {\n if ((n ?? 0) > 0) lines.push(` ${cat}: ${n}`);\n }\n lines.push(\"By severity:\");\n for (const sev of SEVERITY_ORDER) {\n const n = inventory.bySeverity[sev] ?? 0;\n if (n > 0) lines.push(` ${sev}: ${n}`);\n }\n return {\n content: [\n { type: \"text\", text: lines.join(\"\\n\") },\n { type: \"text\", text: JSON.stringify(inventory, null, 2) },\n ],\n };\n },\n};\n\nconst explainFindingTool: ToolDefinition = {\n name: \"explain_finding\",\n description:\n \"Explain a quantakrypto finding and its post-quantum remediation. Provide a \" +\n \"ruleId (e.g. 'forge-rsa-keygen', 'elliptic-ec', 'node-rsa', 'pem-ec-private-key') \" +\n \"and/or an algorithm (e.g. 'RSA', 'ECDSA'). The ruleId is resolved against the \" +\n \"core detector set, so library and config rules explain correctly.\",\n inputSchema: {\n type: \"object\",\n properties: {\n ruleId: {\n type: \"string\",\n description: \"The finding's rule id, matching a detector id prefix.\",\n },\n algorithm: {\n type: \"string\",\n description: \"The classical algorithm family involved (e.g. RSA, ECDH, ECDSA).\",\n },\n },\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const ruleId = typeof args.ruleId === \"string\" ? args.ruleId.trim() : \"\";\n const algoInput = typeof args.algorithm === \"string\" ? args.algorithm.trim() : \"\";\n if (!ruleId && !algoInput) {\n return errorResult(\"explain_finding requires at least one of 'ruleId' or 'algorithm'.\");\n }\n\n const lines: string[] = [];\n\n // Resolve the rule against core's actual detector set/registry (P0-5),\n // not by a fragile id-prefix match. Library rules (forge-*, elliptic-ec,\n // node-rsa, …) resolve to their `crypto-libs` detector and carry their\n // algorithm, so they now explain correctly.\n let resolvedAlgorithm: AlgorithmFamily | undefined;\n if (ruleId) {\n const resolved = resolveRule(ruleId);\n resolvedAlgorithm = resolved.algorithm;\n const meta = resolved.meta;\n lines.push(`Rule: ${meta ? `${ruleId} — ${meta.title}` : ruleId}`);\n if (resolved.detector) {\n lines.push(`Detector: ${resolved.detector.id} — ${resolved.detector.description}`);\n } else if (resolved.via === \"unresolved\") {\n lines.push(\n \"No matching detector found in the catalog (rule may be unknown to this core version).\",\n );\n }\n // Rule catalog metadata (severity / category / HNDL / remediation) so the\n // explanation is actionable on its own, not just a detector pointer.\n if (meta) {\n lines.push(\n `Severity: ${meta.severity} · Category: ${meta.category} · HNDL-exposed: ${meta.hndl ? \"yes\" : \"no\"}`,\n );\n lines.push(`What it detects: ${meta.description ?? meta.message}`);\n if (meta.remediation) lines.push(`Rule remediation: ${meta.remediation}`);\n }\n }\n\n // Prefer an explicit algorithm; otherwise use the one the rule resolved to.\n const algorithm: AlgorithmFamily | undefined = algoInput\n ? normalizeAlgorithm(algoInput)\n : resolvedAlgorithm && resolvedAlgorithm !== \"unknown\"\n ? resolvedAlgorithm\n : undefined;\n\n if (algorithm) {\n if (lines.length) lines.push(\"\");\n lines.push(`Algorithm: ${algorithm}`);\n const rem = await safe<Remediation | undefined>(\"remediationFor\", () =>\n remediationFor(algorithm),\n );\n if (rem.ok && rem.value) {\n lines.push(\n `Why it matters: ${algorithm} relies on hardness assumptions (integer factorization / discrete log) that Shor's algorithm breaks on a cryptographically-relevant quantum computer.`,\n );\n lines.push(`Recommendation: ${rem.value.recommendation}`);\n lines.push(`Detail: ${rem.value.detail}`);\n } else if (rem.ok) {\n lines.push(\"No specific remediation is registered for this algorithm.\");\n } else {\n return rem.result;\n }\n }\n\n return textResult(lines.join(\"\\n\"));\n },\n};\n\nconst suggestHybridTool: ToolDefinition = {\n name: \"suggest_hybrid\",\n description:\n \"Recommend a post-quantum / hybrid migration. Provide an 'algorithm' \" +\n \"(e.g. RSA, ECDH, ECDSA) or free-text 'context' describing the usage. \" +\n \"Set 'tier' to 'category-5' for CNSA 2.0 / national-security systems.\",\n inputSchema: {\n type: \"object\",\n properties: {\n algorithm: {\n type: \"string\",\n description: \"Classical algorithm family to migrate away from.\",\n },\n context: {\n type: \"string\",\n description:\n \"Free-text description of the cryptographic usage (used when no algorithm is given).\",\n },\n tier: {\n type: \"string\",\n enum: [\"category-3\", \"category-5\"],\n description:\n \"Security tier: 'category-3' (default, commercial — ML-KEM-768 / ML-DSA-65) or \" +\n \"'category-5' (CNSA 2.0 / NSS, long-lived secrets — ML-KEM-1024 / ML-DSA-87).\",\n },\n },\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const algoInput = typeof args.algorithm === \"string\" ? args.algorithm.trim() : \"\";\n const context = typeof args.context === \"string\" ? args.context.trim() : \"\";\n if (!algoInput && !context) {\n return errorResult(\"suggest_hybrid requires either 'algorithm' or 'context'.\");\n }\n\n const algorithm = normalizeAlgorithm(algoInput || context);\n const tier =\n args.tier === \"category-5\"\n ? \"category-5\"\n : args.tier === \"category-3\"\n ? \"category-3\"\n : undefined;\n const lines: string[] = [];\n lines.push(`Migration guidance for: ${algoInput || context}`);\n lines.push(`Detected family: ${algorithm}`);\n if (tier) lines.push(`Security tier: ${tier}`);\n\n const rem = await safe<Remediation | undefined>(\"remediationFor\", () =>\n tier ? remediationForTier(algorithm, tier) : remediationFor(algorithm),\n );\n if (rem.ok && rem.value) {\n lines.push(`Recommended replacement: ${rem.value.recommendation}`);\n lines.push(`Rationale: ${rem.value.detail}`);\n } else {\n // Defensive fallback: core has a remediation for every known family, so\n // this only triggers if the lookup throws or the algorithm is unrecognised.\n lines.push(...staticHybridAdvice(algorithm));\n }\n\n lines.push(\"\");\n lines.push(\n \"Hybrid migrations combine a classical primitive with a NIST PQC algorithm \" +\n \"so security holds if either survives. Roll out hybrids first, then drop the \" +\n \"classical half once the PQC side is proven in your environment.\",\n );\n return textResult(lines.join(\"\\n\"));\n },\n};\n\n/** Built-in PQC guidance used when core's remediation table is unavailable. */\nfunction staticHybridAdvice(algorithm: AlgorithmFamily): string[] {\n switch (algorithm) {\n case \"RSA\":\n case \"ECIES\":\n return [\n \"Recommended replacement: ML-KEM-768 for key establishment (hybrid X25519MLKEM768).\",\n \"For signatures use ML-DSA-65 (Dilithium) or SLH-DSA (SPHINCS+) where statelessness matters.\",\n ];\n case \"ECDH\":\n case \"DH\":\n case \"X25519\":\n return [\n \"Recommended replacement: hybrid X25519MLKEM768 key exchange (ML-KEM-768 + X25519).\",\n \"Supported in modern TLS 1.3 stacks; prefer the hybrid named group over bare ML-KEM.\",\n ];\n case \"ECDSA\":\n case \"EdDSA\":\n case \"DSA\":\n return [\n \"Recommended replacement: ML-DSA-65 (Dilithium) for general signatures.\",\n \"Use SLH-DSA (SPHINCS+) for long-lived roots or where a stateless hash-based scheme is preferred.\",\n ];\n default:\n return [\n \"Recommended replacement: adopt NIST PQC — ML-KEM for key establishment, ML-DSA for signatures.\",\n \"Deploy as hybrids (classical + PQC) during transition.\",\n ];\n }\n}\n\nconst listRulesTool: ToolDefinition = {\n name: \"list_rules\",\n description: \"List the quantakrypto detector catalog: every detector id and what it looks for.\",\n inputSchema: {\n type: \"object\",\n properties: {},\n additionalProperties: false,\n },\n async handler(): Promise<ToolResult> {\n const detectorList = await safe(\"detectors\", () => detectors);\n if (!detectorList.ok) return detectorList.result;\n const catalog = detectorList.value.map((d) => ({ id: d.id, description: d.description }));\n if (catalog.length === 0) {\n return textResult(\n \"No detectors are registered in @quantakrypto/core yet (the catalog is empty).\",\n );\n }\n const human = catalog.map((d) => `- ${d.id}: ${d.description}`).join(\"\\n\");\n return {\n content: [\n {\n type: \"text\",\n text: `quantakrypto detector catalog (${catalog.length} rules):\\n${human}`,\n },\n { type: \"text\", text: JSON.stringify(catalog, null, 2) },\n ],\n };\n },\n};\n\nconst generateCbomTool: ToolDefinition = {\n name: \"generate_cbom\",\n description:\n \"Scan a path and emit a CycloneDX 1.6 Cryptographic Bill of Materials (CBOM) \" +\n \"of the classical cryptographic assets found, for compliance / supply-chain \" +\n \"tooling. Reads the filesystem, so it is gated like scan_path over HTTP.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Absolute or relative path to a file or directory to inventory.\",\n },\n },\n required: [\"path\"],\n additionalProperties: false,\n },\n async handler(args, context): Promise<ToolResult> {\n const path = args.path;\n if (typeof path !== \"string\" || path.length === 0) {\n return errorResult(\"generate_cbom requires a non-empty 'path' string.\");\n }\n const opts = await buildScanOptions(path, context);\n if (!opts.ok) return opts.result;\n const scanned = await safe(\"scan\", () => scan(opts.options));\n if (!scanned.ok) return scanned.result;\n const cbom = await safe(\"toCbom\", () => toCbom(scanned.value));\n if (!cbom.ok) return cbom.result;\n return textResult(JSON.stringify(cbom.value, null, 2));\n },\n};\n\n// ---------------------------------------------------------------------------\n// Copilot tools — let an AI coding agent migrate *through* the deterministic\n// engine (\"the model proposes, the engine disposes\"). plan_migration scans and\n// orders the work; get_fix_examples shows the code change; verify_fix re-runs\n// the detectors on the agent's edited code to confirm the classical crypto is\n// actually gone; check_dependency and score_delta quantify the work.\n// ---------------------------------------------------------------------------\n\n// `languageToExtension` + `verifyFix` now live in @quantakrypto/core so this tool and\n// the remediation pipeline share one definition of \"the fix is verified\".\n\n/** Before/after migration snippets per classical family. Static + deterministic. */\nconst FIX_EXAMPLES: Partial<\n Record<AlgorithmFamily, { note: string; before: string; after: string }>\n> = {\n RSA: {\n note: \"RSA key establishment → ML-KEM-768 (hybrid X25519MLKEM768). RSA signatures → ML-DSA-65.\",\n before:\n \"// key establishment\\nconst { publicKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 3072 });\\nconst enc = crypto.publicEncrypt(publicKey, data);\",\n after:\n \"// hybrid KEM (e.g. @noble/post-quantum or a TLS 1.3 hybrid group)\\nimport { MlKem768 } from 'mlkem';\\nconst kem = new MlKem768();\\nconst [encapsulated, sharedSecret] = await kem.encap(peerPublicKey); // pair with X25519 for hybrid\",\n },\n ECDH: {\n note: \"ECDH / DH key agreement → hybrid X25519MLKEM768 (ML-KEM-768 + X25519).\",\n before:\n \"const ecdh = crypto.createECDH('prime256v1');\\nconst shared = ecdh.computeSecret(peerKey);\",\n after:\n \"// TLS: negotiate the X25519MLKEM768 named group. In app code, combine ML-KEM-768\\n// with X25519 and KDF the concatenated secrets so security holds if either survives.\",\n },\n DH: {\n note: \"Finite-field DH → hybrid X25519MLKEM768.\",\n before: \"const dh = crypto.createDiffieHellman(2048);\",\n after: \"// Replace with ML-KEM-768 encapsulation, deployed as a hybrid with X25519.\",\n },\n X25519: {\n note: \"X25519 is modern but classical; wrap it in a hybrid X25519MLKEM768 rather than dropping it.\",\n before: \"const alice = crypto.generateKeyPairSync('x25519');\",\n after: \"// Keep X25519 AND add ML-KEM-768; derive the session key from both (hybrid).\",\n },\n ECDSA: {\n note: \"ECDSA signatures → ML-DSA-65 (Dilithium), or SLH-DSA where statelessness matters.\",\n before: \"const sig = crypto.sign('sha256', msg, ecPrivateKey);\",\n after:\n \"import { ml_dsa65 } from '@noble/post-quantum/ml-dsa';\\nconst sig = ml_dsa65.sign(mlDsaSecretKey, msg);\",\n },\n EdDSA: {\n note: \"Ed25519/Ed448 signatures → ML-DSA-65 (or a hybrid Ed25519+ML-DSA during transition).\",\n before: \"const sig = crypto.sign(null, msg, ed25519PrivateKey);\",\n after:\n \"import { ml_dsa65 } from '@noble/post-quantum/ml-dsa';\\nconst sig = ml_dsa65.sign(mlDsaSecretKey, msg);\",\n },\n DSA: {\n note: \"DSA is deprecated; rotate keys and migrate to ML-DSA-65.\",\n before: \"crypto.generateKeyPairSync('dsa', { modulusLength: 2048 });\",\n after:\n \"import { ml_dsa65 } from '@noble/post-quantum/ml-dsa';\\nconst keys = ml_dsa65.keygen();\",\n },\n};\n\nconst planMigrationTool: ToolDefinition = {\n name: \"plan_migration\",\n description:\n \"Scan a path and return a deterministic, prioritized post-quantum migration \" +\n \"plan: findings grouped by algorithm, ordered harvest-now-decrypt-later first, \" +\n \"each with its PQC target and the readiness-score impact. Reads the filesystem, \" +\n \"so it is gated like scan_path over HTTP.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Absolute or relative path to a file or directory to plan a migration for.\",\n },\n },\n required: [\"path\"],\n additionalProperties: false,\n },\n async handler(args, context): Promise<ToolResult> {\n const path = args.path;\n if (typeof path !== \"string\" || path.length === 0) {\n return errorResult(\"plan_migration requires a non-empty 'path' string.\");\n }\n const opts = await buildScanOptions(path, context);\n if (!opts.ok) return opts.result;\n const scanned = await safe(\"scan\", () => scan(opts.options));\n if (!scanned.ok) return scanned.result;\n const plan = await buildMigrationPlan(scanned.value);\n return {\n content: [\n { type: \"text\", text: plan.human },\n { type: \"text\", text: JSON.stringify(plan.structured, null, 2) },\n ],\n };\n },\n};\n\n/** Migration-phase buckets, ordered by urgency. */\ninterface PlanGroup {\n algorithm: AlgorithmFamily;\n count: number;\n hndlCount: number;\n remediation: string;\n locations: string[];\n}\ninterface PlanPhase {\n phase: number;\n title: string;\n rationale: string;\n groups: PlanGroup[];\n}\n\n/** Build a deterministic, prioritized migration plan from a scan result. */\nasync function buildMigrationPlan(\n result: ScanResult,\n): Promise<{ human: string; structured: Record<string, unknown> }> {\n const findings = result.findings;\n const byPhase: Record<number, Finding[]> = { 1: [], 2: [], 3: [] };\n for (const f of findings) {\n // Phase 1: HNDL-exposed confidentiality (harvest now, decrypt later) — most urgent.\n // Phase 2: forgeable signatures. Phase 3: transport / certificate config.\n if (f.hndl) byPhase[1].push(f);\n else if (f.category === \"tls\" || f.category === \"certificate\") byPhase[3].push(f);\n else byPhase[2].push(f);\n }\n\n const phaseMeta: Record<number, { title: string; rationale: string }> = {\n 1: {\n title: \"Harvest-now-decrypt-later (do first)\",\n rationale:\n \"Key exchange / public-key encryption. Traffic captured today is decryptable once a quantum computer exists — migrate these first.\",\n },\n 2: {\n title: \"Quantum-forgeable signatures\",\n rationale:\n \"Signatures are not retroactively broken, but become forgeable post-Q-day. Migrate before Q-day, prioritising long-lived keys.\",\n },\n 3: {\n title: \"Transport & certificate configuration\",\n rationale:\n \"TLS versions, cipher suites, and certificate signature algorithms. Adopt hybrid PQC named groups and plan PQC-capable CA re-issuance.\",\n },\n };\n\n async function groupsFor(list: Finding[]): Promise<PlanGroup[]> {\n const byAlgo = new Map<AlgorithmFamily, Finding[]>();\n for (const f of list) {\n const a = (f.algorithm ?? \"unknown\") as AlgorithmFamily;\n const arr = byAlgo.get(a) ?? [];\n arr.push(f);\n byAlgo.set(a, arr);\n }\n const groups: PlanGroup[] = [];\n for (const [algorithm, fs] of byAlgo) {\n const rem = await safe<Remediation | undefined>(\"remediationFor\", () =>\n remediationFor(algorithm),\n );\n groups.push({\n algorithm,\n count: fs.length,\n hndlCount: fs.filter((f) => f.hndl).length,\n remediation:\n rem.ok && rem.value ? rem.value.recommendation : \"Adopt NIST PQC (ML-KEM / ML-DSA).\",\n locations: fs.slice(0, 8).map((f) => `${f.location.file}:${f.location.line}`),\n });\n }\n // Largest groups first within a phase.\n groups.sort((a, b) => b.count - a.count);\n return groups;\n }\n\n const phases: PlanPhase[] = [];\n for (const p of [1, 2, 3]) {\n if (byPhase[p].length === 0) continue;\n phases.push({\n phase: p,\n title: phaseMeta[p].title,\n rationale: phaseMeta[p].rationale,\n groups: await groupsFor(byPhase[p]),\n });\n }\n\n const lines: string[] = [];\n lines.push(`Post-quantum migration plan for ${result.root}`);\n lines.push(\n `Readiness score: ${result.inventory.readinessScore}/100 · ${findings.length} finding(s) · ${result.inventory.hndlCount} HNDL-exposed`,\n );\n if (findings.length === 0) {\n lines.push(\"\");\n lines.push(\n result.analyzedFiles === 0\n ? \"No analyzable source was scanned — this plan does NOT cover unsupported languages.\"\n : \"No classical asymmetric cryptography found. Keep scanning in CI to hold the line.\",\n );\n return { human: lines.join(\"\\n\"), structured: { root: result.root, phases: [] } };\n }\n for (const ph of phases) {\n lines.push(\"\");\n lines.push(`Phase ${ph.phase}: ${ph.title}`);\n lines.push(` ${ph.rationale}`);\n for (const g of ph.groups) {\n lines.push(\n ` - ${g.algorithm} × ${g.count}${g.hndlCount ? ` (${g.hndlCount} HNDL)` : \"\"} → ${g.remediation}`,\n );\n lines.push(\n ` e.g. ${g.locations.join(\", \")}${g.count > g.locations.length ? \", …\" : \"\"}`,\n );\n }\n }\n lines.push(\"\");\n lines.push(\n \"Use get_fix_examples for per-algorithm code changes, then verify_fix to confirm each edit.\",\n );\n return {\n human: lines.join(\"\\n\"),\n structured: {\n root: result.root,\n readinessScore: result.inventory.readinessScore,\n totalFindings: findings.length,\n hndlExposed: result.inventory.hndlCount,\n phases,\n },\n };\n}\n\nconst getFixExamplesTool: ToolDefinition = {\n name: \"get_fix_examples\",\n description:\n \"Return before/after code examples for migrating a classical algorithm to a \" +\n \"post-quantum / hybrid replacement. Provide an 'algorithm' (RSA, ECDH, ECDSA, …) \" +\n \"or a 'ruleId' from a finding.\",\n inputSchema: {\n type: \"object\",\n properties: {\n algorithm: {\n type: \"string\",\n description: \"Classical algorithm family to migrate away from.\",\n },\n ruleId: { type: \"string\", description: \"A finding's ruleId (resolved to its algorithm).\" },\n },\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const algoInput = typeof args.algorithm === \"string\" ? args.algorithm.trim() : \"\";\n const ruleId = typeof args.ruleId === \"string\" ? args.ruleId.trim() : \"\";\n if (!algoInput && !ruleId) {\n return errorResult(\"get_fix_examples requires 'algorithm' or 'ruleId'.\");\n }\n let family: AlgorithmFamily;\n if (algoInput) {\n family = normalizeAlgorithm(algoInput);\n } else {\n const resolved = resolveRule(ruleId);\n family = resolved.meta?.algorithm ?? resolved.algorithm ?? \"unknown\";\n }\n // Fold families that share a fix onto the example we have.\n const key: AlgorithmFamily = family === \"ECIES\" ? \"RSA\" : family;\n const ex = FIX_EXAMPLES[key];\n if (!ex) {\n const rem = await safe<Remediation | undefined>(\"remediationFor\", () =>\n remediationFor(family),\n );\n return textResult(\n `No canned example for ${family}. ${\n rem.ok && rem.value\n ? rem.value.recommendation\n : \"Adopt NIST PQC (ML-KEM / ML-DSA), deployed as hybrids.\"\n }`,\n );\n }\n const text = [\n `Migration example — ${family}`,\n ex.note,\n \"\",\n \"BEFORE (classical):\",\n ex.before,\n \"\",\n \"AFTER (post-quantum / hybrid):\",\n ex.after,\n \"\",\n \"Deploy as a hybrid (classical + PQC) first; drop the classical half once the PQC side is proven.\",\n ].join(\"\\n\");\n return {\n content: [\n { type: \"text\", text },\n { type: \"text\", text: JSON.stringify({ algorithm: family, ...ex }, null, 2) },\n ],\n };\n },\n};\n\nconst verifyFixTool: ToolDefinition = {\n name: \"verify_fix\",\n description:\n \"Run the quantakrypto detectors over a code snippet (NOT the filesystem) and \" +\n \"report any classical crypto that remains. Use this to confirm an edit actually \" +\n \"removed the quantum-vulnerable usage. Provide 'code' plus a 'language' or 'filename'.\",\n inputSchema: {\n type: \"object\",\n properties: {\n code: { type: \"string\", description: \"The source code to check.\" },\n language: {\n type: \"string\",\n description: \"Language of the code (js, ts, python, go, java, csharp, rust, ruby, c, …).\",\n },\n filename: {\n type: \"string\",\n description:\n \"Optional filename; its extension selects the detectors (overrides 'language').\",\n },\n },\n required: [\"code\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const code = typeof args.code === \"string\" ? args.code : \"\";\n if (!code) return errorResult(\"verify_fix requires a non-empty 'code' string.\");\n const filename = typeof args.filename === \"string\" ? args.filename.trim() : \"\";\n const language = typeof args.language === \"string\" ? args.language.trim() : \"\";\n\n if (!filename && !language) {\n return errorResult(\n \"verify_fix requires a 'language' or a 'filename' to know which detectors to run.\",\n );\n }\n if (!filename && languageToExtension(language) === null) {\n return errorResult(\n `verify_fix: unknown language \"${language}\". Supported: js/ts, python, go, java, kotlin, csharp, rust, ruby, c/c++ — or pass a 'filename'.`,\n );\n }\n\n const res = await safe<VerifyResult>(\"verifyFix\", () =>\n verifyFix(code, { filename, language }),\n );\n if (!res.ok) return res.result;\n const { supported, findings } = res.value;\n if (findings.length === 0) {\n const caveat = supported\n ? \"Fix verified: no classical asymmetric cryptography detected in this snippet.\"\n : \"No classical crypto detected — but this language is NOT one the scanner analyzes, so this is not a verification. Use a supported language.\";\n return textResult(caveat);\n }\n const lines = [`Still ${findings.length} classical finding(s) — fix NOT complete:`];\n for (const f of findings) {\n lines.push(\n `- [${f.severity}] ${f.ruleId} (line ${f.location.line})${f.hndl ? \" (HNDL)\" : \"\"} — ${f.message}`,\n );\n }\n return {\n content: [\n { type: \"text\", text: lines.join(\"\\n\") },\n { type: \"text\", text: JSON.stringify(findings, null, 2) },\n ],\n };\n },\n};\n\nconst checkDependencyTool: ToolDefinition = {\n name: \"check_dependency\",\n description:\n \"Check whether a package is in quantakrypto's known quantum-vulnerable dependency \" +\n \"database (the classical crypto it exposes). Provide 'name' and optional 'ecosystem' (default npm).\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n description: \"Package name to look up (e.g. 'node-forge', 'jsonwebtoken').\",\n },\n ecosystem: { type: \"string\", description: \"Package ecosystem. Default: npm.\" },\n },\n required: [\"name\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const name = typeof args.name === \"string\" ? args.name.trim().toLowerCase() : \"\";\n if (!name) return errorResult(\"check_dependency requires a non-empty 'name'.\");\n const ecosystem =\n typeof args.ecosystem === \"string\" ? args.ecosystem.trim().toLowerCase() : \"npm\";\n\n const db = await safe<readonly VulnerableDependency[]>(\n \"vulnerableDependencies\",\n () => vulnerableDependencies,\n );\n if (!db.ok) return db.result;\n const hit = db.value.find(\n (d) => d.name.toLowerCase() === name && d.ecosystem.toLowerCase() === ecosystem,\n );\n if (!hit) {\n return textResult(\n `\"${name}\" (${ecosystem}) is NOT in the known quantum-vulnerable dependency database. ` +\n \"That is not proof it's safe — it may simply not be catalogued, or its crypto may be in your own code. Scan the source too.\",\n );\n }\n const rem = await safe<Remediation | undefined>(\"remediationFor\", () =>\n remediationFor(hit.algorithms[0] ?? \"unknown\"),\n );\n const text = [\n `${hit.name} (${hit.ecosystem}) — quantum-vulnerable [${hit.severity}]`,\n `Exposes: ${hit.algorithms.join(\", \")}`,\n `Why: ${hit.reason}`,\n rem.ok && rem.value\n ? `Migrate toward: ${rem.value.recommendation}`\n : \"Migrate toward NIST PQC (ML-KEM / ML-DSA).\",\n ].join(\"\\n\");\n return {\n content: [\n { type: \"text\", text },\n { type: \"text\", text: JSON.stringify(hit, null, 2) },\n ],\n };\n },\n};\n\n/**\n * JSON-schema shape of one finding from `scan_path --format json` (mirrors the\n * core {@link Finding} type). Used as the `items` schema for every findings\n * array below so MCP clients/inspectors get a described element shape instead of\n * a bare `type: \"array\"`. Extra finding fields are allowed (no\n * additionalProperties:false), only ruleId + location.file are required — which\n * is exactly what {@link areFindings} enforces.\n */\nconst FINDING_ITEM_SCHEMA = {\n type: \"object\",\n description: \"A single finding from `scan_path --format json`.\",\n properties: {\n ruleId: { type: \"string\", description: 'Stable rule id, e.g. \"rsa-keygen\".' },\n title: { type: \"string\" },\n category: { type: \"string\" },\n severity: { type: \"string\", description: \"critical | high | medium | low | info.\" },\n confidence: { type: \"string\" },\n algorithm: { type: \"string\", description: \"Classical algorithm family, when applicable.\" },\n hndl: { type: \"boolean\", description: \"Exposed to harvest-now-decrypt-later.\" },\n message: { type: \"string\" },\n remediation: { type: \"string\" },\n cwe: { type: \"string\", description: 'e.g. \"CWE-327\".' },\n location: {\n type: \"object\",\n description: \"Where the finding is.\",\n properties: {\n file: { type: \"string\" },\n line: { type: \"number\" },\n },\n required: [\"file\"],\n },\n },\n required: [\"ruleId\", \"location\"],\n};\n\n/** JSON-schema shape of one triage verdict for `apply_triage`. */\nconst VERDICT_ITEM_SCHEMA = {\n type: \"object\",\n description: \"A triage verdict for one finding.\",\n properties: {\n fingerprint: {\n type: \"string\",\n description: \"Fingerprint of the finding this verdict applies to.\",\n },\n exposureScore: {\n type: \"number\",\n description: \"Real-world exposure (higher = more exposed).\",\n },\n priority: { type: \"string\", enum: [\"now\", \"soon\", \"later\"] },\n rationale: { type: \"string\", description: \"Why this exposure score / priority.\" },\n },\n required: [\"fingerprint\", \"exposureScore\", \"priority\", \"rationale\"],\n};\n\nconst scoreDeltaTool: ToolDefinition = {\n name: \"score_delta\",\n description:\n \"Compute the readiness-score and HNDL change between two finding sets (e.g. before \" +\n \"and after a migration). Pass 'before' and 'after' as arrays of findings from \" +\n \"scan_path --format json.\",\n inputSchema: {\n type: \"object\",\n properties: {\n before: {\n type: \"array\",\n items: FINDING_ITEM_SCHEMA,\n description: \"Findings before the change (from a scan's JSON findings).\",\n },\n after: {\n type: \"array\",\n items: FINDING_ITEM_SCHEMA,\n description: \"Findings after the change.\",\n },\n },\n required: [\"before\", \"after\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n if (!Array.isArray(args.before) || !Array.isArray(args.after)) {\n return errorResult(\"score_delta requires 'before' and 'after' arrays of findings.\");\n }\n // Validate element shape too (mirrors triage/remediate) — a malformed\n // `severity` otherwise yields a NaN readiness score rendered as authoritative.\n if (!areFindings(args.before) || !areFindings(args.after)) {\n return errorResult(\"score_delta: 'before' and 'after' must be arrays of valid findings.\");\n }\n const before = args.before;\n const after = args.after;\n const invBefore = await safe<CryptoInventory>(\"buildInventory\", () => buildInventory(before));\n if (!invBefore.ok) return invBefore.result;\n const invAfter = await safe<CryptoInventory>(\"buildInventory\", () => buildInventory(after));\n if (!invAfter.ok) return invAfter.result;\n\n const dScore = invAfter.value.readinessScore - invBefore.value.readinessScore;\n const dHndl = invAfter.value.hndlCount - invBefore.value.hndlCount;\n const dCount = after.length - before.length;\n const sign = (n: number) => (n > 0 ? `+${n}` : `${n}`);\n const text = [\n \"Readiness delta\",\n `Score: ${invBefore.value.readinessScore} → ${invAfter.value.readinessScore} (${sign(dScore)})`,\n `Findings: ${before.length} → ${after.length} (${sign(dCount)})`,\n `HNDL: ${invBefore.value.hndlCount} → ${invAfter.value.hndlCount} (${sign(dHndl)})`,\n dScore > 0\n ? \"Progress: readiness improved.\"\n : dScore < 0\n ? \"Regression: readiness dropped — new classical crypto was introduced.\"\n : \"No net change in readiness.\",\n ].join(\"\\n\");\n return {\n content: [\n { type: \"text\", text },\n {\n type: \"text\",\n text: JSON.stringify(\n {\n before: {\n score: invBefore.value.readinessScore,\n findings: before.length,\n hndl: invBefore.value.hndlCount,\n },\n after: {\n score: invAfter.value.readinessScore,\n findings: after.length,\n hndl: invAfter.value.hndlCount,\n },\n delta: { score: dScore, findings: dCount, hndl: dHndl },\n },\n null,\n 2,\n ),\n },\n ],\n };\n },\n};\n\n/**\n * True when every element looks like a scan Finding (a string `ruleId` and a\n * `location.file`). Guards the triage/remediate tools so a malformed `findings`\n * element surfaces as a tool `isError` result rather than throwing a protocol\n * `-32603` internal error downstream (audit: mcp #4).\n */\nfunction areFindings(arr: readonly unknown[]): arr is Finding[] {\n return arr.every(\n (f) =>\n f !== null &&\n typeof f === \"object\" &&\n typeof (f as { ruleId?: unknown }).ruleId === \"string\" &&\n typeof (f as { location?: { file?: unknown } }).location?.file === \"string\",\n );\n}\n\nconst triageFindingsTool: ToolDefinition = {\n name: \"triage_findings\",\n description:\n \"Produce a deterministic triage REQUEST bundle (rubric + verdict schema + \" +\n \"per-finding metadata) for YOU (the host agent) to reason over. This tool does \" +\n \"NOT call any model and needs no API key. Assess each finding's real-world \" +\n \"exposure, then call apply_triage with your verdicts. Pass 'findings' as an \" +\n \"array from scan_path --format json.\",\n inputSchema: {\n type: \"object\",\n properties: {\n findings: {\n type: \"array\",\n items: FINDING_ITEM_SCHEMA,\n description: \"Findings from a scan's JSON output.\",\n },\n },\n required: [\"findings\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n if (!Array.isArray(args.findings) || !areFindings(args.findings)) {\n return errorResult(\n \"triage_findings requires a 'findings' array of scan findings (each with a string ruleId and location.file).\",\n );\n }\n const findings = args.findings;\n const request = buildTriageRequest(findings, \"metadata\");\n // Pair each context with the finding fingerprint the verdict must echo back.\n const items = findings.map((f, i) => ({\n fingerprint: fingerprintFinding(f),\n context: request.contexts[i],\n }));\n // The verdict schema advertised to the agent MUST include `fingerprint`\n // (the instructions require it, and apply_triage keys on it) — core's\n // single-verdict schema doesn't, so extend it here (audit: mcp bundle).\n const props = (request.schema as { properties?: Record<string, unknown> }).properties ?? {};\n const schema = {\n type: \"object\",\n required: [\"fingerprint\", \"exposureScore\", \"priority\", \"rationale\"],\n properties: { fingerprint: { type: \"string\" }, ...props },\n };\n const bundle = { rubric: request.rubric, schema, items };\n return {\n content: [\n {\n type: \"text\",\n text:\n \"Triage request. For each item, decide {exposureScore 0-100, priority, rationale} \" +\n \"per the rubric, then call apply_triage with the same 'findings' and a 'verdicts' \" +\n \"array (each carrying the item's 'fingerprint'). You never suppress a finding.\",\n },\n { type: \"text\", text: JSON.stringify(bundle, null, 2) },\n ],\n };\n },\n};\n\n/** Validate one caller-supplied triage verdict. Returns null when malformed. */\nfunction parseVerdict(\n v: unknown,\n): { fingerprint: string; exposureScore: number; priority: string; rationale: string } | null {\n if (typeof v !== \"object\" || v === null) return null;\n const o = v as Record<string, unknown>;\n const fingerprint = o.fingerprint;\n const exposureScore = o.exposureScore;\n const priority = o.priority;\n const rationale = o.rationale;\n if (typeof fingerprint !== \"string\") return null;\n // `Number.isFinite` rejects NaN/Infinity — NaN passes both `< 0` and `> 100`\n // (they're false) and would poison the exposure sort comparator (audit: mcp #3).\n if (typeof exposureScore !== \"number\" || !Number.isFinite(exposureScore)) return null;\n if (exposureScore < 0 || exposureScore > 100) return null;\n if (priority !== \"now\" && priority !== \"soon\" && priority !== \"later\") return null;\n if (typeof rationale !== \"string\") return null;\n return { fingerprint, exposureScore, priority, rationale };\n}\n\nconst applyTriageTool: ToolDefinition = {\n name: \"apply_triage\",\n description:\n \"Deterministically attach your triage verdicts to their findings and re-sort by \" +\n \"exposure (highest first). Never suppresses. Pass the same 'findings' array you \" +\n \"triaged plus a 'verdicts' array of { fingerprint, exposureScore, priority, rationale }.\",\n inputSchema: {\n type: \"object\",\n properties: {\n findings: {\n type: \"array\",\n items: FINDING_ITEM_SCHEMA,\n description: \"The findings that were triaged.\",\n },\n verdicts: {\n type: \"array\",\n items: VERDICT_ITEM_SCHEMA,\n description: \"One verdict per finding, keyed by fingerprint.\",\n },\n },\n required: [\"findings\", \"verdicts\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n if (!Array.isArray(args.findings) || !Array.isArray(args.verdicts)) {\n return errorResult(\"apply_triage requires 'findings' and 'verdicts' arrays.\");\n }\n if (!areFindings(args.findings)) {\n return errorResult(\n \"apply_triage: each 'findings' element needs a string ruleId and location.file.\",\n );\n }\n const findings = args.findings;\n const byFingerprint = new Map<string, ReturnType<typeof parseVerdict>>();\n let skipped = 0;\n for (const raw of args.verdicts) {\n const v = parseVerdict(raw);\n if (v) byFingerprint.set(v.fingerprint, v);\n else skipped++;\n }\n const annotated = findings.map((f) => {\n const v = byFingerprint.get(fingerprintFinding(f));\n return v\n ? {\n ...f,\n triage: {\n exposureScore: v.exposureScore,\n priority: v.priority as \"now\" | \"soon\" | \"later\",\n rationale: v.rationale,\n },\n }\n : f;\n });\n annotated.sort((a, b) => {\n const ea = a.triage?.exposureScore ?? -1;\n const eb = b.triage?.exposureScore ?? -1;\n if (eb !== ea) return eb - ea;\n return compareFindings(a, b);\n });\n const applied = annotated.filter((f) => f.triage).length;\n const head =\n `Triaged ${applied}/${findings.length} finding(s), re-sorted by exposure.` +\n (skipped ? ` ${skipped} malformed verdict(s) ignored.` : \"\");\n return {\n content: [\n { type: \"text\", text: head },\n { type: \"text\", text: JSON.stringify(annotated, null, 2) },\n ],\n };\n },\n};\n\nconst remediateFindingsTool: ToolDefinition = {\n name: \"remediate_findings\",\n description:\n \"Produce a deterministic remediation REQUEST bundle (rubric + fix schema + \" +\n \"per-finding metadata + fingerprints) for YOU (the host agent) to fix. This \" +\n \"tool calls no model and needs no key. For each finding, propose the corrected \" +\n \"FULL file content, then VERIFY with verify_fix and keep only fixes that clear \" +\n \"the finding. Never touch files with secrets; never auto-merge. Pass 'findings' \" +\n \"from scan_path --format json.\",\n inputSchema: {\n type: \"object\",\n properties: {\n findings: {\n type: \"array\",\n items: FINDING_ITEM_SCHEMA,\n description: \"Findings from a scan's JSON output.\",\n },\n },\n required: [\"findings\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n if (!Array.isArray(args.findings) || !areFindings(args.findings)) {\n return errorResult(\n \"remediate_findings requires a 'findings' array of scan findings (each with a string ruleId and location.file).\",\n );\n }\n const findings = args.findings;\n const request = buildRemediateRequest(findings, \"metadata\");\n const items = findings.map((f, i) => ({\n fingerprint: fingerprintFinding(f),\n context: request.contexts[i],\n }));\n const bundle = { instructions: request.instructions, schema: request.schema, items };\n return {\n content: [\n {\n type: \"text\",\n text:\n \"Remediation request. For each item, propose {path, newContent, explanation} \" +\n \"(the FULL corrected file), call verify_fix on your newContent, and keep only \" +\n \"verified fixes. Skip any file containing secrets. This never merges anything.\",\n },\n { type: \"text\", text: JSON.stringify(bundle, null, 2) },\n ],\n };\n },\n};\n\nconst applyVerifiedPatchTool: ToolDefinition = {\n name: \"apply_verified_patch\",\n description:\n \"Deterministically VERIFY a proposed fix before writing it — runs the same \" +\n \"patch-policy + verify_fix + blast-radius gates as `qremediate` (offline, no \" +\n \"key, no network). Give the finding, the file's current content, and your \" +\n \"proposed FULL corrected content; returns approved:true only if the patch is \" +\n \"in-policy, clears the finding, adds no new finding, introduces no network/exec \" +\n \"sink, and is bounded in size. This does NOT write the file — you write it, \" +\n \"only when approved, and never auto-merge.\",\n inputSchema: {\n type: \"object\",\n properties: {\n finding: {\n type: \"object\",\n description: \"The scan finding being fixed (needs a string ruleId and location.file).\",\n },\n originalContent: { type: \"string\", description: \"The file's current full content.\" },\n newContent: { type: \"string\", description: \"Your proposed full corrected file content.\" },\n },\n required: [\"finding\", \"originalContent\", \"newContent\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const finding = args.finding as Finding;\n if (!finding || typeof finding !== \"object\" || !areFindings([finding])) {\n return errorResult(\n \"apply_verified_patch requires a 'finding' with a string ruleId and location.file.\",\n );\n }\n if (typeof args.originalContent !== \"string\" || typeof args.newContent !== \"string\") {\n return errorResult(\n \"apply_verified_patch requires string 'originalContent' and 'newContent'.\",\n );\n }\n const file = finding.location.file;\n const originalContent = args.originalContent;\n const patch = {\n path: file,\n newContent: args.newContent,\n ruleId: finding.ruleId,\n source: \"llm\" as const,\n };\n const res = await safe(\"apply_verified_patch\", () =>\n remediateFindings([finding], {\n readContent: () => originalContent,\n patchSource: () => patch,\n policy: {\n findingFiles: new Set([file]),\n manifestFiles: new Set(isManifestFile(file) ? [file] : []),\n },\n }),\n );\n if (!res.ok) return res.result;\n const approved = res.value.applied.length > 0;\n return textResult(\n JSON.stringify(\n {\n approved,\n path: file,\n ruleId: finding.ruleId,\n ...(approved ? {} : { reason: res.value.rejected[0]?.reason ?? \"rejected\" }),\n note: approved\n ? \"Cleared every deterministic gate — safe to write. Open a diff/PR for review; never auto-merge.\"\n : \"Rejected by the deterministic gates — do NOT write this patch.\",\n },\n null,\n 2,\n ),\n );\n },\n};\n\n/**\n * `probe_endpoint` — actively probe ONE live TLS/SSH endpoint the caller OWNS for\n * post-quantum readiness. This is the ONLY MCP tool that opens a network socket;\n * the qprobe plane is loaded via dynamic import so the server stays offline until\n * the tool is actually invoked, and the ownership attestation gate is enforced in\n * qProbe's `runProbe` before any connection. On the HTTP transport it is OFF by\n * default (see {@link NETWORK_TOOL_NAMES}) — a hosted endpoint should not probe\n * arbitrary hosts — but a trusted operator can opt in with\n * QUANTAKRYPTO_MCP_ALLOW_NETWORK=1.\n */\nconst probeEndpointTool: ToolDefinition = {\n name: \"probe_endpoint\",\n description:\n \"Actively probe ONE live TLS/SSH endpoint YOU OWN for post-quantum readiness \" +\n \"(PQC-hybrid key exchange X25519MLKEM768, classical certificate posture). REQUIRES \" +\n \"an ownership attestation: set i_own_this=true to confirm you are authorized to test \" +\n \"the target. Refuses CIDR ranges / wildcards / lists — one host at a time. Performs \" +\n \"only a benign, unauthenticated handshake and never modifies the endpoint. NOTE: this \" +\n \"is the ONLY quantakrypto MCP tool that opens a network connection; the server is \" +\n \"otherwise offline. Over HTTP it is disabled unless the operator sets \" +\n \"QUANTAKRYPTO_MCP_ALLOW_NETWORK=1.\",\n inputSchema: {\n type: \"object\",\n properties: {\n target: {\n type: \"string\",\n description: \"A single host or host:port you own (no ranges/CIDRs/wildcards).\",\n },\n mode: {\n type: \"string\",\n enum: [\"tls\", \"ssh\", \"auto\"],\n description: \"Probe mode (default: auto — SSH on :22, TLS otherwise).\",\n },\n i_own_this: {\n type: \"boolean\",\n description:\n \"Attestation that you are authorized to probe this endpoint. Must be true; the probe is refused otherwise.\",\n },\n timeout_ms: { type: \"number\", description: \"Per-connection timeout in ms (default 8000).\" },\n },\n required: [\"target\", \"i_own_this\"],\n additionalProperties: false,\n },\n async handler(args): Promise<ToolResult> {\n const target = args.target;\n if (typeof target !== \"string\" || target.length === 0) {\n return errorResult(\"probe_endpoint requires a non-empty 'target' string.\");\n }\n if (args.i_own_this !== true) {\n return errorResult(\n \"probe_endpoint refused: set i_own_this=true to attest you are authorized to probe this endpoint. Active probing of endpoints you do not own may be unlawful.\",\n );\n }\n const mode = args.mode === \"tls\" || args.mode === \"ssh\" ? args.mode : \"auto\";\n const timeoutMs = typeof args.timeout_ms === \"number\" ? args.timeout_ms : undefined;\n // Dynamic import keeps the networked qprobe plane out of the server process\n // until this tool is actually used; runProbe enforces the attestation gate.\n const qprobe = await import(\"@quantakrypto/qprobe\");\n // Parse the target explicitly so a CIDR/range/list refusal returns a helpful\n // message rather than a scrubbed internal error.\n let parsed;\n try {\n parsed = qprobe.parseTarget(target, mode === \"ssh\" ? 22 : 443);\n } catch (e) {\n return errorResult(`probe_endpoint: ${e instanceof Error ? e.message : String(e)}`);\n }\n const probed = await safe(\"probe_endpoint\", () =>\n qprobe.runProbe({ targets: [parsed], mode, attest: { iOwnThis: true }, timeoutMs }),\n );\n if (!probed.ok) return probed.result;\n const { reports, findings, inventory } = probed.value;\n const lines: string[] = [];\n let unreachable = 0;\n for (const r of reports) {\n lines.push(`${r.target.host}:${r.target.port} [${r.mode}]`);\n const err = r.ssh?.error ?? r.tls?.error ?? r.hybrid?.error;\n if (err && r.findings.length === 0) {\n unreachable++;\n // Do NOT let an unreachable/errored endpoint read as a clean 100/100.\n lines.push(` ⚠ probe error: ${err} — endpoint NOT assessed (not a clean result)`);\n }\n for (const p of r.positives) lines.push(` ✓ ${p}`);\n for (const f of r.findings) lines.push(` [${f.severity}] ${f.title} — ${f.message}`);\n }\n const note =\n unreachable > 0\n ? \" — NOTE: an endpoint could not be reached/handshaken, so this is NOT a clean bill of health\"\n : \"\";\n lines.push(\n `\\n${findings.length} finding${findings.length === 1 ? \"\" : \"s\"} · ${inventory.hndlCount} HNDL-exposed · readiness ${inventory.readinessScore}/100${note}`,\n );\n return {\n content: [\n { type: \"text\", text: lines.join(\"\\n\") },\n { type: \"text\", text: JSON.stringify({ findings, inventory }, null, 2) },\n ],\n };\n },\n};\n\n/**\n * Tools that read arbitrary filesystem paths. Disabled by default on the HTTP\n * transport (see {@link ./http.ts}) because a hosted endpoint must not be an\n * arbitrary-file-read oracle (security audit Q-01). The stdio transport, which\n * trusts the local user, always exposes them.\n */\nexport const FS_TOOL_NAMES: readonly string[] = [\n \"scan_path\",\n \"inventory_crypto\",\n \"generate_cbom\",\n \"plan_migration\",\n];\n\n/**\n * Tools that open network connections. On the HTTP transport they are OFF by\n * default — a hosted MCP should not probe arbitrary hosts — but a trusted operator\n * can opt in with QUANTAKRYPTO_MCP_ALLOW_NETWORK=1 (mirroring the FS-tools opt-in).\n * Always available on the local stdio transport, which trusts the local user.\n */\nexport const NETWORK_TOOL_NAMES: readonly string[] = [\"probe_endpoint\"];\n\n/** All quantakrypto MCP tools, in a stable order. */\nexport const quantakryptoTools: ToolDefinition[] = [\n scanPathTool,\n inventoryCryptoTool,\n explainFindingTool,\n suggestHybridTool,\n listRulesTool,\n generateCbomTool,\n // Copilot tools — migrate through the engine.\n planMigrationTool,\n getFixExamplesTool,\n verifyFixTool,\n checkDependencyTool,\n scoreDeltaTool,\n // BYOK triage + remediation — deterministic request/apply (host agent reasons; offline).\n triageFindingsTool,\n applyTriageTool,\n remediateFindingsTool,\n applyVerifiedPatchTool,\n // The only networked tool — offline until invoked; refused on the HTTP transport.\n probeEndpointTool,\n];\n\n/** The core version these tools are built against (re-exported for diagnostics). */\nexport const CORE_VERSION = VERSION;\n\n/** Exposed for tests and advanced callers. */\nexport const __test = {\n normalizeAlgorithm,\n summarizeScan,\n staticHybridAdvice,\n buildScanOptions,\n describeError,\n FIX_EXAMPLES,\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quantakrypto/mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
|
+
"mcpName": "io.github.quantakrypto/pqc-tools",
|
|
4
5
|
"description": "quantakrypto MCP — post-quantum readiness for AI coding agents via the Model Context Protocol. Zero runtime dependencies (stdio JSON-RPC implemented in-house).",
|
|
5
6
|
"license": "Apache-2.0",
|
|
6
7
|
"author": "Dandelion Labs <hello@dandelionlabs.io> (https://dandelionlabs.io)",
|