@karashiiro/mcp 0.2.0 → 0.4.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/README.md +64 -5
- package/dist/event-store.d.ts +26 -0
- package/dist/event-store.d.ts.map +1 -1
- package/dist/event-store.js +37 -0
- package/dist/event-store.js.map +1 -1
- package/dist/http.d.ts +56 -12
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +95 -27
- package/dist/http.js.map +1 -1
- package/dist/stdio.d.ts +6 -4
- package/dist/stdio.d.ts.map +1 -1
- package/dist/stdio.js +3 -1
- package/dist/stdio.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -96,6 +96,41 @@ const handle = await serveHttp(createServer, {
|
|
|
96
96
|
|
|
97
97
|
In stateful mode, `createServer` is called once per client session, allowing each client to have isolated state.
|
|
98
98
|
|
|
99
|
+
#### Session-Aware Factories
|
|
100
|
+
|
|
101
|
+
In stateful mode, the factory function receives the session ID as a parameter, enabling session-specific initialization:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
const handle = await serveHttp(
|
|
105
|
+
(sessionId) => {
|
|
106
|
+
console.log(`Creating server for session: ${sessionId}`);
|
|
107
|
+
return createServer();
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
port: 8080,
|
|
111
|
+
sessions: {},
|
|
112
|
+
},
|
|
113
|
+
);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### Async Factories
|
|
117
|
+
|
|
118
|
+
The factory function can be async, which is useful for initialization that requires async operations:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
const handle = await serveHttp(
|
|
122
|
+
async (sessionId) => {
|
|
123
|
+
// Perform async initialization (e.g., connect to database, load config)
|
|
124
|
+
await initializeResources(sessionId);
|
|
125
|
+
return createServer();
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
port: 8080,
|
|
129
|
+
sessions: {},
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
```
|
|
133
|
+
|
|
99
134
|
#### Custom Session IDs
|
|
100
135
|
|
|
101
136
|
```ts
|
|
@@ -137,22 +172,46 @@ If you only need stdio transport, import from `@karashiiro/mcp/stdio` to avoid b
|
|
|
137
172
|
|
|
138
173
|
## API Reference
|
|
139
174
|
|
|
175
|
+
### Factory Types
|
|
176
|
+
|
|
177
|
+
The library provides two factory types for type-safe server creation:
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
// For stateless mode (serveStdio and serveHttp without sessions)
|
|
181
|
+
type StatelessServerFactory = () => McpServer | Promise<McpServer>;
|
|
182
|
+
|
|
183
|
+
// For stateful mode (serveHttp with sessions)
|
|
184
|
+
type StatefulServerFactory = (sessionId: string) => McpServer | Promise<McpServer>;
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Both factory types support async initialization by returning a `Promise<McpServer>`.
|
|
188
|
+
|
|
140
189
|
### `serveStdio(serverFactory)`
|
|
141
190
|
|
|
142
191
|
Serves an MCP server over stdin/stdout.
|
|
143
192
|
|
|
144
|
-
- `serverFactory:
|
|
193
|
+
- `serverFactory: StatelessServerFactory` - Factory function that creates a single server instance
|
|
194
|
+
- Returns: `Promise<ServerHandle>`
|
|
195
|
+
|
|
196
|
+
### `serveHttp(serverFactory, options?)` (stateless)
|
|
197
|
+
|
|
198
|
+
Serves an MCP server over HTTP in stateless mode.
|
|
199
|
+
|
|
200
|
+
- `serverFactory: StatelessServerFactory` - Factory function called once, creates a shared server
|
|
201
|
+
- `options.port` - Port to listen on (default: `8080`)
|
|
202
|
+
- `options.host` - Host to bind to (default: `"127.0.0.1"`)
|
|
203
|
+
- `options.endpoint` - MCP endpoint path (default: `"/mcp"`)
|
|
145
204
|
- Returns: `Promise<ServerHandle>`
|
|
146
205
|
|
|
147
|
-
### `serveHttp(serverFactory, options
|
|
206
|
+
### `serveHttp(serverFactory, options)` (stateful)
|
|
148
207
|
|
|
149
|
-
Serves an MCP server over HTTP.
|
|
208
|
+
Serves an MCP server over HTTP in stateful mode with per-client sessions.
|
|
150
209
|
|
|
151
|
-
- `serverFactory:
|
|
210
|
+
- `serverFactory: StatefulServerFactory` - Factory function called per session with the session ID
|
|
152
211
|
- `options.port` - Port to listen on (default: `8080`)
|
|
153
212
|
- `options.host` - Host to bind to (default: `"127.0.0.1"`)
|
|
154
213
|
- `options.endpoint` - MCP endpoint path (default: `"/mcp"`)
|
|
155
|
-
- `options.sessions` -
|
|
214
|
+
- `options.sessions` - **Required** to enable stateful mode
|
|
156
215
|
- `options.sessions.sessionIdGenerator` - Custom session ID generator function
|
|
157
216
|
- `options.sessions.legacySse` - Enable legacy SSE transport endpoints
|
|
158
217
|
- Returns: `Promise<ServerHandle>`
|
package/dist/event-store.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import type { EventStore } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
2
2
|
import type { JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Options for configuring the in-memory event store.
|
|
5
|
+
*/
|
|
6
|
+
export interface InMemoryEventStoreOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Maximum number of events to store per stream.
|
|
9
|
+
* When exceeded, oldest events are evicted (FIFO).
|
|
10
|
+
* Defaults to undefined (no limit).
|
|
11
|
+
*/
|
|
12
|
+
maxEventsPerStream?: number;
|
|
13
|
+
}
|
|
3
14
|
/**
|
|
4
15
|
* In-memory event store for SSE resumability.
|
|
5
16
|
* Stores events in memory and allows replaying them from a specific point.
|
|
@@ -7,7 +18,22 @@ import type { JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";
|
|
|
7
18
|
*/
|
|
8
19
|
export declare class InMemoryEventStore implements EventStore {
|
|
9
20
|
private events;
|
|
21
|
+
private readonly maxEventsPerStream;
|
|
22
|
+
constructor(options?: InMemoryEventStoreOptions);
|
|
10
23
|
storeEvent(streamId: string, message: JSONRPCMessage): Promise<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Evict oldest events for a stream if it exceeds maxEventsPerStream.
|
|
26
|
+
*/
|
|
27
|
+
private evictOldestIfNeeded;
|
|
28
|
+
/**
|
|
29
|
+
* Clear all events from the store.
|
|
30
|
+
* Call this when the session is being deleted.
|
|
31
|
+
*/
|
|
32
|
+
clear(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Get the current number of events stored.
|
|
35
|
+
*/
|
|
36
|
+
get size(): number;
|
|
11
37
|
replayEventsAfter(lastEventId: string, { send }: {
|
|
12
38
|
send: (eventId: string, message: JSONRPCMessage) => Promise<void>;
|
|
13
39
|
}): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-store.d.ts","sourceRoot":"","sources":["../src/event-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+DAA+D,CAAC;AAChG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,UAAU;IACnD,OAAO,CAAC,MAAM,CAGV;
|
|
1
|
+
{"version":3,"file":"event-store.d.ts","sourceRoot":"","sources":["../src/event-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+DAA+D,CAAC;AAChG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,UAAU;IACnD,OAAO,CAAC,MAAM,CAGV;IACJ,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IAExD,YAAY,OAAO,GAAE,yBAA8B,EAElD;IAEK,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAU3E;IAED;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;;OAGG;IACH,KAAK,IAAI,IAAI,CAEZ;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEK,iBAAiB,CACrB,WAAW,EAAE,MAAM,EACnB,EACE,IAAI,EACL,EAAE;QAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GACvE,OAAO,CAAC,MAAM,CAAC,CA2BjB;CACF"}
|
package/dist/event-store.js
CHANGED
|
@@ -5,11 +5,48 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export class InMemoryEventStore {
|
|
7
7
|
events = new Map();
|
|
8
|
+
maxEventsPerStream;
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.maxEventsPerStream = options.maxEventsPerStream;
|
|
11
|
+
}
|
|
8
12
|
async storeEvent(streamId, message) {
|
|
9
13
|
const eventId = `${streamId}_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
10
14
|
this.events.set(eventId, { streamId, message });
|
|
15
|
+
// Evict oldest events if limit exceeded
|
|
16
|
+
if (this.maxEventsPerStream !== undefined) {
|
|
17
|
+
this.evictOldestIfNeeded(streamId);
|
|
18
|
+
}
|
|
11
19
|
return eventId;
|
|
12
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Evict oldest events for a stream if it exceeds maxEventsPerStream.
|
|
23
|
+
*/
|
|
24
|
+
evictOldestIfNeeded(streamId) {
|
|
25
|
+
if (this.maxEventsPerStream === undefined)
|
|
26
|
+
return;
|
|
27
|
+
// Get all events for this stream, sorted by ID (contains timestamp)
|
|
28
|
+
const streamEvents = Array.from(this.events.entries())
|
|
29
|
+
.filter(([, event]) => event.streamId === streamId)
|
|
30
|
+
.sort(([a], [b]) => a.localeCompare(b));
|
|
31
|
+
// Remove oldest events until we're under the limit
|
|
32
|
+
while (streamEvents.length > this.maxEventsPerStream) {
|
|
33
|
+
const [oldestId] = streamEvents.shift();
|
|
34
|
+
this.events.delete(oldestId);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Clear all events from the store.
|
|
39
|
+
* Call this when the session is being deleted.
|
|
40
|
+
*/
|
|
41
|
+
clear() {
|
|
42
|
+
this.events.clear();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get the current number of events stored.
|
|
46
|
+
*/
|
|
47
|
+
get size() {
|
|
48
|
+
return this.events.size;
|
|
49
|
+
}
|
|
13
50
|
async replayEventsAfter(lastEventId, { send, }) {
|
|
14
51
|
const lastEvent = this.events.get(lastEventId);
|
|
15
52
|
if (!lastEvent) {
|
package/dist/event-store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-store.js","sourceRoot":"","sources":["../src/event-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"event-store.js","sourceRoot":"","sources":["../src/event-store.ts"],"names":[],"mappings":"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"}
|
package/dist/http.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export type {
|
|
1
|
+
import type { ServerHandle, StatelessServerFactory, StatefulServerFactory } from "./types.js";
|
|
2
|
+
export type { ServerHandle, StatelessServerFactory, StatefulServerFactory, } from "./types.js";
|
|
3
|
+
export type { ServerFactory } from "./types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Options for legacy SSE transport compatibility.
|
|
6
6
|
* @deprecated SSE transport is deprecated in favor of Streamable HTTP.
|
|
@@ -13,6 +13,17 @@ export interface LegacySseOptions {
|
|
|
13
13
|
}
|
|
14
14
|
export interface HttpServerSessionOptions {
|
|
15
15
|
sessionIdGenerator?: () => string;
|
|
16
|
+
/**
|
|
17
|
+
* Session time-to-live in milliseconds. Sessions without activity for this
|
|
18
|
+
* duration will be automatically cleaned up. Defaults to 30 minutes.
|
|
19
|
+
* Set to 0 or undefined to disable automatic cleanup.
|
|
20
|
+
*/
|
|
21
|
+
sessionTtlMs?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Interval in milliseconds for checking expired sessions.
|
|
24
|
+
* Defaults to 60000 (1 minute). Only used if sessionTtlMs is set.
|
|
25
|
+
*/
|
|
26
|
+
cleanupIntervalMs?: number;
|
|
16
27
|
/**
|
|
17
28
|
* Enable legacy SSE transport compatibility.
|
|
18
29
|
* When provided, adds /sse and /messages endpoints for older clients.
|
|
@@ -20,21 +31,54 @@ export interface HttpServerSessionOptions {
|
|
|
20
31
|
*/
|
|
21
32
|
legacySse?: LegacySseOptions;
|
|
22
33
|
}
|
|
23
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Base HTTP server options without session configuration.
|
|
36
|
+
*/
|
|
37
|
+
export interface HttpServerOptionsBase {
|
|
24
38
|
port: number;
|
|
25
39
|
host: string;
|
|
26
40
|
endpoint: string;
|
|
27
|
-
sessions?: HttpServerSessionOptions | undefined;
|
|
28
41
|
}
|
|
29
42
|
/**
|
|
30
|
-
*
|
|
43
|
+
* HTTP server options for stateless mode (no sessions).
|
|
44
|
+
*/
|
|
45
|
+
export interface HttpServerStatelessOptions extends HttpServerOptionsBase {
|
|
46
|
+
sessions?: undefined;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* HTTP server options for stateful mode (with sessions).
|
|
50
|
+
*/
|
|
51
|
+
export interface HttpServerStatefulOptions extends HttpServerOptionsBase {
|
|
52
|
+
sessions: HttpServerSessionOptions;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Combined HTTP server options type.
|
|
56
|
+
*/
|
|
57
|
+
export type HttpServerOptions = HttpServerStatelessOptions | HttpServerStatefulOptions;
|
|
58
|
+
/**
|
|
59
|
+
* Serve an MCP server over HTTP in stateless mode.
|
|
60
|
+
*
|
|
61
|
+
* In stateless mode, the factory is called once and all clients share the same server instance.
|
|
62
|
+
* The factory receives no parameters.
|
|
63
|
+
*
|
|
64
|
+
* @param serverFactory - Factory function that creates a single shared McpServer instance.
|
|
65
|
+
* @param options - Server configuration options (without sessions).
|
|
66
|
+
* @returns A handle to control the server lifecycle.
|
|
67
|
+
*/
|
|
68
|
+
export declare function serveHttp(serverFactory: StatelessServerFactory, options?: Partial<Omit<HttpServerOptionsBase, "sessions">> & {
|
|
69
|
+
sessions?: undefined;
|
|
70
|
+
}): Promise<ServerHandle>;
|
|
71
|
+
/**
|
|
72
|
+
* Serve an MCP server over HTTP in stateful mode with per-client sessions.
|
|
73
|
+
*
|
|
74
|
+
* In stateful mode, the factory is called once per client session, receiving the session ID.
|
|
75
|
+
* This allows each client to have isolated state.
|
|
31
76
|
*
|
|
32
|
-
* @param serverFactory - Factory function that creates McpServer instances.
|
|
33
|
-
*
|
|
34
|
-
* @param options - Server configuration options.
|
|
35
|
-
* If `sessions` is provided, runs in stateful mode with per-session servers.
|
|
36
|
-
* If `sessions` is undefined, runs in stateless mode with a single server.
|
|
77
|
+
* @param serverFactory - Factory function that creates McpServer instances per session.
|
|
78
|
+
* @param options - Server configuration options with sessions enabled.
|
|
37
79
|
* @returns A handle to control the server lifecycle.
|
|
38
80
|
*/
|
|
39
|
-
export declare function serveHttp(serverFactory:
|
|
81
|
+
export declare function serveHttp(serverFactory: StatefulServerFactory, options: Partial<HttpServerOptionsBase> & {
|
|
82
|
+
sessions: HttpServerSessionOptions;
|
|
83
|
+
}): Promise<ServerHandle>;
|
|
40
84
|
//# sourceMappingURL=http.d.ts.map
|
package/dist/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,YAAY,EACZ,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,YAAY,EACZ,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,CAAC,EAAE,MAAM,MAAM,CAAC;IAClC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA2B,SAAQ,qBAAqB;IACvE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,qBAAqB;IACtE,QAAQ,EAAE,wBAAwB,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,0BAA0B,GAC1B,yBAAyB,CAAC;AAyD9B;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACvB,aAAa,EAAE,sBAAsB,EACrC,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,CAAC,GAAG;IAC3D,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,GACA,OAAO,CAAC,YAAY,CAAC,CAAC;AAEzB;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACvB,aAAa,EAAE,qBAAqB,EACpC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG;IACxC,QAAQ,EAAE,wBAAwB,CAAC;CACpC,GACA,OAAO,CAAC,YAAY,CAAC,CAAC"}
|
package/dist/http.js
CHANGED
|
@@ -28,16 +28,7 @@ function createHandle(server) {
|
|
|
28
28
|
}),
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
* Serve an MCP server over HTTP.
|
|
33
|
-
*
|
|
34
|
-
* @param serverFactory - Factory function that creates McpServer instances.
|
|
35
|
-
* In stateless mode, called once. In stateful mode, called per session.
|
|
36
|
-
* @param options - Server configuration options.
|
|
37
|
-
* If `sessions` is provided, runs in stateful mode with per-session servers.
|
|
38
|
-
* If `sessions` is undefined, runs in stateless mode with a single server.
|
|
39
|
-
* @returns A handle to control the server lifecycle.
|
|
40
|
-
*/
|
|
31
|
+
// Implementation signature (accepts both)
|
|
41
32
|
export async function serveHttp(serverFactory, options = {}) {
|
|
42
33
|
const mergedOptions = {
|
|
43
34
|
...defaultOptions,
|
|
@@ -54,8 +45,8 @@ export async function serveHttp(serverFactory, options = {}) {
|
|
|
54
45
|
* Stateless mode: single server instance, single transport, no session tracking.
|
|
55
46
|
*/
|
|
56
47
|
async function serveHttpStateless(serverFactory, options) {
|
|
57
|
-
// Call factory ONCE to get the single server instance
|
|
58
|
-
const server = serverFactory();
|
|
48
|
+
// Call factory ONCE to get the single server instance (no sessionId in stateless mode)
|
|
49
|
+
const server = await serverFactory();
|
|
59
50
|
// Create the transport (no session ID generator = stateless)
|
|
60
51
|
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
61
52
|
sessionIdGenerator: undefined,
|
|
@@ -78,7 +69,34 @@ async function serveHttpStateless(serverFactory, options) {
|
|
|
78
69
|
*/
|
|
79
70
|
function serveHttpStateful(serverFactory, options) {
|
|
80
71
|
const sessions = new Map();
|
|
81
|
-
const sessionIdGenerator = options.sessions
|
|
72
|
+
const sessionIdGenerator = options.sessions.sessionIdGenerator ?? uuidv4;
|
|
73
|
+
// Session TTL configuration
|
|
74
|
+
const sessionTtlMs = options.sessions.sessionTtlMs;
|
|
75
|
+
const cleanupIntervalMs = options.sessions.cleanupIntervalMs ?? 60000; // Default 1 minute
|
|
76
|
+
// Set up periodic cleanup for expired sessions
|
|
77
|
+
let cleanupInterval;
|
|
78
|
+
if (sessionTtlMs && sessionTtlMs > 0) {
|
|
79
|
+
cleanupInterval = setInterval(() => {
|
|
80
|
+
const now = Date.now();
|
|
81
|
+
for (const [sessionId, session] of sessions) {
|
|
82
|
+
// Skip sessions with active streaming connections
|
|
83
|
+
if (session.activeStreams > 0) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (now - session.lastActivity > sessionTtlMs) {
|
|
87
|
+
// Session expired - close transport and remove
|
|
88
|
+
session.transport.close().catch(() => {
|
|
89
|
+
// Ignore close errors for expired sessions
|
|
90
|
+
});
|
|
91
|
+
// Clear event store if this is a streamable HTTP session
|
|
92
|
+
if (session.type === "streamable-http") {
|
|
93
|
+
session.eventStore.clear();
|
|
94
|
+
}
|
|
95
|
+
sessions.delete(sessionId);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}, cleanupIntervalMs);
|
|
99
|
+
}
|
|
82
100
|
// Legacy SSE options
|
|
83
101
|
const legacySse = options.sessions?.legacySse;
|
|
84
102
|
const sseEndpoint = legacySse?.sseEndpoint ?? "/sse";
|
|
@@ -88,6 +106,24 @@ function serveHttpStateful(serverFactory, options) {
|
|
|
88
106
|
// Main MCP endpoint (Streamable HTTP)
|
|
89
107
|
app.all(options.endpoint, async (c) => {
|
|
90
108
|
const sessionId = c.req.header("mcp-session-id");
|
|
109
|
+
// Handle DELETE method for session termination
|
|
110
|
+
if (c.req.method === "DELETE") {
|
|
111
|
+
if (!sessionId) {
|
|
112
|
+
return c.text("Session ID required for DELETE", 400);
|
|
113
|
+
}
|
|
114
|
+
const session = sessions.get(sessionId);
|
|
115
|
+
if (!session) {
|
|
116
|
+
return c.text("Session not found", 404);
|
|
117
|
+
}
|
|
118
|
+
// Close the transport and clean up
|
|
119
|
+
await session.transport.close();
|
|
120
|
+
// Clear event store if this is a streamable HTTP session
|
|
121
|
+
if (session.type === "streamable-http") {
|
|
122
|
+
session.eventStore.clear();
|
|
123
|
+
}
|
|
124
|
+
sessions.delete(sessionId);
|
|
125
|
+
return c.body(null, 204);
|
|
126
|
+
}
|
|
91
127
|
// Clone the request so we can read the body without consuming it
|
|
92
128
|
const rawRequest = c.req.raw;
|
|
93
129
|
const bodyText = await rawRequest.text();
|
|
@@ -106,27 +142,33 @@ function serveHttpStateful(serverFactory, options) {
|
|
|
106
142
|
});
|
|
107
143
|
// New session (initialize request without session ID)
|
|
108
144
|
if (!sessionId && body && isInitializeRequest(body)) {
|
|
145
|
+
// Generate session ID upfront so we can pass it to the factory
|
|
146
|
+
const sid = sessionIdGenerator();
|
|
147
|
+
// Create server with session ID (supports async factories)
|
|
148
|
+
const server = await serverFactory(sid);
|
|
109
149
|
const eventStore = new InMemoryEventStore();
|
|
110
150
|
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
111
|
-
|
|
151
|
+
// Use our pre-generated session ID
|
|
152
|
+
sessionIdGenerator: () => sid,
|
|
112
153
|
eventStore,
|
|
113
|
-
onsessioninitialized: (
|
|
114
|
-
//
|
|
115
|
-
const server = serverFactory();
|
|
154
|
+
onsessioninitialized: () => {
|
|
155
|
+
// Server already created above, just store the session state
|
|
116
156
|
const session = {
|
|
117
157
|
type: "streamable-http",
|
|
118
158
|
transport,
|
|
119
159
|
server,
|
|
120
160
|
eventStore,
|
|
161
|
+
lastActivity: Date.now(),
|
|
162
|
+
activeStreams: 0,
|
|
121
163
|
};
|
|
122
164
|
sessions.set(sid, session);
|
|
123
|
-
server.connect(transport);
|
|
124
165
|
},
|
|
125
166
|
});
|
|
167
|
+
// Connect server to transport before handling the request
|
|
168
|
+
await server.connect(transport);
|
|
126
169
|
transport.onclose = () => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
170
|
+
eventStore.clear();
|
|
171
|
+
sessions.delete(sid);
|
|
130
172
|
};
|
|
131
173
|
return transport.handleRequest(recreateRequest());
|
|
132
174
|
}
|
|
@@ -147,6 +189,8 @@ function serveHttpStateful(serverFactory, options) {
|
|
|
147
189
|
id: null,
|
|
148
190
|
}, 400);
|
|
149
191
|
}
|
|
192
|
+
// Update last activity for TTL tracking
|
|
193
|
+
session.lastActivity = Date.now();
|
|
150
194
|
return session.transport.handleRequest(recreateRequest());
|
|
151
195
|
}
|
|
152
196
|
// Invalid request (no session ID, not an initialize request)
|
|
@@ -159,17 +203,20 @@ function serveHttpStateful(serverFactory, options) {
|
|
|
159
203
|
const { outgoing } = c.env;
|
|
160
204
|
// Create SSE transport with messages endpoint
|
|
161
205
|
const transport = new SSEServerTransport(messagesEndpoint, outgoing);
|
|
162
|
-
// Create
|
|
163
|
-
const server = serverFactory();
|
|
164
|
-
// Store session
|
|
206
|
+
// Create server with session ID (supports async factories)
|
|
207
|
+
const server = await serverFactory(transport.sessionId);
|
|
208
|
+
// Store session - SSE connection counts as an active stream
|
|
165
209
|
const session = {
|
|
166
210
|
type: "sse",
|
|
167
211
|
transport,
|
|
168
212
|
server,
|
|
213
|
+
lastActivity: Date.now(),
|
|
214
|
+
activeStreams: 1, // SSE connection is an active stream
|
|
169
215
|
};
|
|
170
216
|
sessions.set(transport.sessionId, session);
|
|
171
|
-
// Cleanup on close
|
|
217
|
+
// Cleanup on close - SSE stream is no longer active
|
|
172
218
|
transport.onclose = () => {
|
|
219
|
+
session.activeStreams = 0;
|
|
173
220
|
sessions.delete(transport.sessionId);
|
|
174
221
|
};
|
|
175
222
|
// Connect and start
|
|
@@ -199,6 +246,8 @@ function serveHttpStateful(serverFactory, options) {
|
|
|
199
246
|
}, 400);
|
|
200
247
|
}
|
|
201
248
|
const { incoming, outgoing } = c.env;
|
|
249
|
+
// Update last activity for TTL tracking
|
|
250
|
+
session.lastActivity = Date.now();
|
|
202
251
|
// Parse body for SSEServerTransport
|
|
203
252
|
const bodyText = await c.req.text();
|
|
204
253
|
let parsedBody = null;
|
|
@@ -217,9 +266,28 @@ function serveHttpStateful(serverFactory, options) {
|
|
|
217
266
|
port: options.port,
|
|
218
267
|
hostname: options.host,
|
|
219
268
|
});
|
|
220
|
-
|
|
269
|
+
// Create handle that also clears the cleanup interval
|
|
270
|
+
const baseHandle = createHandle(httpServer);
|
|
271
|
+
return {
|
|
272
|
+
close: async () => {
|
|
273
|
+
if (cleanupInterval) {
|
|
274
|
+
clearInterval(cleanupInterval);
|
|
275
|
+
}
|
|
276
|
+
// Close all active sessions and clear their event stores
|
|
277
|
+
for (const [, session] of sessions) {
|
|
278
|
+
await session.transport.close().catch(() => {
|
|
279
|
+
// Ignore close errors during shutdown
|
|
280
|
+
});
|
|
281
|
+
// Clear event store if this is a streamable HTTP session
|
|
282
|
+
if (session.type === "streamable-http") {
|
|
283
|
+
session.eventStore.clear();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
sessions.clear();
|
|
287
|
+
await baseHandle.close();
|
|
288
|
+
},
|
|
289
|
+
};
|
|
221
290
|
}
|
|
222
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
223
291
|
function addCors(app) {
|
|
224
292
|
// Enable CORS for all origins
|
|
225
293
|
app.use("*", cors({
|
package/dist/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAmB,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,wCAAwC,EAAE,MAAM,+DAA+D,CAAC;AACzH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/stdio.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export type {
|
|
1
|
+
import type { ServerHandle, StatelessServerFactory } from "./types.js";
|
|
2
|
+
export type { ServerHandle, StatelessServerFactory } from "./types.js";
|
|
3
|
+
export type { ServerFactory } from "./types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Serve an MCP server over stdio (stdin/stdout).
|
|
6
6
|
*
|
|
7
7
|
* @param serverFactory - Factory function that creates an McpServer instance.
|
|
8
|
+
* Called once with no parameters (stdio is always single-session).
|
|
9
|
+
* Can return a Promise for async initialization.
|
|
8
10
|
* @returns A handle to control the server lifecycle.
|
|
9
11
|
*/
|
|
10
|
-
export declare function serveStdio(serverFactory:
|
|
12
|
+
export declare function serveStdio(serverFactory: StatelessServerFactory): Promise<ServerHandle>;
|
|
11
13
|
//# sourceMappingURL=stdio.d.ts.map
|
package/dist/stdio.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEvE,YAAY,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGvE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,aAAa,EAAE,sBAAsB,GACpC,OAAO,CAAC,YAAY,CAAC,CA4BvB"}
|
package/dist/stdio.js
CHANGED
|
@@ -3,10 +3,12 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
3
3
|
* Serve an MCP server over stdio (stdin/stdout).
|
|
4
4
|
*
|
|
5
5
|
* @param serverFactory - Factory function that creates an McpServer instance.
|
|
6
|
+
* Called once with no parameters (stdio is always single-session).
|
|
7
|
+
* Can return a Promise for async initialization.
|
|
6
8
|
* @returns A handle to control the server lifecycle.
|
|
7
9
|
*/
|
|
8
10
|
export async function serveStdio(serverFactory) {
|
|
9
|
-
const server = serverFactory();
|
|
11
|
+
const server = await serverFactory();
|
|
10
12
|
const transport = new StdioServerTransport();
|
|
11
13
|
// Set up the closed promise before connecting
|
|
12
14
|
let resolveClose;
|
package/dist/stdio.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAQjF;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,aAAqC,EACd;IACvB,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;IAErC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,8CAA8C;IAC9C,IAAI,YAAwB,CAAC;IAC7B,MAAM,aAAa,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QACnD,YAAY,GAAG,OAAO,CAAC;IAAA,CACxB,CAAC,CAAC;IAEH,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC;QACxB,YAAY,EAAE,CAAC;IAAA,CAChB,CAAC;IAEF,4DAA4D;IAC5D,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,IAAI,YAAuC,CAAC;IAE5C,OAAO;QACL,KAAK,EAAE,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,YAAY,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC;YAC7D,CAAC;YACD,OAAO,YAAY,CAAC;QAAA,CACrB;KACF,CAAC;AAAA,CACH"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
1
2
|
/**
|
|
2
3
|
* Handle returned by serve functions for controlling the server lifecycle.
|
|
3
4
|
*/
|
|
@@ -5,4 +6,19 @@ export interface ServerHandle {
|
|
|
5
6
|
/** Close the server and stop accepting new connections. */
|
|
6
7
|
close: () => Promise<void>;
|
|
7
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Factory function for stateless mode (no session ID).
|
|
11
|
+
* Used by serveStdio and serveHttp without sessions.
|
|
12
|
+
*/
|
|
13
|
+
export type StatelessServerFactory = () => McpServer | Promise<McpServer>;
|
|
14
|
+
/**
|
|
15
|
+
* Factory function for stateful mode (receives session ID).
|
|
16
|
+
* Used by serveHttp with sessions enabled.
|
|
17
|
+
*/
|
|
18
|
+
export type StatefulServerFactory = (sessionId: string) => McpServer | Promise<McpServer>;
|
|
19
|
+
/**
|
|
20
|
+
* Union type for all server factory signatures.
|
|
21
|
+
* @deprecated Prefer using StatelessServerFactory or StatefulServerFactory directly.
|
|
22
|
+
*/
|
|
23
|
+
export type ServerFactory = (sessionId?: string) => McpServer | Promise<McpServer>;
|
|
8
24
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AAE1E;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,SAAS,EAAE,MAAM,KACd,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AAEpC;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,SAAS,CAAC,EAAE,MAAM,KACf,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC"}
|