agentic-mermaid 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/agent-core.d.ts +2 -2
  3. package/dist/agent-core.js +2 -2
  4. package/dist/agent.d.ts +2 -2
  5. package/dist/agent.js +4 -4
  6. package/dist/agentic-mermaid-mcp.js +5 -5
  7. package/dist/am.js +6 -6
  8. package/dist/browser-lazy/chunks/{architecture-3CGEU363.js → architecture-WMSX5L4P.js} +1 -1
  9. package/dist/browser-lazy/chunks/{chunk-RVO6J7S3.js → chunk-32FWKUUV.js} +1 -1
  10. package/dist/browser-lazy/chunks/{chunk-KTTWXSIX.js → chunk-ANTNEVJC.js} +1 -1
  11. package/dist/browser-lazy/chunks/{chunk-DPSSG7LR.js → chunk-AOCFMYYH.js} +1 -1
  12. package/dist/browser-lazy/chunks/{chunk-2U4EUPSI.js → chunk-CCTZFX43.js} +1 -1
  13. package/dist/browser-lazy/chunks/{chunk-PXRUFH7U.js → chunk-EBPTM2RP.js} +1 -1
  14. package/dist/browser-lazy/chunks/{chunk-FXBBGAMJ.js → chunk-EX6TP7QM.js} +1 -1
  15. package/dist/browser-lazy/chunks/{chunk-MMWVZP6M.js → chunk-QMZ4Y6I7.js} +1 -1
  16. package/dist/browser-lazy/chunks/{chunk-4IUBLBJJ.js → chunk-QYJMRNS3.js} +1 -1
  17. package/dist/browser-lazy/chunks/{chunk-6UT2VTFI.js → chunk-RLS545DI.js} +1 -1
  18. package/dist/browser-lazy/chunks/{chunk-VDTSULBU.js → chunk-TBZAU7KC.js} +1 -1
  19. package/dist/browser-lazy/chunks/{chunk-JX5ZZY3T.js → chunk-TDGTBGV3.js} +1 -1
  20. package/dist/browser-lazy/chunks/{chunk-HZ4ADQMK.js → chunk-TEH2PRKN.js} +1 -1
  21. package/dist/browser-lazy/chunks/{chunk-CTVVJPMX.js → chunk-W6Q4PHPC.js} +1 -1
  22. package/dist/browser-lazy/chunks/{chunk-4U2TVB2S.js → chunk-WN7SFUCZ.js} +1 -1
  23. package/dist/browser-lazy/chunks/{chunk-7D24ZLOV.js → chunk-ZZECLXC3.js} +1 -1
  24. package/dist/browser-lazy/chunks/{class-B3AVLSIF.js → class-7JRALQIM.js} +1 -1
  25. package/dist/browser-lazy/chunks/{er-AF4BKKKC.js → er-UDCGHKBX.js} +1 -1
  26. package/dist/browser-lazy/chunks/{flowchart-BE6BQZLZ.js → flowchart-5FP7RRIK.js} +1 -1
  27. package/dist/browser-lazy/chunks/{gantt-U4BMMSEL.js → gantt-NTOIC5CW.js} +1 -1
  28. package/dist/browser-lazy/chunks/{gitgraph-UPSWNFRP.js → gitgraph-JYAPXUIJ.js} +1 -1
  29. package/dist/browser-lazy/chunks/{journey-PDZ7FDJR.js → journey-646EFIB6.js} +1 -1
  30. package/dist/browser-lazy/chunks/{mindmap-BFEUURLS.js → mindmap-2SBTQHQO.js} +1 -1
  31. package/dist/browser-lazy/chunks/{pie-ZFYW5JZO.js → pie-7FDXZ24K.js} +1 -1
  32. package/dist/browser-lazy/chunks/{quadrant-XJVEYYXK.js → quadrant-72UT4XAW.js} +1 -1
  33. package/dist/browser-lazy/chunks/{radar-OVXFNRNC.js → radar-SU7BO56J.js} +1 -1
  34. package/dist/browser-lazy/chunks/{render-core-R4ZGGEFS.js → render-core-Q2JWXDDL.js} +2 -2
  35. package/dist/browser-lazy/chunks/{sequence-AWY6JCSB.js → sequence-5O5ET264.js} +1 -1
  36. package/dist/browser-lazy/chunks/{state-TCE4DXKR.js → state-IWPLFQ6R.js} +1 -1
  37. package/dist/browser-lazy/chunks/{timeline-W4ZVT3FF.js → timeline-WJWYHH5Y.js} +1 -1
  38. package/dist/browser-lazy/chunks/{xychart-K3QQACKS.js → xychart-HHQVQA5O.js} +1 -1
  39. package/dist/browser-lazy/index.js +1 -1
  40. package/dist/browser.global.js +2 -2
  41. package/dist/{chunk-XVY324NY.js → chunk-3D4EHVQ4.js} +5 -3
  42. package/dist/{chunk-BSVM3VMO.js → chunk-GX7UT56Q.js} +2 -2
  43. package/dist/{chunk-JJ7JRYZV.js → chunk-IVN6KP3W.js} +2 -2
  44. package/dist/{chunk-FGO3J7RA.js → chunk-NE6JBHSE.js} +680 -42
  45. package/dist/{chunk-KQMJ37OY.js → chunk-R5U67OIW.js} +4 -4
  46. package/dist/{chunk-MBIR6S3B.js → chunk-YWKCUBQN.js} +2 -2
  47. package/dist/{index-Do8z5rPq.d.ts → index-BFg_LoZS.d.ts} +1 -1
  48. package/dist/index.d.ts +1 -1
  49. package/dist/index.js +1 -1
  50. package/dist/mcp-cli-XGZP6CMW.js +17 -0
  51. package/docs/mcp-http-transport.md +2 -0
  52. package/package.json +5 -4
  53. package/server.json +2 -2
  54. package/dist/mcp-cli-7FLGTEG3.js +0 -17
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  projectKnownRenderErrorDiagnostic,
3
3
  projectRenderErrorDiagnostic
4
- } from "./chunk-JJ7JRYZV.js";
4
+ } from "./chunk-IVN6KP3W.js";
5
5
  import {
6
6
  renderMermaidPNG,
7
7
  renderMermaidPNGWithReceipt
8
- } from "./chunk-MBIR6S3B.js";
8
+ } from "./chunk-YWKCUBQN.js";
9
9
  import {
10
10
  analyzeMermaid,
11
11
  analyzeMermaidSource,
@@ -31,7 +31,7 @@ import {
31
31
  renderMermaidSVGWithReceipt,
32
32
  verifyMermaid,
33
33
  verifySummary
34
- } from "./chunk-BSVM3VMO.js";
34
+ } from "./chunk-GX7UT56Q.js";
35
35
  import {
36
36
  BUILTIN_FAMILY_METADATA,
37
37
  PACKAGE_VERSION,
@@ -71,13 +71,11 @@ import {
71
71
  styleSpecTypeScriptDeclaration,
72
72
  validateJsonConfigAdmission,
73
73
  validateSerializableRenderOptions
74
- } from "./chunk-XVY324NY.js";
74
+ } from "./chunk-3D4EHVQ4.js";
75
75
 
76
76
  // src/mcp/server.ts
77
77
  import { randomUUID as randomUUID2 } from "crypto";
78
78
  import { createServer } from "http";
79
- import { tmpdir as tmpdir2 } from "os";
80
- import { join as join2 } from "path";
81
79
  import { URL } from "url";
82
80
 
83
81
  // src/mcp/sandbox.ts
@@ -1214,7 +1212,7 @@ function preserveExactJsonRpcIds(body) {
1214
1212
  cursor++;
1215
1213
  while (/\s/.test(body[cursor] ?? "")) cursor++;
1216
1214
  const number = body.slice(cursor).match(/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/)?.[0];
1217
- if (number && !isSafelyRoundTrippableInteger(number)) {
1215
+ if (number && isIntegerNumberToken(number) && !isSafelyRoundTrippableInteger(number)) {
1218
1216
  let sentinel = `__agentic_mermaid_exact_id_${replacements.length}__`;
1219
1217
  while (body.includes(sentinel)) sentinel += "_";
1220
1218
  replacements.push({ sentinel, raw: number, start: cursor, end: cursor + number.length });
@@ -1233,6 +1231,10 @@ function preserveExactJsonRpcIds(body) {
1233
1231
  }
1234
1232
  return { body: protectedBody, ids: replacements.map(({ sentinel, raw }) => ({ sentinel, raw })) };
1235
1233
  }
1234
+ function isIntegerNumberToken(token) {
1235
+ const value = Number(token);
1236
+ return Number.isFinite(value) && Number.isInteger(value);
1237
+ }
1236
1238
  function isSafelyRoundTrippableInteger(token) {
1237
1239
  if (!/^-?(?:0|[1-9]\d*)$/.test(token)) return false;
1238
1240
  if (token === "-0") return false;
@@ -1259,8 +1261,338 @@ function stringifyJsonRpc(payload, exactIds = []) {
1259
1261
  function reply(id, result) {
1260
1262
  return { jsonrpc: "2.0", id, result };
1261
1263
  }
1262
- function rpcError(id, code, message) {
1263
- return { jsonrpc: "2.0", id, error: { code, message } };
1264
+ function rpcError(id, code, message, data) {
1265
+ return { jsonrpc: "2.0", id, error: data === void 0 ? { code, message } : { code, message, data } };
1266
+ }
1267
+ function toolResult(id, payload, isError) {
1268
+ return reply(id, { content: [{ type: "text", text: JSON.stringify(payload) }], isError });
1269
+ }
1270
+
1271
+ // src/mcp/protocol-versions.ts
1272
+ var LEGACY_PROTOCOL_VERSIONS = ["2024-11-05", "2025-03-26", "2025-06-18", "2025-11-25"];
1273
+ var MODERN_PROTOCOL_VERSIONS = ["2026-07-28"];
1274
+ var META_PROTOCOL_VERSION = "io.modelcontextprotocol/protocolVersion";
1275
+ var META_CLIENT_INFO = "io.modelcontextprotocol/clientInfo";
1276
+ var META_CLIENT_CAPABILITIES = "io.modelcontextprotocol/clientCapabilities";
1277
+ var META_LOG_LEVEL = "io.modelcontextprotocol/logLevel";
1278
+ var META_SERVER_INFO = "io.modelcontextprotocol/serverInfo";
1279
+ var HEADER_MISMATCH = -32020;
1280
+ var UNSUPPORTED_PROTOCOL_VERSION = -32022;
1281
+ var TOOL_ERROR_VALIDATION_SINCE = "2025-11-25";
1282
+ function isModernProtocolVersion(version) {
1283
+ return typeof version === "string" && MODERN_PROTOCOL_VERSIONS.includes(version);
1284
+ }
1285
+ function isLegacyProtocolVersion(version) {
1286
+ return typeof version === "string" && LEGACY_PROTOCOL_VERSIONS.includes(version);
1287
+ }
1288
+ function usesToolErrorForInvalidArguments(version) {
1289
+ return typeof version === "string" && version >= TOOL_ERROR_VALIDATION_SINCE;
1290
+ }
1291
+ function paramsMeta(req) {
1292
+ const params = req.params;
1293
+ if (!params || typeof params !== "object" || Array.isArray(params)) return void 0;
1294
+ const meta = params._meta;
1295
+ if (!meta || typeof meta !== "object" || Array.isArray(meta)) return void 0;
1296
+ return meta;
1297
+ }
1298
+ function requestMetaProtocolVersion(req) {
1299
+ const claim = requestMetaProtocolVersionClaim(req);
1300
+ const value = claim.present ? claim.value : void 0;
1301
+ return typeof value === "string" ? value : void 0;
1302
+ }
1303
+ function requestMetaProtocolVersionClaim(req) {
1304
+ const meta = paramsMeta(req);
1305
+ if (!meta || !Object.prototype.hasOwnProperty.call(meta, META_PROTOCOL_VERSION)) return { present: false };
1306
+ return { present: true, value: meta[META_PROTOCOL_VERSION] };
1307
+ }
1308
+ function mcpImplementationProblems(value, path) {
1309
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
1310
+ return [`${path} is required and must be an object with name and version`];
1311
+ }
1312
+ const problems = [];
1313
+ const info = value;
1314
+ if (typeof info.name !== "string") problems.push(`${path}.name is required and must be a string`);
1315
+ if (typeof info.version !== "string") problems.push(`${path}.version is required and must be a string`);
1316
+ for (const key of ["title", "description", "websiteUrl"]) {
1317
+ if (info[key] !== void 0 && typeof info[key] !== "string") {
1318
+ problems.push(`${path}.${key} must be a string when present`);
1319
+ }
1320
+ }
1321
+ if (info.icons !== void 0) {
1322
+ if (!Array.isArray(info.icons)) {
1323
+ problems.push(`${path}.icons must be an array when present`);
1324
+ } else {
1325
+ for (const [index, icon] of info.icons.entries()) {
1326
+ if (!icon || typeof icon !== "object" || Array.isArray(icon)) {
1327
+ problems.push(`${path}.icons[${index}] must be an object`);
1328
+ continue;
1329
+ }
1330
+ const record = icon;
1331
+ if (typeof record.src !== "string") problems.push(`${path}.icons[${index}].src is required and must be a string`);
1332
+ if (record.mimeType !== void 0 && typeof record.mimeType !== "string") problems.push(`${path}.icons[${index}].mimeType must be a string when present`);
1333
+ if (record.sizes !== void 0 && (!Array.isArray(record.sizes) || record.sizes.some((size) => typeof size !== "string"))) {
1334
+ problems.push(`${path}.icons[${index}].sizes must be an array of strings when present`);
1335
+ }
1336
+ if (record.theme !== void 0 && record.theme !== "light" && record.theme !== "dark") {
1337
+ problems.push(`${path}.icons[${index}].theme must be light or dark when present`);
1338
+ }
1339
+ }
1340
+ }
1341
+ }
1342
+ return problems;
1343
+ }
1344
+ function mcpClientCapabilitiesProblems(value, path) {
1345
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1346
+ return [`${path} is required and must be an object (an empty object declares no optional capabilities)`];
1347
+ }
1348
+ const problems = [];
1349
+ const record = value;
1350
+ const objectMember = (key) => {
1351
+ const member = record[key];
1352
+ if (member === void 0) return void 0;
1353
+ if (typeof member !== "object" || member === null || Array.isArray(member)) {
1354
+ problems.push(`${path}.${key} must be an object when present`);
1355
+ return void 0;
1356
+ }
1357
+ return member;
1358
+ };
1359
+ const roots = objectMember("roots");
1360
+ if (roots?.listChanged !== void 0 && typeof roots.listChanged !== "boolean") {
1361
+ problems.push(`${path}.roots.listChanged must be a boolean when present`);
1362
+ }
1363
+ const sampling = objectMember("sampling");
1364
+ for (const key of ["context", "tools"]) {
1365
+ const member = sampling?.[key];
1366
+ if (member !== void 0 && (typeof member !== "object" || member === null || Array.isArray(member))) {
1367
+ problems.push(`${path}.sampling.${key} must be an object when present`);
1368
+ }
1369
+ }
1370
+ const elicitation = objectMember("elicitation");
1371
+ for (const key of ["form", "url"]) {
1372
+ const member = elicitation?.[key];
1373
+ if (member !== void 0 && (typeof member !== "object" || member === null || Array.isArray(member))) {
1374
+ problems.push(`${path}.elicitation.${key} must be an object when present`);
1375
+ }
1376
+ }
1377
+ for (const key of ["experimental", "extensions"]) {
1378
+ const entries = objectMember(key);
1379
+ if (!entries) continue;
1380
+ for (const [name, member] of Object.entries(entries)) {
1381
+ if (key === "extensions" && !/^[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?\/.+/.test(name)) {
1382
+ problems.push(`${path}.extensions.${name} must use a namespaced key with a prefix`);
1383
+ }
1384
+ if (typeof member !== "object" || member === null || Array.isArray(member)) {
1385
+ problems.push(`${path}.${key}.${name} must be an object`);
1386
+ }
1387
+ }
1388
+ }
1389
+ return problems;
1390
+ }
1391
+ function modernRequestMetaProblems(req) {
1392
+ const meta = paramsMeta(req);
1393
+ if (!meta) return [`params._meta is required and must carry ${META_PROTOCOL_VERSION} and ${META_CLIENT_CAPABILITIES}`];
1394
+ const problems = [];
1395
+ const clientInfo = meta[META_CLIENT_INFO];
1396
+ if (clientInfo !== void 0) {
1397
+ problems.push(...mcpImplementationProblems(clientInfo, `params._meta.${META_CLIENT_INFO}`));
1398
+ }
1399
+ const logLevel = meta[META_LOG_LEVEL];
1400
+ if (logLevel !== void 0 && (typeof logLevel !== "string" || !["debug", "info", "notice", "warning", "error", "critical", "alert", "emergency"].includes(logLevel))) {
1401
+ problems.push(`params._meta.${META_LOG_LEVEL} must be a valid logging level when present`);
1402
+ }
1403
+ const capabilities = meta[META_CLIENT_CAPABILITIES];
1404
+ problems.push(...mcpClientCapabilitiesProblems(capabilities, `params._meta.${META_CLIENT_CAPABILITIES}`));
1405
+ return problems;
1406
+ }
1407
+
1408
+ // src/mcp/admission.ts
1409
+ var admittedMcpMessage = /* @__PURE__ */ Symbol("AdmittedMcpMessage");
1410
+ function admitMcpHeaderVersion(headerVersion, supportedVersions) {
1411
+ if (headerVersion === null || supportedVersions.includes(headerVersion)) return null;
1412
+ return {
1413
+ ok: false,
1414
+ kind: "unsupported-version",
1415
+ response: rpcError(
1416
+ null,
1417
+ UNSUPPORTED_PROTOCOL_VERSION,
1418
+ `Unsupported protocol version: ${headerVersion}`,
1419
+ { supported: [...supportedVersions], requested: headerVersion }
1420
+ )
1421
+ };
1422
+ }
1423
+ function responseId(raw, validId) {
1424
+ const value = raw.id;
1425
+ return validId && value !== void 0 ? value : null;
1426
+ }
1427
+ function rejection(kind, notification, response, protocol, requestedEra) {
1428
+ return {
1429
+ ok: false,
1430
+ kind,
1431
+ response: notification ? null : response,
1432
+ ...protocol ? { protocol } : {},
1433
+ ...requestedEra ? { requestedEra } : {}
1434
+ };
1435
+ }
1436
+ function acceptance(request, id, notification, protocol) {
1437
+ const base = { request, id, protocol, [admittedMcpMessage]: true };
1438
+ return notification ? { ok: true, message: { ...base, notification: true } } : { ok: true, message: { ...base, notification: false } };
1439
+ }
1440
+ function admitMcpMessage(rawMessage, options) {
1441
+ const raw = rawMessage;
1442
+ const hasId = Boolean(raw && Object.prototype.hasOwnProperty.call(raw, "id"));
1443
+ const rawId = raw?.id;
1444
+ const validId = rawId === void 0 || typeof rawId === "string" || typeof rawId === "number" && Number.isSafeInteger(rawId);
1445
+ const validEnvelope = Boolean(raw && !Array.isArray(raw) && raw.jsonrpc === "2.0" && typeof raw.method === "string" && validId);
1446
+ if (!validEnvelope) {
1447
+ return { ok: false, kind: "invalid-request", response: rpcError(null, -32600, "invalid JSON-RPC request") };
1448
+ }
1449
+ const request = rawMessage;
1450
+ const id = responseId(raw, validId);
1451
+ const notification = !hasId;
1452
+ const versionClaim = requestMetaProtocolVersionClaim(request);
1453
+ const declaredVersion = requestMetaProtocolVersion(request);
1454
+ const requestedEra = versionClaim.present ? "modern" : "legacy";
1455
+ const supportedVersions = options.protocolEra === "legacy" ? options.supportedVersions.filter(isLegacyProtocolVersion) : options.protocolEra === "modern" ? options.supportedVersions.filter(isModernProtocolVersion) : [...options.supportedVersions];
1456
+ const effectiveTransportVersion = options.negotiatedVersion ?? options.headerVersion ?? void 0;
1457
+ const provisionalProtocol = isModernProtocolVersion(declaredVersion) ? { era: "modern", version: declaredVersion, supportedVersions } : { era: "legacy", version: declaredVersion ?? effectiveTransportVersion, supportedVersions };
1458
+ const headerAdmission = admitMcpHeaderVersion(options.headerVersion ?? null, supportedVersions);
1459
+ if (headerAdmission) {
1460
+ return { ...headerAdmission, protocol: provisionalProtocol, requestedEra };
1461
+ }
1462
+ if (versionClaim.present && typeof versionClaim.value !== "string") {
1463
+ return rejection(
1464
+ "invalid-modern-metadata",
1465
+ notification,
1466
+ rpcError(id, -32602, `Invalid params: params._meta.${META_PROTOCOL_VERSION} is required and must be a string`),
1467
+ void 0,
1468
+ "modern"
1469
+ );
1470
+ }
1471
+ if (options.negotiatedVersion != null && !supportedVersions.includes(options.negotiatedVersion)) {
1472
+ return rejection(
1473
+ "unsupported-version",
1474
+ notification,
1475
+ rpcError(
1476
+ id,
1477
+ UNSUPPORTED_PROTOCOL_VERSION,
1478
+ `Unsupported protocol version: ${options.negotiatedVersion}`,
1479
+ { supported: [...supportedVersions], requested: options.negotiatedVersion }
1480
+ ),
1481
+ provisionalProtocol,
1482
+ requestedEra
1483
+ );
1484
+ }
1485
+ if (declaredVersion !== void 0 && options.headerVersion != null && declaredVersion !== options.headerVersion) {
1486
+ return rejection(
1487
+ "header-mismatch",
1488
+ notification,
1489
+ rpcError(
1490
+ id,
1491
+ HEADER_MISMATCH,
1492
+ `Header mismatch: MCP-Protocol-Version header value '${options.headerVersion}' does not match body value '${declaredVersion}'`
1493
+ ),
1494
+ provisionalProtocol,
1495
+ requestedEra
1496
+ );
1497
+ }
1498
+ if (options.protocolEra !== void 0 && requestedEra !== options.protocolEra) {
1499
+ const requested = declaredVersion ?? effectiveTransportVersion ?? "unversioned";
1500
+ return rejection(
1501
+ "unsupported-version",
1502
+ notification,
1503
+ rpcError(
1504
+ id,
1505
+ UNSUPPORTED_PROTOCOL_VERSION,
1506
+ `Unsupported protocol version: ${requested}`,
1507
+ { supported: [...supportedVersions], requested }
1508
+ ),
1509
+ provisionalProtocol,
1510
+ requestedEra
1511
+ );
1512
+ }
1513
+ if (requestedEra === "modern" && isLegacyProtocolVersion(declaredVersion) && (!options.requireModernVersionHeader || options.headerVersion != null)) {
1514
+ const modernSupportedVersions = supportedVersions.filter(isModernProtocolVersion);
1515
+ return rejection(
1516
+ "unsupported-version",
1517
+ notification,
1518
+ rpcError(
1519
+ id,
1520
+ UNSUPPORTED_PROTOCOL_VERSION,
1521
+ `Unsupported protocol version: ${declaredVersion}`,
1522
+ { supported: modernSupportedVersions, requested: declaredVersion }
1523
+ ),
1524
+ provisionalProtocol,
1525
+ requestedEra
1526
+ );
1527
+ }
1528
+ if (declaredVersion !== void 0 && !supportedVersions.includes(declaredVersion)) {
1529
+ return rejection(
1530
+ "unsupported-version",
1531
+ notification,
1532
+ rpcError(
1533
+ id,
1534
+ UNSUPPORTED_PROTOCOL_VERSION,
1535
+ `Unsupported protocol version: ${declaredVersion}`,
1536
+ { supported: [...supportedVersions], requested: declaredVersion }
1537
+ ),
1538
+ provisionalProtocol,
1539
+ requestedEra
1540
+ );
1541
+ }
1542
+ const era = options.protocolEra ?? (isModernProtocolVersion(options.headerVersion) || isModernProtocolVersion(options.negotiatedVersion) ? "modern" : requestedEra);
1543
+ if (era === "modern") {
1544
+ if (!isModernProtocolVersion(declaredVersion)) {
1545
+ const problem = `params._meta.${META_PROTOCOL_VERSION} is required and must match the MCP-Protocol-Version header (${options.headerVersion})`;
1546
+ return rejection(
1547
+ "header-mismatch",
1548
+ notification,
1549
+ rpcError(id, HEADER_MISMATCH, `Header mismatch: ${problem}`),
1550
+ provisionalProtocol,
1551
+ requestedEra
1552
+ );
1553
+ }
1554
+ const protocol2 = { era: "modern", version: declaredVersion, supportedVersions };
1555
+ if (options.requireModernVersionHeader && options.headerVersion == null) {
1556
+ return rejection(
1557
+ "header-mismatch",
1558
+ notification,
1559
+ rpcError(
1560
+ id,
1561
+ HEADER_MISMATCH,
1562
+ `Header mismatch: MCP-Protocol-Version header is required for protocol version ${declaredVersion}`
1563
+ ),
1564
+ protocol2,
1565
+ requestedEra
1566
+ );
1567
+ }
1568
+ const transportProblem = options.modernTransportProblem?.(request) ?? null;
1569
+ if (transportProblem !== null) {
1570
+ return rejection(
1571
+ "header-mismatch",
1572
+ notification,
1573
+ rpcError(id, HEADER_MISMATCH, `Header mismatch: ${transportProblem}`),
1574
+ protocol2,
1575
+ requestedEra
1576
+ );
1577
+ }
1578
+ const metaProblems = modernRequestMetaProblems(request);
1579
+ if (metaProblems.length > 0) {
1580
+ return rejection(
1581
+ "invalid-modern-metadata",
1582
+ notification,
1583
+ rpcError(id, -32602, `Invalid params: ${metaProblems.join("; ")}`),
1584
+ protocol2,
1585
+ requestedEra
1586
+ );
1587
+ }
1588
+ return acceptance(request, id, notification, protocol2);
1589
+ }
1590
+ const protocol = {
1591
+ era: "legacy",
1592
+ version: declaredVersion ?? effectiveTransportVersion,
1593
+ supportedVersions
1594
+ };
1595
+ return acceptance(request, id, notification, protocol);
1264
1596
  }
1265
1597
 
1266
1598
  // src/mcp/tool-surface.ts
@@ -1269,6 +1601,7 @@ function withClosedMcpInputSchema(tool) {
1269
1601
  }
1270
1602
  var MCP_SERVER_NAME = "agentic-mermaid-mcp";
1271
1603
  var MCP_SERVER_VERSION = PACKAGE_VERSION;
1604
+ var SERVER_CAPABILITIES = { tools: {}, prompts: {}, resources: {} };
1272
1605
  var PURE_COMPUTE_ANNOTATIONS = {
1273
1606
  readOnlyHint: true,
1274
1607
  destructiveHint: false,
@@ -1476,32 +1809,66 @@ function validateMcpToolArguments(tool, value) {
1476
1809
  const problems = validateSchemaValue(value, tool.inputSchema, tool.inputSchema, [], /* @__PURE__ */ new Set()).map((problem) => `${formatSchemaPath(problem.path)} ${problem.message}`);
1477
1810
  return limitJsonConfigDiagnostics(problems, "arguments");
1478
1811
  }
1479
- async function dispatchMcpRequest(req, context, surface) {
1480
- const raw = req;
1481
- const hasId = Boolean(raw && Object.prototype.hasOwnProperty.call(raw, "id"));
1482
- const rawId = raw?.id;
1483
- const validId = rawId === void 0 || rawId === null || typeof rawId === "string" || typeof rawId === "number" && Number.isFinite(rawId);
1484
- const valid = Boolean(raw && raw.jsonrpc === "2.0" && typeof raw.method === "string" && validId);
1485
- const id = validId && rawId !== void 0 ? rawId : null;
1486
- if (!valid) return rpcError(null, -32600, "invalid JSON-RPC request");
1487
- const notification = !hasId;
1812
+ function surfaceSupportedVersions(surface, options = {}) {
1813
+ const surfaceVersions = surface.supportedVersions ?? (typeof surface.protocolVersion === "string" ? [surface.protocolVersion] : []);
1814
+ if (!options.supportedVersions) return surfaceVersions;
1815
+ return surfaceVersions.filter((version) => options.supportedVersions.includes(version));
1816
+ }
1817
+ function discoverResult(surface, supportedVersions) {
1818
+ return {
1819
+ supportedVersions: supportedVersions.filter(isModernProtocolVersion),
1820
+ capabilities: SERVER_CAPABILITIES,
1821
+ instructions: surface.instructions
1822
+ };
1823
+ }
1824
+ function initializeParamsProblems(params) {
1825
+ if (!plainJsonObject(params)) return ["params is required and must be an object"];
1826
+ const problems = [];
1827
+ if (typeof params.protocolVersion !== "string") {
1828
+ problems.push("params.protocolVersion is required and must be a string");
1829
+ }
1830
+ problems.push(...mcpClientCapabilitiesProblems(params.capabilities, "params.capabilities"));
1831
+ problems.push(...mcpImplementationProblems(params.clientInfo, "params.clientInfo"));
1832
+ return problems;
1833
+ }
1834
+ async function dispatchAdmittedMcpRequest(message, context, surface) {
1835
+ const { request: req, id, notification, protocol } = message;
1836
+ const { era, version, supportedVersions: servedVersions } = protocol;
1488
1837
  let response;
1489
1838
  switch (req.method) {
1839
+ // initialize / notifications/initialized / ping are REMOVED in the modern
1840
+ // era. Under a modern request they are simply unknown methods; a legacy
1841
+ // request keeps the handshake it depends on.
1490
1842
  case "initialize": {
1491
- const protocolVersion = typeof surface.protocolVersion === "function" ? surface.protocolVersion(req.params) : surface.protocolVersion;
1843
+ if (era === "modern") {
1844
+ response = unknownMethod(id, req.method);
1845
+ break;
1846
+ }
1847
+ const problems = initializeParamsProblems(req.params);
1848
+ if (problems.length > 0) {
1849
+ response = rpcError(id, -32602, `Invalid params: ${problems.join("; ")}`);
1850
+ break;
1851
+ }
1852
+ const offered = req.params?.protocolVersion;
1853
+ const legacyServedVersions = servedVersions.filter(isLegacyProtocolVersion);
1854
+ const fallbackLegacyVersion = legacyServedVersions.at(-1) ?? (typeof surface.protocolVersion === "function" ? surface.protocolVersion(req.params) : surface.protocolVersion);
1855
+ const protocolVersion = isLegacyProtocolVersion(offered) && legacyServedVersions.includes(offered) ? offered : fallbackLegacyVersion;
1492
1856
  response = reply(id, {
1493
1857
  protocolVersion,
1494
1858
  serverInfo: { name: surface.serverName ?? MCP_SERVER_NAME, version: MCP_SERVER_VERSION },
1495
- capabilities: { tools: {} },
1859
+ capabilities: SERVER_CAPABILITIES,
1496
1860
  instructions: surface.instructions
1497
1861
  });
1498
1862
  break;
1499
1863
  }
1500
1864
  case "notifications/initialized":
1501
- response = null;
1865
+ response = era === "modern" ? unknownMethod(id, req.method) : null;
1502
1866
  break;
1503
1867
  case "ping":
1504
- response = reply(id, {});
1868
+ response = era === "modern" ? unknownMethod(id, req.method) : reply(id, {});
1869
+ break;
1870
+ case "server/discover":
1871
+ response = era === "modern" ? reply(id, discoverResult(surface, servedVersions)) : unknownMethod(id, req.method);
1505
1872
  break;
1506
1873
  case "tools/list":
1507
1874
  response = reply(id, { tools: surface.tools });
@@ -1524,7 +1891,8 @@ async function dispatchMcpRequest(req, context, surface) {
1524
1891
  const args = req.params.arguments ?? {};
1525
1892
  const problems = validateMcpToolArguments(tool, args);
1526
1893
  if (problems.length > 0) {
1527
- response = rpcError(id, -32602, `Invalid arguments for ${name}: ${problems.join("; ")}`);
1894
+ const message2 = `Invalid arguments for ${name}: ${problems.join("; ")}`;
1895
+ response = usesToolErrorForInvalidArguments(version) ? toolResult(id, { ok: false, error: { code: "INVALID_ARGUMENTS", message: message2 } }, true) : rpcError(id, -32602, message2);
1528
1896
  break;
1529
1897
  }
1530
1898
  response = await surface.handleToolCall(id, { ...req.params, arguments: args }, context);
@@ -1537,9 +1905,31 @@ async function dispatchMcpRequest(req, context, surface) {
1537
1905
  response = reply(id, { resources: [] });
1538
1906
  break;
1539
1907
  default:
1540
- response = rpcError(id, -32601, `Method not found: ${req.method}`);
1908
+ response = unknownMethod(id, req.method);
1909
+ }
1910
+ return notification ? null : decorateMcpResult(response, req.method, era, surface.serverName ?? MCP_SERVER_NAME);
1911
+ }
1912
+ var LIST_RESULT_TTL_MS = 3e5;
1913
+ var CACHEABLE_METHODS = /* @__PURE__ */ new Set(["server/discover", "tools/list", "prompts/list", "resources/list"]);
1914
+ function decorateMcpResult(response, method, era, serverName) {
1915
+ if (era !== "modern" || !response || !plainJsonObject(response.result)) return response;
1916
+ const existingMeta = plainJsonObject(response.result._meta) ? response.result._meta : {};
1917
+ const result = {
1918
+ resultType: "complete",
1919
+ ...response.result,
1920
+ _meta: {
1921
+ ...existingMeta,
1922
+ [META_SERVER_INFO]: { name: serverName, version: MCP_SERVER_VERSION }
1923
+ }
1924
+ };
1925
+ if (CACHEABLE_METHODS.has(method)) {
1926
+ result.ttlMs = LIST_RESULT_TTL_MS;
1927
+ result.cacheScope = "public";
1541
1928
  }
1542
- return notification ? null : response;
1929
+ return { ...response, result };
1930
+ }
1931
+ function unknownMethod(id, method) {
1932
+ return rpcError(id, -32601, `Method not found: ${method}`);
1543
1933
  }
1544
1934
  function createExecuteTool(options) {
1545
1935
  const hostedNote = options.hosted ? `Hosted note: execute runs in an on-demand isolate and costs more than the direct
@@ -2656,6 +3046,7 @@ import {
2656
3046
  readFileSync,
2657
3047
  readdirSync,
2658
3048
  renameSync,
3049
+ rmdirSync,
2659
3050
  unlinkSync,
2660
3051
  writeFileSync,
2661
3052
  writeSync
@@ -2669,7 +3060,12 @@ var DEFAULT_TTL_MS = 60 * 60 * 1e3;
2669
3060
  var MANIFEST_NAME = ".agentic-mermaid-artifacts-v1.json";
2670
3061
  var LOCK_NAME = ".agentic-mermaid-artifacts-v1.lock";
2671
3062
  var MAX_MANIFEST_BYTES = 1024 * 1024;
3063
+ var MAX_LOCK_BYTES = 4096;
2672
3064
  var MANAGED_NAME = /^[0-9a-z]+-[0-9a-f-]{36}\.[a-z0-9_-]+$/;
3065
+ var IMPLICIT_NAMESPACE = /^store-[1-9][0-9]*-[0-9a-f-]{36}$/;
3066
+ var LEGACY_IMPLICIT_NAMESPACE = /^agentic-mermaid-mcp-artifacts-[1-9][0-9]*-[0-9a-f-]{36}$/;
3067
+ var IMPLICIT_REAP_GRACE_MS = 3e4;
3068
+ var DEFAULT_ARTIFACT_ROOT = join(tmpdir(), "agentic-mermaid-mcp-artifacts");
2673
3069
  function positiveSafeInteger(value, field) {
2674
3070
  if (!Number.isSafeInteger(value) || value <= 0) throw new Error(`artifact ${field} must be a positive safe integer`);
2675
3071
  return value;
@@ -2689,7 +3085,9 @@ var ArtifactStore = class {
2689
3085
  lockFd = -1;
2690
3086
  closed = false;
2691
3087
  constructor(opts = {}) {
2692
- this.dir = resolve(opts.dir ?? join(tmpdir(), "agentic-mermaid-mcp-artifacts"));
3088
+ if (opts.dir !== void 0 && opts.namespaceRoot !== void 0) {
3089
+ throw new Error("artifact dir and namespaceRoot are mutually exclusive");
3090
+ }
2693
3091
  this.baseUrl = normalizeBaseUrl(opts.baseUrl);
2694
3092
  this.maxBytes = positiveSafeInteger(opts.maxBytes ?? DEFAULT_MAX_BYTES, "maxBytes");
2695
3093
  this.maxTotalBytes = positiveSafeInteger(opts.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES, "maxTotalBytes");
@@ -2697,7 +3095,23 @@ var ArtifactStore = class {
2697
3095
  this.ttlMs = positiveSafeInteger(opts.ttlMs ?? DEFAULT_TTL_MS, "ttlMs");
2698
3096
  if (this.maxBytes > this.maxTotalBytes) throw new Error("artifact maxBytes must not exceed maxTotalBytes");
2699
3097
  this.now = opts.now ?? (() => Date.now());
2700
- mkdirSync(this.dir, { recursive: true, mode: 448 });
3098
+ if (opts.dir !== void 0) {
3099
+ this.dir = resolve(opts.dir);
3100
+ mkdirSync(this.dir, { recursive: true, mode: 448 });
3101
+ } else {
3102
+ const root = resolve(opts.namespaceRoot ?? DEFAULT_ARTIFACT_ROOT);
3103
+ mkdirSync(root, { recursive: true, mode: 448 });
3104
+ const rootStat = lstatSync(root);
3105
+ if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) {
3106
+ throw new Error("artifact namespace root must be a real directory");
3107
+ }
3108
+ if (opts.namespaceRoot === void 0) {
3109
+ reapImplicitArtifactNamespaces(resolve(tmpdir()), this.now(), LEGACY_IMPLICIT_NAMESPACE);
3110
+ }
3111
+ reapImplicitArtifactNamespaces(root, this.now());
3112
+ this.dir = join(root, `store-${process.pid}-${randomUUID()}`);
3113
+ mkdirSync(this.dir, { mode: 448 });
3114
+ }
2701
3115
  this.manifestPath = join(this.dir, MANIFEST_NAME);
2702
3116
  this.lockPath = join(this.dir, LOCK_NAME);
2703
3117
  this.acquireOwnership();
@@ -2900,7 +3314,7 @@ var ArtifactStore = class {
2900
3314
  }
2901
3315
  let totalBytes = 0;
2902
3316
  for (const candidate of manifest.records) {
2903
- if (!candidate || typeof candidate !== "object" || typeof candidate.name !== "string" || !MANAGED_NAME.test(candidate.name) || typeof candidate.mimeType !== "string" || candidate.mimeType.length === 0 || !Number.isSafeInteger(candidate.bytes) || candidate.bytes < 0 || typeof candidate.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(candidate.sha256) || !Number.isSafeInteger(candidate.createdAt) || !Number.isSafeInteger(candidate.expiresAt) || candidate.expiresAt <= candidate.createdAt) {
3317
+ if (!isManifestRecord(candidate)) {
2904
3318
  throw new Error("artifact manifest contains an invalid record");
2905
3319
  }
2906
3320
  const path = safePath(this.dir, candidate.name);
@@ -2941,6 +3355,113 @@ var ArtifactStore = class {
2941
3355
  if (persist) this.persistManifest();
2942
3356
  }
2943
3357
  };
3358
+ function reapImplicitArtifactNamespaces(root, now, namespacePattern = IMPLICIT_NAMESPACE) {
3359
+ let entries;
3360
+ try {
3361
+ entries = readdirSync(root);
3362
+ } catch {
3363
+ return;
3364
+ }
3365
+ for (const name of entries) {
3366
+ if (!namespacePattern.test(name)) continue;
3367
+ const dir = safePath(root, name);
3368
+ try {
3369
+ const namespace = lstatSync(dir);
3370
+ if (!namespace.isDirectory() || namespace.isSymbolicLink()) continue;
3371
+ if (now - namespace.mtimeMs < IMPLICIT_REAP_GRACE_MS) continue;
3372
+ const lockPath = join(dir, LOCK_NAME);
3373
+ if (existsSync(lockPath)) {
3374
+ const lock = lstatSync(lockPath);
3375
+ if (!lock.isFile() || lock.isSymbolicLink() || lock.size > MAX_LOCK_BYTES) continue;
3376
+ const marker = JSON.parse(readFileSync(lockPath, "utf8"));
3377
+ if (marker.host !== hostname() || !Number.isSafeInteger(marker.pid) || marker.pid <= 0) continue;
3378
+ if (processIsAlive(marker.pid)) continue;
3379
+ const current = lstatSync(lockPath);
3380
+ if (current.dev !== lock.dev || current.ino !== lock.ino) continue;
3381
+ unlinkSync(lockPath);
3382
+ }
3383
+ reapClosedNamespace(dir, now);
3384
+ } catch {
3385
+ }
3386
+ }
3387
+ }
3388
+ function processIsAlive(pid) {
3389
+ try {
3390
+ process.kill(pid, 0);
3391
+ return true;
3392
+ } catch (error) {
3393
+ return error.code !== "ESRCH";
3394
+ }
3395
+ }
3396
+ function reapClosedNamespace(dir, now) {
3397
+ const manifestPath = join(dir, MANIFEST_NAME);
3398
+ let records = [];
3399
+ if (existsSync(manifestPath)) {
3400
+ const stat = lstatSync(manifestPath);
3401
+ if (!stat.isFile() || stat.isSymbolicLink() || stat.size > MAX_MANIFEST_BYTES) return;
3402
+ const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
3403
+ if (manifest?.schemaVersion !== 1 || !Array.isArray(manifest.records) || manifest.records.some((record) => !isManifestRecord(record))) return;
3404
+ records = manifest.records;
3405
+ }
3406
+ const live = [];
3407
+ for (const record of records) {
3408
+ const path = safePath(dir, record.name);
3409
+ if (record.expiresAt <= now) {
3410
+ try {
3411
+ unlinkSync(path);
3412
+ } catch {
3413
+ }
3414
+ continue;
3415
+ }
3416
+ try {
3417
+ const file = lstatSync(path);
3418
+ if (file.isFile() && !file.isSymbolicLink() && file.size === record.bytes) live.push(record);
3419
+ else if (file.isFile() || file.isSymbolicLink()) unlinkSync(path);
3420
+ } catch {
3421
+ }
3422
+ }
3423
+ const liveNames = new Set(live.map((record) => record.name));
3424
+ for (const name of readdirSync(dir)) {
3425
+ if (!MANAGED_NAME.test(name) || liveNames.has(name)) continue;
3426
+ const path = safePath(dir, name);
3427
+ try {
3428
+ const file = lstatSync(path);
3429
+ if (file.isFile() || file.isSymbolicLink()) unlinkSync(path);
3430
+ } catch {
3431
+ }
3432
+ }
3433
+ if (live.length > 0) {
3434
+ if (live.length !== records.length) persistManifestRecords(dir, live);
3435
+ return;
3436
+ }
3437
+ try {
3438
+ const manifest = lstatSync(manifestPath);
3439
+ if (manifest.isFile() && !manifest.isSymbolicLink()) unlinkSync(manifestPath);
3440
+ } catch {
3441
+ }
3442
+ try {
3443
+ rmdirSync(dir);
3444
+ } catch {
3445
+ }
3446
+ }
3447
+ function persistManifestRecords(dir, records) {
3448
+ const path = join(dir, MANIFEST_NAME);
3449
+ const temp = join(dir, `.${MANIFEST_NAME}.${process.pid}.${randomUUID()}.tmp`);
3450
+ try {
3451
+ writeFileSync(temp, JSON.stringify({ schemaVersion: 1, records }), { mode: 384 });
3452
+ renameSync(temp, path);
3453
+ } finally {
3454
+ try {
3455
+ unlinkSync(temp);
3456
+ } catch {
3457
+ }
3458
+ }
3459
+ }
3460
+ function isManifestRecord(candidate) {
3461
+ if (!candidate || typeof candidate !== "object") return false;
3462
+ const record = candidate;
3463
+ return typeof record.name === "string" && MANAGED_NAME.test(record.name) && typeof record.mimeType === "string" && record.mimeType.length > 0 && Number.isSafeInteger(record.bytes) && record.bytes >= 0 && typeof record.sha256 === "string" && /^[a-f0-9]{64}$/.test(record.sha256) && Number.isSafeInteger(record.createdAt) && Number.isSafeInteger(record.expiresAt) && record.expiresAt > record.createdAt;
3464
+ }
2944
3465
  function createArtifactStore(opts = {}) {
2945
3466
  return new ArtifactStore(opts);
2946
3467
  }
@@ -2967,6 +3488,9 @@ function safePath(root, name) {
2967
3488
 
2968
3489
  // src/mcp/server.ts
2969
3490
  var PROTOCOL_VERSION = "2024-11-05";
3491
+ var STDIO_PROTOCOL_VERSIONS = ["2024-11-05", "2025-03-26", "2025-06-18", "2025-11-25", "2026-07-28"];
3492
+ var HTTP_SSE_PROTOCOL_VERSIONS = ["2024-11-05"];
3493
+ var HTTP_SSE_DISPATCH = { supportedVersions: HTTP_SSE_PROTOCOL_VERSIONS };
2970
3494
  var MAX_RPC_BODY_BYTES = 1024 * 1024;
2971
3495
  var MAX_SANDBOX_TIMEOUT_MS = 3e4;
2972
3496
  var MAX_SSE_SESSIONS = 32;
@@ -2989,12 +3513,21 @@ var MCP_NARROWERS = BUILTIN_FAMILY_METADATA.map((f) => f.narrower).join("/");
2989
3513
  var LOCAL_INSTRUCTIONS = `agentic-mermaid Code Mode server. Primary tool execute runs synchronous JavaScript against the typed mermaid.* SDK in a sandbox; async/await and Promise jobs are not supported. describe_sdk progressively discloses one family's version-matched mutation schema; call it before authoring unfamiliar ops. render_png and describe are narrow helpers. render_png can return base64, managed file paths, or managed URLs when the transport config provides an artifact store. There is no mutate tool on this server: structured edits go through the SDK's mermaid.mutate(...) inside execute; narrow via ${MCP_NARROWERS}. Every built-in renderable family ships a typed path when the body narrows; only opaque fallback bodies are source-level only. Layout is deterministic; there is no layout seed (the optional style seed only re-rolls ink of styled looks, never geometry).`;
2990
3514
  var LOCAL_SURFACE = {
2991
3515
  protocolVersion: PROTOCOL_VERSION,
3516
+ supportedVersions: STDIO_PROTOCOL_VERSIONS,
2992
3517
  tools: LOCAL_TOOLS,
2993
3518
  instructions: LOCAL_INSTRUCTIONS,
2994
3519
  handleToolCall
2995
3520
  };
2996
- async function handleRequest(req, context = {}) {
2997
- return dispatchMcpRequest(req, context, LOCAL_SURFACE);
3521
+ function admitLocalRequest(req, options = {}) {
3522
+ return admitMcpMessage(req, {
3523
+ supportedVersions: surfaceSupportedVersions(LOCAL_SURFACE, options),
3524
+ negotiatedVersion: options.protocolVersion,
3525
+ protocolEra: options.protocolEra
3526
+ });
3527
+ }
3528
+ async function handleRequest(req, context = {}, options = {}) {
3529
+ const admission = admitLocalRequest(req, options);
3530
+ return admission.ok ? dispatchAdmittedMcpRequest(admission.message, context, LOCAL_SURFACE) : admission.response;
2998
3531
  }
2999
3532
  async function handleToolCall(id, params, context) {
3000
3533
  const p = params;
@@ -3075,7 +3608,7 @@ function artifactPayload(artifact, output) {
3075
3608
  return { ...base, path: artifact.path };
3076
3609
  }
3077
3610
  function getDefaultArtifactStore() {
3078
- defaultArtifactStore ??= createArtifactStore({ dir: join2(tmpdir2(), "agentic-mermaid-mcp-artifacts") });
3611
+ defaultArtifactStore ??= createArtifactStore();
3079
3612
  if (!defaultArtifactStoreExitHook) {
3080
3613
  defaultArtifactStoreExitHook = true;
3081
3614
  process.once("exit", () => defaultArtifactStore?.close());
@@ -3088,6 +3621,112 @@ function warmUpPngRenderer() {
3088
3621
  } catch {
3089
3622
  }
3090
3623
  }
3624
+ function stdioCancellationTarget(value) {
3625
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
3626
+ const request = value;
3627
+ if (request.jsonrpc !== "2.0" || request.method !== "notifications/cancelled" || Object.prototype.hasOwnProperty.call(request, "id")) return void 0;
3628
+ const params = request.params;
3629
+ if (!params || typeof params !== "object" || Array.isArray(params)) return void 0;
3630
+ const requestId = params.requestId;
3631
+ return typeof requestId === "string" || typeof requestId === "number" && Number.isSafeInteger(requestId) ? requestId : void 0;
3632
+ }
3633
+ function stdioRequestId(value) {
3634
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
3635
+ const request = value;
3636
+ if (request.jsonrpc !== "2.0" || typeof request.method !== "string" || !Object.prototype.hasOwnProperty.call(request, "id")) return void 0;
3637
+ const requestId = request.id;
3638
+ return typeof requestId === "string" || typeof requestId === "number" && Number.isSafeInteger(requestId) ? requestId : void 0;
3639
+ }
3640
+ function stdioRequestKey(id) {
3641
+ return `${typeof id}:${String(id)}`;
3642
+ }
3643
+ function createStdioMessageProcessor(context, write, dispatch = dispatchAdmittedMcpRequest) {
3644
+ let negotiatedProtocolVersion = null;
3645
+ let negotiatedEra = null;
3646
+ let admissionGate = Promise.resolve();
3647
+ const tasks = /* @__PURE__ */ new Set();
3648
+ const inFlight = /* @__PURE__ */ new Map();
3649
+ const register = (id, controller) => {
3650
+ if (id === void 0) return;
3651
+ const key = stdioRequestKey(id);
3652
+ const controllers = inFlight.get(key) ?? /* @__PURE__ */ new Set();
3653
+ controllers.add(controller);
3654
+ inFlight.set(key, controllers);
3655
+ };
3656
+ const unregister = (id, controller) => {
3657
+ if (id === void 0) return;
3658
+ const key = stdioRequestKey(id);
3659
+ const controllers = inFlight.get(key);
3660
+ controllers?.delete(controller);
3661
+ if (controllers?.size === 0) inFlight.delete(key);
3662
+ };
3663
+ const emit = (response, exactIds, signal) => {
3664
+ if (response && !signal?.aborted) write(stringifyJsonRpc(response, exactIds) + "\n");
3665
+ };
3666
+ const accept = (line) => {
3667
+ let exact;
3668
+ let request;
3669
+ try {
3670
+ exact = preserveExactJsonRpcIds(line);
3671
+ request = JSON.parse(exact.body);
3672
+ } catch (cause) {
3673
+ write(JSON.stringify(rpcError(null, -32700, `parse error: ${cause instanceof Error ? cause.message : String(cause)}`)) + "\n");
3674
+ return;
3675
+ }
3676
+ const cancellationTarget = stdioCancellationTarget(request);
3677
+ if (cancellationTarget !== void 0) {
3678
+ for (const controller2 of inFlight.get(stdioRequestKey(cancellationTarget)) ?? []) controller2.abort();
3679
+ return;
3680
+ }
3681
+ const requestId = stdioRequestId(request);
3682
+ const controller = new AbortController();
3683
+ register(requestId, controller);
3684
+ const preparation = admissionGate.then(async () => {
3685
+ const dispatchOptions = negotiatedEra === "legacy" ? { protocolEra: "legacy", protocolVersion: negotiatedProtocolVersion, supportedVersions: negotiatedProtocolVersion ? [negotiatedProtocolVersion] : void 0 } : negotiatedEra === "modern" ? { protocolEra: "modern", supportedVersions: STDIO_PROTOCOL_VERSIONS } : {};
3686
+ const admission = admitLocalRequest(request, dispatchOptions);
3687
+ if (admission.ok && negotiatedEra === null && request.method === "initialize") {
3688
+ const response = controller.signal.aborted ? null : await dispatch(admission.message, { ...context, signal: controller.signal }, LOCAL_SURFACE);
3689
+ if (!controller.signal.aborted && response?.result && typeof response.result === "object") {
3690
+ const selected = response.result.protocolVersion;
3691
+ if (typeof selected === "string" && STDIO_PROTOCOL_VERSIONS.includes(selected)) {
3692
+ negotiatedProtocolVersion = selected;
3693
+ negotiatedEra = "legacy";
3694
+ }
3695
+ }
3696
+ emit(response, exact.ids, controller.signal);
3697
+ return { handled: true, admission };
3698
+ }
3699
+ if (admission.ok && negotiatedEra === null && admission.message.protocol.era === "modern") {
3700
+ negotiatedEra = "modern";
3701
+ }
3702
+ return { handled: false, admission };
3703
+ });
3704
+ admissionGate = preparation.then(() => void 0, () => void 0);
3705
+ let task;
3706
+ task = preparation.then(async (prepared) => {
3707
+ if (prepared.handled) return;
3708
+ const response = prepared.admission.ok ? controller.signal.aborted ? null : await dispatch(prepared.admission.message, { ...context, signal: controller.signal }, LOCAL_SURFACE) : prepared.admission.response;
3709
+ emit(response, exact.ids, controller.signal);
3710
+ }).catch((cause) => {
3711
+ emit(
3712
+ rpcError(requestId ?? null, -32603, `internal error: ${cause instanceof Error ? cause.message : String(cause)}`),
3713
+ exact.ids,
3714
+ controller.signal
3715
+ );
3716
+ }).finally(() => {
3717
+ unregister(requestId, controller);
3718
+ tasks.delete(task);
3719
+ });
3720
+ tasks.add(task);
3721
+ };
3722
+ return {
3723
+ accept,
3724
+ async drain() {
3725
+ await admissionGate;
3726
+ while (tasks.size > 0) await Promise.allSettled([...tasks]);
3727
+ }
3728
+ };
3729
+ }
3091
3730
  async function runStdio(options = {}) {
3092
3731
  warmUpPngRenderer();
3093
3732
  const artifactStore = createArtifactStore({
@@ -3097,22 +3736,20 @@ async function runStdio(options = {}) {
3097
3736
  maxArtifacts: options.maxArtifacts,
3098
3737
  ttlMs: options.artifactTtlMs
3099
3738
  });
3739
+ const processor = createStdioMessageProcessor(
3740
+ { artifactStore, maxSandboxTimeoutMs: options.maxSandboxTimeoutMs },
3741
+ (line) => process.stdout.write(line)
3742
+ );
3100
3743
  process.stdin.setEncoding("utf8");
3101
3744
  let buf = "";
3102
- process.stdin.on("data", async (chunk) => {
3745
+ process.stdin.on("data", (chunk) => {
3103
3746
  buf += chunk;
3104
3747
  let nl;
3105
3748
  while ((nl = buf.indexOf("\n")) >= 0) {
3106
3749
  const line = buf.slice(0, nl).trim();
3107
3750
  buf = buf.slice(nl + 1);
3108
3751
  if (!line) continue;
3109
- try {
3110
- const exact = preserveExactJsonRpcIds(line);
3111
- const res = await handleRequest(JSON.parse(exact.body), { artifactStore, maxSandboxTimeoutMs: options.maxSandboxTimeoutMs });
3112
- if (res) process.stdout.write(stringifyJsonRpc(res, exact.ids) + "\n");
3113
- } catch (e) {
3114
- process.stdout.write(JSON.stringify(rpcError(null, -32700, `parse error: ${e.message}`)) + "\n");
3115
- }
3752
+ processor.accept(line);
3116
3753
  }
3117
3754
  });
3118
3755
  try {
@@ -3120,6 +3757,7 @@ async function runStdio(options = {}) {
3120
3757
  process.stdin.on("end", () => resolve2());
3121
3758
  process.stdin.on("close", () => resolve2());
3122
3759
  });
3760
+ await processor.drain();
3123
3761
  } finally {
3124
3762
  artifactStore.close();
3125
3763
  }
@@ -3288,7 +3926,7 @@ async function postSseMessage(req, res, sessions, context, maxBytes) {
3288
3926
  } catch {
3289
3927
  throw new HttpStatusError(400, "invalid JSON-RPC body");
3290
3928
  }
3291
- const response = await handleRequest(parsed, context);
3929
+ const response = await handleRequest(parsed, context, HTTP_SSE_DISPATCH);
3292
3930
  if (response) {
3293
3931
  sse.write(`event: message
3294
3932
  data: ${stringifyJsonRpc(response, exact.ids)}
@@ -3308,7 +3946,7 @@ async function postRpc(req, res, context, maxBytes) {
3308
3946
  } catch {
3309
3947
  throw new HttpStatusError(400, "invalid JSON-RPC body");
3310
3948
  }
3311
- const response = await handleRequest(parsed, context);
3949
+ const response = await handleRequest(parsed, context, HTTP_SSE_DISPATCH);
3312
3950
  if (response === null) {
3313
3951
  res.writeHead(202);
3314
3952
  res.end();
@@ -3482,4 +4120,4 @@ export {
3482
4120
  parseMcpCliOptions,
3483
4121
  runMcpCli
3484
4122
  };
3485
- //# sourceMappingURL=chunk-FGO3J7RA.js.map
4123
+ //# sourceMappingURL=chunk-NE6JBHSE.js.map