@mcpfn/testing 0.0.4 → 0.0.6
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/README.md +178 -2
- package/dist/auth.cjs +1 -1
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.js +1 -1
- package/dist/auth.js.map +1 -1
- package/dist/index.cjs +3016 -158
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +426 -89
- package/dist/index.d.ts +426 -89
- package/dist/index.js +2993 -155
- package/dist/index.js.map +1 -1
- package/dist/playwright.cjs +1 -1
- package/dist/playwright.cjs.map +1 -1
- package/dist/playwright.js +1 -1
- package/dist/playwright.js.map +1 -1
- package/package.json +43 -16
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/assertions.ts","../src/auth-core.ts","../src/mock-oauth-server.ts","../src/client.ts","../src/conformance.ts","../src/host-profiles.ts","../src/scenarios.ts","../src/suite.ts"],"sourcesContent":["export * from \"./assertions.js\";\nexport * from \"./auth.js\";\nexport * from \"./client.js\";\nexport * from \"./conformance.js\";\nexport * from \"./host-profiles.js\";\nexport * from \"./scenarios.js\";\nexport * from \"./suite.js\";\n","import type { Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport { UriTemplate } from \"@modelcontextprotocol/sdk/shared/uriTemplate.js\";\nimport type { McpFnManifest } from \"@mcpfn/core\";\n\nimport type { McpFnTestClient } from \"./client.js\";\n\nexport function stableJson(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableJson).join(\",\")}]`;\n if (value && typeof value === \"object\") {\n return `{${Object.entries(value as Record<string, unknown>)\n .filter(([, entry]) => entry !== undefined)\n .sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)\n .map(([key, entry]) => `${JSON.stringify(key)}:${stableJson(entry)}`)\n .join(\",\")}}`;\n }\n return JSON.stringify(value);\n}\n\nexport class McpFnAssertionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"McpFnAssertionError\";\n }\n}\n\nexport interface AssertManifestContractOptions {\n /** Exact tools expected to be visible for the test client's request context. */\n expectedToolNames?: readonly string[];\n}\n\nexport async function assertManifestContract(\n client: McpFnTestClient<unknown>,\n manifest: McpFnManifest,\n options: AssertManifestContractOptions = {},\n): Promise<Tool[]> {\n const actual = await client.listTools();\n const actualByName = new Map(actual.map((tool) => [tool.name, tool]));\n const manifestByName = new Map(manifest.tools.map((tool) => [tool.name, tool]));\n const expectedNames = [...(\n options.expectedToolNames ?? manifest.tools.map((tool) => tool.name)\n )].sort();\n const unknownExpectedNames = expectedNames.filter((name) => !manifestByName.has(name));\n if (unknownExpectedNames.length) {\n throw new McpFnAssertionError(\n `Expected visible tools are absent from the manifest: ${stableJson(unknownExpectedNames)}`,\n );\n }\n const actualNames = actual.map((tool) => tool.name).sort();\n if (stableJson(expectedNames) !== stableJson(actualNames)) {\n throw new McpFnAssertionError(\n `Tool inventory mismatch\\nexpected: ${stableJson(expectedNames)}\\nactual: ${stableJson(actualNames)}`,\n );\n }\n for (const name of expectedNames) {\n const expected = manifestByName.get(name)!;\n const tool = actualByName.get(expected.name)!;\n const comparableExpected = {\n name: expected.name,\n description: expected.description,\n inputSchema: expected.inputSchema,\n outputSchema: expected.outputSchema,\n annotations: expected.annotations,\n execution: expected.execution,\n icons: expected.icons,\n title: expected.title,\n _meta: expected.metadata,\n };\n const comparableActual = {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n outputSchema: tool.outputSchema,\n annotations: tool.annotations,\n execution: tool.execution,\n icons: tool.icons,\n title: tool.title,\n _meta: tool._meta,\n };\n if (stableJson(comparableExpected) !== stableJson(comparableActual)) {\n throw new McpFnAssertionError(\n `Contract mismatch for ${expected.name}\\nexpected: ${stableJson(comparableExpected)}\\nactual: ${stableJson(comparableActual)}`,\n );\n }\n }\n\n const actualCapabilities = client.client.getServerCapabilities() ?? {};\n if (stableJson(manifest.capabilities ?? {}) !== stableJson(actualCapabilities)) {\n throw new McpFnAssertionError(\n `Capability mismatch\\nexpected: ${stableJson(manifest.capabilities ?? {})}\\nactual: ${stableJson(actualCapabilities)}`,\n );\n }\n\n const actualResources = actualCapabilities.resources\n ? await client.listResources()\n : [];\n const comparableResources = actualResources.map(({ _meta, ...resource }) => ({\n ...resource,\n metadata: _meta,\n }));\n const staticResourceUris = new Set(\n (manifest.resources ?? []).map((resource) => resource.uri),\n );\n const resourceTemplates = (manifest.resourceTemplates ?? []).map(\n (template) => new UriTemplate(template.uriTemplate),\n );\n const comparableStaticResources = comparableResources.filter(\n (resource) =>\n staticResourceUris.has(resource.uri) ||\n !resourceTemplates.some((template) => template.match(resource.uri)),\n );\n const expectedResources = (manifest.resources ?? []).map(\n ({ subscribable: _subscribable, ...resource }) => resource,\n );\n if (stableJson(expectedResources) !== stableJson(comparableStaticResources)) {\n throw new McpFnAssertionError(\n `Resource inventory mismatch\\nexpected: ${stableJson(expectedResources)}\\nactual: ${stableJson(comparableStaticResources)}`,\n );\n }\n\n const actualTemplates = actualCapabilities.resources\n ? await client.listResourceTemplates()\n : [];\n const comparableTemplates = actualTemplates.map(({ _meta, ...template }) => ({\n ...template,\n metadata: _meta,\n }));\n const expectedTemplates = (manifest.resourceTemplates ?? []).map(\n ({ subscribable: _subscribable, ...template }) => template,\n );\n if (stableJson(expectedTemplates) !== stableJson(comparableTemplates)) {\n throw new McpFnAssertionError(\n `Resource template inventory mismatch\\nexpected: ${stableJson(expectedTemplates)}\\nactual: ${stableJson(comparableTemplates)}`,\n );\n }\n\n for (const resource of comparableResources) {\n const expected = (manifest.resources ?? []).find(\n (candidate) => candidate.uri === resource.uri,\n ) ?? (manifest.resourceTemplates ?? []).find(\n (candidate) => new UriTemplate(candidate.uriTemplate).match(resource.uri),\n );\n const subscribable = expected?.subscribable === true;\n if (subscribable) {\n try {\n await client.subscribeResource(resource.uri);\n await client.unsubscribeResource(resource.uri);\n } catch (error) {\n throw new McpFnAssertionError(\n `Resource subscription mismatch for ${resource.uri}: expected subscribe and unsubscribe to succeed (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n continue;\n }\n let accepted = false;\n try {\n await client.subscribeResource(resource.uri);\n accepted = true;\n await client.unsubscribeResource(resource.uri).catch(() => undefined);\n } catch {\n // Rejection is the expected behavior for a non-subscribable resource.\n }\n if (accepted) {\n throw new McpFnAssertionError(\n `Resource subscription mismatch for ${resource.uri}: expected subscribe to be rejected`,\n );\n }\n }\n\n const actualPrompts = actualCapabilities.prompts\n ? await client.listPrompts()\n : [];\n const comparablePrompts = actualPrompts.map(({ _meta, ...prompt }) => ({\n ...prompt,\n metadata: _meta,\n }));\n const expectedPrompts = (manifest.prompts ?? []).map(({ argumentsSchema: _schema, ...prompt }) => prompt);\n if (stableJson(expectedPrompts) !== stableJson(comparablePrompts)) {\n throw new McpFnAssertionError(\n `Prompt inventory mismatch\\nexpected: ${stableJson(expectedPrompts)}\\nactual: ${stableJson(comparablePrompts)}`,\n );\n }\n return actual;\n}\n\nexport function assertStructuredTextParity(result: {\n content?: unknown[];\n structuredContent?: Record<string, unknown>;\n}): void {\n if (!result.structuredContent) {\n throw new McpFnAssertionError(\"Tool result has no structuredContent\");\n }\n const text = (result.content ?? []).find(\n (entry): entry is { type: \"text\"; text: string } =>\n !!entry &&\n typeof entry === \"object\" &&\n (entry as { type?: unknown }).type === \"text\" &&\n typeof (entry as { text?: unknown }).text === \"string\",\n )?.text;\n if (!text) {\n throw new McpFnAssertionError(\"Tool result has no text content\");\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n throw new McpFnAssertionError(\"Tool text content is not JSON\");\n }\n if (stableJson(parsed) !== stableJson(result.structuredContent)) {\n throw new McpFnAssertionError(\n \"Tool text content and structuredContent are not equivalent\",\n );\n }\n}\n","export type McpFnAuthCredentialKind = \"api-key\" | \"oauth\";\n\nexport interface McpFnAuthCredential {\n kind: McpFnAuthCredentialKind;\n headers: HeadersInit;\n label?: string;\n dispose?(): void | Promise<void>;\n}\n\nexport interface McpFnAuthCredentialRequest {\n kind: McpFnAuthCredentialKind;\n scopes?: string[];\n resource?: string;\n expiresInSeconds?: number;\n}\n\nexport interface McpFnAuthProviderCapabilities {\n expiration?: boolean;\n resourceBinding?: boolean;\n revocation?: boolean;\n scopes?: boolean;\n}\n\n/**\n * The application-owned seam. Skillplane only needs to map this interface to\n * its existing API-key or OAuth issuance and revocation helpers.\n */\nexport interface McpFnAuthProviderAdapter {\n capabilities?: McpFnAuthProviderCapabilities;\n issue(input: McpFnAuthCredentialRequest): Promise<McpFnAuthCredential>;\n revoke?(credential: McpFnAuthCredential): void | Promise<void>;\n}\n\nexport interface McpFnAuthProbeScenario {\n name:\n | \"missing-credential\"\n | \"invalid-credential\"\n | \"valid-credential\"\n | \"insufficient-scope\"\n | \"expired-credential\"\n | \"missing-resource\"\n | \"wrong-resource\"\n | \"revoked-credential\";\n kind: McpFnAuthCredentialKind;\n}\n\nexport interface McpFnAuthTarget {\n request(\n headers: Headers,\n scenario: McpFnAuthProbeScenario,\n ): Promise<Response>;\n}\n\nexport interface McpFnAuthRegressionOptions {\n kind: McpFnAuthCredentialKind;\n provider: McpFnAuthProviderAdapter;\n target: McpFnAuthTarget;\n requiredScopes?: string[];\n resource?: string;\n wrongResource?: string;\n invalidCredentialHeaders?: HeadersInit;\n /** OAuth failures are required to advertise protected-resource metadata. */\n protectedResourceMetadataUrl?: string;\n expectedAuthenticatedStatuses?: number[];\n verifyAuthenticatedResponse?(\n response: Response,\n credential: McpFnAuthCredential,\n ): void | Promise<void>;\n}\n\nexport interface McpFnAuthScenarioResult {\n name: McpFnAuthProbeScenario[\"name\"];\n status: \"passed\" | \"failed\";\n responseStatus?: number;\n error?: string;\n}\n\nexport interface McpFnBearerChallenge {\n scheme: string;\n parameters: Record<string, string>;\n}\n\nexport class McpFnAuthAssertionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"McpFnAuthAssertionError\";\n }\n}\n\nfunction expectedStatus(\n response: Response,\n expected: number | number[],\n name: string,\n): void {\n const statuses = Array.isArray(expected) ? expected : [expected];\n if (!statuses.includes(response.status)) {\n throw new McpFnAuthAssertionError(\n `${name} expected HTTP ${statuses.join(\" or \")}, received ${response.status}`,\n );\n }\n}\n\nexport function parseBearerChallenge(\n header: string | null,\n): McpFnBearerChallenge | undefined {\n if (!header) return undefined;\n const matches = [...header.matchAll(/(?:^|,)\\s*([A-Za-z][A-Za-z0-9_-]*)\\s+/g)];\n const selectedIndex = matches.findIndex((entry) => entry[1].toLowerCase() === \"bearer\");\n if (selectedIndex < 0) return undefined;\n const match = matches[selectedIndex];\n const start = (match.index ?? 0) + match[0].length;\n const end = matches[selectedIndex + 1]?.index ?? header.length;\n const parameters: Record<string, string> = {};\n const source = header.slice(start, end);\n const pattern = /([A-Za-z][A-Za-z0-9_-]*)\\s*=\\s*(?:\"((?:[^\"\\\\]|\\\\.)*)\"|([^,\\s]+))/g;\n for (const entry of source.matchAll(pattern)) {\n const quoted = entry[2]?.replace(/\\\\([\"\\\\])/g, \"$1\");\n parameters[entry[1]] = quoted ?? entry[3] ?? \"\";\n }\n return { scheme: match[1], parameters };\n}\n\nexport function assertBearerResourceChallenge(\n response: Response,\n expectedMetadataUrl?: string,\n): McpFnBearerChallenge {\n const challenge = parseBearerChallenge(response.headers.get(\"www-authenticate\"));\n if (!challenge || challenge.scheme.toLowerCase() !== \"bearer\") {\n throw new McpFnAuthAssertionError(\"Expected a Bearer WWW-Authenticate challenge\");\n }\n const metadataUrl = challenge.parameters.resource_metadata;\n if (!metadataUrl) {\n throw new McpFnAuthAssertionError(\n \"Bearer challenge is missing the resource_metadata parameter\",\n );\n }\n try {\n const parsed = new URL(metadataUrl);\n if (!parsed.protocol || !parsed.host) throw new Error(\"not absolute\");\n } catch {\n throw new McpFnAuthAssertionError(\n `Bearer challenge has an invalid resource_metadata URL: ${metadataUrl}`,\n );\n }\n if (expectedMetadataUrl && metadataUrl !== expectedMetadataUrl) {\n throw new McpFnAuthAssertionError(\n `Expected resource_metadata=${expectedMetadataUrl}, received ${metadataUrl}`,\n );\n }\n return challenge;\n}\n\nexport function bearerCredential(\n token: string,\n kind: McpFnAuthCredentialKind = \"oauth\",\n): McpFnAuthCredential {\n return {\n kind,\n headers: { authorization: `Bearer ${token}` },\n };\n}\n\nexport function apiKeyCredential(\n apiKey: string,\n options: { headerName?: string; scheme?: string } = {},\n): McpFnAuthCredential {\n const headerName = options.headerName ?? \"authorization\";\n const value = options.scheme === \"\"\n ? apiKey\n : `${options.scheme ?? \"Bearer\"} ${apiKey}`;\n return { kind: \"api-key\", headers: { [headerName]: value } };\n}\n\nfunction invalidHeaders(options: McpFnAuthRegressionOptions): Headers {\n return new Headers(options.invalidCredentialHeaders ?? {\n authorization: `Bearer mcpfn-invalid-${options.kind}`,\n });\n}\n\nasync function runOne(\n options: McpFnAuthRegressionOptions,\n scenario: McpFnAuthProbeScenario,\n prepare: () => Promise<McpFnAuthCredential | undefined>,\n expected: number | number[],\n): Promise<McpFnAuthScenarioResult> {\n let credential: McpFnAuthCredential | undefined;\n try {\n credential = await prepare();\n const headers = credential\n ? new Headers(credential.headers)\n : scenario.name === \"invalid-credential\"\n ? invalidHeaders(options)\n : new Headers();\n const response = await options.target.request(headers, scenario);\n expectedStatus(response, expected, scenario.name);\n if (\n options.kind === \"oauth\" &&\n scenario.name !== \"valid-credential\"\n ) {\n assertBearerResourceChallenge(\n response,\n options.protectedResourceMetadataUrl,\n );\n }\n if (scenario.name === \"valid-credential\" && credential) {\n await options.verifyAuthenticatedResponse?.(response.clone(), credential);\n }\n return {\n name: scenario.name,\n status: \"passed\",\n responseStatus: response.status,\n };\n } catch (error) {\n return {\n name: scenario.name,\n status: \"failed\",\n error: error instanceof Error ? error.message : String(error),\n };\n } finally {\n await credential?.dispose?.();\n }\n}\n\n/** Runs the common API-key or OAuth resource-server regression matrix. */\nexport async function runAuthRegressionSuite(\n options: McpFnAuthRegressionOptions,\n): Promise<McpFnAuthScenarioResult[]> {\n const issue = (overrides: Partial<McpFnAuthCredentialRequest> = {}) =>\n options.provider.issue({\n kind: options.kind,\n scopes: options.requiredScopes,\n resource: options.resource,\n ...overrides,\n });\n const results: McpFnAuthScenarioResult[] = [];\n results.push(await runOne(\n options,\n { name: \"missing-credential\", kind: options.kind },\n async () => undefined,\n 401,\n ));\n results.push(await runOne(\n options,\n { name: \"invalid-credential\", kind: options.kind },\n async () => undefined,\n 401,\n ));\n results.push(await runOne(\n options,\n { name: \"valid-credential\", kind: options.kind },\n () => issue(),\n options.expectedAuthenticatedStatuses ?? [200, 201, 202, 204],\n ));\n\n const capabilities = options.provider.capabilities ?? {};\n if (capabilities.scopes && options.requiredScopes?.length) {\n results.push(await runOne(\n options,\n { name: \"insufficient-scope\", kind: options.kind },\n () => issue({ scopes: [] }),\n 403,\n ));\n }\n if (capabilities.expiration) {\n results.push(await runOne(\n options,\n { name: \"expired-credential\", kind: options.kind },\n () => issue({ expiresInSeconds: -60 }),\n 401,\n ));\n }\n if (capabilities.resourceBinding && options.resource) {\n results.push(await runOne(\n options,\n { name: \"missing-resource\", kind: options.kind },\n () => issue({ resource: undefined }),\n 401,\n ));\n }\n if (capabilities.resourceBinding && options.wrongResource) {\n results.push(await runOne(\n options,\n { name: \"wrong-resource\", kind: options.kind },\n () => issue({ resource: options.wrongResource }),\n 401,\n ));\n }\n if (capabilities.revocation && options.provider.revoke) {\n results.push(await runOne(\n options,\n { name: \"revoked-credential\", kind: options.kind },\n async () => {\n const credential = await issue();\n await options.provider.revoke?.(credential);\n return credential;\n },\n 401,\n ));\n }\n return results;\n}\n\nexport async function assertAuthRegressionSuite(\n options: McpFnAuthRegressionOptions,\n): Promise<McpFnAuthScenarioResult[]> {\n const results = await runAuthRegressionSuite(options);\n const failures = results.filter((result) => result.status === \"failed\");\n if (failures.length) {\n throw new McpFnAuthAssertionError(\n failures.map((failure) => `${failure.name}: ${failure.error}`).join(\"\\n\"),\n );\n }\n return results;\n}\n\nexport interface McpFnFetchAuthTargetOptions {\n url: string | URL;\n fetch?: typeof globalThis.fetch;\n requestInit?: RequestInit | ((scenario: McpFnAuthProbeScenario) => RequestInit);\n}\n\n/** Creates a protected MCP initialize probe suitable for local or deployed endpoints. */\nexport function createFetchAuthTarget(\n options: McpFnFetchAuthTargetOptions,\n): McpFnAuthTarget {\n const fetchImplementation = options.fetch ?? globalThis.fetch;\n if (!fetchImplementation) {\n throw new Error(\"A fetch implementation is required\");\n }\n return {\n async request(authHeaders, scenario) {\n const configured = typeof options.requestInit === \"function\"\n ? options.requestInit(scenario)\n : options.requestInit ?? {};\n const headers = new Headers(configured.headers);\n headers.set(\"accept\", \"application/json, text/event-stream\");\n headers.set(\"content-type\", \"application/json\");\n authHeaders.forEach((value, name) => headers.set(name, value));\n return fetchImplementation(options.url, {\n method: \"POST\",\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: `mcpfn-auth-${scenario.name}`,\n method: \"initialize\",\n params: {\n protocolVersion: \"2025-11-25\",\n capabilities: {},\n clientInfo: { name: \"mcpfn-auth-test\", version: \"1.0.0\" },\n },\n }),\n ...configured,\n headers,\n });\n },\n };\n}\n\nexport const MCPFN_OAUTH_EXTENSION_GRANTS = {\n jwtBearer: \"urn:ietf:params:oauth:grant-type:jwt-bearer\",\n deviceCode: \"urn:ietf:params:oauth:grant-type:device_code\",\n generic: \"urn:example:params:oauth:grant-type:extension\",\n} as const;\n\nexport interface McpFnOAuthClientMetadata extends Record<string, unknown> {\n client_id: string;\n client_name?: string;\n redirect_uris: string[];\n response_types: string[];\n grant_types: string[];\n token_endpoint_auth_method: string;\n}\n\nexport interface McpFnOAuthClientMetadataFixtureOptions {\n clientId: string;\n redirectUris: string[];\n clientName?: string;\n extraGrantTypes?: string[];\n extraMetadata?: Record<string, unknown>;\n}\n\nexport interface McpFnOAuthClientMetadataVariants {\n basic: McpFnOAuthClientMetadata;\n jwtBearerExtension: McpFnOAuthClientMetadata;\n deviceCodeExtension: McpFnOAuthClientMetadata;\n genericExtension: McpFnOAuthClientMetadata;\n}\n\nexport interface McpFnNamedOAuthHostFixture {\n id: \"chatgpt\" | \"claude\";\n name: string;\n redirectUris: string[];\n responseTypes: [\"code\"];\n grantTypes: string[];\n tokenEndpointAuthMethod: \"none\";\n}\n\n/** Host-shaped fixtures; applications still configure their registered production URLs. */\nexport const MCPFN_NAMED_OAUTH_HOST_FIXTURES = {\n chatgpt: {\n id: \"chatgpt\",\n name: \"ChatGPT connector\",\n redirectUris: [\"https://chatgpt.com/connector_platform_oauth_redirect\"],\n responseTypes: [\"code\"],\n grantTypes: [\"authorization_code\", \"refresh_token\"],\n tokenEndpointAuthMethod: \"none\",\n },\n claude: {\n id: \"claude\",\n name: \"Claude connector\",\n redirectUris: [\"https://claude.example.com/oauth/callback\"],\n responseTypes: [\"code\"],\n grantTypes: [\n \"authorization_code\",\n \"refresh_token\",\n MCPFN_OAUTH_EXTENSION_GRANTS.jwtBearer,\n ],\n tokenEndpointAuthMethod: \"none\",\n },\n} as const satisfies Record<string, McpFnNamedOAuthHostFixture>;\n\nexport function createOAuthClientMetadataFixture(\n options: McpFnOAuthClientMetadataFixtureOptions,\n): McpFnOAuthClientMetadata {\n return {\n ...options.extraMetadata,\n client_id: new URL(options.clientId).toString(),\n client_name: options.clientName ?? \"McpFn OAuth test client\",\n redirect_uris: [...new Set(options.redirectUris.map((uri) => new URL(uri).toString()))],\n response_types: [\"code\"],\n grant_types: [\n \"authorization_code\",\n \"refresh_token\",\n ...new Set(options.extraGrantTypes ?? []),\n ],\n token_endpoint_auth_method: \"none\",\n };\n}\n\nexport function createOAuthClientMetadataVariants(\n baseUrl: string | URL,\n redirectUri = new URL(\"/callback\", baseUrl).toString(),\n): McpFnOAuthClientMetadataVariants {\n const base = new URL(baseUrl);\n const fixture = (name: string, extraGrantTypes: string[] = []) =>\n createOAuthClientMetadataFixture({\n clientId: new URL(`/client-metadata/${name}`, base).toString(),\n redirectUris: [redirectUri],\n clientName: `McpFn ${name} client`,\n extraGrantTypes,\n });\n return {\n basic: fixture(\"basic\"),\n jwtBearerExtension: fixture(\"jwt-bearer-extension\", [MCPFN_OAUTH_EXTENSION_GRANTS.jwtBearer]),\n deviceCodeExtension: fixture(\"device-code-extension\", [MCPFN_OAUTH_EXTENSION_GRANTS.deviceCode]),\n genericExtension: fixture(\"generic-extension\", [MCPFN_OAUTH_EXTENSION_GRANTS.generic]),\n };\n}\n\n/**\n * Validates compatibility with authorization-code + PKCE without applying a\n * closed-world allowlist to unrelated grant types advertised by the client.\n */\nexport function assertAuthorizationCodeClientMetadata(\n metadata: McpFnOAuthClientMetadata,\n expectedClientId?: string,\n): McpFnOAuthClientMetadata {\n if (expectedClientId && metadata.client_id !== new URL(expectedClientId).toString()) {\n throw new McpFnAuthAssertionError(\"OAuth client metadata client_id does not match its document URL\");\n }\n if (!metadata.response_types.includes(\"code\")) {\n throw new McpFnAuthAssertionError(\"OAuth client metadata does not support response_type=code\");\n }\n if (!metadata.grant_types.includes(\"authorization_code\")) {\n throw new McpFnAuthAssertionError(\"OAuth client metadata does not support authorization_code\");\n }\n if (!metadata.redirect_uris.length) {\n throw new McpFnAuthAssertionError(\"OAuth client metadata must declare at least one redirect URI\");\n }\n return metadata;\n}\n","import { randomUUID } from \"node:crypto\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\n\nimport type { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport { derivePkceS256Challenge, generatePkcePair } from \"@superfunctions/oauth-core\";\n\nimport {\n assertAuthorizationCodeClientMetadata,\n createOAuthClientMetadataVariants,\n type McpFnOAuthClientMetadataVariants,\n} from \"./auth-core.js\";\n\ninterface AuthorizationCodeRecord {\n clientId: string;\n redirectUri: string;\n codeChallenge: string;\n scopes: string[];\n resource?: string;\n expiresAt: number;\n used: boolean;\n}\n\ninterface AccessTokenRecord {\n clientId: string;\n scopes: string[];\n resource?: string;\n expiresAt: number;\n revoked: boolean;\n}\n\ninterface RefreshTokenRecord {\n clientId: string;\n scopes: string[];\n resource?: string;\n expiresAt: number;\n revoked: boolean;\n}\n\nexport interface McpFnMockOAuthServerOptions {\n issuer: string | URL;\n clientId?: string;\n redirectUris?: string[];\n scopesSupported?: string[];\n accessTokenLifetimeSeconds?: number;\n authorizationCodeLifetimeSeconds?: number;\n refreshTokenLifetimeSeconds?: number;\n clock?: () => number;\n}\n\nexport interface McpFnMockOAuthTokenSet {\n access_token: string;\n token_type: \"Bearer\";\n expires_in: number;\n refresh_token: string;\n scope: string;\n resource?: string;\n}\n\nexport interface McpFnPkcePair {\n verifier: string;\n challenge: string;\n method: \"S256\";\n}\n\nexport interface McpFnOAuthCallback {\n url: string;\n parameters: Record<string, string>;\n}\n\nexport function createPkcePair(): McpFnPkcePair {\n const pair = generatePkcePair(48);\n return {\n verifier: pair.codeVerifier,\n challenge: pair.codeChallenge,\n method: pair.codeChallengeMethod,\n };\n}\n\nfunction uniqueScopes(value: string | null | undefined): string[] {\n return [...new Set((value ?? \"\").split(/\\s+/).filter(Boolean))].sort();\n}\n\nfunction json(status: number, body: unknown): Response {\n return Response.json(body, {\n status,\n headers: { \"cache-control\": \"no-store\" },\n });\n}\n\nfunction oauthError(status: number, error: string, description: string): Response {\n return json(status, { error, error_description: description });\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replaceAll(\"&\", \"&\")\n .replaceAll('\"', \""\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\");\n}\n\nfunction formValue(form: URLSearchParams, name: string): string | undefined {\n const value = form.get(name);\n return value === null || value === \"\" ? undefined : value;\n}\n\nexport class McpFnMockOAuthAuthorizationServer {\n readonly issuer: URL;\n readonly clientId: string;\n readonly redirectUris: string[];\n readonly scopesSupported: string[];\n readonly clientMetadata: McpFnOAuthClientMetadataVariants;\n\n private readonly codes = new Map<string, AuthorizationCodeRecord>();\n private readonly accessTokens = new Map<string, AccessTokenRecord>();\n private readonly refreshTokens = new Map<string, RefreshTokenRecord>();\n private readonly callbacks: McpFnOAuthCallback[] = [];\n private readonly clock: () => number;\n private readonly accessTokenLifetimeSeconds: number;\n private readonly authorizationCodeLifetimeSeconds: number;\n private readonly refreshTokenLifetimeSeconds: number;\n\n constructor(options: McpFnMockOAuthServerOptions) {\n this.issuer = new URL(options.issuer);\n this.issuer.pathname = this.issuer.pathname.replace(/\\/?$/, \"/\");\n this.clientId = options.clientId ?? \"mcpfn-playwright\";\n this.redirectUris = options.redirectUris?.map((uri) => new URL(uri).toString()) ?? [\n new URL(\"callback\", this.issuer).toString(),\n ];\n this.scopesSupported = [...new Set(options.scopesSupported ?? [\"mcp:read\", \"mcp:write\"])].sort();\n this.clock = options.clock ?? Date.now;\n this.accessTokenLifetimeSeconds = options.accessTokenLifetimeSeconds ?? 300;\n this.authorizationCodeLifetimeSeconds = options.authorizationCodeLifetimeSeconds ?? 120;\n this.refreshTokenLifetimeSeconds = options.refreshTokenLifetimeSeconds ?? 3_600;\n this.clientMetadata = createOAuthClientMetadataVariants(\n this.issuer,\n this.redirectUris[0],\n );\n }\n\n get metadataUrl(): string {\n return new URL(\".well-known/oauth-authorization-server\", this.issuer).toString();\n }\n\n get authorizationEndpoint(): string {\n return new URL(\"authorize\", this.issuer).toString();\n }\n\n get tokenEndpoint(): string {\n return new URL(\"token\", this.issuer).toString();\n }\n\n get revocationEndpoint(): string {\n return new URL(\"revoke\", this.issuer).toString();\n }\n\n get callbackUrl(): string {\n return this.redirectUris[0];\n }\n\n clientMetadataUrl(\n variant: keyof McpFnOAuthClientMetadataVariants,\n ): string {\n return this.clientMetadata[variant].client_id;\n }\n\n authorizationUrl(input: {\n clientId?: string;\n redirectUri?: string;\n codeChallenge: string;\n state?: string;\n scopes?: string[];\n resource?: string;\n extraParameters?: Record<string, string>;\n }): string {\n const url = new URL(this.authorizationEndpoint);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"client_id\", input.clientId ?? this.clientId);\n url.searchParams.set(\"redirect_uri\", input.redirectUri ?? this.callbackUrl);\n url.searchParams.set(\"code_challenge\", input.codeChallenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n url.searchParams.set(\"scope\", (input.scopes ?? [\"mcp:read\"]).join(\" \"));\n if (input.state) url.searchParams.set(\"state\", input.state);\n if (input.resource) url.searchParams.set(\"resource\", input.resource);\n for (const [name, value] of Object.entries(input.extraParameters ?? {})) {\n url.searchParams.set(name, value);\n }\n return url.toString();\n }\n\n latestCallback(): McpFnOAuthCallback | undefined {\n return this.callbacks.at(-1);\n }\n\n expireAccessToken(token: string): void {\n const record = this.accessTokens.get(token);\n if (record) record.expiresAt = this.nowSeconds() - 1;\n }\n\n revokeToken(token: string): void {\n const access = this.accessTokens.get(token);\n if (access) access.revoked = true;\n const refresh = this.refreshTokens.get(token);\n if (refresh) refresh.revoked = true;\n }\n\n async verifyAccessToken(token: string): Promise<AuthInfo> {\n const record = this.accessTokens.get(token);\n if (!record || record.revoked || record.expiresAt <= this.nowSeconds()) {\n throw new Error(\"Invalid access token\");\n }\n return {\n token,\n clientId: record.clientId,\n scopes: record.scopes,\n expiresAt: record.expiresAt,\n ...(record.resource ? { resource: new URL(record.resource) } : {}),\n };\n }\n\n async handle(request: Request): Promise<Response> {\n const url = new URL(request.url);\n const path = url.pathname.replace(this.issuer.pathname.replace(/\\/$/, \"\"), \"\") || \"/\";\n if (request.method === \"GET\" && path === \"/.well-known/oauth-authorization-server\") {\n return json(200, {\n issuer: this.issuer.toString(),\n authorization_endpoint: this.authorizationEndpoint,\n token_endpoint: this.tokenEndpoint,\n revocation_endpoint: this.revocationEndpoint,\n response_types_supported: [\"code\"],\n grant_types_supported: [\"authorization_code\", \"refresh_token\"],\n code_challenge_methods_supported: [\"S256\"],\n token_endpoint_auth_methods_supported: [\"none\"],\n scopes_supported: this.scopesSupported,\n client_id_metadata_document_supported: true,\n });\n }\n\n if (request.method === \"GET\" && path.startsWith(\"/client-metadata/\")) {\n const metadata = Object.values(this.clientMetadata)\n .find((candidate) => new URL(candidate.client_id).pathname === url.pathname);\n return metadata ? json(200, metadata) : json(404, { error: \"not_found\" });\n }\n\n if (request.method === \"GET\" && path === \"/authorize\") {\n return this.authorize(url);\n }\n if (request.method === \"POST\" && path === \"/token\") {\n return this.token(await request.text());\n }\n if (request.method === \"POST\" && path === \"/revoke\") {\n return this.revoke(await request.text());\n }\n if (request.method === \"GET\" && path === \"/callback\") {\n const parameters = Object.fromEntries(url.searchParams);\n this.callbacks.push({ url: url.toString(), parameters });\n return new Response(\n `<!doctype html><html><body><main><h1>OAuth callback received</h1><pre>${escapeHtml(JSON.stringify(parameters, null, 2))}</pre></main></body></html>`,\n { headers: { \"content-type\": \"text/html; charset=utf-8\" } },\n );\n }\n return json(404, { error: \"not_found\" });\n }\n\n private nowSeconds(): number {\n return Math.floor(this.clock() / 1_000);\n }\n\n private resolveClient(clientId: string): { clientId: string; redirectUris: string[] } | undefined {\n if (clientId === this.clientId) {\n return { clientId, redirectUris: this.redirectUris };\n }\n const metadata = Object.values(this.clientMetadata)\n .find((candidate) => candidate.client_id === clientId);\n if (!metadata) return undefined;\n assertAuthorizationCodeClientMetadata(metadata, clientId);\n return { clientId, redirectUris: metadata.redirect_uris };\n }\n\n private authorize(url: URL): Response {\n const clientId = url.searchParams.get(\"client_id\") ?? \"\";\n const redirectUri = url.searchParams.get(\"redirect_uri\") ?? \"\";\n const client = this.resolveClient(clientId);\n if (!client) return oauthError(400, \"invalid_client\", \"Unknown OAuth client\");\n if (!client.redirectUris.includes(redirectUri)) {\n return oauthError(400, \"invalid_request\", \"redirect_uri is not registered\");\n }\n if (url.searchParams.get(\"response_type\") !== \"code\") {\n return this.authorizationRedirect(url, redirectUri, \"unsupported_response_type\");\n }\n const codeChallenge = url.searchParams.get(\"code_challenge\");\n if (!codeChallenge || url.searchParams.get(\"code_challenge_method\") !== \"S256\") {\n return this.authorizationRedirect(url, redirectUri, \"invalid_request\", \"PKCE S256 is required\");\n }\n const requestedScopes = uniqueScopes(url.searchParams.get(\"scope\"));\n if (requestedScopes.some((scope) => !this.scopesSupported.includes(scope))) {\n return this.authorizationRedirect(url, redirectUri, \"invalid_scope\");\n }\n const decision = url.searchParams.get(\"decision\");\n if (!decision) {\n const hidden = [...url.searchParams]\n .filter(([name]) => name !== \"decision\")\n .map(([name, value]) => `<input type=\"hidden\" name=\"${escapeHtml(name)}\" value=\"${escapeHtml(value)}\">`)\n .join(\"\");\n return new Response(\n `<!doctype html><html><body><main><h1>Authorize MCP client</h1><p>${escapeHtml(clientId)}</p><form method=\"get\" action=\"${escapeHtml(this.authorizationEndpoint)}\">${hidden}<button name=\"decision\" value=\"approve\">Approve</button><button name=\"decision\" value=\"deny\">Deny</button></form></main></body></html>`,\n { headers: { \"content-type\": \"text/html; charset=utf-8\", \"cache-control\": \"no-store\" } },\n );\n }\n if (decision === \"deny\") {\n return this.authorizationRedirect(url, redirectUri, \"access_denied\");\n }\n if (decision !== \"approve\") {\n return oauthError(400, \"invalid_request\", \"Unknown authorization decision\");\n }\n const code = `mcpfn_code_${randomUUID()}`;\n this.codes.set(code, {\n clientId,\n redirectUri,\n codeChallenge,\n scopes: requestedScopes,\n resource: url.searchParams.get(\"resource\") ?? undefined,\n expiresAt: this.nowSeconds() + this.authorizationCodeLifetimeSeconds,\n used: false,\n });\n const callback = new URL(redirectUri);\n callback.searchParams.set(\"code\", code);\n const state = url.searchParams.get(\"state\");\n if (state) callback.searchParams.set(\"state\", state);\n return Response.redirect(callback, 302);\n }\n\n private authorizationRedirect(\n requestUrl: URL,\n redirectUri: string,\n error: string,\n description?: string,\n ): Response {\n const callback = new URL(redirectUri);\n callback.searchParams.set(\"error\", error);\n if (description) callback.searchParams.set(\"error_description\", description);\n const state = requestUrl.searchParams.get(\"state\");\n if (state) callback.searchParams.set(\"state\", state);\n return Response.redirect(callback, 302);\n }\n\n private token(source: string): Response {\n const form = new URLSearchParams(source);\n const grantType = formValue(form, \"grant_type\");\n if (grantType === \"authorization_code\") return this.exchangeAuthorizationCode(form);\n if (grantType === \"refresh_token\") return this.exchangeRefreshToken(form);\n return oauthError(400, \"unsupported_grant_type\", \"The grant type is not supported\");\n }\n\n private exchangeAuthorizationCode(form: URLSearchParams): Response {\n const code = formValue(form, \"code\");\n const record = code ? this.codes.get(code) : undefined;\n if (!record || record.used || record.expiresAt <= this.nowSeconds()) {\n return oauthError(400, \"invalid_grant\", \"Authorization code is invalid or expired\");\n }\n if (\n formValue(form, \"client_id\") !== record.clientId ||\n formValue(form, \"redirect_uri\") !== record.redirectUri\n ) {\n return oauthError(400, \"invalid_grant\", \"Authorization code binding does not match\");\n }\n const verifier = formValue(form, \"code_verifier\");\n const challenge = verifier ? derivePkceS256Challenge(verifier) : undefined;\n if (challenge !== record.codeChallenge) {\n return oauthError(400, \"invalid_grant\", \"PKCE verification failed\");\n }\n record.used = true;\n return json(200, this.issueTokenSet(record));\n }\n\n private exchangeRefreshToken(form: URLSearchParams): Response {\n const refreshToken = formValue(form, \"refresh_token\");\n const record = refreshToken ? this.refreshTokens.get(refreshToken) : undefined;\n if (!record || record.revoked || record.expiresAt <= this.nowSeconds()) {\n return oauthError(400, \"invalid_grant\", \"Refresh token is invalid or expired\");\n }\n if (formValue(form, \"client_id\") !== record.clientId) {\n return oauthError(400, \"invalid_grant\", \"Refresh token client binding does not match\");\n }\n const requestedScopes = form.has(\"scope\")\n ? uniqueScopes(form.get(\"scope\"))\n : record.scopes;\n if (requestedScopes.some((scope) => !record.scopes.includes(scope))) {\n return oauthError(400, \"invalid_scope\", \"Refresh cannot increase granted scopes\");\n }\n record.revoked = true;\n return json(200, this.issueTokenSet({ ...record, scopes: requestedScopes }));\n }\n\n private issueTokenSet(\n input: Pick<AccessTokenRecord, \"clientId\" | \"scopes\" | \"resource\">,\n ): McpFnMockOAuthTokenSet {\n const accessToken = `mcpfn_access_${randomUUID()}`;\n const refreshToken = `mcpfn_refresh_${randomUUID()}`;\n this.accessTokens.set(accessToken, {\n ...input,\n expiresAt: this.nowSeconds() + this.accessTokenLifetimeSeconds,\n revoked: false,\n });\n this.refreshTokens.set(refreshToken, {\n ...input,\n expiresAt: this.nowSeconds() + this.refreshTokenLifetimeSeconds,\n revoked: false,\n });\n return {\n access_token: accessToken,\n token_type: \"Bearer\",\n expires_in: this.accessTokenLifetimeSeconds,\n refresh_token: refreshToken,\n scope: input.scopes.join(\" \"),\n ...(input.resource ? { resource: input.resource } : {}),\n };\n }\n\n private revoke(source: string): Response {\n const token = new URLSearchParams(source).get(\"token\");\n if (token) this.revokeToken(token);\n return new Response(null, { status: 200 });\n }\n}\n\nexport interface McpFnStartedMockOAuthServer {\n origin: string;\n oauth: McpFnMockOAuthAuthorizationServer;\n close(): Promise<void>;\n}\n\nexport interface McpFnStartMockOAuthServerOptions\n extends Omit<McpFnMockOAuthServerOptions, \"issuer\"> {\n hostname?: string;\n port?: number;\n /** Optional same-origin route used to compose a protected MCP fixture. */\n handle?(\n request: Request,\n oauth: McpFnMockOAuthAuthorizationServer,\n ): Promise<Response | undefined> | Response | undefined;\n}\n\nasync function toRequest(req: IncomingMessage, origin: string): Promise<Request> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) chunks.push(Buffer.from(chunk));\n const headers = new Headers();\n for (const [name, value] of Object.entries(req.headers)) {\n if (Array.isArray(value)) {\n for (const entry of value) headers.append(name, entry);\n } else if (value !== undefined) {\n headers.set(name, value);\n }\n }\n const body = chunks.length ? Buffer.concat(chunks) : undefined;\n const init: RequestInit & { duplex?: \"half\" } = {\n method: req.method,\n headers,\n ...(body ? { body, duplex: \"half\" } : {}),\n };\n return new Request(new URL(req.url ?? \"/\", origin), init);\n}\n\nasync function writeResponse(res: ServerResponse, response: Response): Promise<void> {\n res.statusCode = response.status;\n response.headers.forEach((value, name) => res.setHeader(name, value));\n res.end(Buffer.from(await response.arrayBuffer()));\n}\n\nexport async function startMockOAuthAuthorizationServer(\n options: McpFnStartMockOAuthServerOptions = {},\n): Promise<McpFnStartedMockOAuthServer> {\n let oauth: McpFnMockOAuthAuthorizationServer | undefined;\n let origin = \"\";\n const server = createServer(async (req, res) => {\n try {\n if (!oauth) throw new Error(\"Mock OAuth server is not initialized\");\n const request = await toRequest(req, origin);\n const custom = await options.handle?.(request.clone(), oauth);\n await writeResponse(res, custom ?? await oauth.handle(request));\n } catch {\n res.statusCode = 500;\n res.setHeader(\"content-type\", \"application/json\");\n res.end(JSON.stringify({\n error: \"server_error\",\n error_description: \"Internal Server Error\",\n }));\n }\n });\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(options.port ?? 0, options.hostname ?? \"127.0.0.1\", () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n const address = server.address() as AddressInfo;\n origin = `http://${address.address.includes(\":\") ? `[${address.address}]` : address.address}:${address.port}`;\n oauth = new McpFnMockOAuthAuthorizationServer({ ...options, issuer: origin });\n return {\n origin,\n oauth,\n close: () => new Promise<void>((resolve, reject) => {\n server.close((error) => error ? reject(error) : resolve());\n }),\n };\n}\n","import {\n createMcpFnClient,\n customTarget,\n type McpFnClient,\n type McpFnClientEventSink,\n type McpFnClientMediatedHandlers,\n type McpFnDiagnosticSink,\n type McpFnTarget,\n} from \"@mcpfn/client\";\nimport { InMemoryTransport } from \"@modelcontextprotocol/sdk/inMemory.js\";\nimport type { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type { RequestOptions } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n CallToolResult,\n ClientCapabilities,\n CompleteRequest,\n CompleteResult,\n CreateTaskResult,\n GetPromptResult,\n Implementation,\n ListTasksResult,\n Prompt,\n ReadResourceResult,\n Resource,\n ResourceTemplate,\n Task,\n Tool,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { McpFnServer } from \"@mcpfn/core\";\n\nexport interface McpFnTestClientOptions {\n capabilities?: ClientCapabilities;\n handlers?: McpFnClientMediatedHandlers;\n events?: McpFnClientEventSink;\n /** Install roots, sampling, elicitation, or notification handlers before initialize. */\n configure?(client: Client): void | Promise<void>;\n diagnostics?: McpFnDiagnosticSink;\n}\n\nexport class McpFnTestClient<TContext = undefined> {\n readonly session: McpFnClient;\n\n private constructor(session: McpFnClient) {\n this.session = session;\n }\n\n get client(): Client {\n return this.session.protocol;\n }\n\n static async connect<TContext>(\n server: McpFnServer<TContext>,\n info = { name: \"mcpfn-test-client\", version: \"1.0.0\" },\n options: McpFnTestClientOptions = {},\n ): Promise<McpFnTestClient<TContext>> {\n const serverName = (server as McpFnServer<TContext> & { info?: { name?: string } })\n .info?.name ?? \"mcpfn-server\";\n return this.connectTarget<TContext>(customTarget({\n kind: \"in-memory\",\n descriptor: { server: serverName },\n open: async () => {\n const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();\n await server.connect(serverTransport);\n return { transport: clientTransport, close: () => server.close() };\n },\n }), info, options);\n }\n\n static async connectTarget<TContext = undefined>(\n target: McpFnTarget,\n info?: Implementation,\n options: McpFnTestClientOptions = {},\n ): Promise<McpFnTestClient<TContext>> {\n const session = createMcpFnClient({\n target,\n info: info ?? { name: \"mcpfn-test-client\", version: \"1.0.0\" },\n capabilities: options.capabilities,\n handlers: options.handlers,\n events: options.events,\n configure: options.configure,\n diagnostics: options.diagnostics,\n });\n try {\n await session.connect();\n return new McpFnTestClient<TContext>(session);\n } catch (error) {\n await session.close(true).catch(() => undefined);\n throw error;\n }\n }\n\n listTools(options?: RequestOptions): Promise<Tool[]> { return this.session.tools.listAll(options); }\n callTool(\n name: string,\n args: Record<string, unknown> = {},\n options?: RequestOptions,\n ): Promise<CallToolResult> {\n return this.session.tools.call(name, args, options);\n }\n createToolTask(\n name: string,\n args: Record<string, unknown> = {},\n task: { ttl?: number } = {},\n options?: RequestOptions,\n ): Promise<CreateTaskResult> {\n return this.session.tools.createTask(name, args, task, options);\n }\n getTask(taskId: string, options?: RequestOptions): Promise<Task> {\n return this.session.tasks.get(taskId, options);\n }\n getTaskResult(taskId: string, options?: RequestOptions): Promise<CallToolResult> {\n return this.session.tasks.result(taskId, options);\n }\n listTasks(cursor?: string, options?: RequestOptions): Promise<ListTasksResult> {\n return this.session.tasks.list(cursor, options);\n }\n cancelTask(taskId: string, options?: RequestOptions): Promise<Task> {\n return this.session.tasks.cancel(taskId, options);\n }\n listResources(options?: RequestOptions): Promise<Resource[]> {\n return this.session.resources.listAll(options);\n }\n listResourceTemplates(options?: RequestOptions): Promise<ResourceTemplate[]> {\n return this.session.resources.listTemplatesAll(options);\n }\n readResource(uri: string, options?: RequestOptions): Promise<ReadResourceResult> {\n return this.session.resources.read(uri, options);\n }\n subscribeResource(uri: string, options?: RequestOptions): Promise<void> {\n return this.session.resources.subscribe(uri, options);\n }\n unsubscribeResource(uri: string, options?: RequestOptions): Promise<void> {\n return this.session.resources.unsubscribe(uri, options);\n }\n listPrompts(options?: RequestOptions): Promise<Prompt[]> {\n return this.session.prompts.listAll(options);\n }\n getPrompt(\n name: string,\n args?: Record<string, string>,\n options?: RequestOptions,\n ): Promise<GetPromptResult> {\n return this.session.prompts.get(name, args, options);\n }\n complete(params: CompleteRequest[\"params\"], options?: RequestOptions): Promise<CompleteResult> {\n return this.session.prompts.complete(params, options);\n }\n close(): Promise<void> { return this.session.close(); }\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport {\n createServer,\n request as httpRequest,\n type IncomingHttpHeaders,\n} from \"node:http\";\nimport { request as httpsRequest } from \"node:https\";\nimport type { Socket } from \"node:net\";\nimport path from \"node:path\";\n\nexport const OFFICIAL_CONFORMANCE_VERSION = \"0.1.16\";\n\nexport interface OfficialConformanceOptions {\n url: string;\n suite?: \"active\" | \"all\" | \"pending\";\n scenario?: string;\n expectedFailures?: string;\n outputDir?: string;\n specVersion?: string;\n verbose?: boolean;\n cwd?: string;\n stdio?: \"inherit\" | \"pipe\";\n}\n\nexport interface OfficialConformanceResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\nexport interface AuthenticatedConformanceProxy {\n /** Loopback URL to pass to the official conformance runner. */\n url: string;\n close(): Promise<void>;\n}\n\nexport interface AuthenticatedConformanceProxyOptions {\n /** Fixed loopback MCP URL. Requests cannot select a different origin or path. */\n url: string;\n /** Headers injected into requests using the proxy's own authority. Values are never logged. */\n headers: HeadersInit;\n}\n\nexport interface AuthenticatedOfficialConformanceOptions extends OfficialConformanceOptions {\n headers: HeadersInit;\n}\n\n/**\n * Start a loopback-only streaming proxy for runners that cannot send auth\n * headers. Authenticated requests use one fixed upstream authority and path.\n * Host-manipulation probes are forwarded without injected credentials.\n */\nexport async function createAuthenticatedConformanceProxy(\n options: AuthenticatedConformanceProxyOptions,\n): Promise<AuthenticatedConformanceProxy> {\n const upstream = new URL(options.url);\n if (![\"http:\", \"https:\"].includes(upstream.protocol)) {\n throw new TypeError(\n \"Authenticated conformance upstream must use HTTP or HTTPS\",\n );\n }\n if (upstream.username || upstream.password || upstream.hash) {\n throw new TypeError(\n \"Authenticated conformance upstream must not contain userinfo or a fragment\",\n );\n }\n const hostname = normalizeLoopbackHostname(upstream.hostname);\n if (!hostname) {\n throw new TypeError(\n \"Authenticated conformance upstream must use a literal loopback address\",\n );\n }\n const protocol = upstream.protocol === \"https:\" ? \"https:\" : \"http:\";\n const port = upstream.port === \"\" ? undefined : Number(upstream.port);\n const requestPath = `${upstream.pathname}${upstream.search}`;\n const injected = new Headers(options.headers);\n const activeRequests = new Set<ReturnType<typeof httpRequest>>();\n const activeSockets = new Set<Socket>();\n let proxyAuthority: string | undefined;\n const server = createServer((incoming, outgoing) => {\n if (!incoming.url?.startsWith(\"/\")) {\n outgoing.writeHead(400).end();\n return;\n }\n const headers: IncomingHttpHeaders = { ...incoming.headers };\n delete headers.connection;\n const usesProxyAuthority = incoming.headers.host === proxyAuthority;\n injected.forEach((value, name) => {\n const normalizedName = name.toLowerCase();\n delete headers[normalizedName];\n if (usesProxyAuthority) headers[normalizedName] = value;\n });\n // Authenticated traffic is pinned to the upstream Host. Host-manipulation\n // probes retain their hostile value, but never receive injected credentials.\n if (usesProxyAuthority) headers.host = upstream.host;\n const transport = protocol === \"https:\" ? httpsRequest : httpRequest;\n const proxied = transport(\n {\n protocol,\n hostname,\n port,\n path: requestPath,\n method: incoming.method,\n headers,\n },\n (response) => {\n outgoing.writeHead(response.statusCode ?? 502, response.headers);\n response.pipe(outgoing);\n },\n );\n activeRequests.add(proxied);\n proxied.once(\"close\", () => activeRequests.delete(proxied));\n proxied.once(\"error\", () => {\n if (!outgoing.headersSent) outgoing.writeHead(502);\n outgoing.end();\n });\n incoming.once(\"aborted\", () => proxied.destroy());\n incoming.pipe(proxied);\n });\n server.on(\"connection\", (socket) => {\n activeSockets.add(socket);\n socket.once(\"close\", () => activeSockets.delete(socket));\n });\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n const address = server.address();\n if (!address || typeof address === \"string\") {\n await new Promise<void>((resolve) => server.close(() => resolve()));\n throw new Error(\"Authenticated conformance proxy did not bind a TCP port\");\n }\n const url = new URL(\n upstream.pathname + upstream.search,\n `http://127.0.0.1:${address.port}`,\n );\n proxyAuthority = url.host;\n return {\n url: url.toString(),\n close: async () => {\n for (const request of activeRequests) request.destroy();\n for (const socket of activeSockets) socket.destroy();\n if (!server.listening) return;\n await new Promise<void>((resolve, reject) => {\n server.close((error) => (error ? reject(error) : resolve()));\n });\n },\n };\n}\n\nfunction normalizeLoopbackHostname(\n hostname: string,\n): \"127.0.0.1\" | \"::1\" | undefined {\n if (hostname === \"127.0.0.1\") return \"127.0.0.1\";\n if (hostname === \"[::1]\") return \"::1\";\n return undefined;\n}\n\nfunction npxInvocation(args: string[]): { command: string; args: string[] } {\n if (process.platform !== \"win32\") return { command: \"npx\", args };\n const npmExecPath = process.env.npm_execpath;\n const candidates = [\n npmExecPath ? path.join(path.dirname(npmExecPath), \"npx-cli.js\") : undefined,\n path.resolve(path.dirname(process.execPath), \"node_modules/npm/bin/npx-cli.js\"),\n path.resolve(path.dirname(process.execPath), \"../lib/node_modules/npm/bin/npx-cli.js\"),\n ].filter((candidate): candidate is string => Boolean(candidate));\n const npxCli = candidates.find((candidate) => existsSync(candidate));\n if (!npxCli) {\n throw new Error(\"Unable to locate npm's npx-cli.js for the official MCP conformance runner\");\n }\n return { command: process.execPath, args: [npxCli, ...args] };\n}\n\nexport function buildOfficialConformanceArgs(\n options: OfficialConformanceOptions,\n): string[] {\n const args = [\n \"--yes\",\n `@modelcontextprotocol/conformance@${OFFICIAL_CONFORMANCE_VERSION}`,\n \"server\",\n \"--url\",\n options.url,\n ];\n if (options.suite) args.push(\"--suite\", options.suite);\n if (options.scenario) args.push(\"--scenario\", options.scenario);\n if (options.expectedFailures) {\n args.push(\"--expected-failures\", options.expectedFailures);\n }\n if (options.outputDir) args.push(\"--output-dir\", options.outputDir);\n if (options.specVersion) args.push(\"--spec-version\", options.specVersion);\n if (options.verbose) args.push(\"--verbose\");\n return args;\n}\n\nexport async function runOfficialConformance(\n options: OfficialConformanceOptions,\n): Promise<OfficialConformanceResult> {\n const nodeMajor = Number.parseInt(process.versions.node.split(\".\")[0] ?? \"0\", 10);\n if (nodeMajor < 22) {\n throw new Error(\n `Official MCP conformance ${OFFICIAL_CONFORMANCE_VERSION} requires Node.js 22 or newer; current runtime is ${process.versions.node}`,\n );\n }\n const args = buildOfficialConformanceArgs(options);\n const invocation = npxInvocation(args);\n\n return await new Promise<OfficialConformanceResult>((resolve, reject) => {\n const child = spawn(invocation.command, invocation.args, {\n cwd: options.cwd,\n env: {\n ...process.env,\n PATH: [path.dirname(process.execPath), process.env.PATH]\n .filter(Boolean)\n .join(path.delimiter),\n },\n stdio: options.stdio === \"inherit\" ? \"inherit\" : \"pipe\",\n });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout?.on(\"data\", (chunk) => {\n stdout += chunk.toString();\n });\n child.stderr?.on(\"data\", (chunk) => {\n stderr += chunk.toString();\n });\n child.once(\"error\", reject);\n child.once(\"close\", (code) => {\n resolve({ exitCode: code ?? 1, stdout, stderr });\n });\n });\n}\n\n/** Run the pinned official suite against an authenticated MCP endpoint. */\nexport async function runAuthenticatedOfficialConformance(\n options: AuthenticatedOfficialConformanceOptions,\n): Promise<OfficialConformanceResult> {\n const { headers, ...conformance } = options;\n const proxy = await createAuthenticatedConformanceProxy({\n url: conformance.url,\n headers,\n });\n try {\n return await runOfficialConformance({ ...conformance, url: proxy.url });\n } finally {\n await proxy.close();\n }\n}\n","import {\n MCP_APP_EXTENSION_ID,\n type McpFnManifest,\n} from \"@mcpfn/core\";\n\nexport type McpFnServerFeature =\n | \"tools\"\n | \"resources\"\n | \"prompts\"\n | \"completions\"\n | \"tasks\"\n | \"logging\";\n\nexport interface McpFnHostProfile {\n id: string;\n name: string;\n protocolVersions: string[];\n serverFeatures: McpFnServerFeature[];\n clientFeatures?: {\n sampling?: boolean;\n elicitation?: Array<\"form\" | \"url\">;\n roots?: boolean;\n };\n extensions?: string[];\n}\n\nexport interface McpFnHostCompatibilityIssue {\n severity: \"incompatible\" | \"degraded\";\n code: string;\n path: string;\n message: string;\n}\n\nexport interface McpFnHostCompatibilityResult {\n status: \"compatible\" | \"degraded\" | \"incompatible\";\n compatible: boolean;\n issues: McpFnHostCompatibilityIssue[];\n}\n\nexport const MCPFN_HOST_PROFILES = {\n toolsOnly: {\n id: \"mcpfn/tools-only\",\n name: \"Tools-only MCP host\",\n protocolVersions: [\"2025-03-26\", \"2025-06-18\", \"2025-11-25\"],\n serverFeatures: [\"tools\"],\n },\n fullProtocol: {\n id: \"mcpfn/full-protocol\",\n name: \"Full protocol MCP host\",\n protocolVersions: [\"2025-03-26\", \"2025-06-18\", \"2025-11-25\"],\n serverFeatures: [\"tools\", \"resources\", \"prompts\", \"completions\", \"tasks\", \"logging\"],\n clientFeatures: { sampling: true, elicitation: [\"form\", \"url\"], roots: true },\n },\n mcpApps: {\n id: \"mcpfn/mcp-apps\",\n name: \"Full protocol host with MCP Apps\",\n protocolVersions: [\"2025-11-25\"],\n serverFeatures: [\"tools\", \"resources\", \"prompts\", \"completions\", \"tasks\", \"logging\"],\n clientFeatures: { sampling: true, elicitation: [\"form\", \"url\"], roots: true },\n extensions: [MCP_APP_EXTENSION_ID],\n },\n} as const satisfies Record<string, McpFnHostProfile>;\n\nexport function checkHostCompatibility(\n manifest: McpFnManifest,\n profile: McpFnHostProfile,\n): McpFnHostCompatibilityResult {\n const issues: McpFnHostCompatibilityIssue[] = [];\n if (\n manifest.protocolVersions?.length &&\n !manifest.protocolVersions.some((version) => profile.protocolVersions.includes(version))\n ) {\n issues.push({\n severity: \"incompatible\",\n code: \"protocol-version-mismatch\",\n path: \"protocolVersions\",\n message: `${profile.name} and ${manifest.server.name} have no protocol version in common`,\n });\n }\n\n const supportedServerFeatures = new Set(profile.serverFeatures);\n for (const feature of Object.keys(manifest.capabilities ?? {})) {\n if (\n feature === \"experimental\" ||\n supportedServerFeatures.has(feature as McpFnServerFeature)\n ) continue;\n issues.push({\n severity: \"degraded\",\n code: \"server-feature-unavailable\",\n path: `capabilities.${feature}`,\n message: `${profile.name} will not expose the server's ${feature} feature`,\n });\n }\n\n const required = manifest.clientRequirements;\n if (required?.sampling && !profile.clientFeatures?.sampling) {\n issues.push({\n severity: \"incompatible\",\n code: \"sampling-required\",\n path: \"clientRequirements.sampling\",\n message: `${manifest.server.name} requires client sampling`,\n });\n }\n if (required?.roots && !profile.clientFeatures?.roots) {\n issues.push({\n severity: \"incompatible\",\n code: \"roots-required\",\n path: \"clientRequirements.roots\",\n message: `${manifest.server.name} requires client roots`,\n });\n }\n for (const mode of required?.elicitation ?? []) {\n if (!profile.clientFeatures?.elicitation?.includes(mode)) {\n issues.push({\n severity: \"incompatible\",\n code: \"elicitation-required\",\n path: `clientRequirements.elicitation.${mode}`,\n message: `${manifest.server.name} requires ${mode} elicitation`,\n });\n }\n }\n\n const extensions = new Set(profile.extensions ?? []);\n for (const [extension, configuration] of Object.entries(manifest.extensions ?? {})) {\n if (extensions.has(extension)) continue;\n const requiredExtension =\n configuration && typeof configuration === \"object\" &&\n (configuration as Record<string, unknown>).required === true;\n issues.push({\n severity: requiredExtension ? \"incompatible\" : \"degraded\",\n code: \"extension-unavailable\",\n path: `extensions.${extension}`,\n message: `${profile.name} does not support ${extension}`,\n });\n }\n\n if (!extensions.has(MCP_APP_EXTENSION_ID)) {\n for (const tool of manifest.tools) {\n const ui = tool.metadata?.ui as { visibility?: string[] } | undefined;\n if (ui?.visibility?.length && !ui.visibility.includes(\"model\")) {\n issues.push({\n severity: \"incompatible\",\n code: \"app-only-tool-unavailable\",\n path: `tools.${tool.name}.metadata.ui.visibility`,\n message: `${tool.name} is app-only but ${profile.name} does not support MCP Apps`,\n });\n }\n }\n }\n\n issues.sort((left, right) => {\n if (left.path !== right.path) return left.path < right.path ? -1 : 1;\n if (left.code < right.code) return -1;\n if (left.code > right.code) return 1;\n return 0;\n });\n let status: McpFnHostCompatibilityResult[\"status\"] = \"compatible\";\n if (issues.some((issue) => issue.severity === \"incompatible\")) {\n status = \"incompatible\";\n } else if (issues.length > 0) {\n status = \"degraded\";\n }\n return { status, compatible: status !== \"incompatible\", issues };\n}\n","import type {\n CallToolResult,\n CreateTaskResult,\n GetPromptResult,\n ListTasksResult,\n ReadResourceResult,\n Task,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { McpFnClientEvent, McpFnClientEventKind } from \"@mcpfn/client\";\nimport { redactOAuthValue } from \"@superfunctions/oauth-core\";\n\nimport { McpFnAssertionError, assertStructuredTextParity, stableJson } from \"./assertions.js\";\nimport type { McpFnTestClient } from \"./client.js\";\n\nexport type McpFnScenarioSideEffect = \"none\" | \"idempotent\" | \"non-idempotent\";\n\nexport interface McpFnScenarioBase {\n formatVersion?: 1;\n name: string;\n /** Defaults to the runner timeout. */\n timeoutMs?: number;\n sideEffect?: McpFnScenarioSideEffect;\n status?: \"complete\" | \"incomplete\";\n incompleteReason?: string;\n /** Environment-backed placeholders used by this scenario, never their values. */\n variables?: string[];\n}\n\nexport interface McpFnToolScenario extends McpFnScenarioBase {\n kind?: \"tools.call\";\n tool: string;\n arguments?: Record<string, unknown>;\n expect?: {\n isError?: boolean;\n structuredContent?: unknown;\n structuredTextParity?: boolean;\n };\n verify?(result: CallToolResult): void | Promise<void>;\n}\n\nexport interface McpFnInventoryScenario extends McpFnScenarioBase {\n kind: \"tools.list\" | \"resources.list\" | \"resources.templates.list\" | \"prompts.list\";\n expectNames?: string[];\n}\n\nexport interface McpFnResourceScenario extends McpFnScenarioBase {\n kind: \"resources.read\" | \"resources.subscribe\" | \"resources.unsubscribe\";\n uri: string;\n expect?: unknown;\n}\n\nexport interface McpFnPromptScenario extends McpFnScenarioBase {\n kind: \"prompts.get\";\n prompt: string;\n arguments?: Record<string, string>;\n expect?: unknown;\n}\n\nexport interface McpFnInitializeScenario extends McpFnScenarioBase {\n kind: \"initialize\";\n expectCapabilities?: Record<string, unknown>;\n}\n\nexport interface McpFnCreateTaskScenario extends McpFnScenarioBase {\n kind: \"tools.call:task\";\n tool: string;\n arguments?: Record<string, unknown>;\n task?: { ttl?: number };\n expect?: unknown;\n}\n\nexport interface McpFnTaskScenario extends McpFnScenarioBase {\n kind: \"tasks.get\" | \"tasks.result\" | \"tasks.cancel\" | \"tasks.list\";\n taskId?: string;\n cursor?: string;\n expect?: unknown;\n}\n\nexport interface McpFnEventScenario extends McpFnScenarioBase {\n kind: \"events.expect\";\n event: McpFnClientEventKind;\n minimum?: number;\n expectPayload?: unknown;\n}\n\nexport interface McpFnAuthScenario extends McpFnScenarioBase {\n kind: \"auth.assert\";\n phase: string;\n expect: {\n outcome: \"allowed\" | \"denied\";\n code?: string;\n };\n input?: Record<string, unknown>;\n}\n\nexport type McpFnScenario =\n | McpFnToolScenario\n | McpFnInventoryScenario\n | McpFnResourceScenario\n | McpFnPromptScenario\n | McpFnInitializeScenario\n | McpFnCreateTaskScenario\n | McpFnTaskScenario\n | McpFnEventScenario\n | McpFnAuthScenario;\n\nexport interface McpFnScenarioArtifact {\n formatVersion: 1;\n kind: \"mcpfn.scenarios\";\n status: \"complete\" | \"incomplete\";\n scenarios: McpFnScenario[];\n variables?: string[];\n incompleteReason?: string;\n}\n\nexport type McpFnRecordedOperation =\n | { kind: \"tools.call\"; name: string; arguments?: Record<string, unknown> }\n | { kind: \"tools.call:task\"; name: string; arguments?: Record<string, unknown>; task?: { ttl?: number } }\n | { kind: \"resources.read\"; uri: string }\n | { kind: \"resources.subscribe\"; uri: string }\n | { kind: \"resources.unsubscribe\"; uri: string }\n | { kind: \"prompts.get\"; name: string; arguments?: Record<string, string> }\n | { kind: \"tasks.get\"; taskId: string }\n | { kind: \"tasks.result\"; taskId: string }\n | { kind: \"tasks.cancel\"; taskId: string }\n | { kind: \"tasks.list\"; cursor?: string };\n\nexport type McpFnRecordedOperationResult =\n | CallToolResult\n | ReadResourceResult\n | GetPromptResult\n | CreateTaskResult\n | Task\n | ListTasksResult\n | void;\n\nexport interface McpFnScenarioResult {\n formatVersion: 1;\n name: string;\n operation: string;\n tool?: string;\n status: \"passed\" | \"failed\" | \"incomplete\";\n sideEffect: McpFnScenarioSideEffect;\n durationMs: number;\n error?: string;\n /** Observed client events discarded while this scenario was running. */\n droppedObservedEvents?: number;\n}\n\nexport interface McpFnScenarioReport {\n formatVersion: 1;\n kind: \"mcpfn.scenario-report\";\n status: \"complete\" | \"incomplete\";\n manifestHash?: string;\n total: number;\n passed: number;\n failed: number;\n incomplete: number;\n droppedResults: number;\n droppedObservedEvents: number;\n incompleteReason?: string;\n results: McpFnScenarioResult[];\n}\n\n/** Convert an observed production-client operation into the shared runner contract. */\nexport function createMcpFnScenario(\n name: string,\n operation: McpFnRecordedOperation,\n result: McpFnRecordedOperationResult,\n): McpFnScenario {\n switch (operation.kind) {\n case \"tools.call\":\n return createToolCallScenario(name, operation, result as CallToolResult);\n case \"tools.call:task\":\n return createToolTaskScenario(name, operation);\n case \"resources.read\":\n return createResourceReadScenario(name, operation, result);\n case \"resources.subscribe\":\n case \"resources.unsubscribe\":\n return createResourceLifecycleScenario(name, operation);\n case \"tasks.get\":\n case \"tasks.cancel\":\n return createTaskLifecycleScenario(name, operation);\n case \"tasks.result\":\n return createTaskResultScenario(name, operation, result);\n case \"tasks.list\":\n return createTaskListScenario(name, operation);\n case \"prompts.get\":\n return createPromptScenario(name, operation, result);\n }\n}\n\nfunction scenarioBase(name: string, sideEffect: McpFnScenarioSideEffect) {\n return { formatVersion: 1 as const, name, sideEffect };\n}\n\nfunction createToolCallScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"tools.call\" }>,\n result: CallToolResult,\n): McpFnToolScenario {\n return {\n ...scenarioBase(name, \"non-idempotent\"),\n kind: \"tools.call\",\n tool: operation.name,\n ...(operation.arguments ? { arguments: operation.arguments } : {}),\n expect: {\n isError: Boolean(result.isError),\n ...(result.structuredContent !== undefined\n ? { structuredContent: result.structuredContent }\n : {}),\n },\n };\n}\n\nfunction createToolTaskScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"tools.call:task\" }>,\n): McpFnCreateTaskScenario {\n return {\n ...scenarioBase(name, \"non-idempotent\"),\n kind: operation.kind,\n tool: operation.name,\n ...(operation.arguments ? { arguments: operation.arguments } : {}),\n ...(operation.task ? { task: operation.task } : {}),\n };\n}\n\nfunction createResourceReadScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"resources.read\" }>,\n result: McpFnRecordedOperationResult,\n): McpFnResourceScenario {\n return {\n ...scenarioBase(name, \"none\"),\n kind: operation.kind,\n uri: operation.uri,\n expect: result,\n };\n}\n\nfunction createResourceLifecycleScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"resources.subscribe\" | \"resources.unsubscribe\" }>,\n): McpFnResourceScenario {\n return {\n ...scenarioBase(name, \"idempotent\"),\n kind: operation.kind,\n uri: operation.uri,\n };\n}\n\nfunction createTaskLifecycleScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"tasks.get\" | \"tasks.cancel\" }>,\n): McpFnTaskScenario {\n return {\n ...scenarioBase(name, operation.kind === \"tasks.cancel\" ? \"idempotent\" : \"none\"),\n kind: operation.kind,\n taskId: operation.taskId,\n };\n}\n\nfunction createTaskResultScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"tasks.result\" }>,\n result: McpFnRecordedOperationResult,\n): McpFnTaskScenario {\n return {\n ...scenarioBase(name, \"none\"),\n kind: operation.kind,\n taskId: operation.taskId,\n expect: result,\n };\n}\n\nfunction createTaskListScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"tasks.list\" }>,\n): McpFnTaskScenario {\n return {\n ...scenarioBase(name, \"none\"),\n kind: operation.kind,\n ...(operation.cursor ? { cursor: operation.cursor } : {}),\n };\n}\n\nfunction createPromptScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"prompts.get\" }>,\n result: McpFnRecordedOperationResult,\n): McpFnPromptScenario {\n return {\n ...scenarioBase(name, \"none\"),\n kind: operation.kind,\n prompt: operation.name,\n ...(operation.arguments ? { arguments: operation.arguments } : {}),\n expect: result,\n };\n}\n\n/** Validate an unknown scenario module before it reaches the shared runner. */\nexport function validateMcpFnScenarios(value: unknown): McpFnScenario[] {\n const artifact = isScenarioArtifact(value) ? value : undefined;\n if (artifact?.status === \"incomplete\") {\n throw new Error(`McpFn scenario artifact is incomplete: ${artifact.incompleteReason}`);\n }\n const scenarios = artifact?.scenarios ?? value;\n if (!Array.isArray(scenarios)) {\n throw new TypeError(\"Scenario module must export an array or mcpfn.scenarios artifact\");\n }\n for (const [index, scenario] of scenarios.entries()) {\n validateScenarioCandidate(scenario, index);\n }\n return scenarios as McpFnScenario[];\n}\n\nconst SCENARIO_KINDS_WITHOUT_REQUIRED_FIELDS = new Set([\n \"initialize\",\n \"tools.list\",\n \"resources.list\",\n \"resources.templates.list\",\n \"prompts.list\",\n \"tasks.list\",\n \"auth.assert\",\n]);\n\nfunction validateScenarioCandidate(scenario: unknown, index: number): void {\n if (!scenario || typeof scenario !== \"object\" || Array.isArray(scenario)) {\n throw new TypeError(`Invalid scenario at index ${index}`);\n }\n const candidate = scenario as Record<string, unknown>;\n validateScenarioIdentity(candidate, index);\n const kind = scenarioKind(candidate, index);\n validateScenarioOperation(candidate, kind, index);\n validateScenarioLimits(candidate, index);\n if (kind === \"events.expect\") validateEventScenario(candidate, index);\n validateScenarioMetadata(candidate, index);\n if (kind === \"auth.assert\") validateAuthScenario(candidate, index);\n}\n\nfunction validateScenarioIdentity(candidate: Record<string, unknown>, index: number): void {\n if (candidate.formatVersion !== undefined && candidate.formatVersion !== 1) {\n throw new TypeError(`Invalid scenario at index ${index}: unsupported formatVersion`);\n }\n if (typeof candidate.name !== \"string\" || !candidate.name.trim()) {\n throw new TypeError(`Invalid scenario at index ${index}: name is required`);\n }\n}\n\nfunction scenarioKind(candidate: Record<string, unknown>, index: number): string {\n const kind = candidate.kind ?? \"tools.call\";\n if (typeof kind !== \"string\") {\n throw new TypeError(`Invalid scenario at index ${index}: kind must be a string`);\n }\n return kind;\n}\n\nfunction validateScenarioOperation(\n candidate: Record<string, unknown>,\n kind: string,\n index: number,\n): void {\n const requiredField = requiredScenarioField(kind);\n if (requiredField && typeof candidate[requiredField] !== \"string\") {\n throw new TypeError(`Invalid scenario at index ${index}: ${kind} requires ${requiredField}`);\n }\n if (!requiredField && !SCENARIO_KINDS_WITHOUT_REQUIRED_FIELDS.has(kind)) {\n throw new TypeError(`Invalid scenario at index ${index}: unsupported kind ${kind}`);\n }\n}\n\nfunction validateScenarioLimits(candidate: Record<string, unknown>, index: number): void {\n if (\n candidate.timeoutMs !== undefined &&\n (!Number.isInteger(candidate.timeoutMs) || Number(candidate.timeoutMs) < 1 || Number(candidate.timeoutMs) > 300_000)\n ) {\n throw new TypeError(`Invalid scenario at index ${index}: timeoutMs must be 1..300000`);\n }\n if (\n candidate.variables !== undefined &&\n (\n !Array.isArray(candidate.variables) ||\n candidate.variables.some((entry) => typeof entry !== \"string\" || !/^[A-Z][A-Z0-9_]*$/.test(entry))\n )\n ) {\n throw new TypeError(`Invalid scenario at index ${index}: variables must be environment names`);\n }\n}\n\nfunction validateScenarioMetadata(candidate: Record<string, unknown>, index: number): void {\n if (\n candidate.status !== undefined &&\n candidate.status !== \"complete\" &&\n candidate.status !== \"incomplete\"\n ) {\n throw new TypeError(`Invalid scenario at index ${index}: status must be complete or incomplete`);\n }\n if (candidate.status === \"incomplete\" && typeof candidate.incompleteReason !== \"string\") {\n throw new TypeError(`Invalid scenario at index ${index}: incompleteReason is required`);\n }\n if (\n candidate.sideEffect !== undefined &&\n (typeof candidate.sideEffect !== \"string\" || ![\"none\", \"idempotent\", \"non-idempotent\"].includes(candidate.sideEffect))\n ) {\n throw new TypeError(`Invalid scenario at index ${index}: sideEffect is unsupported`);\n }\n}\n\nfunction validateEventScenario(candidate: Record<string, unknown>, index: number): void {\n if (\n candidate.minimum !== undefined &&\n (!Number.isSafeInteger(candidate.minimum) || Number(candidate.minimum) < 1)\n ) {\n throw new TypeError(\n `Invalid scenario at index ${index}: events.expect minimum must be a positive integer`,\n );\n }\n}\n\nfunction validateAuthScenario(candidate: Record<string, unknown>, index: number): void {\n const expectation = candidate.expect as Record<string, unknown> | undefined;\n if (\n typeof candidate.phase !== \"string\" ||\n !expectation ||\n typeof expectation.outcome !== \"string\" ||\n ![\"allowed\", \"denied\"].includes(expectation.outcome)\n ) {\n throw new TypeError(`Invalid scenario at index ${index}: auth.assert expectation is required`);\n }\n}\n\nexport function createMcpFnScenarioArtifact(\n scenarios: McpFnScenario[],\n options?: Omit<McpFnScenarioArtifact, \"formatVersion\" | \"kind\" | \"scenarios\">,\n): McpFnScenarioArtifact {\n const artifactOptions = options ?? { status: \"complete\" as const };\n return {\n formatVersion: 1,\n kind: \"mcpfn.scenarios\",\n ...artifactOptions,\n scenarios: validateMcpFnScenarios(scenarios),\n };\n}\n\nfunction isScenarioArtifact(value: unknown): value is McpFnScenarioArtifact {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const candidate = value as Record<string, unknown>;\n if (candidate.kind !== \"mcpfn.scenarios\") return false;\n if (candidate.formatVersion !== 1) {\n throw new Error(\"Unsupported McpFn scenario artifact formatVersion\");\n }\n if (candidate.status !== \"complete\" && candidate.status !== \"incomplete\") {\n throw new Error(\"McpFn scenario artifact status must be complete or incomplete\");\n }\n if (candidate.status === \"incomplete\" && typeof candidate.incompleteReason !== \"string\") {\n throw new Error(\"Incomplete McpFn scenario artifact requires incompleteReason\");\n }\n return true;\n}\n\nexport async function runScenarios(\n client: McpFnTestClient<unknown>,\n scenarios: McpFnScenario[],\n options: McpFnScenarioRunOptions = {},\n): Promise<McpFnScenarioResult[]> {\n if (\n options.defaultTimeoutMs !== undefined &&\n (\n !Number.isInteger(options.defaultTimeoutMs) ||\n options.defaultTimeoutMs < 1 ||\n options.defaultTimeoutMs > 300_000\n )\n ) {\n throw new Error(\"defaultTimeoutMs must be an integer from 1 through 300000\");\n }\n if (\n options.maxScenarios !== undefined &&\n (!Number.isInteger(options.maxScenarios) || options.maxScenarios < 1)\n ) {\n throw new Error(\"maxScenarios must be a positive integer\");\n }\n if (\n options.maxErrorBytes !== undefined &&\n (!Number.isInteger(options.maxErrorBytes) || options.maxErrorBytes < 64)\n ) {\n throw new Error(\"maxErrorBytes must be an integer of at least 64\");\n }\n if (\n options.maxObservedEvents !== undefined &&\n (!Number.isInteger(options.maxObservedEvents) || options.maxObservedEvents < 1)\n ) {\n throw new Error(\"maxObservedEvents must be a positive integer\");\n }\n if (scenarios.length > (options.maxScenarios ?? 1_000)) {\n throw new Error(`Scenario count exceeds the configured cap of ${options.maxScenarios ?? 1_000}`);\n }\n const results: McpFnScenarioResult[] = [];\n const observedEvents: McpFnClientEvent[] = [];\n const maxObservedEvents = options.maxObservedEvents ?? 500;\n let droppedObservedEvents = 0;\n let attributedDroppedObservedEvents = 0;\n const pushResult = (result: McpFnScenarioResult): void => {\n const newlyDropped = droppedObservedEvents - attributedDroppedObservedEvents;\n results.push({\n ...result,\n ...(newlyDropped > 0\n ? { droppedObservedEvents: (result.droppedObservedEvents ?? 0) + newlyDropped }\n : {}),\n });\n attributedDroppedObservedEvents = droppedObservedEvents;\n };\n const unsubscribe = client.session.onEvent((event) => {\n observedEvents.push(event);\n if (observedEvents.length > maxObservedEvents) {\n observedEvents.shift();\n droppedObservedEvents += 1;\n }\n });\n let timedOutScenario: string | undefined;\n try {\n for (const scenario of scenarios) {\n const startedAt = performance.now();\n const operation = scenario.kind ?? \"tools.call\";\n const common = {\n formatVersion: 1 as const,\n name: scenario.name,\n operation,\n ...(isToolScenario(scenario) ? { tool: scenario.tool } : {}),\n sideEffect: scenario.sideEffect ?? defaultSideEffect(operation),\n };\n if (timedOutScenario) {\n pushResult({\n ...common,\n status: \"incomplete\",\n durationMs: 0,\n error: truncateError(`Skipped after timed-out scenario: ${timedOutScenario}`, options),\n });\n continue;\n }\n const resolved = resolveScenarioVariables(scenario, options.variables);\n if (resolved.missing.length > 0) {\n pushResult({\n ...common,\n status: \"incomplete\",\n durationMs: 0,\n error: truncateError(\n `Missing scenario variables: ${resolved.missing.join(\", \")}`,\n options,\n ),\n });\n continue;\n }\n if (scenario.status === \"incomplete\") {\n pushResult({\n ...common,\n status: \"incomplete\",\n durationMs: 0,\n error: truncateError(scenario.incompleteReason ?? \"Scenario is incomplete\", options),\n });\n continue;\n }\n const timeoutMs = scenario.timeoutMs ?? options.defaultTimeoutMs ?? 30_000;\n const controller = new AbortController();\n let timer: ReturnType<typeof setTimeout> | undefined;\n let timedOut = false;\n try {\n await Promise.race([\n executeScenario(client, resolved.scenario, {\n signal: controller.signal,\n timeout: timeoutMs,\n }, observedEvents, options),\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n timedOut = true;\n controller.abort();\n reject(new McpFnAssertionError(`Scenario timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n }),\n ]);\n pushResult({\n ...common,\n status: \"passed\",\n durationMs: performance.now() - startedAt,\n });\n } catch (error) {\n pushResult({\n ...common,\n status: \"failed\",\n durationMs: performance.now() - startedAt,\n error: truncateError(error instanceof Error ? error.message : String(error), options),\n });\n if (timedOut) timedOutScenario = scenario.name;\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n } finally {\n const unattributed = droppedObservedEvents - attributedDroppedObservedEvents;\n const lastResult = results.at(-1);\n if (lastResult && unattributed > 0) {\n lastResult.droppedObservedEvents =\n (lastResult.droppedObservedEvents ?? 0) + unattributed;\n }\n unsubscribe();\n }\n return results;\n}\n\nexport interface McpFnScenarioRunOptions {\n defaultTimeoutMs?: number;\n maxScenarios?: number;\n maxErrorBytes?: number;\n /** Observed client-event count cap. Defaults to 500. */\n maxObservedEvents?: number;\n variables?: Record<string, string | undefined>;\n auth?(scenario: McpFnAuthScenario, signal: AbortSignal): Promise<{\n outcome: \"allowed\" | \"denied\";\n code?: string;\n }>;\n}\n\nfunction resolveScenarioVariables(\n scenario: McpFnScenario,\n supplied: Record<string, string | undefined> | undefined,\n): { scenario: McpFnScenario; missing: string[] } {\n const values = { ...process.env, ...supplied };\n const required = new Set(scenario.variables ?? []);\n const marker = /\\$\\{([A-Z][A-Z0-9_]*)\\}/g;\n const encodedMarker = /%24%7[Bb]([A-Z][A-Z0-9_]*)%7[Dd]/g;\n const visit = (value: unknown): unknown => {\n if (typeof value === \"string\") {\n for (const match of value.matchAll(marker)) required.add(match[1]);\n for (const match of value.matchAll(encodedMarker)) required.add(match[1]);\n return value\n .replace(marker, (original, name: string) => values[name] ?? original)\n .replace(encodedMarker, (original, name: string) =>\n values[name] === undefined ? original : encodeURIComponent(values[name]),\n );\n }\n if (Array.isArray(value)) return value.map(visit);\n if (value && typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, entry]) => [key, visit(entry)]),\n );\n }\n return value;\n };\n const resolved = visit(scenario) as McpFnScenario;\n return {\n scenario: resolved,\n missing: [...required]\n .filter((name) => values[name] === undefined)\n .sort(compareCodeUnits),\n };\n}\n\nexport function createMcpFnScenarioReport(\n results: McpFnScenarioResult[],\n options: { manifestHash?: string; maxBytes?: number } = {},\n): McpFnScenarioReport {\n const failed = results.filter((result) => result.status === \"failed\").length;\n const incomplete = results.filter((result) => result.status === \"incomplete\").length;\n const droppedObservedEvents = results.reduce(\n (total, result) => total + (result.droppedObservedEvents ?? 0),\n 0,\n );\n const report: McpFnScenarioReport = {\n formatVersion: 1,\n kind: \"mcpfn.scenario-report\",\n status: incomplete === 0 && droppedObservedEvents === 0 ? \"complete\" : \"incomplete\",\n ...(options.manifestHash ? { manifestHash: options.manifestHash } : {}),\n total: results.length,\n passed: results.length - failed - incomplete,\n failed,\n incomplete,\n droppedResults: 0,\n droppedObservedEvents,\n ...(droppedObservedEvents > 0\n ? { incompleteReason: \"Observed client events exceeded maxObservedEvents\" }\n : {}),\n results: structuredClone(results),\n };\n const maxBytes = options.maxBytes ?? 1_048_576;\n if (!Number.isInteger(maxBytes) || maxBytes < 1_024) {\n throw new Error(\"maxBytes must be an integer of at least 1024\");\n }\n if (serializedBytes(report) > maxBytes) {\n report.status = \"incomplete\";\n report.incompleteReason = \"Report content exceeded maxBytes and was truncated\";\n }\n while (serializedBytes(report) > maxBytes && report.results.length > 0) {\n report.results.pop();\n report.droppedResults += 1;\n }\n if (report.droppedResults > 0) {\n report.status = \"incomplete\";\n }\n if (serializedBytes(report) > maxBytes) {\n throw new Error(\"The minimum scenario report exceeds maxBytes\");\n }\n return report;\n}\n\nfunction serializedBytes(value: unknown): number {\n return new TextEncoder().encode(JSON.stringify(value)).byteLength;\n}\n\nasync function executeScenario(\n client: McpFnTestClient<unknown>,\n scenario: McpFnScenario,\n requestOptions: { signal: AbortSignal; timeout: number },\n observedEvents: McpFnClientEvent[],\n runOptions: McpFnScenarioRunOptions,\n): Promise<void> {\n const kind = scenario.kind ?? \"tools.call\";\n if (isInventoryScenario(scenario)) {\n await executeInventoryScenario(client, scenario, requestOptions);\n return;\n }\n switch (scenario.kind) {\n case undefined:\n case \"tools.call\":\n return executeToolScenario(client, scenario, requestOptions);\n case \"initialize\":\n return executeInitializeScenario(client, scenario);\n case \"resources.read\":\n return assertExpectedAsync(client.readResource(scenario.uri, requestOptions), scenario.expect);\n case \"resources.subscribe\":\n return client.subscribeResource(scenario.uri, requestOptions);\n case \"resources.unsubscribe\":\n return client.unsubscribeResource(scenario.uri, requestOptions);\n case \"prompts.get\":\n return assertExpectedAsync(\n client.getPrompt(scenario.prompt, scenario.arguments, requestOptions),\n scenario.expect,\n );\n case \"tools.call:task\":\n return assertExpectedAsync(\n client.createToolTask(scenario.tool, scenario.arguments, scenario.task, requestOptions),\n scenario.expect,\n );\n case \"tasks.get\":\n return assertExpectedAsync(client.getTask(scenario.taskId!, requestOptions), scenario.expect);\n case \"tasks.result\":\n return assertExpectedAsync(client.getTaskResult(scenario.taskId!, requestOptions), scenario.expect);\n case \"tasks.cancel\":\n return assertExpectedAsync(client.cancelTask(scenario.taskId!, requestOptions), scenario.expect);\n case \"tasks.list\":\n return assertExpectedAsync(client.listTasks(scenario.cursor, requestOptions), scenario.expect);\n case \"events.expect\":\n return executeEventScenario(scenario, observedEvents);\n case \"auth.assert\":\n return executeAuthScenario(scenario, requestOptions.signal, runOptions);\n }\n throw new McpFnAssertionError(`Unsupported scenario operation ${kind}`);\n}\n\nasync function executeToolScenario(\n client: McpFnTestClient<unknown>,\n scenario: McpFnToolScenario,\n requestOptions: { signal: AbortSignal; timeout: number },\n): Promise<void> {\n const result = await client.callTool(\n scenario.tool,\n scenario.arguments,\n requestOptions,\n );\n assertToolResult(result, scenario);\n await scenario.verify?.(result);\n}\n\nfunction assertToolResult(result: CallToolResult, scenario: McpFnToolScenario): void {\n if (result.isError && scenario.expect?.isError === undefined) {\n throw new McpFnAssertionError(\n \"Tool returned isError=true without an explicit expect.isError=true assertion\",\n );\n }\n if (\n scenario.expect?.isError !== undefined &&\n Boolean(result.isError) !== scenario.expect.isError\n ) {\n throw new McpFnAssertionError(\n `Expected isError=${scenario.expect.isError}, received ${Boolean(result.isError)}`,\n );\n }\n if (\n scenario.expect &&\n Object.hasOwn(scenario.expect, \"structuredContent\") &&\n stableJson(result.structuredContent) !== stableJson(scenario.expect.structuredContent)\n ) {\n throw new McpFnAssertionError(\n `Structured result mismatch\\nexpected: ${stableJson(scenario.expect.structuredContent)}\\nactual: ${stableJson(result.structuredContent)}`,\n );\n }\n if (scenario.expect?.structuredTextParity) assertStructuredTextParity(result);\n}\n\nfunction executeInitializeScenario(\n client: McpFnTestClient<unknown>,\n scenario: McpFnInitializeScenario,\n): void {\n const actual = client.client.getServerCapabilities() ?? {};\n if (scenario.expectCapabilities && stableJson(actual) !== stableJson(scenario.expectCapabilities)) {\n throw new McpFnAssertionError(\n `Capability mismatch\\nexpected: ${stableJson(scenario.expectCapabilities)}\\nactual: ${stableJson(actual)}`,\n );\n }\n}\n\nasync function executeInventoryScenario(\n client: McpFnTestClient<unknown>,\n scenario: McpFnInventoryScenario,\n requestOptions: { signal: AbortSignal; timeout: number },\n): Promise<void> {\n const values = await listScenarioInventory(client, scenario.kind, requestOptions);\n if (!scenario.expectNames) return;\n const actual = values.map((value) => value.name).sort(compareCodeUnits);\n const expected = [...scenario.expectNames].sort(compareCodeUnits);\n if (stableJson(actual) !== stableJson(expected)) {\n throw new McpFnAssertionError(\n `Inventory mismatch\\nexpected: ${stableJson(expected)}\\nactual: ${stableJson(actual)}`,\n );\n }\n}\n\nasync function assertExpectedAsync(actual: Promise<unknown>, expected: unknown): Promise<void> {\n assertExpected(await actual, expected);\n}\n\nfunction executeEventScenario(\n scenario: McpFnEventScenario,\n observedEvents: McpFnClientEvent[],\n): void {\n const matching = observedEvents.filter((event) => event.kind === scenario.event);\n if (matching.length < (scenario.minimum ?? 1)) {\n throw new McpFnAssertionError(\n `Expected at least ${scenario.minimum ?? 1} ${scenario.event} event(s), received ${matching.length}`,\n );\n }\n if (scenario.expectPayload !== undefined) {\n assertExpected(matching.at(-1)?.payload, scenario.expectPayload);\n }\n}\n\nasync function executeAuthScenario(\n scenario: McpFnAuthScenario,\n signal: AbortSignal,\n runOptions: McpFnScenarioRunOptions,\n): Promise<void> {\n if (!runOptions.auth) {\n throw new McpFnAssertionError(\"auth.assert requires a scenario auth adapter\");\n }\n assertExpected(await runOptions.auth(scenario, signal), scenario.expect);\n}\n\nfunction truncateError(value: string, options: McpFnScenarioRunOptions): string {\n const redacted = String(redactOAuthValue(value));\n const maxBytes = options.maxErrorBytes ?? 4_096;\n const bytes = new TextEncoder().encode(redacted);\n if (bytes.byteLength <= maxBytes) return redacted;\n return `${new TextDecoder().decode(bytes.slice(0, Math.max(0, maxBytes - 16)))}...[TRUNCATED]`;\n}\n\nfunction defaultSideEffect(operation: string): McpFnScenarioSideEffect {\n if (operation === \"tools.call\" || operation === \"tools.call:task\") {\n return \"non-idempotent\";\n }\n if (operation === \"tasks.cancel\") return \"idempotent\";\n return \"none\";\n}\n\nfunction compareCodeUnits(left: string, right: string): number {\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n\nfunction assertExpected(actual: unknown, expected: unknown): void {\n if (expected !== undefined && stableJson(actual) !== stableJson(expected)) {\n throw new McpFnAssertionError(\n `Scenario result mismatch\\nexpected: ${stableJson(expected)}\\nactual: ${stableJson(actual)}`,\n );\n }\n}\n\nfunction isToolScenario(scenario: McpFnScenario): scenario is McpFnToolScenario {\n return \"tool\" in scenario;\n}\n\nfunction isInventoryScenario(scenario: McpFnScenario): scenario is McpFnInventoryScenario {\n return [\"tools.list\", \"resources.list\", \"resources.templates.list\", \"prompts.list\"]\n .includes(scenario.kind ?? \"\");\n}\n\nfunction requiredScenarioField(kind: string): string | undefined {\n switch (kind) {\n case \"tools.call\":\n case \"tools.call:task\":\n return \"tool\";\n case \"resources.read\":\n case \"resources.subscribe\":\n case \"resources.unsubscribe\":\n return \"uri\";\n case \"prompts.get\":\n return \"prompt\";\n case \"tasks.get\":\n case \"tasks.result\":\n case \"tasks.cancel\":\n return \"taskId\";\n case \"events.expect\":\n return \"event\";\n default:\n return undefined;\n }\n}\n\nasync function listScenarioInventory(\n client: McpFnTestClient<unknown>,\n kind: McpFnInventoryScenario[\"kind\"],\n requestOptions: { signal: AbortSignal; timeout: number },\n) {\n switch (kind) {\n case \"tools.list\":\n return client.listTools(requestOptions);\n case \"resources.list\":\n return client.listResources(requestOptions);\n case \"resources.templates.list\":\n return client.listResourceTemplates(requestOptions);\n case \"prompts.list\":\n return client.listPrompts(requestOptions);\n }\n}\n","import type { Implementation, ServerCapabilities } from \"@modelcontextprotocol/sdk/types.js\";\nimport type {\n McpFnDiagnosticEvent,\n McpFnTarget,\n McpFnTargetDescriptor,\n} from \"@mcpfn/client\";\nimport type { McpFnManifest } from \"@mcpfn/core\";\nimport { redactOAuthValue } from \"@superfunctions/oauth-core\";\n\nimport { assertManifestContract } from \"./assertions.js\";\nimport { McpFnTestClient, type McpFnTestClientOptions } from \"./client.js\";\nimport {\n runScenarios,\n type McpFnScenario,\n type McpFnScenarioResult,\n} from \"./scenarios.js\";\n\nexport interface RunMcpFnTargetSuiteOptions {\n target: McpFnTarget;\n scenarios?: McpFnScenario[];\n manifest?: McpFnManifest;\n expectedToolNames?: readonly string[];\n clientInfo?: Implementation;\n client?: McpFnTestClientOptions;\n scenarioRun?: NonNullable<Parameters<typeof runScenarios>[2]>;\n /** Aggregate JSON size cap. Defaults to 1 MiB. */\n maxReportBytes?: number;\n /** Diagnostic timeline count cap. Defaults to 500. */\n maxTimelineEvents?: number;\n}\n\nexport interface McpFnTargetSuiteReport {\n formatVersion: 1;\n kind: \"mcpfn.target-suite-report\";\n status: \"complete\" | \"incomplete\";\n runtime: { node: string; scenarioFormatVersion: 1 };\n ok: boolean;\n target: McpFnTargetDescriptor;\n server?: Implementation;\n capabilities?: ServerCapabilities;\n manifestChecked: boolean;\n manifestHash?: string;\n total: number;\n passed: number;\n failed: number;\n incomplete: number;\n droppedResults: number;\n droppedObservedEvents: number;\n incompleteReason?: string;\n timeline: McpFnDiagnosticEvent[];\n droppedTimelineEvents: number;\n results: McpFnScenarioResult[];\n}\n\n/** Runs local, stdio, HTTP, or custom targets through the production session engine. */\nexport async function runMcpFnTargetSuite(\n options: RunMcpFnTargetSuiteOptions,\n): Promise<McpFnTargetSuiteReport> {\n const timeline: McpFnDiagnosticEvent[] = [];\n let droppedTimelineEvents = 0;\n const maxTimelineEvents = options.maxTimelineEvents ?? 500;\n if (!Number.isInteger(maxTimelineEvents) || maxTimelineEvents < 1) {\n throw new Error(\"maxTimelineEvents must be a positive integer\");\n }\n const maxReportBytes = options.maxReportBytes ?? 1_048_576;\n validateReportCap(maxReportBytes);\n const consumerDiagnostic = options.client?.diagnostics;\n const client = await McpFnTestClient.connectTarget(\n options.target,\n options.clientInfo ?? { name: \"mcpfn-suite\", version: \"0.0.1\" },\n {\n ...options.client,\n diagnostics: async (event) => {\n timeline.push(redactOAuthValue(event) as unknown as McpFnDiagnosticEvent);\n if (timeline.length > maxTimelineEvents) {\n timeline.shift();\n droppedTimelineEvents += 1;\n }\n await consumerDiagnostic?.(event);\n },\n },\n );\n const execution = await (async () => {\n try {\n if (options.manifest) {\n await assertManifestContract(client, options.manifest, {\n expectedToolNames: options.expectedToolNames,\n });\n }\n const results = await runScenarios(client, options.scenarios ?? [], options.scenarioRun);\n return {\n results,\n server: client.session.getServerVersion(),\n capabilities: client.session.getServerCapabilities(),\n };\n } finally {\n await client.close();\n }\n })();\n const results = execution.results;\n const failed = results.filter((result) => result.status === \"failed\").length;\n const incomplete = results.filter((result) => result.status === \"incomplete\").length;\n const droppedObservedEvents = results.reduce(\n (total, result) => total + (result.droppedObservedEvents ?? 0),\n 0,\n );\n const artifactIncomplete = incomplete > 0 ||\n droppedTimelineEvents > 0 ||\n droppedObservedEvents > 0;\n const report: McpFnTargetSuiteReport = {\n formatVersion: 1,\n kind: \"mcpfn.target-suite-report\",\n status: artifactIncomplete ? \"incomplete\" : \"complete\",\n runtime: { node: process.version, scenarioFormatVersion: 1 },\n ok: failed === 0 && !artifactIncomplete,\n target: redactOAuthValue(\n options.target.describe(),\n ) as unknown as McpFnTargetDescriptor,\n server: execution.server,\n capabilities: execution.capabilities,\n manifestChecked: Boolean(options.manifest),\n ...(options.manifest ? { manifestHash: options.manifest.hash } : {}),\n total: results.length,\n passed: results.length - failed - incomplete,\n failed,\n incomplete,\n droppedResults: 0,\n droppedObservedEvents,\n ...(droppedTimelineEvents > 0 || droppedObservedEvents > 0\n ? {\n incompleteReason: [\n ...(droppedTimelineEvents > 0\n ? [\"Diagnostic timeline exceeded maxTimelineEvents\"]\n : []),\n ...(droppedObservedEvents > 0\n ? [\"Observed client events exceeded maxObservedEvents\"]\n : []),\n ].join(\"; \"),\n }\n : {}),\n timeline,\n droppedTimelineEvents,\n results,\n };\n return enforceReportCap(report, maxReportBytes);\n}\n\nfunction enforceReportCap(\n report: McpFnTargetSuiteReport,\n maxBytes: number,\n): McpFnTargetSuiteReport {\n validateReportCap(maxBytes);\n const bounded = structuredClone(report);\n if (jsonBytes(bounded) > maxBytes) {\n bounded.ok = false;\n bounded.status = \"incomplete\";\n bounded.incompleteReason = \"Report content exceeded maxReportBytes and was truncated\";\n }\n while (jsonBytes(bounded) > maxBytes && bounded.results.length > 0) {\n bounded.results.pop();\n bounded.droppedResults += 1;\n }\n if (jsonBytes(bounded) > maxBytes) {\n bounded.target = { kind: report.target.kind };\n bounded.server = undefined;\n bounded.capabilities = undefined;\n bounded.timeline = [];\n bounded.droppedTimelineEvents += report.timeline.length;\n }\n if (bounded.droppedResults > 0 || jsonBytes(bounded) > maxBytes) {\n bounded.ok = false;\n bounded.status = \"incomplete\";\n bounded.incompleteReason = \"Report content exceeded maxReportBytes and was truncated\";\n }\n if (jsonBytes(bounded) > maxBytes) {\n throw new Error(\"The minimum target suite report exceeds maxReportBytes\");\n }\n return bounded;\n}\n\nfunction validateReportCap(maxBytes: number): void {\n if (!Number.isInteger(maxBytes) || maxBytes < 1_024) {\n throw new Error(\"maxReportBytes must be an integer of at least 1024\");\n }\n}\n\nfunction jsonBytes(value: unknown): number {\n return new TextEncoder().encode(JSON.stringify(value)).byteLength;\n}\n"],"mappings":"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","names":["path","import_node_http","httpsRequest","httpRequest","path","import_oauth_core","import_oauth_core","results"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/assertions.ts","../src/auth-core.ts","../src/mock-oauth-server.ts","../src/client.ts","../src/client-profile-contracts.ts","../src/conformance-process.ts","../src/conformance.ts","../src/remote-target.ts","../src/reports.ts","../src/artifact-guards.ts","../src/host-profiles.ts","../src/host-authorization.ts","../src/scenarios.ts","../src/suite.ts"],"sourcesContent":["export * from \"./assertions.js\";\nexport * from \"./auth.js\";\nexport * from \"./client.js\";\nexport * from \"./client-profile-contracts.js\";\nexport * from \"./conformance.js\";\nexport * from \"./host-profiles.js\";\nexport * from \"./host-authorization.js\";\nexport * from \"./remote-target.js\";\nexport * from \"./reports.js\";\nexport * from \"./scenarios.js\";\nexport * from \"./suite.js\";\n","import type { Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport { UriTemplate } from \"@modelcontextprotocol/sdk/shared/uriTemplate.js\";\nimport type { McpFnManifest } from \"@mcpfn/core\";\n\nimport type { McpFnTestClient } from \"./client.js\";\n\nexport function stableJson(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableJson).join(\",\")}]`;\n if (value && typeof value === \"object\") {\n return `{${Object.entries(value as Record<string, unknown>)\n .filter(([, entry]) => entry !== undefined)\n .sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)\n .map(([key, entry]) => `${JSON.stringify(key)}:${stableJson(entry)}`)\n .join(\",\")}}`;\n }\n return JSON.stringify(value);\n}\n\nexport class McpFnAssertionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"McpFnAssertionError\";\n }\n}\n\nexport interface AssertManifestContractOptions {\n /** Exact tools expected to be visible for the test client's request context. */\n expectedToolNames?: readonly string[];\n}\n\nexport async function assertManifestContract(\n client: McpFnTestClient<unknown>,\n manifest: McpFnManifest,\n options: AssertManifestContractOptions = {},\n): Promise<Tool[]> {\n const actual = await client.listTools();\n const actualByName = new Map(actual.map((tool) => [tool.name, tool]));\n const manifestByName = new Map(manifest.tools.map((tool) => [tool.name, tool]));\n const expectedNames = [...(\n options.expectedToolNames ?? manifest.tools.map((tool) => tool.name)\n )].sort();\n const unknownExpectedNames = expectedNames.filter((name) => !manifestByName.has(name));\n if (unknownExpectedNames.length) {\n throw new McpFnAssertionError(\n `Expected visible tools are absent from the manifest: ${stableJson(unknownExpectedNames)}`,\n );\n }\n const actualNames = actual.map((tool) => tool.name).sort();\n if (stableJson(expectedNames) !== stableJson(actualNames)) {\n throw new McpFnAssertionError(\n `Tool inventory mismatch\\nexpected: ${stableJson(expectedNames)}\\nactual: ${stableJson(actualNames)}`,\n );\n }\n for (const name of expectedNames) {\n const expected = manifestByName.get(name)!;\n const tool = actualByName.get(expected.name)!;\n const comparableExpected = {\n name: expected.name,\n description: expected.description,\n inputSchema: expected.inputSchema,\n outputSchema: expected.outputSchema,\n annotations: expected.annotations,\n execution: expected.execution,\n icons: expected.icons,\n title: expected.title,\n _meta: expected.metadata,\n };\n const comparableActual = {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n outputSchema: tool.outputSchema,\n annotations: tool.annotations,\n execution: tool.execution,\n icons: tool.icons,\n title: tool.title,\n _meta: tool._meta,\n };\n if (stableJson(comparableExpected) !== stableJson(comparableActual)) {\n throw new McpFnAssertionError(\n `Contract mismatch for ${expected.name}\\nexpected: ${stableJson(comparableExpected)}\\nactual: ${stableJson(comparableActual)}`,\n );\n }\n }\n\n const actualCapabilities = client.client.getServerCapabilities() ?? {};\n if (stableJson(manifest.capabilities ?? {}) !== stableJson(actualCapabilities)) {\n throw new McpFnAssertionError(\n `Capability mismatch\\nexpected: ${stableJson(manifest.capabilities ?? {})}\\nactual: ${stableJson(actualCapabilities)}`,\n );\n }\n\n const actualResources = actualCapabilities.resources\n ? await client.listResources()\n : [];\n const comparableResources = actualResources.map(({ _meta, ...resource }) => ({\n ...resource,\n metadata: _meta,\n }));\n const staticResourceUris = new Set(\n (manifest.resources ?? []).map((resource) => resource.uri),\n );\n const resourceTemplates = (manifest.resourceTemplates ?? []).map(\n (template) => new UriTemplate(template.uriTemplate),\n );\n const comparableStaticResources = comparableResources.filter(\n (resource) =>\n staticResourceUris.has(resource.uri) ||\n !resourceTemplates.some((template) => template.match(resource.uri)),\n );\n const expectedResources = (manifest.resources ?? []).map(\n ({ subscribable: _subscribable, ...resource }) => resource,\n );\n if (stableJson(expectedResources) !== stableJson(comparableStaticResources)) {\n throw new McpFnAssertionError(\n `Resource inventory mismatch\\nexpected: ${stableJson(expectedResources)}\\nactual: ${stableJson(comparableStaticResources)}`,\n );\n }\n\n const actualTemplates = actualCapabilities.resources\n ? await client.listResourceTemplates()\n : [];\n const comparableTemplates = actualTemplates.map(({ _meta, ...template }) => ({\n ...template,\n metadata: _meta,\n }));\n const expectedTemplates = (manifest.resourceTemplates ?? []).map(\n ({ subscribable: _subscribable, ...template }) => template,\n );\n if (stableJson(expectedTemplates) !== stableJson(comparableTemplates)) {\n throw new McpFnAssertionError(\n `Resource template inventory mismatch\\nexpected: ${stableJson(expectedTemplates)}\\nactual: ${stableJson(comparableTemplates)}`,\n );\n }\n\n for (const resource of comparableResources) {\n const expected = (manifest.resources ?? []).find(\n (candidate) => candidate.uri === resource.uri,\n ) ?? (manifest.resourceTemplates ?? []).find(\n (candidate) => new UriTemplate(candidate.uriTemplate).match(resource.uri),\n );\n const subscribable = expected?.subscribable === true;\n if (subscribable) {\n try {\n await client.subscribeResource(resource.uri);\n await client.unsubscribeResource(resource.uri);\n } catch (error) {\n throw new McpFnAssertionError(\n `Resource subscription mismatch for ${resource.uri}: expected subscribe and unsubscribe to succeed (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n continue;\n }\n let accepted = false;\n try {\n await client.subscribeResource(resource.uri);\n accepted = true;\n await client.unsubscribeResource(resource.uri).catch(() => undefined);\n } catch {\n // Rejection is the expected behavior for a non-subscribable resource.\n }\n if (accepted) {\n throw new McpFnAssertionError(\n `Resource subscription mismatch for ${resource.uri}: expected subscribe to be rejected`,\n );\n }\n }\n\n const actualPrompts = actualCapabilities.prompts\n ? await client.listPrompts()\n : [];\n const comparablePrompts = actualPrompts.map(({ _meta, ...prompt }) => ({\n ...prompt,\n metadata: _meta,\n }));\n const expectedPrompts = (manifest.prompts ?? []).map(({ argumentsSchema: _schema, ...prompt }) => prompt);\n if (stableJson(expectedPrompts) !== stableJson(comparablePrompts)) {\n throw new McpFnAssertionError(\n `Prompt inventory mismatch\\nexpected: ${stableJson(expectedPrompts)}\\nactual: ${stableJson(comparablePrompts)}`,\n );\n }\n return actual;\n}\n\nexport function assertStructuredTextParity(result: {\n content?: unknown[];\n structuredContent?: Record<string, unknown>;\n}): void {\n if (!result.structuredContent) {\n throw new McpFnAssertionError(\"Tool result has no structuredContent\");\n }\n const text = (result.content ?? []).find(\n (entry): entry is { type: \"text\"; text: string } =>\n !!entry &&\n typeof entry === \"object\" &&\n (entry as { type?: unknown }).type === \"text\" &&\n typeof (entry as { text?: unknown }).text === \"string\",\n )?.text;\n if (!text) {\n throw new McpFnAssertionError(\"Tool result has no text content\");\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n throw new McpFnAssertionError(\"Tool text content is not JSON\");\n }\n if (stableJson(parsed) !== stableJson(result.structuredContent)) {\n throw new McpFnAssertionError(\n \"Tool text content and structuredContent are not equivalent\",\n );\n }\n}\n","export type McpFnAuthCredentialKind = \"api-key\" | \"oauth\";\n\nexport interface McpFnAuthCredential {\n kind: McpFnAuthCredentialKind;\n headers: HeadersInit;\n label?: string;\n dispose?(): void | Promise<void>;\n}\n\nexport interface McpFnAuthCredentialRequest {\n kind: McpFnAuthCredentialKind;\n scopes?: string[];\n resource?: string;\n expiresInSeconds?: number;\n}\n\nexport interface McpFnAuthProviderCapabilities {\n expiration?: boolean;\n resourceBinding?: boolean;\n revocation?: boolean;\n scopes?: boolean;\n}\n\n/**\n * The application-owned seam. Skillplane only needs to map this interface to\n * its existing API-key or OAuth issuance and revocation helpers.\n */\nexport interface McpFnAuthProviderAdapter {\n capabilities?: McpFnAuthProviderCapabilities;\n issue(input: McpFnAuthCredentialRequest): Promise<McpFnAuthCredential>;\n revoke?(credential: McpFnAuthCredential): void | Promise<void>;\n}\n\nexport interface McpFnAuthProbeScenario {\n name:\n | \"missing-credential\"\n | \"invalid-credential\"\n | \"valid-credential\"\n | \"insufficient-scope\"\n | \"expired-credential\"\n | \"missing-resource\"\n | \"wrong-resource\"\n | \"revoked-credential\";\n kind: McpFnAuthCredentialKind;\n}\n\nexport interface McpFnAuthTarget {\n request(\n headers: Headers,\n scenario: McpFnAuthProbeScenario,\n ): Promise<Response>;\n}\n\nexport interface McpFnAuthRegressionOptions {\n kind: McpFnAuthCredentialKind;\n provider: McpFnAuthProviderAdapter;\n target: McpFnAuthTarget;\n requiredScopes?: string[];\n resource?: string;\n wrongResource?: string;\n invalidCredentialHeaders?: HeadersInit;\n /** OAuth failures are required to advertise protected-resource metadata. */\n protectedResourceMetadataUrl?: string;\n expectedAuthenticatedStatuses?: number[];\n verifyAuthenticatedResponse?(\n response: Response,\n credential: McpFnAuthCredential,\n ): void | Promise<void>;\n}\n\nexport interface McpFnAuthScenarioResult {\n name: McpFnAuthProbeScenario[\"name\"];\n status: \"passed\" | \"failed\";\n responseStatus?: number;\n error?: string;\n}\n\nexport interface McpFnBearerChallenge {\n scheme: string;\n parameters: Record<string, string>;\n}\n\nexport class McpFnAuthAssertionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"McpFnAuthAssertionError\";\n }\n}\n\nfunction expectedStatus(\n response: Response,\n expected: number | number[],\n name: string,\n): void {\n const statuses = Array.isArray(expected) ? expected : [expected];\n if (!statuses.includes(response.status)) {\n throw new McpFnAuthAssertionError(\n `${name} expected HTTP ${statuses.join(\" or \")}, received ${response.status}`,\n );\n }\n}\n\nexport function parseBearerChallenge(\n header: string | null,\n): McpFnBearerChallenge | undefined {\n if (!header) return undefined;\n const matches = [...header.matchAll(/(?:^|,)\\s*([A-Za-z][A-Za-z0-9_-]*)\\s+/g)];\n const selectedIndex = matches.findIndex((entry) => entry[1].toLowerCase() === \"bearer\");\n if (selectedIndex < 0) return undefined;\n const match = matches[selectedIndex];\n const start = (match.index ?? 0) + match[0].length;\n const end = matches[selectedIndex + 1]?.index ?? header.length;\n const parameters: Record<string, string> = {};\n const source = header.slice(start, end);\n const pattern = /([A-Za-z][A-Za-z0-9_-]*)\\s*=\\s*(?:\"((?:[^\"\\\\]|\\\\.)*)\"|([^,\\s]+))/g;\n for (const entry of source.matchAll(pattern)) {\n const quoted = entry[2]?.replace(/\\\\([\"\\\\])/g, \"$1\");\n parameters[entry[1]] = quoted ?? entry[3] ?? \"\";\n }\n return { scheme: match[1], parameters };\n}\n\nexport function assertBearerResourceChallenge(\n response: Response,\n expectedMetadataUrl?: string,\n): McpFnBearerChallenge {\n const challenge = parseBearerChallenge(response.headers.get(\"www-authenticate\"));\n if (!challenge || challenge.scheme.toLowerCase() !== \"bearer\") {\n throw new McpFnAuthAssertionError(\"Expected a Bearer WWW-Authenticate challenge\");\n }\n const metadataUrl = challenge.parameters.resource_metadata;\n if (!metadataUrl) {\n throw new McpFnAuthAssertionError(\n \"Bearer challenge is missing the resource_metadata parameter\",\n );\n }\n try {\n const parsed = new URL(metadataUrl);\n if (!parsed.protocol || !parsed.host) throw new Error(\"not absolute\");\n } catch {\n throw new McpFnAuthAssertionError(\n `Bearer challenge has an invalid resource_metadata URL: ${metadataUrl}`,\n );\n }\n if (expectedMetadataUrl && metadataUrl !== expectedMetadataUrl) {\n throw new McpFnAuthAssertionError(\n `Expected resource_metadata=${expectedMetadataUrl}, received ${metadataUrl}`,\n );\n }\n return challenge;\n}\n\nexport function bearerCredential(\n token: string,\n kind: McpFnAuthCredentialKind = \"oauth\",\n): McpFnAuthCredential {\n return {\n kind,\n headers: { authorization: `Bearer ${token}` },\n };\n}\n\nexport function apiKeyCredential(\n apiKey: string,\n options: { headerName?: string; scheme?: string } = {},\n): McpFnAuthCredential {\n const headerName = options.headerName ?? \"authorization\";\n const value = options.scheme === \"\"\n ? apiKey\n : `${options.scheme ?? \"Bearer\"} ${apiKey}`;\n return { kind: \"api-key\", headers: { [headerName]: value } };\n}\n\nfunction invalidHeaders(options: McpFnAuthRegressionOptions): Headers {\n return new Headers(options.invalidCredentialHeaders ?? {\n authorization: `Bearer mcpfn-invalid-${options.kind}`,\n });\n}\n\nasync function runOne(\n options: McpFnAuthRegressionOptions,\n scenario: McpFnAuthProbeScenario,\n prepare: () => Promise<McpFnAuthCredential | undefined>,\n expected: number | number[],\n): Promise<McpFnAuthScenarioResult> {\n let credential: McpFnAuthCredential | undefined;\n try {\n credential = await prepare();\n const headers = credential\n ? new Headers(credential.headers)\n : scenario.name === \"invalid-credential\"\n ? invalidHeaders(options)\n : new Headers();\n const response = await options.target.request(headers, scenario);\n expectedStatus(response, expected, scenario.name);\n if (\n options.kind === \"oauth\" &&\n scenario.name !== \"valid-credential\"\n ) {\n assertBearerResourceChallenge(\n response,\n options.protectedResourceMetadataUrl,\n );\n }\n if (scenario.name === \"valid-credential\" && credential) {\n await options.verifyAuthenticatedResponse?.(response.clone(), credential);\n }\n return {\n name: scenario.name,\n status: \"passed\",\n responseStatus: response.status,\n };\n } catch (error) {\n return {\n name: scenario.name,\n status: \"failed\",\n error: error instanceof Error ? error.message : String(error),\n };\n } finally {\n await credential?.dispose?.();\n }\n}\n\n/** Runs the common API-key or OAuth resource-server regression matrix. */\nexport async function runAuthRegressionSuite(\n options: McpFnAuthRegressionOptions,\n): Promise<McpFnAuthScenarioResult[]> {\n const issue = (overrides: Partial<McpFnAuthCredentialRequest> = {}) =>\n options.provider.issue({\n kind: options.kind,\n scopes: options.requiredScopes,\n resource: options.resource,\n ...overrides,\n });\n const results: McpFnAuthScenarioResult[] = [];\n results.push(await runOne(\n options,\n { name: \"missing-credential\", kind: options.kind },\n async () => undefined,\n 401,\n ));\n results.push(await runOne(\n options,\n { name: \"invalid-credential\", kind: options.kind },\n async () => undefined,\n 401,\n ));\n results.push(await runOne(\n options,\n { name: \"valid-credential\", kind: options.kind },\n () => issue(),\n options.expectedAuthenticatedStatuses ?? [200, 201, 202, 204],\n ));\n\n const capabilities = options.provider.capabilities ?? {};\n if (capabilities.scopes && options.requiredScopes?.length) {\n results.push(await runOne(\n options,\n { name: \"insufficient-scope\", kind: options.kind },\n () => issue({ scopes: [] }),\n 403,\n ));\n }\n if (capabilities.expiration) {\n results.push(await runOne(\n options,\n { name: \"expired-credential\", kind: options.kind },\n () => issue({ expiresInSeconds: -60 }),\n 401,\n ));\n }\n if (capabilities.resourceBinding && options.resource) {\n results.push(await runOne(\n options,\n { name: \"missing-resource\", kind: options.kind },\n () => issue({ resource: undefined }),\n 401,\n ));\n }\n if (capabilities.resourceBinding && options.wrongResource) {\n results.push(await runOne(\n options,\n { name: \"wrong-resource\", kind: options.kind },\n () => issue({ resource: options.wrongResource }),\n 401,\n ));\n }\n if (capabilities.revocation && options.provider.revoke) {\n results.push(await runOne(\n options,\n { name: \"revoked-credential\", kind: options.kind },\n async () => {\n const credential = await issue();\n await options.provider.revoke?.(credential);\n return credential;\n },\n 401,\n ));\n }\n return results;\n}\n\nexport async function assertAuthRegressionSuite(\n options: McpFnAuthRegressionOptions,\n): Promise<McpFnAuthScenarioResult[]> {\n const results = await runAuthRegressionSuite(options);\n const failures = results.filter((result) => result.status === \"failed\");\n if (failures.length) {\n throw new McpFnAuthAssertionError(\n failures.map((failure) => `${failure.name}: ${failure.error}`).join(\"\\n\"),\n );\n }\n return results;\n}\n\nexport interface McpFnFetchAuthTargetOptions {\n url: string | URL;\n fetch?: typeof globalThis.fetch;\n requestInit?: RequestInit | ((scenario: McpFnAuthProbeScenario) => RequestInit);\n}\n\n/** Creates a protected MCP initialize probe suitable for local or deployed endpoints. */\nexport function createFetchAuthTarget(\n options: McpFnFetchAuthTargetOptions,\n): McpFnAuthTarget {\n const fetchImplementation = options.fetch ?? globalThis.fetch;\n if (!fetchImplementation) {\n throw new Error(\"A fetch implementation is required\");\n }\n return {\n async request(authHeaders, scenario) {\n const configured = typeof options.requestInit === \"function\"\n ? options.requestInit(scenario)\n : options.requestInit ?? {};\n const headers = new Headers(configured.headers);\n headers.set(\"accept\", \"application/json, text/event-stream\");\n headers.set(\"content-type\", \"application/json\");\n authHeaders.forEach((value, name) => headers.set(name, value));\n return fetchImplementation(options.url, {\n method: \"POST\",\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: `mcpfn-auth-${scenario.name}`,\n method: \"initialize\",\n params: {\n protocolVersion: \"2025-11-25\",\n capabilities: {},\n clientInfo: { name: \"mcpfn-auth-test\", version: \"1.0.0\" },\n },\n }),\n ...configured,\n headers,\n });\n },\n };\n}\n\nexport const MCPFN_OAUTH_EXTENSION_GRANTS = {\n jwtBearer: \"urn:ietf:params:oauth:grant-type:jwt-bearer\",\n deviceCode: \"urn:ietf:params:oauth:grant-type:device_code\",\n generic: \"urn:example:params:oauth:grant-type:extension\",\n} as const;\n\nexport interface McpFnOAuthClientMetadata extends Record<string, unknown> {\n client_id: string;\n client_name?: string;\n redirect_uris: string[];\n response_types: string[];\n grant_types: string[];\n token_endpoint_auth_method: string;\n}\n\nexport interface McpFnOAuthClientMetadataFixtureOptions {\n clientId: string;\n redirectUris: string[];\n clientName?: string;\n extraGrantTypes?: string[];\n extraMetadata?: Record<string, unknown>;\n}\n\nexport interface McpFnOAuthClientMetadataVariants {\n basic: McpFnOAuthClientMetadata;\n jwtBearerExtension: McpFnOAuthClientMetadata;\n deviceCodeExtension: McpFnOAuthClientMetadata;\n genericExtension: McpFnOAuthClientMetadata;\n}\n\nexport interface McpFnNamedOAuthHostFixture {\n id: \"chatgpt\" | \"claude\";\n name: string;\n redirectUris: string[];\n responseTypes: [\"code\"];\n grantTypes: string[];\n tokenEndpointAuthMethod: \"none\";\n}\n\n/** Host-shaped fixtures; applications still configure their registered production URLs. */\nexport const MCPFN_NAMED_OAUTH_HOST_FIXTURES = {\n chatgpt: {\n id: \"chatgpt\",\n name: \"ChatGPT connector\",\n redirectUris: [\"https://chatgpt.com/connector_platform_oauth_redirect\"],\n responseTypes: [\"code\"],\n grantTypes: [\"authorization_code\", \"refresh_token\"],\n tokenEndpointAuthMethod: \"none\",\n },\n claude: {\n id: \"claude\",\n name: \"Claude connector\",\n redirectUris: [\"https://claude.example.com/oauth/callback\"],\n responseTypes: [\"code\"],\n grantTypes: [\n \"authorization_code\",\n \"refresh_token\",\n MCPFN_OAUTH_EXTENSION_GRANTS.jwtBearer,\n ],\n tokenEndpointAuthMethod: \"none\",\n },\n} as const satisfies Record<string, McpFnNamedOAuthHostFixture>;\n\nexport function createOAuthClientMetadataFixture(\n options: McpFnOAuthClientMetadataFixtureOptions,\n): McpFnOAuthClientMetadata {\n return {\n ...options.extraMetadata,\n client_id: new URL(options.clientId).toString(),\n client_name: options.clientName ?? \"McpFn OAuth test client\",\n redirect_uris: [...new Set(options.redirectUris.map((uri) => new URL(uri).toString()))],\n response_types: [\"code\"],\n grant_types: [\n \"authorization_code\",\n \"refresh_token\",\n ...new Set(options.extraGrantTypes ?? []),\n ],\n token_endpoint_auth_method: \"none\",\n };\n}\n\nexport function createOAuthClientMetadataVariants(\n baseUrl: string | URL,\n redirectUri = new URL(\"/callback\", baseUrl).toString(),\n): McpFnOAuthClientMetadataVariants {\n const base = new URL(baseUrl);\n const fixture = (name: string, extraGrantTypes: string[] = []) =>\n createOAuthClientMetadataFixture({\n clientId: new URL(`/client-metadata/${name}`, base).toString(),\n redirectUris: [redirectUri],\n clientName: `McpFn ${name} client`,\n extraGrantTypes,\n });\n return {\n basic: fixture(\"basic\"),\n jwtBearerExtension: fixture(\"jwt-bearer-extension\", [MCPFN_OAUTH_EXTENSION_GRANTS.jwtBearer]),\n deviceCodeExtension: fixture(\"device-code-extension\", [MCPFN_OAUTH_EXTENSION_GRANTS.deviceCode]),\n genericExtension: fixture(\"generic-extension\", [MCPFN_OAUTH_EXTENSION_GRANTS.generic]),\n };\n}\n\n/**\n * Validates compatibility with authorization-code + PKCE without applying a\n * closed-world allowlist to unrelated grant types advertised by the client.\n */\nexport function assertAuthorizationCodeClientMetadata(\n metadata: McpFnOAuthClientMetadata,\n expectedClientId?: string,\n): McpFnOAuthClientMetadata {\n if (expectedClientId && metadata.client_id !== new URL(expectedClientId).toString()) {\n throw new McpFnAuthAssertionError(\"OAuth client metadata client_id does not match its document URL\");\n }\n if (!metadata.response_types.includes(\"code\")) {\n throw new McpFnAuthAssertionError(\"OAuth client metadata does not support response_type=code\");\n }\n if (!metadata.grant_types.includes(\"authorization_code\")) {\n throw new McpFnAuthAssertionError(\"OAuth client metadata does not support authorization_code\");\n }\n if (!metadata.redirect_uris.length) {\n throw new McpFnAuthAssertionError(\"OAuth client metadata must declare at least one redirect URI\");\n }\n return metadata;\n}\n","import { randomUUID } from \"node:crypto\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\n\nimport type { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport { derivePkceS256Challenge, generatePkcePair } from \"@superfunctions/oauth-core\";\n\nimport {\n assertAuthorizationCodeClientMetadata,\n createOAuthClientMetadataVariants,\n type McpFnOAuthClientMetadataVariants,\n} from \"./auth-core.js\";\n\ninterface AuthorizationCodeRecord {\n clientId: string;\n redirectUri: string;\n codeChallenge: string;\n scopes: string[];\n resource?: string;\n expiresAt: number;\n used: boolean;\n}\n\ninterface AccessTokenRecord {\n clientId: string;\n scopes: string[];\n resource?: string;\n expiresAt: number;\n revoked: boolean;\n}\n\ninterface RefreshTokenRecord {\n clientId: string;\n scopes: string[];\n resource?: string;\n expiresAt: number;\n revoked: boolean;\n}\n\nexport interface McpFnMockOAuthServerOptions {\n issuer: string | URL;\n clientId?: string;\n redirectUris?: string[];\n scopesSupported?: string[];\n accessTokenLifetimeSeconds?: number;\n authorizationCodeLifetimeSeconds?: number;\n refreshTokenLifetimeSeconds?: number;\n clock?: () => number;\n}\n\nexport interface McpFnMockOAuthTokenSet {\n access_token: string;\n token_type: \"Bearer\";\n expires_in: number;\n refresh_token: string;\n scope: string;\n resource?: string;\n}\n\nexport interface McpFnPkcePair {\n verifier: string;\n challenge: string;\n method: \"S256\";\n}\n\nexport interface McpFnOAuthCallback {\n url: string;\n parameters: Record<string, string>;\n}\n\nexport function createPkcePair(): McpFnPkcePair {\n const pair = generatePkcePair(48);\n return {\n verifier: pair.codeVerifier,\n challenge: pair.codeChallenge,\n method: pair.codeChallengeMethod,\n };\n}\n\nfunction uniqueScopes(value: string | null | undefined): string[] {\n return [...new Set((value ?? \"\").split(/\\s+/).filter(Boolean))].sort();\n}\n\nfunction json(status: number, body: unknown): Response {\n return Response.json(body, {\n status,\n headers: { \"cache-control\": \"no-store\", pragma: \"no-cache\" },\n });\n}\n\nfunction oauthError(status: number, error: string, description: string): Response {\n return json(status, { error, error_description: description });\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replaceAll(\"&\", \"&\")\n .replaceAll('\"', \""\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\");\n}\n\nfunction formValue(form: URLSearchParams, name: string): string | undefined {\n const value = form.get(name);\n return value === null || value === \"\" ? undefined : value;\n}\n\nexport class McpFnMockOAuthAuthorizationServer {\n readonly issuer: URL;\n readonly clientId: string;\n readonly redirectUris: string[];\n readonly scopesSupported: string[];\n readonly clientMetadata: McpFnOAuthClientMetadataVariants;\n\n private readonly codes = new Map<string, AuthorizationCodeRecord>();\n private readonly accessTokens = new Map<string, AccessTokenRecord>();\n private readonly refreshTokens = new Map<string, RefreshTokenRecord>();\n private readonly callbacks: McpFnOAuthCallback[] = [];\n private readonly clock: () => number;\n private readonly accessTokenLifetimeSeconds: number;\n private readonly authorizationCodeLifetimeSeconds: number;\n private readonly refreshTokenLifetimeSeconds: number;\n\n constructor(options: McpFnMockOAuthServerOptions) {\n this.issuer = new URL(options.issuer);\n this.issuer.pathname = this.issuer.pathname.replace(/\\/?$/, \"/\");\n this.clientId = options.clientId ?? \"mcpfn-playwright\";\n this.redirectUris = options.redirectUris?.map((uri) => new URL(uri).toString()) ?? [\n new URL(\"callback\", this.issuer).toString(),\n ];\n this.scopesSupported = [...new Set(options.scopesSupported ?? [\"mcp:read\", \"mcp:write\"])].sort();\n this.clock = options.clock ?? Date.now;\n this.accessTokenLifetimeSeconds = options.accessTokenLifetimeSeconds ?? 300;\n this.authorizationCodeLifetimeSeconds = options.authorizationCodeLifetimeSeconds ?? 120;\n this.refreshTokenLifetimeSeconds = options.refreshTokenLifetimeSeconds ?? 3_600;\n this.clientMetadata = createOAuthClientMetadataVariants(\n this.issuer,\n this.redirectUris[0],\n );\n }\n\n get metadataUrl(): string {\n return new URL(\".well-known/oauth-authorization-server\", this.issuer).toString();\n }\n\n get authorizationEndpoint(): string {\n return new URL(\"authorize\", this.issuer).toString();\n }\n\n get tokenEndpoint(): string {\n return new URL(\"token\", this.issuer).toString();\n }\n\n get revocationEndpoint(): string {\n return new URL(\"revoke\", this.issuer).toString();\n }\n\n get callbackUrl(): string {\n return this.redirectUris[0];\n }\n\n clientMetadataUrl(\n variant: keyof McpFnOAuthClientMetadataVariants,\n ): string {\n return this.clientMetadata[variant].client_id;\n }\n\n authorizationUrl(input: {\n clientId?: string;\n redirectUri?: string;\n codeChallenge: string;\n state?: string;\n scopes?: string[];\n resource?: string;\n extraParameters?: Record<string, string>;\n }): string {\n const url = new URL(this.authorizationEndpoint);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"client_id\", input.clientId ?? this.clientId);\n url.searchParams.set(\"redirect_uri\", input.redirectUri ?? this.callbackUrl);\n url.searchParams.set(\"code_challenge\", input.codeChallenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n url.searchParams.set(\"scope\", (input.scopes ?? [\"mcp:read\"]).join(\" \"));\n if (input.state) url.searchParams.set(\"state\", input.state);\n if (input.resource) url.searchParams.set(\"resource\", input.resource);\n for (const [name, value] of Object.entries(input.extraParameters ?? {})) {\n url.searchParams.set(name, value);\n }\n return url.toString();\n }\n\n latestCallback(): McpFnOAuthCallback | undefined {\n return this.callbacks.at(-1);\n }\n\n expireAccessToken(token: string): void {\n const record = this.accessTokens.get(token);\n if (record) record.expiresAt = this.nowSeconds() - 1;\n }\n\n revokeToken(token: string): void {\n const access = this.accessTokens.get(token);\n if (access) access.revoked = true;\n const refresh = this.refreshTokens.get(token);\n if (refresh) refresh.revoked = true;\n }\n\n async verifyAccessToken(token: string): Promise<AuthInfo> {\n const record = this.accessTokens.get(token);\n if (!record || record.revoked || record.expiresAt <= this.nowSeconds()) {\n throw new Error(\"Invalid access token\");\n }\n return {\n token,\n clientId: record.clientId,\n scopes: record.scopes,\n expiresAt: record.expiresAt,\n ...(record.resource ? { resource: new URL(record.resource) } : {}),\n };\n }\n\n async handle(request: Request): Promise<Response> {\n const url = new URL(request.url);\n const path = url.pathname.replace(this.issuer.pathname.replace(/\\/$/, \"\"), \"\") || \"/\";\n if (request.method === \"GET\" && path === \"/.well-known/oauth-authorization-server\") {\n return json(200, {\n issuer: this.issuer.toString(),\n authorization_endpoint: this.authorizationEndpoint,\n token_endpoint: this.tokenEndpoint,\n revocation_endpoint: this.revocationEndpoint,\n response_types_supported: [\"code\"],\n grant_types_supported: [\"authorization_code\", \"refresh_token\"],\n code_challenge_methods_supported: [\"S256\"],\n token_endpoint_auth_methods_supported: [\"none\"],\n scopes_supported: this.scopesSupported,\n client_id_metadata_document_supported: true,\n });\n }\n\n if (request.method === \"GET\" && path.startsWith(\"/client-metadata/\")) {\n const metadata = Object.values(this.clientMetadata)\n .find((candidate) => new URL(candidate.client_id).pathname === url.pathname);\n return metadata ? json(200, metadata) : json(404, { error: \"not_found\" });\n }\n\n if (request.method === \"GET\" && path === \"/authorize\") {\n return this.authorize(url);\n }\n if (request.method === \"POST\" && path === \"/token\") {\n return this.token(await request.text());\n }\n if (request.method === \"POST\" && path === \"/revoke\") {\n return this.revoke(await request.text());\n }\n if (request.method === \"GET\" && path === \"/callback\") {\n const parameters = Object.fromEntries(url.searchParams);\n this.callbacks.push({ url: url.toString(), parameters });\n return new Response(\n `<!doctype html><html><body><main><h1>OAuth callback received</h1><pre>${escapeHtml(JSON.stringify(parameters, null, 2))}</pre></main></body></html>`,\n { headers: { \"content-type\": \"text/html; charset=utf-8\" } },\n );\n }\n return json(404, { error: \"not_found\" });\n }\n\n private nowSeconds(): number {\n return Math.floor(this.clock() / 1_000);\n }\n\n private resolveClient(clientId: string): { clientId: string; redirectUris: string[] } | undefined {\n if (clientId === this.clientId) {\n return { clientId, redirectUris: this.redirectUris };\n }\n const metadata = Object.values(this.clientMetadata)\n .find((candidate) => candidate.client_id === clientId);\n if (!metadata) return undefined;\n assertAuthorizationCodeClientMetadata(metadata, clientId);\n return { clientId, redirectUris: metadata.redirect_uris };\n }\n\n private authorize(url: URL): Response {\n const clientId = url.searchParams.get(\"client_id\") ?? \"\";\n const redirectUri = url.searchParams.get(\"redirect_uri\") ?? \"\";\n const client = this.resolveClient(clientId);\n if (!client) return oauthError(400, \"invalid_client\", \"Unknown OAuth client\");\n if (!client.redirectUris.includes(redirectUri)) {\n return oauthError(400, \"invalid_request\", \"redirect_uri is not registered\");\n }\n if (url.searchParams.get(\"response_type\") !== \"code\") {\n return this.authorizationRedirect(url, redirectUri, \"unsupported_response_type\");\n }\n const codeChallenge = url.searchParams.get(\"code_challenge\");\n if (!codeChallenge || url.searchParams.get(\"code_challenge_method\") !== \"S256\") {\n return this.authorizationRedirect(url, redirectUri, \"invalid_request\", \"PKCE S256 is required\");\n }\n const requestedScopes = uniqueScopes(url.searchParams.get(\"scope\"));\n if (requestedScopes.some((scope) => !this.scopesSupported.includes(scope))) {\n return this.authorizationRedirect(url, redirectUri, \"invalid_scope\");\n }\n const decision = url.searchParams.get(\"decision\");\n if (!decision) {\n const hidden = [...url.searchParams]\n .filter(([name]) => name !== \"decision\")\n .map(([name, value]) => `<input type=\"hidden\" name=\"${escapeHtml(name)}\" value=\"${escapeHtml(value)}\">`)\n .join(\"\");\n return new Response(\n `<!doctype html><html><body><main><h1>Authorize MCP client</h1><p>${escapeHtml(clientId)}</p><form method=\"get\" action=\"${escapeHtml(this.authorizationEndpoint)}\">${hidden}<button name=\"decision\" value=\"approve\">Approve</button><button name=\"decision\" value=\"deny\">Deny</button></form></main></body></html>`,\n { headers: { \"content-type\": \"text/html; charset=utf-8\", \"cache-control\": \"no-store\" } },\n );\n }\n if (decision === \"deny\") {\n return this.authorizationRedirect(url, redirectUri, \"access_denied\");\n }\n if (decision !== \"approve\") {\n return oauthError(400, \"invalid_request\", \"Unknown authorization decision\");\n }\n const code = `mcpfn_code_${randomUUID()}`;\n this.codes.set(code, {\n clientId,\n redirectUri,\n codeChallenge,\n scopes: requestedScopes,\n resource: url.searchParams.get(\"resource\") ?? undefined,\n expiresAt: this.nowSeconds() + this.authorizationCodeLifetimeSeconds,\n used: false,\n });\n const callback = new URL(redirectUri);\n callback.searchParams.set(\"code\", code);\n const state = url.searchParams.get(\"state\");\n if (state) callback.searchParams.set(\"state\", state);\n return Response.redirect(callback, 302);\n }\n\n private authorizationRedirect(\n requestUrl: URL,\n redirectUri: string,\n error: string,\n description?: string,\n ): Response {\n const callback = new URL(redirectUri);\n callback.searchParams.set(\"error\", error);\n if (description) callback.searchParams.set(\"error_description\", description);\n const state = requestUrl.searchParams.get(\"state\");\n if (state) callback.searchParams.set(\"state\", state);\n return Response.redirect(callback, 302);\n }\n\n private token(source: string): Response {\n const form = new URLSearchParams(source);\n const grantType = formValue(form, \"grant_type\");\n if (grantType === \"authorization_code\") return this.exchangeAuthorizationCode(form);\n if (grantType === \"refresh_token\") return this.exchangeRefreshToken(form);\n return oauthError(400, \"unsupported_grant_type\", \"The grant type is not supported\");\n }\n\n private exchangeAuthorizationCode(form: URLSearchParams): Response {\n const code = formValue(form, \"code\");\n const record = code ? this.codes.get(code) : undefined;\n if (!record || record.used || record.expiresAt <= this.nowSeconds()) {\n return oauthError(400, \"invalid_grant\", \"Authorization code is invalid or expired\");\n }\n if (\n formValue(form, \"client_id\") !== record.clientId ||\n formValue(form, \"redirect_uri\") !== record.redirectUri\n ) {\n return oauthError(400, \"invalid_grant\", \"Authorization code binding does not match\");\n }\n const verifier = formValue(form, \"code_verifier\");\n const challenge = verifier ? derivePkceS256Challenge(verifier) : undefined;\n if (challenge !== record.codeChallenge) {\n return oauthError(400, \"invalid_grant\", \"PKCE verification failed\");\n }\n record.used = true;\n return json(200, this.issueTokenSet(record));\n }\n\n private exchangeRefreshToken(form: URLSearchParams): Response {\n const refreshToken = formValue(form, \"refresh_token\");\n const record = refreshToken ? this.refreshTokens.get(refreshToken) : undefined;\n if (!record || record.revoked || record.expiresAt <= this.nowSeconds()) {\n return oauthError(400, \"invalid_grant\", \"Refresh token is invalid or expired\");\n }\n if (formValue(form, \"client_id\") !== record.clientId) {\n return oauthError(400, \"invalid_grant\", \"Refresh token client binding does not match\");\n }\n const requestedScopes = form.has(\"scope\")\n ? uniqueScopes(form.get(\"scope\"))\n : record.scopes;\n if (requestedScopes.some((scope) => !record.scopes.includes(scope))) {\n return oauthError(400, \"invalid_scope\", \"Refresh cannot increase granted scopes\");\n }\n record.revoked = true;\n return json(200, this.issueTokenSet({ ...record, scopes: requestedScopes }));\n }\n\n private issueTokenSet(\n input: Pick<AccessTokenRecord, \"clientId\" | \"scopes\" | \"resource\">,\n ): McpFnMockOAuthTokenSet {\n const accessToken = `mcpfn_access_${randomUUID()}`;\n const refreshToken = `mcpfn_refresh_${randomUUID()}`;\n this.accessTokens.set(accessToken, {\n ...input,\n expiresAt: this.nowSeconds() + this.accessTokenLifetimeSeconds,\n revoked: false,\n });\n this.refreshTokens.set(refreshToken, {\n ...input,\n expiresAt: this.nowSeconds() + this.refreshTokenLifetimeSeconds,\n revoked: false,\n });\n return {\n access_token: accessToken,\n token_type: \"Bearer\",\n expires_in: this.accessTokenLifetimeSeconds,\n refresh_token: refreshToken,\n scope: input.scopes.join(\" \"),\n ...(input.resource ? { resource: input.resource } : {}),\n };\n }\n\n private revoke(source: string): Response {\n const token = new URLSearchParams(source).get(\"token\");\n if (token) this.revokeToken(token);\n return new Response(null, { status: 200 });\n }\n}\n\nexport interface McpFnStartedMockOAuthServer {\n origin: string;\n oauth: McpFnMockOAuthAuthorizationServer;\n close(): Promise<void>;\n}\n\nexport interface McpFnStartMockOAuthServerOptions\n extends Omit<McpFnMockOAuthServerOptions, \"issuer\"> {\n hostname?: string;\n port?: number;\n /** Optional same-origin route used to compose a protected MCP fixture. */\n handle?(\n request: Request,\n oauth: McpFnMockOAuthAuthorizationServer,\n ): Promise<Response | undefined> | Response | undefined;\n}\n\nasync function toRequest(req: IncomingMessage, origin: string): Promise<Request> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) chunks.push(Buffer.from(chunk));\n const headers = new Headers();\n for (const [name, value] of Object.entries(req.headers)) {\n if (Array.isArray(value)) {\n for (const entry of value) headers.append(name, entry);\n } else if (value !== undefined) {\n headers.set(name, value);\n }\n }\n const body = chunks.length ? Buffer.concat(chunks) : undefined;\n const init: RequestInit & { duplex?: \"half\" } = {\n method: req.method,\n headers,\n ...(body ? { body, duplex: \"half\" } : {}),\n };\n return new Request(new URL(req.url ?? \"/\", origin), init);\n}\n\nasync function writeResponse(res: ServerResponse, response: Response): Promise<void> {\n res.statusCode = response.status;\n response.headers.forEach((value, name) => res.setHeader(name, value));\n res.end(Buffer.from(await response.arrayBuffer()));\n}\n\nexport async function startMockOAuthAuthorizationServer(\n options: McpFnStartMockOAuthServerOptions = {},\n): Promise<McpFnStartedMockOAuthServer> {\n let oauth: McpFnMockOAuthAuthorizationServer | undefined;\n let origin = \"\";\n const server = createServer(async (req, res) => {\n try {\n if (!oauth) throw new Error(\"Mock OAuth server is not initialized\");\n const request = await toRequest(req, origin);\n const custom = await options.handle?.(request.clone(), oauth);\n await writeResponse(res, custom ?? await oauth.handle(request));\n } catch {\n res.statusCode = 500;\n res.setHeader(\"content-type\", \"application/json\");\n res.end(JSON.stringify({\n error: \"server_error\",\n error_description: \"Internal Server Error\",\n }));\n }\n });\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(options.port ?? 0, options.hostname ?? \"127.0.0.1\", () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n const address = server.address() as AddressInfo;\n origin = `http://${address.address.includes(\":\") ? `[${address.address}]` : address.address}:${address.port}`;\n oauth = new McpFnMockOAuthAuthorizationServer({ ...options, issuer: origin });\n return {\n origin,\n oauth,\n close: () => new Promise<void>((resolve, reject) => {\n server.close((error) => error ? reject(error) : resolve());\n }),\n };\n}\n","import {\n createMcpFnClient,\n customTarget,\n type McpFnClient,\n type McpFnClientEventSink,\n type McpFnClientMediatedHandlers,\n type McpFnDiagnosticSink,\n type McpFnTarget,\n} from \"@mcpfn/client\";\nimport { InMemoryTransport } from \"@modelcontextprotocol/sdk/inMemory.js\";\nimport type { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type { RequestOptions } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n CallToolResult,\n ClientCapabilities,\n CompleteRequest,\n CompleteResult,\n CreateTaskResult,\n GetPromptResult,\n Implementation,\n ListTasksResult,\n Prompt,\n ReadResourceResult,\n Resource,\n ResourceTemplate,\n Task,\n Tool,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { McpFnServer } from \"@mcpfn/core\";\n\nexport interface McpFnTestClientOptions {\n capabilities?: ClientCapabilities;\n handlers?: McpFnClientMediatedHandlers;\n events?: McpFnClientEventSink;\n /** Install roots, sampling, elicitation, or notification handlers before initialize. */\n configure?(client: Client): void | Promise<void>;\n diagnostics?: McpFnDiagnosticSink;\n}\n\nconst testClientCleanupOwners = new WeakMap<\n McpFnTestClientCleanupError,\n { close: () => Promise<void>; pending?: Promise<void> }\n>();\n\n/** Test-client cleanup failed and remains owned by this retryable error. */\nexport class McpFnTestClientCleanupError extends Error {\n constructor(close: () => Promise<void>, cause: unknown) {\n super(\n \"Test client cleanup remains pending; retain this error and retryCleanup()\",\n { cause },\n );\n this.name = \"McpFnTestClientCleanupError\";\n testClientCleanupOwners.set(this, { close });\n }\n\n retryCleanup(): Promise<void> {\n const owner = testClientCleanupOwners.get(this);\n if (!owner) return Promise.resolve();\n if (owner.pending) return owner.pending;\n const pending = Promise.resolve().then(owner.close).then(\n () => { testClientCleanupOwners.delete(this); },\n () => { throw this; },\n ).finally(() => { owner.pending = undefined; });\n owner.pending = pending;\n return pending;\n }\n}\n\nexport class McpFnTestClient<TContext = undefined> {\n readonly session: McpFnClient;\n\n private constructor(session: McpFnClient) {\n this.session = session;\n }\n\n get client(): Client {\n return this.session.protocol;\n }\n\n static async connect<TContext>(\n server: McpFnServer<TContext>,\n info = { name: \"mcpfn-test-client\", version: \"1.0.0\" },\n options: McpFnTestClientOptions = {},\n ): Promise<McpFnTestClient<TContext>> {\n const serverName = (server as McpFnServer<TContext> & { info?: { name?: string } })\n .info?.name ?? \"mcpfn-server\";\n return this.connectTarget<TContext>(customTarget({\n kind: \"in-memory\",\n descriptor: { server: serverName },\n open: async () => {\n const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();\n await server.connect(serverTransport);\n return { transport: clientTransport, close: () => server.close() };\n },\n }), info, options);\n }\n\n /** Create the session owner before connecting, so failed initialization remains closeable. */\n static createTarget<TContext = undefined>(\n target: McpFnTarget,\n info?: Implementation,\n options: McpFnTestClientOptions = {},\n ): McpFnTestClient<TContext> {\n return new McpFnTestClient<TContext>(createMcpFnClient({\n target,\n info: info ?? { name: \"mcpfn-test-client\", version: \"1.0.0\" },\n capabilities: options.capabilities,\n handlers: options.handlers,\n events: options.events,\n configure: options.configure,\n diagnostics: options.diagnostics,\n }));\n }\n\n static async connectTarget<TContext = undefined>(\n target: McpFnTarget,\n info?: Implementation,\n options: McpFnTestClientOptions = {},\n ): Promise<McpFnTestClient<TContext>> {\n const client = this.createTarget<TContext>(target, info, options);\n try {\n await client.session.connect();\n return client;\n } catch (error) {\n const connectionFailure = error instanceof Error && error.cause !== undefined\n ? error.cause\n : error;\n try { await client.session.close(); }\n catch { throw new McpFnTestClientCleanupError(() => client.session.close(), connectionFailure); }\n throw error;\n }\n }\n\n listTools(options?: RequestOptions): Promise<Tool[]> { return this.session.tools.listAll(options); }\n callTool(\n name: string,\n args: Record<string, unknown> = {},\n options?: RequestOptions,\n ): Promise<CallToolResult> {\n return this.session.tools.call(name, args, options);\n }\n createToolTask(\n name: string,\n args: Record<string, unknown> = {},\n task: { ttl?: number } = {},\n options?: RequestOptions,\n ): Promise<CreateTaskResult> {\n return this.session.tools.createTask(name, args, task, options);\n }\n getTask(taskId: string, options?: RequestOptions): Promise<Task> {\n return this.session.tasks.get(taskId, options);\n }\n getTaskResult(taskId: string, options?: RequestOptions): Promise<CallToolResult> {\n return this.session.tasks.result(taskId, options);\n }\n listTasks(cursor?: string, options?: RequestOptions): Promise<ListTasksResult> {\n return this.session.tasks.list(cursor, options);\n }\n cancelTask(taskId: string, options?: RequestOptions): Promise<Task> {\n return this.session.tasks.cancel(taskId, options);\n }\n listResources(options?: RequestOptions): Promise<Resource[]> {\n return this.session.resources.listAll(options);\n }\n listResourceTemplates(options?: RequestOptions): Promise<ResourceTemplate[]> {\n return this.session.resources.listTemplatesAll(options);\n }\n readResource(uri: string, options?: RequestOptions): Promise<ReadResourceResult> {\n return this.session.resources.read(uri, options);\n }\n subscribeResource(uri: string, options?: RequestOptions): Promise<void> {\n return this.session.resources.subscribe(uri, options);\n }\n unsubscribeResource(uri: string, options?: RequestOptions): Promise<void> {\n return this.session.resources.unsubscribe(uri, options);\n }\n listPrompts(options?: RequestOptions): Promise<Prompt[]> {\n return this.session.prompts.listAll(options);\n }\n getPrompt(\n name: string,\n args?: Record<string, string>,\n options?: RequestOptions,\n ): Promise<GetPromptResult> {\n return this.session.prompts.get(name, args, options);\n }\n complete(params: CompleteRequest[\"params\"], options?: RequestOptions): Promise<CompleteResult> {\n return this.session.prompts.complete(params, options);\n }\n async close(): Promise<void> {\n try { await this.session.close(); }\n catch (error) {\n throw new McpFnTestClientCleanupError(() => this.session.close(), error);\n }\n }\n}\n","import { createHash } from \"node:crypto\";\n\nimport Ajv from \"ajv\";\nimport Ajv2019 from \"ajv/dist/2019.js\";\nimport Ajv2020 from \"ajv/dist/2020.js\";\nimport type {\n CallToolResult,\n ClientCapabilities,\n Implementation,\n Tool,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { McpFnSchemaIssue } from \"@mcpfn/core\";\nimport type { McpFnTarget } from \"@mcpfn/client\";\nimport { redactOAuthValue } from \"@superfunctions/oauth-core\";\n\nimport { stableJson } from \"./assertions.js\";\nimport { McpFnTestClient, McpFnTestClientCleanupError, type McpFnTestClientOptions } from \"./client.js\";\n\nexport type McpFnFixtureSideEffect =\n | \"read-only\"\n | \"idempotent\"\n | \"non-idempotent\";\n\nexport interface McpFnClientProfileFixtureExpectation {\n isError?: boolean;\n structuredContent?: Record<string, unknown>;\n errorCode?: string;\n lifecycleStage?: string;\n validationIssue?: Partial<\n Pick<\n McpFnSchemaIssue,\n | \"instancePath\"\n | \"schemaPath\"\n | \"keyword\"\n | \"rejectedProperty\"\n | \"missingProperty\"\n >\n >;\n}\n\nexport interface McpFnClientProfileFixture {\n name: string;\n tool: string;\n /** Values are executed but never copied into compatibility reports. */\n arguments?: Record<string, unknown>;\n sideEffect: McpFnFixtureSideEffect;\n source?: \"minimal-valid\" | \"captured-failure\";\n expect?: McpFnClientProfileFixtureExpectation;\n}\n\nexport interface McpFnSchemaPortabilityPolicy {\n /** Treat otherwise-valid compatibility-reducing keywords as failures. */\n warningsAsErrors?: boolean;\n /** Suppress warnings for explicitly reviewed keywords. */\n allowKeywords?: readonly string[];\n}\n\nexport interface McpFnSchemaPortabilityIssue {\n severity: \"error\" | \"warning\";\n code:\n | \"schema-invalid\"\n | \"schema-dialect-unsupported\"\n | \"schema-portability-warning\";\n path: string;\n keyword?: string;\n message: string;\n}\n\nexport interface McpFnClientProfileSnapshotTool {\n name: string;\n hash: string;\n}\n\nexport interface McpFnClientProfileSnapshot {\n formatVersion: 1;\n kind: \"mcpfn.client-profile-snapshot\";\n profile: { id: string; version: string };\n catalogHash: string;\n tools: McpFnClientProfileSnapshotTool[];\n}\n\nexport interface McpFnClientProfileSnapshotChange {\n kind: \"added\" | \"removed\" | \"modified\";\n tool: string;\n beforeHash?: string;\n afterHash?: string;\n}\n\nexport interface McpFnClientProfileSnapshotDiff {\n compatible: boolean;\n changes: McpFnClientProfileSnapshotChange[];\n summary: { added: number; removed: number; modified: number };\n}\n\nexport interface McpFnClientProfileContractCase {\n id: string;\n version: string;\n target: McpFnTarget;\n clientInfo?: Implementation;\n capabilities?: ClientCapabilities;\n client?: Omit<McpFnTestClientOptions, \"capabilities\">;\n fixtures?: readonly McpFnClientProfileFixture[];\n expectedSnapshot?: McpFnClientProfileSnapshot;\n portability?: McpFnSchemaPortabilityPolicy;\n}\n\nexport interface RunMcpFnClientProfileContractsOptions {\n profiles: readonly McpFnClientProfileContractCase[];\n /** Explicit opt-in for fixtures that could mutate state. Defaults to false. */\n allowSideEffects?: boolean;\n /** Aggregate JSON size cap. Defaults to 1 MiB. */\n maxReportBytes?: number;\n}\n\nexport interface McpFnClientProfileFixtureResult {\n name: string;\n tool: string;\n source: \"minimal-valid\" | \"captured-failure\";\n status: \"passed\" | \"failed\" | \"incomplete\";\n code?: string;\n error?: string;\n}\n\nexport interface McpFnClientProfileContractResult {\n profile: { id: string; version: string };\n status: \"complete\" | \"incomplete\";\n ok: boolean;\n phase?: \"connect\" | \"catalog\" | \"fixtures\" | \"close\";\n snapshot?: McpFnClientProfileSnapshot;\n snapshotMatches?: boolean;\n portability: McpFnSchemaPortabilityIssue[];\n fixtures: McpFnClientProfileFixtureResult[];\n error?: string;\n}\n\nexport interface McpFnClientProfileContractReport {\n formatVersion: 1;\n kind: \"mcpfn.client-profile-contract-report\";\n status: \"complete\" | \"incomplete\";\n ok: boolean;\n profiles: McpFnClientProfileContractResult[];\n droppedProfiles: number;\n incompleteReason?: string;\n}\n\n/** A complete bounded report with retry ownership for unfinished target cleanup. */\nexport class McpFnClientProfileContractCleanupError extends Error {\n constructor(\n readonly report: McpFnClientProfileContractReport,\n private readonly owners: readonly McpFnTestClientCleanupError[],\n ) {\n super(\"Client profile target cleanup remains pending; retain this error and retryCleanup()\");\n this.name = \"McpFnClientProfileContractCleanupError\";\n }\n\n async retryCleanup(): Promise<void> {\n const results = await Promise.allSettled(this.owners.map(owner => owner.retryCleanup()));\n if (results.some(result => result.status === \"rejected\")) throw this;\n }\n}\n\nclass ProfileCaseCleanupError extends Error {\n constructor(readonly owner: McpFnTestClientCleanupError, readonly result: McpFnClientProfileContractResult) {\n super(\"Client profile target cleanup remains pending\");\n }\n}\n\nconst PORTABILITY_KEYWORDS = new Set([\n \"$anchor\",\n \"$recursiveAnchor\",\n \"$recursiveRef\",\n \"$dynamicAnchor\",\n \"$dynamicRef\",\n \"dependentSchemas\",\n \"dependentRequired\",\n \"minContains\",\n \"maxContains\",\n \"prefixItems\",\n \"unevaluatedItems\",\n \"unevaluatedProperties\",\n]);\n\nfunction hash(value: unknown): string {\n return createHash(\"sha256\").update(stableJson(value)).digest(\"hex\");\n}\n\nfunction boundedError(value: unknown): string {\n const redacted = String(\n redactOAuthValue(value instanceof Error ? value.message : value),\n );\n return redacted.slice(0, 512);\n}\n\nfunction assertProfileReference(id: string, version: string): void {\n for (const [label, value] of [\n [\"id\", id],\n [\"version\", version],\n ] as const) {\n if (typeof value !== \"string\" || !value || value.length > 128 || !/^[A-Za-z0-9._/-]+$/.test(value)) {\n throw new Error(\n `Client profile ${label} must be a non-empty stable identifier`,\n );\n }\n }\n}\n\nexport function createMcpFnClientProfileSnapshot(\n profile: { id: string; version: string },\n tools: readonly Tool[],\n): McpFnClientProfileSnapshot {\n assertProfileReference(profile.id, profile.version);\n const normalized = [...tools]\n .map((tool) => structuredClone(tool))\n .sort((left, right) =>\n left.name < right.name ? -1 : left.name > right.name ? 1 : 0,\n );\n if (normalized.some((tool, index) => index > 0 && tool.name === normalized[index - 1].name)) {\n throw new Error(\"Effective catalog contains duplicate tool names\");\n }\n return {\n formatVersion: 1,\n kind: \"mcpfn.client-profile-snapshot\",\n profile: { id: profile.id, version: profile.version },\n catalogHash: hash(normalized),\n tools: normalized.map((tool) => ({ name: tool.name, hash: hash(tool) })),\n };\n}\n\nfunction assertSnapshotFields(value: unknown, fields: readonly string[], location: string): void {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(`Client profile snapshot ${location} must be an object`);\n }\n const key = Object.keys(value).find(key => !fields.includes(key));\n if (key !== undefined) {\n throw new Error(`Client profile snapshot contains unsupported fields at ${location}: ${JSON.stringify(key.slice(0, 128))}`);\n }\n}\n\nexport function validateMcpFnClientProfileSnapshot(\n value: unknown,\n): McpFnClientProfileSnapshot {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(\"Client profile snapshot must be an object\");\n }\n assertSnapshotFields(value, [\"formatVersion\", \"kind\", \"profile\", \"catalogHash\", \"tools\"], \"root\");\n const snapshot = value as Partial<McpFnClientProfileSnapshot>;\n if (\n snapshot.formatVersion !== 1 ||\n snapshot.kind !== \"mcpfn.client-profile-snapshot\"\n ) {\n throw new Error(\"Unsupported client profile snapshot format\");\n }\n if (!snapshot.profile)\n throw new Error(\"Client profile snapshot requires profile metadata\");\n assertSnapshotFields(snapshot.profile, [\"id\", \"version\"], \"profile\");\n assertProfileReference(snapshot.profile.id, snapshot.profile.version);\n if (\n typeof snapshot.catalogHash !== \"string\" ||\n !/^[a-f0-9]{64}$/.test(snapshot.catalogHash)\n ) {\n throw new Error(\"Client profile snapshot requires a SHA-256 catalogHash\");\n }\n if (!Array.isArray(snapshot.tools))\n throw new Error(\"Client profile snapshot tools must be an array\");\n let prior = \"\";\n for (const [index, tool] of snapshot.tools.entries()) {\n assertSnapshotFields(tool, [\"name\", \"hash\"], `tools[${index}]`);\n if (\n !tool ||\n typeof tool.name !== \"string\" ||\n !tool.name ||\n !/^[a-f0-9]{64}$/.test(tool.hash)\n ) {\n throw new Error(\"Client profile snapshot contains an invalid tool entry\");\n }\n if (tool.name <= prior)\n throw new Error(\n \"Client profile snapshot tools must be sorted and unique\",\n );\n prior = tool.name;\n }\n return snapshot as McpFnClientProfileSnapshot;\n}\n\nexport function diffMcpFnClientProfileSnapshots(\n beforeValue: unknown,\n afterValue: unknown,\n): McpFnClientProfileSnapshotDiff {\n const before = validateMcpFnClientProfileSnapshot(beforeValue);\n const after = validateMcpFnClientProfileSnapshot(afterValue);\n if (before.profile.id !== after.profile.id) {\n throw new Error(\"Cannot diff snapshots for different client profile ids\");\n }\n const beforeByName = new Map(\n before.tools.map((tool) => [tool.name, tool.hash]),\n );\n const afterByName = new Map(\n after.tools.map((tool) => [tool.name, tool.hash]),\n );\n const names = [\n ...new Set([...beforeByName.keys(), ...afterByName.keys()]),\n ].sort((left, right) => left < right ? -1 : left > right ? 1 : 0);\n const changes: McpFnClientProfileSnapshotChange[] = [];\n for (const tool of names) {\n const beforeHash = beforeByName.get(tool);\n const afterHash = afterByName.get(tool);\n if (!beforeHash) changes.push({ kind: \"added\", tool, afterHash });\n else if (!afterHash) changes.push({ kind: \"removed\", tool, beforeHash });\n else if (beforeHash !== afterHash) {\n changes.push({ kind: \"modified\", tool, beforeHash, afterHash });\n }\n }\n if ((changes.length === 0) !== (before.catalogHash === after.catalogHash)) {\n throw new Error(\"Inconsistent catalog hashes for tool entries\");\n }\n const summary = {\n added: changes.filter(({ kind }) => kind === \"added\").length,\n removed: changes.filter(({ kind }) => kind === \"removed\").length,\n modified: changes.filter(({ kind }) => kind === \"modified\").length,\n };\n return { compatible: summary.removed === 0, changes, summary };\n}\n\nfunction createDialectValidator(dialect: string) {\n const normalized = dialect.replace(/#$/, \"\");\n if (\n normalized === \"http://json-schema.org/draft-07/schema\" ||\n normalized === \"https://json-schema.org/draft-07/schema\"\n )\n return new Ajv({ allErrors: true, strict: false, validateFormats: false });\n if (\n normalized === \"http://json-schema.org/draft/2019-09/schema\" ||\n normalized === \"https://json-schema.org/draft/2019-09/schema\"\n )\n return new Ajv2019({\n allErrors: true,\n strict: false,\n validateFormats: false,\n });\n if (\n normalized === \"http://json-schema.org/draft/2020-12/schema\" ||\n normalized === \"https://json-schema.org/draft/2020-12/schema\"\n )\n return new Ajv2020({\n allErrors: true,\n strict: false,\n validateFormats: false,\n });\n return undefined;\n}\n\nfunction pointerSegment(value: string): string {\n return value.replaceAll(\"~\", \"~0\").replaceAll(\"/\", \"~1\");\n}\n\nfunction walkSchema(\n value: unknown,\n path: string,\n visit: (keyword: string, path: string, schema: Record<string, unknown>) => void,\n): void {\n if (!value || typeof value !== \"object\") return;\n const schema = value as Record<string, unknown>;\n for (const keyword of Object.keys(schema)) {\n visit(keyword, `${path}/${pointerSegment(keyword)}`, schema);\n }\n for (const mapKeyword of [\n \"$defs\",\n \"definitions\",\n \"dependencies\",\n \"dependentSchemas\",\n \"patternProperties\",\n \"properties\",\n ]) {\n const entries = schema[mapKeyword];\n if (!entries || typeof entries !== \"object\" || Array.isArray(entries))\n continue;\n for (const [name, child] of Object.entries(\n entries as Record<string, unknown>,\n )) {\n walkSchema(child, `${path}/${mapKeyword}/${pointerSegment(name)}`, visit);\n }\n }\n for (const arrayKeyword of [\"allOf\", \"anyOf\", \"oneOf\", \"prefixItems\", \"items\"]) {\n const entries = schema[arrayKeyword];\n if (!Array.isArray(entries)) continue;\n entries.forEach((child, index) =>\n walkSchema(child, `${path}/${arrayKeyword}/${index}`, visit),\n );\n }\n for (const schemaKeyword of [\n \"additionalItems\",\n \"additionalProperties\",\n \"contains\",\n \"contentSchema\",\n \"else\",\n \"if\",\n \"items\",\n \"not\",\n \"propertyNames\",\n \"then\",\n \"unevaluatedItems\",\n \"unevaluatedProperties\",\n ]) {\n const child = schema[schemaKeyword];\n if (child && typeof child === \"object\" && !Array.isArray(child)) {\n walkSchema(child, `${path}/${schemaKeyword}`, visit);\n }\n }\n}\n\nexport function validateMcpFnSchemaPortability(\n schema: unknown,\n path: string,\n policy: McpFnSchemaPortabilityPolicy = {},\n): McpFnSchemaPortabilityIssue[] {\n if (!schema || typeof schema !== \"object\" || Array.isArray(schema)) {\n return [\n {\n severity: \"error\",\n code: \"schema-invalid\",\n path,\n message: \"Tool schema must be an object\",\n },\n ];\n }\n const declared = (schema as Record<string, unknown>).$schema;\n const dialect =\n typeof declared === \"string\"\n ? declared\n : \"http://json-schema.org/draft-07/schema#\";\n const validator = createDialectValidator(dialect);\n if (!validator) {\n return [\n {\n severity: \"error\",\n code: \"schema-dialect-unsupported\",\n path: `${path}/$schema`,\n message: boundedError(`Unsupported JSON Schema dialect ${dialect}`),\n },\n ];\n }\n const issues: McpFnSchemaPortabilityIssue[] = [];\n try {\n validator.compile(schema);\n } catch (error) {\n issues.push({\n severity: \"error\",\n code: \"schema-invalid\",\n path,\n message: boundedError(error),\n });\n }\n const allowed = new Set(policy.allowKeywords ?? []);\n const modernDialect = /draft\\/(2019-09|2020-12)\\/schema#?$/.test(dialect);\n const assertionKeywords = new Set([\n \"type\", \"enum\", \"const\", \"multipleOf\", \"maximum\", \"exclusiveMaximum\", \"minimum\", \"exclusiveMinimum\",\n \"maxLength\", \"minLength\", \"pattern\", \"format\", \"maxItems\", \"minItems\", \"uniqueItems\", \"contains\",\n \"minContains\", \"maxContains\", \"maxProperties\", \"minProperties\", \"required\", \"dependentRequired\",\n \"properties\", \"patternProperties\", \"additionalProperties\", \"propertyNames\", \"dependentSchemas\",\n \"items\", \"prefixItems\", \"additionalItems\", \"unevaluatedItems\", \"unevaluatedProperties\",\n \"allOf\", \"anyOf\", \"oneOf\", \"not\", \"if\", \"then\", \"else\",\n ]);\n walkSchema(schema, path, (keyword, keywordPath, node) => {\n if (modernDialect && keyword === \"$ref\" && !allowed.has(keyword) &&\n Object.keys(node).some(sibling => assertionKeywords.has(sibling))) {\n issues.push({ severity: policy.warningsAsErrors ? \"error\" : \"warning\",\n code: \"schema-portability-warning\", path: keywordPath, keyword,\n message: \"$ref assertion siblings are evaluated by modern dialects but ignored by draft-07 clients\",\n });\n }\n if (!PORTABILITY_KEYWORDS.has(keyword) || allowed.has(keyword)) return;\n issues.push({\n severity: policy.warningsAsErrors ? \"error\" : \"warning\",\n code: \"schema-portability-warning\",\n path: keywordPath,\n keyword,\n message: `${keyword} is valid but may reduce client portability`,\n });\n });\n return issues.sort((left, right) =>\n left.path < right.path ? -1 : left.path > right.path ? 1 : 0,\n );\n}\n\nfunction extractError(\n result: CallToolResult,\n): Record<string, unknown> | undefined {\n const structured = result.structuredContent as\n | Record<string, unknown>\n | undefined;\n if (structured?.error && typeof structured.error === \"object\") {\n return structured.error as Record<string, unknown>;\n }\n const text = result.content.find((content) => content.type === \"text\")?.text;\n if (!text) return undefined;\n try {\n const parsed = JSON.parse(text) as { error?: unknown };\n return parsed.error && typeof parsed.error === \"object\"\n ? (parsed.error as Record<string, unknown>)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction fixtureFailure(\n result: CallToolResult,\n fixture: McpFnClientProfileFixture,\n): string | undefined {\n const expected = fixture.expect;\n if (fixture.source !== \"captured-failure\" && result.isError) return \"Minimal-valid fixture returned isError=true\";\n if (fixture.source === \"captured-failure\" && !result.isError) return \"Captured failure did not reproduce an error\";\n if (!expected)\n return result.isError ? \"Tool returned isError=true\" : undefined;\n if (\n expected.isError !== undefined &&\n Boolean(result.isError) !== expected.isError\n ) {\n return `Expected isError=${expected.isError}, received ${Boolean(result.isError)}`;\n }\n if (\n expected.structuredContent !== undefined &&\n stableJson(result.structuredContent) !==\n stableJson(expected.structuredContent)\n )\n return \"Structured content did not match the fixture expectation\";\n const error = extractError(result);\n if (expected.errorCode !== undefined && error?.code !== expected.errorCode) {\n return \"Error code did not match the declared expectation\";\n }\n const details =\n error?.details && typeof error.details === \"object\"\n ? (error.details as Record<string, unknown>)\n : undefined;\n if (\n expected.lifecycleStage !== undefined &&\n details?.lifecycleStage !== expected.lifecycleStage\n )\n return `Expected lifecycle stage ${expected.lifecycleStage}`;\n if (expected.validationIssue) {\n const issues = Array.isArray(details?.issues)\n ? (details.issues as Record<string, unknown>[])\n : [];\n const fields = Object.entries(expected.validationIssue).filter(([, value]) => value !== undefined);\n const matched = fields.length > 0 && issues.some((issue) =>\n fields.every(\n ([key, value]) => issue[key] === value,\n ),\n );\n if (!matched)\n return \"Expected structured validation issue was not reported\";\n }\n return undefined;\n}\n\nasync function runProfileCase(\n profileCase: McpFnClientProfileContractCase,\n allowSideEffects: boolean,\n): Promise<McpFnClientProfileContractResult> {\n const profile = { id: profileCase.id, version: profileCase.version };\n let client: McpFnTestClient | undefined;\n let configurationError: Error | undefined;\n let pendingFailure: unknown;\n let hasPendingFailure = false;\n let cleanupOwner: McpFnTestClientCleanupError | undefined;\n let result: McpFnClientProfileContractResult = {\n profile,\n status: \"complete\",\n ok: false,\n portability: [],\n fixtures: [],\n };\n try {\n try {\n client = await McpFnTestClient.connectTarget(\n profileCase.target,\n profileCase.clientInfo ?? {\n name: \"mcpfn-profile-suite\",\n version: \"1.0.0\",\n },\n { ...profileCase.client, capabilities: profileCase.capabilities },\n );\n } catch (error) {\n if (error instanceof McpFnTestClientCleanupError) throw error;\n return { ...result, phase: \"connect\", error: \"Target connection failed\" };\n }\n let tools: Tool[] | undefined;\n try {\n tools = await client.listTools();\n const repeatedTools = await client.listTools();\n if (stableJson(tools) !== stableJson(repeatedTools)) {\n throw new Error(\n \"Effective catalog changed across identical profile list requests\",\n );\n }\n result.snapshot = createMcpFnClientProfileSnapshot(profile, tools);\n result.snapshotMatches = profileCase.expectedSnapshot\n ? stableJson(result.snapshot) ===\n stableJson(profileCase.expectedSnapshot)\n : undefined;\n for (const tool of tools) {\n result.portability.push(\n ...validateMcpFnSchemaPortability(\n tool.inputSchema,\n `tools/${tool.name}/inputSchema`,\n profileCase.portability,\n ),\n );\n if (tool.outputSchema) {\n result.portability.push(\n ...validateMcpFnSchemaPortability(\n tool.outputSchema,\n `tools/${tool.name}/outputSchema`,\n profileCase.portability,\n ),\n );\n }\n }\n } catch (error) {\n tools = undefined;\n result = { ...result, phase: \"catalog\", error: \"Target catalog validation failed\" };\n }\n if (tools) {\n const advertised = new Set(tools.map(({ name }) => name));\n const taskRequired = new Set(tools.filter(tool => tool.execution?.taskSupport === \"required\").map(tool => tool.name));\n if (profileCase.fixtures?.some(fixture => taskRequired.has(fixture.tool))) {\n configurationError = new Error(`Client profile ${profile.id}@${profile.version} task-required fixtures are unsupported by this contract runner`);\n throw configurationError;\n }\n for (const fixture of profileCase.fixtures ?? []) {\n const base = {\n name: fixture.name,\n tool: fixture.tool,\n source: fixture.source ?? (\"minimal-valid\" as const),\n };\n if (!advertised.has(fixture.tool)) {\n result.fixtures.push({\n ...base,\n status: \"failed\",\n code: \"fixture-tool-not-advertised\",\n error:\n \"Fixture references a tool absent from the effective catalog\",\n });\n continue;\n }\n if (fixture.sideEffect !== \"read-only\" && !allowSideEffects) {\n result.fixtures.push({\n ...base,\n status: \"incomplete\",\n code: \"side-effect-not-authorized\",\n error:\n \"Fixture was not executed because side effects were not explicitly allowed\",\n });\n continue;\n }\n try {\n const callResult = await client.callTool(\n fixture.tool,\n fixture.arguments ?? {},\n );\n const failure = fixtureFailure(callResult, fixture);\n result.fixtures.push(\n failure\n ? {\n ...base,\n status: \"failed\",\n code: \"fixture-expectation-failed\",\n error: failure,\n }\n : { ...base, status: \"passed\" },\n );\n } catch (error) {\n result.fixtures.push({\n ...base,\n status: \"failed\",\n code: \"fixture-call-failed\",\n error: \"Tool invocation failed; argument values and exception text are omitted\",\n });\n }\n }\n const incomplete = result.fixtures.some(\n ({ status }) => status === \"incomplete\",\n );\n const failed =\n result.fixtures.some(({ status }) => status === \"failed\") ||\n result.portability.some(({ severity }) => severity === \"error\") ||\n result.snapshotMatches === false;\n result = {\n ...result,\n phase: result.snapshotMatches === false || result.portability.some(({ severity }) => severity === \"error\")\n ? \"catalog\" : failed || incomplete ? \"fixtures\" : undefined,\n status: incomplete ? \"incomplete\" : \"complete\",\n ok: !failed && !incomplete,\n ...(result.snapshotMatches === false\n ? {\n error:\n \"Effective catalog does not match the reviewed profile snapshot\",\n }\n : {}),\n };\n }\n } catch (error) {\n pendingFailure = error;\n hasPendingFailure = true;\n } finally {\n if (client) {\n try {\n await client.close();\n } catch (error) {\n if (error instanceof McpFnTestClientCleanupError) cleanupOwner = error;\n else {\n if (configurationError) configurationError.message = `${configurationError.message}; target cleanup failed`;\n result = {\n ...result,\n ok: false,\n phase: result.phase ?? \"close\",\n error: result.error ? `${result.error}; target cleanup failed`.slice(0, 512) : \"Target cleanup failed\",\n };\n }\n }\n }\n }\n if (cleanupOwner) throw new ProfileCaseCleanupError(cleanupOwner, {\n ...result, ok: false, status: \"incomplete\", phase: result.phase ?? (hasPendingFailure ? \"fixtures\" : \"close\"),\n error: hasPendingFailure ? \"Profile execution failed; target cleanup remains pending\" : \"Target cleanup remains pending\",\n });\n if (hasPendingFailure) {\n if (pendingFailure instanceof McpFnTestClientCleanupError) {\n throw new ProfileCaseCleanupError(pendingFailure, {\n ...result, ok: false, status: \"incomplete\", phase: \"connect\", error: \"Target cleanup remains pending\",\n });\n }\n throw pendingFailure;\n }\n return result;\n}\n\n/** Exercise every profile through the production target/client list-and-call lifecycle. */\nexport async function runMcpFnClientProfileContracts(\n options: RunMcpFnClientProfileContractsOptions,\n): Promise<McpFnClientProfileContractReport> {\n const maxReportBytes = options.maxReportBytes ?? 1_048_576;\n if (!Number.isSafeInteger(maxReportBytes) || maxReportBytes < 2_048) {\n throw new Error(\"maxReportBytes must be an integer of at least 2048\");\n }\n if (!Array.isArray(options.profiles) || options.profiles.length === 0) {\n throw new Error(\n \"At least one generic or configured client profile is required\",\n );\n }\n if (options.profiles.length > 100)\n throw new Error(\"At most 100 client profiles may be tested\");\n const keys = new Set<string>();\n for (const profile of options.profiles) {\n assertProfileReference(profile.id, profile.version);\n const key = `${profile.id}@${profile.version}`;\n if (keys.has(key)) throw new Error(`Duplicate client profile case ${key}`);\n keys.add(key);\n if (profile.expectedSnapshot)\n validateMcpFnClientProfileSnapshot(profile.expectedSnapshot);\n for (const fixture of profile.fixtures ?? []) {\n if (fixture.source === \"captured-failure\" && (!fixture.expect || fixture.expect.isError === false ||\n !(fixture.expect.structuredContent !== undefined || fixture.expect.errorCode || fixture.expect.lifecycleStage ||\n (fixture.expect.validationIssue && Object.values(fixture.expect.validationIssue).some(value => value !== undefined))))) {\n throw new Error(`Captured-failure fixture ${fixture.name} requires meaningful error expectations`);\n }\n if (fixture.source !== undefined && ![\"minimal-valid\", \"captured-failure\"].includes(fixture.source)) throw new Error(\"Invalid fixture source\");\n if (!fixture.name || !fixture.tool || ![\"read-only\", \"idempotent\", \"non-idempotent\"].includes(fixture.sideEffect)) {\n throw new Error(`Client profile ${key} contains an invalid fixture`);\n }\n }\n }\n const profiles: McpFnClientProfileContractResult[] = [];\n const cleanupOwners: McpFnTestClientCleanupError[] = [];\n for (const profile of [...options.profiles].sort((left, right) => {\n const leftKey = `${left.id}@${left.version}`;\n const rightKey = `${right.id}@${right.version}`;\n return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0;\n })) {\n try {\n profiles.push(await runProfileCase(profile, options.allowSideEffects === true));\n } catch (error) {\n if (error instanceof ProfileCaseCleanupError) {\n profiles.push(error.result);\n cleanupOwners.push(error.owner);\n } else {\n if (cleanupOwners.length === 0) throw error;\n // An earlier session still needs a retry owner. Keep the aggregate\n // available and finish the remaining independent profile cases.\n profiles.push({ profile: { id: profile.id, version: profile.version },\n status: \"incomplete\", ok: false, phase: \"fixtures\", portability: [], fixtures: [],\n error: \"Profile execution failed\",\n });\n }\n }\n }\n const report: McpFnClientProfileContractReport = {\n formatVersion: 1,\n kind: \"mcpfn.client-profile-contract-report\",\n status: profiles.some(({ status }) => status === \"incomplete\")\n ? \"incomplete\"\n : \"complete\",\n ok: profiles.every(({ ok }) => ok),\n profiles,\n droppedProfiles: 0,\n };\n if (\n new TextEncoder().encode(JSON.stringify(report)).byteLength <=\n maxReportBytes\n )\n return finishReport(report, cleanupOwners);\n report.ok = false;\n report.status = \"incomplete\";\n report.incompleteReason =\n \"Report content exceeded maxReportBytes and was truncated\";\n while (\n new TextEncoder().encode(JSON.stringify(report)).byteLength >\n maxReportBytes &&\n report.profiles.length > 0\n ) {\n report.profiles.pop();\n report.droppedProfiles += 1;\n }\n if (\n new TextEncoder().encode(JSON.stringify(report)).byteLength > maxReportBytes\n ) {\n throw new Error(\"The minimum client profile report exceeds maxReportBytes\");\n }\n return finishReport(report, cleanupOwners);\n}\n\nfunction finishReport(\n report: McpFnClientProfileContractReport,\n cleanupOwners: readonly McpFnTestClientCleanupError[],\n): McpFnClientProfileContractReport {\n if (cleanupOwners.length) throw new McpFnClientProfileContractCleanupError(report, cleanupOwners);\n return report;\n}\n","import { execFile, type ChildProcess } from \"node:child_process\";\nimport path from \"node:path\";\n\n/** Internal bounded best-effort process-tree cleanup after capture overflow. */\nexport async function terminateConformanceRunner(\n child: ChildProcess,\n platform = process.platform,\n systemRoot = process.env.SystemRoot,\n): Promise<void> {\n const killWrapper = () => { try { child.kill(\"SIGKILL\"); } catch { /* Report remains failed. */ } };\n try {\n if (platform === \"win32\" && child.pid) {\n if (!systemRoot || !path.win32.isAbsolute(systemRoot)) { killWrapper(); return; }\n await new Promise<void>(resolve => {\n const timer = setTimeout(() => { killWrapper(); resolve(); }, 2500);\n const done = (error: Error | null) => {\n clearTimeout(timer);\n if (error) killWrapper();\n resolve();\n };\n try {\n execFile(path.win32.join(systemRoot, \"System32\", \"taskkill.exe\"),\n [\"/pid\", String(child.pid), \"/T\", \"/F\"], { timeout: 2000, windowsHide: true }, done);\n } catch (error) { done(error as Error); }\n });\n } else if (child.pid) {\n try { process.kill(-child.pid, \"SIGKILL\"); }\n catch (error) { if ((error as NodeJS.ErrnoException).code !== \"ESRCH\") killWrapper(); }\n } else killWrapper();\n } finally {\n child.stdout?.destroy();\n child.stderr?.destroy();\n }\n}\n","import { terminateConformanceRunner } from \"./conformance-process.js\";\nimport { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport {\n createServer,\n request as httpRequest,\n type IncomingHttpHeaders,\n} from \"node:http\";\nimport { request as httpsRequest } from \"node:https\";\nimport type { Socket } from \"node:net\";\nimport path from \"node:path\";\nimport { redactOAuthValue } from \"@superfunctions/oauth-core\";\n\nimport {\n acquireRemoteCredential,\n redactRemoteCredential,\n validateRemoteCredentialHeaders,\n type McpFnRemoteCredential,\n type McpFnRemoteCredentialProvider,\n} from \"./remote-target.js\";\nimport {\n normalizeMcpFnReportFailure,\n type McpFnReportFailure,\n} from \"./reports.js\";\n\nexport const OFFICIAL_CONFORMANCE_VERSION = \"0.1.16\";\n\nexport interface OfficialConformanceOptions {\n url: string;\n suite?: \"active\" | \"all\" | \"pending\";\n scenario?: string;\n expectedFailures?: string;\n outputDir?: string;\n specVersion?: string;\n verbose?: boolean;\n cwd?: string;\n stdio?: \"inherit\" | \"pipe\";\n /** Environment names removed before spawning the upstream runner. */\n sensitiveEnvironmentVariables?: readonly string[];\n}\n\nexport interface OfficialConformanceResult {\n formatVersion: 1;\n kind: \"mcpfn.official-conformance-report\";\n ok: boolean;\n suiteVersion: string;\n exitCode: number;\n stdout: string;\n stderr: string;\n failure?: McpFnReportFailure;\n /** Credential cleanup failure, separate from the upstream runner diagnosis. */\n cleanupFailure?: McpFnReportFailure;\n}\n\nexport interface AuthenticatedConformanceProxy {\n /** Loopback URL to pass to the official conformance runner. */\n url: string;\n close(): Promise<void>;\n}\n\nexport interface AuthenticatedConformanceProxyOptions {\n /** Fixed loopback MCP URL. Requests cannot select a different origin or path. */\n url: string;\n /** Headers injected into requests using the proxy's own authority. Values are never logged. */\n headers: HeadersInit;\n}\n\nexport interface AuthenticatedOfficialConformanceOptions extends OfficialConformanceOptions {\n /** Preferred typed credential lifecycle. */\n credential?: McpFnRemoteCredential | McpFnRemoteCredentialProvider;\n /** Backward-compatible static header input. Prefer credential. */\n headers?: HeadersInit;\n}\n\nfunction validateAuthenticatedConformanceUrl(url: string): { upstream: URL; hostname: string } {\n const upstream = new URL(url);\n if (![\"http:\", \"https:\"].includes(upstream.protocol)) {\n throw new TypeError(\n \"Authenticated conformance upstream must use HTTP or HTTPS\",\n );\n }\n if (upstream.username || upstream.password || upstream.hash) {\n throw new TypeError(\n \"Authenticated conformance upstream must not contain userinfo or a fragment\",\n );\n }\n const hostname = normalizeLoopbackHostname(upstream.hostname);\n if (!hostname) {\n throw new TypeError(\n \"Authenticated conformance upstream must use a literal loopback address\",\n );\n }\n return { upstream, hostname };\n}\n\n/**\n * Start a loopback-only streaming proxy for runners that cannot send auth\n * headers. Authenticated requests use one fixed upstream authority and path.\n * Host-manipulation probes are forwarded without injected credentials.\n */\nexport async function createAuthenticatedConformanceProxy(\n options: AuthenticatedConformanceProxyOptions,\n): Promise<AuthenticatedConformanceProxy> {\n const { upstream, hostname } = validateAuthenticatedConformanceUrl(options.url);\n const protocol = upstream.protocol === \"https:\" ? \"https:\" : \"http:\";\n const port = upstream.port === \"\" ? undefined : Number(upstream.port);\n const requestPath = `${upstream.pathname}${upstream.search}`;\n const injected = validateRemoteCredentialHeaders(options.headers);\n const activeRequests = new Set<ReturnType<typeof httpRequest>>();\n const activeSockets = new Set<Socket>();\n let proxyAuthority: string | undefined;\n const server = createServer((incoming, outgoing) => {\n if (!incoming.url?.startsWith(\"/\")) {\n outgoing.writeHead(400).end();\n return;\n }\n const headers: IncomingHttpHeaders = { ...incoming.headers };\n delete headers.connection;\n const usesProxyAuthority = incoming.headers.host === proxyAuthority;\n injected.forEach((value, name) => {\n const normalizedName = name.toLowerCase();\n delete headers[normalizedName];\n if (usesProxyAuthority) headers[normalizedName] = value;\n });\n // Authenticated traffic is pinned to the upstream Host. Host-manipulation\n // probes retain their hostile value, but never receive injected credentials.\n if (usesProxyAuthority) headers.host = upstream.host;\n const transport = protocol === \"https:\" ? httpsRequest : httpRequest;\n const proxied = transport(\n {\n protocol,\n hostname,\n port,\n path: requestPath,\n method: incoming.method,\n headers,\n },\n (response) => {\n outgoing.writeHead(response.statusCode ?? 502, response.headers);\n response.pipe(outgoing);\n },\n );\n activeRequests.add(proxied);\n proxied.once(\"close\", () => activeRequests.delete(proxied));\n proxied.once(\"error\", () => {\n if (!outgoing.headersSent) outgoing.writeHead(502);\n outgoing.end();\n });\n incoming.once(\"aborted\", () => proxied.destroy());\n incoming.pipe(proxied);\n });\n server.on(\"connection\", (socket) => {\n activeSockets.add(socket);\n socket.once(\"close\", () => activeSockets.delete(socket));\n });\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n const address = server.address();\n if (!address || typeof address === \"string\") {\n await new Promise<void>((resolve) => server.close(() => resolve()));\n throw new Error(\"Authenticated conformance proxy did not bind a TCP port\");\n }\n const url = new URL(\n upstream.pathname + upstream.search,\n `http://127.0.0.1:${address.port}`,\n );\n proxyAuthority = url.host;\n let closePromise: Promise<void> | undefined;\n return {\n url: url.toString(),\n close: () => {\n closePromise ??= (async () => {\n for (const request of activeRequests) request.destroy();\n for (const socket of activeSockets) socket.destroy();\n if (!server.listening) return;\n await new Promise<void>((resolve, reject) => {\n server.close((error) => (error ? reject(error) : resolve()));\n });\n })();\n return closePromise;\n },\n };\n}\n\nfunction normalizeLoopbackHostname(\n hostname: string,\n): string | undefined {\n const parts = hostname.split(\".\");\n if (parts.length === 4 && parts[0] === \"127\" && parts.every(part => /^\\d{1,3}$/.test(part) && Number(part) <= 255)) return hostname;\n if (hostname === \"[::1]\") return \"::1\";\n return undefined;\n}\n\nfunction npxInvocation(args: string[]): { command: string; args: string[] } {\n if (process.platform !== \"win32\") return { command: \"npx\", args };\n const npmExecPath = process.env.npm_execpath;\n const candidates = [\n npmExecPath ? path.join(path.dirname(npmExecPath), \"npx-cli.js\") : undefined,\n path.resolve(path.dirname(process.execPath), \"node_modules/npm/bin/npx-cli.js\"),\n path.resolve(path.dirname(process.execPath), \"../lib/node_modules/npm/bin/npx-cli.js\"),\n ].filter((candidate): candidate is string => Boolean(candidate));\n const npxCli = candidates.find((candidate) => existsSync(candidate));\n if (!npxCli) {\n throw new Error(\"Unable to locate npm's npx-cli.js for the official MCP conformance runner\");\n }\n return { command: process.execPath, args: [npxCli, ...args] };\n}\n\nexport function buildOfficialConformanceArgs(\n options: OfficialConformanceOptions,\n): string[] {\n const args = [\n \"--yes\",\n `@modelcontextprotocol/conformance@${OFFICIAL_CONFORMANCE_VERSION}`,\n \"server\",\n \"--url\",\n options.url,\n ];\n if (options.suite) args.push(\"--suite\", options.suite);\n if (options.scenario) args.push(\"--scenario\", options.scenario);\n if (options.expectedFailures) {\n args.push(\"--expected-failures\", options.expectedFailures);\n }\n if (options.outputDir) args.push(\"--output-dir\", options.outputDir);\n if (options.specVersion) args.push(\"--spec-version\", options.specVersion);\n if (options.verbose) args.push(\"--verbose\");\n return args;\n}\n\nexport function buildOfficialConformanceEnvironment(\n sensitiveNames: readonly string[] = [],\n source: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n const environment = { ...source };\n const sensitive = new Set(sensitiveNames.map((name) => name.toLowerCase()));\n for (const name of Object.keys(environment)) {\n if (sensitive.has(name.toLowerCase())) delete environment[name];\n }\n environment.PATH = [path.dirname(process.execPath), environment.PATH]\n .filter(Boolean)\n .join(path.delimiter);\n return environment;\n}\n\nexport async function runOfficialConformance(options: OfficialConformanceOptions): Promise<OfficialConformanceResult> {\n return runConformance(options, value => String(redactOAuthValue(value, { maxStringLength: 262_144 })));\n}\n\nasync function runConformance(\n options: OfficialConformanceOptions,\n redactOutput: (value: string) => string,\n): Promise<OfficialConformanceResult> {\n const nodeMajor = Number.parseInt(process.versions.node.split(\".\")[0] ?? \"0\", 10);\n if (nodeMajor < 22) {\n throw new Error(\n `Official MCP conformance ${OFFICIAL_CONFORMANCE_VERSION} requires Node.js 22 or newer; current runtime is ${process.versions.node}`,\n );\n }\n const args = buildOfficialConformanceArgs(options);\n const invocation = npxInvocation(args);\n const childEnvironment = buildOfficialConformanceEnvironment(\n options.sensitiveEnvironmentVariables,\n );\n\n return await new Promise<OfficialConformanceResult>((resolve) => {\n const child = spawn(invocation.command, invocation.args, {\n detached: process.platform !== \"win32\",\n cwd: options.cwd,\n env: childEnvironment,\n stdio: options.stdio === \"inherit\" ? \"inherit\" : \"pipe\",\n });\n let stdout = \"\";\n let stderr = \"\";\n let capturedBytes = 0;\n let outputExceeded = false;\n const capture = (chunk: string, stream: \"stdout\" | \"stderr\") => {\n if (outputExceeded) return;\n capturedBytes += Buffer.byteLength(chunk, \"utf8\");\n if (capturedBytes > 262_144) {\n outputExceeded = true;\n stdout = \"\"; stderr = \"\";\n // Always settle the failed report after the bounded termination attempt,\n // even if the wrapper never emits close (for example, a failed taskkill).\n void terminateConformanceRunner(child).finally(() => finish(1));\n return;\n }\n if (stream === \"stdout\") stdout += chunk.toString();\n else stderr += chunk.toString();\n };\n child.stdout?.setEncoding(\"utf8\");\n child.stderr?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", chunk => capture(chunk, \"stdout\"));\n child.stderr?.on(\"data\", chunk => capture(chunk, \"stderr\"));\n let settled = false;\n child.once(\"error\", (error) => {\n if (settled) return;\n settled = true;\n const failure = normalizeMcpFnReportFailure(error, \"upstream-conformance\");\n resolve({\n formatVersion: 1,\n kind: \"mcpfn.official-conformance-report\",\n ok: false,\n suiteVersion: OFFICIAL_CONFORMANCE_VERSION,\n exitCode: 1,\n stdout: \"\",\n stderr: failure.message,\n failure,\n });\n });\n const finish = (code: number | null) => {\n if (settled) return;\n settled = true;\n let safeStdout = \"\";\n let safeStderr = \"\";\n let outputFailure = false;\n try {\n if (outputExceeded) throw new Error(\"capture limit\");\n safeStdout = redactOutput(stdout);\n safeStderr = redactOutput(stderr);\n } catch {\n outputFailure = true;\n safeStdout = \"\";\n safeStderr = outputExceeded ? \"Conformance output exceeded its capture limit\" : \"Conformance output omitted because credential redaction exceeded its bounds\";\n }\n const exitCode = outputFailure ? 1 : (code ?? 1);\n const failure = exitCode === 0\n ? undefined\n : normalizeMcpFnReportFailure(\n new Error(safeStderr || safeStdout || `Official conformance exited ${exitCode}`),\n \"upstream-conformance\",\n );\n resolve({\n formatVersion: 1,\n kind: \"mcpfn.official-conformance-report\",\n ok: exitCode === 0,\n suiteVersion: OFFICIAL_CONFORMANCE_VERSION,\n exitCode,\n stdout: safeStdout,\n stderr: safeStderr,\n ...(failure ? { failure } : {}),\n });\n };\n child.once(\"close\", finish);\n });\n}\n\nconst retainedConformanceCleanup = new WeakMap<Error, () => Promise<void>>();\n\n/** Cleanup failed after retries. Retain this error and call retryCleanup(). */\nexport class McpFnConformanceCleanupError extends Error {\n constructor(release: () => Promise<void>, readonly result?: OfficialConformanceResult) {\n super(\"Authenticated conformance credential cleanup failed; retry cleanup\");\n this.name = \"McpFnConformanceCleanupError\";\n retainedConformanceCleanup.set(this, release);\n }\n async retryCleanup(): Promise<void> {\n const release = retainedConformanceCleanup.get(this);\n if (!release) return;\n try { await release(); }\n catch { throw this; }\n retainedConformanceCleanup.delete(this);\n }\n}\n\n/**\n * Run the pinned official suite against an authenticated MCP endpoint.\n * Always captures stdio (even when inherit is requested) to redact credentials.\n * outputDir is rejected before acquisition; only the returned redacted result is safe to persist.\n */\nexport async function runAuthenticatedOfficialConformance(\n options: AuthenticatedOfficialConformanceOptions,\n): Promise<OfficialConformanceResult> {\n if (options.outputDir !== undefined) throw new TypeError(\"Authenticated conformance does not support outputDir; serialize the redacted result instead\");\n const { headers, credential, ...conformance } = options;\n if ((headers === undefined) === (credential === undefined)) {\n throw new TypeError(\"Provide exactly one of credential or headers for authenticated conformance\");\n }\n validateAuthenticatedConformanceUrl(conformance.url);\n const lease = await acquireRemoteCredential(\n credential ?? { headers: headers! },\n {\n url: conformance.url,\n requestId: randomUUID(),\n },\n );\n let proxy: AuthenticatedConformanceProxy | undefined;\n let result: OfficialConformanceResult | undefined;\n let operationFailure: { error: Error } | undefined;\n const safeFailure = (error: unknown): { error: Error } => {\n let message = \"Authenticated conformance operation failed\";\n try { message = redactRemoteCredential(lease.credential, error instanceof Error ? error.message : String(error)); }\n catch { /* Keep a safe fallback if redaction exceeds its budget. */ }\n return { error: new Error(message) };\n };\n try {\n proxy = await createAuthenticatedConformanceProxy({\n url: conformance.url,\n headers: lease.credential.headers,\n });\n result = redactRemoteCredential(lease.credential, await runConformance({ ...conformance, stdio: \"pipe\", url: proxy.url }, value => String(redactRemoteCredential(lease.credential, value))), { preserveKeys: true });\n } catch (error) {\n operationFailure = safeFailure(error);\n }\n try { await proxy?.close(); }\n catch (error) { operationFailure ??= safeFailure(error); }\n let released = false;\n for (let attempt = 0; attempt < 3; attempt++) {\n try { await lease.release(); released = true; break; } catch { /* Retry transient revocation failure. */ }\n }\n if (!released) {\n const message = \"Authenticated conformance credential cleanup failed; retry cleanup\";\n const cleanupFailure = normalizeMcpFnReportFailure(new Error(message), lease.cleanupPhase());\n const failedResult = result ? { ...result, ok: false, exitCode: result.exitCode || 1,\n cleanupFailure,\n ...(result.failure ? {} : { failure: cleanupFailure }),\n } : undefined;\n throw new McpFnConformanceCleanupError(() => lease.release(), failedResult);\n }\n if (operationFailure) throw operationFailure.error;\n if (!result) throw new Error(\"Conformance produced no result\");\n return result;\n}\n","import {\n McpFnClientError,\n customTarget,\n streamableHttpTarget,\n type McpFnStreamableHttpTargetOptions,\n type McpFnTarget,\n type McpFnTransportHandle,\n} from \"@mcpfn/client\";\n\nimport { redactOAuthValue } from \"@superfunctions/oauth-core\";\n\ntype SecretState = { active: Map<string, number>; scopes: Set<Set<string>> };\nconst targetSecrets = new WeakMap<McpFnTarget, SecretState>();\nconst utf8Encoder = new TextEncoder();\n\n/** Retain released credentials only for the lifetime of a report operation. */\nexport function beginTargetCredentialRedaction(target: McpFnTarget): () => void {\n const state = targetSecrets.get(target);\n if (!state) return () => undefined;\n const scope = new Set(state.active.keys());\n state.scopes.add(scope);\n return () => { state.scopes.delete(scope); scope.clear(); };\n}\n\nfunction credentialValues(headers: HeadersInit): Set<string> {\n const values = boundedCredentialEntries(headers);\n const secrets = new Set<string>();\n for (const [header, raw] of values) {\n if (!raw.trim()) continue;\n secrets.add(raw);\n secrets.add(raw.trim());\n const normalizedHeader = header.toLowerCase();\n if ([\"authorization\", \"proxy-authorization\"].includes(normalizedHeader)) {\n addAuthorizationSecrets(raw, secrets);\n }\n if (normalizedHeader === \"cookie\") addCookieSecrets(raw, secrets);\n }\n return secrets;\n}\n\nfunction addAuthorizationSecrets(raw: string, secrets: Set<string>): void {\n const trimmed = raw.trim();\n const separator = trimmed.search(/\\s/);\n if (separator <= 0) return;\n const scheme = trimmed.slice(0, separator).toLowerCase();\n const token = trimmed.slice(separator).trim();\n if (token) secrets.add(token);\n if (scheme !== \"basic\") {\n if (scheme !== \"bearer\" && !authorizationToken68.test(token)) {\n addAuthorizationParameterSecrets(token, secrets);\n }\n return;\n }\n addBasicAuthorizationSecrets(token, secrets);\n}\n\nfunction addBasicAuthorizationSecrets(token: string, secrets: Set<string>): void {\n if (!/^[\\dA-Za-z+/]+={0,2}$/.test(token)) return;\n const decoded = Buffer.from(token, \"base64\");\n // Round-trip validation avoids interpreting malformed tokens as credentials.\n if (stripBase64Padding(decoded.toString(\"base64\")) !== stripBase64Padding(token)) return;\n for (const encoding of [\"utf8\", \"latin1\"] as const) {\n const pair = decoded.toString(encoding);\n const colon = pair.indexOf(\":\");\n if (colon < 0) continue;\n for (const value of [pair, pair.slice(0, colon), pair.slice(colon + 1)]) {\n if (value) secrets.add(value);\n }\n }\n}\n\nconst authorizationToken68 = /^[\\dA-Za-z._~+\\x2F-]+=*$/;\nconst authorizationParameterName = /^[!#$%&'*+.^_`|~\\dA-Za-z-]+$/;\n\ninterface ParsedAuthorizationValue {\n cursor: number;\n components: string[];\n}\n\nfunction skipAuthorizationWhitespace(token: string, cursor: number): number {\n while (token[cursor] === \" \" || token[cursor] === \"\\t\") cursor += 1;\n return cursor;\n}\n\nfunction parseQuotedAuthorizationValue(token: string, start: number): ParsedAuthorizationValue {\n let cursor = start + 1;\n let decoded = \"\";\n while (cursor < token.length && token[cursor] !== '\"') {\n if (token[cursor] === \"\\\\\") {\n cursor += 1;\n if (cursor >= token.length) {\n throw new TypeError(\"Authorization credential parameters must use balanced quotes\");\n }\n }\n decoded += token[cursor];\n cursor += 1;\n }\n if (token[cursor] !== '\"') {\n throw new TypeError(\"Authorization credential parameters must use balanced quotes\");\n }\n cursor += 1;\n const rawValue = token.slice(start, cursor);\n return {\n cursor,\n components: [rawValue, rawValue.slice(1, -1), decoded].filter(Boolean),\n };\n}\n\nfunction parseUnquotedAuthorizationValue(token: string, start: number): ParsedAuthorizationValue {\n let cursor = start;\n while (cursor < token.length && token[cursor] !== \",\") cursor += 1;\n const value = token.slice(start, cursor).trim();\n if (!value || /\\s/.test(value) || value.includes('\"')) {\n throw new TypeError(\"Authorization credential parameters must contain valid values\");\n }\n return { cursor, components: [value] };\n}\n\nfunction parseAuthorizationParameter(token: string, start: number): ParsedAuthorizationValue {\n let cursor = skipAuthorizationWhitespace(token, start);\n const nameStart = cursor;\n while (cursor < token.length && token[cursor] !== \"=\" &&\n token[cursor] !== \" \" && token[cursor] !== \"\\t\" && token[cursor] !== \",\") cursor += 1;\n const name = token.slice(nameStart, cursor);\n cursor = skipAuthorizationWhitespace(token, cursor);\n if (!authorizationParameterName.test(name) || token[cursor] !== \"=\") {\n throw new TypeError(\"Authorization credential parameters must use name=value syntax\");\n }\n cursor = skipAuthorizationWhitespace(token, cursor + 1);\n if (cursor >= token.length) {\n throw new TypeError(\"Authorization credential parameters must contain values\");\n }\n const parsed = token[cursor] === '\"'\n ? parseQuotedAuthorizationValue(token, cursor)\n : parseUnquotedAuthorizationValue(token, cursor);\n return { ...parsed, cursor: skipAuthorizationWhitespace(token, parsed.cursor) };\n}\n\nfunction addAuthorizationParameterSecrets(token: string, secrets: Set<string>): void {\n const firstEquals = token.indexOf(\"=\");\n if (firstEquals < 1 || !authorizationParameterName.test(token.slice(0, firstEquals).trim())) return;\n let cursor = 0;\n while (cursor < token.length) {\n const parsed = parseAuthorizationParameter(token, cursor);\n for (const component of parsed.components) secrets.add(component);\n cursor = parsed.cursor;\n if (cursor === token.length) return;\n if (token[cursor] !== \",\") {\n throw new TypeError(\"Authorization credential parameters must be comma separated\");\n }\n cursor = skipAuthorizationWhitespace(token, cursor + 1);\n if (cursor === token.length) {\n throw new TypeError(\"Authorization credential parameters must not end with a comma\");\n }\n }\n}\n\nfunction stripBase64Padding(value: string): string {\n let end = value.length;\n while (end > 0 && value[end - 1] === \"=\") end -= 1;\n return value.slice(0, end);\n}\n\nfunction addCookieSecrets(raw: string, secrets: Set<string>): void {\n // Cookie values are independently reflectable even though the request\n // authenticates with the complete header. RFC 6265 cookie values cannot\n // contain comma or semicolon, so both delimiters cover combined entries.\n for (const part of raw.split(/[;,]/)) {\n const pair = part.trim();\n if (!pair) continue;\n const equals = pair.indexOf(\"=\");\n if (equals < 1) {\n throw new TypeError(\"Cookie credential headers must contain name=value pairs\");\n }\n const value = pair.slice(equals + 1).trim();\n if (!value) continue;\n secrets.add(value);\n addUnquotedCookieSecret(value, secrets);\n }\n}\n\nfunction addUnquotedCookieSecret(value: string, secrets: Set<string>): void {\n if (!value.startsWith('\"') && !value.endsWith('\"')) return;\n if (value.length < 2 || !value.startsWith('\"') || !value.endsWith('\"')) {\n throw new TypeError(\"Cookie credential values must use balanced quotes\");\n }\n const unquoted = value.slice(1, -1);\n if (unquoted.includes('\"') || unquoted.includes(\"\\\\\")) {\n throw new TypeError(\"Cookie credential values must use RFC 6265 syntax\");\n }\n if (unquoted) secrets.add(unquoted);\n}\n\nexport class McpFnRedactionLimitError extends Error {\n constructor(message = \"Credential redaction exceeded its traversal budget\") { super(message); }\n}\n\n/** No typed artifact can preserve this authored structure without exposing a credential. */\nexport class McpFnStructuralCredentialCollisionError extends McpFnRedactionLimitError {\n constructor() {\n super(\"Credential collides with required artifact structure\");\n }\n}\n\n// Only these locally authored envelope paths retain structural keys. Unknown\n// children (including inspector events and server metadata) are always payloads.\nconst envelopeKeys: Record<string, Set<string>> = Object.fromEntries(Object.entries({\n root: \"formatVersion kind artifactValidation status runtime ok target server capabilities manifestChecked manifestHash total passed failed incomplete droppedResults droppedObservedEvents redactionOmittedObservedEvents incompleteReason failure timeline droppedTimelineEvents results count clientState tools resources resourceTemplates prompts droppedEvents timelineComplete droppedInventoryEntries inventoryComplete suiteVersion exitCode stdout stderr phase outcome code requestId at details payload\",\n result: \"formatVersion name operation tool status sideEffect durationMs error droppedObservedEvents redactionOmittedObservedEvents\",\n diagnostic: \"phase outcome code requestId at target details\",\n inspectorEvent: \"formatVersion source kind at event\",\n failure: \"name message layer code phase details\",\n runtime: \"node scenarioFormatVersion reportSchemaVersion packages\",\n packages: \"testing\",\n droppedInventoryEntries: \"tools resources resourceTemplates prompts\",\n target: \"kind\",\n}).map(([role, keys]) => [role, new Set(keys.split(\" \"))]));\n\nconst structuralArtifactValues = new Map<string, Set<string>>([\n [\"root:kind\", new Set([\"logging.message\", \"progress\", \"tasks.status\", \"resources.updated\", \"tools.list_changed\", \"resources.list_changed\", \"prompts.list_changed\", \"resources.subscribed\", \"resources.unsubscribed\", \"client.roots\", \"client.sampling\", \"client.elicitation\", \"mcpfn.target-suite-report\", \"mcpfn.inspector-snapshot\", \"mcpfn.official-conformance-report\"])],\n [\"inspectorEvent:kind\", new Set([\"logging.message\", \"progress\", \"tasks.status\", \"resources.updated\", \"tools.list_changed\", \"resources.list_changed\", \"prompts.list_changed\", \"resources.subscribed\", \"resources.unsubscribed\", \"client.roots\", \"client.sampling\", \"client.elicitation\"])],\n [\"root:clientState\", new Set([\"idle\", \"connecting\", \"authorization-required\", \"connected\", \"closing\", \"closed\"])],\n [\"target:kind\", new Set([\"authenticated-streamable-http\", \"streamable-http\", \"stdio\", \"in-memory\", \"custom\"])],\n [\"root:status\", new Set([\"passed\", \"failed\", \"incomplete\", \"complete\"])],\n [\"result:status\", new Set([\"passed\", \"failed\", \"incomplete\", \"complete\"])],\n [\"root:outcome\", new Set([\"started\", \"succeeded\", \"failed\"])],\n [\"diagnostic:outcome\", new Set([\"started\", \"succeeded\", \"failed\"])],\n ...[\"root\", \"diagnostic\", \"failure\"].map(role => [\n `${role}:phase`,\n new Set([\"resource-discovery\", \"authorization-server-discovery\", \"client-registration\", \"authorization-request\", \"authorization-callback\", \"token-exchange\", \"token-refresh\", \"token-revocation\", \"transport-connect\", \"mcp-initialize\", \"capability-operation\", \"transport-close\"]),\n ] as [string, Set<string>]),\n [\"failure:layer\", new Set([\"mcpfn-preflight\", \"authorization-server\", \"resource-server\", \"mcp-initialization\", \"scenario\", \"upstream-conformance\"])],\n [\"inspectorEvent:source\", new Set([\"diagnostic\", \"client\"])],\n [\"result:sideEffect\", new Set([\"none\", \"idempotent\", \"non-idempotent\"])],\n]);\n\nconst unrestrictedStructuralValueFields = new Set([\n \"packages:testing\",\n \"runtime:node\",\n \"runtime:reportSchemaVersion\",\n \"root:suiteVersion\",\n]);\n\nfunction childEnvelopeRole(\n fixed: boolean,\n key: string,\n role: string,\n input: Record<string, unknown>,\n rootKind: unknown,\n): string {\n if (!fixed) return \"payload\";\n if (key === \"results\") return \"result\";\n if (key === \"timeline\") {\n return rootKind === \"mcpfn.inspector-snapshot\" ? \"inspectorEvent\" : \"diagnostic\";\n }\n if ([\"failure\", \"runtime\", \"packages\", \"droppedInventoryEntries\", \"target\"].includes(key)) {\n return key;\n }\n if (role === \"inspectorEvent\" && key === \"event\") {\n return input.source === \"client\" ? \"root\" : \"diagnostic\";\n }\n return \"payload\";\n}\n\nfunction specialValue(input: unknown): unknown {\n if (input instanceof Error) return normalizeErrorValue(input);\n if (input instanceof Date) return Number.isNaN(input.getTime()) ? \"Invalid Date\" : input.toISOString();\n if (input instanceof URL) return input.href;\n if (input instanceof Map) {\n if (Object.getOwnPropertyDescriptor(Map.prototype, \"size\")!.get!.call(input) > 100_000) throw new McpFnRedactionLimitError();\n return { type: \"Map\", entries: [...Map.prototype.entries.call(input)] };\n }\n if (input instanceof Set) {\n if (Object.getOwnPropertyDescriptor(Set.prototype, \"size\")!.get!.call(input) > 100_000) throw new McpFnRedactionLimitError();\n return { type: \"Set\", values: [...Set.prototype.values.call(input)] };\n }\n return input;\n}\n\nfunction normalizeErrorValue(input: Error): Record<string, unknown> {\n // Error instances may expose attacker-controlled enumerable keys. A\n // null-prototype accumulator keeps `__proto__` as ordinary payload data.\n const normalized = Object.create(null) as Record<string, unknown>;\n let enumerableFields = 0;\n for (const key in input) {\n if (!Object.hasOwn(input, key)) continue;\n if (++enumerableFields > 100_000) throw new McpFnRedactionLimitError();\n normalized[key] = (input as unknown as Record<string, unknown>)[key];\n }\n normalized.name = input.name;\n normalized.message = input.message;\n normalized.stack = input.stack;\n if (input.cause !== undefined) normalized.cause = input.cause;\n return normalized;\n}\n\ninterface CredentialVariant {\n value: string;\n encoded: boolean;\n}\n\nfunction credentialPatterns(values: Iterable<string>): {\n secretPattern: RegExp | undefined;\n replacementPattern: RegExp | undefined;\n} {\n // Preserve whether a pattern came from opaque text or a serializer. Literal\n // percent sequences in credentials must not acquire URL hex-case semantics.\n const variants: CredentialVariant[] = [...values].filter(Boolean).flatMap(secret => [\n { value: secret, encoded: false },\n { value: JSON.stringify(secret).slice(1, -1), encoded: false },\n { value: encodeURIComponent(secret), encoded: true },\n { value: new URLSearchParams({ value: secret }).toString().slice(\"value=\".length), encoded: true },\n ]).sort((a, b) => b.value.length - a.value.length);\n const patterns = variants.map(({ value, encoded }) => {\n const literal = value.replace(/[.*+?^${}()|[\\]\\\\]/g, String.raw`\\$&`);\n // Only generated percent escapes accept mixed-case hex digits.\n return encoded\n ? literal.replace(/%[\\dA-Fa-f]{2}/g, escape => escape.replace(/[A-Fa-f]/g, hex => `[${hex.toLowerCase()}${hex.toUpperCase()}]`))\n : literal;\n });\n return {\n secretPattern: patterns.length ? new RegExp(patterns.join(\"|\"), \"g\") : undefined,\n replacementPattern: patterns.length ? new RegExp(patterns.join(\"|\")) : undefined,\n };\n}\n\nfunction targetCredentialValues(target: McpFnTarget): Set<string> {\n const state = targetSecrets.get(target);\n return new Set([\n ...(state?.active.keys() ?? []),\n ...[...(state?.scopes ?? [])].flatMap(scope => [...scope]),\n ]);\n}\n\nfunction scrubCredentials<T>(value: T, values: Iterable<string>, preserveKeys = false, redactionMarker?: string): T {\n let entries = 0, stringBytes = 0;\n const budget = (input: unknown, depth = 0): void => {\n input = specialValue(input);\n if ((Array.isArray(input) && input.length > 100_000) || ++entries > 100_000 || depth > 32) throw new McpFnRedactionLimitError();\n if (typeof input === \"string\") {\n stringBytes += Buffer.byteLength(input);\n if (input.length > 262_144 || stringBytes > 2_097_152) throw new McpFnRedactionLimitError();\n } else if (input && typeof input === \"object\") {\n for (const key in input) if (Object.hasOwn(input, key)) {\n budget(key, depth + 1);\n budget((input as Record<string, unknown>)[key], depth + 1);\n }\n }\n };\n // Check before either redactor allocates copies. Exceeding a budget is an\n // explicit failure, never silent truncation of a typed report collection.\n budget(value);\n const { secretPattern, replacementPattern } = credentialPatterns(values);\n const preserveStructural = (input: string): string => {\n if (replacementPattern?.test(input)) {\n throw new McpFnRedactionLimitError(\n \"Credential collides with a required structural artifact field\",\n );\n }\n return input;\n };\n const preserveStructuralKey = (input: string): string => {\n if (replacementPattern?.test(input)) {\n throw new McpFnStructuralCredentialCollisionError();\n }\n return input;\n };\n // A requested marker is itself output and must not reproduce a credential.\n if (secretPattern) {\n const markerContainsSecret = secretPattern.test(redactionMarker ?? \"[REDACTED]\");\n secretPattern.lastIndex = 0;\n if (markerContainsSecret) redactionMarker = \"\";\n }\n const scrubString = (input: string, role: string, field: string, finalPass: boolean): string => {\n const structuralField = `${role}:${field}`;\n if (unrestrictedStructuralValueFields.has(structuralField) ||\n structuralArtifactValues.get(structuralField)?.has(input)) {\n return preserveStructural(input);\n }\n // Whole-string rejection cannot compose another credential by joining pieces.\n // Run after both redactors; never feed this result through another redactor.\n if (finalPass) return replacementPattern?.test(input) ? \"\" : input;\n if (!secretPattern) return input;\n return input.replace(secretPattern, secret => {\n const maskCharacter = secret.includes(\"*\") ? \"#\" : \"*\";\n const defaultReplacement = secret.length < 10\n ? maskCharacter.repeat(secret.length)\n : \"[REDACTED]\";\n const replacement = redactionMarker ?? defaultReplacement;\n // Every generated mask must be safe against the entire credential set.\n return replacementPattern!.test(replacement) ? \"\" : replacement;\n });\n };\n function scrubArray(input: unknown[], role: string, finalPass: boolean): unknown[] {\n const result = input.map(entry => scrub(entry, role, \"\", finalPass));\n assertPayloadSerialization(result, role, finalPass, replacementPattern);\n return result;\n }\n function scrubObject(\n input: Record<string, unknown>,\n role: string,\n finalPass: boolean,\n ): Record<string, unknown> {\n const entries: Array<[string, unknown]> = [];\n const keys = new Set<string>();\n for (const [key, entry] of Object.entries(input)) {\n const fixed = envelopeKeys[role]?.has(key) ?? false;\n if (fixed) preserveStructuralKey(key);\n const childRole = childEnvelopeRole(\n fixed,\n key,\n role,\n input,\n (value as { kind?: unknown } | null)?.kind,\n );\n const scrubbedKey = fixed ? key : scrub(key, \"payload\", \"\", finalPass) as string;\n if (keys.has(scrubbedKey)) {\n throw new McpFnRedactionLimitError(\n \"Credential redaction created duplicate object keys\",\n );\n }\n keys.add(scrubbedKey);\n const entryRole = fixed ? role : \"payload\";\n const scrubbedEntry = typeof entry === \"string\"\n ? scrub(entry, entryRole, key, finalPass)\n : scrub(entry, childRole, \"\", finalPass);\n entries.push([scrubbedKey, scrubbedEntry]);\n }\n const result = Object.fromEntries(entries);\n assertPayloadSerialization(result, role, finalPass, replacementPattern);\n return result;\n }\n function scrub(input: unknown, role = \"payload\", field = \"\", finalPass = false): unknown {\n input = specialValue(input);\n if (typeof input === \"string\") return scrubString(input, role, field, finalPass);\n if (Array.isArray(input)) return scrubArray(input, role, finalPass);\n if (input && typeof input === \"object\") {\n return scrubObject(input as Record<string, unknown>, role, finalPass);\n }\n return input;\n }\n const timelineEvent = value && typeof value === \"object\" && [\"client\", \"diagnostic\"].includes((value as { source?: string }).source ?? \"\");\n let role = \"payload\";\n if (preserveKeys) role = timelineEvent ? \"inspectorEvent\" : \"root\";\n const scrubbed = scrub(value, role);\n const generic = redactOAuthValue(scrubbed, { maxStringLength: 262_144, maxDepth: 64, maxArrayEntries: 100_000, maxObjectEntries: 100_000, ...(redactionMarker !== undefined ? { redactionMarker } : {}) });\n const result = scrub(generic, role, \"\", true) as T;\n assertPayloadSerialization(\n result,\n \"payload\",\n true,\n replacementPattern,\n );\n return result;\n}\n\nfunction assertPayloadSerialization(\n value: unknown,\n role: string,\n finalPass: boolean,\n credentialPattern: RegExp | undefined,\n): void {\n if (!finalPass || role !== \"payload\" || !credentialPattern) return;\n const serialized = JSON.stringify(value);\n if (serialized !== undefined && credentialPattern.test(serialized)) {\n throw new McpFnRedactionLimitError(\n \"Credential redaction could not guarantee safe serialized output\",\n );\n }\n}\n\n/** Remove known opaque credential values as well as credential-shaped fields. */\nexport function redactTargetCredentials<T>(target: McpFnTarget, value: T, options: { preserveKeys?: boolean; redactionMarker?: string } = {}): T {\n return scrubCredentials(\n value,\n targetCredentialValues(target),\n options.preserveKeys,\n options.redactionMarker,\n );\n}\n\n/** Assert completed bounded output without applying payload traversal limits. */\nexport function assertTargetArtifactSafe(target: McpFnTarget, value: string): void {\n const { replacementPattern } = credentialPatterns(targetCredentialValues(target));\n if (replacementPattern?.test(value)) {\n throw new McpFnRedactionLimitError(\n \"Credential redaction could not guarantee safe serialized output\",\n );\n }\n}\n\n/** Redact authenticated conformance output using the acquired credential. */\nexport function redactRemoteCredential<T>(credential: McpFnRemoteCredential, value: T, options: { preserveKeys?: boolean } = {}): T {\n return scrubCredentials(value, credentialValues(credential.headers), options.preserveKeys);\n}\n\nconst MAX_CREDENTIAL_HEADERS = 32;\nconst MAX_CREDENTIAL_HEADER_BYTES = 16_384;\nconst MAX_CREDENTIAL_HEADER_VALUE_BYTES = 8_192;\nconst FORBIDDEN_CREDENTIAL_HEADERS = new Set([\n \"connection\",\n \"content-length\",\n \"host\",\n \"proxy-connection\",\n \"te\",\n \"trailer\",\n \"transfer-encoding\",\n \"upgrade\",\n]);\n\nexport type McpFnRemoteCredentialKind = \"api-key\" | \"oauth\" | \"custom\";\n\nexport interface McpFnRemoteCredential {\n /** Credential headers are applied only to the fixed target origin. */\n headers: HeadersInit;\n kind?: McpFnRemoteCredentialKind;\n label?: string;\n}\n\nexport interface McpFnRemoteCredentialContext {\n url: string;\n requestId: string;\n signal?: AbortSignal;\n}\n\n/**\n * Application-owned credential lifecycle for external MCP targets. McpFn\n * acquires once per target open, revokes before disposal, and never serializes\n * the returned headers into descriptors or reports. If acquisition rejects, the\n * provider must roll back its own partial resources; no lease has been returned.\n */\nexport interface McpFnRemoteCredentialProvider {\n acquire(\n context: McpFnRemoteCredentialContext,\n ): McpFnRemoteCredential | Promise<McpFnRemoteCredential>;\n revoke?(\n credential: McpFnRemoteCredential,\n context: McpFnRemoteCredentialContext,\n ): void | Promise<void>;\n dispose?(\n credential: McpFnRemoteCredential,\n context: McpFnRemoteCredentialContext,\n ): void | Promise<void>;\n}\n\nexport interface McpFnRemoteCredentialLease {\n credential: McpFnRemoteCredential;\n release(): Promise<void>;\n /** The lifecycle stage that most recently prevented credential release. */\n cleanupPhase(): \"token-revocation\" | \"transport-close\";\n}\n\nexport interface McpFnAuthenticatedHttpTargetOptions\n extends Omit<McpFnStreamableHttpTargetOptions, \"authProvider\" | \"requestInit\"> {\n credential: McpFnRemoteCredential | McpFnRemoteCredentialProvider;\n requestInit?: Omit<RequestInit, \"headers\" | \"redirect\"> & { headers?: HeadersInit };\n}\n\n/** Create a provider for an already-bounded API key or OAuth-derived token. */\nexport function staticRemoteCredentialProvider(\n credential: McpFnRemoteCredential,\n): McpFnRemoteCredentialProvider {\n return { acquire: () => credential };\n}\n\n/** Acquire a credential and return an idempotent revoke-then-dispose lease. */\nexport async function acquireRemoteCredential(\n source: McpFnRemoteCredential | McpFnRemoteCredentialProvider,\n context: McpFnRemoteCredentialContext,\n): Promise<McpFnRemoteCredentialLease> {\n let provider: McpFnRemoteCredentialProvider;\n let acquired: McpFnRemoteCredential;\n try {\n provider = isCredentialProvider(source) ? source : staticRemoteCredentialProvider(source);\n acquired = await provider.acquire(context);\n } catch {\n // Until acquisition returns, its opaque secrets are unknown to the redactor.\n // The provider owns rollback of resources allocated before it rejects.\n throw new Error(\"Target credential acquisition failed\");\n }\n let credential = acquired;\n try {\n // Detach all valid header forms from provider-owned mutable storage.\n credential = { ...acquired, headers: boundedCredentialEntries(acquired.headers) };\n } catch {\n // Invalid headers are rejected by the caller's validation inside its cleanup\n // boundary. Keep the acquired object so that rejection can still revoke it.\n }\n let releasePromise: Promise<void> | undefined;\n let revoked = false;\n let disposed = false;\n let cleanupPhase: \"token-revocation\" | \"transport-close\" = credential.kind === \"oauth\"\n ? \"token-revocation\"\n : \"transport-close\";\n return {\n credential,\n cleanupPhase: () => cleanupPhase,\n release() {\n releasePromise ??= (async () => {\n // Cancellation of acquisition must not cancel revocation or its retries.\n const cleanupContext = { ...context, signal: new AbortController().signal };\n try {\n // Provider-local state may be required to retry revocation.\n if (!revoked) {\n cleanupPhase = credential.kind === \"oauth\" ? \"token-revocation\" : \"transport-close\";\n await provider.revoke?.(acquired, cleanupContext);\n revoked = true;\n }\n if (!disposed) {\n // Revocation already completed: a later disposal failure is not an\n // authorization-server failure.\n cleanupPhase = \"transport-close\";\n await provider.dispose?.(acquired, cleanupContext);\n disposed = true;\n }\n } catch {\n throw new McpFnClientError(\n \"MCPFN_OPERATION_FAILED\",\n \"Target credential cleanup failed\",\n { phase: cleanupPhase, retryable: true },\n );\n }\n })().catch(error => { releasePromise = undefined; throw error; });\n return releasePromise;\n },\n };\n}\n\n/**\n * A URL-plus-credential target for non-McpFn servers. It delegates MCP and\n * transport behavior to the production @mcpfn/client session engine.\n */\nexport function authenticatedHttpTarget(\n url: string | URL,\n options: McpFnAuthenticatedHttpTargetOptions,\n): McpFnTarget {\n const targetUrl = normalizeRemoteTargetUrl(url);\n const descriptorUrl = new URL(targetUrl);\n descriptorUrl.search = \"\";\n const { credential: _credential, requestInit, ...transportOptions } = options;\n\n const state: SecretState = { active: new Map(), scopes: new Set() };\n const pendingReleases = new Set<() => Promise<void>>();\n const authenticated = customTarget({\n kind: \"authenticated-streamable-http\",\n descriptor: {\n url: descriptorUrl.toString(),\n authenticated: true,\n },\n redact: (value, redaction) => redactTargetCredentials(authenticated, value, { preserveKeys: true, ...redaction }),\n assertArtifactSafe: value => assertTargetArtifactSafe(authenticated, value),\n beginRedactionScope: () => beginTargetCredentialRedaction(authenticated),\n async cleanup() {\n const results = await Promise.allSettled([...pendingReleases].map(release => release()));\n const failures = results.filter((result): result is PromiseRejectedResult => result.status === \"rejected\");\n const failure = failures.find(({ reason }) => reason && typeof reason === \"object\" &&\n (reason as { phase?: unknown }).phase === \"token-revocation\") ?? failures[0];\n if (failure) throw failure.reason;\n },\n async open(targetContext): Promise<McpFnTransportHandle> {\n const context: McpFnRemoteCredentialContext = {\n url: targetUrl.toString(),\n requestId: targetContext.requestId,\n signal: targetContext.signal,\n };\n const lease = await acquireRemoteCredential(options.credential, context);\n const secrets = new Set<string>();\n const release = async () => {\n try { await lease.release(); }\n catch (error) { pendingReleases.add(release); throw error; }\n pendingReleases.delete(release);\n for (const secret of secrets) {\n const count = (state.active.get(secret) ?? 1) - 1;\n if (count) state.active.set(secret, count); else state.active.delete(secret);\n }\n secrets.clear();\n };\n let handle: McpFnTransportHandle | undefined;\n try {\n for (const secret of credentialValues(lease.credential.headers)) {\n secrets.add(secret);\n state.active.set(secret, (state.active.get(secret) ?? 0) + 1);\n for (const scope of state.scopes) scope.add(secret);\n }\n const credentialHeaders = validateRemoteCredentialHeaders(lease.credential.headers);\n const headers = new Headers(requestInit?.headers);\n credentialHeaders.forEach((value, name) => headers.set(name, value));\n const target = streamableHttpTarget(targetUrl, {\n ...transportOptions,\n requestInit: {\n ...requestInit,\n headers,\n // Fetch must not replay credentials to a redirect destination.\n redirect: \"error\",\n },\n });\n handle = await target.open(targetContext);\n } catch (error) {\n // Sanitize while the lease still supplies its immutable header snapshot.\n // Cleanup removes active secrets before the client emits failed-open diagnostics.\n let message = \"Authenticated target could not be opened\";\n try { message = redactRemoteCredential(lease.credential, error instanceof Error ? error.message : String(error)); }\n catch { /* Invalid or oversized credentials must not escape through diagnostics. */ }\n pendingReleases.add(release);\n await release();\n throw new Error(message);\n }\n\n let closePromise: Promise<void> | undefined;\n let transportClosed = false;\n return {\n transport: handle.transport,\n finishAuthorization: handle.finishAuthorization,\n terminateSession: handle.terminateSession,\n close() {\n closePromise ??= Promise.resolve().then(async () => {\n // The client coordinator retains this handle until both stages finish.\n // Never release authentication while transport shutdown still needs retry.\n if (!transportClosed) {\n if (handle!.close) await handle!.close();\n else await handle!.transport.close();\n transportClosed = true;\n }\n await release();\n }).catch(async (error) => {\n closePromise = undefined;\n const phase = transportClosed ? lease.cleanupPhase() : \"transport-close\";\n await targetContext.diagnostic({\n phase, outcome: \"failed\", code: \"MCPFN_CREDENTIAL_CLEANUP_FAILED\",\n requestId: targetContext.requestId, at: new Date().toISOString(),\n target: { kind: \"authenticated-streamable-http\", url: descriptorUrl.toString() },\n details: { message: \"Target credential cleanup failed\" },\n });\n throw error;\n });\n return closePromise;\n },\n };\n },\n });\n targetSecrets.set(authenticated, state);\n return authenticated;\n}\n\nfunction normalizeRemoteTargetUrl(value: string | URL): URL {\n const url = new URL(value.toString());\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n throw new TypeError(\"Authenticated MCP targets must use HTTP or HTTPS\");\n }\n if (url.protocol === \"http:\" && url.hostname !== \"[::1]\" &&\n !/^127(?:\\.\\d{1,3}){3}$/.test(url.hostname)) {\n throw new TypeError(\"Credential-bearing HTTP targets require a literal loopback address; use HTTPS remotely\");\n }\n if (url.username || url.password || url.hash) {\n throw new TypeError(\n \"Authenticated MCP target URLs must not contain userinfo or a fragment\",\n );\n }\n return url;\n}\n\nfunction isCredentialProvider(\n value: McpFnRemoteCredential | McpFnRemoteCredentialProvider,\n): value is McpFnRemoteCredentialProvider {\n return \"acquire\" in value && typeof value.acquire === \"function\";\n}\n\nfunction boundedCredentialEntries(value: HeadersInit): Array<[string, string]> {\n const entries: Array<[string, string]> = [];\n let bytes = 0;\n const append = (name: string, headerValue: string) => {\n if (entries.length >= MAX_CREDENTIAL_HEADERS) throw new TypeError(\"Credential headers exceed the header limit\");\n if (typeof name !== \"string\" || typeof headerValue !== \"string\") throw new TypeError(\"Credential header values must be strings\");\n if (name.length > MAX_CREDENTIAL_HEADER_BYTES || headerValue.length > MAX_CREDENTIAL_HEADER_VALUE_BYTES) throw new TypeError(\"Credential header exceeds the value-size limit\");\n if (utf8Encoder.encode(headerValue).byteLength > MAX_CREDENTIAL_HEADER_VALUE_BYTES) throw new TypeError(\"Credential header exceeds the value-size limit\");\n bytes += utf8Encoder.encode(`${name}: ${headerValue}\\r\\n`).byteLength;\n if (bytes > MAX_CREDENTIAL_HEADER_BYTES) throw new TypeError(\"Credential headers exceed the aggregate size limit\");\n entries.push([name, headerValue]);\n };\n if (value instanceof Headers) value.forEach((v, k) => append(k, v));\n else if (Array.isArray(value)) {\n if (value.length > MAX_CREDENTIAL_HEADERS) throw new TypeError(\"Credential headers exceed the header limit\");\n for (const entry of value) append(entry[0], entry[1]);\n } else {\n for (const name in value) if (Object.hasOwn(value, name)) append(name, value[name]);\n }\n return entries;\n}\n\nexport function validateRemoteCredentialHeaders(value: HeadersInit): Headers {\n const headers = new Headers(boundedCredentialEntries(value));\n const entries: Array<[string, string]> = [];\n headers.forEach((headerValue, name) => entries.push([name, headerValue]));\n if (entries.length === 0) {\n throw new TypeError(\"Authenticated MCP targets require at least one credential header\");\n }\n if (entries.length > MAX_CREDENTIAL_HEADERS) {\n throw new TypeError(`Credential headers exceed the ${MAX_CREDENTIAL_HEADERS}-header limit`);\n }\n let bytes = 0;\n for (const [name, headerValue] of entries) {\n if (!headerValue.trim()) throw new TypeError(\"Credential header values must not be blank\");\n if (FORBIDDEN_CREDENTIAL_HEADERS.has(name)) {\n throw new TypeError(`Credential header ${name} is not allowed`);\n }\n const valueBytes = utf8Encoder.encode(headerValue).byteLength;\n if (valueBytes > MAX_CREDENTIAL_HEADER_VALUE_BYTES) {\n throw new TypeError(`Credential header ${name} exceeds the value-size limit`);\n }\n bytes += utf8Encoder.encode(`${name}: ${headerValue}\\r\\n`).byteLength;\n }\n if (bytes > MAX_CREDENTIAL_HEADER_BYTES) {\n throw new TypeError(\"Credential headers exceed the aggregate size limit\");\n }\n return headers;\n}\n","import type { McpFnDiagnosticPhase } from \"@mcpfn/client\";\nimport { redactOAuthValue } from \"@superfunctions/oauth-core\";\n\nimport {\n disposeMcpFnTargetSuiteArtifactGuard,\n preserveMcpFnTargetSuiteArtifact,\n} from \"./artifact-guards.js\";\nimport type { McpFnTargetSuiteReport } from \"./suite.js\";\n\ndeclare const __MCPFN_TESTING_VERSION__: string;\n\nexport const MCPFN_TESTING_VERSION = __MCPFN_TESTING_VERSION__;\nexport const MCPFN_REPORT_SCHEMA_VERSION = \"1.0.0\";\n\nexport type McpFnFailureLayer =\n | \"mcpfn-preflight\"\n | \"authorization-server\"\n | \"resource-server\"\n | \"mcp-initialization\"\n | \"scenario\"\n | \"upstream-conformance\";\n\nexport interface McpFnReportFailure {\n name: string;\n message: string;\n layer: McpFnFailureLayer;\n code?: string;\n phase?: string;\n details?: Record<string, unknown>;\n}\n\nexport interface McpFnJunitOptions {\n /** Aggregate XML size cap after serialization. Defaults to 1 MiB. */\n maxBytes?: number;\n}\n\nexport interface McpFnTargetSuiteJsonOptions {\n /** JSON indentation. Defaults to compact output; maximum 10 spaces. */\n space?: number;\n /** Include a final newline in the validated artifact. */\n trailingNewline?: boolean;\n}\n\n/** Serialize the exact JSON representation while target proof is retained. */\nexport function serializeMcpFnTargetSuiteReport(\n report: McpFnTargetSuiteReport,\n options: McpFnTargetSuiteJsonOptions = {},\n): string {\n const space = options.space ?? 0;\n if (!Number.isInteger(space) || space < 0 || space > 10) {\n throw new TypeError(\"space must be an integer from 0 through 10\");\n }\n const serialized = JSON.stringify(report, null, space) +\n (options.trailingNewline ? \"\\n\" : \"\");\n return preserveMcpFnTargetSuiteArtifact(report, serialized);\n}\n\n/** Release target-owned proof after every required report encoding is complete. */\nexport function disposeMcpFnTargetSuiteReport(report: McpFnTargetSuiteReport): void {\n disposeMcpFnTargetSuiteArtifactGuard(report);\n}\n\nfunction objectRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : undefined;\n}\n\nfunction redactedFailureCause(error: unknown): Record<string, unknown> | undefined {\n if (!error || typeof error !== \"object\") return undefined;\n const cause = (error as { cause?: unknown }).cause;\n if (cause === undefined) return undefined;\n return objectRecord(redactOAuthValue(cause, {\n maxDepth: 4,\n maxArrayEntries: 20,\n maxObjectEntries: 20,\n maxStringLength: 1_024,\n }));\n}\n\nfunction resourceDenied(\n layer: McpFnFailureLayer,\n record: Record<string, unknown>,\n cause: Record<string, unknown> | undefined,\n): boolean {\n if (layer === \"authorization-server\") return false;\n return [cause?.code, cause?.status, record.code, record.status]\n .some(value => [401, 403].includes(Number(value)));\n}\n\nexport function normalizeMcpFnReportFailure(\n error: unknown,\n fallbackPhase?: McpFnDiagnosticPhase | \"scenario\" | \"upstream-conformance\",\n): McpFnReportFailure {\n const redacted = redactOAuthValue(error, {\n maxDepth: 6,\n maxArrayEntries: 50,\n maxObjectEntries: 50,\n maxStringLength: 2_048,\n });\n const record = objectRecord(redacted) ?? {};\n const phase = stringField(record.phase) ?? fallbackPhase;\n const details = objectRecord(record.details);\n let message = stringField(record.message) ?? String(\n redactOAuthValue(error instanceof Error ? error.message : String(error)),\n );\n const causeRecord = redactedFailureCause(error);\n const causeMessage = stringField(causeRecord?.message);\n if (causeMessage && !message.includes(causeMessage)) message = `${message}: ${causeMessage}`;\n const combinedDetails = causeRecord ? { ...details, cause: causeRecord } : details;\n const layer = failureLayer(phase);\n const deniedByResource = resourceDenied(layer, record, causeRecord);\n return {\n name: stringField(record.name) ?? \"Error\",\n message,\n layer: deniedByResource ? \"resource-server\" : layer,\n ...(stringField(record.code) ? { code: stringField(record.code)! } : {}),\n ...(phase ? { phase } : {}),\n ...(combinedDetails ? { details: combinedDetails } : {}),\n };\n}\n\n/** Serialize a redacted target-suite report as bounded JUnit XML. */\nexport function createMcpFnTargetSuiteJUnit(\n report: McpFnTargetSuiteReport,\n options: McpFnJunitOptions = {},\n): string {\n const maxBytes = options.maxBytes ?? 1_048_576;\n validateArtifactCap(maxBytes);\n const safe = redactOAuthValue(report, {\n maxDepth: 10,\n maxArrayEntries: 1_000,\n maxObjectEntries: 200,\n maxStringLength: 4_096,\n }) as unknown as McpFnTargetSuiteReport;\n // Redaction appends a string sentinel when an array exceeds its cap.\n const results = safe.results.filter((result) => result && typeof result === \"object\" && typeof result.name === \"string\");\n const omitted = report.results.length - results.length;\n const cases = results.map((result) => {\n const duration = Math.max(0, result.durationMs ?? 0) / 1_000;\n let failure = \"\";\n if (result.status !== \"passed\") {\n const failureType = result.status === \"failed\" ? \"scenario\" : \"incomplete\";\n failure = junitFailure(result.error ?? `Scenario ${result.status}`, failureType);\n }\n return ` <testcase name=\"${xml(result.name)}\" classname=\"mcpfn.scenario\" time=\"${duration.toFixed(3)}\">${failure}</testcase>`;\n });\n if (safe.failure) {\n cases.unshift(\n ` <testcase name=\"${xml(safe.failure.phase ?? \"target\")}\" classname=\"mcpfn.${xml(safe.failure.layer)}\" time=\"0.000\">${junitFailure(safe.failure.message, safe.failure.code ?? safe.failure.layer)}</testcase>`,\n );\n }\n if (safe.status === \"incomplete\" || omitted > 0 || (!safe.ok && !safe.failure && results.every((result) => result.status === \"passed\"))) {\n cases.push(` <testcase name=\"suite-incomplete\" classname=\"mcpfn.report\" time=\"0.000\">${junitFailure(safe.incompleteReason ?? \"Suite evidence is incomplete or omitted\", \"incomplete\")}</testcase>`);\n }\n if (cases.length === 0) {\n cases.push(\n ' <testcase name=\"target-suite\" classname=\"mcpfn.target\" time=\"0.000\"></testcase>',\n );\n }\n const failures = cases.filter((entry) => entry.includes(\"<failure \")).length;\n let serialized = junitDocument(safe, cases, failures);\n if (bytes(serialized) <= maxBytes) {\n return preserveMcpFnTargetSuiteArtifact(report, serialized);\n }\n\n const boundedCases = [\n ` <testcase name=\"artifact-cap\" classname=\"mcpfn.report\" time=\"0.000\">${junitFailure(\"JUnit content exceeded maxBytes and was truncated\", \"incomplete\")}</testcase>`,\n ];\n serialized = junitDocument(safe, boundedCases, 1, true);\n if (bytes(serialized) > maxBytes) {\n throw new Error(\"The minimum McpFn JUnit report exceeds maxBytes\");\n }\n return preserveMcpFnTargetSuiteArtifact(report, serialized);\n}\n\nfunction junitDocument(\n report: McpFnTargetSuiteReport,\n cases: string[],\n failures: number,\n truncated = false,\n): string {\n const suiteName = String(redactOAuthValue(`mcpfn:${report.target.kind}`));\n return [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n `<testsuite name=\"${xml(suiteName)}\" tests=\"${cases.length}\" failures=\"${failures}\" errors=\"0\" skipped=\"0\">`,\n \" <properties>\",\n ` <property name=\"mcpfn.report.schema\" value=\"${xml(MCPFN_REPORT_SCHEMA_VERSION)}\"/>`,\n ` <property name=\"mcpfn.testing.version\" value=\"${xml(MCPFN_TESTING_VERSION)}\"/>`,\n ` <property name=\"node.version\" value=\"${xml(report.runtime.node)}\"/>`,\n ` <property name=\"artifact.truncated\" value=\"${truncated}\"/>`,\n \" </properties>\",\n ...cases,\n \"</testsuite>\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction junitFailure(message: string, type: string): string {\n const safe = String(redactOAuthValue(message, { maxStringLength: 4_096 }));\n return `<failure type=\"${xml(type)}\" message=\"${xml(safe)}\">${xml(safe)}</failure>`;\n}\n\nfunction failureLayer(phase: string | undefined): McpFnFailureLayer {\n if (phase === \"resource-discovery\" || phase === \"transport-connect\") {\n return \"resource-server\";\n }\n if (\n phase === \"authorization-server-discovery\" ||\n phase === \"client-registration\" ||\n phase === \"authorization-request\" ||\n phase === \"authorization-callback\" ||\n phase === \"token-exchange\" ||\n phase === \"token-refresh\" ||\n phase === \"token-revocation\"\n ) {\n return \"authorization-server\";\n }\n if (phase === \"mcp-initialize\" || phase === \"capability-operation\") {\n return \"mcp-initialization\";\n }\n if (phase === \"scenario\") return \"scenario\";\n if (phase === \"upstream-conformance\") return \"upstream-conformance\";\n return \"mcpfn-preflight\";\n}\n\nfunction stringField(value: unknown): string | undefined {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return String(value);\n return undefined;\n}\n\nfunction xml(value: string): string {\n return stripInvalidXmlControls(value)\n .replaceAll(\"&\", \"&\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\")\n .replaceAll('\"', \""\")\n .replaceAll(\"'\", \"'\");\n}\n\nfunction stripInvalidXmlControls(value: string): string {\n return value.replace(/[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F\\uFFFE\\uFFFF\\uD800-\\uDFFF]/gu, \"\");\n}\n\nfunction validateArtifactCap(maxBytes: number): void {\n if (!Number.isInteger(maxBytes) || maxBytes < 1_024) {\n throw new Error(\"maxBytes must be an integer of at least 1024\");\n }\n}\n\nfunction bytes(value: string): number {\n return new TextEncoder().encode(value).byteLength;\n}\n","import { McpFnClientError } from \"@mcpfn/client\";\n\nimport type { McpFnTargetSuiteReport } from \"./suite.js\";\n\ninterface McpFnTargetSuiteArtifactGuard {\n maxBytes: number;\n validate(value: string): boolean;\n release(): void;\n}\n\nconst targetSuiteArtifactGuards = new WeakMap<\n McpFnTargetSuiteReport,\n McpFnTargetSuiteArtifactGuard\n>();\nconst targetSuiteArtifactFinalizer = new FinalizationRegistry<() => void>(release => {\n try { release(); } catch {}\n});\n\n/** Retain target-aware proof for artifacts derived after suite execution. */\nexport function registerMcpFnTargetSuiteArtifactGuard(\n report: McpFnTargetSuiteReport,\n validate: (value: string) => boolean,\n release: () => void,\n maxBytes: number,\n): void {\n const previous = targetSuiteArtifactGuards.get(report);\n if (previous) {\n targetSuiteArtifactFinalizer.unregister(report);\n targetSuiteArtifactGuards.delete(report);\n previous.release();\n }\n let active = true;\n const releaseOnce = () => {\n if (!active) return;\n active = false;\n release();\n };\n targetSuiteArtifactGuards.set(report, { maxBytes, validate, release: releaseOnce });\n targetSuiteArtifactFinalizer.register(report, releaseOnce, report);\n}\n\nexport function disposeMcpFnTargetSuiteArtifactGuard(\n report: McpFnTargetSuiteReport,\n): void {\n const guard = targetSuiteArtifactGuards.get(report);\n if (!guard) return;\n targetSuiteArtifactGuards.delete(report);\n targetSuiteArtifactFinalizer.unregister(report);\n guard.release();\n}\n\nexport function preserveMcpFnTargetSuiteArtifact(\n report: McpFnTargetSuiteReport,\n artifact: string,\n): string {\n const guard = targetSuiteArtifactGuards.get(report);\n if (!guard) {\n if (report.artifactValidation === \"target-aware\") {\n throw new McpFnClientError(\n \"MCPFN_OPERATION_FAILED\",\n \"MCP target artifact proof is unavailable\",\n { phase: \"capability-operation\" },\n );\n }\n return artifact;\n }\n if (new TextEncoder().encode(artifact).byteLength > guard.maxBytes) {\n throw new Error(\"Serialized target suite artifact exceeds maxReportBytes\");\n }\n try {\n if (!guard.validate(artifact)) throw new Error(\"unsafe serialized artifact\");\n return artifact;\n } catch {\n throw new McpFnClientError(\n \"MCPFN_OPERATION_FAILED\",\n \"MCP artifact structure conflicts with credential redaction\",\n { phase: \"capability-operation\" },\n );\n }\n}\n","import {\n MCP_APP_EXTENSION_ID,\n type McpFnManifest,\n} from \"@mcpfn/core\";\n\nexport type McpFnServerFeature =\n | \"tools\"\n | \"resources\"\n | \"prompts\"\n | \"completions\"\n | \"tasks\"\n | \"logging\";\n\nexport interface McpFnHostProfile {\n id: string;\n name: string;\n protocolVersions: string[];\n serverFeatures: McpFnServerFeature[];\n clientFeatures?: {\n sampling?: boolean;\n elicitation?: Array<\"form\" | \"url\">;\n roots?: boolean;\n };\n extensions?: string[];\n}\n\nexport interface McpFnHostCompatibilityIssue {\n severity: \"incompatible\" | \"degraded\";\n code: string;\n path: string;\n message: string;\n}\n\nexport interface McpFnHostCompatibilityResult {\n status: \"compatible\" | \"degraded\" | \"incompatible\";\n compatible: boolean;\n issues: McpFnHostCompatibilityIssue[];\n}\n\nexport const MCPFN_HOST_PROFILES = {\n toolsOnly: {\n id: \"mcpfn/tools-only\",\n name: \"Tools-only MCP host\",\n protocolVersions: [\"2025-03-26\", \"2025-06-18\", \"2025-11-25\"],\n serverFeatures: [\"tools\"],\n },\n fullProtocol: {\n id: \"mcpfn/full-protocol\",\n name: \"Full protocol MCP host\",\n protocolVersions: [\"2025-03-26\", \"2025-06-18\", \"2025-11-25\"],\n serverFeatures: [\"tools\", \"resources\", \"prompts\", \"completions\", \"tasks\", \"logging\"],\n clientFeatures: { sampling: true, elicitation: [\"form\", \"url\"], roots: true },\n },\n mcpApps: {\n id: \"mcpfn/mcp-apps\",\n name: \"Full protocol host with MCP Apps\",\n protocolVersions: [\"2025-11-25\"],\n serverFeatures: [\"tools\", \"resources\", \"prompts\", \"completions\", \"tasks\", \"logging\"],\n clientFeatures: { sampling: true, elicitation: [\"form\", \"url\"], roots: true },\n extensions: [MCP_APP_EXTENSION_ID],\n },\n} as const satisfies Record<string, McpFnHostProfile>;\n\nexport function checkHostCompatibility(\n manifest: McpFnManifest,\n profile: McpFnHostProfile,\n): McpFnHostCompatibilityResult {\n const issues: McpFnHostCompatibilityIssue[] = [];\n if (\n manifest.protocolVersions?.length &&\n !manifest.protocolVersions.some((version) => profile.protocolVersions.includes(version))\n ) {\n issues.push({\n severity: \"incompatible\",\n code: \"protocol-version-mismatch\",\n path: \"protocolVersions\",\n message: `${profile.name} and ${manifest.server.name} have no protocol version in common`,\n });\n }\n\n const supportedServerFeatures = new Set(profile.serverFeatures);\n for (const feature of Object.keys(manifest.capabilities ?? {})) {\n if (\n feature === \"experimental\" ||\n supportedServerFeatures.has(feature as McpFnServerFeature)\n ) continue;\n issues.push({\n severity: \"degraded\",\n code: \"server-feature-unavailable\",\n path: `capabilities.${feature}`,\n message: `${profile.name} will not expose the server's ${feature} feature`,\n });\n }\n\n const required = manifest.clientRequirements;\n if (required?.sampling && !profile.clientFeatures?.sampling) {\n issues.push({\n severity: \"incompatible\",\n code: \"sampling-required\",\n path: \"clientRequirements.sampling\",\n message: `${manifest.server.name} requires client sampling`,\n });\n }\n if (required?.roots && !profile.clientFeatures?.roots) {\n issues.push({\n severity: \"incompatible\",\n code: \"roots-required\",\n path: \"clientRequirements.roots\",\n message: `${manifest.server.name} requires client roots`,\n });\n }\n for (const mode of required?.elicitation ?? []) {\n if (!profile.clientFeatures?.elicitation?.includes(mode)) {\n issues.push({\n severity: \"incompatible\",\n code: \"elicitation-required\",\n path: `clientRequirements.elicitation.${mode}`,\n message: `${manifest.server.name} requires ${mode} elicitation`,\n });\n }\n }\n\n const extensions = new Set(profile.extensions ?? []);\n for (const [extension, configuration] of Object.entries(manifest.extensions ?? {})) {\n if (extensions.has(extension)) continue;\n const requiredExtension =\n configuration && typeof configuration === \"object\" &&\n (configuration as Record<string, unknown>).required === true;\n issues.push({\n severity: requiredExtension ? \"incompatible\" : \"degraded\",\n code: \"extension-unavailable\",\n path: `extensions.${extension}`,\n message: `${profile.name} does not support ${extension}`,\n });\n }\n\n if (!extensions.has(MCP_APP_EXTENSION_ID)) {\n for (const tool of manifest.tools) {\n const ui = tool.metadata?.ui as { visibility?: string[] } | undefined;\n if (ui?.visibility?.length && !ui.visibility.includes(\"model\")) {\n issues.push({\n severity: \"incompatible\",\n code: \"app-only-tool-unavailable\",\n path: `tools.${tool.name}.metadata.ui.visibility`,\n message: `${tool.name} is app-only but ${profile.name} does not support MCP Apps`,\n });\n }\n }\n }\n\n issues.sort((left, right) => {\n if (left.path !== right.path) return left.path < right.path ? -1 : 1;\n if (left.code < right.code) return -1;\n if (left.code > right.code) return 1;\n return 0;\n });\n let status: McpFnHostCompatibilityResult[\"status\"] = \"compatible\";\n if (issues.some((issue) => issue.severity === \"incompatible\")) {\n status = \"incompatible\";\n } else if (issues.length > 0) {\n status = \"degraded\";\n }\n return { status, compatible: status !== \"incompatible\", issues };\n}\n","import type { OAuthClientMetadata } from \"@modelcontextprotocol/sdk/shared/auth.js\";\nimport type { McpFnClientRegistrationSource } from \"@mcpfn/auth\";\nimport {\n derivePkceS256Challenge,\n redactOAuthValue,\n} from \"@superfunctions/oauth-core\";\n\nexport interface McpFnHostedRegistrationFixture {\n clientId: string;\n source: McpFnClientRegistrationSource;\n metadata: OAuthClientMetadata;\n}\n\nexport interface McpFnHostedAuthorizationRequestFixture {\n clientId: string;\n redirectUri: string;\n resource: string;\n scopes: string[];\n state: string;\n codeVerifier: string;\n}\n\nexport interface McpFnHostedTokenRequestFixture {\n grantType: string;\n /** Optional independently-authored code override for negative token-exchange cases. */\n code?: string;\n refreshToken?: string;\n refreshAfterExchange?: boolean;\n}\n\nexport interface McpFnHostedAuthorizationCase {\n id: string;\n host: \"chatgpt\" | \"claude\" | \"generic\";\n registration: McpFnHostedRegistrationFixture;\n authorization: McpFnHostedAuthorizationRequestFixture;\n token?: McpFnHostedTokenRequestFixture;\n expected: {\n outcome: \"allowed\" | \"rejected\";\n errorCode?: string;\n phase?: \"client-registration\" | \"authorization-request\" | \"token-exchange\" | \"token-refresh\";\n };\n}\n\nexport interface McpFnHostedAuthorizationTargetAdapter {\n issuer: string;\n prepareRegistration(fixture: McpFnHostedRegistrationFixture): Promise<void>;\n request(request: Request): Promise<Response>;\n}\n\nexport interface McpFnHostedAuthorizationCaseResult {\n formatVersion: 1;\n id: string;\n host: McpFnHostedAuthorizationCase[\"host\"];\n status: \"passed\" | \"failed\";\n phase: \"client-registration\" | \"authorization-request\" | \"token-exchange\" | \"token-refresh\";\n layer: \"mcpfn-preflight\" | \"authorization-server\";\n responseStatus?: number;\n errorCode?: string;\n error?: string;\n}\n\nexport interface McpFnHostedAuthorizationFixtureOptions {\n issuer: string;\n resource: string;\n chatgptRedirectUri?: string;\n claudeRedirectUri?: string;\n}\n\n/**\n * Provider-shaped role-3 fixtures. Registration metadata and authorization\n * requests are separate objects so redirect, grant, and deployment drift can\n * fail instead of being generated from one self-consistent source.\n */\nexport function createHostedAuthorizationFixtures(\n options: McpFnHostedAuthorizationFixtureOptions,\n): McpFnHostedAuthorizationCase[] {\n const issuer = new URL(options.issuer);\n const resource = new URL(options.resource).toString();\n const chatgptRedirect = options.chatgptRedirectUri ??\n \"https://chatgpt.com/connector_platform_oauth_redirect\";\n const claudeRedirect = options.claudeRedirectUri ??\n \"https://claude.example.com/oauth/callback\";\n const verifier = \"mcpfn-role3-shared-pkce-verifier-000000000000000000000000\";\n const registration = (\n clientId: string,\n source: McpFnClientRegistrationSource,\n redirectUri: string,\n grantTypes: string[],\n ): McpFnHostedRegistrationFixture => ({\n clientId,\n source,\n metadata: {\n client_name: `McpFn ${source} fixture`,\n redirect_uris: [redirectUri],\n response_types: [\"code\"],\n grant_types: grantTypes,\n token_endpoint_auth_method: \"none\",\n },\n });\n const authorization = (\n clientId: string,\n redirectUri: string,\n ): McpFnHostedAuthorizationRequestFixture => ({\n clientId,\n redirectUri,\n resource,\n scopes: [\"mcp:read\"],\n state: \"mcpfn-role3-state\",\n codeVerifier: verifier,\n });\n const chatgptId = \"chatgpt-client\";\n const claudeId = new URL(\"/client-metadata/claude\", issuer).toString();\n const dcrId = \"dcr-client\";\n const supported = [\"authorization_code\", \"refresh_token\"];\n return [\n {\n id: \"chatgpt-pre-registered-code-pkce\",\n host: \"chatgpt\",\n registration: registration(chatgptId, \"pre-registered\", chatgptRedirect, supported),\n authorization: authorization(chatgptId, chatgptRedirect),\n token: {\n grantType: \"authorization_code\",\n refreshAfterExchange: true,\n },\n expected: { outcome: \"allowed\" },\n },\n {\n id: \"claude-client-metadata-extensible-grants\",\n host: \"claude\",\n registration: registration(claudeId, \"client-metadata-document\", claudeRedirect, [\n ...supported,\n \"urn:ietf:params:oauth:grant-type:jwt-bearer\",\n \"urn:ietf:params:oauth:grant-type:device_code\",\n \"urn:example:params:oauth:grant-type:extension\",\n ]),\n authorization: authorization(claudeId, claudeRedirect),\n token: {\n grantType: \"authorization_code\",\n refreshAfterExchange: true,\n },\n expected: { outcome: \"allowed\" },\n },\n {\n id: \"dynamic-registration-code-pkce\",\n host: \"generic\",\n registration: registration(dcrId, \"dynamic\", \"http://127.0.0.1/callback\", supported),\n authorization: authorization(dcrId, \"http://127.0.0.1/callback\"),\n token: { grantType: \"authorization_code\" },\n expected: { outcome: \"allowed\" },\n },\n {\n id: \"chatgpt-unregistered-redirect\",\n host: \"chatgpt\",\n registration: registration(chatgptId, \"pre-registered\", chatgptRedirect, supported),\n authorization: authorization(chatgptId, `${chatgptRedirect}/drift`),\n expected: {\n outcome: \"rejected\",\n errorCode: \"invalid_request\",\n phase: \"authorization-request\",\n },\n },\n {\n id: \"incompatible-registration-grants\",\n host: \"generic\",\n registration: registration(\n \"incompatible-client\",\n \"pre-registered\",\n \"https://client.example.com/callback\",\n [\"urn:ietf:params:oauth:grant-type:jwt-bearer\"],\n ),\n authorization: authorization(\n \"incompatible-client\",\n \"https://client.example.com/callback\",\n ),\n expected: {\n outcome: \"rejected\",\n errorCode: \"invalid_client\",\n phase: \"authorization-request\",\n },\n },\n {\n id: \"actual-unsupported-token-grant\",\n host: \"generic\",\n registration: registration(\n \"unsupported-token-client\",\n \"pre-registered\",\n \"https://client.example.com/callback\",\n supported,\n ),\n authorization: authorization(\n \"unsupported-token-client\",\n \"https://client.example.com/callback\",\n ),\n token: { grantType: \"urn:example:unsupported-token-grant\" },\n expected: {\n outcome: \"rejected\",\n errorCode: \"unsupported_grant_type\",\n phase: \"token-exchange\",\n },\n },\n ];\n}\n\n/** Run the independently-configured hosted-authorization matrix. */\nexport async function runHostedAuthorizationRegression(\n target: McpFnHostedAuthorizationTargetAdapter,\n fixtures: readonly McpFnHostedAuthorizationCase[],\n): Promise<McpFnHostedAuthorizationCaseResult[]> {\n const results: McpFnHostedAuthorizationCaseResult[] = [];\n for (const fixture of fixtures) {\n results.push(await runHostedCase(target, fixture));\n }\n return results;\n}\n\nasync function runHostedCase(\n target: McpFnHostedAuthorizationTargetAdapter,\n fixture: McpFnHostedAuthorizationCase,\n): Promise<McpFnHostedAuthorizationCaseResult> {\n let phase: McpFnHostedAuthorizationCaseResult[\"phase\"] = \"client-registration\";\n let responseStatus: number | undefined;\n try {\n await target.prepareRegistration(structuredClone(fixture.registration));\n phase = \"authorization-request\";\n const authorization = hostedAuthorizationUrl(target.issuer, fixture);\n responseStatus = undefined;\n const authorizationResponse = await target.request(new Request(authorization, {\n redirect: \"manual\",\n }));\n responseStatus = authorizationResponse.status;\n const authorizationError = await oauthError(authorizationResponse);\n if (authorizationError) {\n await validateOAuthRejection(authorizationResponse, fixture, target.issuer, \"authorization\");\n return assessHostedCase(fixture, phase, authorizationResponse.status, authorizationError);\n }\n if (!isRedirect(authorizationResponse.status)) {\n throw new Error(`Authorization request did not redirect (HTTP ${authorizationResponse.status})`);\n }\n const code = validatedRedirectCode(authorizationResponse, fixture, target.issuer);\n if (fixture.token) return runHostedTokenCase(target, fixture, fixture.token, code);\n return assessHostedCase(fixture, phase, responseStatus);\n } catch (error) {\n return assessHostedFailure(fixture, phase, responseStatus, error);\n }\n}\n\nasync function runHostedTokenCase(\n target: McpFnHostedAuthorizationTargetAdapter,\n fixture: McpFnHostedAuthorizationCase,\n token: NonNullable<McpFnHostedAuthorizationCase[\"token\"]>,\n code: string,\n): Promise<McpFnHostedAuthorizationCaseResult> {\n let phase: McpFnHostedAuthorizationCaseResult[\"phase\"] = token.grantType === \"refresh_token\"\n ? \"token-refresh\"\n : \"token-exchange\";\n let responseStatus: number | undefined;\n try {\n const tokenResponse = await target.request(hostedTokenRequest(\n target.issuer,\n tokenRequestBody(fixture, token, code),\n ));\n responseStatus = tokenResponse.status;\n const tokenError = await oauthError(tokenResponse);\n if (tokenError) {\n await validateOAuthRejection(tokenResponse, fixture, target.issuer, \"token\");\n return assessHostedCase(fixture, phase, responseStatus, tokenError);\n }\n if (!tokenResponse.ok) throw new Error(`Token request returned HTTP ${tokenResponse.status}`);\n const tokenSet = await validatedTokenSet(tokenResponse);\n if (!token.refreshAfterExchange) {\n return assessHostedCase(fixture, phase, responseStatus);\n }\n if (typeof tokenSet.refresh_token !== \"string\" || !tokenSet.refresh_token) {\n throw new Error(\"Authorization-code response did not include a refresh token\");\n }\n phase = \"token-refresh\";\n responseStatus = undefined;\n const refreshBody = new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: fixture.authorization.clientId,\n refresh_token: tokenSet.refresh_token,\n resource: fixture.authorization.resource,\n });\n const refreshResponse = await target.request(hostedTokenRequest(target.issuer, refreshBody));\n responseStatus = refreshResponse.status;\n const refreshError = await oauthError(refreshResponse);\n if (refreshError) {\n await validateOAuthRejection(refreshResponse, fixture, target.issuer, \"token\");\n return assessHostedCase(fixture, phase, responseStatus, refreshError);\n }\n if (!refreshResponse.ok) {\n throw new Error(`Refresh request returned HTTP ${refreshResponse.status}`);\n }\n await validatedTokenSet(refreshResponse);\n return assessHostedCase(fixture, phase, responseStatus);\n } catch (error) {\n return assessHostedFailure(fixture, phase, responseStatus, error);\n }\n}\n\nfunction tokenRequestBody(\n fixture: McpFnHostedAuthorizationCase,\n token: NonNullable<McpFnHostedAuthorizationCase[\"token\"]>,\n code: string,\n): URLSearchParams {\n const body = new URLSearchParams({\n grant_type: token.grantType,\n client_id: fixture.authorization.clientId,\n });\n if (token.grantType === \"authorization_code\") {\n body.set(\"code\", token.code ?? code);\n body.set(\"redirect_uri\", fixture.authorization.redirectUri);\n body.set(\"code_verifier\", fixture.authorization.codeVerifier);\n body.set(\"resource\", fixture.authorization.resource);\n } else if (token.refreshToken) {\n body.set(\"refresh_token\", token.refreshToken);\n body.set(\"resource\", fixture.authorization.resource);\n }\n return body;\n}\n\nfunction hostedTokenRequest(issuer: string, body: URLSearchParams): Request {\n return new Request(new URL(\"token\", ensureTrailingSlash(issuer)), {\n method: \"POST\",\n redirect: \"manual\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body,\n });\n}\n\nfunction assessHostedFailure(\n fixture: McpFnHostedAuthorizationCase,\n phase: McpFnHostedAuthorizationCaseResult[\"phase\"],\n responseStatus: number | undefined,\n error: unknown,\n): McpFnHostedAuthorizationCaseResult {\n const redacted = redactOAuthValue(error);\n const safe = redacted && typeof redacted === \"object\"\n ? redacted as Record<string, unknown>\n : {};\n const code = typeof safe.code === \"string\" ? safe.code : undefined;\n const message = typeof safe.message === \"string\" ? safe.message : String(redacted);\n return assessHostedCase(\n fixture,\n phase,\n responseStatus,\n code,\n message || \"Hosted adapter failed\",\n );\n}\n\nfunction hostedAuthorizationUrl(\n issuer: string,\n fixture: McpFnHostedAuthorizationCase,\n): URL {\n const authorization = new URL(\"authorize\", ensureTrailingSlash(issuer));\n authorization.searchParams.set(\"response_type\", \"code\");\n authorization.searchParams.set(\"client_id\", fixture.authorization.clientId);\n authorization.searchParams.set(\"redirect_uri\", fixture.authorization.redirectUri);\n authorization.searchParams.set(\n \"code_challenge\",\n derivePkceS256Challenge(fixture.authorization.codeVerifier),\n );\n authorization.searchParams.set(\"code_challenge_method\", \"S256\");\n authorization.searchParams.set(\"state\", fixture.authorization.state);\n authorization.searchParams.set(\"resource\", fixture.authorization.resource);\n authorization.searchParams.set(\"scope\", fixture.authorization.scopes.join(\" \"));\n return authorization;\n}\n\nfunction assessHostedCase(\n fixture: McpFnHostedAuthorizationCase,\n phase: McpFnHostedAuthorizationCaseResult[\"phase\"],\n responseStatus?: number,\n errorCode?: string,\n error?: string,\n): McpFnHostedAuthorizationCaseResult {\n const observedOutcome = errorCode || error ? \"rejected\" : \"allowed\";\n const expected = fixture.expected;\n const passed = !error && observedOutcome === expected.outcome &&\n (expected.errorCode === undefined || expected.errorCode === errorCode) &&\n (expected.phase === undefined || expected.phase === phase);\n const expectedCode = expected.errorCode ? `:${expected.errorCode}` : \"\";\n const observedCode = errorCode ? `:${errorCode}` : \"\";\n const mismatch = `Expected ${expected.outcome}${expectedCode}, received ${observedOutcome}${observedCode}`;\n return {\n formatVersion: 1,\n id: fixture.id,\n host: fixture.host,\n status: passed ? \"passed\" : \"failed\",\n phase,\n layer: phase === \"client-registration\" ? \"mcpfn-preflight\" : \"authorization-server\",\n ...(responseStatus === undefined ? {} : { responseStatus }),\n ...(errorCode ? { errorCode } : {}),\n ...(!passed || error ? {\n error: error ?? mismatch,\n } : {}),\n };\n}\n\nfunction isJsonResponse(response: Response): boolean {\n const mediaType = (response.headers.get(\"content-type\") ?? \"\").split(\";\", 1)[0].trim().toLowerCase();\n return mediaType === \"application/json\" || /^application\\/[a-z0-9!#$&^_.+-]+\\+json$/.test(mediaType);\n}\n\nasync function oauthError(response: Response): Promise<string | undefined> {\n const location = response.headers.get(\"location\");\n if (location) {\n const code = new URL(location).searchParams.get(\"error\");\n if (code) return code;\n }\n if (!isJsonResponse(response)) return undefined;\n const body = await response.clone().json().catch(() => undefined) as\n | { error?: unknown }\n | undefined;\n return typeof body?.error === \"string\" ? body.error : undefined;\n}\n\nasync function validateOAuthRejection(\n response: Response,\n fixture: McpFnHostedAuthorizationCase,\n issuer: string,\n context: \"authorization\" | \"token\",\n): Promise<void> {\n if (context === \"authorization\" && isRedirect(response.status)) {\n validateAuthorizationErrorRedirect(response, fixture, issuer);\n return;\n }\n const body = await response.clone().json().catch(() => undefined);\n const registered = (fixture.registration.metadata.redirect_uris as string[])\n ?.includes(fixture.authorization.redirectUri);\n if (context === \"authorization\" && body?.error !== \"invalid_client\" && registered) {\n throw new Error(\"Registered authorization requests require an OAuth error callback\");\n }\n if (response.status !== 400) throw new Error(\"OAuth error response has invalid HTTP status\");\n if (response.headers.has(\"location\") || !isJsonResponse(response) ||\n !body || typeof body.error !== \"string\" || !body.error) {\n throw new Error(\"OAuth error response must be a JSON error envelope\");\n }\n}\n\nfunction validateAuthorizationErrorRedirect(\n response: Response,\n fixture: McpFnHostedAuthorizationCase,\n issuer: string,\n): void {\n const callback = new URL(response.headers.get(\"location\") ?? \"\");\n // Redirects must target the registered URI, never a rejected requested URI.\n const registered = fixture.registration.metadata.redirect_uris as string[];\n if (!registered?.includes(fixture.authorization.redirectUri)) {\n throw new Error(\"Rejected redirect URI must not receive a callback\");\n }\n const errors = callback.searchParams.getAll(\"error\");\n if (errors.length !== 1 || !errors[0] || callback.searchParams.has(\"code\")) {\n throw new Error(\"Invalid OAuth error callback\");\n }\n if (errors[0] === \"invalid_client\") {\n throw new Error(\"Invalid-client authorization failures must not redirect\");\n }\n callback.searchParams.delete(\"error\");\n callback.searchParams.delete(\"error_description\");\n callback.searchParams.delete(\"error_uri\");\n callback.searchParams.set(\"code\", \"error-envelope-validation\");\n validatedRedirectCode(\n new Response(null, { status: response.status, headers: { location: callback.toString() } }),\n fixture,\n issuer,\n );\n}\n\nfunction validatedRedirectCode(\n response: Response,\n fixture: McpFnHostedAuthorizationCase,\n issuer: string,\n): string {\n const location = response.headers.get(\"location\");\n if (!location) throw new Error(\"Authorization callback is missing\");\n const callback = new URL(location);\n const expected = new URL(fixture.authorization.redirectUri);\n const codes = callback.searchParams.getAll(\"code\");\n const states = callback.searchParams.getAll(\"state\");\n if (codes.length !== 1 || !codes[0] || states.length !== 1 || states[0] !== fixture.authorization.state) {\n throw new Error(\"Authorization callback code or state is invalid\");\n }\n const issuers = callback.searchParams.getAll(\"iss\");\n if (issuers.length > 1 || (issuers.length === 1 && issuers[0] !== issuer)) {\n throw new Error(\"Authorization callback issuer is invalid\");\n }\n if (callback.protocol !== expected.protocol || callback.host !== expected.host ||\n callback.username !== expected.username || callback.password !== expected.password ||\n callback.pathname !== expected.pathname || callback.hash !== expected.hash ||\n [...new Set(expected.searchParams.keys())].some((key) =>\n JSON.stringify(callback.searchParams.getAll(key)) !== JSON.stringify(expected.searchParams.getAll(key)))) {\n throw new Error(\"Authorization callback destination is invalid\");\n }\n return codes[0];\n}\n\nasync function validatedTokenSet(response: Response): Promise<{ refresh_token?: unknown }> {\n if (response.status !== 200) throw new Error(\"Successful token responses must use HTTP 200\");\n if (!isJsonResponse(response)) throw new Error(\"Token response must use a JSON media type\");\n if (!hasHeaderDirective(response.headers.get(\"cache-control\"), \"no-store\") ||\n !hasHeaderDirective(response.headers.get(\"pragma\"), \"no-cache\")) {\n throw new Error(\"Token responses must disable caching with Cache-Control: no-store and Pragma: no-cache\");\n }\n const value = await response.clone().json() as Record<string, unknown> | null;\n if (!value || typeof value.access_token !== \"string\" || !/^[\\dA-Za-z._~+/-]+=*$/.test(value.access_token) ||\n typeof value.token_type !== \"string\" || value.token_type.toLowerCase() !== \"bearer\") {\n throw new Error(\"Token response requires an access token and Bearer token type\");\n }\n return value;\n}\n\nfunction hasHeaderDirective(value: string | null, expected: string): boolean {\n return (value ?? \"\").split(\",\").some((directive) =>\n directive.trim().toLowerCase() === expected,\n );\n}\n\nfunction isRedirect(status: number): boolean {\n return [301, 302, 303, 307, 308].includes(status);\n}\n\nfunction ensureTrailingSlash(value: string): URL {\n const url = new URL(value);\n if (!url.pathname.endsWith(\"/\")) url.pathname += \"/\";\n return url;\n}\n","import type {\n CallToolResult,\n CreateTaskResult,\n GetPromptResult,\n ListTasksResult,\n ReadResourceResult,\n Task,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { McpFnClientEvent, McpFnClientEventKind } from \"@mcpfn/client\";\n\nimport { McpFnAssertionError, assertStructuredTextParity, stableJson } from \"./assertions.js\";\nimport type { McpFnTestClient } from \"./client.js\";\n\nexport type McpFnScenarioSideEffect = \"none\" | \"idempotent\" | \"non-idempotent\";\n\nexport interface McpFnScenarioBase {\n formatVersion?: 1;\n name: string;\n /** Defaults to the runner timeout. */\n timeoutMs?: number;\n sideEffect?: McpFnScenarioSideEffect;\n status?: \"complete\" | \"incomplete\";\n incompleteReason?: string;\n /** Environment-backed placeholders used by this scenario, never their values. */\n variables?: string[];\n}\n\nexport interface McpFnToolScenario extends McpFnScenarioBase {\n kind?: \"tools.call\";\n tool: string;\n arguments?: Record<string, unknown>;\n expect?: {\n isError?: boolean;\n structuredContent?: unknown;\n structuredTextParity?: boolean;\n };\n verify?(result: CallToolResult): void | Promise<void>;\n}\n\nexport interface McpFnInventoryScenario extends McpFnScenarioBase {\n kind: \"tools.list\" | \"resources.list\" | \"resources.templates.list\" | \"prompts.list\";\n expectNames?: string[];\n}\n\nexport interface McpFnResourceScenario extends McpFnScenarioBase {\n kind: \"resources.read\" | \"resources.subscribe\" | \"resources.unsubscribe\";\n uri: string;\n expect?: unknown;\n}\n\nexport interface McpFnPromptScenario extends McpFnScenarioBase {\n kind: \"prompts.get\";\n prompt: string;\n arguments?: Record<string, string>;\n expect?: unknown;\n}\n\nexport interface McpFnInitializeScenario extends McpFnScenarioBase {\n kind: \"initialize\";\n expectCapabilities?: Record<string, unknown>;\n}\n\nexport interface McpFnCreateTaskScenario extends McpFnScenarioBase {\n kind: \"tools.call:task\";\n tool: string;\n arguments?: Record<string, unknown>;\n task?: { ttl?: number };\n expect?: unknown;\n}\n\nexport interface McpFnTaskScenario extends McpFnScenarioBase {\n kind: \"tasks.get\" | \"tasks.result\" | \"tasks.cancel\" | \"tasks.list\";\n taskId?: string;\n cursor?: string;\n expect?: unknown;\n}\n\nexport interface McpFnEventScenario extends McpFnScenarioBase {\n kind: \"events.expect\";\n event: McpFnClientEventKind;\n minimum?: number;\n expectPayload?: unknown;\n}\n\nexport interface McpFnAuthScenario extends McpFnScenarioBase {\n kind: \"auth.assert\";\n phase: string;\n expect: {\n outcome: \"allowed\" | \"denied\";\n code?: string;\n };\n input?: Record<string, unknown>;\n}\n\nexport type McpFnScenario =\n | McpFnToolScenario\n | McpFnInventoryScenario\n | McpFnResourceScenario\n | McpFnPromptScenario\n | McpFnInitializeScenario\n | McpFnCreateTaskScenario\n | McpFnTaskScenario\n | McpFnEventScenario\n | McpFnAuthScenario;\n\nexport interface McpFnScenarioArtifact {\n formatVersion: 1;\n kind: \"mcpfn.scenarios\";\n status: \"complete\" | \"incomplete\";\n scenarios: McpFnScenario[];\n variables?: string[];\n incompleteReason?: string;\n}\n\nexport type McpFnRecordedOperation =\n | { kind: \"tools.call\"; name: string; arguments?: Record<string, unknown> }\n | { kind: \"tools.call:task\"; name: string; arguments?: Record<string, unknown>; task?: { ttl?: number } }\n | { kind: \"resources.read\"; uri: string }\n | { kind: \"resources.subscribe\"; uri: string }\n | { kind: \"resources.unsubscribe\"; uri: string }\n | { kind: \"prompts.get\"; name: string; arguments?: Record<string, string> }\n | { kind: \"tasks.get\"; taskId: string }\n | { kind: \"tasks.result\"; taskId: string }\n | { kind: \"tasks.cancel\"; taskId: string }\n | { kind: \"tasks.list\"; cursor?: string };\n\nexport type McpFnRecordedOperationResult =\n | CallToolResult\n | ReadResourceResult\n | GetPromptResult\n | CreateTaskResult\n | Task\n | ListTasksResult\n | void;\n\nexport interface McpFnScenarioResult {\n formatVersion: 1;\n name: string;\n operation: string;\n tool?: string;\n status: \"passed\" | \"failed\" | \"incomplete\";\n sideEffect: McpFnScenarioSideEffect;\n durationMs: number;\n error?: string;\n /** Observed client events discarded while this scenario was running. */\n droppedObservedEvents?: number;\n /** Dropped observed events whose original payload could not be safely redacted. */\n redactionOmittedObservedEvents?: number;\n}\n\nexport interface McpFnScenarioReport {\n formatVersion: 1;\n kind: \"mcpfn.scenario-report\";\n status: \"complete\" | \"incomplete\";\n manifestHash?: string;\n total: number;\n passed: number;\n failed: number;\n incomplete: number;\n droppedResults: number;\n droppedObservedEvents: number;\n redactionOmittedObservedEvents?: number;\n incompleteReason?: string;\n results: McpFnScenarioResult[];\n}\n\n/** Convert an observed production-client operation into the shared runner contract. */\nexport function createMcpFnScenario(\n name: string,\n operation: McpFnRecordedOperation,\n result: McpFnRecordedOperationResult,\n): McpFnScenario {\n switch (operation.kind) {\n case \"tools.call\":\n return createToolCallScenario(name, operation, result as CallToolResult);\n case \"tools.call:task\":\n return createToolTaskScenario(name, operation);\n case \"resources.read\":\n return createResourceReadScenario(name, operation, result);\n case \"resources.subscribe\":\n case \"resources.unsubscribe\":\n return createResourceLifecycleScenario(name, operation);\n case \"tasks.get\":\n case \"tasks.cancel\":\n return createTaskLifecycleScenario(name, operation);\n case \"tasks.result\":\n return createTaskResultScenario(name, operation, result);\n case \"tasks.list\":\n return createTaskListScenario(name, operation);\n case \"prompts.get\":\n return createPromptScenario(name, operation, result);\n }\n}\n\nfunction scenarioBase(name: string, sideEffect: McpFnScenarioSideEffect) {\n return { formatVersion: 1 as const, name, sideEffect };\n}\n\nfunction createToolCallScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"tools.call\" }>,\n result: CallToolResult,\n): McpFnToolScenario {\n return {\n ...scenarioBase(name, \"non-idempotent\"),\n kind: \"tools.call\",\n tool: operation.name,\n ...(operation.arguments ? { arguments: operation.arguments } : {}),\n expect: {\n isError: Boolean(result.isError),\n ...(result.structuredContent !== undefined\n ? { structuredContent: result.structuredContent }\n : {}),\n },\n };\n}\n\nfunction createToolTaskScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"tools.call:task\" }>,\n): McpFnCreateTaskScenario {\n return {\n ...scenarioBase(name, \"non-idempotent\"),\n kind: operation.kind,\n tool: operation.name,\n ...(operation.arguments ? { arguments: operation.arguments } : {}),\n ...(operation.task ? { task: operation.task } : {}),\n };\n}\n\nfunction createResourceReadScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"resources.read\" }>,\n result: McpFnRecordedOperationResult,\n): McpFnResourceScenario {\n return {\n ...scenarioBase(name, \"none\"),\n kind: operation.kind,\n uri: operation.uri,\n expect: result,\n };\n}\n\nfunction createResourceLifecycleScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"resources.subscribe\" | \"resources.unsubscribe\" }>,\n): McpFnResourceScenario {\n return {\n ...scenarioBase(name, \"idempotent\"),\n kind: operation.kind,\n uri: operation.uri,\n };\n}\n\nfunction createTaskLifecycleScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"tasks.get\" | \"tasks.cancel\" }>,\n): McpFnTaskScenario {\n return {\n ...scenarioBase(name, operation.kind === \"tasks.cancel\" ? \"idempotent\" : \"none\"),\n kind: operation.kind,\n taskId: operation.taskId,\n };\n}\n\nfunction createTaskResultScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"tasks.result\" }>,\n result: McpFnRecordedOperationResult,\n): McpFnTaskScenario {\n return {\n ...scenarioBase(name, \"none\"),\n kind: operation.kind,\n taskId: operation.taskId,\n expect: result,\n };\n}\n\nfunction createTaskListScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"tasks.list\" }>,\n): McpFnTaskScenario {\n return {\n ...scenarioBase(name, \"none\"),\n kind: operation.kind,\n ...(operation.cursor ? { cursor: operation.cursor } : {}),\n };\n}\n\nfunction createPromptScenario(\n name: string,\n operation: Extract<McpFnRecordedOperation, { kind: \"prompts.get\" }>,\n result: McpFnRecordedOperationResult,\n): McpFnPromptScenario {\n return {\n ...scenarioBase(name, \"none\"),\n kind: operation.kind,\n prompt: operation.name,\n ...(operation.arguments ? { arguments: operation.arguments } : {}),\n expect: result,\n };\n}\n\n/** Validate an unknown scenario module before it reaches the shared runner. */\nexport function validateMcpFnScenarios(value: unknown): McpFnScenario[] {\n const artifact = isScenarioArtifact(value) ? value : undefined;\n if (artifact?.status === \"incomplete\") {\n throw new Error(`McpFn scenario artifact is incomplete: ${artifact.incompleteReason}`);\n }\n const scenarios = artifact?.scenarios ?? value;\n if (!Array.isArray(scenarios)) {\n throw new TypeError(\"Scenario module must export an array or mcpfn.scenarios artifact\");\n }\n for (const [index, scenario] of scenarios.entries()) {\n validateScenarioCandidate(scenario, index);\n }\n return scenarios as McpFnScenario[];\n}\n\nconst SCENARIO_KINDS_WITHOUT_REQUIRED_FIELDS = new Set([\n \"initialize\",\n \"tools.list\",\n \"resources.list\",\n \"resources.templates.list\",\n \"prompts.list\",\n \"tasks.list\",\n \"auth.assert\",\n]);\n\nfunction validateScenarioCandidate(scenario: unknown, index: number): void {\n if (!scenario || typeof scenario !== \"object\" || Array.isArray(scenario)) {\n throw new TypeError(`Invalid scenario at index ${index}`);\n }\n const candidate = scenario as Record<string, unknown>;\n validateScenarioIdentity(candidate, index);\n const kind = scenarioKind(candidate, index);\n validateScenarioOperation(candidate, kind, index);\n validateScenarioLimits(candidate, index);\n if (kind === \"events.expect\") validateEventScenario(candidate, index);\n validateScenarioMetadata(candidate, index);\n if (kind === \"auth.assert\") validateAuthScenario(candidate, index);\n}\n\nfunction validateScenarioIdentity(candidate: Record<string, unknown>, index: number): void {\n if (candidate.formatVersion !== undefined && candidate.formatVersion !== 1) {\n throw new TypeError(`Invalid scenario at index ${index}: unsupported formatVersion`);\n }\n if (typeof candidate.name !== \"string\" || !candidate.name.trim()) {\n throw new TypeError(`Invalid scenario at index ${index}: name is required`);\n }\n}\n\nfunction scenarioKind(candidate: Record<string, unknown>, index: number): string {\n const kind = candidate.kind ?? \"tools.call\";\n if (typeof kind !== \"string\") {\n throw new TypeError(`Invalid scenario at index ${index}: kind must be a string`);\n }\n return kind;\n}\n\nfunction validateScenarioOperation(\n candidate: Record<string, unknown>,\n kind: string,\n index: number,\n): void {\n const requiredField = requiredScenarioField(kind);\n if (requiredField && typeof candidate[requiredField] !== \"string\") {\n throw new TypeError(`Invalid scenario at index ${index}: ${kind} requires ${requiredField}`);\n }\n if (!requiredField && !SCENARIO_KINDS_WITHOUT_REQUIRED_FIELDS.has(kind)) {\n throw new TypeError(`Invalid scenario at index ${index}: unsupported kind ${kind}`);\n }\n}\n\nfunction validateScenarioLimits(candidate: Record<string, unknown>, index: number): void {\n if (\n candidate.timeoutMs !== undefined &&\n (!Number.isInteger(candidate.timeoutMs) || Number(candidate.timeoutMs) < 1 || Number(candidate.timeoutMs) > 300_000)\n ) {\n throw new TypeError(`Invalid scenario at index ${index}: timeoutMs must be 1..300000`);\n }\n if (\n candidate.variables !== undefined &&\n (\n !Array.isArray(candidate.variables) ||\n candidate.variables.some((entry) => typeof entry !== \"string\" || !/^[A-Z][A-Z0-9_]*$/.test(entry))\n )\n ) {\n throw new TypeError(`Invalid scenario at index ${index}: variables must be environment names`);\n }\n}\n\nfunction validateScenarioMetadata(candidate: Record<string, unknown>, index: number): void {\n if (\n candidate.status !== undefined &&\n candidate.status !== \"complete\" &&\n candidate.status !== \"incomplete\"\n ) {\n throw new TypeError(`Invalid scenario at index ${index}: status must be complete or incomplete`);\n }\n if (candidate.status === \"incomplete\" && typeof candidate.incompleteReason !== \"string\") {\n throw new TypeError(`Invalid scenario at index ${index}: incompleteReason is required`);\n }\n if (\n candidate.sideEffect !== undefined &&\n (typeof candidate.sideEffect !== \"string\" || ![\"none\", \"idempotent\", \"non-idempotent\"].includes(candidate.sideEffect))\n ) {\n throw new TypeError(`Invalid scenario at index ${index}: sideEffect is unsupported`);\n }\n}\n\nfunction validateEventScenario(candidate: Record<string, unknown>, index: number): void {\n if (\n candidate.minimum !== undefined &&\n (!Number.isSafeInteger(candidate.minimum) || Number(candidate.minimum) < 1)\n ) {\n throw new TypeError(\n `Invalid scenario at index ${index}: events.expect minimum must be a positive integer`,\n );\n }\n}\n\nfunction validateAuthScenario(candidate: Record<string, unknown>, index: number): void {\n const expectation = candidate.expect as Record<string, unknown> | undefined;\n if (\n typeof candidate.phase !== \"string\" ||\n !expectation ||\n typeof expectation.outcome !== \"string\" ||\n ![\"allowed\", \"denied\"].includes(expectation.outcome)\n ) {\n throw new TypeError(`Invalid scenario at index ${index}: auth.assert expectation is required`);\n }\n}\n\nexport function createMcpFnScenarioArtifact(\n scenarios: McpFnScenario[],\n options?: Omit<McpFnScenarioArtifact, \"formatVersion\" | \"kind\" | \"scenarios\">,\n): McpFnScenarioArtifact {\n const artifactOptions = options ?? { status: \"complete\" as const };\n return {\n formatVersion: 1,\n kind: \"mcpfn.scenarios\",\n ...artifactOptions,\n scenarios: validateMcpFnScenarios(scenarios),\n };\n}\n\nfunction isScenarioArtifact(value: unknown): value is McpFnScenarioArtifact {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const candidate = value as Record<string, unknown>;\n if (candidate.kind !== \"mcpfn.scenarios\") return false;\n if (candidate.formatVersion !== 1) {\n throw new Error(\"Unsupported McpFn scenario artifact formatVersion\");\n }\n if (candidate.status !== \"complete\" && candidate.status !== \"incomplete\") {\n throw new Error(\"McpFn scenario artifact status must be complete or incomplete\");\n }\n if (candidate.status === \"incomplete\" && typeof candidate.incompleteReason !== \"string\") {\n throw new Error(\"Incomplete McpFn scenario artifact requires incompleteReason\");\n }\n return true;\n}\n\nexport async function runScenarios(\n client: McpFnTestClient<unknown>,\n scenarios: McpFnScenario[],\n options: McpFnScenarioRunOptions = {},\n): Promise<McpFnScenarioResult[]> {\n if (\n options.defaultTimeoutMs !== undefined &&\n (\n !Number.isInteger(options.defaultTimeoutMs) ||\n options.defaultTimeoutMs < 1 ||\n options.defaultTimeoutMs > 300_000\n )\n ) {\n throw new Error(\"defaultTimeoutMs must be an integer from 1 through 300000\");\n }\n if (\n options.maxScenarios !== undefined &&\n (!Number.isInteger(options.maxScenarios) || options.maxScenarios < 1)\n ) {\n throw new Error(\"maxScenarios must be a positive integer\");\n }\n if (\n options.maxErrorBytes !== undefined &&\n (!Number.isInteger(options.maxErrorBytes) || options.maxErrorBytes < 64)\n ) {\n throw new Error(\"maxErrorBytes must be an integer of at least 64\");\n }\n if (\n options.maxObservedEvents !== undefined &&\n (!Number.isInteger(options.maxObservedEvents) || options.maxObservedEvents < 1)\n ) {\n throw new Error(\"maxObservedEvents must be a positive integer\");\n }\n if (scenarios.length > (options.maxScenarios ?? 1_000)) {\n throw new Error(`Scenario count exceeds the configured cap of ${options.maxScenarios ?? 1_000}`);\n }\n const results: McpFnScenarioResult[] = [];\n const observedEvents: McpFnClientEvent[] = [];\n const maxObservedEvents = options.maxObservedEvents ?? 500;\n let droppedObservedEvents = 0;\n let redactionOmittedObservedEvents = 0;\n let observedRedactionOmissionEvents = 0;\n let attributedDroppedObservedEvents = 0;\n let attributedRedactionOmittedObservedEvents = 0;\n const initialClientEventRedactionOmissions = client.session\n .getRedactionOmissionCounts().clientEvents;\n const pushResult = (result: McpFnScenarioResult): void => {\n const newlyDropped = droppedObservedEvents - attributedDroppedObservedEvents;\n const newlyRedactionOmitted = redactionOmittedObservedEvents -\n attributedRedactionOmittedObservedEvents;\n results.push({\n ...result,\n ...(newlyDropped > 0\n ? { droppedObservedEvents: (result.droppedObservedEvents ?? 0) + newlyDropped }\n : {}),\n ...(newlyRedactionOmitted > 0\n ? {\n redactionOmittedObservedEvents:\n (result.redactionOmittedObservedEvents ?? 0) + newlyRedactionOmitted,\n }\n : {}),\n });\n attributedDroppedObservedEvents = droppedObservedEvents;\n attributedRedactionOmittedObservedEvents = redactionOmittedObservedEvents;\n };\n const unsubscribe = client.session.onEvent((event) => {\n if (client.session.isRedactionOmission(event)) {\n observedRedactionOmissionEvents += 1;\n droppedObservedEvents += 1;\n redactionOmittedObservedEvents += 1;\n return;\n }\n observedEvents.push(event);\n if (observedEvents.length > maxObservedEvents) {\n observedEvents.shift();\n droppedObservedEvents += 1;\n }\n });\n let timedOutScenario: string | undefined;\n try {\n for (const scenario of scenarios) {\n const startedAt = performance.now();\n const operation = scenario.kind ?? \"tools.call\";\n const common = {\n formatVersion: 1 as const,\n name: scenario.name,\n operation,\n ...(isToolScenario(scenario) ? { tool: scenario.tool } : {}),\n sideEffect: scenario.sideEffect ?? defaultSideEffect(operation),\n };\n if (timedOutScenario) {\n pushResult({\n ...common,\n status: \"incomplete\",\n durationMs: 0,\n error: truncateError(`Skipped after timed-out scenario: ${timedOutScenario}`, options, client),\n });\n continue;\n }\n const resolved = resolveScenarioVariables(scenario, options.variables);\n if (resolved.missing.length > 0) {\n pushResult({\n ...common,\n status: \"incomplete\",\n durationMs: 0,\n error: truncateError(\n `Missing scenario variables: ${resolved.missing.join(\", \")}`,\n options,\n client,\n ),\n });\n continue;\n }\n if (scenario.status === \"incomplete\") {\n pushResult({\n ...common,\n status: \"incomplete\",\n durationMs: 0,\n error: truncateError(scenario.incompleteReason ?? \"Scenario is incomplete\", options, client),\n });\n continue;\n }\n const timeoutMs = scenario.timeoutMs ?? options.defaultTimeoutMs ?? 30_000;\n const controller = new AbortController();\n let timer: ReturnType<typeof setTimeout> | undefined;\n let timedOut = false;\n try {\n await Promise.race([\n executeScenario(client, resolved.scenario, {\n signal: controller.signal,\n timeout: timeoutMs,\n }, observedEvents, options),\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n timedOut = true;\n controller.abort();\n reject(new McpFnAssertionError(`Scenario timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n }),\n ]);\n pushResult({\n ...common,\n status: \"passed\",\n durationMs: performance.now() - startedAt,\n });\n } catch (error) {\n pushResult({\n ...common,\n status: \"failed\",\n durationMs: performance.now() - startedAt,\n error: truncateError(error instanceof Error ? error.message : String(error), options, client),\n });\n if (timedOut) timedOutScenario = scenario.name;\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n } finally {\n const unobservedRedactionOmissions = Math.max(\n 0,\n client.session.getRedactionOmissionCounts().clientEvents -\n initialClientEventRedactionOmissions - observedRedactionOmissionEvents,\n );\n droppedObservedEvents += unobservedRedactionOmissions;\n redactionOmittedObservedEvents += unobservedRedactionOmissions;\n const unattributed = droppedObservedEvents - attributedDroppedObservedEvents;\n const lastResult = results.at(-1);\n if (lastResult && unattributed > 0) {\n lastResult.droppedObservedEvents =\n (lastResult.droppedObservedEvents ?? 0) + unattributed;\n }\n const unattributedRedaction = redactionOmittedObservedEvents -\n attributedRedactionOmittedObservedEvents;\n if (lastResult && unattributedRedaction > 0) {\n lastResult.redactionOmittedObservedEvents =\n (lastResult.redactionOmittedObservedEvents ?? 0) + unattributedRedaction;\n }\n unsubscribe();\n }\n return results;\n}\n\nexport interface McpFnScenarioRunOptions {\n defaultTimeoutMs?: number;\n maxScenarios?: number;\n maxErrorBytes?: number;\n /** Observed client-event count cap. Defaults to 500. */\n maxObservedEvents?: number;\n variables?: Record<string, string | undefined>;\n auth?(scenario: McpFnAuthScenario, signal: AbortSignal): Promise<{\n outcome: \"allowed\" | \"denied\";\n code?: string;\n }>;\n}\n\nfunction resolveScenarioVariables(\n scenario: McpFnScenario,\n supplied: Record<string, string | undefined> | undefined,\n): { scenario: McpFnScenario; missing: string[] } {\n const values = { ...process.env, ...supplied };\n const required = new Set(scenario.variables ?? []);\n const marker = /\\$\\{([A-Z][A-Z0-9_]*)\\}/g;\n const encodedMarker = /%24%7[Bb]([A-Z][A-Z0-9_]*)%7[Dd]/g;\n const visitString = (value: string): string => {\n for (const match of value.matchAll(marker)) required.add(match[1]);\n for (const match of value.matchAll(encodedMarker)) required.add(match[1]);\n return value\n .replace(marker, (original, name: string) => values[name] ?? original)\n .replace(encodedMarker, (original, name: string) =>\n values[name] === undefined ? original : encodeURIComponent(values[name]),\n );\n };\n const visit = (value: unknown): unknown => {\n if (typeof value === \"string\") return visitString(value);\n if (Array.isArray(value)) return value.map(visit);\n if (value && typeof value === \"object\") {\n const entries: Array<[string, unknown]> = [];\n const keys = new Set<string>();\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {\n const resolvedKey = visitString(key);\n if (keys.has(resolvedKey)) {\n throw new Error(\"Scenario variable substitution creates duplicate object key\");\n }\n keys.add(resolvedKey);\n entries.push([resolvedKey, visit(entry)]);\n }\n return Object.fromEntries(entries);\n }\n return value;\n };\n const resolved = visit(scenario) as McpFnScenario;\n return {\n scenario: resolved,\n missing: [...required]\n .filter((name) => values[name] === undefined)\n .sort(compareCodeUnits),\n };\n}\n\nexport function createMcpFnScenarioReport(\n results: McpFnScenarioResult[],\n options: { manifestHash?: string; maxBytes?: number } = {},\n): McpFnScenarioReport {\n const failed = results.filter((result) => result.status === \"failed\").length;\n const incomplete = results.filter((result) => result.status === \"incomplete\").length;\n const droppedObservedEvents = results.reduce(\n (total, result) => total + (result.droppedObservedEvents ?? 0),\n 0,\n );\n const redactionOmittedObservedEvents = results.reduce(\n (total, result) => total + (result.redactionOmittedObservedEvents ?? 0),\n 0,\n );\n const overflowedObservedEvents = droppedObservedEvents - redactionOmittedObservedEvents;\n const report: McpFnScenarioReport = {\n formatVersion: 1,\n kind: \"mcpfn.scenario-report\",\n status: incomplete === 0 && droppedObservedEvents === 0 ? \"complete\" : \"incomplete\",\n ...(options.manifestHash ? { manifestHash: options.manifestHash } : {}),\n total: results.length,\n passed: results.length - failed - incomplete,\n failed,\n incomplete,\n droppedResults: 0,\n droppedObservedEvents,\n ...(redactionOmittedObservedEvents > 0 ? { redactionOmittedObservedEvents } : {}),\n ...(droppedObservedEvents > 0\n ? {\n incompleteReason: [\n ...(redactionOmittedObservedEvents > 0\n ? [\"Observed client events were omitted because credential redaction failed\"]\n : []),\n ...(overflowedObservedEvents > 0\n ? [\"Observed client events exceeded maxObservedEvents\"]\n : []),\n ].join(\"; \"),\n }\n : {}),\n results: structuredClone(results),\n };\n const maxBytes = options.maxBytes ?? 1_048_576;\n if (!Number.isInteger(maxBytes) || maxBytes < 1_024) {\n throw new Error(\"maxBytes must be an integer of at least 1024\");\n }\n if (serializedBytes(report) > maxBytes) {\n report.status = \"incomplete\";\n report.incompleteReason = \"Report content exceeded maxBytes and was truncated\";\n }\n while (serializedBytes(report) > maxBytes && report.results.length > 0) {\n report.results.pop();\n report.droppedResults += 1;\n }\n if (report.droppedResults > 0) {\n report.status = \"incomplete\";\n }\n if (serializedBytes(report) > maxBytes) {\n throw new Error(\"The minimum scenario report exceeds maxBytes\");\n }\n return report;\n}\n\nfunction serializedBytes(value: unknown): number {\n return new TextEncoder().encode(JSON.stringify(value)).byteLength;\n}\n\nasync function executeScenario(\n client: McpFnTestClient<unknown>,\n scenario: McpFnScenario,\n requestOptions: { signal: AbortSignal; timeout: number },\n observedEvents: McpFnClientEvent[],\n runOptions: McpFnScenarioRunOptions,\n): Promise<void> {\n const kind = scenario.kind ?? \"tools.call\";\n if (isInventoryScenario(scenario)) {\n await executeInventoryScenario(client, scenario, requestOptions);\n return;\n }\n switch (scenario.kind) {\n case undefined:\n case \"tools.call\":\n return executeToolScenario(client, scenario, requestOptions);\n case \"initialize\":\n return executeInitializeScenario(client, scenario);\n case \"resources.read\":\n return assertExpectedAsync(client.readResource(scenario.uri, requestOptions), scenario.expect);\n case \"resources.subscribe\":\n return client.subscribeResource(scenario.uri, requestOptions);\n case \"resources.unsubscribe\":\n return client.unsubscribeResource(scenario.uri, requestOptions);\n case \"prompts.get\":\n return assertExpectedAsync(\n client.getPrompt(scenario.prompt, scenario.arguments, requestOptions),\n scenario.expect,\n );\n case \"tools.call:task\":\n return assertExpectedAsync(\n client.createToolTask(scenario.tool, scenario.arguments, scenario.task, requestOptions),\n scenario.expect,\n );\n case \"tasks.get\":\n return assertExpectedAsync(client.getTask(scenario.taskId!, requestOptions), scenario.expect);\n case \"tasks.result\":\n return assertExpectedAsync(client.getTaskResult(scenario.taskId!, requestOptions), scenario.expect);\n case \"tasks.cancel\":\n return assertExpectedAsync(client.cancelTask(scenario.taskId!, requestOptions), scenario.expect);\n case \"tasks.list\":\n return assertExpectedAsync(client.listTasks(scenario.cursor, requestOptions), scenario.expect);\n case \"events.expect\":\n return executeEventScenario(scenario, observedEvents);\n case \"auth.assert\":\n return executeAuthScenario(scenario, requestOptions.signal, runOptions);\n }\n throw new McpFnAssertionError(`Unsupported scenario operation ${kind}`);\n}\n\nasync function executeToolScenario(\n client: McpFnTestClient<unknown>,\n scenario: McpFnToolScenario,\n requestOptions: { signal: AbortSignal; timeout: number },\n): Promise<void> {\n const result = await client.callTool(\n scenario.tool,\n scenario.arguments,\n requestOptions,\n );\n assertToolResult(result, scenario);\n await scenario.verify?.(result);\n}\n\nfunction assertToolResult(result: CallToolResult, scenario: McpFnToolScenario): void {\n if (result.isError && scenario.expect?.isError === undefined) {\n throw new McpFnAssertionError(\n \"Tool returned isError=true without an explicit expect.isError=true assertion\",\n );\n }\n if (\n scenario.expect?.isError !== undefined &&\n Boolean(result.isError) !== scenario.expect.isError\n ) {\n throw new McpFnAssertionError(\n `Expected isError=${scenario.expect.isError}, received ${Boolean(result.isError)}`,\n );\n }\n if (\n scenario.expect &&\n Object.hasOwn(scenario.expect, \"structuredContent\") &&\n stableJson(result.structuredContent) !== stableJson(scenario.expect.structuredContent)\n ) {\n throw new McpFnAssertionError(\n `Structured result mismatch\\nexpected: ${stableJson(scenario.expect.structuredContent)}\\nactual: ${stableJson(result.structuredContent)}`,\n );\n }\n if (scenario.expect?.structuredTextParity) assertStructuredTextParity(result);\n}\n\nfunction executeInitializeScenario(\n client: McpFnTestClient<unknown>,\n scenario: McpFnInitializeScenario,\n): void {\n const actual = client.client.getServerCapabilities() ?? {};\n if (scenario.expectCapabilities && stableJson(actual) !== stableJson(scenario.expectCapabilities)) {\n throw new McpFnAssertionError(\n `Capability mismatch\\nexpected: ${stableJson(scenario.expectCapabilities)}\\nactual: ${stableJson(actual)}`,\n );\n }\n}\n\nasync function executeInventoryScenario(\n client: McpFnTestClient<unknown>,\n scenario: McpFnInventoryScenario,\n requestOptions: { signal: AbortSignal; timeout: number },\n): Promise<void> {\n const values = await listScenarioInventory(client, scenario.kind, requestOptions);\n if (!scenario.expectNames) return;\n const actual = values.map((value) => value.name).sort(compareCodeUnits);\n const expected = [...scenario.expectNames].sort(compareCodeUnits);\n if (stableJson(actual) !== stableJson(expected)) {\n throw new McpFnAssertionError(\n `Inventory mismatch\\nexpected: ${stableJson(expected)}\\nactual: ${stableJson(actual)}`,\n );\n }\n}\n\nasync function assertExpectedAsync(actual: Promise<unknown>, expected: unknown): Promise<void> {\n assertExpected(await actual, expected);\n}\n\nfunction executeEventScenario(\n scenario: McpFnEventScenario,\n observedEvents: McpFnClientEvent[],\n): void {\n const matching = observedEvents.filter((event) => event.kind === scenario.event);\n if (matching.length < (scenario.minimum ?? 1)) {\n throw new McpFnAssertionError(\n `Expected at least ${scenario.minimum ?? 1} ${scenario.event} event(s), received ${matching.length}`,\n );\n }\n if (scenario.expectPayload !== undefined) {\n assertExpected(matching.at(-1)?.payload, scenario.expectPayload);\n }\n}\n\nasync function executeAuthScenario(\n scenario: McpFnAuthScenario,\n signal: AbortSignal,\n runOptions: McpFnScenarioRunOptions,\n): Promise<void> {\n if (!runOptions.auth) {\n throw new McpFnAssertionError(\"auth.assert requires a scenario auth adapter\");\n }\n assertExpected(await runOptions.auth(scenario, signal), scenario.expect);\n}\n\nfunction truncateError(value: string, options: McpFnScenarioRunOptions, client: McpFnTestClient): string {\n let redacted = \"Scenario error omitted because credential redaction failed\";\n try { redacted = String(client.session.redact(value)); }\n catch { /* Report safely even when a diagnostic exceeds the redaction budget. */ }\n const maxBytes = options.maxErrorBytes ?? 4_096;\n const bytes = new TextEncoder().encode(redacted);\n if (bytes.byteLength <= maxBytes) return redacted;\n return `${new TextDecoder().decode(bytes.slice(0, Math.max(0, maxBytes - 16)))}...[TRUNCATED]`;\n}\n\nfunction defaultSideEffect(operation: string): McpFnScenarioSideEffect {\n if (operation === \"tools.call\" || operation === \"tools.call:task\") {\n return \"non-idempotent\";\n }\n if (operation === \"tasks.cancel\") return \"idempotent\";\n return \"none\";\n}\n\nfunction compareCodeUnits(left: string, right: string): number {\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n\nfunction assertExpected(actual: unknown, expected: unknown): void {\n if (expected !== undefined && stableJson(actual) !== stableJson(expected)) {\n throw new McpFnAssertionError(\n `Scenario result mismatch\\nexpected: ${stableJson(expected)}\\nactual: ${stableJson(actual)}`,\n );\n }\n}\n\nfunction isToolScenario(scenario: McpFnScenario): scenario is McpFnToolScenario {\n return \"tool\" in scenario;\n}\n\nfunction isInventoryScenario(scenario: McpFnScenario): scenario is McpFnInventoryScenario {\n return [\"tools.list\", \"resources.list\", \"resources.templates.list\", \"prompts.list\"]\n .includes(scenario.kind ?? \"\");\n}\n\nfunction requiredScenarioField(kind: string): string | undefined {\n switch (kind) {\n case \"tools.call\":\n case \"tools.call:task\":\n return \"tool\";\n case \"resources.read\":\n case \"resources.subscribe\":\n case \"resources.unsubscribe\":\n return \"uri\";\n case \"prompts.get\":\n return \"prompt\";\n case \"tasks.get\":\n case \"tasks.result\":\n case \"tasks.cancel\":\n return \"taskId\";\n case \"events.expect\":\n return \"event\";\n default:\n return undefined;\n }\n}\n\nasync function listScenarioInventory(\n client: McpFnTestClient<unknown>,\n kind: McpFnInventoryScenario[\"kind\"],\n requestOptions: { signal: AbortSignal; timeout: number },\n) {\n switch (kind) {\n case \"tools.list\":\n return client.listTools(requestOptions);\n case \"resources.list\":\n return client.listResources(requestOptions);\n case \"resources.templates.list\":\n return client.listResourceTemplates(requestOptions);\n case \"prompts.list\":\n return client.listPrompts(requestOptions);\n }\n}\n","import {\n McpFnRedactionLimitError,\n McpFnStructuralCredentialCollisionError,\n beginTargetCredentialRedaction,\n redactTargetCredentials,\n} from \"./remote-target.js\";\nimport type { Implementation, ServerCapabilities } from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n McpFnClientError,\n type McpFnDiagnosticEvent,\n type McpFnTarget,\n type McpFnTargetDescriptor,\n} from \"@mcpfn/client\";\nimport type { McpFnManifest } from \"@mcpfn/core\";\n\nimport { assertManifestContract, McpFnAssertionError, stableJson } from \"./assertions.js\";\nimport {\n McpFnTestClient,\n McpFnTestClientCleanupError,\n type McpFnTestClientOptions,\n} from \"./client.js\";\nimport {\n MCPFN_REPORT_SCHEMA_VERSION,\n MCPFN_TESTING_VERSION,\n normalizeMcpFnReportFailure,\n type McpFnReportFailure,\n} from \"./reports.js\";\nimport {\n disposeMcpFnTargetSuiteArtifactGuard,\n preserveMcpFnTargetSuiteArtifact,\n registerMcpFnTargetSuiteArtifactGuard,\n} from \"./artifact-guards.js\";\nimport {\n runScenarios,\n type McpFnScenario,\n type McpFnScenarioResult,\n} from \"./scenarios.js\";\n\nexport interface RunMcpFnTargetSuiteOptions {\n target: McpFnTarget;\n scenarios?: McpFnScenario[];\n manifest?: McpFnManifest;\n expectedToolNames?: readonly string[];\n clientInfo?: Implementation;\n client?: McpFnTestClientOptions;\n scenarioRun?: NonNullable<Parameters<typeof runScenarios>[2]>;\n /** Aggregate JSON size cap. Defaults to 1 MiB. */\n maxReportBytes?: number;\n /** Diagnostic timeline count cap. Defaults to 500. */\n maxTimelineEvents?: number;\n}\n\nexport interface McpFnTargetSuiteReport {\n formatVersion: 1;\n kind: \"mcpfn.target-suite-report\";\n /** Generated reports require retained target proof for derived encodings. */\n artifactValidation?: \"target-aware\";\n status: \"complete\" | \"incomplete\";\n runtime: {\n node: string;\n scenarioFormatVersion: 1;\n reportSchemaVersion: string;\n packages: { testing: string };\n };\n ok: boolean;\n target: McpFnTargetDescriptor;\n server?: Implementation;\n capabilities?: ServerCapabilities;\n manifestChecked: boolean;\n manifestHash?: string;\n total: number;\n passed: number;\n failed: number;\n incomplete: number;\n droppedResults: number;\n droppedObservedEvents: number;\n redactionOmittedObservedEvents?: number;\n incompleteReason?: string;\n failure?: McpFnReportFailure;\n timeline: McpFnDiagnosticEvent[];\n droppedTimelineEvents: number;\n results: McpFnScenarioResult[];\n}\n\nconst suiteCleanupOwners = new WeakMap<Error, { close: () => Promise<void>; pending?: Promise<void> }>();\n\nfunction retryTargetSuiteCleanup(error: Error): Promise<void> {\n const owner = suiteCleanupOwners.get(error);\n if (!owner) return Promise.resolve();\n if (owner.pending) return owner.pending;\n const pending = Promise.resolve().then(owner.close).then(\n () => { suiteCleanupOwners.delete(error); },\n () => { throw error; },\n ).finally(() => { owner.pending = undefined; });\n owner.pending = pending;\n return pending;\n}\n\n/** Final cleanup failed. The bounded report is a snapshot; retain this error to retry. */\nexport class McpFnTargetSuiteCleanupError extends Error {\n constructor(readonly report: McpFnTargetSuiteReport, close: () => Promise<void>) {\n super(\"Target suite cleanup failed; retain this error and retryCleanup()\");\n this.name = \"McpFnTargetSuiteCleanupError\";\n suiteCleanupOwners.set(this, { close });\n }\n\n retryCleanup(): Promise<void> {\n return retryTargetSuiteCleanup(this);\n }\n}\n\n/** Report serialization failed after cleanup ownership had already transferred. */\nexport class McpFnTargetSuiteArtifactCleanupError extends Error {\n constructor(close: () => Promise<void>, cause: Error) {\n super(`${cause.message}; retain this error and retryCleanup()`, { cause });\n this.name = \"McpFnTargetSuiteArtifactCleanupError\";\n suiteCleanupOwners.set(this, { close });\n }\n\n retryCleanup(): Promise<void> {\n return retryTargetSuiteCleanup(this);\n }\n}\n\n/** Runs local, stdio, HTTP, or custom targets through the production session engine. */\nexport async function runMcpFnTargetSuite(\n options: RunMcpFnTargetSuiteOptions,\n): Promise<McpFnTargetSuiteReport> {\n const artifactRedaction = beginSuiteArtifactRedaction(options.target);\n let finishRedaction = artifactRedaction.finish;\n const retainArtifactGuard = (report: McpFnTargetSuiteReport) => {\n registerMcpFnTargetSuiteArtifactGuard(\n report,\n artifact => {\n if (!artifactRedaction.retained) return false;\n if (options.target.assertArtifactSafe) {\n options.target.assertArtifactSafe(artifact);\n return true;\n }\n // Built-in unauthenticated targets do not own credential material.\n // Custom targets that do own it must expose either the exact validator\n // above or a redactor that can prove the completed artifact unchanged.\n if (!options.target.redact) return true;\n return Object.is(\n redactSuiteArtifact(options.target, artifact, { preserveKeys: false }),\n artifact,\n );\n },\n finishRedaction,\n options.maxReportBytes ?? 1_048_576,\n );\n finishRedaction = () => undefined;\n try {\n preserveMcpFnTargetSuiteArtifact(report, JSON.stringify(report));\n } catch (error) {\n disposeMcpFnTargetSuiteArtifactGuard(report);\n throw error;\n }\n };\n try {\n const report = await runTargetSuite(options);\n retainArtifactGuard(report);\n return report;\n } catch (error) {\n if (error instanceof McpFnTargetSuiteCleanupError) {\n try {\n retainArtifactGuard(error.report);\n } catch (artifactError) {\n const cause = artifactError instanceof Error\n ? artifactError\n : new Error(\"Target report artifact proof failed\");\n throw new McpFnTargetSuiteArtifactCleanupError(\n () => error.retryCleanup(),\n cause,\n );\n }\n }\n throw error;\n } finally {\n finishRedaction();\n }\n}\n\nfunction beginSuiteArtifactRedaction(target: McpFnTarget): {\n finish: () => void;\n retained: boolean;\n} {\n let finish: (() => void) | undefined;\n if (target.beginRedactionScope) {\n try { finish = target.beginRedactionScope(); }\n catch { return { finish: () => undefined, retained: false }; }\n if (!finish) return { finish: () => undefined, retained: false };\n } else {\n finish = beginTargetCredentialRedaction(target);\n }\n return {\n finish: () => {\n try { finish?.(); } catch {}\n },\n retained: true,\n };\n}\n\n/** Apply the target-owned scrubber before the bounded generic artifact pass. */\nfunction redactSuiteArtifact<T>(target: McpFnTarget, value: T, options: { preserveKeys?: boolean } = {}): T {\n const scrubbed = target.redact ? target.redact(value, options) : value;\n return redactTargetCredentials(target, scrubbed, options);\n}\n\nfunction compareInventoryNames(left: string, right: string): number {\n if (left === right) return 0;\n return left < right ? -1 : 1;\n}\n\nfunction reportProjectionFailureReason(\n error: unknown,\n projectionFailure: \"redaction\" | \"serialization\" | undefined,\n): string {\n if (error instanceof McpFnRedactionLimitError) {\n return \"Credential redaction exceeded its traversal budget\";\n }\n if (projectionFailure === \"redaction\") {\n return \"Credential redaction failed; report content omitted because safe serialization failed\";\n }\n return \"Report content omitted because safe serialization failed\";\n}\n\nclass SuiteDiagnosticCollector {\n readonly timeline: McpFnDiagnosticEvent[] = [];\n private readonly timelineSizes: number[] = [];\n private timelineBytes = 0;\n private observedRedactionOmissions = 0;\n private initialRedactionOmissions = 0;\n dropped = 0;\n countExceeded = false;\n bytesExceeded = false;\n serializationFailed = false;\n redactionFailed = false;\n cleanupFailure: McpFnReportFailure | undefined;\n\n constructor(\n private readonly maxEvents: number,\n private readonly maxBytes: number,\n private readonly target: McpFnTarget,\n private readonly consumer?: (event: McpFnDiagnosticEvent) => void | Promise<void>,\n ) {}\n\n captureBaseline(client: McpFnTestClient): void {\n this.initialRedactionOmissions = client.session\n .getRedactionOmissionCounts().diagnostics;\n }\n\n captureUnobserved(client: McpFnTestClient | undefined): void {\n const total = client?.session.getRedactionOmissionCounts().diagnostics ??\n this.initialRedactionOmissions;\n const unobserved = Math.max(\n 0,\n total - this.initialRedactionOmissions - this.observedRedactionOmissions,\n );\n if (unobserved > 0) {\n this.redactionFailed = true;\n this.dropped += unobserved;\n }\n }\n\n async record(client: McpFnTestClient | undefined, event: McpFnDiagnosticEvent): Promise<void> {\n if (client?.session.isRedactionOmission(event)) {\n this.observedRedactionOmissions += 1;\n this.redactionFailed = true;\n this.dropped += 1;\n }\n if ([\"token-revocation\", \"transport-close\"].includes(event.phase) &&\n event.outcome === \"failed\") {\n this.cleanupFailure ??= normalizeMcpFnReportFailure({\n name: \"CleanupError\", message: \"Target cleanup failed\",\n code: event.code, phase: event.phase,\n });\n }\n const safeEvent = redactTargetCredentials(this.target, event, { preserveKeys: true });\n const bytes = this.serializedBytes(safeEvent);\n if (bytes === undefined) {\n await this.consumer?.(safeEvent);\n return;\n }\n if (bytes > this.maxBytes) {\n this.bytesExceeded = true;\n this.dropped += 1;\n } else {\n this.timeline.push(safeEvent);\n this.timelineSizes.push(bytes);\n this.timelineBytes += bytes;\n this.enforceBounds();\n }\n await this.consumer?.(safeEvent);\n }\n\n private serializedBytes(event: McpFnDiagnosticEvent): number | undefined {\n try {\n const json = JSON.stringify(event, (_key, value: unknown) => {\n if (value === undefined || (typeof value === \"number\" && !Number.isFinite(value))) {\n throw new Error(\"Diagnostic contains a non-JSON value\");\n }\n return value;\n });\n structuredClone(event);\n return Buffer.byteLength(json);\n } catch {\n this.serializationFailed = true;\n this.dropped += 1;\n return undefined;\n }\n }\n\n private enforceBounds(): void {\n while (this.timeline.length > this.maxEvents || this.timelineBytes > this.maxBytes) {\n this.countExceeded ||= this.timeline.length > this.maxEvents;\n this.bytesExceeded ||= this.timelineBytes > this.maxBytes;\n this.timeline.shift();\n this.timelineBytes -= this.timelineSizes.shift()!;\n this.dropped += 1;\n }\n }\n}\n\ninterface SuiteExecution {\n results: McpFnScenarioResult[];\n server?: Implementation;\n capabilities?: ServerCapabilities;\n}\n\ninterface SuiteProjection {\n target: McpFnTargetDescriptor;\n manifestHash?: string;\n execution: SuiteExecution;\n failure?: \"redaction\" | \"serialization\";\n}\n\nasync function executeConnectedSuite(\n client: McpFnTestClient,\n options: RunMcpFnTargetSuiteOptions,\n): Promise<{ execution: SuiteExecution; manifestChecked: boolean }> {\n let manifestChecked = false;\n if (options.manifest) {\n manifestChecked = true;\n await assertManifestContract(client, options.manifest, {\n expectedToolNames: options.expectedToolNames,\n });\n } else if (options.expectedToolNames) {\n const actual = (await client.listTools()).map((tool) => tool.name).sort(compareInventoryNames);\n const expected = [...options.expectedToolNames].sort(compareInventoryNames);\n if (stableJson(actual) !== stableJson(expected)) {\n throw new McpFnAssertionError(\n `Tool inventory mismatch: expected ${stableJson(expected)}, actual ${stableJson(actual)}`,\n );\n }\n }\n const results = await runScenarios(client, options.scenarios ?? [], options.scenarioRun);\n return {\n manifestChecked,\n execution: {\n results,\n server: client.session.getServerVersion(),\n capabilities: client.session.getServerCapabilities(),\n },\n };\n}\n\nfunction safeTargetFailure(target: McpFnTarget, error: unknown): McpFnReportFailure {\n try {\n return normalizeMcpFnReportFailure(redactSuiteArtifact(target, error, { preserveKeys: true }));\n } catch {\n // Arbitrary error properties/proxies can throw, including secret-bearing errors.\n return normalizeMcpFnReportFailure({\n name: \"RedactionError\",\n code: \"MCPFN_REDACTION_FAILED\",\n message: \"Target failure omitted because credential redaction failed\",\n });\n }\n}\n\nfunction initialTargetDescriptor(target: McpFnTarget): McpFnTargetDescriptor {\n const kind = target.kind;\n return [\"stdio\", \"streamable-http\", \"authenticated-streamable-http\", \"in-memory\", \"custom\"]\n .includes(kind)\n ? { kind }\n : { kind: \"custom\" };\n}\n\nfunction safeInitialTargetDescriptor(target: McpFnTarget): McpFnTargetDescriptor {\n try { return initialTargetDescriptor(target); }\n catch { return { kind: \"custom\" }; }\n}\n\nfunction projectSuiteArtifacts(\n options: RunMcpFnTargetSuiteOptions,\n client: McpFnTestClient | undefined,\n execution: SuiteExecution,\n): SuiteProjection {\n const fallback: SuiteProjection = {\n target: safeInitialTargetDescriptor(options.target), execution,\n };\n try {\n if (client?.session.state !== \"connected\") {\n return execution.results.length || execution.server || execution.capabilities\n ? { ...fallback, failure: \"serialization\" }\n : fallback;\n }\n let described: McpFnTargetDescriptor;\n try { described = options.target.describe(); }\n catch { return { ...fallback, failure: \"serialization\" }; }\n try {\n const { kind, ...descriptor } = described;\n return {\n target: {\n ...redactSuiteArtifact(options.target, descriptor, { preserveKeys: false }),\n kind: client.session.preserveArtifactStructure(kind),\n },\n manifestHash: options.manifest\n ? redactSuiteArtifact(options.target, options.manifest.hash, { preserveKeys: false })\n : undefined,\n execution: {\n server: execution.server === undefined\n ? undefined\n : redactSuiteArtifact(options.target, execution.server, { preserveKeys: false }),\n capabilities: execution.capabilities === undefined\n ? undefined\n : redactSuiteArtifact(options.target, execution.capabilities, { preserveKeys: false }),\n results: execution.results.map(result => ({\n ...result,\n name: redactSuiteArtifact(options.target, result.name, { preserveKeys: false }),\n operation: redactSuiteArtifact(options.target, result.operation, { preserveKeys: false }),\n ...(result.tool === undefined ? {} : {\n tool: redactSuiteArtifact(options.target, result.tool, { preserveKeys: false }),\n }),\n })),\n },\n };\n } catch {\n return { ...fallback, failure: \"redaction\" };\n }\n } catch {\n return { ...fallback, failure: \"serialization\" };\n }\n}\n\nconst suiteStructureKeys = [\n \"formatVersion\", \"kind\", \"artifactValidation\", \"status\", \"runtime\", \"ok\", \"target\", \"server\",\n \"capabilities\", \"manifestChecked\", \"manifestHash\", \"total\", \"passed\", \"failed\",\n \"incomplete\", \"droppedResults\", \"droppedObservedEvents\",\n \"redactionOmittedObservedEvents\", \"incompleteReason\", \"failure\", \"timeline\",\n \"droppedTimelineEvents\", \"results\", \"node\", \"scenarioFormatVersion\",\n \"reportSchemaVersion\", \"packages\", \"testing\", \"name\", \"message\", \"layer\", \"code\",\n \"phase\", \"details\", \"outcome\", \"requestId\", \"at\", \"sideEffect\", \"durationMs\",\n \"error\", \"operation\", \"tool\",\n] as const;\n\nconst suiteStructureValues = [\n \"mcpfn.target-suite-report\", \"target-aware\", \"complete\", \"incomplete\", \"passed\", \"failed\",\n \"started\", \"succeeded\", \"none\", \"idempotent\", \"non-idempotent\",\n \"mcpfn-preflight\", \"authorization-server\", \"resource-server\", \"mcp-initialization\",\n \"scenario\", \"upstream-conformance\", \"resource-discovery\",\n \"authorization-server-discovery\", \"client-registration\", \"authorization-request\",\n \"authorization-callback\", \"token-exchange\", \"token-refresh\", \"token-revocation\",\n \"transport-connect\", \"mcp-initialize\", \"capability-operation\", \"transport-close\",\n \"authenticated-streamable-http\", \"streamable-http\", \"stdio\", \"in-memory\", \"custom\",\n] as const;\n\ninterface SuiteStructureGuard {\n assert(value: string): void;\n}\n\nfunction captureSuiteStructureGuard(\n target: McpFnTarget,\n projection: SuiteProjection,\n diagnostics: SuiteDiagnosticCollector,\n failure: McpFnReportFailure | undefined,\n): SuiteStructureGuard {\n const candidates = new Set<string>([\n ...suiteStructureKeys,\n ...suiteStructureValues,\n process.version,\n MCPFN_REPORT_SCHEMA_VERSION,\n MCPFN_TESTING_VERSION,\n projection.target.kind,\n ]);\n if (failure?.phase) candidates.add(failure.phase);\n for (const result of projection.execution.results) {\n candidates.add(result.status);\n if (result.sideEffect) candidates.add(result.sideEffect);\n }\n for (const event of diagnostics.timeline) {\n candidates.add(event.phase);\n candidates.add(event.outcome);\n if (event.target?.kind) candidates.add(event.target.kind);\n }\n const safe = new Set<string>();\n for (const candidate of candidates) {\n try {\n if (redactSuiteArtifact(target, candidate, { preserveKeys: false }) === candidate) {\n safe.add(candidate);\n }\n } catch {\n // If the live custom scrubber cannot classify a string, fail closed only\n // when the final report actually needs that unproven structure.\n }\n }\n return {\n assert(value: string): void {\n if (!safe.has(value)) throw new McpFnStructuralCredentialCollisionError();\n },\n };\n}\n\nfunction assertStructureKeys(value: object, guard: SuiteStructureGuard): void {\n for (const key of Object.keys(value)) guard.assert(key);\n}\n\nfunction assertTargetStructure(\n target: McpFnTargetDescriptor,\n guard: SuiteStructureGuard,\n): void {\n guard.assert(\"kind\");\n guard.assert(target.kind);\n}\n\nfunction assertSuiteReportStructure(\n report: McpFnTargetSuiteReport,\n guard: SuiteStructureGuard,\n): void {\n assertStructureKeys(report, guard);\n guard.assert(report.kind);\n if (report.artifactValidation) guard.assert(report.artifactValidation);\n guard.assert(report.status);\n assertStructureKeys(report.runtime, guard);\n guard.assert(report.runtime.node);\n guard.assert(report.runtime.reportSchemaVersion);\n assertStructureKeys(report.runtime.packages, guard);\n guard.assert(report.runtime.packages.testing);\n assertTargetStructure(report.target, guard);\n if (report.failure) {\n assertStructureKeys(report.failure, guard);\n guard.assert(report.failure.layer);\n if (report.failure.phase) guard.assert(report.failure.phase);\n }\n for (const event of report.timeline) {\n assertStructureKeys(event, guard);\n guard.assert(event.phase);\n guard.assert(event.outcome);\n if (event.target) assertTargetStructure(event.target, guard);\n }\n for (const result of report.results) {\n assertStructureKeys(result, guard);\n guard.assert(result.status);\n if (result.sideEffect) guard.assert(result.sideEffect);\n }\n}\n\nasync function closeSuiteClient(client: McpFnTestClient | undefined): Promise<{\n cleanupFailure?: McpFnReportFailure;\n retainedCleanup?: () => Promise<void>;\n}> {\n try {\n await client?.close();\n return {};\n } catch (error) {\n let retainedCleanup: (() => Promise<void>) | undefined;\n if (error instanceof McpFnTestClientCleanupError) {\n retainedCleanup = () => error.retryCleanup();\n } else if (client) {\n retainedCleanup = () => client.close();\n }\n const terminal = error instanceof McpFnTestClientCleanupError && error.cause !== undefined\n ? error.cause\n : error;\n const phase = terminal && typeof terminal === \"object\" &&\n (terminal as { phase?: unknown }).phase === \"token-revocation\"\n ? \"token-revocation\"\n : \"transport-close\";\n return {\n retainedCleanup,\n cleanupFailure: normalizeMcpFnReportFailure({\n name: \"CleanupError\",\n message: \"Target cleanup failed\",\n code: \"MCPFN_TARGET_CLEANUP_FAILED\",\n phase,\n }),\n };\n }\n}\n\ninterface SuiteConnection {\n client?: McpFnTestClient;\n initialClientEventRedactionOmissions: number;\n manifestChecked: boolean;\n failure?: McpFnReportFailure;\n execution: SuiteExecution;\n}\n\nasync function connectSuite(\n options: RunMcpFnTargetSuiteOptions,\n diagnostics: SuiteDiagnosticCollector,\n): Promise<SuiteConnection> {\n let client: McpFnTestClient | undefined;\n let initialClientEventRedactionOmissions = 0;\n let manifestChecked = false;\n let failure: McpFnReportFailure | undefined;\n let execution: SuiteExecution = { results: [] };\n try {\n client = McpFnTestClient.createTarget(\n options.target,\n options.clientInfo ?? { name: \"mcpfn-suite\", version: \"0.0.1\" },\n {\n ...options.client,\n diagnostics: event => diagnostics.record(client, event),\n },\n );\n initialClientEventRedactionOmissions = client.session\n .getRedactionOmissionCounts().clientEvents;\n diagnostics.captureBaseline(client);\n await client.session.connect();\n ({ execution, manifestChecked } = await executeConnectedSuite(client, options));\n } catch (error) {\n failure = safeTargetFailure(options.target, error);\n }\n return {\n client,\n initialClientEventRedactionOmissions,\n manifestChecked,\n failure,\n execution,\n };\n}\n\nasync function projectAndCloseSuite(\n options: RunMcpFnTargetSuiteOptions,\n diagnostics: SuiteDiagnosticCollector,\n connection: SuiteConnection,\n): Promise<{\n projection: SuiteProjection;\n structureGuard: SuiteStructureGuard;\n closeResult: Awaited<ReturnType<typeof closeSuiteClient>>;\n}> {\n let projection: SuiteProjection;\n let structureGuard: SuiteStructureGuard;\n let closeResult: Awaited<ReturnType<typeof closeSuiteClient>> = {};\n try {\n projection = projectSuiteArtifacts(options, connection.client, connection.execution);\n structureGuard = captureSuiteStructureGuard(\n options.target,\n projection,\n diagnostics,\n connection.failure,\n );\n } finally {\n closeResult = await closeSuiteClient(connection.client);\n }\n return { projection, structureGuard, closeResult };\n}\n\nfunction suiteIncompleteReasons(\n failure: McpFnReportFailure | undefined,\n cleanupFailure: McpFnReportFailure | undefined,\n diagnostics: SuiteDiagnosticCollector,\n redactionOmittedObservedEvents: number,\n overflowedObservedEvents: number,\n): string | undefined {\n const reasons = [\n ...(failure ? [`${failure.layer}: ${failure.message}`] : []),\n ...(cleanupFailure ? [`Cleanup: ${cleanupFailure.message}`] : []),\n ...(diagnostics.serializationFailed ? [\"Diagnostic timeline contained non-JSON data\"] : []),\n ...(diagnostics.redactionFailed ? [\"Diagnostic timeline redaction failed; original events omitted\"] : []),\n ...(diagnostics.countExceeded ? [\"Diagnostic timeline exceeded maxTimelineEvents\"] : []),\n ...(diagnostics.bytesExceeded ? [\"Diagnostic timeline exceeded maxReportBytes\"] : []),\n ...(redactionOmittedObservedEvents > 0\n ? [\"Observed client events were omitted because credential redaction failed\"]\n : []),\n ...(overflowedObservedEvents > 0\n ? [\"Observed client events exceeded maxObservedEvents\"]\n : []),\n ];\n return reasons.length ? reasons.join(\"; \") : undefined;\n}\n\nfunction buildSuiteReport(\n projection: SuiteProjection,\n manifestChecked: boolean,\n failure: McpFnReportFailure | undefined,\n cleanupFailure: McpFnReportFailure | undefined,\n diagnostics: SuiteDiagnosticCollector,\n lifecycleRedactionOmissions: number,\n): McpFnTargetSuiteReport {\n const results = projection.execution.results;\n const failed = results.filter((result) => result.status === \"failed\").length;\n const incomplete = results.filter((result) => result.status === \"incomplete\").length;\n const scenarioDroppedObservedEvents = results.reduce(\n (total, result) => total + (result.droppedObservedEvents ?? 0),\n 0,\n );\n const scenarioRedactionOmissions = results.reduce(\n (total, result) => total + (result.redactionOmittedObservedEvents ?? 0),\n 0,\n );\n const redactionOmittedObservedEvents = Math.max(\n lifecycleRedactionOmissions,\n scenarioRedactionOmissions,\n );\n const overflowedObservedEvents = Math.max(\n 0,\n scenarioDroppedObservedEvents - scenarioRedactionOmissions,\n );\n const droppedObservedEvents = redactionOmittedObservedEvents + overflowedObservedEvents;\n const artifactIncomplete = Boolean(failure) || incomplete > 0 ||\n diagnostics.dropped > 0 || droppedObservedEvents > 0;\n const incompleteReason = suiteIncompleteReasons(\n failure,\n cleanupFailure,\n diagnostics,\n redactionOmittedObservedEvents,\n overflowedObservedEvents,\n );\n return {\n formatVersion: 1,\n kind: \"mcpfn.target-suite-report\",\n artifactValidation: \"target-aware\",\n status: artifactIncomplete ? \"incomplete\" : \"complete\",\n runtime: {\n node: process.version,\n scenarioFormatVersion: 1,\n reportSchemaVersion: MCPFN_REPORT_SCHEMA_VERSION,\n packages: { testing: MCPFN_TESTING_VERSION },\n },\n ok: failed === 0 && !artifactIncomplete,\n target: projection.target,\n server: projection.execution.server,\n capabilities: projection.execution.capabilities,\n manifestChecked,\n ...(projection.manifestHash === undefined ? {} : { manifestHash: projection.manifestHash }),\n total: results.length,\n passed: results.length - failed - incomplete,\n failed,\n incomplete,\n droppedResults: 0,\n droppedObservedEvents,\n ...(redactionOmittedObservedEvents > 0 ? { redactionOmittedObservedEvents } : {}),\n ...(incompleteReason ? { incompleteReason } : {}),\n ...(failure ? { failure } : {}),\n timeline: diagnostics.timeline,\n droppedTimelineEvents: diagnostics.dropped,\n results,\n };\n}\n\nfunction structuralReportFailure(retainedCleanup: (() => Promise<void>) | undefined): never {\n const failure = new McpFnClientError(\n \"MCPFN_OPERATION_FAILED\",\n \"Target report cannot be serialized because a credential conflicts with required artifact structure\",\n { phase: \"capability-operation\" },\n );\n if (retainedCleanup) {\n throw new McpFnTargetSuiteArtifactCleanupError(retainedCleanup, failure);\n }\n throw failure;\n}\n\nfunction boundedSuiteReport(\n report: McpFnTargetSuiteReport,\n guard: SuiteStructureGuard,\n maxReportBytes: number,\n): McpFnTargetSuiteReport {\n const bounded = enforceReportCap(report, maxReportBytes);\n assertSuiteReportStructure(bounded, guard);\n return bounded;\n}\n\nfunction finalizeSuiteReport(\n options: RunMcpFnTargetSuiteOptions,\n projection: SuiteProjection,\n report: McpFnTargetSuiteReport,\n guard: SuiteStructureGuard,\n maxReportBytes: number,\n retainedCleanup: (() => Promise<void>) | undefined,\n): McpFnTargetSuiteReport {\n let finalized: McpFnTargetSuiteReport;\n try {\n if (projection.failure) throw new Error(\"Report payload projection failed\");\n assertSuiteReportStructure(report, guard);\n // Custom redaction already completed before cleanup. Built-in report scopes\n // remain active here for bounded final serialization.\n finalized = boundedSuiteReport(\n redactTargetCredentials(options.target, report, { preserveKeys: true }),\n guard,\n maxReportBytes,\n );\n } catch (error) {\n if (error instanceof McpFnStructuralCredentialCollisionError) {\n return structuralReportFailure(retainedCleanup);\n }\n const fallback = {\n ...report,\n ok: false,\n status: \"incomplete\" as const,\n incompleteReason: reportProjectionFailureReason(error, projection.failure),\n target: { kind: \"custom\" as const },\n server: undefined,\n capabilities: undefined,\n manifestHash: undefined,\n failure: undefined,\n results: [],\n timeline: [],\n droppedResults: report.results.length,\n droppedTimelineEvents: report.droppedTimelineEvents + report.timeline.length,\n };\n try {\n finalized = boundedSuiteReport(\n redactTargetCredentials(options.target, fallback, { preserveKeys: true }),\n guard,\n maxReportBytes,\n );\n } catch (fallbackError) {\n if (fallbackError instanceof McpFnRedactionLimitError) {\n return structuralReportFailure(retainedCleanup);\n }\n throw fallbackError;\n }\n }\n if (retainedCleanup) throw new McpFnTargetSuiteCleanupError(finalized, retainedCleanup);\n return finalized;\n}\n\nasync function runTargetSuite(options: RunMcpFnTargetSuiteOptions): Promise<McpFnTargetSuiteReport> {\n const maxTimelineEvents = options.maxTimelineEvents ?? 500;\n if (!Number.isInteger(maxTimelineEvents) || maxTimelineEvents < 1) {\n throw new Error(\"maxTimelineEvents must be a positive integer\");\n }\n const maxReportBytes = options.maxReportBytes ?? 1_048_576;\n validateReportCap(maxReportBytes);\n const consumerDiagnostic = options.client?.diagnostics;\n const diagnostics = new SuiteDiagnosticCollector(\n maxTimelineEvents,\n maxReportBytes,\n options.target,\n consumerDiagnostic,\n );\n const connection = await connectSuite(options, diagnostics);\n // Custom hooks may depend on credentials cleared by close. Capture payload\n // projection and structural safety while the session still owns that state,\n // but never let either operation bypass the sole cleanup boundary.\n const { projection, structureGuard, closeResult } = await projectAndCloseSuite(\n options,\n diagnostics,\n connection,\n );\n const { cleanupFailure: closeFailure, retainedCleanup } = closeResult;\n diagnostics.captureUnobserved(connection.client);\n const lifecycleRedactionOmissions = Math.max(\n 0,\n (connection.client?.session.getRedactionOmissionCounts().clientEvents ??\n connection.initialClientEventRedactionOmissions) -\n connection.initialClientEventRedactionOmissions,\n );\n let cleanupFailure = closeFailure;\n cleanupFailure ??= diagnostics.cleanupFailure;\n const failure = connection.failure ?? cleanupFailure;\n const report = buildSuiteReport(\n projection,\n connection.manifestChecked,\n failure,\n cleanupFailure,\n diagnostics,\n lifecycleRedactionOmissions,\n );\n return finalizeSuiteReport(\n options,\n projection,\n report,\n structureGuard,\n maxReportBytes,\n retainedCleanup,\n );\n}\n\nfunction enforceReportCap(\n report: McpFnTargetSuiteReport,\n maxBytes: number,\n): McpFnTargetSuiteReport {\n validateReportCap(maxBytes);\n const bounded = structuredClone(report);\n if (jsonBytes(bounded) > maxBytes) {\n bounded.ok = false;\n bounded.status = \"incomplete\";\n bounded.incompleteReason = \"Report content exceeded maxReportBytes and was truncated\";\n }\n while (jsonBytes(bounded) > maxBytes && bounded.results.length > 0) {\n bounded.results.pop();\n bounded.droppedResults += 1;\n }\n if (jsonBytes(bounded) > maxBytes) {\n bounded.target = { kind: report.target.kind };\n bounded.server = undefined;\n bounded.capabilities = undefined;\n bounded.timeline = [];\n bounded.droppedTimelineEvents += report.timeline.length;\n if (bounded.failure) {\n bounded.failure.details = undefined;\n bounded.failure.message = \"Target operation failed; details omitted to fit report budget\";\n }\n }\n if (bounded.droppedResults > 0 || jsonBytes(bounded) > maxBytes) {\n bounded.ok = false;\n bounded.status = \"incomplete\";\n bounded.incompleteReason = \"Report content exceeded maxReportBytes and was truncated\";\n }\n if (jsonBytes(bounded) > maxBytes) {\n throw new Error(\"The minimum target suite report exceeds maxReportBytes\");\n }\n return bounded;\n}\n\nfunction validateReportCap(maxBytes: number): void {\n if (!Number.isInteger(maxBytes) || maxBytes < 1_024) {\n throw new Error(\"maxReportBytes must be an integer of at least 1024\");\n }\n}\n\nfunction jsonBytes(value: unknown): number {\n return new TextEncoder().encode(JSON.stringify(value)).byteLength;\n}\n"],"mappings":"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","names":["path","import_node_crypto","import__","import_oauth_core","key","Ajv","Ajv2019","Ajv2020","path","path","import_node_child_process","import_node_crypto","import_node_http","import_node_path","import_oauth_core","import_client","import_oauth_core","role","result","entries","bytes","import_oauth_core","import_client","httpsRequest","httpRequest","path","import_oauth_core","oauthError","bytes","import_client","bytes","json"]}
|