@frontmcp/sdk 1.0.0-beta.4 → 1.0.0-beta.6
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/common/utils/decide-request-intent.utils.d.ts.map +1 -1
- package/esm/index.mjs +47 -26
- package/index.js +47 -26
- package/package.json +8 -8
- package/transport/adapters/streamable-http-transport.d.ts +12 -0
- package/transport/adapters/streamable-http-transport.d.ts.map +1 -1
- package/transport/adapters/transport.streamable-http.adapter.d.ts +6 -4
- package/transport/adapters/transport.streamable-http.adapter.d.ts.map +1 -1
- package/transport/mcp-handlers/initialize-request.handler.d.ts.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decide-request-intent.utils.d.ts","sourceRoot":"","sources":["../../../src/common/utils/decide-request-intent.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAI/C,eAAO,MAAM,YAAY,iOAQvB,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;iBAiBzB,CAAC;AAEH,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,KAAK,GACL,iBAAiB,GACjB,eAAe,GACf,gBAAgB,GAChB,gBAAgB,CAAC;AAErB,MAAM,MAAM,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAC;AAEnD,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAEzD,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,MAAO,SAAQ,mBAAmB;IACjD,qBAAqB,EAAE,OAAO,CAAC;CAChC;
|
|
1
|
+
{"version":3,"file":"decide-request-intent.utils.d.ts","sourceRoot":"","sources":["../../../src/common/utils/decide-request-intent.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAI/C,eAAO,MAAM,YAAY,iOAQvB,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;iBAiBzB,CAAC;AAEH,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,KAAK,GACL,iBAAiB,GACjB,eAAe,GACf,gBAAgB,GAChB,gBAAgB,CAAC;AAErB,MAAM,MAAM,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAC;AAEnD,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAEzD,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,MAAO,SAAQ,mBAAmB;IACjD,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAuWD,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAsDtE"}
|
package/esm/index.mjs
CHANGED
|
@@ -28342,6 +28342,11 @@ var init_sse_transport = __esm({
|
|
|
28342
28342
|
// libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts
|
|
28343
28343
|
import { InitializeRequestSchema } from "@frontmcp/protocol";
|
|
28344
28344
|
import { LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS } from "@frontmcp/protocol";
|
|
28345
|
+
function persistInitPayload(sessionId, initPayload, ctx) {
|
|
28346
|
+
updateSessionPayload(sessionId, initPayload);
|
|
28347
|
+
const transport = ctx.authInfo?.transport;
|
|
28348
|
+
transport?.setInitSessionPayload(initPayload);
|
|
28349
|
+
}
|
|
28345
28350
|
function guardClientVersion(clientVersion) {
|
|
28346
28351
|
const parsed = new Date(clientVersion);
|
|
28347
28352
|
if (isNaN(parsed.getTime())) {
|
|
@@ -28402,28 +28407,30 @@ function initializeRequestHandler({
|
|
|
28402
28407
|
if (finalPlatform) {
|
|
28403
28408
|
ctx.authInfo.sessionIdPayload.platformType = finalPlatform;
|
|
28404
28409
|
}
|
|
28405
|
-
|
|
28406
|
-
|
|
28407
|
-
|
|
28408
|
-
|
|
28409
|
-
|
|
28410
|
-
|
|
28411
|
-
|
|
28412
|
-
|
|
28413
|
-
|
|
28410
|
+
persistInitPayload(
|
|
28411
|
+
sessionId,
|
|
28412
|
+
{
|
|
28413
|
+
clientName,
|
|
28414
|
+
clientVersion,
|
|
28415
|
+
supportsElicitation: clientSupportsElicitation,
|
|
28416
|
+
...finalPlatform && { platformType: finalPlatform }
|
|
28417
|
+
},
|
|
28418
|
+
ctx
|
|
28419
|
+
);
|
|
28414
28420
|
}
|
|
28415
28421
|
} else if (ctx.authInfo?.sessionIdPayload) {
|
|
28416
28422
|
ctx.authInfo.sessionIdPayload.supportsElicitation = clientSupportsElicitation;
|
|
28417
28423
|
if (detectedPlatform) {
|
|
28418
28424
|
ctx.authInfo.sessionIdPayload.platformType = detectedPlatform;
|
|
28419
28425
|
}
|
|
28420
|
-
|
|
28421
|
-
|
|
28422
|
-
|
|
28423
|
-
|
|
28424
|
-
|
|
28425
|
-
|
|
28426
|
-
|
|
28426
|
+
persistInitPayload(
|
|
28427
|
+
sessionId,
|
|
28428
|
+
{
|
|
28429
|
+
supportsElicitation: clientSupportsElicitation,
|
|
28430
|
+
...detectedPlatform && { platformType: detectedPlatform }
|
|
28431
|
+
},
|
|
28432
|
+
ctx
|
|
28433
|
+
);
|
|
28427
28434
|
}
|
|
28428
28435
|
}
|
|
28429
28436
|
const requestedVersion = request.params.protocolVersion;
|
|
@@ -31021,9 +31028,16 @@ var init_streamable_http_transport = __esm({
|
|
|
31021
31028
|
* so we need to create fresh instances for each request.
|
|
31022
31029
|
*/
|
|
31023
31030
|
_constructorOptions;
|
|
31031
|
+
/**
|
|
31032
|
+
* When true, the transport recreates the internal transport for each request.
|
|
31033
|
+
* Decoupled from sessionIdGenerator so stateless transports can still
|
|
31034
|
+
* provide a session ID (e.g., '__stateless__') in the response header.
|
|
31035
|
+
*/
|
|
31036
|
+
_isStateless;
|
|
31024
31037
|
constructor(options = {}) {
|
|
31025
31038
|
super(options);
|
|
31026
31039
|
this._constructorOptions = options;
|
|
31040
|
+
this._isStateless = options.isStateless ?? false;
|
|
31027
31041
|
}
|
|
31028
31042
|
/**
|
|
31029
31043
|
* Returns whether the transport has been initialized.
|
|
@@ -31087,7 +31101,7 @@ var init_streamable_http_transport = __esm({
|
|
|
31087
31101
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31088
31102
|
async handleRequest(req, res, body) {
|
|
31089
31103
|
const oldWebTransport = this._webStandardTransport;
|
|
31090
|
-
if (oldWebTransport &&
|
|
31104
|
+
if (oldWebTransport && this._isStateless && oldWebTransport._hasHandledRequest) {
|
|
31091
31105
|
const fresh = new WebStandardStreamableHTTPServerTransport(this._constructorOptions);
|
|
31092
31106
|
fresh.onmessage = oldWebTransport.onmessage;
|
|
31093
31107
|
fresh.onclose = oldWebTransport.onclose;
|
|
@@ -31119,14 +31133,16 @@ var init_transport_streamable_http_adapter = __esm({
|
|
|
31119
31133
|
init_streamable_http_transport();
|
|
31120
31134
|
init_errors();
|
|
31121
31135
|
resolveSessionIdGenerator = (transportType, sessionId) => {
|
|
31122
|
-
return transportType === "stateless-http" ?
|
|
31136
|
+
return transportType === "stateless-http" ? () => "__stateless__" : () => sessionId;
|
|
31123
31137
|
};
|
|
31124
31138
|
TransportStreamableHttpAdapter = class extends LocalTransportAdapter {
|
|
31125
31139
|
createTransport(sessionId, response) {
|
|
31126
31140
|
const sessionIdGenerator = resolveSessionIdGenerator(this.key.type, sessionId);
|
|
31127
31141
|
const eventStore = this.scope.eventStore;
|
|
31142
|
+
const isStateless = this.key.type === "stateless-http";
|
|
31128
31143
|
return new RecreateableStreamableHTTPServerTransport({
|
|
31129
31144
|
sessionIdGenerator,
|
|
31145
|
+
isStateless,
|
|
31130
31146
|
onsessionclosed: () => {
|
|
31131
31147
|
},
|
|
31132
31148
|
onsessioninitialized: (sessionId2) => {
|
|
@@ -45124,9 +45140,12 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45124
45140
|
outcome: { intent: "sse", reason: "GET /sse with Mcp-Session-Id." }
|
|
45125
45141
|
},
|
|
45126
45142
|
// D) Initialize (POST → SSE)
|
|
45127
|
-
// D1) Stateless initialize (no session, stateless enabled
|
|
45143
|
+
// D1) Stateless initialize (no session, stateless enabled, streamable NOT enabled)
|
|
45144
|
+
// When streamable is also enabled, prefer streamable-http (which creates a session).
|
|
45145
|
+
// Per MCP spec, first initialize naturally has no session — stateless should only
|
|
45146
|
+
// match when it's the sole enabled protocol.
|
|
45128
45147
|
{
|
|
45129
|
-
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
|
|
45148
|
+
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN | B_STREAMABLE_EN,
|
|
45130
45149
|
match: CH_POST_INIT_SSE | B_STATELESS_EN,
|
|
45131
45150
|
outcome: { intent: "stateless-http", reason: "Stateless initialize (no session)." }
|
|
45132
45151
|
},
|
|
@@ -45145,9 +45164,9 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45145
45164
|
outcome: { intent: "streamable-http", reason: "Initialize with SSE." }
|
|
45146
45165
|
},
|
|
45147
45166
|
// E) Initialize (POST → JSON)
|
|
45148
|
-
// E1) Stateless initialize JSON (no session, stateless enabled
|
|
45167
|
+
// E1) Stateless initialize JSON (no session, stateless enabled, streamable NOT enabled)
|
|
45149
45168
|
{
|
|
45150
|
-
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
|
|
45169
|
+
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN | B_STREAMABLE_EN,
|
|
45151
45170
|
match: CH_POST_INIT_JSON | B_STATELESS_EN,
|
|
45152
45171
|
outcome: { intent: "stateless-http", reason: "Stateless initialize JSON (no session)." }
|
|
45153
45172
|
},
|
|
@@ -45176,7 +45195,7 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45176
45195
|
}
|
|
45177
45196
|
},
|
|
45178
45197
|
{
|
|
45179
|
-
care: CH_MASK | B_STREAMABLE_EN,
|
|
45198
|
+
care: CH_MASK | B_STREAMABLE_EN | B_STATELESS_EN,
|
|
45180
45199
|
match: CH_POST_SSE,
|
|
45181
45200
|
outcome: {
|
|
45182
45201
|
intent: "unknown",
|
|
@@ -45184,8 +45203,9 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45184
45203
|
recommendation: { httpStatus: 405, message: "Streamable HTTP disabled" }
|
|
45185
45204
|
}
|
|
45186
45205
|
},
|
|
45206
|
+
// Stateless short-lived SSE only when streamable is NOT enabled
|
|
45187
45207
|
{
|
|
45188
|
-
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
|
|
45208
|
+
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN | B_STREAMABLE_EN,
|
|
45189
45209
|
match: CH_POST_SSE | B_STATELESS_EN,
|
|
45190
45210
|
outcome: { intent: "stateless-http", reason: "Stateless short-lived SSE." }
|
|
45191
45211
|
},
|
|
@@ -45205,7 +45225,7 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45205
45225
|
}
|
|
45206
45226
|
},
|
|
45207
45227
|
{
|
|
45208
|
-
care: CH_MASK | B_STATEFUL_EN | B_STREAMABLE_EN,
|
|
45228
|
+
care: CH_MASK | B_STATEFUL_EN | B_STREAMABLE_EN | B_STATELESS_EN,
|
|
45209
45229
|
match: CH_POST_JSON,
|
|
45210
45230
|
outcome: {
|
|
45211
45231
|
intent: "unknown",
|
|
@@ -45213,8 +45233,9 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45213
45233
|
recommendation: { httpStatus: 405, message: "JSON mode disabled" }
|
|
45214
45234
|
}
|
|
45215
45235
|
},
|
|
45236
|
+
// Stateless JSON only when streamable is NOT enabled
|
|
45216
45237
|
{
|
|
45217
|
-
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
|
|
45238
|
+
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN | B_STREAMABLE_EN,
|
|
45218
45239
|
match: CH_POST_JSON | B_STATELESS_EN,
|
|
45219
45240
|
outcome: { intent: "stateless-http", reason: "Stateless JSON request." }
|
|
45220
45241
|
},
|
package/index.js
CHANGED
|
@@ -28278,6 +28278,11 @@ var init_sse_transport = __esm({
|
|
|
28278
28278
|
});
|
|
28279
28279
|
|
|
28280
28280
|
// libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts
|
|
28281
|
+
function persistInitPayload(sessionId, initPayload, ctx) {
|
|
28282
|
+
updateSessionPayload(sessionId, initPayload);
|
|
28283
|
+
const transport = ctx.authInfo?.transport;
|
|
28284
|
+
transport?.setInitSessionPayload(initPayload);
|
|
28285
|
+
}
|
|
28281
28286
|
function guardClientVersion(clientVersion) {
|
|
28282
28287
|
const parsed = new Date(clientVersion);
|
|
28283
28288
|
if (isNaN(parsed.getTime())) {
|
|
@@ -28338,28 +28343,30 @@ function initializeRequestHandler({
|
|
|
28338
28343
|
if (finalPlatform) {
|
|
28339
28344
|
ctx.authInfo.sessionIdPayload.platformType = finalPlatform;
|
|
28340
28345
|
}
|
|
28341
|
-
|
|
28342
|
-
|
|
28343
|
-
|
|
28344
|
-
|
|
28345
|
-
|
|
28346
|
-
|
|
28347
|
-
|
|
28348
|
-
|
|
28349
|
-
|
|
28346
|
+
persistInitPayload(
|
|
28347
|
+
sessionId,
|
|
28348
|
+
{
|
|
28349
|
+
clientName,
|
|
28350
|
+
clientVersion,
|
|
28351
|
+
supportsElicitation: clientSupportsElicitation,
|
|
28352
|
+
...finalPlatform && { platformType: finalPlatform }
|
|
28353
|
+
},
|
|
28354
|
+
ctx
|
|
28355
|
+
);
|
|
28350
28356
|
}
|
|
28351
28357
|
} else if (ctx.authInfo?.sessionIdPayload) {
|
|
28352
28358
|
ctx.authInfo.sessionIdPayload.supportsElicitation = clientSupportsElicitation;
|
|
28353
28359
|
if (detectedPlatform) {
|
|
28354
28360
|
ctx.authInfo.sessionIdPayload.platformType = detectedPlatform;
|
|
28355
28361
|
}
|
|
28356
|
-
|
|
28357
|
-
|
|
28358
|
-
|
|
28359
|
-
|
|
28360
|
-
|
|
28361
|
-
|
|
28362
|
-
|
|
28362
|
+
persistInitPayload(
|
|
28363
|
+
sessionId,
|
|
28364
|
+
{
|
|
28365
|
+
supportsElicitation: clientSupportsElicitation,
|
|
28366
|
+
...detectedPlatform && { platformType: detectedPlatform }
|
|
28367
|
+
},
|
|
28368
|
+
ctx
|
|
28369
|
+
);
|
|
28363
28370
|
}
|
|
28364
28371
|
}
|
|
28365
28372
|
const requestedVersion = request.params.protocolVersion;
|
|
@@ -30964,9 +30971,16 @@ var init_streamable_http_transport = __esm({
|
|
|
30964
30971
|
* so we need to create fresh instances for each request.
|
|
30965
30972
|
*/
|
|
30966
30973
|
_constructorOptions;
|
|
30974
|
+
/**
|
|
30975
|
+
* When true, the transport recreates the internal transport for each request.
|
|
30976
|
+
* Decoupled from sessionIdGenerator so stateless transports can still
|
|
30977
|
+
* provide a session ID (e.g., '__stateless__') in the response header.
|
|
30978
|
+
*/
|
|
30979
|
+
_isStateless;
|
|
30967
30980
|
constructor(options = {}) {
|
|
30968
30981
|
super(options);
|
|
30969
30982
|
this._constructorOptions = options;
|
|
30983
|
+
this._isStateless = options.isStateless ?? false;
|
|
30970
30984
|
}
|
|
30971
30985
|
/**
|
|
30972
30986
|
* Returns whether the transport has been initialized.
|
|
@@ -31030,7 +31044,7 @@ var init_streamable_http_transport = __esm({
|
|
|
31030
31044
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31031
31045
|
async handleRequest(req, res, body) {
|
|
31032
31046
|
const oldWebTransport = this._webStandardTransport;
|
|
31033
|
-
if (oldWebTransport &&
|
|
31047
|
+
if (oldWebTransport && this._isStateless && oldWebTransport._hasHandledRequest) {
|
|
31034
31048
|
const fresh = new import_protocol37.WebStandardStreamableHTTPServerTransport(this._constructorOptions);
|
|
31035
31049
|
fresh.onmessage = oldWebTransport.onmessage;
|
|
31036
31050
|
fresh.onclose = oldWebTransport.onclose;
|
|
@@ -31062,14 +31076,16 @@ var init_transport_streamable_http_adapter = __esm({
|
|
|
31062
31076
|
init_streamable_http_transport();
|
|
31063
31077
|
init_errors();
|
|
31064
31078
|
resolveSessionIdGenerator = (transportType, sessionId) => {
|
|
31065
|
-
return transportType === "stateless-http" ?
|
|
31079
|
+
return transportType === "stateless-http" ? () => "__stateless__" : () => sessionId;
|
|
31066
31080
|
};
|
|
31067
31081
|
TransportStreamableHttpAdapter = class extends LocalTransportAdapter {
|
|
31068
31082
|
createTransport(sessionId, response) {
|
|
31069
31083
|
const sessionIdGenerator = resolveSessionIdGenerator(this.key.type, sessionId);
|
|
31070
31084
|
const eventStore = this.scope.eventStore;
|
|
31085
|
+
const isStateless = this.key.type === "stateless-http";
|
|
31071
31086
|
return new RecreateableStreamableHTTPServerTransport({
|
|
31072
31087
|
sessionIdGenerator,
|
|
31088
|
+
isStateless,
|
|
31073
31089
|
onsessionclosed: () => {
|
|
31074
31090
|
},
|
|
31075
31091
|
onsessioninitialized: (sessionId2) => {
|
|
@@ -45080,9 +45096,12 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45080
45096
|
outcome: { intent: "sse", reason: "GET /sse with Mcp-Session-Id." }
|
|
45081
45097
|
},
|
|
45082
45098
|
// D) Initialize (POST → SSE)
|
|
45083
|
-
// D1) Stateless initialize (no session, stateless enabled
|
|
45099
|
+
// D1) Stateless initialize (no session, stateless enabled, streamable NOT enabled)
|
|
45100
|
+
// When streamable is also enabled, prefer streamable-http (which creates a session).
|
|
45101
|
+
// Per MCP spec, first initialize naturally has no session — stateless should only
|
|
45102
|
+
// match when it's the sole enabled protocol.
|
|
45084
45103
|
{
|
|
45085
|
-
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
|
|
45104
|
+
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN | B_STREAMABLE_EN,
|
|
45086
45105
|
match: CH_POST_INIT_SSE | B_STATELESS_EN,
|
|
45087
45106
|
outcome: { intent: "stateless-http", reason: "Stateless initialize (no session)." }
|
|
45088
45107
|
},
|
|
@@ -45101,9 +45120,9 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45101
45120
|
outcome: { intent: "streamable-http", reason: "Initialize with SSE." }
|
|
45102
45121
|
},
|
|
45103
45122
|
// E) Initialize (POST → JSON)
|
|
45104
|
-
// E1) Stateless initialize JSON (no session, stateless enabled
|
|
45123
|
+
// E1) Stateless initialize JSON (no session, stateless enabled, streamable NOT enabled)
|
|
45105
45124
|
{
|
|
45106
|
-
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
|
|
45125
|
+
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN | B_STREAMABLE_EN,
|
|
45107
45126
|
match: CH_POST_INIT_JSON | B_STATELESS_EN,
|
|
45108
45127
|
outcome: { intent: "stateless-http", reason: "Stateless initialize JSON (no session)." }
|
|
45109
45128
|
},
|
|
@@ -45132,7 +45151,7 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45132
45151
|
}
|
|
45133
45152
|
},
|
|
45134
45153
|
{
|
|
45135
|
-
care: CH_MASK | B_STREAMABLE_EN,
|
|
45154
|
+
care: CH_MASK | B_STREAMABLE_EN | B_STATELESS_EN,
|
|
45136
45155
|
match: CH_POST_SSE,
|
|
45137
45156
|
outcome: {
|
|
45138
45157
|
intent: "unknown",
|
|
@@ -45140,8 +45159,9 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45140
45159
|
recommendation: { httpStatus: 405, message: "Streamable HTTP disabled" }
|
|
45141
45160
|
}
|
|
45142
45161
|
},
|
|
45162
|
+
// Stateless short-lived SSE only when streamable is NOT enabled
|
|
45143
45163
|
{
|
|
45144
|
-
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
|
|
45164
|
+
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN | B_STREAMABLE_EN,
|
|
45145
45165
|
match: CH_POST_SSE | B_STATELESS_EN,
|
|
45146
45166
|
outcome: { intent: "stateless-http", reason: "Stateless short-lived SSE." }
|
|
45147
45167
|
},
|
|
@@ -45161,7 +45181,7 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45161
45181
|
}
|
|
45162
45182
|
},
|
|
45163
45183
|
{
|
|
45164
|
-
care: CH_MASK | B_STATEFUL_EN | B_STREAMABLE_EN,
|
|
45184
|
+
care: CH_MASK | B_STATEFUL_EN | B_STREAMABLE_EN | B_STATELESS_EN,
|
|
45165
45185
|
match: CH_POST_JSON,
|
|
45166
45186
|
outcome: {
|
|
45167
45187
|
intent: "unknown",
|
|
@@ -45169,8 +45189,9 @@ var init_decide_request_intent_utils = __esm({
|
|
|
45169
45189
|
recommendation: { httpStatus: 405, message: "JSON mode disabled" }
|
|
45170
45190
|
}
|
|
45171
45191
|
},
|
|
45192
|
+
// Stateless JSON only when streamable is NOT enabled
|
|
45172
45193
|
{
|
|
45173
|
-
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
|
|
45194
|
+
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN | B_STREAMABLE_EN,
|
|
45174
45195
|
match: CH_POST_JSON | B_STATELESS_EN,
|
|
45175
45196
|
outcome: { intent: "stateless-http", reason: "Stateless JSON request." }
|
|
45176
45197
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/sdk",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.6",
|
|
4
4
|
"description": "FrontMCP SDK",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"homepage": "https://docs.agentfront.dev",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"raw-body": "^3.0.0",
|
|
74
74
|
"content-type": "^1.0.5",
|
|
75
75
|
"@vercel/kv": "^3.0.0",
|
|
76
|
-
"@frontmcp/storage-sqlite": "1.0.0-beta.
|
|
76
|
+
"@frontmcp/storage-sqlite": "1.0.0-beta.6",
|
|
77
77
|
"@enclave-vm/core": "^2.11.1",
|
|
78
78
|
"openai": "^4.0.0 || ^5.0.0 || ^6.0.0",
|
|
79
79
|
"@anthropic-ai/sdk": "^0.30.0 || ^0.78.0"
|
|
@@ -97,12 +97,12 @@
|
|
|
97
97
|
},
|
|
98
98
|
"dependencies": {
|
|
99
99
|
"@types/cors": "^2.8.17",
|
|
100
|
-
"@frontmcp/utils": "1.0.0-beta.
|
|
101
|
-
"@frontmcp/guard": "1.0.0-beta.
|
|
102
|
-
"@frontmcp/di": "1.0.0-beta.
|
|
103
|
-
"@frontmcp/uipack": "1.0.0-beta.
|
|
104
|
-
"@frontmcp/auth": "1.0.0-beta.
|
|
105
|
-
"@frontmcp/protocol": "1.0.0-beta.
|
|
100
|
+
"@frontmcp/utils": "1.0.0-beta.6",
|
|
101
|
+
"@frontmcp/guard": "1.0.0-beta.6",
|
|
102
|
+
"@frontmcp/di": "1.0.0-beta.6",
|
|
103
|
+
"@frontmcp/uipack": "1.0.0-beta.6",
|
|
104
|
+
"@frontmcp/auth": "1.0.0-beta.6",
|
|
105
|
+
"@frontmcp/protocol": "1.0.0-beta.6",
|
|
106
106
|
"ioredis": "^5.8.0",
|
|
107
107
|
"vectoriadb": "^2.1.3",
|
|
108
108
|
"js-yaml": "^4.1.1",
|
|
@@ -36,6 +36,12 @@ export interface StreamableHTTPServerTransportOptions {
|
|
|
36
36
|
* Callback when a session is closed.
|
|
37
37
|
*/
|
|
38
38
|
onsessionclosed?: (sessionId?: string) => void | Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* When true, the transport operates in stateless mode and recreates
|
|
41
|
+
* the internal WebStandardStreamableHTTPServerTransport for each request.
|
|
42
|
+
* This is needed because MCP SDK 1.26.0 enforces single-use for stateless transports.
|
|
43
|
+
*/
|
|
44
|
+
isStateless?: boolean;
|
|
39
45
|
}
|
|
40
46
|
/**
|
|
41
47
|
* StreamableHTTPServerTransport with session recreation support.
|
|
@@ -60,6 +66,12 @@ export declare class RecreateableStreamableHTTPServerTransport extends Streamabl
|
|
|
60
66
|
* so we need to create fresh instances for each request.
|
|
61
67
|
*/
|
|
62
68
|
private readonly _constructorOptions;
|
|
69
|
+
/**
|
|
70
|
+
* When true, the transport recreates the internal transport for each request.
|
|
71
|
+
* Decoupled from sessionIdGenerator so stateless transports can still
|
|
72
|
+
* provide a session ID (e.g., '__stateless__') in the response header.
|
|
73
|
+
*/
|
|
74
|
+
private readonly _isStateless;
|
|
63
75
|
constructor(options?: StreamableHTTPServerTransportOptions);
|
|
64
76
|
/**
|
|
65
77
|
* Returns whether the transport has been initialized.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streamable-http-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/adapters/streamable-http-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,6BAA6B,EAA4C,MAAM,oBAAoB,CAAC;AAG7G,MAAM,WAAW,oCAAoC;IACnD;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,MAAM,CAAC;IAElC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;;OAKG;IAEH,UAAU,CAAC,EAAE,GAAG,CAAC;IAEjB;;OAEG;IACH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnE;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"streamable-http-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/adapters/streamable-http-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,6BAA6B,EAA4C,MAAM,oBAAoB,CAAC;AAG7G,MAAM,WAAW,oCAAoC;IACnD;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,MAAM,CAAC;IAElC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;;OAKG;IAEH,UAAU,CAAC,EAAE,GAAG,CAAC;IAEjB;;OAEG;IACH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnE;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/D;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,yCAA0C,SAAQ,6BAA6B;IAC1F;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAAC,CAAS;IAEnC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAuC;IAE3E;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;gBAE3B,OAAO,GAAE,oCAAyC;IAM9D;;OAEG;IACH,IAAI,aAAa,IAAI,OAAO,CAK3B;IAED;;;OAGG;IACH,IAAI,mBAAmB,IAAI,OAAO,CAEjC;IAED;;;;;;;;;;;;;OAaG;IACH,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAqB/C;;;;;OAKG;IAEH,OAAO,CAAC,eAAe;IAevB;;;;OAIG;IAEY,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CAiC5E"}
|
|
@@ -7,10 +7,12 @@ import { ServerResponse } from '../../common';
|
|
|
7
7
|
import { RecreateableStreamableHTTPServerTransport } from './streamable-http-transport';
|
|
8
8
|
import { ElicitResult, ElicitOptions } from '../../elicitation';
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* Resolves the session ID generator for the transport.
|
|
11
|
+
*
|
|
12
|
+
* For stateless-http, returns a generator that always yields '__stateless__'
|
|
13
|
+
* so the MCP SDK sets the Mcp-Session-Id response header (required by the
|
|
14
|
+
* MCP spec for streamable HTTP). The per-request recreation logic uses the
|
|
15
|
+
* dedicated `isStateless` flag instead of checking sessionIdGenerator.
|
|
14
16
|
*/
|
|
15
17
|
export declare const resolveSessionIdGenerator: (transportType: TransportType, sessionId: string) => (() => string) | undefined;
|
|
16
18
|
export declare class TransportStreamableHttpAdapter extends LocalTransportAdapter<RecreateableStreamableHTTPServerTransport> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.streamable-http.adapter.d.ts","sourceRoot":"","sources":["../../../src/transport/adapters/transport.streamable-http.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAG9B,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,yCAAyC,EAAE,MAAM,6BAA6B,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGhE
|
|
1
|
+
{"version":3,"file":"transport.streamable-http.adapter.d.ts","sourceRoot":"","sources":["../../../src/transport/adapters/transport.streamable-http.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAG9B,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,yCAAyC,EAAE,MAAM,6BAA6B,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGhE;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,GACpC,eAAe,aAAa,EAC5B,WAAW,MAAM,KAChB,CAAC,MAAM,MAAM,CAAC,GAAG,SAEnB,CAAC;AAEF,qBAAa,8BAA+B,SAAQ,qBAAqB,CAAC,yCAAyC,CAAC;IACzG,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,yCAAyC;IAgC1G,UAAU,CAAC,GAAG,EAAE,0BAA0B,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA4D/E,aAAa,CAAC,GAAG,EAAE,0BAA0B,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBxF;;;;;;;;;;;;;;;;;OAiBG;IACG,iBAAiB,CAAC,CAAC,SAAS,OAAO,EACvC,gBAAgB,EAAE,SAAS,EAC3B,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,CAAC,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAiHlE;;;;;;;OAOG;IACM,iBAAiB,IAAI,IAAI;CAOnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialize-request.handler.d.ts","sourceRoot":"","sources":["../../../src/transport/mcp-handlers/initialize-request.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE5G,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"initialize-request.handler.d.ts","sourceRoot":"","sources":["../../../src/transport/mcp-handlers/initialize-request.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE5G,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAwCrE,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAAC,EAC/C,aAAa,EACb,KAAK,GACN,EAAE,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAgJrE"}
|