- Run Prettier on the 60 core/ files this PR touched — the deterministic import rewrite had collapsed multi-line imports and left throws unwrapped; core/ is in no format gate so it slipped past CI. Now Prettier-clean. - Default-path output-schema violation now throws ProtocolError(ProtocolErrorCode.InvalidParams, …) instead of a bare Error, matching the prior v1 contract (SDK threw a typed McpError with a code) so downstream `instanceof`/`.code` branching keeps working. - Document the "assumes serial construction" invariant on pollTaskToolCall's progress-subscription revival (the `_progressHandlers` new-key heuristic). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
47 lines
1.8 KiB
TypeScript
47 lines
1.8 KiB
TypeScript
import type { CallToolResult, Tool } from "@modelcontextprotocol/client";
|
|
import type {
|
|
JsonSchemaType,
|
|
jsonSchemaValidator,
|
|
} from "@modelcontextprotocol/client";
|
|
|
|
/**
|
|
* Validate a delivered tool result's `structuredContent` against the tool's
|
|
* declared `outputSchema`, mirroring the SDK client's strict check but WITHOUT
|
|
* throwing. Returns a human-readable error message when a strict client would
|
|
* reject the payload, or `undefined` when it's valid (or there's nothing to
|
|
* check).
|
|
*
|
|
* Used by {@link InspectorClient.callTool}'s `skipOutputValidation` path: MCP
|
|
* Apps forward the result verbatim to the running view, so the host must not
|
|
* reject it — but it should still surface the mismatch as a non-fatal advisory.
|
|
*
|
|
* @param provider A JSON Schema validator provider (the SDK's Ajv provider).
|
|
* @param tool The tool that was called (carries the declared outputSchema).
|
|
* @param result The delivered CallToolResult.
|
|
*/
|
|
export function validateToolOutput(
|
|
provider: jsonSchemaValidator,
|
|
tool: Tool,
|
|
result: CallToolResult,
|
|
): string | undefined {
|
|
if (!tool.outputSchema) return undefined;
|
|
const structured = result.structuredContent;
|
|
if (structured == null) {
|
|
// Strict clients reject "has outputSchema but no structuredContent" unless
|
|
// the result is itself an error.
|
|
return result.isError
|
|
? undefined
|
|
: `Tool "${tool.name}" declares an output schema but returned no structured content`;
|
|
}
|
|
try {
|
|
const validate = provider.getValidator(
|
|
tool.outputSchema as unknown as JsonSchemaType,
|
|
);
|
|
const validation = validate(structured);
|
|
return validation.valid ? undefined : validation.errorMessage;
|
|
} catch {
|
|
// A malformed schema (validator compilation failure) shouldn't block the
|
|
// call or produce a misleading warning.
|
|
return undefined;
|
|
}
|
|
}
|