@mcpfn/testing 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -4
- package/dist/auth.cjs +35 -10
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +30 -1
- package/dist/auth.d.ts +30 -1
- package/dist/auth.js +35 -11
- package/dist/auth.js.map +1 -1
- package/dist/index.cjs +956 -148
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +242 -26
- package/dist/index.d.ts +242 -26
- package/dist/index.js +954 -151
- package/dist/index.js.map +1 -1
- package/dist/playwright.cjs +33 -10
- package/dist/playwright.cjs.map +1 -1
- package/dist/playwright.js +34 -11
- package/dist/playwright.js.map +1 -1
- package/package.json +12 -13
package/dist/index.d.cts
CHANGED
|
@@ -1,40 +1,45 @@
|
|
|
1
|
-
import { ClientCapabilities, Tool, CallToolResult, CreateTaskResult, Task, ListTasksResult, Resource, ResourceTemplate, ReadResourceResult, Prompt, GetPromptResult, CompleteRequest, CompleteResult } from '@modelcontextprotocol/sdk/types.js';
|
|
1
|
+
import { ClientCapabilities, Implementation, Tool, CallToolResult, CreateTaskResult, Task, ListTasksResult, Resource, ResourceTemplate, ReadResourceResult, Prompt, GetPromptResult, CompleteRequest, CompleteResult, ServerCapabilities } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
import { McpFnServer, McpFnManifest } from '@mcpfn/core';
|
|
3
|
+
import { McpFnClient, McpFnClientMediatedHandlers, McpFnClientEventSink, McpFnDiagnosticSink, McpFnTarget, McpFnClientEventKind, McpFnTargetDescriptor, McpFnDiagnosticEvent } from '@mcpfn/client';
|
|
3
4
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
4
|
-
|
|
5
|
+
import { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
6
|
+
export { MCPFN_NAMED_OAUTH_HOST_FIXTURES, MCPFN_OAUTH_EXTENSION_GRANTS, McpFnAuthAssertionError, McpFnAuthCredential, McpFnAuthCredentialKind, McpFnAuthCredentialRequest, McpFnAuthProbeScenario, McpFnAuthProviderAdapter, McpFnAuthProviderCapabilities, McpFnAuthRegressionOptions, McpFnAuthScenarioResult, McpFnAuthTarget, McpFnBearerChallenge, McpFnFetchAuthTargetOptions, McpFnMockOAuthAuthorizationServer, McpFnMockOAuthServerOptions, McpFnMockOAuthTokenSet, McpFnNamedOAuthHostFixture, McpFnOAuthCallback, McpFnOAuthClientMetadata, McpFnOAuthClientMetadataFixtureOptions, McpFnOAuthClientMetadataVariants, McpFnPkcePair, McpFnStartMockOAuthServerOptions, McpFnStartedMockOAuthServer, apiKeyCredential, assertAuthRegressionSuite, assertAuthorizationCodeClientMetadata, assertBearerResourceChallenge, bearerCredential, createFetchAuthTarget, createOAuthClientMetadataFixture, createOAuthClientMetadataVariants, createPkcePair, parseBearerChallenge, runAuthRegressionSuite, startMockOAuthAuthorizationServer } from './auth.cjs';
|
|
5
7
|
import '@modelcontextprotocol/sdk/server/auth/types.js';
|
|
6
8
|
|
|
7
9
|
interface McpFnTestClientOptions {
|
|
8
10
|
capabilities?: ClientCapabilities;
|
|
11
|
+
handlers?: McpFnClientMediatedHandlers;
|
|
12
|
+
events?: McpFnClientEventSink;
|
|
9
13
|
/** Install roots, sampling, elicitation, or notification handlers before initialize. */
|
|
10
14
|
configure?(client: Client): void | Promise<void>;
|
|
15
|
+
diagnostics?: McpFnDiagnosticSink;
|
|
11
16
|
}
|
|
12
17
|
declare class McpFnTestClient<TContext = undefined> {
|
|
13
|
-
readonly
|
|
14
|
-
private readonly server;
|
|
15
|
-
private closed;
|
|
18
|
+
readonly session: McpFnClient;
|
|
16
19
|
private constructor();
|
|
20
|
+
get client(): Client;
|
|
17
21
|
static connect<TContext>(server: McpFnServer<TContext>, info?: {
|
|
18
22
|
name: string;
|
|
19
23
|
version: string;
|
|
20
24
|
}, options?: McpFnTestClientOptions): Promise<McpFnTestClient<TContext>>;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
static connectTarget<TContext = undefined>(target: McpFnTarget, info?: Implementation, options?: McpFnTestClientOptions): Promise<McpFnTestClient<TContext>>;
|
|
26
|
+
listTools(options?: RequestOptions): Promise<Tool[]>;
|
|
27
|
+
callTool(name: string, args?: Record<string, unknown>, options?: RequestOptions): Promise<CallToolResult>;
|
|
28
|
+
createToolTask(name: string, args?: Record<string, unknown>, task?: {
|
|
24
29
|
ttl?: number;
|
|
25
|
-
}): Promise<CreateTaskResult>;
|
|
26
|
-
getTask(taskId: string): Promise<Task>;
|
|
27
|
-
getTaskResult(taskId: string): Promise<CallToolResult>;
|
|
28
|
-
listTasks(cursor?: string): Promise<ListTasksResult>;
|
|
29
|
-
cancelTask(taskId: string): Promise<Task>;
|
|
30
|
-
listResources(): Promise<Resource[]>;
|
|
31
|
-
listResourceTemplates(): Promise<ResourceTemplate[]>;
|
|
32
|
-
readResource(uri: string): Promise<ReadResourceResult>;
|
|
33
|
-
subscribeResource(uri: string): Promise<void>;
|
|
34
|
-
unsubscribeResource(uri: string): Promise<void>;
|
|
35
|
-
listPrompts(): Promise<Prompt[]>;
|
|
36
|
-
getPrompt(name: string, args?: Record<string, string
|
|
37
|
-
complete(params: CompleteRequest["params"]): Promise<CompleteResult>;
|
|
30
|
+
}, options?: RequestOptions): Promise<CreateTaskResult>;
|
|
31
|
+
getTask(taskId: string, options?: RequestOptions): Promise<Task>;
|
|
32
|
+
getTaskResult(taskId: string, options?: RequestOptions): Promise<CallToolResult>;
|
|
33
|
+
listTasks(cursor?: string, options?: RequestOptions): Promise<ListTasksResult>;
|
|
34
|
+
cancelTask(taskId: string, options?: RequestOptions): Promise<Task>;
|
|
35
|
+
listResources(options?: RequestOptions): Promise<Resource[]>;
|
|
36
|
+
listResourceTemplates(options?: RequestOptions): Promise<ResourceTemplate[]>;
|
|
37
|
+
readResource(uri: string, options?: RequestOptions): Promise<ReadResourceResult>;
|
|
38
|
+
subscribeResource(uri: string, options?: RequestOptions): Promise<void>;
|
|
39
|
+
unsubscribeResource(uri: string, options?: RequestOptions): Promise<void>;
|
|
40
|
+
listPrompts(options?: RequestOptions): Promise<Prompt[]>;
|
|
41
|
+
getPrompt(name: string, args?: Record<string, string>, options?: RequestOptions): Promise<GetPromptResult>;
|
|
42
|
+
complete(params: CompleteRequest["params"], options?: RequestOptions): Promise<CompleteResult>;
|
|
38
43
|
close(): Promise<void>;
|
|
39
44
|
}
|
|
40
45
|
|
|
@@ -69,8 +74,30 @@ interface OfficialConformanceResult {
|
|
|
69
74
|
stdout: string;
|
|
70
75
|
stderr: string;
|
|
71
76
|
}
|
|
77
|
+
interface AuthenticatedConformanceProxy {
|
|
78
|
+
/** Loopback URL to pass to the official conformance runner. */
|
|
79
|
+
url: string;
|
|
80
|
+
close(): Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
interface AuthenticatedConformanceProxyOptions {
|
|
83
|
+
/** Fixed loopback MCP URL. Requests cannot select a different origin or path. */
|
|
84
|
+
url: string;
|
|
85
|
+
/** Headers injected into requests using the proxy's own authority. Values are never logged. */
|
|
86
|
+
headers: HeadersInit;
|
|
87
|
+
}
|
|
88
|
+
interface AuthenticatedOfficialConformanceOptions extends OfficialConformanceOptions {
|
|
89
|
+
headers: HeadersInit;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Start a loopback-only streaming proxy for runners that cannot send auth
|
|
93
|
+
* headers. Authenticated requests use one fixed upstream authority and path.
|
|
94
|
+
* Host-manipulation probes are forwarded without injected credentials.
|
|
95
|
+
*/
|
|
96
|
+
declare function createAuthenticatedConformanceProxy(options: AuthenticatedConformanceProxyOptions): Promise<AuthenticatedConformanceProxy>;
|
|
72
97
|
declare function buildOfficialConformanceArgs(options: OfficialConformanceOptions): string[];
|
|
73
98
|
declare function runOfficialConformance(options: OfficialConformanceOptions): Promise<OfficialConformanceResult>;
|
|
99
|
+
/** Run the pinned official suite against an authenticated MCP endpoint. */
|
|
100
|
+
declare function runAuthenticatedOfficialConformance(options: AuthenticatedOfficialConformanceOptions): Promise<OfficialConformanceResult>;
|
|
74
101
|
|
|
75
102
|
type McpFnServerFeature = "tools" | "resources" | "prompts" | "completions" | "tasks" | "logging";
|
|
76
103
|
interface McpFnHostProfile {
|
|
@@ -129,8 +156,20 @@ declare const MCPFN_HOST_PROFILES: {
|
|
|
129
156
|
};
|
|
130
157
|
declare function checkHostCompatibility(manifest: McpFnManifest, profile: McpFnHostProfile): McpFnHostCompatibilityResult;
|
|
131
158
|
|
|
132
|
-
|
|
159
|
+
type McpFnScenarioSideEffect = "none" | "idempotent" | "non-idempotent";
|
|
160
|
+
interface McpFnScenarioBase {
|
|
161
|
+
formatVersion?: 1;
|
|
133
162
|
name: string;
|
|
163
|
+
/** Defaults to the runner timeout. */
|
|
164
|
+
timeoutMs?: number;
|
|
165
|
+
sideEffect?: McpFnScenarioSideEffect;
|
|
166
|
+
status?: "complete" | "incomplete";
|
|
167
|
+
incompleteReason?: string;
|
|
168
|
+
/** Environment-backed placeholders used by this scenario, never their values. */
|
|
169
|
+
variables?: string[];
|
|
170
|
+
}
|
|
171
|
+
interface McpFnToolScenario extends McpFnScenarioBase {
|
|
172
|
+
kind?: "tools.call";
|
|
134
173
|
tool: string;
|
|
135
174
|
arguments?: Record<string, unknown>;
|
|
136
175
|
expect?: {
|
|
@@ -140,13 +179,190 @@ interface McpFnScenario {
|
|
|
140
179
|
};
|
|
141
180
|
verify?(result: CallToolResult): void | Promise<void>;
|
|
142
181
|
}
|
|
182
|
+
interface McpFnInventoryScenario extends McpFnScenarioBase {
|
|
183
|
+
kind: "tools.list" | "resources.list" | "resources.templates.list" | "prompts.list";
|
|
184
|
+
expectNames?: string[];
|
|
185
|
+
}
|
|
186
|
+
interface McpFnResourceScenario extends McpFnScenarioBase {
|
|
187
|
+
kind: "resources.read" | "resources.subscribe" | "resources.unsubscribe";
|
|
188
|
+
uri: string;
|
|
189
|
+
expect?: unknown;
|
|
190
|
+
}
|
|
191
|
+
interface McpFnPromptScenario extends McpFnScenarioBase {
|
|
192
|
+
kind: "prompts.get";
|
|
193
|
+
prompt: string;
|
|
194
|
+
arguments?: Record<string, string>;
|
|
195
|
+
expect?: unknown;
|
|
196
|
+
}
|
|
197
|
+
interface McpFnInitializeScenario extends McpFnScenarioBase {
|
|
198
|
+
kind: "initialize";
|
|
199
|
+
expectCapabilities?: Record<string, unknown>;
|
|
200
|
+
}
|
|
201
|
+
interface McpFnCreateTaskScenario extends McpFnScenarioBase {
|
|
202
|
+
kind: "tools.call:task";
|
|
203
|
+
tool: string;
|
|
204
|
+
arguments?: Record<string, unknown>;
|
|
205
|
+
task?: {
|
|
206
|
+
ttl?: number;
|
|
207
|
+
};
|
|
208
|
+
expect?: unknown;
|
|
209
|
+
}
|
|
210
|
+
interface McpFnTaskScenario extends McpFnScenarioBase {
|
|
211
|
+
kind: "tasks.get" | "tasks.result" | "tasks.cancel" | "tasks.list";
|
|
212
|
+
taskId?: string;
|
|
213
|
+
cursor?: string;
|
|
214
|
+
expect?: unknown;
|
|
215
|
+
}
|
|
216
|
+
interface McpFnEventScenario extends McpFnScenarioBase {
|
|
217
|
+
kind: "events.expect";
|
|
218
|
+
event: McpFnClientEventKind;
|
|
219
|
+
minimum?: number;
|
|
220
|
+
expectPayload?: unknown;
|
|
221
|
+
}
|
|
222
|
+
interface McpFnAuthScenario extends McpFnScenarioBase {
|
|
223
|
+
kind: "auth.assert";
|
|
224
|
+
phase: string;
|
|
225
|
+
expect: {
|
|
226
|
+
outcome: "allowed" | "denied";
|
|
227
|
+
code?: string;
|
|
228
|
+
};
|
|
229
|
+
input?: Record<string, unknown>;
|
|
230
|
+
}
|
|
231
|
+
type McpFnScenario = McpFnToolScenario | McpFnInventoryScenario | McpFnResourceScenario | McpFnPromptScenario | McpFnInitializeScenario | McpFnCreateTaskScenario | McpFnTaskScenario | McpFnEventScenario | McpFnAuthScenario;
|
|
232
|
+
interface McpFnScenarioArtifact {
|
|
233
|
+
formatVersion: 1;
|
|
234
|
+
kind: "mcpfn.scenarios";
|
|
235
|
+
status: "complete" | "incomplete";
|
|
236
|
+
scenarios: McpFnScenario[];
|
|
237
|
+
variables?: string[];
|
|
238
|
+
incompleteReason?: string;
|
|
239
|
+
}
|
|
240
|
+
type McpFnRecordedOperation = {
|
|
241
|
+
kind: "tools.call";
|
|
242
|
+
name: string;
|
|
243
|
+
arguments?: Record<string, unknown>;
|
|
244
|
+
} | {
|
|
245
|
+
kind: "tools.call:task";
|
|
246
|
+
name: string;
|
|
247
|
+
arguments?: Record<string, unknown>;
|
|
248
|
+
task?: {
|
|
249
|
+
ttl?: number;
|
|
250
|
+
};
|
|
251
|
+
} | {
|
|
252
|
+
kind: "resources.read";
|
|
253
|
+
uri: string;
|
|
254
|
+
} | {
|
|
255
|
+
kind: "resources.subscribe";
|
|
256
|
+
uri: string;
|
|
257
|
+
} | {
|
|
258
|
+
kind: "resources.unsubscribe";
|
|
259
|
+
uri: string;
|
|
260
|
+
} | {
|
|
261
|
+
kind: "prompts.get";
|
|
262
|
+
name: string;
|
|
263
|
+
arguments?: Record<string, string>;
|
|
264
|
+
} | {
|
|
265
|
+
kind: "tasks.get";
|
|
266
|
+
taskId: string;
|
|
267
|
+
} | {
|
|
268
|
+
kind: "tasks.result";
|
|
269
|
+
taskId: string;
|
|
270
|
+
} | {
|
|
271
|
+
kind: "tasks.cancel";
|
|
272
|
+
taskId: string;
|
|
273
|
+
} | {
|
|
274
|
+
kind: "tasks.list";
|
|
275
|
+
cursor?: string;
|
|
276
|
+
};
|
|
277
|
+
type McpFnRecordedOperationResult = CallToolResult | ReadResourceResult | GetPromptResult | CreateTaskResult | Task | ListTasksResult | void;
|
|
143
278
|
interface McpFnScenarioResult {
|
|
279
|
+
formatVersion: 1;
|
|
144
280
|
name: string;
|
|
145
|
-
|
|
146
|
-
|
|
281
|
+
operation: string;
|
|
282
|
+
tool?: string;
|
|
283
|
+
status: "passed" | "failed" | "incomplete";
|
|
284
|
+
sideEffect: McpFnScenarioSideEffect;
|
|
147
285
|
durationMs: number;
|
|
148
286
|
error?: string;
|
|
287
|
+
/** Observed client events discarded while this scenario was running. */
|
|
288
|
+
droppedObservedEvents?: number;
|
|
289
|
+
}
|
|
290
|
+
interface McpFnScenarioReport {
|
|
291
|
+
formatVersion: 1;
|
|
292
|
+
kind: "mcpfn.scenario-report";
|
|
293
|
+
status: "complete" | "incomplete";
|
|
294
|
+
manifestHash?: string;
|
|
295
|
+
total: number;
|
|
296
|
+
passed: number;
|
|
297
|
+
failed: number;
|
|
298
|
+
incomplete: number;
|
|
299
|
+
droppedResults: number;
|
|
300
|
+
droppedObservedEvents: number;
|
|
301
|
+
incompleteReason?: string;
|
|
302
|
+
results: McpFnScenarioResult[];
|
|
303
|
+
}
|
|
304
|
+
/** Convert an observed production-client operation into the shared runner contract. */
|
|
305
|
+
declare function createMcpFnScenario(name: string, operation: McpFnRecordedOperation, result: McpFnRecordedOperationResult): McpFnScenario;
|
|
306
|
+
/** Validate an unknown scenario module before it reaches the shared runner. */
|
|
307
|
+
declare function validateMcpFnScenarios(value: unknown): McpFnScenario[];
|
|
308
|
+
declare function createMcpFnScenarioArtifact(scenarios: McpFnScenario[], options?: Omit<McpFnScenarioArtifact, "formatVersion" | "kind" | "scenarios">): McpFnScenarioArtifact;
|
|
309
|
+
declare function runScenarios(client: McpFnTestClient<unknown>, scenarios: McpFnScenario[], options?: McpFnScenarioRunOptions): Promise<McpFnScenarioResult[]>;
|
|
310
|
+
interface McpFnScenarioRunOptions {
|
|
311
|
+
defaultTimeoutMs?: number;
|
|
312
|
+
maxScenarios?: number;
|
|
313
|
+
maxErrorBytes?: number;
|
|
314
|
+
/** Observed client-event count cap. Defaults to 500. */
|
|
315
|
+
maxObservedEvents?: number;
|
|
316
|
+
variables?: Record<string, string | undefined>;
|
|
317
|
+
auth?(scenario: McpFnAuthScenario, signal: AbortSignal): Promise<{
|
|
318
|
+
outcome: "allowed" | "denied";
|
|
319
|
+
code?: string;
|
|
320
|
+
}>;
|
|
321
|
+
}
|
|
322
|
+
declare function createMcpFnScenarioReport(results: McpFnScenarioResult[], options?: {
|
|
323
|
+
manifestHash?: string;
|
|
324
|
+
maxBytes?: number;
|
|
325
|
+
}): McpFnScenarioReport;
|
|
326
|
+
|
|
327
|
+
interface RunMcpFnTargetSuiteOptions {
|
|
328
|
+
target: McpFnTarget;
|
|
329
|
+
scenarios?: McpFnScenario[];
|
|
330
|
+
manifest?: McpFnManifest;
|
|
331
|
+
expectedToolNames?: readonly string[];
|
|
332
|
+
clientInfo?: Implementation;
|
|
333
|
+
client?: McpFnTestClientOptions;
|
|
334
|
+
scenarioRun?: NonNullable<Parameters<typeof runScenarios>[2]>;
|
|
335
|
+
/** Aggregate JSON size cap. Defaults to 1 MiB. */
|
|
336
|
+
maxReportBytes?: number;
|
|
337
|
+
/** Diagnostic timeline count cap. Defaults to 500. */
|
|
338
|
+
maxTimelineEvents?: number;
|
|
339
|
+
}
|
|
340
|
+
interface McpFnTargetSuiteReport {
|
|
341
|
+
formatVersion: 1;
|
|
342
|
+
kind: "mcpfn.target-suite-report";
|
|
343
|
+
status: "complete" | "incomplete";
|
|
344
|
+
runtime: {
|
|
345
|
+
node: string;
|
|
346
|
+
scenarioFormatVersion: 1;
|
|
347
|
+
};
|
|
348
|
+
ok: boolean;
|
|
349
|
+
target: McpFnTargetDescriptor;
|
|
350
|
+
server?: Implementation;
|
|
351
|
+
capabilities?: ServerCapabilities;
|
|
352
|
+
manifestChecked: boolean;
|
|
353
|
+
manifestHash?: string;
|
|
354
|
+
total: number;
|
|
355
|
+
passed: number;
|
|
356
|
+
failed: number;
|
|
357
|
+
incomplete: number;
|
|
358
|
+
droppedResults: number;
|
|
359
|
+
droppedObservedEvents: number;
|
|
360
|
+
incompleteReason?: string;
|
|
361
|
+
timeline: McpFnDiagnosticEvent[];
|
|
362
|
+
droppedTimelineEvents: number;
|
|
363
|
+
results: McpFnScenarioResult[];
|
|
149
364
|
}
|
|
150
|
-
|
|
365
|
+
/** Runs local, stdio, HTTP, or custom targets through the production session engine. */
|
|
366
|
+
declare function runMcpFnTargetSuite(options: RunMcpFnTargetSuiteOptions): Promise<McpFnTargetSuiteReport>;
|
|
151
367
|
|
|
152
|
-
export { type AssertManifestContractOptions, MCPFN_HOST_PROFILES, McpFnAssertionError, type McpFnHostCompatibilityIssue, type McpFnHostCompatibilityResult, type McpFnHostProfile, type McpFnScenario, type McpFnScenarioResult, type McpFnServerFeature, McpFnTestClient, type McpFnTestClientOptions, OFFICIAL_CONFORMANCE_VERSION, type OfficialConformanceOptions, type OfficialConformanceResult, assertManifestContract, assertStructuredTextParity, buildOfficialConformanceArgs, checkHostCompatibility, runOfficialConformance, runScenarios, stableJson };
|
|
368
|
+
export { type AssertManifestContractOptions, type AuthenticatedConformanceProxy, type AuthenticatedConformanceProxyOptions, type AuthenticatedOfficialConformanceOptions, MCPFN_HOST_PROFILES, McpFnAssertionError, type McpFnAuthScenario, type McpFnCreateTaskScenario, type McpFnEventScenario, type McpFnHostCompatibilityIssue, type McpFnHostCompatibilityResult, type McpFnHostProfile, type McpFnInitializeScenario, type McpFnInventoryScenario, type McpFnPromptScenario, type McpFnRecordedOperation, type McpFnRecordedOperationResult, type McpFnResourceScenario, type McpFnScenario, type McpFnScenarioArtifact, type McpFnScenarioBase, type McpFnScenarioReport, type McpFnScenarioResult, type McpFnScenarioRunOptions, type McpFnScenarioSideEffect, type McpFnServerFeature, type McpFnTargetSuiteReport, type McpFnTaskScenario, McpFnTestClient, type McpFnTestClientOptions, type McpFnToolScenario, OFFICIAL_CONFORMANCE_VERSION, type OfficialConformanceOptions, type OfficialConformanceResult, type RunMcpFnTargetSuiteOptions, assertManifestContract, assertStructuredTextParity, buildOfficialConformanceArgs, checkHostCompatibility, createAuthenticatedConformanceProxy, createMcpFnScenario, createMcpFnScenarioArtifact, createMcpFnScenarioReport, runAuthenticatedOfficialConformance, runMcpFnTargetSuite, runOfficialConformance, runScenarios, stableJson, validateMcpFnScenarios };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,40 +1,45 @@
|
|
|
1
|
-
import { ClientCapabilities, Tool, CallToolResult, CreateTaskResult, Task, ListTasksResult, Resource, ResourceTemplate, ReadResourceResult, Prompt, GetPromptResult, CompleteRequest, CompleteResult } from '@modelcontextprotocol/sdk/types.js';
|
|
1
|
+
import { ClientCapabilities, Implementation, Tool, CallToolResult, CreateTaskResult, Task, ListTasksResult, Resource, ResourceTemplate, ReadResourceResult, Prompt, GetPromptResult, CompleteRequest, CompleteResult, ServerCapabilities } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
import { McpFnServer, McpFnManifest } from '@mcpfn/core';
|
|
3
|
+
import { McpFnClient, McpFnClientMediatedHandlers, McpFnClientEventSink, McpFnDiagnosticSink, McpFnTarget, McpFnClientEventKind, McpFnTargetDescriptor, McpFnDiagnosticEvent } from '@mcpfn/client';
|
|
3
4
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
4
|
-
|
|
5
|
+
import { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
6
|
+
export { MCPFN_NAMED_OAUTH_HOST_FIXTURES, MCPFN_OAUTH_EXTENSION_GRANTS, McpFnAuthAssertionError, McpFnAuthCredential, McpFnAuthCredentialKind, McpFnAuthCredentialRequest, McpFnAuthProbeScenario, McpFnAuthProviderAdapter, McpFnAuthProviderCapabilities, McpFnAuthRegressionOptions, McpFnAuthScenarioResult, McpFnAuthTarget, McpFnBearerChallenge, McpFnFetchAuthTargetOptions, McpFnMockOAuthAuthorizationServer, McpFnMockOAuthServerOptions, McpFnMockOAuthTokenSet, McpFnNamedOAuthHostFixture, McpFnOAuthCallback, McpFnOAuthClientMetadata, McpFnOAuthClientMetadataFixtureOptions, McpFnOAuthClientMetadataVariants, McpFnPkcePair, McpFnStartMockOAuthServerOptions, McpFnStartedMockOAuthServer, apiKeyCredential, assertAuthRegressionSuite, assertAuthorizationCodeClientMetadata, assertBearerResourceChallenge, bearerCredential, createFetchAuthTarget, createOAuthClientMetadataFixture, createOAuthClientMetadataVariants, createPkcePair, parseBearerChallenge, runAuthRegressionSuite, startMockOAuthAuthorizationServer } from './auth.js';
|
|
5
7
|
import '@modelcontextprotocol/sdk/server/auth/types.js';
|
|
6
8
|
|
|
7
9
|
interface McpFnTestClientOptions {
|
|
8
10
|
capabilities?: ClientCapabilities;
|
|
11
|
+
handlers?: McpFnClientMediatedHandlers;
|
|
12
|
+
events?: McpFnClientEventSink;
|
|
9
13
|
/** Install roots, sampling, elicitation, or notification handlers before initialize. */
|
|
10
14
|
configure?(client: Client): void | Promise<void>;
|
|
15
|
+
diagnostics?: McpFnDiagnosticSink;
|
|
11
16
|
}
|
|
12
17
|
declare class McpFnTestClient<TContext = undefined> {
|
|
13
|
-
readonly
|
|
14
|
-
private readonly server;
|
|
15
|
-
private closed;
|
|
18
|
+
readonly session: McpFnClient;
|
|
16
19
|
private constructor();
|
|
20
|
+
get client(): Client;
|
|
17
21
|
static connect<TContext>(server: McpFnServer<TContext>, info?: {
|
|
18
22
|
name: string;
|
|
19
23
|
version: string;
|
|
20
24
|
}, options?: McpFnTestClientOptions): Promise<McpFnTestClient<TContext>>;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
static connectTarget<TContext = undefined>(target: McpFnTarget, info?: Implementation, options?: McpFnTestClientOptions): Promise<McpFnTestClient<TContext>>;
|
|
26
|
+
listTools(options?: RequestOptions): Promise<Tool[]>;
|
|
27
|
+
callTool(name: string, args?: Record<string, unknown>, options?: RequestOptions): Promise<CallToolResult>;
|
|
28
|
+
createToolTask(name: string, args?: Record<string, unknown>, task?: {
|
|
24
29
|
ttl?: number;
|
|
25
|
-
}): Promise<CreateTaskResult>;
|
|
26
|
-
getTask(taskId: string): Promise<Task>;
|
|
27
|
-
getTaskResult(taskId: string): Promise<CallToolResult>;
|
|
28
|
-
listTasks(cursor?: string): Promise<ListTasksResult>;
|
|
29
|
-
cancelTask(taskId: string): Promise<Task>;
|
|
30
|
-
listResources(): Promise<Resource[]>;
|
|
31
|
-
listResourceTemplates(): Promise<ResourceTemplate[]>;
|
|
32
|
-
readResource(uri: string): Promise<ReadResourceResult>;
|
|
33
|
-
subscribeResource(uri: string): Promise<void>;
|
|
34
|
-
unsubscribeResource(uri: string): Promise<void>;
|
|
35
|
-
listPrompts(): Promise<Prompt[]>;
|
|
36
|
-
getPrompt(name: string, args?: Record<string, string
|
|
37
|
-
complete(params: CompleteRequest["params"]): Promise<CompleteResult>;
|
|
30
|
+
}, options?: RequestOptions): Promise<CreateTaskResult>;
|
|
31
|
+
getTask(taskId: string, options?: RequestOptions): Promise<Task>;
|
|
32
|
+
getTaskResult(taskId: string, options?: RequestOptions): Promise<CallToolResult>;
|
|
33
|
+
listTasks(cursor?: string, options?: RequestOptions): Promise<ListTasksResult>;
|
|
34
|
+
cancelTask(taskId: string, options?: RequestOptions): Promise<Task>;
|
|
35
|
+
listResources(options?: RequestOptions): Promise<Resource[]>;
|
|
36
|
+
listResourceTemplates(options?: RequestOptions): Promise<ResourceTemplate[]>;
|
|
37
|
+
readResource(uri: string, options?: RequestOptions): Promise<ReadResourceResult>;
|
|
38
|
+
subscribeResource(uri: string, options?: RequestOptions): Promise<void>;
|
|
39
|
+
unsubscribeResource(uri: string, options?: RequestOptions): Promise<void>;
|
|
40
|
+
listPrompts(options?: RequestOptions): Promise<Prompt[]>;
|
|
41
|
+
getPrompt(name: string, args?: Record<string, string>, options?: RequestOptions): Promise<GetPromptResult>;
|
|
42
|
+
complete(params: CompleteRequest["params"], options?: RequestOptions): Promise<CompleteResult>;
|
|
38
43
|
close(): Promise<void>;
|
|
39
44
|
}
|
|
40
45
|
|
|
@@ -69,8 +74,30 @@ interface OfficialConformanceResult {
|
|
|
69
74
|
stdout: string;
|
|
70
75
|
stderr: string;
|
|
71
76
|
}
|
|
77
|
+
interface AuthenticatedConformanceProxy {
|
|
78
|
+
/** Loopback URL to pass to the official conformance runner. */
|
|
79
|
+
url: string;
|
|
80
|
+
close(): Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
interface AuthenticatedConformanceProxyOptions {
|
|
83
|
+
/** Fixed loopback MCP URL. Requests cannot select a different origin or path. */
|
|
84
|
+
url: string;
|
|
85
|
+
/** Headers injected into requests using the proxy's own authority. Values are never logged. */
|
|
86
|
+
headers: HeadersInit;
|
|
87
|
+
}
|
|
88
|
+
interface AuthenticatedOfficialConformanceOptions extends OfficialConformanceOptions {
|
|
89
|
+
headers: HeadersInit;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Start a loopback-only streaming proxy for runners that cannot send auth
|
|
93
|
+
* headers. Authenticated requests use one fixed upstream authority and path.
|
|
94
|
+
* Host-manipulation probes are forwarded without injected credentials.
|
|
95
|
+
*/
|
|
96
|
+
declare function createAuthenticatedConformanceProxy(options: AuthenticatedConformanceProxyOptions): Promise<AuthenticatedConformanceProxy>;
|
|
72
97
|
declare function buildOfficialConformanceArgs(options: OfficialConformanceOptions): string[];
|
|
73
98
|
declare function runOfficialConformance(options: OfficialConformanceOptions): Promise<OfficialConformanceResult>;
|
|
99
|
+
/** Run the pinned official suite against an authenticated MCP endpoint. */
|
|
100
|
+
declare function runAuthenticatedOfficialConformance(options: AuthenticatedOfficialConformanceOptions): Promise<OfficialConformanceResult>;
|
|
74
101
|
|
|
75
102
|
type McpFnServerFeature = "tools" | "resources" | "prompts" | "completions" | "tasks" | "logging";
|
|
76
103
|
interface McpFnHostProfile {
|
|
@@ -129,8 +156,20 @@ declare const MCPFN_HOST_PROFILES: {
|
|
|
129
156
|
};
|
|
130
157
|
declare function checkHostCompatibility(manifest: McpFnManifest, profile: McpFnHostProfile): McpFnHostCompatibilityResult;
|
|
131
158
|
|
|
132
|
-
|
|
159
|
+
type McpFnScenarioSideEffect = "none" | "idempotent" | "non-idempotent";
|
|
160
|
+
interface McpFnScenarioBase {
|
|
161
|
+
formatVersion?: 1;
|
|
133
162
|
name: string;
|
|
163
|
+
/** Defaults to the runner timeout. */
|
|
164
|
+
timeoutMs?: number;
|
|
165
|
+
sideEffect?: McpFnScenarioSideEffect;
|
|
166
|
+
status?: "complete" | "incomplete";
|
|
167
|
+
incompleteReason?: string;
|
|
168
|
+
/** Environment-backed placeholders used by this scenario, never their values. */
|
|
169
|
+
variables?: string[];
|
|
170
|
+
}
|
|
171
|
+
interface McpFnToolScenario extends McpFnScenarioBase {
|
|
172
|
+
kind?: "tools.call";
|
|
134
173
|
tool: string;
|
|
135
174
|
arguments?: Record<string, unknown>;
|
|
136
175
|
expect?: {
|
|
@@ -140,13 +179,190 @@ interface McpFnScenario {
|
|
|
140
179
|
};
|
|
141
180
|
verify?(result: CallToolResult): void | Promise<void>;
|
|
142
181
|
}
|
|
182
|
+
interface McpFnInventoryScenario extends McpFnScenarioBase {
|
|
183
|
+
kind: "tools.list" | "resources.list" | "resources.templates.list" | "prompts.list";
|
|
184
|
+
expectNames?: string[];
|
|
185
|
+
}
|
|
186
|
+
interface McpFnResourceScenario extends McpFnScenarioBase {
|
|
187
|
+
kind: "resources.read" | "resources.subscribe" | "resources.unsubscribe";
|
|
188
|
+
uri: string;
|
|
189
|
+
expect?: unknown;
|
|
190
|
+
}
|
|
191
|
+
interface McpFnPromptScenario extends McpFnScenarioBase {
|
|
192
|
+
kind: "prompts.get";
|
|
193
|
+
prompt: string;
|
|
194
|
+
arguments?: Record<string, string>;
|
|
195
|
+
expect?: unknown;
|
|
196
|
+
}
|
|
197
|
+
interface McpFnInitializeScenario extends McpFnScenarioBase {
|
|
198
|
+
kind: "initialize";
|
|
199
|
+
expectCapabilities?: Record<string, unknown>;
|
|
200
|
+
}
|
|
201
|
+
interface McpFnCreateTaskScenario extends McpFnScenarioBase {
|
|
202
|
+
kind: "tools.call:task";
|
|
203
|
+
tool: string;
|
|
204
|
+
arguments?: Record<string, unknown>;
|
|
205
|
+
task?: {
|
|
206
|
+
ttl?: number;
|
|
207
|
+
};
|
|
208
|
+
expect?: unknown;
|
|
209
|
+
}
|
|
210
|
+
interface McpFnTaskScenario extends McpFnScenarioBase {
|
|
211
|
+
kind: "tasks.get" | "tasks.result" | "tasks.cancel" | "tasks.list";
|
|
212
|
+
taskId?: string;
|
|
213
|
+
cursor?: string;
|
|
214
|
+
expect?: unknown;
|
|
215
|
+
}
|
|
216
|
+
interface McpFnEventScenario extends McpFnScenarioBase {
|
|
217
|
+
kind: "events.expect";
|
|
218
|
+
event: McpFnClientEventKind;
|
|
219
|
+
minimum?: number;
|
|
220
|
+
expectPayload?: unknown;
|
|
221
|
+
}
|
|
222
|
+
interface McpFnAuthScenario extends McpFnScenarioBase {
|
|
223
|
+
kind: "auth.assert";
|
|
224
|
+
phase: string;
|
|
225
|
+
expect: {
|
|
226
|
+
outcome: "allowed" | "denied";
|
|
227
|
+
code?: string;
|
|
228
|
+
};
|
|
229
|
+
input?: Record<string, unknown>;
|
|
230
|
+
}
|
|
231
|
+
type McpFnScenario = McpFnToolScenario | McpFnInventoryScenario | McpFnResourceScenario | McpFnPromptScenario | McpFnInitializeScenario | McpFnCreateTaskScenario | McpFnTaskScenario | McpFnEventScenario | McpFnAuthScenario;
|
|
232
|
+
interface McpFnScenarioArtifact {
|
|
233
|
+
formatVersion: 1;
|
|
234
|
+
kind: "mcpfn.scenarios";
|
|
235
|
+
status: "complete" | "incomplete";
|
|
236
|
+
scenarios: McpFnScenario[];
|
|
237
|
+
variables?: string[];
|
|
238
|
+
incompleteReason?: string;
|
|
239
|
+
}
|
|
240
|
+
type McpFnRecordedOperation = {
|
|
241
|
+
kind: "tools.call";
|
|
242
|
+
name: string;
|
|
243
|
+
arguments?: Record<string, unknown>;
|
|
244
|
+
} | {
|
|
245
|
+
kind: "tools.call:task";
|
|
246
|
+
name: string;
|
|
247
|
+
arguments?: Record<string, unknown>;
|
|
248
|
+
task?: {
|
|
249
|
+
ttl?: number;
|
|
250
|
+
};
|
|
251
|
+
} | {
|
|
252
|
+
kind: "resources.read";
|
|
253
|
+
uri: string;
|
|
254
|
+
} | {
|
|
255
|
+
kind: "resources.subscribe";
|
|
256
|
+
uri: string;
|
|
257
|
+
} | {
|
|
258
|
+
kind: "resources.unsubscribe";
|
|
259
|
+
uri: string;
|
|
260
|
+
} | {
|
|
261
|
+
kind: "prompts.get";
|
|
262
|
+
name: string;
|
|
263
|
+
arguments?: Record<string, string>;
|
|
264
|
+
} | {
|
|
265
|
+
kind: "tasks.get";
|
|
266
|
+
taskId: string;
|
|
267
|
+
} | {
|
|
268
|
+
kind: "tasks.result";
|
|
269
|
+
taskId: string;
|
|
270
|
+
} | {
|
|
271
|
+
kind: "tasks.cancel";
|
|
272
|
+
taskId: string;
|
|
273
|
+
} | {
|
|
274
|
+
kind: "tasks.list";
|
|
275
|
+
cursor?: string;
|
|
276
|
+
};
|
|
277
|
+
type McpFnRecordedOperationResult = CallToolResult | ReadResourceResult | GetPromptResult | CreateTaskResult | Task | ListTasksResult | void;
|
|
143
278
|
interface McpFnScenarioResult {
|
|
279
|
+
formatVersion: 1;
|
|
144
280
|
name: string;
|
|
145
|
-
|
|
146
|
-
|
|
281
|
+
operation: string;
|
|
282
|
+
tool?: string;
|
|
283
|
+
status: "passed" | "failed" | "incomplete";
|
|
284
|
+
sideEffect: McpFnScenarioSideEffect;
|
|
147
285
|
durationMs: number;
|
|
148
286
|
error?: string;
|
|
287
|
+
/** Observed client events discarded while this scenario was running. */
|
|
288
|
+
droppedObservedEvents?: number;
|
|
289
|
+
}
|
|
290
|
+
interface McpFnScenarioReport {
|
|
291
|
+
formatVersion: 1;
|
|
292
|
+
kind: "mcpfn.scenario-report";
|
|
293
|
+
status: "complete" | "incomplete";
|
|
294
|
+
manifestHash?: string;
|
|
295
|
+
total: number;
|
|
296
|
+
passed: number;
|
|
297
|
+
failed: number;
|
|
298
|
+
incomplete: number;
|
|
299
|
+
droppedResults: number;
|
|
300
|
+
droppedObservedEvents: number;
|
|
301
|
+
incompleteReason?: string;
|
|
302
|
+
results: McpFnScenarioResult[];
|
|
303
|
+
}
|
|
304
|
+
/** Convert an observed production-client operation into the shared runner contract. */
|
|
305
|
+
declare function createMcpFnScenario(name: string, operation: McpFnRecordedOperation, result: McpFnRecordedOperationResult): McpFnScenario;
|
|
306
|
+
/** Validate an unknown scenario module before it reaches the shared runner. */
|
|
307
|
+
declare function validateMcpFnScenarios(value: unknown): McpFnScenario[];
|
|
308
|
+
declare function createMcpFnScenarioArtifact(scenarios: McpFnScenario[], options?: Omit<McpFnScenarioArtifact, "formatVersion" | "kind" | "scenarios">): McpFnScenarioArtifact;
|
|
309
|
+
declare function runScenarios(client: McpFnTestClient<unknown>, scenarios: McpFnScenario[], options?: McpFnScenarioRunOptions): Promise<McpFnScenarioResult[]>;
|
|
310
|
+
interface McpFnScenarioRunOptions {
|
|
311
|
+
defaultTimeoutMs?: number;
|
|
312
|
+
maxScenarios?: number;
|
|
313
|
+
maxErrorBytes?: number;
|
|
314
|
+
/** Observed client-event count cap. Defaults to 500. */
|
|
315
|
+
maxObservedEvents?: number;
|
|
316
|
+
variables?: Record<string, string | undefined>;
|
|
317
|
+
auth?(scenario: McpFnAuthScenario, signal: AbortSignal): Promise<{
|
|
318
|
+
outcome: "allowed" | "denied";
|
|
319
|
+
code?: string;
|
|
320
|
+
}>;
|
|
321
|
+
}
|
|
322
|
+
declare function createMcpFnScenarioReport(results: McpFnScenarioResult[], options?: {
|
|
323
|
+
manifestHash?: string;
|
|
324
|
+
maxBytes?: number;
|
|
325
|
+
}): McpFnScenarioReport;
|
|
326
|
+
|
|
327
|
+
interface RunMcpFnTargetSuiteOptions {
|
|
328
|
+
target: McpFnTarget;
|
|
329
|
+
scenarios?: McpFnScenario[];
|
|
330
|
+
manifest?: McpFnManifest;
|
|
331
|
+
expectedToolNames?: readonly string[];
|
|
332
|
+
clientInfo?: Implementation;
|
|
333
|
+
client?: McpFnTestClientOptions;
|
|
334
|
+
scenarioRun?: NonNullable<Parameters<typeof runScenarios>[2]>;
|
|
335
|
+
/** Aggregate JSON size cap. Defaults to 1 MiB. */
|
|
336
|
+
maxReportBytes?: number;
|
|
337
|
+
/** Diagnostic timeline count cap. Defaults to 500. */
|
|
338
|
+
maxTimelineEvents?: number;
|
|
339
|
+
}
|
|
340
|
+
interface McpFnTargetSuiteReport {
|
|
341
|
+
formatVersion: 1;
|
|
342
|
+
kind: "mcpfn.target-suite-report";
|
|
343
|
+
status: "complete" | "incomplete";
|
|
344
|
+
runtime: {
|
|
345
|
+
node: string;
|
|
346
|
+
scenarioFormatVersion: 1;
|
|
347
|
+
};
|
|
348
|
+
ok: boolean;
|
|
349
|
+
target: McpFnTargetDescriptor;
|
|
350
|
+
server?: Implementation;
|
|
351
|
+
capabilities?: ServerCapabilities;
|
|
352
|
+
manifestChecked: boolean;
|
|
353
|
+
manifestHash?: string;
|
|
354
|
+
total: number;
|
|
355
|
+
passed: number;
|
|
356
|
+
failed: number;
|
|
357
|
+
incomplete: number;
|
|
358
|
+
droppedResults: number;
|
|
359
|
+
droppedObservedEvents: number;
|
|
360
|
+
incompleteReason?: string;
|
|
361
|
+
timeline: McpFnDiagnosticEvent[];
|
|
362
|
+
droppedTimelineEvents: number;
|
|
363
|
+
results: McpFnScenarioResult[];
|
|
149
364
|
}
|
|
150
|
-
|
|
365
|
+
/** Runs local, stdio, HTTP, or custom targets through the production session engine. */
|
|
366
|
+
declare function runMcpFnTargetSuite(options: RunMcpFnTargetSuiteOptions): Promise<McpFnTargetSuiteReport>;
|
|
151
367
|
|
|
152
|
-
export { type AssertManifestContractOptions, MCPFN_HOST_PROFILES, McpFnAssertionError, type McpFnHostCompatibilityIssue, type McpFnHostCompatibilityResult, type McpFnHostProfile, type McpFnScenario, type McpFnScenarioResult, type McpFnServerFeature, McpFnTestClient, type McpFnTestClientOptions, OFFICIAL_CONFORMANCE_VERSION, type OfficialConformanceOptions, type OfficialConformanceResult, assertManifestContract, assertStructuredTextParity, buildOfficialConformanceArgs, checkHostCompatibility, runOfficialConformance, runScenarios, stableJson };
|
|
368
|
+
export { type AssertManifestContractOptions, type AuthenticatedConformanceProxy, type AuthenticatedConformanceProxyOptions, type AuthenticatedOfficialConformanceOptions, MCPFN_HOST_PROFILES, McpFnAssertionError, type McpFnAuthScenario, type McpFnCreateTaskScenario, type McpFnEventScenario, type McpFnHostCompatibilityIssue, type McpFnHostCompatibilityResult, type McpFnHostProfile, type McpFnInitializeScenario, type McpFnInventoryScenario, type McpFnPromptScenario, type McpFnRecordedOperation, type McpFnRecordedOperationResult, type McpFnResourceScenario, type McpFnScenario, type McpFnScenarioArtifact, type McpFnScenarioBase, type McpFnScenarioReport, type McpFnScenarioResult, type McpFnScenarioRunOptions, type McpFnScenarioSideEffect, type McpFnServerFeature, type McpFnTargetSuiteReport, type McpFnTaskScenario, McpFnTestClient, type McpFnTestClientOptions, type McpFnToolScenario, OFFICIAL_CONFORMANCE_VERSION, type OfficialConformanceOptions, type OfficialConformanceResult, type RunMcpFnTargetSuiteOptions, assertManifestContract, assertStructuredTextParity, buildOfficialConformanceArgs, checkHostCompatibility, createAuthenticatedConformanceProxy, createMcpFnScenario, createMcpFnScenarioArtifact, createMcpFnScenarioReport, runAuthenticatedOfficialConformance, runMcpFnTargetSuite, runOfficialConformance, runScenarios, stableJson, validateMcpFnScenarios };
|