@mcpspec/core 1.0.0
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/LICENSE +21 -0
- package/dist/http-XUWKDMSR.js +9 -0
- package/dist/index.d.ts +526 -0
- package/dist/index.js +3305 -0
- package/dist/sse-NXEF5JDZ.js +9 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MCPSpec Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// src/client/transports/http.ts
|
|
2
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
3
|
+
function createStreamableHTTPTransport(url) {
|
|
4
|
+
return new StreamableHTTPClientTransport(new URL(url));
|
|
5
|
+
}
|
|
6
|
+
export {
|
|
7
|
+
StreamableHTTPClientTransport,
|
|
8
|
+
createStreamableHTTPTransport
|
|
9
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import * as _mcpspec_shared from '@mcpspec/shared';
|
|
2
|
+
import { ErrorTemplate, ManagedProcess, ProcessConfig, ServerConfig, ConnectionConfig, ConnectionState, TestResult, TestRunResult, CollectionDefinition, RateLimitConfig, TestDefinition, SecurityScanMode, SeverityLevel, SecurityScanConfig, SecurityFinding, SecurityScanResult, ProfileEntry, BenchmarkStats, BenchmarkResult, BenchmarkConfig, WaterfallEntry, MCPScore } from '@mcpspec/shared';
|
|
3
|
+
import { Transport, TransportSendOptions } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
4
|
+
import { JSONRPCMessage, MessageExtraInfo } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
|
|
6
|
+
type ErrorCode = 'CONNECTION_TIMEOUT' | 'CONNECTION_REFUSED' | 'CONNECTION_LOST' | 'PROCESS_SPAWN_FAILED' | 'PROCESS_CRASHED' | 'PROCESS_TIMEOUT' | 'TOOL_NOT_FOUND' | 'TOOL_CALL_FAILED' | 'INVALID_RESPONSE' | 'SCHEMA_VALIDATION_FAILED' | 'ASSERTION_FAILED' | 'COLLECTION_PARSE_ERROR' | 'COLLECTION_VALIDATION_ERROR' | 'YAML_PARSE_ERROR' | 'YAML_TOO_LARGE' | 'YAML_TOO_DEEP' | 'TIMEOUT' | 'RATE_LIMITED' | 'CONFIG_ERROR' | 'SECURITY_SCAN_ERROR' | 'NOT_IMPLEMENTED' | 'UNKNOWN_ERROR';
|
|
7
|
+
declare const ERROR_CODE_MAP: Record<ErrorCode, number>;
|
|
8
|
+
|
|
9
|
+
declare class MCPSpecError extends Error {
|
|
10
|
+
readonly code: ErrorCode;
|
|
11
|
+
readonly exitCode: number;
|
|
12
|
+
readonly context: Record<string, unknown>;
|
|
13
|
+
constructor(code: ErrorCode, message: string, context?: Record<string, unknown>);
|
|
14
|
+
}
|
|
15
|
+
declare class NotImplementedError extends MCPSpecError {
|
|
16
|
+
constructor(feature: string);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare const ERROR_TEMPLATES: Record<string, ErrorTemplate>;
|
|
20
|
+
|
|
21
|
+
interface FormattedError {
|
|
22
|
+
title: string;
|
|
23
|
+
description: string;
|
|
24
|
+
suggestions: string[];
|
|
25
|
+
docs?: string;
|
|
26
|
+
code: string;
|
|
27
|
+
exitCode: number;
|
|
28
|
+
}
|
|
29
|
+
declare function formatError(error: unknown): FormattedError;
|
|
30
|
+
|
|
31
|
+
declare const YAML_LIMITS: {
|
|
32
|
+
maxFileSize: number;
|
|
33
|
+
maxNestingDepth: number;
|
|
34
|
+
maxTests: number;
|
|
35
|
+
};
|
|
36
|
+
declare function loadYamlSafely(content: string): unknown;
|
|
37
|
+
|
|
38
|
+
declare class SecretMasker {
|
|
39
|
+
private secrets;
|
|
40
|
+
private static readonly REDACTED;
|
|
41
|
+
private static readonly SECRET_PATTERNS;
|
|
42
|
+
private static readonly MIN_SECRET_LENGTH;
|
|
43
|
+
register(secret: string): void;
|
|
44
|
+
registerFromEnv(env: Record<string, string>): void;
|
|
45
|
+
mask(text: string): string;
|
|
46
|
+
clear(): void;
|
|
47
|
+
get size(): number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
declare function resolveVariables(template: string, variables: Record<string, unknown>): string;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Simple JSONPath implementation supporting basic dot notation.
|
|
54
|
+
* Supports: $.foo.bar, $.foo[0], $.foo[0].bar
|
|
55
|
+
*/
|
|
56
|
+
declare function queryJsonPath(data: unknown, path: string): unknown;
|
|
57
|
+
|
|
58
|
+
interface PlatformInfo {
|
|
59
|
+
os: NodeJS.Platform;
|
|
60
|
+
arch: string;
|
|
61
|
+
release: string;
|
|
62
|
+
nodeVersion: string;
|
|
63
|
+
isWindows: boolean;
|
|
64
|
+
isMacOS: boolean;
|
|
65
|
+
isLinux: boolean;
|
|
66
|
+
tmpDir: string;
|
|
67
|
+
homeDir: string;
|
|
68
|
+
dataDir: string;
|
|
69
|
+
}
|
|
70
|
+
declare function getPlatformInfo(): PlatformInfo;
|
|
71
|
+
|
|
72
|
+
declare class ProcessRegistry {
|
|
73
|
+
private processes;
|
|
74
|
+
register(process: ManagedProcess): void;
|
|
75
|
+
unregister(id: string): void;
|
|
76
|
+
get(id: string): ManagedProcess | undefined;
|
|
77
|
+
getAll(): ManagedProcess[];
|
|
78
|
+
has(id: string): boolean;
|
|
79
|
+
get size(): number;
|
|
80
|
+
clear(): void;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
declare class ProcessManagerImpl {
|
|
84
|
+
private registry;
|
|
85
|
+
private readonly defaultGracePeriod;
|
|
86
|
+
constructor(registry?: ProcessRegistry);
|
|
87
|
+
spawn(config: ProcessConfig): Promise<ManagedProcess>;
|
|
88
|
+
shutdown(processId: string, gracePeriodMs?: number): Promise<void>;
|
|
89
|
+
shutdownAll(): Promise<void>;
|
|
90
|
+
isAlive(processId: string): boolean;
|
|
91
|
+
getRegistry(): ProcessRegistry;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
declare function registerCleanupHandlers(manager: ProcessManagerImpl): void;
|
|
95
|
+
|
|
96
|
+
interface ToolInfo {
|
|
97
|
+
name: string;
|
|
98
|
+
description?: string;
|
|
99
|
+
inputSchema?: Record<string, unknown>;
|
|
100
|
+
}
|
|
101
|
+
interface ResourceInfo {
|
|
102
|
+
uri: string;
|
|
103
|
+
name?: string;
|
|
104
|
+
description?: string;
|
|
105
|
+
mimeType?: string;
|
|
106
|
+
}
|
|
107
|
+
interface ToolCallResult {
|
|
108
|
+
content: unknown[];
|
|
109
|
+
isError?: boolean;
|
|
110
|
+
}
|
|
111
|
+
interface MCPClientInterface {
|
|
112
|
+
connect(): Promise<void>;
|
|
113
|
+
disconnect(): Promise<void>;
|
|
114
|
+
isConnected(): boolean;
|
|
115
|
+
listTools(): Promise<ToolInfo[]>;
|
|
116
|
+
listResources(): Promise<ResourceInfo[]>;
|
|
117
|
+
callTool(name: string, args: Record<string, unknown>): Promise<ToolCallResult>;
|
|
118
|
+
readResource(uri: string): Promise<{
|
|
119
|
+
contents: unknown[];
|
|
120
|
+
}>;
|
|
121
|
+
getServerInfo(): {
|
|
122
|
+
name?: string;
|
|
123
|
+
version?: string;
|
|
124
|
+
} | undefined;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
type OnProtocolMessage = (direction: 'outgoing' | 'incoming', message: Record<string, unknown>) => void;
|
|
128
|
+
/**
|
|
129
|
+
* Wraps an SDK Transport to intercept and log all JSON-RPC messages.
|
|
130
|
+
*/
|
|
131
|
+
declare class LoggingTransport implements Transport {
|
|
132
|
+
private inner;
|
|
133
|
+
private callback;
|
|
134
|
+
constructor(inner: Transport, callback: OnProtocolMessage);
|
|
135
|
+
start(): Promise<void>;
|
|
136
|
+
send(message: JSONRPCMessage, options?: TransportSendOptions): Promise<void>;
|
|
137
|
+
close(): Promise<void>;
|
|
138
|
+
get onclose(): (() => void) | undefined;
|
|
139
|
+
set onclose(handler: (() => void) | undefined);
|
|
140
|
+
get onerror(): ((error: Error) => void) | undefined;
|
|
141
|
+
set onerror(handler: ((error: Error) => void) | undefined);
|
|
142
|
+
get onmessage(): (<T extends JSONRPCMessage>(message: T, extra?: MessageExtraInfo) => void) | undefined;
|
|
143
|
+
set onmessage(handler: (<T extends JSONRPCMessage>(message: T, extra?: MessageExtraInfo) => void) | undefined);
|
|
144
|
+
get sessionId(): string | undefined;
|
|
145
|
+
set sessionId(value: string | undefined);
|
|
146
|
+
get setProtocolVersion(): ((version: string) => void) | undefined;
|
|
147
|
+
set setProtocolVersion(handler: ((version: string) => void) | undefined);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
interface MCPClientOptions {
|
|
151
|
+
serverConfig: ServerConfig | string;
|
|
152
|
+
processManager?: ProcessManagerImpl;
|
|
153
|
+
onProtocolMessage?: OnProtocolMessage;
|
|
154
|
+
}
|
|
155
|
+
declare class MCPClient implements MCPClientInterface {
|
|
156
|
+
private client;
|
|
157
|
+
private transport;
|
|
158
|
+
private connectionManager;
|
|
159
|
+
readonly processManager: ProcessManagerImpl;
|
|
160
|
+
private serverConfig;
|
|
161
|
+
private serverInfo;
|
|
162
|
+
private onProtocolMessage?;
|
|
163
|
+
constructor(options: MCPClientOptions);
|
|
164
|
+
private normalizeConfig;
|
|
165
|
+
connect(): Promise<void>;
|
|
166
|
+
private reconnect;
|
|
167
|
+
private createTransport;
|
|
168
|
+
disconnect(): Promise<void>;
|
|
169
|
+
isConnected(): boolean;
|
|
170
|
+
listTools(): Promise<ToolInfo[]>;
|
|
171
|
+
listResources(): Promise<ResourceInfo[]>;
|
|
172
|
+
callTool(name: string, args: Record<string, unknown>): Promise<ToolCallResult>;
|
|
173
|
+
readResource(uri: string): Promise<{
|
|
174
|
+
contents: unknown[];
|
|
175
|
+
}>;
|
|
176
|
+
getServerInfo(): {
|
|
177
|
+
name?: string;
|
|
178
|
+
version?: string;
|
|
179
|
+
} | undefined;
|
|
180
|
+
getConnectionState(): _mcpspec_shared.ConnectionState;
|
|
181
|
+
private ensureConnected;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
declare class ConnectionManager {
|
|
185
|
+
private state;
|
|
186
|
+
private reconnectAttempts;
|
|
187
|
+
private config;
|
|
188
|
+
private listeners;
|
|
189
|
+
constructor(config?: Partial<ConnectionConfig>);
|
|
190
|
+
getState(): ConnectionState;
|
|
191
|
+
canTransition(to: ConnectionState): boolean;
|
|
192
|
+
transition(to: ConnectionState): void;
|
|
193
|
+
onTransition(listener: (from: ConnectionState, to: ConnectionState) => void): () => void;
|
|
194
|
+
shouldReconnect(): boolean;
|
|
195
|
+
getReconnectDelay(): number;
|
|
196
|
+
resetReconnectAttempts(): void;
|
|
197
|
+
getConfig(): ConnectionConfig;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
interface TestRunnerOptions {
|
|
201
|
+
environment?: string;
|
|
202
|
+
reporter?: TestRunReporter;
|
|
203
|
+
parallelism?: number;
|
|
204
|
+
tags?: string[];
|
|
205
|
+
rateLimitConfig?: Partial<RateLimitConfig>;
|
|
206
|
+
}
|
|
207
|
+
interface TestRunReporter {
|
|
208
|
+
onRunStart(collectionName: string, testCount: number): void;
|
|
209
|
+
onTestStart(testName: string): void;
|
|
210
|
+
onTestComplete(result: TestResult): void;
|
|
211
|
+
onRunComplete(result: TestRunResult): void;
|
|
212
|
+
setSecretMasker?(masker: SecretMasker): void;
|
|
213
|
+
}
|
|
214
|
+
declare class TestRunner {
|
|
215
|
+
private processManager;
|
|
216
|
+
constructor();
|
|
217
|
+
run(collection: CollectionDefinition, options?: TestRunnerOptions): Promise<TestRunResult>;
|
|
218
|
+
private resolveServerConfig;
|
|
219
|
+
private computeSummary;
|
|
220
|
+
cleanup(): Promise<void>;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
declare class RateLimiter {
|
|
224
|
+
private limiter;
|
|
225
|
+
private config;
|
|
226
|
+
constructor(config?: Partial<RateLimitConfig>);
|
|
227
|
+
schedule<T>(fn: () => Promise<T>): Promise<T>;
|
|
228
|
+
getConfig(): RateLimitConfig;
|
|
229
|
+
stop(): Promise<void>;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
declare class TestExecutor {
|
|
233
|
+
private variables;
|
|
234
|
+
private rateLimiter;
|
|
235
|
+
constructor(initialVariables?: Record<string, unknown>, rateLimiter?: RateLimiter);
|
|
236
|
+
execute(test: TestDefinition, client: MCPClientInterface): Promise<TestResult>;
|
|
237
|
+
private executeWithTimeout;
|
|
238
|
+
private executeInternal;
|
|
239
|
+
private buildResponse;
|
|
240
|
+
private runAssertion;
|
|
241
|
+
private runSimpleExpectation;
|
|
242
|
+
getVariables(): Record<string, unknown>;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
interface SchedulerOptions {
|
|
246
|
+
parallelism: number;
|
|
247
|
+
tags?: string[];
|
|
248
|
+
reporter?: TestRunReporter;
|
|
249
|
+
rateLimiter?: RateLimiter;
|
|
250
|
+
initialVariables?: Record<string, unknown>;
|
|
251
|
+
}
|
|
252
|
+
declare class TestScheduler {
|
|
253
|
+
schedule(tests: TestDefinition[], client: MCPClientInterface, options: SchedulerOptions): Promise<TestResult[]>;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
declare class ConsoleReporter implements TestRunReporter {
|
|
257
|
+
private ci;
|
|
258
|
+
constructor(options?: {
|
|
259
|
+
ci?: boolean;
|
|
260
|
+
});
|
|
261
|
+
onRunStart(collectionName: string, testCount: number): void;
|
|
262
|
+
onTestStart(_testName: string): void;
|
|
263
|
+
onTestComplete(result: TestResult): void;
|
|
264
|
+
onRunComplete(result: TestRunResult): void;
|
|
265
|
+
private getIcon;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
declare class JsonReporter implements TestRunReporter {
|
|
269
|
+
private readonly outputPath?;
|
|
270
|
+
private output;
|
|
271
|
+
constructor(outputPath?: string | undefined);
|
|
272
|
+
onRunStart(_collectionName: string, _testCount: number): void;
|
|
273
|
+
onTestStart(_testName: string): void;
|
|
274
|
+
onTestComplete(_result: TestResult): void;
|
|
275
|
+
onRunComplete(result: TestRunResult): void;
|
|
276
|
+
getOutput(): string | undefined;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
declare class JunitReporter implements TestRunReporter {
|
|
280
|
+
private readonly outputPath?;
|
|
281
|
+
private output;
|
|
282
|
+
private secretMasker;
|
|
283
|
+
constructor(outputPath?: string | undefined);
|
|
284
|
+
setSecretMasker(masker: SecretMasker): void;
|
|
285
|
+
onRunStart(_collectionName: string, _testCount: number): void;
|
|
286
|
+
onTestStart(_testName: string): void;
|
|
287
|
+
onTestComplete(_result: TestResult): void;
|
|
288
|
+
onRunComplete(result: TestRunResult): void;
|
|
289
|
+
getOutput(): string | undefined;
|
|
290
|
+
private mask;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
declare class HtmlReporter implements TestRunReporter {
|
|
294
|
+
private readonly outputPath?;
|
|
295
|
+
private output;
|
|
296
|
+
private secretMasker;
|
|
297
|
+
constructor(outputPath?: string | undefined);
|
|
298
|
+
setSecretMasker(masker: SecretMasker): void;
|
|
299
|
+
onRunStart(_collectionName: string, _testCount: number): void;
|
|
300
|
+
onTestStart(_testName: string): void;
|
|
301
|
+
onTestComplete(_result: TestResult): void;
|
|
302
|
+
onRunComplete(result: TestRunResult): void;
|
|
303
|
+
getOutput(): string | undefined;
|
|
304
|
+
private mask;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
declare class TapReporter implements TestRunReporter {
|
|
308
|
+
private testIndex;
|
|
309
|
+
private secretMasker;
|
|
310
|
+
setSecretMasker(masker: SecretMasker): void;
|
|
311
|
+
onRunStart(_collectionName: string, testCount: number): void;
|
|
312
|
+
onTestStart(_testName: string): void;
|
|
313
|
+
onTestComplete(result: TestResult): void;
|
|
314
|
+
onRunComplete(_result: TestRunResult): void;
|
|
315
|
+
private mask;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
declare class BaselineStore {
|
|
319
|
+
private basePath;
|
|
320
|
+
constructor(basePath?: string);
|
|
321
|
+
save(name: string, result: TestRunResult): string;
|
|
322
|
+
load(name: string): TestRunResult | null;
|
|
323
|
+
list(): string[];
|
|
324
|
+
private getFilePath;
|
|
325
|
+
private ensureDir;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
interface TestDiff {
|
|
329
|
+
testName: string;
|
|
330
|
+
type: 'regression' | 'fix' | 'new' | 'removed' | 'unchanged';
|
|
331
|
+
before?: TestResult;
|
|
332
|
+
after?: TestResult;
|
|
333
|
+
}
|
|
334
|
+
interface RunDiff {
|
|
335
|
+
baselineName: string;
|
|
336
|
+
currentRunId: string;
|
|
337
|
+
regressions: TestDiff[];
|
|
338
|
+
fixes: TestDiff[];
|
|
339
|
+
newTests: TestDiff[];
|
|
340
|
+
removedTests: TestDiff[];
|
|
341
|
+
unchanged: TestDiff[];
|
|
342
|
+
summary: {
|
|
343
|
+
totalBefore: number;
|
|
344
|
+
totalAfter: number;
|
|
345
|
+
regressions: number;
|
|
346
|
+
fixes: number;
|
|
347
|
+
newTests: number;
|
|
348
|
+
removedTests: number;
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
declare class ResultDiffer {
|
|
352
|
+
diff(baseline: TestRunResult, current: TestRunResult, baselineName?: string): RunDiff;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
declare class ScanConfig {
|
|
356
|
+
readonly mode: SecurityScanMode;
|
|
357
|
+
readonly rules: string[];
|
|
358
|
+
readonly severityThreshold: SeverityLevel;
|
|
359
|
+
readonly acknowledgeRisk: boolean;
|
|
360
|
+
readonly timeout: number;
|
|
361
|
+
readonly maxProbesPerTool: number;
|
|
362
|
+
constructor(config?: Partial<SecurityScanConfig>);
|
|
363
|
+
requiresConfirmation(): boolean;
|
|
364
|
+
meetsThreshold(severity: SeverityLevel): boolean;
|
|
365
|
+
private getRulesForMode;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
interface SecurityRule {
|
|
369
|
+
readonly id: string;
|
|
370
|
+
readonly name: string;
|
|
371
|
+
readonly description: string;
|
|
372
|
+
scan(client: MCPClientInterface, tools: ToolInfo[], config: ScanConfig): Promise<SecurityFinding[]>;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
interface ScanProgress {
|
|
376
|
+
onRuleStart?: (ruleId: string, ruleName: string) => void;
|
|
377
|
+
onRuleComplete?: (ruleId: string, findingCount: number) => void;
|
|
378
|
+
onFinding?: (finding: SecurityFinding) => void;
|
|
379
|
+
}
|
|
380
|
+
declare class SecurityScanner {
|
|
381
|
+
private readonly rules;
|
|
382
|
+
constructor();
|
|
383
|
+
registerRule(rule: SecurityRule): void;
|
|
384
|
+
scan(client: MCPClientInterface, config: ScanConfig, progress?: ScanProgress): Promise<SecurityScanResult>;
|
|
385
|
+
private buildSummary;
|
|
386
|
+
private registerBuiltinRules;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
declare class PathTraversalRule implements SecurityRule {
|
|
390
|
+
readonly id = "path-traversal";
|
|
391
|
+
readonly name = "Path Traversal";
|
|
392
|
+
readonly description = "Tests for directory traversal vulnerabilities in path-based parameters";
|
|
393
|
+
scan(client: MCPClientInterface, tools: ToolInfo[], config: ScanConfig): Promise<SecurityFinding[]>;
|
|
394
|
+
private findPathParams;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
declare class InputValidationRule implements SecurityRule {
|
|
398
|
+
readonly id = "input-validation";
|
|
399
|
+
readonly name = "Input Validation";
|
|
400
|
+
readonly description = "Tests for missing or inadequate input validation";
|
|
401
|
+
scan(client: MCPClientInterface, tools: ToolInfo[], config: ScanConfig): Promise<SecurityFinding[]>;
|
|
402
|
+
private getRequiredFields;
|
|
403
|
+
private getProperties;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
declare class ResourceExhaustionRule implements SecurityRule {
|
|
407
|
+
readonly id = "resource-exhaustion";
|
|
408
|
+
readonly name = "Resource Exhaustion";
|
|
409
|
+
readonly description = "Tests for resource exhaustion vulnerabilities (DoS potential)";
|
|
410
|
+
scan(client: MCPClientInterface, tools: ToolInfo[], config: ScanConfig): Promise<SecurityFinding[]>;
|
|
411
|
+
private getStringParams;
|
|
412
|
+
private createDeepObject;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
declare class AuthBypassRule implements SecurityRule {
|
|
416
|
+
readonly id = "auth-bypass";
|
|
417
|
+
readonly name = "Auth Bypass";
|
|
418
|
+
readonly description = "Tests for unrestricted access to administrative or privileged tools";
|
|
419
|
+
scan(client: MCPClientInterface, tools: ToolInfo[], config: ScanConfig): Promise<SecurityFinding[]>;
|
|
420
|
+
private getRequiredFields;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
declare class InjectionRule implements SecurityRule {
|
|
424
|
+
readonly id = "injection";
|
|
425
|
+
readonly name = "Injection";
|
|
426
|
+
readonly description = "Tests for SQL injection, command injection, and template injection vulnerabilities";
|
|
427
|
+
scan(client: MCPClientInterface, tools: ToolInfo[], config: ScanConfig): Promise<SecurityFinding[]>;
|
|
428
|
+
private getStringParams;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
declare class InformationDisclosureRule implements SecurityRule {
|
|
432
|
+
readonly id = "information-disclosure";
|
|
433
|
+
readonly name = "Information Disclosure";
|
|
434
|
+
readonly description = "Tests for unintended information disclosure in error messages and responses";
|
|
435
|
+
scan(client: MCPClientInterface, tools: ToolInfo[], config: ScanConfig): Promise<SecurityFinding[]>;
|
|
436
|
+
private getFirstParam;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
interface PayloadSet {
|
|
440
|
+
category: string;
|
|
441
|
+
label: string;
|
|
442
|
+
value: unknown;
|
|
443
|
+
description: string;
|
|
444
|
+
}
|
|
445
|
+
declare function getSafePayloads(): PayloadSet[];
|
|
446
|
+
|
|
447
|
+
interface PlatformPayload {
|
|
448
|
+
category: string;
|
|
449
|
+
label: string;
|
|
450
|
+
value: string;
|
|
451
|
+
description: string;
|
|
452
|
+
minMode: SecurityScanMode;
|
|
453
|
+
platforms: NodeJS.Platform[];
|
|
454
|
+
}
|
|
455
|
+
declare function getPlatformPayloads(): PlatformPayload[];
|
|
456
|
+
declare function getPayloadsForMode(mode: SecurityScanMode): PlatformPayload[];
|
|
457
|
+
|
|
458
|
+
declare function computeStats(sortedDurations: number[]): BenchmarkStats;
|
|
459
|
+
declare class Profiler {
|
|
460
|
+
private entries;
|
|
461
|
+
profileCall(client: MCPClientInterface, toolName: string, args: Record<string, unknown>): Promise<ProfileEntry>;
|
|
462
|
+
getEntries(): ProfileEntry[];
|
|
463
|
+
getStats(toolName?: string): BenchmarkStats;
|
|
464
|
+
clear(): void;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
interface BenchmarkProgress {
|
|
468
|
+
onWarmupStart?: (iterations: number) => void;
|
|
469
|
+
onIterationComplete?: (iteration: number, total: number, durationMs: number) => void;
|
|
470
|
+
onComplete?: (result: BenchmarkResult) => void;
|
|
471
|
+
}
|
|
472
|
+
declare class BenchmarkRunner {
|
|
473
|
+
run(client: MCPClientInterface, toolName: string, args: Record<string, unknown>, config?: Partial<BenchmarkConfig>, progress?: BenchmarkProgress): Promise<BenchmarkResult>;
|
|
474
|
+
private runSingleIteration;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
declare class WaterfallGenerator {
|
|
478
|
+
generate(entries: ProfileEntry[]): WaterfallEntry[];
|
|
479
|
+
toAscii(entries: WaterfallEntry[], width?: number): string;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
interface ServerDocData {
|
|
483
|
+
serverName: string;
|
|
484
|
+
serverVersion?: string;
|
|
485
|
+
tools: ToolInfo[];
|
|
486
|
+
resources: ResourceInfo[];
|
|
487
|
+
generatedAt: Date;
|
|
488
|
+
}
|
|
489
|
+
declare class MarkdownGenerator {
|
|
490
|
+
generate(data: ServerDocData): string;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
interface DocGeneratorOptions {
|
|
494
|
+
format: 'markdown' | 'html';
|
|
495
|
+
outputDir?: string;
|
|
496
|
+
}
|
|
497
|
+
declare class DocGenerator {
|
|
498
|
+
introspect(client: MCPClientInterface): Promise<ServerDocData>;
|
|
499
|
+
generate(client: MCPClientInterface, options: DocGeneratorOptions): Promise<string>;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
declare class HtmlDocGenerator {
|
|
503
|
+
private template;
|
|
504
|
+
constructor();
|
|
505
|
+
generate(data: ServerDocData): string;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
interface ScoreProgress {
|
|
509
|
+
onCategoryStart?: (category: string) => void;
|
|
510
|
+
onCategoryComplete?: (category: string, score: number) => void;
|
|
511
|
+
}
|
|
512
|
+
declare class MCPScoreCalculator {
|
|
513
|
+
calculate(client: MCPClientInterface, progress?: ScoreProgress): Promise<MCPScore>;
|
|
514
|
+
private scoreDocumentation;
|
|
515
|
+
private scoreSchemaQuality;
|
|
516
|
+
private scoreErrorHandling;
|
|
517
|
+
private scorePerformance;
|
|
518
|
+
private scoreSecurity;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
declare class BadgeGenerator {
|
|
522
|
+
generate(score: MCPScore): string;
|
|
523
|
+
getColor(score: number): string;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
export { AuthBypassRule, BadgeGenerator, BaselineStore, type BenchmarkProgress, BenchmarkRunner, ConnectionManager, ConsoleReporter, DocGenerator, type DocGeneratorOptions, ERROR_CODE_MAP, ERROR_TEMPLATES, type ErrorCode, HtmlDocGenerator, HtmlReporter, InformationDisclosureRule, InjectionRule, InputValidationRule, JsonReporter, JunitReporter, LoggingTransport, MCPClient, type MCPClientInterface, MCPScoreCalculator, MCPSpecError, MarkdownGenerator, NotImplementedError, type OnProtocolMessage, PathTraversalRule, type PayloadSet, type PlatformPayload, ProcessManagerImpl, ProcessRegistry, Profiler, RateLimiter, ResourceExhaustionRule, ResultDiffer, type RunDiff, ScanConfig, type ScanProgress, type ScoreProgress, SecretMasker, type SecurityRule, SecurityScanner, type ServerDocData, TapReporter, type TestDiff, TestExecutor, type TestRunReporter, TestRunner, TestScheduler, WaterfallGenerator, YAML_LIMITS, computeStats, formatError, getPayloadsForMode, getPlatformInfo, getPlatformPayloads, getSafePayloads, loadYamlSafely, queryJsonPath, registerCleanupHandlers, resolveVariables };
|