@j0hanz/fetch-url-mcp 1.10.8 → 1.10.10
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/dist/http/auth.d.ts.map +1 -1
- package/dist/http/auth.js +1 -2
- package/dist/http/helpers.d.ts.map +1 -1
- package/dist/http/helpers.js +2 -5
- package/dist/http/native.d.ts.map +1 -1
- package/dist/http/native.js +101 -64
- package/dist/http/session-teardown.d.ts +1 -0
- package/dist/http/session-teardown.d.ts.map +1 -1
- package/dist/http/session-teardown.js +15 -5
- package/dist/lib/code-lang.d.ts.map +1 -1
- package/dist/lib/code-lang.js +35 -102
- package/dist/lib/core.d.ts.map +1 -1
- package/dist/lib/core.js +65 -84
- package/dist/lib/dom-prep.d.ts.map +1 -1
- package/dist/lib/dom-prep.js +60 -58
- package/dist/lib/fetch-pipeline.d.ts.map +1 -1
- package/dist/lib/fetch-pipeline.js +35 -80
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +2 -6
- package/dist/lib/md-cleanup.d.ts +0 -5
- package/dist/lib/md-cleanup.d.ts.map +1 -1
- package/dist/lib/md-cleanup.js +63 -80
- package/dist/lib/progress.d.ts +1 -1
- package/dist/lib/progress.d.ts.map +1 -1
- package/dist/lib/progress.js +28 -39
- package/dist/lib/url.d.ts +3 -0
- package/dist/lib/url.d.ts.map +1 -1
- package/dist/lib/url.js +48 -54
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +9 -36
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +2 -2
- package/dist/resources/instructions.d.ts.map +1 -1
- package/dist/resources/instructions.js +27 -33
- package/dist/tasks/execution.d.ts.map +1 -1
- package/dist/tasks/execution.js +43 -111
- package/dist/tasks/manager.d.ts +0 -8
- package/dist/tasks/manager.d.ts.map +1 -1
- package/dist/tasks/manager.js +54 -118
- package/dist/tasks/owner.d.ts.map +1 -1
- package/dist/tasks/owner.js +13 -4
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +1 -9
- package/dist/transform/html-translators.d.ts.map +1 -1
- package/dist/transform/html-translators.js +39 -89
- package/dist/transform/next-flight.d.ts.map +1 -1
- package/dist/transform/next-flight.js +72 -57
- package/dist/transform/transform.d.ts.map +1 -1
- package/dist/transform/transform.js +144 -99
- package/dist/transform/worker-pool.d.ts.map +1 -1
- package/dist/transform/worker-pool.js +38 -35
- package/package.json +1 -1
package/dist/http/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/http/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/http/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/http/auth.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Buffer } from 'node:buffer';
|
|
2
1
|
import { randomBytes } from 'node:crypto';
|
|
3
2
|
import { InvalidTokenError, ServerError, } from '@modelcontextprotocol/sdk/server/auth/errors.js';
|
|
4
3
|
import { config } from '../lib/core.js';
|
|
@@ -327,7 +326,7 @@ class AuthService {
|
|
|
327
326
|
buildBasicAuthHeader(clientId, clientSecret) {
|
|
328
327
|
// Base64 is only an encoding for header transport; it is NOT encryption.
|
|
329
328
|
const credentials = `${clientId}:${clientSecret ?? ''}`;
|
|
330
|
-
return `Basic ${
|
|
329
|
+
return `Basic ${btoa(credentials)}`;
|
|
331
330
|
}
|
|
332
331
|
buildIntrospectionRequest(token, resourceUrl, clientId, clientSecret) {
|
|
333
332
|
const body = new URLSearchParams({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/http/helpers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,YAAY,CAAC;AAKxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gDAAgD,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACxG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAK/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAQrD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,CAAC;AAcjD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,eAAe,CAAC;IACrB,GAAG,EAAE,cAAc,CAAC;IACpB,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,IAAI,EAAE,QAAQ,CAAC;CAChB;AAWD,wBAAgB,QAAQ,CACtB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,GACZ,IAAI,CAKN;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAInE;AAED,wBAAgB,SAAS,CACvB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,SAAM,EACZ,EAAE,GAAE,SAAgB,GACnB,IAAI,CAMN;AAMD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAIf;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAKnE;AAkBD,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,eAAe,GACnB,MAAM,GAAG,IAAI,CAKf;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAOvD;AAMD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,eAAe,GAAG;IAC9D,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CA2CA;AAgBD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAoBpE;AAMD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,MAAM,CAAC,EAAE,WAAW,GACnB,cAAc,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/http/helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/http/helpers.js
CHANGED
|
@@ -168,11 +168,8 @@ export function registerInboundBlockList(server) {
|
|
|
168
168
|
// Request context builder
|
|
169
169
|
// ---------------------------------------------------------------------------
|
|
170
170
|
export function buildRequestContext(req, res, signal) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
url = new URL(req.url ?? '', 'http://localhost');
|
|
174
|
-
}
|
|
175
|
-
catch {
|
|
171
|
+
const url = URL.parse(req.url ?? '', 'http://localhost');
|
|
172
|
+
if (!url) {
|
|
176
173
|
sendJson(res, 400, { error: 'Invalid request URL' });
|
|
177
174
|
return null;
|
|
178
175
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../src/http/native.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../src/http/native.ts"],"names":[],"mappings":"AA+iCA,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CA0DD"}
|
package/dist/http/native.js
CHANGED
|
@@ -17,9 +17,9 @@ import { isObject } from '../lib/utils.js';
|
|
|
17
17
|
import { createMcpServerForHttpSession } from '../server.js';
|
|
18
18
|
import { applyInsufficientScopeAuthHeaders, applyUnauthorizedAuthHeaders, assertHttpModeConfiguration, authService, buildAuthFingerprint, buildProtectedResourceMetadataDocument, corsPolicy, DEFAULT_MCP_PROTOCOL_VERSION, ensureMcpProtocolVersion, hostOriginPolicy, isInsufficientScopeError, isOAuthMetadataEnabled, isProtectedResourceMetadataPath, SUPPORTED_MCP_PROTOCOL_VERSIONS, } from './auth.js';
|
|
19
19
|
import { disableEventLoopMonitoring, isVerboseHealthRequest, resetEventLoopMonitoring, sendHealthRouteResponse, shouldHandleHealthRoute, } from './health.js';
|
|
20
|
-
import { buildRequestContext,
|
|
20
|
+
import { buildRequestContext, createRequestAbortSignal, createTransportAdapter, DEFAULT_BODY_LIMIT_BYTES, drainRequest, findDuplicateSingleValueHeader, getHeaderValue, getMcpSessionId, isJsonBodyError, jsonBodyReader, registerInboundBlockList, sendEmpty, sendError, sendJson, } from './helpers.js';
|
|
21
21
|
import { createRateLimitManagerImpl, } from './rate-limit.js';
|
|
22
|
-
import { teardownSessionRegistration, teardownSessionResources, } from './session-teardown.js';
|
|
22
|
+
import { teardownSessionRegistration, teardownSessionResources, teardownUnregisteredSessionResources, } from './session-teardown.js';
|
|
23
23
|
function resolveRequestedProtocolVersion(body) {
|
|
24
24
|
if (!isObject(body))
|
|
25
25
|
return DEFAULT_MCP_PROTOCOL_VERSION;
|
|
@@ -50,6 +50,30 @@ function isInitializedNotification(method) {
|
|
|
50
50
|
function isPingRequest(method) {
|
|
51
51
|
return method === 'ping';
|
|
52
52
|
}
|
|
53
|
+
function createSessionTeardownOptions(mode, context) {
|
|
54
|
+
switch (mode) {
|
|
55
|
+
case 'ended':
|
|
56
|
+
return {
|
|
57
|
+
cancelMessage: 'The task was cancelled because the MCP session ended.',
|
|
58
|
+
closeServerReason: `${context ?? 'session'}-server`,
|
|
59
|
+
};
|
|
60
|
+
case 'evicted':
|
|
61
|
+
return {
|
|
62
|
+
cancelMessage: 'The task was cancelled because the MCP session was evicted.',
|
|
63
|
+
closeTransportReason: 'session-eviction',
|
|
64
|
+
closeServerReason: 'session-eviction',
|
|
65
|
+
unregisterByServer: true,
|
|
66
|
+
};
|
|
67
|
+
case 'shutdown':
|
|
68
|
+
return {
|
|
69
|
+
cancelMessage: 'The task was cancelled because the HTTP server is shutting down.',
|
|
70
|
+
closeTransportReason: 'shutdown-session-close',
|
|
71
|
+
closeServerReason: 'shutdown-session-close',
|
|
72
|
+
unregisterByServer: true,
|
|
73
|
+
awaitClose: true,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
53
77
|
class McpSessionGateway {
|
|
54
78
|
store;
|
|
55
79
|
createSessionServer;
|
|
@@ -59,42 +83,13 @@ class McpSessionGateway {
|
|
|
59
83
|
this.createSessionServer = createSessionServer;
|
|
60
84
|
}
|
|
61
85
|
async handlePost(ctx) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
error: 'Accept header must include application/json and text/event-stream',
|
|
65
|
-
});
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const { body } = ctx;
|
|
69
|
-
if (isJsonRpcBatchRequest(body)) {
|
|
70
|
-
sendError(ctx.res, -32600, 'Batch requests not supported');
|
|
86
|
+
const body = this.validatePostRequest(ctx);
|
|
87
|
+
if (!body)
|
|
71
88
|
return;
|
|
72
|
-
|
|
73
|
-
if (!
|
|
74
|
-
sendError(ctx.res, -32600, 'Invalid request body');
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const requestId = body.id ?? null;
|
|
78
|
-
const method = isMcpRequestBody(body) ? body.method : null;
|
|
79
|
-
const isInitializedMethod = method !== null && isInitializedNotification(method);
|
|
80
|
-
const isInitNotification = isInitializedMethod && body.id === undefined;
|
|
81
|
-
const sessionId = getMcpSessionId(ctx.req);
|
|
82
|
-
if (isInitializedMethod && !isInitNotification) {
|
|
83
|
-
sendError(ctx.res, -32600, 'notifications/initialized must be sent as a notification', 400, requestId);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const session = sessionId
|
|
87
|
-
? this.getAuthenticatedSessionById(sessionId, ctx.auth, ctx.res, requestId)
|
|
88
|
-
: undefined;
|
|
89
|
-
if (!this.ensurePostSessionAccess({
|
|
90
|
-
ctx,
|
|
91
|
-
sessionId,
|
|
92
|
-
session,
|
|
93
|
-
requestId,
|
|
94
|
-
method,
|
|
95
|
-
isInitNotification,
|
|
96
|
-
}))
|
|
89
|
+
const postState = this.resolvePostRequestState(ctx, body);
|
|
90
|
+
if (!postState)
|
|
97
91
|
return;
|
|
92
|
+
const { requestId, method, sessionId, session, isInitNotification } = postState;
|
|
98
93
|
if (session && isInitNotification) {
|
|
99
94
|
this.markSessionInitialized(sessionId, session);
|
|
100
95
|
sendEmpty(ctx.res, 202);
|
|
@@ -138,6 +133,56 @@ class McpSessionGateway {
|
|
|
138
133
|
this.cleanupSessionRecord(sessionId, 'session-delete');
|
|
139
134
|
sendJson(ctx.res, 200, { status: 'closed' });
|
|
140
135
|
}
|
|
136
|
+
validatePostRequest(ctx) {
|
|
137
|
+
if (!acceptsJsonAndEventStream(getHeaderValue(ctx.req, 'accept'))) {
|
|
138
|
+
sendJson(ctx.res, 400, {
|
|
139
|
+
error: 'Accept header must include application/json and text/event-stream',
|
|
140
|
+
});
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
const { body } = ctx;
|
|
144
|
+
if (isJsonRpcBatchRequest(body)) {
|
|
145
|
+
sendError(ctx.res, -32600, 'Batch requests not supported');
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
if (!isMcpMessageBody(body)) {
|
|
149
|
+
sendError(ctx.res, -32600, 'Invalid request body');
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
return body;
|
|
153
|
+
}
|
|
154
|
+
resolvePostRequestState(ctx, body) {
|
|
155
|
+
const requestId = body.id ?? null;
|
|
156
|
+
const method = typeof body.method === 'string' ? body.method : null;
|
|
157
|
+
const isInitializedMethod = method !== null && isInitializedNotification(method);
|
|
158
|
+
const isInitNotification = isInitializedMethod && body.id === undefined;
|
|
159
|
+
const sessionId = getMcpSessionId(ctx.req);
|
|
160
|
+
if (isInitializedMethod && !isInitNotification) {
|
|
161
|
+
sendError(ctx.res, -32600, 'notifications/initialized must be sent as a notification', 400, requestId);
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
const authFingerprint = buildAuthFingerprint(ctx.auth);
|
|
165
|
+
const session = sessionId
|
|
166
|
+
? (this.getAuthenticatedSessionById(sessionId, authFingerprint, ctx.res, requestId) ?? undefined)
|
|
167
|
+
: undefined;
|
|
168
|
+
if (!this.ensurePostSessionAccess({
|
|
169
|
+
ctx,
|
|
170
|
+
sessionId,
|
|
171
|
+
session,
|
|
172
|
+
requestId,
|
|
173
|
+
method,
|
|
174
|
+
isInitNotification,
|
|
175
|
+
})) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
requestId,
|
|
180
|
+
method,
|
|
181
|
+
sessionId,
|
|
182
|
+
session,
|
|
183
|
+
isInitNotification,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
141
186
|
ensurePostSessionAccess(params) {
|
|
142
187
|
const { ctx, sessionId, session, requestId, method, isInitNotification } = params;
|
|
143
188
|
if (sessionId && !session)
|
|
@@ -166,6 +211,12 @@ class McpSessionGateway {
|
|
|
166
211
|
const fingerprint = buildAuthFingerprint(ctx.auth);
|
|
167
212
|
return this.getExistingTransport(sessionId, fingerprint, ctx.res, requestId);
|
|
168
213
|
}
|
|
214
|
+
const negotiatedProtocolVersion = this.getInitializeProtocolVersion(ctx, requestId);
|
|
215
|
+
if (!negotiatedProtocolVersion)
|
|
216
|
+
return null;
|
|
217
|
+
return this.createNewSession(ctx, requestId, negotiatedProtocolVersion);
|
|
218
|
+
}
|
|
219
|
+
getInitializeProtocolVersion(ctx, requestId) {
|
|
169
220
|
if (!isMcpRequestBody(ctx.body)) {
|
|
170
221
|
sendError(ctx.res, -32600, 'Missing session ID', 400, requestId);
|
|
171
222
|
return null;
|
|
@@ -187,7 +238,7 @@ class McpSessionGateway {
|
|
|
187
238
|
sendError(ctx.res, -32600, `initialize protocolVersion mismatch: header=${headerProtocolVersion}, body=${negotiatedProtocolVersion}`, 400, requestId);
|
|
188
239
|
return null;
|
|
189
240
|
}
|
|
190
|
-
return
|
|
241
|
+
return negotiatedProtocolVersion;
|
|
191
242
|
}
|
|
192
243
|
getExistingTransport(sessionId, authFingerprint, res, requestId) {
|
|
193
244
|
const session = this.getAuthenticatedSessionById(sessionId, authFingerprint, res, requestId);
|
|
@@ -200,7 +251,8 @@ class McpSessionGateway {
|
|
|
200
251
|
const sessionId = this.getRequiredSessionId(ctx.req, ctx.res, requestId);
|
|
201
252
|
if (!sessionId)
|
|
202
253
|
return null;
|
|
203
|
-
const
|
|
254
|
+
const authFingerprint = buildAuthFingerprint(ctx.auth);
|
|
255
|
+
const session = this.getAuthenticatedSessionById(sessionId, authFingerprint, ctx.res, requestId);
|
|
204
256
|
if (!session)
|
|
205
257
|
return null;
|
|
206
258
|
if (!this.ensureSessionProtocolVersion(ctx, session))
|
|
@@ -218,16 +270,13 @@ class McpSessionGateway {
|
|
|
218
270
|
sendError(res, -32600, 'Missing session ID', 400, requestId);
|
|
219
271
|
return null;
|
|
220
272
|
}
|
|
221
|
-
getAuthenticatedSessionById(sessionId,
|
|
273
|
+
getAuthenticatedSessionById(sessionId, authFingerprint, res, requestId = null) {
|
|
222
274
|
const session = this.store.get(sessionId);
|
|
223
275
|
if (!session) {
|
|
224
276
|
sendError(res, -32600, 'Session not found', 404, requestId);
|
|
225
277
|
return null;
|
|
226
278
|
}
|
|
227
|
-
|
|
228
|
-
? auth
|
|
229
|
-
: buildAuthFingerprint(auth);
|
|
230
|
-
if (!fingerprint || session.authFingerprint !== fingerprint) {
|
|
279
|
+
if (!authFingerprint || session.authFingerprint !== authFingerprint) {
|
|
231
280
|
sendError(res, -32600, 'Session not found', 404, requestId);
|
|
232
281
|
return null;
|
|
233
282
|
}
|
|
@@ -267,6 +316,10 @@ class McpSessionGateway {
|
|
|
267
316
|
const transportImpl = new StreamableHTTPServerTransport({
|
|
268
317
|
sessionIdGenerator: () => newSessionId,
|
|
269
318
|
});
|
|
319
|
+
const unpublishedSession = {
|
|
320
|
+
server: sessionServer,
|
|
321
|
+
transport: transportImpl,
|
|
322
|
+
};
|
|
270
323
|
const initTimeout = setTimeout(() => {
|
|
271
324
|
const session = this.store.get(newSessionId);
|
|
272
325
|
if (session) {
|
|
@@ -278,8 +331,7 @@ class McpSessionGateway {
|
|
|
278
331
|
return;
|
|
279
332
|
}
|
|
280
333
|
tracker.releaseSlot();
|
|
281
|
-
void
|
|
282
|
-
void closeMcpServerBestEffort(sessionServer, 'session-init-timeout');
|
|
334
|
+
void teardownUnregisteredSessionResources(unpublishedSession, 'session-init-timeout');
|
|
283
335
|
}, config.server.sessionInitTimeoutMs);
|
|
284
336
|
initTimeout.unref();
|
|
285
337
|
transportImpl.onclose = () => {
|
|
@@ -294,8 +346,7 @@ class McpSessionGateway {
|
|
|
294
346
|
catch (err) {
|
|
295
347
|
clearTimeout(initTimeout);
|
|
296
348
|
tracker.releaseSlot();
|
|
297
|
-
void
|
|
298
|
-
void closeMcpServerBestEffort(sessionServer, 'session-connect-failed');
|
|
349
|
+
void teardownUnregisteredSessionResources(unpublishedSession, 'session-connect-failed');
|
|
299
350
|
throw err;
|
|
300
351
|
}
|
|
301
352
|
tracker.releaseSlot();
|
|
@@ -320,10 +371,7 @@ class McpSessionGateway {
|
|
|
320
371
|
const session = this.store.remove(sessionId);
|
|
321
372
|
if (!session)
|
|
322
373
|
return;
|
|
323
|
-
void teardownSessionResources(session,
|
|
324
|
-
cancelMessage: 'The task was cancelled because the MCP session ended.',
|
|
325
|
-
closeServerReason: `${context}-server`,
|
|
326
|
-
});
|
|
374
|
+
void teardownSessionResources(session, createSessionTeardownOptions('ended', context));
|
|
327
375
|
}
|
|
328
376
|
clearSessionInitTimeout(sessionId) {
|
|
329
377
|
if (!sessionId)
|
|
@@ -341,12 +389,7 @@ class McpSessionGateway {
|
|
|
341
389
|
evictOldest: (store) => {
|
|
342
390
|
const evicted = store.evictOldest();
|
|
343
391
|
if (evicted) {
|
|
344
|
-
void teardownSessionResources(evicted,
|
|
345
|
-
cancelMessage: 'The task was cancelled because the MCP session was evicted.',
|
|
346
|
-
closeTransportReason: 'session-eviction',
|
|
347
|
-
closeServerReason: 'session-eviction',
|
|
348
|
-
unregisterByServer: true,
|
|
349
|
-
});
|
|
392
|
+
void teardownSessionResources(evicted, createSessionTeardownOptions('evicted'));
|
|
350
393
|
return true;
|
|
351
394
|
}
|
|
352
395
|
return false;
|
|
@@ -663,13 +706,7 @@ function createShutdownHandler(options) {
|
|
|
663
706
|
for (let i = 0; i < sessions.length; i += closeBatchSize) {
|
|
664
707
|
const batch = sessions.slice(i, i + closeBatchSize);
|
|
665
708
|
await Promise.all(batch.map(async (session) => {
|
|
666
|
-
await teardownSessionResources(session,
|
|
667
|
-
cancelMessage: 'The task was cancelled because the HTTP server is shutting down.',
|
|
668
|
-
closeTransportReason: 'shutdown-session-close',
|
|
669
|
-
closeServerReason: 'shutdown-session-close',
|
|
670
|
-
unregisterByServer: true,
|
|
671
|
-
awaitClose: true,
|
|
672
|
-
});
|
|
709
|
+
await teardownSessionResources(session, createSessionTeardownOptions('shutdown'));
|
|
673
710
|
}));
|
|
674
711
|
}
|
|
675
712
|
const { promise, resolve, reject } = Promise.withResolvers();
|
|
@@ -12,6 +12,7 @@ interface SessionTeardownOptions {
|
|
|
12
12
|
awaitClose?: boolean;
|
|
13
13
|
}
|
|
14
14
|
export declare function teardownSessionResources(session: SessionRecordLike, options: SessionTeardownOptions): Promise<void>;
|
|
15
|
+
export declare function teardownUnregisteredSessionResources(session: SessionRecordLike, context: string): Promise<void>;
|
|
15
16
|
export declare function teardownSessionRegistration(server: McpServer, cancelMessage: string): void;
|
|
16
17
|
export {};
|
|
17
18
|
//# sourceMappingURL=session-teardown.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-teardown.d.ts","sourceRoot":"","sources":["../../src/http/session-teardown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAcxG,UAAU,iBAAiB;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,6BAA6B,CAAC;CAC1C;AAED,UAAU,sBAAsB;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"session-teardown.d.ts","sourceRoot":"","sources":["../../src/http/session-teardown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAcxG,UAAU,iBAAiB;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,6BAA6B,CAAC;CAC1C;AAED,UAAU,sBAAsB;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAqCD,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,wBAAsB,oCAAoC,CACxD,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EACjB,aAAa,EAAE,MAAM,GACpB,IAAI,CAEN"}
|
|
@@ -9,11 +9,7 @@ function cancelSessionTasks(server, message) {
|
|
|
9
9
|
unregisterMcpSessionServer(sessionId);
|
|
10
10
|
return sessionId;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
cancelSessionTasks(session.server, options.cancelMessage);
|
|
14
|
-
if (options.unregisterByServer) {
|
|
15
|
-
unregisterMcpSessionServerByServer(session.server);
|
|
16
|
-
}
|
|
12
|
+
async function closeSessionResources(session, options) {
|
|
17
13
|
const closeTasks = [];
|
|
18
14
|
if (options.closeTransportReason) {
|
|
19
15
|
closeTasks.push(closeTransportBestEffort(session.transport, options.closeTransportReason));
|
|
@@ -25,6 +21,20 @@ export async function teardownSessionResources(session, options) {
|
|
|
25
21
|
await Promise.all(closeTasks);
|
|
26
22
|
}
|
|
27
23
|
}
|
|
24
|
+
export async function teardownSessionResources(session, options) {
|
|
25
|
+
cancelSessionTasks(session.server, options.cancelMessage);
|
|
26
|
+
if (options.unregisterByServer) {
|
|
27
|
+
unregisterMcpSessionServerByServer(session.server);
|
|
28
|
+
}
|
|
29
|
+
await closeSessionResources(session, options);
|
|
30
|
+
}
|
|
31
|
+
export async function teardownUnregisteredSessionResources(session, context) {
|
|
32
|
+
await closeSessionResources(session, {
|
|
33
|
+
closeTransportReason: context,
|
|
34
|
+
closeServerReason: context,
|
|
35
|
+
awaitClose: true,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
28
38
|
export function teardownSessionRegistration(server, cancelMessage) {
|
|
29
39
|
cancelSessionTasks(server, cancelMessage);
|
|
30
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-lang.d.ts","sourceRoot":"","sources":["../../src/lib/code-lang.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"code-lang.d.ts","sourceRoot":"","sources":["../../src/lib/code-lang.ts"],"names":[],"mappings":"AAoPA,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAuBpB;AAOD,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,SAAS,CAKpB;AACD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKvE"}
|
package/dist/lib/code-lang.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
const ASCII_SPACE = 32;
|
|
2
|
-
const ASCII_TAB = 9;
|
|
3
|
-
const ASCII_DIGIT_0 = 48;
|
|
4
|
-
const ASCII_DIGIT_9 = 57;
|
|
5
|
-
const ASCII_UPPER_A = 65;
|
|
6
|
-
const ASCII_UPPER_Z = 90;
|
|
7
|
-
const ASCII_LOWER_A = 97;
|
|
8
|
-
const ASCII_LOWER_Z = 122;
|
|
9
|
-
const ASCII_UNDERSCORE = 95;
|
|
10
1
|
class DetectionContext {
|
|
11
2
|
code;
|
|
12
3
|
_lower;
|
|
@@ -16,16 +7,13 @@ class DetectionContext {
|
|
|
16
7
|
this.code = code;
|
|
17
8
|
}
|
|
18
9
|
get lower() {
|
|
19
|
-
this._lower ??= this.code.toLowerCase();
|
|
20
|
-
return this._lower;
|
|
10
|
+
return (this._lower ??= this.code.toLowerCase());
|
|
21
11
|
}
|
|
22
12
|
get lines() {
|
|
23
|
-
this._lines ??= this.code.split(/\r?\n/);
|
|
24
|
-
return this._lines;
|
|
13
|
+
return (this._lines ??= this.code.split(/\r?\n/));
|
|
25
14
|
}
|
|
26
15
|
get trimmedStart() {
|
|
27
|
-
this._trimmedStart ??= this.code.trimStart();
|
|
28
|
-
return this._trimmedStart;
|
|
16
|
+
return (this._trimmedStart ??= this.code.trimStart());
|
|
29
17
|
}
|
|
30
18
|
}
|
|
31
19
|
const BASH_COMMANDS = new Set([
|
|
@@ -91,9 +79,8 @@ function containsJsxTag(code) {
|
|
|
91
79
|
}
|
|
92
80
|
function isBashLine(line) {
|
|
93
81
|
const trimmed = line.trimStart();
|
|
94
|
-
if (trimmed
|
|
82
|
+
if (!trimmed)
|
|
95
83
|
return false;
|
|
96
|
-
// Shell Prefix
|
|
97
84
|
if (trimmed.startsWith('#!') ||
|
|
98
85
|
trimmed.startsWith('$ ') ||
|
|
99
86
|
WINDOWS_SHELL_PROMPT_REGEX.test(trimmed)) {
|
|
@@ -103,24 +90,19 @@ function isBashLine(line) {
|
|
|
103
90
|
const firstWord = spaceIdx === -1 ? trimmed : trimmed.slice(0, spaceIdx);
|
|
104
91
|
if (BASH_COMMANDS.has(firstWord))
|
|
105
92
|
return true;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (isPkgMgr && spaceIdx !== -1)
|
|
109
|
-
return true;
|
|
110
|
-
return false;
|
|
93
|
+
return (spaceIdx !== -1 &&
|
|
94
|
+
BASH_PACKAGE_MANAGERS.includes(firstWord));
|
|
111
95
|
}
|
|
112
96
|
function detectBashIndicators(lines) {
|
|
113
|
-
return lines.some(
|
|
97
|
+
return lines.some(isBashLine);
|
|
114
98
|
}
|
|
115
99
|
function detectCssStructure(lines) {
|
|
116
100
|
for (const line of lines) {
|
|
117
101
|
const trimmed = line.trimStart();
|
|
118
|
-
if (trimmed.
|
|
102
|
+
if (!trimmed || trimmed.startsWith('# ') || trimmed.startsWith('//')) {
|
|
119
103
|
continue;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const hasSelector = /^[.#][A-Za-z_-][\w-]*\s*\{/.test(trimmed);
|
|
123
|
-
if (hasSelector)
|
|
104
|
+
}
|
|
105
|
+
if (/^[.#][A-Za-z_-][\w-]*\s*\{/.test(trimmed))
|
|
124
106
|
return true;
|
|
125
107
|
if (trimmed.includes(';') &&
|
|
126
108
|
CSS_PROPERTY_REGEX.test(trimmed) &&
|
|
@@ -133,14 +115,12 @@ function detectCssStructure(lines) {
|
|
|
133
115
|
function detectYamlStructure(lines) {
|
|
134
116
|
for (const line of lines) {
|
|
135
117
|
const trimmed = line.trim();
|
|
136
|
-
if (trimmed.length === 0)
|
|
137
|
-
continue;
|
|
138
118
|
const colonIdx = trimmed.indexOf(':');
|
|
139
|
-
if (colonIdx
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
119
|
+
if (colonIdx > 0) {
|
|
120
|
+
const after = trimmed[colonIdx + 1];
|
|
121
|
+
if (after === ' ' || after === '\t')
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
144
124
|
}
|
|
145
125
|
return false;
|
|
146
126
|
}
|
|
@@ -167,14 +147,8 @@ function matchJsx(ctx) {
|
|
|
167
147
|
return containsJsxTag(ctx.code);
|
|
168
148
|
}
|
|
169
149
|
function matchTypeScript(ctx) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const l = ctx.lower;
|
|
173
|
-
for (const hint of TYPESCRIPT_HINTS) {
|
|
174
|
-
if (l.includes(hint))
|
|
175
|
-
return true;
|
|
176
|
-
}
|
|
177
|
-
return false;
|
|
150
|
+
return (/\b(?:interface|type)\b/.test(ctx.lower) ||
|
|
151
|
+
TYPESCRIPT_HINTS.some((hint) => ctx.lower.includes(hint)));
|
|
178
152
|
}
|
|
179
153
|
function matchSql(ctx) {
|
|
180
154
|
return /\b(?:select\s+(?:.+?\s+from|[\d*@])|insert\s+into|update\s+.+?\s+set|delete\s+from|create\s+(?:table|database|index|view|function|procedure|trigger|user|role)|alter\s+(?:table|database|index|view))\b/.test(ctx.lower);
|
|
@@ -188,39 +162,26 @@ function matchPython(ctx) {
|
|
|
188
162
|
if (matchHtml(ctx))
|
|
189
163
|
return false;
|
|
190
164
|
const l = ctx.lower;
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (ctx.code.includes('None') ||
|
|
205
|
-
ctx.code.includes('True') ||
|
|
206
|
-
ctx.code.includes('False')) {
|
|
165
|
+
const c = ctx.code;
|
|
166
|
+
if (PYTHON_REPL_PROMPT_REGEX.test(c) ||
|
|
167
|
+
PYTHON_OUTPUT_HINT_REGEX.test(c) ||
|
|
168
|
+
/^\s*[A-Za-z_][\w.]*\s*=\s*[A-Z][\w.]*\(/m.test(c) ||
|
|
169
|
+
/^\s*[A-Za-z_][\w.]*\.[A-Za-z_][\w]*\s*$/m.test(c) ||
|
|
170
|
+
c.includes('None') ||
|
|
171
|
+
c.includes('True') ||
|
|
172
|
+
c.includes('False') ||
|
|
173
|
+
l.includes('print(') ||
|
|
174
|
+
l.includes('__name__') ||
|
|
175
|
+
l.includes('self.') ||
|
|
176
|
+
l.includes('elif ') ||
|
|
177
|
+
PYTHON_UNIQUE_REGEX.test(l)) {
|
|
207
178
|
return true;
|
|
208
179
|
}
|
|
209
|
-
if (PYTHON_UNIQUE_REGEX.test(l))
|
|
210
|
-
return true;
|
|
211
180
|
// Shared keywords (import, from, class) — only match if no JS signals present
|
|
212
|
-
|
|
213
|
-
return true;
|
|
214
|
-
}
|
|
215
|
-
return false;
|
|
181
|
+
return /\b(?:import|from|class)\b/.test(l) && !hasJsSignals(l);
|
|
216
182
|
}
|
|
217
183
|
function matchHtml(ctx) {
|
|
218
|
-
|
|
219
|
-
for (const tag of HTML_TAGS) {
|
|
220
|
-
if (l.includes(tag))
|
|
221
|
-
return true;
|
|
222
|
-
}
|
|
223
|
-
return false;
|
|
184
|
+
return HTML_TAGS.some((tag) => ctx.lower.includes(tag));
|
|
224
185
|
}
|
|
225
186
|
// Pre-sorted by weight descending — first match wins in detectLanguageFromCode
|
|
226
187
|
const LANGUAGES = [
|
|
@@ -273,43 +234,15 @@ export function extractLanguageFromClassName(className) {
|
|
|
273
234
|
}
|
|
274
235
|
function resolveLanguageFromDataAttribute(dataLang) {
|
|
275
236
|
const trimmed = dataLang.trim();
|
|
276
|
-
|
|
277
|
-
return undefined;
|
|
278
|
-
// Check if \w+
|
|
279
|
-
for (let i = 0; i < trimmed.length; i++) {
|
|
280
|
-
const c = trimmed.charCodeAt(i);
|
|
281
|
-
const isUpper = c >= ASCII_UPPER_A && c <= ASCII_UPPER_Z;
|
|
282
|
-
const isLower = c >= ASCII_LOWER_A && c <= ASCII_LOWER_Z;
|
|
283
|
-
const isDigit = c >= ASCII_DIGIT_0 && c <= ASCII_DIGIT_9;
|
|
284
|
-
const isUnder = c === ASCII_UNDERSCORE;
|
|
285
|
-
if (!isUpper && !isLower && !isDigit && !isUnder) {
|
|
286
|
-
return undefined;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
return trimmed;
|
|
237
|
+
return /^\w+$/.test(trimmed) ? trimmed : undefined;
|
|
290
238
|
}
|
|
291
239
|
export function resolveLanguageFromAttributes(className, dataLang) {
|
|
292
240
|
return (extractLanguageFromClassName(className) ??
|
|
293
241
|
resolveLanguageFromDataAttribute(dataLang));
|
|
294
242
|
}
|
|
295
243
|
export function detectLanguageFromCode(code) {
|
|
296
|
-
if (!code)
|
|
297
|
-
return undefined;
|
|
298
|
-
// Fast path for empty/whitespace only
|
|
299
|
-
let empty = true;
|
|
300
|
-
for (let i = 0; i < code.length; i++) {
|
|
301
|
-
if (code.charCodeAt(i) > ASCII_SPACE) {
|
|
302
|
-
empty = false;
|
|
303
|
-
break;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
if (empty)
|
|
244
|
+
if (!code || !/\S/.test(code))
|
|
307
245
|
return undefined;
|
|
308
246
|
const ctx = new DetectionContext(code);
|
|
309
|
-
|
|
310
|
-
for (const def of LANGUAGES) {
|
|
311
|
-
if (def.match(ctx))
|
|
312
|
-
return def.lang;
|
|
313
|
-
}
|
|
314
|
-
return undefined;
|
|
247
|
+
return LANGUAGES.find((def) => def.match(ctx))?.lang;
|
|
315
248
|
}
|
package/dist/lib/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AASjD,eAAO,MAAM,aAAa,EAAE,MAA2C,CAAC;AACxE,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AACpD,KAAK,WAAW,GACZ,OAAO,GACP,MAAM,GACN,QAAQ,GACR,SAAS,GACT,OAAO,GACP,UAAU,GACV,OAAO,GACP,WAAW,CAAC;AAwBhB,KAAK,mBAAmB,GAAG,SAAS,GAAG,SAAS,CAAC;AACjD,KAAK,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"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"}
|