refactor(mcp): make analysis states unrepresentable (#468)

* refactor(config): parse capability settings into exact states

* refactor(runtime): encode replay and process outcomes exactly

* refactor: make analysis states unrepresentable

* refactor(mcp): register canonical schemas with SDK

* fix: preserve capability and catalog invariants

* fix(build): remove stale compiled modules

* fix(replay): update real verifier policy dependency

* fix(package): verify the complete MCP catalog

* fix(test): supply complete replay reload policy

* refactor(contracts): centralize output schema lookup

* refactor(mcp): delegate protocol boundaries to SDK

* fix(browser): approve real source capture

* fix(mcp): preserve catalog guidance
This commit is contained in:
morluto authored and GitHub committed 2026-08-10 02:28:11 +08:00
1 parent 6901edc05d
commit b8a9da0c0f
271 files changed
+5970 -5699

No files matched your search

@@ -1,5 +1,4 @@
import type { McpServer } from "@modelcontextprotocol/server";
import type { z } from "zod";
import type { McpServer, ServerContext } from "@modelcontextprotocol/server";
import type { BinarySessionPort } from "../application/BinarySession.js";
import type { JavaScriptRuntimeObservationPort } from "../application/JavaScriptRuntimeObservationPort.js";
@@ -12,14 +11,9 @@ import { JAVASCRIPT_RUNTIME_OBSERVATION_TOOL_CONTRACTS } from "../contracts/java
import type { ToolContract } from "../contracts/toolContracts.js";
import type { AnalysisError } from "../domain/errors.js";
import type { Evidence } from "../domain/evidence.js";
import {
listJavaScriptRuntimeTargetsInputSchema,
observeJavaScriptRuntimeInputSchema,
} from "../domain/javascriptRuntimeObservation.js";
import type { Result } from "../domain/result.js";
import type { Logger } from "../logger.js";
import { logToolExecution } from "./toolLogging.js";
import { safeParseToolInput } from "./toolInputValidation.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
import { toCallToolResult } from "./toolResult.js";
@@ -30,15 +24,6 @@ interface RuntimeToolRegistration {
readonly recordEvidence: BinarySessionPort["recordEvidence"] | undefined;
}
interface RuntimeToolSpec<Schema extends z.ZodType> {
readonly contract: ToolContract;
readonly schema: Schema;
readonly execute: (
parsed: z.output<Schema>,
signal: AbortSignal,
) => Promise<Result<Evidence, AnalysisError>>;
}
/** Register passive Inspector tools even when policy keeps them unavailable. */
export const registerJavaScriptRuntimeObservationTools = (
server: McpServer,
@@ -46,53 +31,60 @@ export const registerJavaScriptRuntimeObservationTools = (
): void => {
const [listContract, observeContract] =
JAVASCRIPT_RUNTIME_OBSERVATION_TOOL_CONTRACTS;
registerRuntimeTool(server, options, {
contract: listContract,
schema: listJavaScriptRuntimeTargetsInputSchema,
execute: (parsed, signal) =>
listJavaScriptRuntimeTargets(
options.runtime,
options.permissionAuthority,
parsed,
{ signal },
),
});
registerRuntimeTool(server, options, {
contract: observeContract,
schema: observeJavaScriptRuntimeInputSchema,
execute: (parsed, signal) =>
observeJavaScriptRuntime(
options.runtime,
options.permissionAuthority,
parsed,
{ signal },
),
});
};
const registerRuntimeTool = <Schema extends z.ZodType>(
server: McpServer,
options: RuntimeToolRegistration,
spec: RuntimeToolSpec<Schema>,
): void => {
server.registerTool(
spec.contract.name,
toolRegistrationOptions(spec.contract),
async (input, context) => {
const parsed = safeParseToolInput(spec.schema, input, spec.contract.name);
if (!parsed.ok) return toCallToolResult(parsed, spec.contract);
const result = await logToolExecution(
options.logger,
spec.contract.name,
() => spec.execute(parsed.value, context.mcpReq.signal),
);
if (!result.ok) return toCallToolResult(result, spec.contract);
const recorded = options.recordEvidence?.(result.value);
return recorded !== undefined && !recorded.ok
? toCallToolResult(recorded, spec.contract)
: toCallToolResult({ ok: true, value: result.value }, spec.contract, {
evidenceResourcesAvailable: recorded !== undefined,
});
},
listContract.name,
toolRegistrationOptions(listContract),
(input, context) =>
runRuntimeTool(
options,
listContract,
{ input, context },
(parsed, signal) =>
listJavaScriptRuntimeTargets(
options.runtime,
options.permissionAuthority,
parsed,
{ signal },
),
),
);
server.registerTool(
observeContract.name,
toolRegistrationOptions(observeContract),
(input, context) =>
runRuntimeTool(
options,
observeContract,
{ input, context },
(parsed, signal) =>
observeJavaScriptRuntime(
options.runtime,
options.permissionAuthority,
parsed,
{ signal },
),
),
);
};
const runRuntimeTool = async <Input>(
options: RuntimeToolRegistration,
contract: ToolContract,
request: { readonly input: Input; readonly context: ServerContext },
execute: (
input: Input,
signal: AbortSignal,
) => Promise<Result<Evidence, AnalysisError>>,
) => {
const { input, context } = request;
const result = await logToolExecution(options.logger, contract.name, () =>
execute(input, context.mcpReq.signal),
);
if (!result.ok) return toCallToolResult(result, contract);
const recorded = options.recordEvidence?.(result.value);
return recorded !== undefined && !recorded.ok
? toCallToolResult(recorded, contract)
: toCallToolResult({ ok: true, value: result.value }, contract, {
evidenceResourcesAvailable: recorded !== undefined,
});
};