@code-yeongyu/senpi 2026.10.25-1 → 2026.10.25-3

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 (226) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/bundle/chunks/{args-JXULI4EH.js → args-B444OQBK.js} +1 -1
  3. package/dist/bundle/chunks/{auth-4NUNUSTF.js → auth-C77UQA55.js} +1 -1
  4. package/dist/bundle/chunks/{chunk-RHHBXIRN.js → chunk-4WZRVZNX.js} +1 -1
  5. package/dist/bundle/chunks/chunk-6O4SEW2W.js +5 -0
  6. package/dist/bundle/chunks/{chunk-Y5OTHMXO.js → chunk-7CNOCJCN.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-YDCRA5ES.js → chunk-7W7OJDIY.js} +4 -4
  8. package/dist/bundle/chunks/chunk-AX72VNRS.js +27 -0
  9. package/dist/bundle/chunks/{chunk-FWXMMMCV.js → chunk-C5UFJ7B3.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-7IRLFYNM.js → chunk-CNL6QSUB.js} +4 -4
  11. package/dist/bundle/chunks/{chunk-BTNYLNWZ.js → chunk-FFQOEC76.js} +5 -5
  12. package/dist/bundle/chunks/{chunk-VOBD6FQG.js → chunk-FHXR4ZAC.js} +1 -1
  13. package/dist/bundle/chunks/chunk-H3HNMY2W.js +13 -0
  14. package/dist/bundle/chunks/{chunk-BMYNMUVZ.js → chunk-HVJI5T75.js} +1 -1
  15. package/dist/bundle/chunks/{chunk-EWOEVVQT.js → chunk-JA2R2ZSE.js} +1 -1
  16. package/dist/bundle/chunks/chunk-JPGT64RV.js +2 -0
  17. package/dist/bundle/chunks/chunk-KXB5WIS5.js +4 -0
  18. package/dist/bundle/chunks/chunk-L73UYAH5.js +3 -0
  19. package/dist/bundle/chunks/chunk-LTU6UFEX.js +2 -0
  20. package/dist/bundle/chunks/{chunk-EYBDBR7V.js → chunk-MJ5NNWX4.js} +1 -1
  21. package/dist/bundle/chunks/{chunk-RVYSJBZ7.js → chunk-O3Q2ET6W.js} +2 -5
  22. package/dist/bundle/chunks/chunk-O5RYI3IW.js +2 -0
  23. package/dist/bundle/chunks/{chunk-SGDOZT6B.js → chunk-ODTGC6YU.js} +1 -1
  24. package/dist/bundle/chunks/chunk-P3M2PF6K.js +27 -0
  25. package/dist/bundle/chunks/chunk-SWJXRC2I.js +5 -0
  26. package/dist/bundle/chunks/{chunk-QH2HSCMX.js → chunk-TTU2RNVX.js} +3 -3
  27. package/dist/bundle/chunks/{chunk-PXKF2RHD.js → chunk-UFJ2K7Q7.js} +1 -1
  28. package/dist/bundle/chunks/{chunk-7UUOGZKR.js → chunk-UQNRW3VU.js} +1 -1
  29. package/dist/bundle/chunks/{chunk-U67ML6CQ.js → chunk-WD6WBYC5.js} +1 -1
  30. package/dist/bundle/chunks/chunk-WJOT3DFL.js +2 -0
  31. package/dist/bundle/chunks/{chunk-7WAJCESX.js → chunk-WLHNEUGD.js} +1 -1
  32. package/dist/bundle/chunks/chunk-YI7SPFDN.js +5 -0
  33. package/dist/bundle/chunks/{chunk-URBJS24R.js → chunk-YRF4I43T.js} +35 -35
  34. package/dist/bundle/chunks/chunk-Z3UYNSVR.js +3 -0
  35. package/dist/bundle/chunks/cli-main-HEKFFB5S.js +3 -0
  36. package/dist/bundle/chunks/{client-KWTLTKVV.js → client-WTYEICLH.js} +3 -3
  37. package/dist/bundle/chunks/dispatch-NYAULNVW.js +9 -0
  38. package/dist/bundle/chunks/{help-fast-path-ZHZGXAUG.js → help-fast-path-3Z26DQSV.js} +1 -1
  39. package/dist/bundle/chunks/host-command-Z3WPHJOW.js +2 -0
  40. package/dist/bundle/chunks/host-lifecycle-ONQIMWMX.js +3 -0
  41. package/dist/bundle/chunks/host-lifecycle.js +9 -7
  42. package/dist/bundle/chunks/host-session-command-J65ENSV5.js +20 -0
  43. package/dist/bundle/chunks/{host-socket-request-ZDJGSSZO.js → host-socket-request-3CWE4265.js} +1 -1
  44. package/dist/bundle/chunks/interactive-mode-DEPQC6TX.js +2 -0
  45. package/dist/bundle/chunks/mcp-presenter-bootstrap-XUSCQVRC.js +2 -0
  46. package/dist/bundle/chunks/{multi-session-host-M7HVUMRH.js → multi-session-host-YI2WZOET.js} +12 -9
  47. package/dist/bundle/chunks/{package-manager-cli-FSR5P6YL.js → package-manager-cli-GHZPJMRF.js} +1 -1
  48. package/dist/bundle/chunks/{role-M2MTVACJ.js → role-JVSBNKGE.js} +1 -1
  49. package/dist/bundle/chunks/{rotation-stream-U7YQMC7H.js → rotation-stream-ZPVCFOVD.js} +1 -1
  50. package/dist/bundle/chunks/rpc-mode-ORHBGBBV.js +2 -0
  51. package/dist/bundle/chunks/{rpc-monitor-source-OL5KU6NO.js → rpc-monitor-source-FFEQS744.js} +1 -1
  52. package/dist/bundle/chunks/{runtime-session-CLNODAYE.js → runtime-session-V5OO7ZRM.js} +1 -1
  53. package/dist/bundle/chunks/{schedule-command-XBW4EOG5.js → schedule-command-YWG6D6ZF.js} +1 -1
  54. package/dist/bundle/chunks/session-control-endpoint-36HAQSQO.js +3 -0
  55. package/dist/bundle/chunks/{session-picker-KQUFWDQC.js → session-picker-25H5KNYP.js} +1 -1
  56. package/dist/bundle/chunks/session-worker.js +285 -271
  57. package/dist/bundle/chunks/{stdio-IEC635SY.js → stdio-YXDKKKQZ.js} +1 -1
  58. package/dist/bundle/chunks/{streamableHttp-KJI5KE4K.js → streamableHttp-DKIBUWVY.js} +1 -1
  59. package/dist/bundle/chunks/{types-LLNV23LW.js → types-BJUEQ4II.js} +1 -1
  60. package/dist/bundle/chunks/zod-compat-RJDXCU7S.js +2 -0
  61. package/dist/bundle/cli.js +2 -2
  62. package/dist/bundle/host-supervisor.js +9 -7
  63. package/dist/bundle/index.js +1 -1
  64. package/dist/bundle/rpc-entry.js +1 -1
  65. package/dist/bundle/runtime-manifest.json +1 -1
  66. package/dist/cli/args.d.ts +2 -0
  67. package/dist/cli/args.js +9 -0
  68. package/dist/cli/host-command-args.d.ts +1 -0
  69. package/dist/cli/host-command-args.js +7 -1
  70. package/dist/cli/host-command.js +3 -1
  71. package/dist/core/agent-session.d.ts +1 -0
  72. package/dist/core/agent-session.js +50 -16
  73. package/dist/core/engine-turn-limit.d.ts +2 -0
  74. package/dist/core/engine-turn-limit.js +7 -1
  75. package/dist/core/extensions/builtin/anthropic-subscription/auth-attempt.js +5 -0
  76. package/dist/core/extensions/builtin/goal/index.js +1 -0
  77. package/dist/core/extensions/builtin/goal/lifecycle-facts.d.ts +3 -0
  78. package/dist/core/extensions/builtin/goal/stop-pause.js +2 -1
  79. package/dist/core/extensions/builtin/loop/session-hold.js +2 -1
  80. package/dist/core/extensions/builtin/mcp/catalog.d.ts +3 -1
  81. package/dist/core/extensions/builtin/mcp/catalog.js +2 -0
  82. package/dist/core/extensions/builtin/mcp/connection.d.ts +1 -0
  83. package/dist/core/extensions/builtin/mcp/connection.js +46 -1
  84. package/dist/core/extensions/builtin/mcp/elicitation.d.ts +6 -1
  85. package/dist/core/extensions/builtin/mcp/elicitation.js +56 -2
  86. package/dist/core/extensions/builtin/mcp/expose/call.js +6 -2
  87. package/dist/core/extensions/builtin/mcp/expose/session.d.ts +4 -1
  88. package/dist/core/extensions/builtin/mcp/expose/session.js +7 -0
  89. package/dist/core/extensions/builtin/mcp/health.js +5 -0
  90. package/dist/core/extensions/builtin/mcp/host-registry.js +7 -1
  91. package/dist/core/extensions/builtin/mcp/index.js +2 -0
  92. package/dist/core/extensions/builtin/mcp/modern/client.d.ts +5 -0
  93. package/dist/core/extensions/builtin/mcp/modern/client.js +15 -0
  94. package/dist/core/extensions/builtin/mcp/modern/consent-queue.d.ts +2 -0
  95. package/dist/core/extensions/builtin/mcp/modern/consent-queue.js +59 -0
  96. package/dist/core/extensions/builtin/mcp/modern/diagnostics.d.ts +4 -0
  97. package/dist/core/extensions/builtin/mcp/modern/diagnostics.js +39 -0
  98. package/dist/core/extensions/builtin/mcp/modern/dispatch.js +21 -11
  99. package/dist/core/extensions/builtin/mcp/modern/elicitation.d.ts +14 -0
  100. package/dist/core/extensions/builtin/mcp/modern/elicitation.js +145 -0
  101. package/dist/core/extensions/builtin/mcp/modern/errors.d.ts +21 -0
  102. package/dist/core/extensions/builtin/mcp/modern/errors.js +23 -0
  103. package/dist/core/extensions/builtin/mcp/modern/form-schema.d.ts +20 -0
  104. package/dist/core/extensions/builtin/mcp/modern/form-schema.js +153 -0
  105. package/dist/core/extensions/builtin/mcp/modern/http-fetch.d.ts +3 -1
  106. package/dist/core/extensions/builtin/mcp/modern/http-fetch.js +8 -2
  107. package/dist/core/extensions/builtin/mcp/modern/inputs.d.ts +11 -0
  108. package/dist/core/extensions/builtin/mcp/modern/inputs.js +65 -0
  109. package/dist/core/extensions/builtin/mcp/modern/parameter-headers.d.ts +11 -0
  110. package/dist/core/extensions/builtin/mcp/modern/parameter-headers.js +109 -0
  111. package/dist/core/extensions/builtin/mcp/modern/request.d.ts +20 -0
  112. package/dist/core/extensions/builtin/mcp/modern/request.js +292 -0
  113. package/dist/core/extensions/builtin/mcp/modern/stdio-probe.d.ts +1 -1
  114. package/dist/core/extensions/builtin/mcp/modern/stdio-probe.js +54 -6
  115. package/dist/core/extensions/builtin/mcp/modern/transport.js +80 -14
  116. package/dist/core/extensions/builtin/mcp/modern/wire.js +11 -7
  117. package/dist/core/extensions/builtin/mcp/prompts.d.ts +5 -1
  118. package/dist/core/extensions/builtin/mcp/prompts.js +6 -1
  119. package/dist/core/extensions/builtin/mcp/request-origin.d.ts +47 -0
  120. package/dist/core/extensions/builtin/mcp/request-origin.js +59 -0
  121. package/dist/core/extensions/builtin/mcp/resources.d.ts +4 -1
  122. package/dist/core/extensions/builtin/mcp/resources.js +19 -4
  123. package/dist/core/extensions/builtin/mcp/sdk.lazy.d.ts +3 -1
  124. package/dist/core/extensions/builtin/mcp/sdk.lazy.js +3 -1
  125. package/dist/core/extensions/builtin/mcp/service-register.d.ts +4 -1
  126. package/dist/core/extensions/builtin/mcp/service-register.js +3 -0
  127. package/dist/core/extensions/builtin/mcp/service-types.d.ts +2 -1
  128. package/dist/core/extensions/builtin/mcp/service.d.ts +1 -0
  129. package/dist/core/extensions/builtin/mcp/service.js +79 -4
  130. package/dist/core/extensions/builtin/mcp/shared-connection.js +36 -2
  131. package/dist/core/extensions/builtin/mcp/shared-lease.d.ts +1 -0
  132. package/dist/core/extensions/builtin/mcp/shared-lease.js +9 -0
  133. package/dist/core/extensions/builtin/mcp/transport-sdk.d.ts +3 -2
  134. package/dist/core/extensions/builtin/mcp/transport-sdk.js +56 -25
  135. package/dist/core/extensions/builtin/mcp/wrap.d.ts +7 -0
  136. package/dist/core/extensions/builtin/mcp/wrap.js +6 -0
  137. package/dist/core/extensions/runner.js +3 -2
  138. package/dist/core/extensions/types.d.ts +2 -0
  139. package/dist/core/lifecycle-ledger.d.ts +1 -0
  140. package/dist/core/lifecycle-ledger.js +7 -2
  141. package/dist/core/lifecycle-record.js +3 -0
  142. package/dist/core/lifecycle-runtime-facts.js +3 -0
  143. package/dist/core/lifecycle-session-binding.d.ts +11 -1
  144. package/dist/core/lifecycle-session-binding.js +35 -4
  145. package/dist/core/lifecycle-stop.d.ts +41 -0
  146. package/dist/core/lifecycle-stop.js +92 -0
  147. package/dist/core/mcp-form-types.d.ts +89 -0
  148. package/dist/core/mcp-form-types.js +23 -0
  149. package/dist/core/mcp-mrtr-presentations.d.ts +15 -0
  150. package/dist/core/mcp-mrtr-presentations.js +17 -0
  151. package/dist/core/run-resume-turn.d.ts +1 -0
  152. package/dist/core/run-resume-turn.js +4 -3
  153. package/dist/core/session-lifecycle-types.d.ts +15 -0
  154. package/dist/core/session-lifecycle.d.ts +17 -1
  155. package/dist/core/session-lifecycle.js +40 -2
  156. package/dist/core/stop-resume-directive.d.ts +1 -1
  157. package/dist/core/stop-resume-directive.js +10 -1
  158. package/dist/main.js +5 -1
  159. package/dist/modes/interactive/components/extension-selector.d.ts +1 -0
  160. package/dist/modes/interactive/components/extension-selector.js +4 -0
  161. package/dist/modes/interactive/interactive-mode.d.ts +4 -0
  162. package/dist/modes/interactive/interactive-mode.js +35 -8
  163. package/dist/modes/interactive/mcp-local-presenter.d.ts +5 -0
  164. package/dist/modes/interactive/mcp-local-presenter.js +109 -0
  165. package/dist/modes/interactive/pause-footer.d.ts +5 -0
  166. package/dist/modes/interactive/pause-footer.js +2 -0
  167. package/dist/modes/rpc/connection-handler.d.ts +1 -0
  168. package/dist/modes/rpc/connection-handler.js +7 -1
  169. package/dist/modes/rpc/host-capabilities.d.ts +1 -0
  170. package/dist/modes/rpc/host-capabilities.js +2 -1
  171. package/dist/modes/rpc/host-ensure-start.js +13 -2
  172. package/dist/modes/rpc/host-ensure-types.d.ts +2 -0
  173. package/dist/modes/rpc/host-ensure.js +1 -0
  174. package/dist/modes/rpc/host-handoff.d.ts +2 -0
  175. package/dist/modes/rpc/host-handover-wire.d.ts +2 -0
  176. package/dist/modes/rpc/host-handover-wire.js +1 -0
  177. package/dist/modes/rpc/host-lifecycle-launch.d.ts +1 -0
  178. package/dist/modes/rpc/host-lifecycle-launch.js +43 -2
  179. package/dist/modes/rpc/host-reservations.js +3 -2
  180. package/dist/modes/rpc/host-runner.d.ts +2 -0
  181. package/dist/modes/rpc/host-runner.js +8 -6
  182. package/dist/modes/rpc/host-stalled-evidence.js +2 -1
  183. package/dist/modes/rpc/host-successor.js +11 -1
  184. package/dist/modes/rpc/mcp-form-dialog.d.ts +45 -0
  185. package/dist/modes/rpc/mcp-form-dialog.js +159 -0
  186. package/dist/modes/rpc/mcp-form-worker.d.ts +14 -0
  187. package/dist/modes/rpc/mcp-form-worker.js +167 -0
  188. package/dist/modes/rpc/mcp-presenter-authority.d.ts +53 -0
  189. package/dist/modes/rpc/mcp-presenter-authority.js +309 -0
  190. package/dist/modes/rpc/mcp-presenter-bootstrap.d.ts +8 -0
  191. package/dist/modes/rpc/mcp-presenter-bootstrap.js +111 -0
  192. package/dist/modes/rpc/mcp-presenter-control.d.ts +24 -0
  193. package/dist/modes/rpc/mcp-presenter-control.js +330 -0
  194. package/dist/modes/rpc/multi-session-host.d.ts +3 -0
  195. package/dist/modes/rpc/multi-session-host.js +36 -1
  196. package/dist/modes/rpc/session-binding.js +6 -1
  197. package/dist/modes/rpc/session-event-writer.d.ts +14 -0
  198. package/dist/modes/rpc/session-event-writer.js +128 -1
  199. package/dist/modes/rpc/session-router-routing.js +1 -0
  200. package/dist/modes/rpc/session-worker-client.d.ts +3 -0
  201. package/dist/modes/rpc/session-worker-client.js +89 -0
  202. package/dist/modes/rpc/session-worker-protocol.d.ts +41 -0
  203. package/dist/modes/rpc/session-worker.js +9 -0
  204. package/dist/modes/rpc/tool-child/group-ownership.js +4 -2
  205. package/dist/utils/process-identity.d.ts +7 -0
  206. package/dist/utils/process-identity.js +32 -5
  207. package/docs/extensions.md +5 -0
  208. package/docs/mcp.md +20 -3
  209. package/docs/rpc.md +111 -0
  210. package/package.json +6 -6
  211. package/dist/bundle/chunks/chunk-3VOG6WFU.js +0 -27
  212. package/dist/bundle/chunks/chunk-7ASLQ243.js +0 -2
  213. package/dist/bundle/chunks/chunk-CDRFFHLL.js +0 -4
  214. package/dist/bundle/chunks/chunk-HPCS4HM4.js +0 -27
  215. package/dist/bundle/chunks/chunk-II22E3CV.js +0 -3
  216. package/dist/bundle/chunks/chunk-J5P2VL3Y.js +0 -5
  217. package/dist/bundle/chunks/chunk-SCVRKIFK.js +0 -2
  218. package/dist/bundle/chunks/chunk-XUFUKDKJ.js +0 -5
  219. package/dist/bundle/chunks/cli-main-TABBP55A.js +0 -3
  220. package/dist/bundle/chunks/dispatch-DEP4PEDZ.js +0 -10
  221. package/dist/bundle/chunks/host-command-OQR4RDTM.js +0 -2
  222. package/dist/bundle/chunks/host-lifecycle-U36U7JTE.js +0 -3
  223. package/dist/bundle/chunks/host-session-command-IGB27ZPJ.js +0 -20
  224. package/dist/bundle/chunks/interactive-mode-DGQNSXUA.js +0 -2
  225. package/dist/bundle/chunks/rpc-mode-SZAJNKKL.js +0 -2
  226. package/dist/bundle/chunks/session-control-endpoint-WEF3XTJR.js +0 -3
@@ -0,0 +1,153 @@
1
+ export const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
2
+ const own = (value, key) => Object.hasOwn(value, key);
3
+ export function enums(property) {
4
+ if (Array.isArray(property.enum) &&
5
+ property.enum.length > 0 &&
6
+ property.enum.every((entry) => typeof entry === "string")) {
7
+ return property.enum.map((value) => ({ value, label: value }));
8
+ }
9
+ const choices = property.oneOf ?? property.anyOf;
10
+ if (Array.isArray(choices) &&
11
+ choices.length > 0 &&
12
+ choices.every((entry) => isRecord(entry) &&
13
+ typeof entry.const === "string" &&
14
+ typeof entry.title === "string" &&
15
+ Object.keys(entry).every((key) => key === "const" || key === "title"))) {
16
+ return choices.map((entry) => ({ value: entry.const, label: entry.title }));
17
+ }
18
+ return undefined;
19
+ }
20
+ export function validValue(property, value) {
21
+ if (property.type === "boolean")
22
+ return typeof value === "boolean";
23
+ if (property.type === "integer" || property.type === "number") {
24
+ return (typeof value === "number" &&
25
+ Number.isFinite(value) &&
26
+ (property.type !== "integer" || Number.isInteger(value)) &&
27
+ (typeof property.minimum !== "number" || value >= property.minimum) &&
28
+ (typeof property.maximum !== "number" || value <= property.maximum));
29
+ }
30
+ if (property.type === "array") {
31
+ const choices = isRecord(property.items) ? enums(property.items) : undefined;
32
+ return (Array.isArray(value) &&
33
+ value.every((entry) => typeof entry === "string" && choices?.some((choice) => choice.value === entry)) &&
34
+ new Set(value).size === value.length &&
35
+ (typeof property.minItems !== "number" || value.length >= property.minItems) &&
36
+ (typeof property.maxItems !== "number" || value.length <= property.maxItems));
37
+ }
38
+ if (typeof value !== "string")
39
+ return false;
40
+ const choices = enums(property);
41
+ if (choices && !choices.some((choice) => choice.value === value))
42
+ return false;
43
+ if (typeof property.minLength === "number" && [...value].length < property.minLength)
44
+ return false;
45
+ if (typeof property.maxLength === "number" && [...value].length > property.maxLength)
46
+ return false;
47
+ switch (property.format) {
48
+ case "email":
49
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
50
+ case "uri": {
51
+ try {
52
+ return new URL(value).protocol.length > 1;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ }
58
+ case "date":
59
+ return (/^\d{4}-\d{2}-\d{2}$/.test(value) &&
60
+ Number.isFinite(Date.parse(value)) &&
61
+ new Date(value).toISOString().slice(0, 10) === value);
62
+ case "date-time": {
63
+ const date = value.slice(0, 10);
64
+ return (/^\d{4}-\d{2}-\d{2}T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(value) &&
65
+ Number.isFinite(Date.parse(value)) &&
66
+ new Date(date).toISOString().slice(0, 10) === date);
67
+ }
68
+ default:
69
+ return true;
70
+ }
71
+ }
72
+ /** Validate a complete submitted form, including unknown keys and omitted required fields. */
73
+ export function validMcpFormContent(schema, content) {
74
+ return (isRecord(content) &&
75
+ (schema.required ?? []).every((key) => own(content, key)) &&
76
+ Object.entries(content).every(([key, value]) => own(schema.properties, key) && validValue(schema.properties[key], value)));
77
+ }
78
+ /** Reject unsupported constraints rather than presenting a weaker schema. */
79
+ export function validateMrtrForm(schema) {
80
+ if (!isRecord(schema) || schema.type !== "object" || !isRecord(schema.properties))
81
+ return false;
82
+ for (const key of ["title", "description"])
83
+ if (own(schema, key) && typeof schema[key] !== "string")
84
+ return false;
85
+ if (Object.keys(schema).some((key) => !["type", "properties", "required", "title", "description", "$schema"].includes(key)))
86
+ return false;
87
+ if (schema.required !== undefined &&
88
+ (!Array.isArray(schema.required) ||
89
+ !schema.required.every((key) => typeof key === "string" && own(schema.properties, key))))
90
+ return false;
91
+ for (const property of Object.values(schema.properties)) {
92
+ if (!isRecord(property))
93
+ return false;
94
+ const allowed = ["type", "title", "description", "default"];
95
+ switch (property.type) {
96
+ case "string":
97
+ allowed.push("minLength", "maxLength", "format", "enum", "oneOf");
98
+ if (property.format !== undefined &&
99
+ !["email", "uri", "date", "date-time"].includes(String(property.format)))
100
+ return false;
101
+ if ((own(property, "enum") || own(property, "oneOf")) && !enums(property))
102
+ return false;
103
+ if (own(property, "enum") && own(property, "oneOf"))
104
+ return false;
105
+ break;
106
+ case "number":
107
+ case "integer":
108
+ allowed.push("minimum", "maximum");
109
+ break;
110
+ case "boolean":
111
+ break;
112
+ case "array":
113
+ allowed.push("items", "minItems", "maxItems");
114
+ if (!isRecord(property.items) ||
115
+ !enums(property.items) ||
116
+ Object.keys(property.items).some((key) => !["type", "enum", "anyOf"].includes(key)) ||
117
+ (property.items.type !== undefined && property.items.type !== "string"))
118
+ return false;
119
+ break;
120
+ default:
121
+ return false;
122
+ }
123
+ if (Object.keys(property).some((key) => !allowed.includes(key)))
124
+ return false;
125
+ for (const key of ["title", "description"])
126
+ if (own(property, key) && typeof property[key] !== "string")
127
+ return false;
128
+ for (const key of ["minimum", "maximum", "minLength", "maxLength", "minItems", "maxItems"]) {
129
+ const value = property[key];
130
+ if (value !== undefined &&
131
+ (typeof value !== "number" ||
132
+ !Number.isFinite(value) ||
133
+ (!["minimum", "maximum"].includes(key) && (!Number.isInteger(value) || value < 0))))
134
+ return false;
135
+ }
136
+ for (const [min, max] of [
137
+ ["minimum", "maximum"],
138
+ ["minLength", "maxLength"],
139
+ ["minItems", "maxItems"],
140
+ ]) {
141
+ if (min &&
142
+ max &&
143
+ typeof property[min] === "number" &&
144
+ typeof property[max] === "number" &&
145
+ property[min] > property[max])
146
+ return false;
147
+ }
148
+ if (own(property, "default") && !validValue(property, property.default))
149
+ return false;
150
+ }
151
+ return true;
152
+ }
153
+ //# sourceMappingURL=form-schema.js.map
@@ -1,5 +1,7 @@
1
1
  import type { FetchLike } from "@modelcontextprotocol/sdk/shared/transport.js";
2
+ import type { OAuthTokens } from "@modelcontextprotocol/sdk/shared/auth.js";
2
3
  import type { McpHttpTransportSpec } from "../transport-sdk.ts";
4
+ export declare const modernCredentialSnapshot: (tokens: OAuthTokens | undefined) => string | undefined;
3
5
  /** The existing OAuth provider owns credentials; the SDK owns authorization and origin-safe redirects. */
4
- export declare function modernHttpFetch(spec: McpHttpTransportSpec, signal: AbortSignal): FetchLike;
6
+ export declare function modernHttpFetch(spec: McpHttpTransportSpec, signal: AbortSignal, authorizeResend?: boolean): FetchLike;
5
7
  //# sourceMappingURL=http-fetch.d.ts.map
@@ -1,13 +1,18 @@
1
1
  import { fetchWithinOrigin } from "@modelcontextprotocol/sdk/shared/transport.js";
2
2
  import { loadMcpSdkAuth } from "../sdk.lazy.js";
3
+ import { modernDispatchGuard } from "./request.js";
4
+ import { clearMcpParameterHeaders } from "./parameter-headers.js";
5
+ export const modernCredentialSnapshot = (tokens) => tokens === undefined ? undefined : JSON.stringify([tokens.access_token, tokens.refresh_token]);
3
6
  /** The existing OAuth provider owns credentials; the SDK owns authorization and origin-safe redirects. */
4
- export function modernHttpFetch(spec, signal) {
7
+ export function modernHttpFetch(spec, signal, authorizeResend = true) {
5
8
  const fetch = fetchWithinOrigin();
6
9
  return async (url, init) => {
7
10
  const requestSignal = init?.signal ? AbortSignal.any([signal, init.signal]) : signal;
8
11
  const send = () => {
9
12
  const headers = new Headers();
10
13
  const tokens = spec.authProvider?.tokens();
14
+ const guard = init?.[modernDispatchGuard];
15
+ guard?.(modernCredentialSnapshot(tokens));
11
16
  if (tokens)
12
17
  headers.set("Authorization", `Bearer ${tokens.access_token}`);
13
18
  new Headers(spec.requestInit?.headers).forEach((value, key) => {
@@ -15,6 +20,7 @@ export function modernHttpFetch(spec, signal) {
15
20
  });
16
21
  for (const key of ["Mcp-Session-Id", "Mcp-Name", "Mcp-Method", "MCP-Protocol-Version"])
17
22
  headers.delete(key);
23
+ clearMcpParameterHeaders(headers);
18
24
  new Headers(init?.headers).forEach((value, key) => {
19
25
  headers.set(key, value);
20
26
  });
@@ -27,7 +33,7 @@ export function modernHttpFetch(spec, signal) {
27
33
  });
28
34
  };
29
35
  let response = await send();
30
- if (spec.authProvider && (response.status === 401 || response.status === 403)) {
36
+ if (authorizeResend && spec.authProvider && (response.status === 401 || response.status === 403)) {
31
37
  const { auth, extractWWWAuthenticateParams, UnauthorizedError } = await loadMcpSdkAuth();
32
38
  const { resourceMetadataUrl, scope, error } = extractWWWAuthenticateParams(response);
33
39
  if (response.status === 401 || error === "insufficient_scope") {
@@ -0,0 +1,11 @@
1
+ type Input = {
2
+ method: "elicitation/create";
3
+ params: {
4
+ mode?: "form" | "url";
5
+ message: string;
6
+ requestedSchema?: unknown;
7
+ };
8
+ };
9
+ export declare function parseInputs(result: Record<string, unknown>): Map<string, Input> | undefined;
10
+ export {};
11
+ //# sourceMappingURL=inputs.d.ts.map
@@ -0,0 +1,65 @@
1
+ import { isRecord, validateMrtrForm } from "./form-schema.js";
2
+ import { McpMrtrError } from "./errors.js";
3
+ const own = (value, key) => Object.hasOwn(value, key);
4
+ const byteSize = (value) => Buffer.byteLength(JSON.stringify(value), "utf8");
5
+ export function parseInputs(result) {
6
+ if (!own(result, "requestState") && !own(result, "inputRequests"))
7
+ throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");
8
+ if (own(result, "requestState") && typeof result.requestState !== "string")
9
+ throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");
10
+ if (byteSize(result) > 512 * 1024 ||
11
+ (typeof result.requestState === "string" && Buffer.byteLength(result.requestState) > 64 * 1024))
12
+ throw new McpMrtrError("MCP_MRTR_INPUT_LIMIT");
13
+ if (!own(result, "inputRequests"))
14
+ return undefined;
15
+ if (!isRecord(result.inputRequests))
16
+ throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");
17
+ const entries = Object.entries(result.inputRequests);
18
+ if (entries.length > 32)
19
+ throw new McpMrtrError("MCP_MRTR_INPUT_LIMIT");
20
+ // Scan the complete batch before collecting anything, including unsupported capability requests.
21
+ for (const [, input] of entries)
22
+ if (isRecord(input) && ["roots/list", "sampling/createMessage"].includes(String(input.method)))
23
+ throw new McpMrtrError("MCP_MRTR_UNSUPPORTED_INPUT");
24
+ const inputs = new Map();
25
+ const checkStrings = (value) => {
26
+ if (typeof value === "string" && Buffer.byteLength(value) > 16 * 1024)
27
+ throw new McpMrtrError("MCP_MRTR_INPUT_LIMIT");
28
+ if (Array.isArray(value))
29
+ for (const entry of value)
30
+ checkStrings(entry);
31
+ else if (isRecord(value))
32
+ for (const [key, entry] of Object.entries(value)) {
33
+ checkStrings(key);
34
+ checkStrings(entry);
35
+ }
36
+ };
37
+ for (const [key, input] of entries) {
38
+ checkStrings(key);
39
+ if (!isRecord(input) ||
40
+ input.method !== "elicitation/create" ||
41
+ !isRecord(input.params) ||
42
+ typeof input.params.message !== "string")
43
+ throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");
44
+ const params = input.params;
45
+ checkStrings(params);
46
+ if (params.mode === "url") {
47
+ if (typeof params.url !== "string" || typeof params.elicitationId !== "string")
48
+ throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");
49
+ throw new McpMrtrError("MCP_MRTR_UNSUPPORTED_INPUT");
50
+ }
51
+ else {
52
+ if (params.mode !== undefined && params.mode !== "form")
53
+ throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");
54
+ if (isRecord(params.requestedSchema) &&
55
+ isRecord(params.requestedSchema.properties) &&
56
+ Object.keys(params.requestedSchema.properties).length > 64)
57
+ throw new McpMrtrError("MCP_MRTR_INPUT_LIMIT");
58
+ if (!validateMrtrForm(params.requestedSchema))
59
+ throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");
60
+ }
61
+ inputs.set(key, input);
62
+ }
63
+ return inputs;
64
+ }
65
+ //# sourceMappingURL=inputs.js.map
@@ -0,0 +1,11 @@
1
+ /** RFC 9110 field values, preserving whitespace and literal sentinel strings. */
2
+ export declare function encodeMcpHeaderValue(value: string): string;
3
+ /** Configured headers must never supply parameter metadata absent from the request body. */
4
+ export declare function clearMcpParameterHeaders(headers: Headers): void;
5
+ /** Connection-local catalog: never shared with another server or transport generation. */
6
+ export declare class ModernParameterHeaders {
7
+ #private;
8
+ filterTools(tools: readonly unknown[], firstPage: boolean): unknown[];
9
+ append(headers: Headers, name: unknown, args: unknown): void;
10
+ }
11
+ //# sourceMappingURL=parameter-headers.d.ts.map
@@ -0,0 +1,109 @@
1
+ import { Buffer } from "node:buffer";
2
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
3
+ /** RFC 9110 field values, preserving whitespace and literal sentinel strings. */
4
+ export function encodeMcpHeaderValue(value) {
5
+ return /^[\x09\x20-\x7e]*$/.test(value) &&
6
+ value.trim() === value &&
7
+ !(value.startsWith("=?base64?") && value.endsWith("?="))
8
+ ? value
9
+ : `=?base64?${Buffer.from(value, "utf8").toString("base64")}?=`;
10
+ }
11
+ /** Configured headers must never supply parameter metadata absent from the request body. */
12
+ export function clearMcpParameterHeaders(headers) {
13
+ for (const name of [...headers.keys()]) {
14
+ if (name.toLowerCase().startsWith("mcp-param-"))
15
+ headers.delete(name);
16
+ }
17
+ }
18
+ function parseParameterHeaders(schema) {
19
+ const headers = [];
20
+ const names = new Set();
21
+ const visit = (node, path) => {
22
+ if (!isRecord(node))
23
+ return true;
24
+ if (Object.hasOwn(node, "x-mcp-header")) {
25
+ const name = node["x-mcp-header"];
26
+ const type = node.type;
27
+ if (!path?.length ||
28
+ typeof name !== "string" ||
29
+ !/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(name) ||
30
+ names.has(name.toLowerCase()) ||
31
+ (type !== "string" && type !== "integer" && type !== "boolean"))
32
+ return false;
33
+ names.add(name.toLowerCase());
34
+ headers.push({ name, path, type });
35
+ }
36
+ // Only schema-valued keywords are traversed: examples/default/const are instance data.
37
+ for (const [keyword, value] of Object.entries(node)) {
38
+ if (["properties", "patternProperties", "$defs", "definitions", "dependentSchemas", "dependencies"].includes(keyword)) {
39
+ if (!isRecord(value))
40
+ continue;
41
+ for (const [key, child] of Object.entries(value)) {
42
+ const childPath = keyword === "properties" && path !== undefined ? [...path, key] : undefined;
43
+ if (!visit(child, childPath))
44
+ return false;
45
+ }
46
+ }
47
+ else if ([
48
+ "items",
49
+ "prefixItems",
50
+ "allOf",
51
+ "anyOf",
52
+ "oneOf",
53
+ "additionalItems",
54
+ "additionalProperties",
55
+ "unevaluatedItems",
56
+ "unevaluatedProperties",
57
+ "contains",
58
+ "propertyNames",
59
+ "not",
60
+ "if",
61
+ "then",
62
+ "else",
63
+ "contentSchema",
64
+ ].includes(keyword)) {
65
+ for (const child of Array.isArray(value) ? value : [value]) {
66
+ if (!visit(child, undefined))
67
+ return false;
68
+ }
69
+ }
70
+ }
71
+ return true;
72
+ };
73
+ return visit(schema, []) ? headers : undefined;
74
+ }
75
+ /** Connection-local catalog: never shared with another server or transport generation. */
76
+ export class ModernParameterHeaders {
77
+ #tools = new Map();
78
+ filterTools(tools, firstPage) {
79
+ if (firstPage)
80
+ this.#tools.clear();
81
+ return tools.filter((tool) => {
82
+ if (!isRecord(tool) || typeof tool.name !== "string")
83
+ return true;
84
+ const headers = parseParameterHeaders(tool.inputSchema);
85
+ if (headers === undefined) {
86
+ this.#tools.delete(tool.name);
87
+ return false;
88
+ }
89
+ this.#tools.set(tool.name, headers);
90
+ return true;
91
+ });
92
+ }
93
+ append(headers, name, args) {
94
+ if (typeof name !== "string")
95
+ return;
96
+ for (const parameter of this.#tools.get(name) ?? []) {
97
+ let value = args;
98
+ for (const key of parameter.path) {
99
+ value = isRecord(value) && Object.hasOwn(value, key) ? value[key] : undefined;
100
+ }
101
+ const valid = (parameter.type === "string" && typeof value === "string") ||
102
+ (parameter.type === "boolean" && typeof value === "boolean") ||
103
+ (parameter.type === "integer" && typeof value === "number" && Number.isSafeInteger(value));
104
+ if (valid)
105
+ headers.set(`Mcp-Param-${parameter.name}`, encodeMcpHeaderValue(String(value)));
106
+ }
107
+ }
108
+ }
109
+ //# sourceMappingURL=parameter-headers.js.map
@@ -0,0 +1,20 @@
1
+ import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { type McpClock } from "../wrap.ts";
3
+ export declare const MAX_MCP_MRTR_ROUNDS = 8;
4
+ /** Local dispatch guard survives SDK object spreads but is never JSON serialized. */
5
+ export declare const modernDispatchGuard: unique symbol;
6
+ export interface ModernProtocolState {
7
+ privateForms?: boolean;
8
+ legacyFormEligible?: boolean;
9
+ version?: string;
10
+ legacy?: boolean;
11
+ resolveStdioDiagnostics?: (modern: boolean) => void;
12
+ activateRequests?: () => void;
13
+ }
14
+ export type MrtrClock = McpClock;
15
+ export declare const isModernMcpClient: (client: Client) => boolean;
16
+ export declare const legacyMcpFormsAdvertised: (client: Client) => boolean | undefined;
17
+ export declare function getModernDispatchGuard(params: unknown): ((credential?: string) => void) | undefined;
18
+ /** One instance-local adapter. Captured SDK requests retain ID allocation and final output-schema validation. */
19
+ export declare function installModernRequestAdapter(client: Client, protocol: ModernProtocolState, clock?: MrtrClock, readCredential?: () => string | undefined): void;
20
+ //# sourceMappingURL=request.d.ts.map