@rekog/mcp-nest 1.5.0 → 1.5.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/.github/workflows/pipeline.yml +11 -1
- package/README.md +28 -42
- package/coverage/clover.xml +324 -325
- package/coverage/coverage-final.json +20 -20
- package/coverage/lcov-report/decorators/constants.ts.html +4 -4
- package/coverage/lcov-report/decorators/index.html +1 -1
- package/coverage/lcov-report/decorators/index.ts.html +5 -5
- package/coverage/lcov-report/decorators/prompt.decorator.ts.html +4 -4
- package/coverage/lcov-report/decorators/resource.decorator.ts.html +4 -4
- package/coverage/lcov-report/decorators/tool.decorator.ts.html +5 -5
- package/coverage/lcov-report/index.html +37 -37
- package/coverage/lcov-report/services/index.html +9 -39
- package/coverage/lcov-report/services/mcp-registry.service.ts.html +6 -6
- package/coverage/lcov-report/tests/index.html +21 -21
- package/coverage/lcov-report/tests/utils.ts.html +45 -45
- package/coverage/lcov.info +446 -449
- package/dist/interfaces/mcp-tool.interface.d.ts +7 -1
- package/dist/interfaces/mcp-tool.interface.d.ts.map +1 -1
- package/dist/services/handlers/mcp-handler.base.d.ts +3 -5
- package/dist/services/handlers/mcp-handler.base.d.ts.map +1 -1
- package/dist/services/handlers/mcp-handler.base.js +6 -2
- package/dist/services/handlers/mcp-handler.base.js.map +1 -1
- package/dist/transport/streamable-http.controller.factory.js +2 -2
- package/dist/transport/streamable-http.controller.factory.js.map +1 -1
- package/package.json +5 -3
- package/playground/resources/greeting.tool.ts +4 -3
- package/tests/mcp-tool.e2e.spec.ts +74 -10
- package/tsconfig.build.tsbuildinfo +1 -1
- package/coverage/lcov-report/services/handlers/index.html +0 -161
- package/coverage/lcov-report/services/handlers/mcp-handler.base.ts.html +0 -421
- package/coverage/lcov-report/services/handlers/mcp-prompts.handler.ts.html +0 -385
- package/coverage/lcov-report/services/handlers/mcp-resources.handler.ts.html +0 -361
- package/coverage/lcov-report/services/handlers/mcp-tools.handler.ts.html +0 -355
- package/coverage/lcov-report/services/mcp-executor.service.ts.html +0 -199
- package/coverage/lcov-report/services/sse-ping.service.ts.html +0 -499
- package/coverage/lcov-report/transport/index.html +0 -131
- package/coverage/lcov-report/transport/sse.controller.factory.ts.html +0 -532
- package/coverage/lcov-report/transport/streamable-http.controller.factory.ts.html +0 -1258
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { Progress } from '@modelcontextprotocol/sdk/types.js';
|
|
1
|
+
import { CallToolRequestSchema, GetPromptRequestSchema, Progress, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
4
|
export type Literal = boolean | null | number | string | undefined;
|
|
3
5
|
export type SerializableValue = Literal | SerializableValue[] | {
|
|
4
6
|
[key: string]: SerializableValue;
|
|
5
7
|
};
|
|
8
|
+
export type McpRequestSchema = typeof CallToolRequestSchema | typeof ReadResourceRequestSchema | typeof GetPromptRequestSchema;
|
|
9
|
+
export type McpRequest = z.infer<McpRequestSchema>;
|
|
6
10
|
export type Context = {
|
|
7
11
|
reportProgress: (progress: Progress) => Promise<void>;
|
|
8
12
|
log: {
|
|
@@ -11,5 +15,7 @@ export type Context = {
|
|
|
11
15
|
info: (message: string, data?: SerializableValue) => void;
|
|
12
16
|
warn: (message: string, data?: SerializableValue) => void;
|
|
13
17
|
};
|
|
18
|
+
mcpServer: McpServer;
|
|
19
|
+
mcpRequest: McpRequest;
|
|
14
20
|
};
|
|
15
21
|
//# sourceMappingURL=mcp-tool.interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-tool.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/mcp-tool.interface.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"mcp-tool.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/mcp-tool.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,QAAQ,EACR,yBAAyB,EAC1B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAEnE,MAAM,MAAM,iBAAiB,GACzB,OAAO,GACP,iBAAiB,EAAE,GACnB;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,gBAAgB,GACxB,OAAO,qBAAqB,GAC5B,OAAO,yBAAyB,GAChC,OAAO,sBAAsB,CAAC;AAElC,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;AAKnD,MAAM,MAAM,OAAO,GAAG;IACpB,cAAc,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,GAAG,EAAE;QACH,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;QAC3D,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;QAC3D,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;QAC1D,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;KAC3D,CAAC;IACF,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC"}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { Logger } from '@nestjs/common';
|
|
2
2
|
import { ModuleRef } from '@nestjs/core';
|
|
3
3
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
|
-
import {
|
|
5
|
-
import { CallToolRequestSchema, GetPromptRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
-
import { Context } from '../../interfaces/mcp-tool.interface';
|
|
4
|
+
import { Context, McpRequest } from '../../interfaces';
|
|
7
5
|
import { McpRegistryService } from '../mcp-registry.service';
|
|
8
6
|
export declare abstract class McpHandlerBase {
|
|
9
7
|
protected readonly moduleRef: ModuleRef;
|
|
10
8
|
protected readonly registry: McpRegistryService;
|
|
11
9
|
protected logger: Logger;
|
|
12
10
|
constructor(moduleRef: ModuleRef, registry: McpRegistryService, loggerContext: string);
|
|
13
|
-
protected createContext(mcpServer: McpServer, mcpRequest:
|
|
14
|
-
protected createStatelessContext(): Context;
|
|
11
|
+
protected createContext(mcpServer: McpServer, mcpRequest: McpRequest): Context;
|
|
12
|
+
protected createStatelessContext(mcpServer: McpServer, mcpRequest: McpRequest): Context;
|
|
15
13
|
}
|
|
16
14
|
//# sourceMappingURL=mcp-handler.base.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-handler.base.d.ts","sourceRoot":"","sources":["../../../src/services/handlers/mcp-handler.base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-handler.base.d.ts","sourceRoot":"","sources":["../../../src/services/handlers/mcp-handler.base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAqB,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,8BAAsB,cAAc;IAIhC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS;IACvC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB;IAJjD,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;gBAGJ,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,kBAAkB,EAC/C,aAAa,EAAE,MAAM;IAKvB,SAAS,CAAC,aAAa,CACrB,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,GACrB,OAAO;IAkDV,SAAS,CAAC,sBAAsB,CAC9B,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,GACrB,OAAO;CA+BX"}
|
|
@@ -10,7 +10,7 @@ class McpHandlerBase {
|
|
|
10
10
|
}
|
|
11
11
|
createContext(mcpServer, mcpRequest) {
|
|
12
12
|
if (mcpServer.server.transport.sessionId === undefined) {
|
|
13
|
-
return this.createStatelessContext();
|
|
13
|
+
return this.createStatelessContext(mcpServer, mcpRequest);
|
|
14
14
|
}
|
|
15
15
|
const progressToken = mcpRequest.params?._meta?.progressToken;
|
|
16
16
|
return {
|
|
@@ -51,9 +51,11 @@ class McpHandlerBase {
|
|
|
51
51
|
});
|
|
52
52
|
},
|
|
53
53
|
},
|
|
54
|
+
mcpServer,
|
|
55
|
+
mcpRequest,
|
|
54
56
|
};
|
|
55
57
|
}
|
|
56
|
-
createStatelessContext() {
|
|
58
|
+
createStatelessContext(mcpServer, mcpRequest) {
|
|
57
59
|
const warn = (fn) => {
|
|
58
60
|
this.logger.warn(`Stateless context: '${fn}' is not supported.`);
|
|
59
61
|
};
|
|
@@ -75,6 +77,8 @@ class McpHandlerBase {
|
|
|
75
77
|
warn('server report logging not supported in stateless');
|
|
76
78
|
},
|
|
77
79
|
},
|
|
80
|
+
mcpServer,
|
|
81
|
+
mcpRequest,
|
|
78
82
|
};
|
|
79
83
|
}
|
|
80
84
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-handler.base.js","sourceRoot":"","sources":["../../../src/services/handlers/mcp-handler.base.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;
|
|
1
|
+
{"version":3,"file":"mcp-handler.base.js","sourceRoot":"","sources":["../../../src/services/handlers/mcp-handler.base.ts"],"names":[],"mappings":"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"}
|
|
@@ -47,7 +47,7 @@ function createStreamableHttpController(endpoint, globalApiPrefix, guards = [],
|
|
|
47
47
|
async initializeStatelessMode() {
|
|
48
48
|
this.logger.log('Initializing MCP Streamable HTTP in stateless mode');
|
|
49
49
|
this.statelessTransport = new streamableHttp_js_1.StreamableHTTPServerTransport({
|
|
50
|
-
sessionIdGenerator:
|
|
50
|
+
sessionIdGenerator: undefined,
|
|
51
51
|
enableJsonResponse: this.options.streamableHttp?.enableJsonResponse || false,
|
|
52
52
|
});
|
|
53
53
|
this.statelessTransport._initialized = true;
|
|
@@ -243,7 +243,7 @@ function createStreamableHttpController(endpoint, globalApiPrefix, guards = [],
|
|
|
243
243
|
}
|
|
244
244
|
};
|
|
245
245
|
__decorate([
|
|
246
|
-
(0, common_1.Post)(endpoint),
|
|
246
|
+
(0, common_1.Post)(`${globalApiPrefix}/${endpoint}`.replace(/\/+/g, '/')),
|
|
247
247
|
(0, common_1.UseGuards)(...guards),
|
|
248
248
|
__param(0, (0, common_1.Req)()),
|
|
249
249
|
__param(1, (0, common_1.Res)()),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streamable-http.controller.factory.js","sourceRoot":"","sources":["../../src/transport/streamable-http.controller.factory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AA8BA,wEAwWC;AAtYD,2CAewB;AACxB,uCAA2D;AAC3D,mCAAoC;AAGpC,oEAAoE;AACpE,0FAAmG;AAEnG,2EAAsE;AACtE,2EAAsE;AAMtE,SAAgB,8BAA8B,CAC5C,QAAgB,EAChB,eAAuB,EACvB,SAA8B,EAAE,EAChC,aAA+B,EAAE;;IAEjC,IAEM,wBAAwB,gCAF9B,MAEM,wBAAwB;QAW5B,YACyB,OAAmC,EAC1C,SAAoB,EACpB,YAAgC;YAFT,YAAO,GAAP,OAAO,CAAY;YAC1C,cAAS,GAAT,SAAS,CAAW;YACpB,iBAAY,GAAZ,YAAY,CAAoB;YAblC,WAAM,GAAG,IAAI,eAAM,CAAC,0BAAwB,CAAC,IAAI,CAAC,CAAC;YAC5D,eAAU,GACf,EAAE,CAAC;YACE,eAAU,GAAuC,EAAE,CAAC;YAGpD,uBAAkB,GAAyC,IAAI,CAAC;YAChE,uBAAkB,GAAqB,IAAI,CAAC;YAC5C,oBAAe,GAAY,KAAK,CAAC;YAQtC,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,aAAa,CAAC;YAG/D,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACzB,IAAI,CAAC,uBAAuB,EAAE;qBAC3B,IAAI,CAAC,GAAG,EAAE;oBACT,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;gBAClD,CAAC,CAAC;qBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;gBACjE,CAAC,CAAC,CAAC;YACP,CAAC;QACH,CAAC;QAKM,KAAK,CAAC,uBAAuB;YAClC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;YAGtE,IAAI,CAAC,kBAAkB,GAAG,IAAI,iDAA6B,CAAC;gBAE1D,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"streamable-http.controller.factory.js","sourceRoot":"","sources":["../../src/transport/streamable-http.controller.factory.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rekog/mcp-nest",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "NestJS module for creating Model Context Protocol (MCP) servers",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,12 +26,14 @@
|
|
|
26
26
|
"@nestjs/common": ">=9.0.0",
|
|
27
27
|
"@nestjs/core": ">=9.0.0",
|
|
28
28
|
"express": ">=4.0.0",
|
|
29
|
-
"reflect-metadata": ">=0.1.14"
|
|
29
|
+
"reflect-metadata": ">=0.1.14",
|
|
30
|
+
"zod": ">=3.0.0",
|
|
31
|
+
"zod-to-json-schema": ">=3.23.0"
|
|
30
32
|
},
|
|
31
33
|
"devDependencies": {
|
|
32
34
|
"@eslint/eslintrc": "^3.2.0",
|
|
33
35
|
"@eslint/js": "^9.18.0",
|
|
34
|
-
"@modelcontextprotocol/sdk": "^1.10.
|
|
36
|
+
"@modelcontextprotocol/sdk": "^1.10.2",
|
|
35
37
|
"@nestjs/common": "^11.0.5",
|
|
36
38
|
"@nestjs/core": "^11.0.5",
|
|
37
39
|
"@nestjs/platform-express": "^11.0.5",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Request } from 'express';
|
|
1
2
|
import { Injectable } from '@nestjs/common';
|
|
2
3
|
import { Context, Tool } from '../../src';
|
|
3
4
|
import { Progress } from '@modelcontextprotocol/sdk/types.js';
|
|
@@ -13,9 +14,9 @@ export class GreetingTool {
|
|
|
13
14
|
name: z.string().default('World'),
|
|
14
15
|
}),
|
|
15
16
|
})
|
|
16
|
-
async sayHello({ name }, context: Context) {
|
|
17
|
-
const
|
|
18
|
-
|
|
17
|
+
async sayHello({ name }, context: Context, request: Request) {
|
|
18
|
+
const userAgent = request.get('user-agent') || 'Unknown';
|
|
19
|
+
const greeting = `Hello, ${name}! Your user agent is: ${userAgent}`;
|
|
19
20
|
const totalSteps = 5;
|
|
20
21
|
for (let i = 0; i < totalSteps; i++) {
|
|
21
22
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -43,6 +43,14 @@ export class GreetingTool {
|
|
|
43
43
|
}),
|
|
44
44
|
})
|
|
45
45
|
async sayHello({ name }, context: Context) {
|
|
46
|
+
// Validate that mcpServer and mcpRequest properties exist
|
|
47
|
+
if (!context.mcpServer) {
|
|
48
|
+
throw new Error('mcpServer is not defined in the context');
|
|
49
|
+
}
|
|
50
|
+
if (!context.mcpRequest) {
|
|
51
|
+
throw new Error('mcpRequest is not defined in the context');
|
|
52
|
+
}
|
|
53
|
+
|
|
46
54
|
const user = await this.userRepository.findByName(name);
|
|
47
55
|
for (let i = 0; i < 5; i++) {
|
|
48
56
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
@@ -125,9 +133,15 @@ export class ToolRequestScoped {
|
|
|
125
133
|
|
|
126
134
|
describe('E2E: MCP ToolServer', () => {
|
|
127
135
|
let app: INestApplication;
|
|
128
|
-
let
|
|
136
|
+
let statelessApp: INestApplication;
|
|
137
|
+
let statefulServerPort: number;
|
|
138
|
+
let statelessServerPort: number;
|
|
139
|
+
|
|
140
|
+
// Set timeout for all tests in this describe block to 15000ms
|
|
141
|
+
jest.setTimeout(15000);
|
|
129
142
|
|
|
130
143
|
beforeAll(async () => {
|
|
144
|
+
// Create stateful server (original)
|
|
131
145
|
const moduleFixture: TestingModule = await Test.createTestingModule({
|
|
132
146
|
imports: [
|
|
133
147
|
McpModule.forRoot({
|
|
@@ -156,21 +170,63 @@ describe('E2E: MCP ToolServer', () => {
|
|
|
156
170
|
if (!server.address()) {
|
|
157
171
|
throw new Error('Server address not found after listen');
|
|
158
172
|
}
|
|
159
|
-
|
|
173
|
+
statefulServerPort = (server.address() as import('net').AddressInfo).port;
|
|
174
|
+
|
|
175
|
+
// Create stateless server
|
|
176
|
+
const statelessModuleFixture: TestingModule =
|
|
177
|
+
await Test.createTestingModule({
|
|
178
|
+
imports: [
|
|
179
|
+
McpModule.forRoot({
|
|
180
|
+
name: 'test-stateless-mcp-server',
|
|
181
|
+
version: '0.0.1',
|
|
182
|
+
guards: [],
|
|
183
|
+
transport: McpTransportType.STREAMABLE_HTTP,
|
|
184
|
+
streamableHttp: {
|
|
185
|
+
enableJsonResponse: true,
|
|
186
|
+
sessionIdGenerator: undefined,
|
|
187
|
+
statelessMode: true,
|
|
188
|
+
},
|
|
189
|
+
}),
|
|
190
|
+
],
|
|
191
|
+
providers: [
|
|
192
|
+
GreetingTool,
|
|
193
|
+
GreetingToolRequestScoped,
|
|
194
|
+
MockUserRepository,
|
|
195
|
+
ToolRequestScoped,
|
|
196
|
+
],
|
|
197
|
+
}).compile();
|
|
198
|
+
|
|
199
|
+
statelessApp = statelessModuleFixture.createNestApplication();
|
|
200
|
+
await statelessApp.listen(0);
|
|
201
|
+
|
|
202
|
+
const statelessServer = statelessApp.getHttpServer();
|
|
203
|
+
if (!statelessServer.address()) {
|
|
204
|
+
throw new Error('Stateless server address not found after listen');
|
|
205
|
+
}
|
|
206
|
+
statelessServerPort = (
|
|
207
|
+
statelessServer.address() as import('net').AddressInfo
|
|
208
|
+
).port;
|
|
160
209
|
});
|
|
161
210
|
|
|
162
211
|
afterAll(async () => {
|
|
163
212
|
await app.close();
|
|
213
|
+
await statelessApp.close();
|
|
164
214
|
});
|
|
165
215
|
|
|
166
216
|
const runClientTests = (
|
|
167
217
|
clientType: 'http+sse' | 'streamable http' | 'stdio',
|
|
168
218
|
clientCreator: (port: number, options?: any) => Promise<Client>,
|
|
169
219
|
requestScopedHeaderValue: string,
|
|
220
|
+
stateless = false,
|
|
170
221
|
) => {
|
|
171
222
|
describe(`using ${clientType} client (${clientCreator.name})`, () => {
|
|
223
|
+
let port: number;
|
|
224
|
+
|
|
225
|
+
beforeAll(async () => {
|
|
226
|
+
port = stateless ? statelessServerPort : statefulServerPort;
|
|
227
|
+
});
|
|
172
228
|
it('should list tools', async () => {
|
|
173
|
-
const client = await clientCreator(
|
|
229
|
+
const client = await clientCreator(port);
|
|
174
230
|
try {
|
|
175
231
|
const tools = await client.listTools();
|
|
176
232
|
expect(tools.tools.length).toBeGreaterThan(0);
|
|
@@ -191,7 +247,7 @@ describe('E2E: MCP ToolServer', () => {
|
|
|
191
247
|
it.each([{ tool: 'hello-world' }, { tool: 'hello-world-scoped' }])(
|
|
192
248
|
'should call the tool $tool and receive results',
|
|
193
249
|
async ({ tool }) => {
|
|
194
|
-
const client = await clientCreator(
|
|
250
|
+
const client = await clientCreator(port);
|
|
195
251
|
try {
|
|
196
252
|
let progressCount = 1;
|
|
197
253
|
const result: any = await client.callTool(
|
|
@@ -206,7 +262,7 @@ describe('E2E: MCP ToolServer', () => {
|
|
|
206
262
|
},
|
|
207
263
|
);
|
|
208
264
|
|
|
209
|
-
if (clientType != 'stdio') {
|
|
265
|
+
if (clientType != 'stdio' && !stateless) {
|
|
210
266
|
// stdio has no support for progress
|
|
211
267
|
expect(progressCount).toBe(5);
|
|
212
268
|
}
|
|
@@ -221,7 +277,7 @@ describe('E2E: MCP ToolServer', () => {
|
|
|
221
277
|
);
|
|
222
278
|
|
|
223
279
|
it('should call the tool get-request-scoped and receive header', async () => {
|
|
224
|
-
const client = await clientCreator(
|
|
280
|
+
const client = await clientCreator(port, {
|
|
225
281
|
requestInit: {
|
|
226
282
|
headers: { 'any-header': requestScopedHeaderValue },
|
|
227
283
|
},
|
|
@@ -240,7 +296,7 @@ describe('E2E: MCP ToolServer', () => {
|
|
|
240
296
|
});
|
|
241
297
|
|
|
242
298
|
it('should reject invalid arguments for hello-world', async () => {
|
|
243
|
-
const client = await clientCreator(
|
|
299
|
+
const client = await clientCreator(port);
|
|
244
300
|
|
|
245
301
|
try {
|
|
246
302
|
await client.callTool({
|
|
@@ -256,7 +312,7 @@ describe('E2E: MCP ToolServer', () => {
|
|
|
256
312
|
});
|
|
257
313
|
|
|
258
314
|
it('should reject missing arguments for hello-world', async () => {
|
|
259
|
-
const client = await clientCreator(
|
|
315
|
+
const client = await clientCreator(port);
|
|
260
316
|
|
|
261
317
|
try {
|
|
262
318
|
await client.callTool({
|
|
@@ -272,7 +328,7 @@ describe('E2E: MCP ToolServer', () => {
|
|
|
272
328
|
});
|
|
273
329
|
|
|
274
330
|
it('should call the tool and receive an error', async () => {
|
|
275
|
-
const client = await clientCreator(
|
|
331
|
+
const client = await clientCreator(port);
|
|
276
332
|
try {
|
|
277
333
|
const result: any = await client.callTool({
|
|
278
334
|
name: 'hello-world-error',
|
|
@@ -294,9 +350,17 @@ describe('E2E: MCP ToolServer', () => {
|
|
|
294
350
|
// Run tests using the HTTP+SSE MCP client
|
|
295
351
|
runClientTests('http+sse', createSseClient, 'any-value');
|
|
296
352
|
|
|
297
|
-
// Run tests using the Streamable HTTP MCP client
|
|
353
|
+
// Run tests using the [Stateful] Streamable HTTP MCP client
|
|
298
354
|
runClientTests('streamable http', createStreamableClient, 'streamable-value');
|
|
299
355
|
|
|
356
|
+
// Run tests using the [Stateless] Streamable HTTP MCP client
|
|
357
|
+
runClientTests(
|
|
358
|
+
'streamable http',
|
|
359
|
+
createStreamableClient,
|
|
360
|
+
'stateless-streamable-value',
|
|
361
|
+
true,
|
|
362
|
+
);
|
|
363
|
+
|
|
300
364
|
runClientTests(
|
|
301
365
|
'stdio',
|
|
302
366
|
() =>
|