Skip to content

Commit ffc1e19

Browse files
authored
fix: update sessionIdGenerator (#320)
<!-- Thank you for your pull request. Please review below requirements. Bug fixes and new features should include tests and possibly benchmarks. Contributors guide: https://github.com/eggjs/egg/blob/master/CONTRIBUTING.md 感谢您贡献代码。请确认下列 checklist 的完成情况。 Bug 修复和新功能必须包含测试,必要时请附上性能测试。 Contributors guide: https://github.com/eggjs/egg/blob/master/CONTRIBUTING.md --> ##### Checklist <!-- Remove items that do not apply. For completed items, change [ ] to [x]. --> - [ ] `npm test` passes - [ ] tests and/or benchmarks are included - [ ] documentation is changed or added - [ ] commit message follows commit guidelines ##### Affected core subsystem(s) <!-- Provide affected core subsystem(s). --> ##### Description of change <!-- Provide a description of the change below this comment. --> <!-- - any feature? - close https://github.com/eggjs/egg/ISSUE_URL --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Refactor** - Improved flexibility of session ID generation by allowing the generator to accept the current request context. - Enhanced session handling to support context-aware session ID generation. - **New Features** - Added support for custom session IDs via request headers, enabling consistent session identification across requests. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent c8080b1 commit ffc1e19

File tree

5 files changed

+16
-6
lines changed

5 files changed

+16
-6
lines changed

plugin/controller/lib/impl/mcp/MCPConfig.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { Context } from 'egg';
12
import { randomUUID } from 'node:crypto';
23
import { EventStore } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
34
import { InMemoryEventStore } from '@modelcontextprotocol/sdk/examples/shared/inMemoryEventStore.js';
@@ -7,7 +8,7 @@ export interface MCPConfigOptions {
78
sseMessagePath: string;
89
streamPath: string;
910
statelessStreamPath: string;
10-
sessionIdGenerator?: () => string;
11+
sessionIdGenerator?: (ctx: Context) => string;
1112
eventStore?: EventStore;
1213
sseHeartTime?: number;
1314
}
@@ -17,12 +18,12 @@ export class MCPConfig {
1718
private _sseMessagePath: string;
1819
private _streamPath: string;
1920
private _statelessStreamPath: string;
20-
private _sessionIdGenerator: () => string;
21+
private _sessionIdGenerator: (ctx: Context) => string;
2122
private _eventStore: EventStore;
2223
private _sseHeartTime: number;
2324

2425
constructor(options: MCPConfigOptions) {
25-
this._sessionIdGenerator = options.sessionIdGenerator ?? randomUUID;
26+
this._sessionIdGenerator = options.sessionIdGenerator ?? (() => randomUUID());
2627
this._sseInitPath = options.sseInitPath;
2728
this._sseMessagePath = options.sseMessagePath;
2829
this._streamPath = options.streamPath;

plugin/controller/lib/impl/mcp/MCPControllerRegister.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ export class MCPControllerRegister implements ControllerRegister {
250250
const eventStore = this.mcpConfig.eventStore;
251251
const self = this;
252252
const transport = new StreamableHTTPServerTransport({
253-
sessionIdGenerator: () => this.mcpConfig.sessionIdGenerator(),
253+
sessionIdGenerator: () => this.mcpConfig.sessionIdGenerator(ctx),
254254
eventStore,
255255
onsessioninitialized: async () => {
256256
if (MCPControllerRegister.hooks.length > 0) {

plugin/controller/test/fixtures/apps/mcp-app/config/config.default.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
'use strict';
2+
// eslint-disable-next-line @typescript-eslint/no-var-requires
3+
const { randomUUID } = require('node:crypto');
24

35
module.exports = function() {
46
const config = {
@@ -8,6 +10,11 @@ module.exports = function() {
810
enable: false,
911
},
1012
},
13+
mcp: {
14+
sessionIdGenerator: ctx => {
15+
return ctx.request.headers['custom-session-id'] || randomUUID();
16+
},
17+
},
1118
};
1219
return config;
1320
};

plugin/controller/test/mcp/mcp.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,15 @@ describe('plugin/controller/test/mcp/mcp.test.ts', () => {
181181
});
182182
const baseUrl = await app.httpRequest()
183183
.post('/mcp/stream').url;
184-
const streamableTransport = new StreamableHTTPClientTransport(new URL(baseUrl));
184+
const streamableTransport = new StreamableHTTPClientTransport(new URL(baseUrl), { requestInit: { headers: { 'custom-session-id': 'custom-session-id' } } });
185185
const streamableNotifications: { level: string, data: string }[] = [];
186186
streamableClient.setNotificationHandler(LoggingMessageNotificationSchema, notification => {
187187
streamableNotifications.push({ level: notification.params.level, data: notification.params.data as string });
188188
});
189189
await streamableClient.connect(streamableTransport);
190190
// tool
191191
const tools = await listTools(streamableClient);
192+
assert.deepEqual(streamableTransport.sessionId, 'custom-session-id');
192193
assert.deepEqual(tools, [
193194
{
194195
name: 'start-notification-stream',

plugin/controller/test/mcp/mcpCluster.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,15 @@ describe('plugin/controller/test/mcp/mcpCluster.test.ts', () => {
191191
});
192192
const baseUrl = await app.httpRequest()
193193
.post('/mcp/stream').url;
194-
const streamableTransport = new StreamableHTTPClientTransport(new URL(baseUrl));
194+
const streamableTransport = new StreamableHTTPClientTransport(new URL(baseUrl), { requestInit: { headers: { 'custom-session-id': 'custom-session-id' } } });
195195
const streamableNotifications: { level: string, data: string }[] = [];
196196
streamableClient.setNotificationHandler(LoggingMessageNotificationSchema, notification => {
197197
streamableNotifications.push({ level: notification.params.level, data: notification.params.data as string });
198198
});
199199
await streamableClient.connect(streamableTransport);
200200
// tool
201201
const tools = await listTools(streamableClient);
202+
assert.deepEqual(streamableTransport.sessionId, 'custom-session-id');
202203
assert.deepEqual(tools, [
203204
{
204205
name: 'start-notification-stream',

0 commit comments

Comments
 (0)