@frontmcp/sdk 0.4.1 → 0.5.1

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 (558) hide show
  1. package/README.md +30 -18
  2. package/package.json +20 -5
  3. package/src/app/app.registry.d.ts +3 -2
  4. package/src/app/app.registry.js +3 -1
  5. package/src/app/app.registry.js.map +1 -1
  6. package/src/app/instances/app.local.instance.js +2 -2
  7. package/src/app/instances/app.local.instance.js.map +1 -1
  8. package/src/auth/auth.registry.d.ts +34 -2
  9. package/src/auth/auth.registry.js +162 -24
  10. package/src/auth/auth.registry.js.map +1 -1
  11. package/src/auth/auth.utils.js +8 -9
  12. package/src/auth/auth.utils.js.map +1 -1
  13. package/src/auth/authorization/authorization.class.d.ts +125 -0
  14. package/src/auth/authorization/authorization.class.js +224 -0
  15. package/src/auth/authorization/authorization.class.js.map +1 -0
  16. package/src/auth/authorization/authorization.types.d.ts +300 -0
  17. package/src/auth/authorization/authorization.types.js +79 -0
  18. package/src/auth/authorization/authorization.types.js.map +1 -0
  19. package/src/auth/authorization/index.d.ts +5 -0
  20. package/src/auth/authorization/index.js +19 -0
  21. package/src/auth/authorization/index.js.map +1 -0
  22. package/src/auth/authorization/orchestrated.authorization.d.ts +242 -0
  23. package/src/auth/authorization/orchestrated.authorization.js +306 -0
  24. package/src/auth/authorization/orchestrated.authorization.js.map +1 -0
  25. package/src/auth/authorization/public.authorization.d.ts +91 -0
  26. package/src/auth/authorization/public.authorization.js +132 -0
  27. package/src/auth/authorization/public.authorization.js.map +1 -0
  28. package/src/auth/authorization/transparent.authorization.d.ts +130 -0
  29. package/src/auth/authorization/transparent.authorization.js +147 -0
  30. package/src/auth/authorization/transparent.authorization.js.map +1 -0
  31. package/src/auth/consent/consent.types.d.ts +111 -0
  32. package/src/auth/consent/consent.types.js +119 -0
  33. package/src/auth/consent/consent.types.js.map +1 -0
  34. package/src/auth/consent/index.d.ts +1 -0
  35. package/src/auth/consent/index.js +13 -0
  36. package/src/auth/consent/index.js.map +1 -0
  37. package/src/auth/detection/auth-provider-detection.d.ts +84 -0
  38. package/src/auth/detection/auth-provider-detection.js +230 -0
  39. package/src/auth/detection/auth-provider-detection.js.map +1 -0
  40. package/src/auth/detection/index.d.ts +1 -0
  41. package/src/auth/detection/index.js +15 -0
  42. package/src/auth/detection/index.js.map +1 -0
  43. package/src/auth/flows/auth.verify.flow.d.ts +110 -0
  44. package/src/auth/flows/auth.verify.flow.js +379 -0
  45. package/src/auth/flows/auth.verify.flow.js.map +1 -0
  46. package/src/auth/flows/oauth.authorize.flow.d.ts +118 -164
  47. package/src/auth/flows/oauth.authorize.flow.js +701 -33
  48. package/src/auth/flows/oauth.authorize.flow.js.map +1 -1
  49. package/src/auth/flows/oauth.callback.flow.d.ts +117 -0
  50. package/src/auth/flows/oauth.callback.flow.js +357 -0
  51. package/src/auth/flows/oauth.callback.flow.js.map +1 -0
  52. package/src/auth/flows/oauth.register.flow.d.ts +32 -125
  53. package/src/auth/flows/oauth.token.flow.d.ts +52 -154
  54. package/src/auth/flows/oauth.token.flow.js +193 -55
  55. package/src/auth/flows/oauth.token.flow.js.map +1 -1
  56. package/src/auth/flows/session.verify.flow.d.ts +66 -321
  57. package/src/auth/flows/session.verify.flow.js +107 -18
  58. package/src/auth/flows/session.verify.flow.js.map +1 -1
  59. package/src/auth/flows/well-known.jwks.flow.d.ts +34 -205
  60. package/src/auth/flows/well-known.jwks.flow.js +15 -8
  61. package/src/auth/flows/well-known.jwks.flow.js.map +1 -1
  62. package/src/auth/flows/well-known.oauth-authorization-server.flow.d.ts +48 -223
  63. package/src/auth/flows/well-known.oauth-authorization-server.flow.js +2 -3
  64. package/src/auth/flows/well-known.oauth-authorization-server.flow.js.map +1 -1
  65. package/src/auth/flows/well-known.prm.flow.d.ts +19 -120
  66. package/src/auth/flows/well-known.prm.flow.js +3 -4
  67. package/src/auth/flows/well-known.prm.flow.js.map +1 -1
  68. package/src/auth/instances/instance.local-primary-auth.d.ts +91 -4
  69. package/src/auth/instances/instance.local-primary-auth.js +236 -6
  70. package/src/auth/instances/instance.local-primary-auth.js.map +1 -1
  71. package/src/auth/instances/instance.remote-primary-auth.d.ts +4 -3
  72. package/src/auth/instances/instance.remote-primary-auth.js +2 -2
  73. package/src/auth/instances/instance.remote-primary-auth.js.map +1 -1
  74. package/src/auth/session/authorization-vault.d.ts +611 -0
  75. package/src/auth/session/authorization-vault.js +817 -0
  76. package/src/auth/session/authorization-vault.js.map +1 -0
  77. package/src/auth/session/authorization.store.d.ts +301 -0
  78. package/src/auth/session/authorization.store.js +323 -0
  79. package/src/auth/session/authorization.store.js.map +1 -0
  80. package/src/auth/session/encrypted-authorization-vault.d.ts +181 -0
  81. package/src/auth/session/encrypted-authorization-vault.js +493 -0
  82. package/src/auth/session/encrypted-authorization-vault.js.map +1 -0
  83. package/src/auth/session/index.d.ts +4 -4
  84. package/src/auth/session/index.js +11 -7
  85. package/src/auth/session/index.js.map +1 -1
  86. package/src/auth/session/session.schema.d.ts +1 -1
  87. package/src/auth/session/session.service.d.ts +1 -1
  88. package/src/auth/session/transport-session.manager.d.ts +101 -0
  89. package/src/auth/session/transport-session.manager.js +300 -0
  90. package/src/auth/session/transport-session.manager.js.map +1 -0
  91. package/src/auth/session/transport-session.types.d.ts +457 -0
  92. package/src/auth/session/transport-session.types.js +110 -0
  93. package/src/auth/session/transport-session.types.js.map +1 -0
  94. package/src/auth/session/utils/session-id.utils.d.ts +14 -2
  95. package/src/auth/session/utils/session-id.utils.js +68 -19
  96. package/src/auth/session/utils/session-id.utils.js.map +1 -1
  97. package/src/auth/session/vault-encryption.d.ts +189 -0
  98. package/src/auth/session/vault-encryption.js +263 -0
  99. package/src/auth/session/vault-encryption.js.map +1 -0
  100. package/src/auth/ui/base-layout.d.ts +188 -0
  101. package/src/auth/ui/base-layout.js +292 -0
  102. package/src/auth/ui/base-layout.js.map +1 -0
  103. package/src/auth/ui/htmx-templates.d.ts +135 -0
  104. package/src/auth/ui/htmx-templates.js +433 -0
  105. package/src/auth/ui/htmx-templates.js.map +1 -0
  106. package/src/auth/ui/index.d.ts +11 -0
  107. package/src/auth/ui/index.js +35 -0
  108. package/src/auth/ui/index.js.map +1 -0
  109. package/src/auth/utils/audience.validator.d.ts +129 -0
  110. package/src/auth/utils/audience.validator.js +196 -0
  111. package/src/auth/utils/audience.validator.js.map +1 -0
  112. package/src/auth/utils/index.d.ts +2 -0
  113. package/src/auth/utils/index.js +7 -0
  114. package/src/auth/utils/index.js.map +1 -0
  115. package/src/auth/utils/www-authenticate.utils.d.ts +97 -0
  116. package/src/auth/utils/www-authenticate.utils.js +183 -0
  117. package/src/auth/utils/www-authenticate.utils.js.map +1 -0
  118. package/src/common/common.schema.d.ts +2 -16
  119. package/src/common/constants.d.ts +3 -0
  120. package/src/common/constants.js +6 -1
  121. package/src/common/constants.js.map +1 -1
  122. package/src/common/decorators/decorator-utils.d.ts +131 -0
  123. package/src/common/decorators/decorator-utils.js +195 -0
  124. package/src/common/decorators/decorator-utils.js.map +1 -0
  125. package/src/common/decorators/front-mcp.decorator.js +3 -2
  126. package/src/common/decorators/front-mcp.decorator.js.map +1 -1
  127. package/src/common/decorators/hook.decorator.d.ts +58 -2
  128. package/src/common/decorators/hook.decorator.js +127 -17
  129. package/src/common/decorators/hook.decorator.js.map +1 -1
  130. package/src/common/decorators/plugin.decorator.d.ts +1 -1
  131. package/src/common/decorators/plugin.decorator.js +11 -10
  132. package/src/common/decorators/plugin.decorator.js.map +1 -1
  133. package/src/common/decorators/resource.decorator.d.ts +32 -3
  134. package/src/common/decorators/resource.decorator.js +46 -4
  135. package/src/common/decorators/resource.decorator.js.map +1 -1
  136. package/src/common/decorators/tool.decorator.d.ts +54 -5
  137. package/src/common/decorators/tool.decorator.js.map +1 -1
  138. package/src/common/dynamic/dynamic.plugin.d.ts +22 -11
  139. package/src/common/dynamic/dynamic.plugin.js +7 -1
  140. package/src/common/dynamic/dynamic.plugin.js.map +1 -1
  141. package/src/common/entries/prompt.entry.d.ts +46 -2
  142. package/src/common/entries/prompt.entry.js +10 -0
  143. package/src/common/entries/prompt.entry.js.map +1 -1
  144. package/src/common/entries/resource.entry.d.ts +69 -6
  145. package/src/common/entries/resource.entry.js +27 -3
  146. package/src/common/entries/resource.entry.js.map +1 -1
  147. package/src/common/entries/scope.entry.d.ts +5 -1
  148. package/src/common/entries/scope.entry.js +3 -3
  149. package/src/common/entries/scope.entry.js.map +1 -1
  150. package/src/common/flow/flow.utils.d.ts +56 -0
  151. package/src/common/flow/flow.utils.js +96 -0
  152. package/src/common/flow/flow.utils.js.map +1 -0
  153. package/src/common/index.d.ts +2 -2
  154. package/src/common/index.js +2 -2
  155. package/src/common/index.js.map +1 -1
  156. package/src/common/interfaces/execution-context.interface.d.ts +59 -0
  157. package/src/common/interfaces/execution-context.interface.js +81 -0
  158. package/src/common/interfaces/execution-context.interface.js.map +1 -0
  159. package/src/common/interfaces/flow.interface.d.ts +1 -1
  160. package/src/common/interfaces/flow.interface.js.map +1 -1
  161. package/src/common/interfaces/index.d.ts +1 -0
  162. package/src/common/interfaces/index.js +1 -0
  163. package/src/common/interfaces/index.js.map +1 -1
  164. package/src/common/interfaces/internal/primary-auth-provider.interface.d.ts +17 -2
  165. package/src/common/interfaces/internal/primary-auth-provider.interface.js +52 -4
  166. package/src/common/interfaces/internal/primary-auth-provider.interface.js.map +1 -1
  167. package/src/common/interfaces/internal/registry.interface.d.ts +16 -2
  168. package/src/common/interfaces/internal/registry.interface.js.map +1 -1
  169. package/src/common/interfaces/plugin.interface.js.map +1 -1
  170. package/src/common/interfaces/prompt.interface.d.ts +53 -4
  171. package/src/common/interfaces/prompt.interface.js +78 -0
  172. package/src/common/interfaces/prompt.interface.js.map +1 -1
  173. package/src/common/interfaces/resource.interface.d.ts +47 -17
  174. package/src/common/interfaces/resource.interface.js +53 -0
  175. package/src/common/interfaces/resource.interface.js.map +1 -1
  176. package/src/common/interfaces/tool.interface.d.ts +39 -22
  177. package/src/common/interfaces/tool.interface.js +61 -34
  178. package/src/common/interfaces/tool.interface.js.map +1 -1
  179. package/src/common/metadata/adapter.metadata.d.ts +1 -9
  180. package/src/common/metadata/app.metadata.d.ts +425 -730
  181. package/src/common/metadata/auth-provider.metadata.d.ts +2 -12
  182. package/src/common/metadata/flow.metadata.d.ts +10 -25
  183. package/src/common/metadata/front-mcp.metadata.d.ts +602 -1023
  184. package/src/common/metadata/front-mcp.metadata.js +6 -4
  185. package/src/common/metadata/front-mcp.metadata.js.map +1 -1
  186. package/src/common/metadata/hook.metadata.d.ts +1 -1
  187. package/src/common/metadata/hook.metadata.js.map +1 -1
  188. package/src/common/metadata/index.d.ts +1 -0
  189. package/src/common/metadata/index.js +1 -0
  190. package/src/common/metadata/index.js.map +1 -1
  191. package/src/common/metadata/logger.metadata.d.ts +1 -9
  192. package/src/common/metadata/plugin.metadata.d.ts +8 -30
  193. package/src/common/metadata/prompt.metadata.d.ts +4 -161
  194. package/src/common/metadata/provider.metadata.d.ts +2 -12
  195. package/src/common/metadata/resource.metadata.d.ts +6 -98
  196. package/src/common/metadata/resource.metadata.js +15 -6
  197. package/src/common/metadata/resource.metadata.js.map +1 -1
  198. package/src/common/metadata/tool-ui.metadata.d.ts +10 -0
  199. package/src/common/metadata/tool-ui.metadata.js +12 -0
  200. package/src/common/metadata/tool-ui.metadata.js.map +1 -0
  201. package/src/common/metadata/tool.metadata.d.ts +110 -199
  202. package/src/common/metadata/tool.metadata.js +11 -14
  203. package/src/common/metadata/tool.metadata.js.map +1 -1
  204. package/src/common/providers/base-config.provider.d.ts +84 -0
  205. package/src/common/providers/base-config.provider.js +128 -0
  206. package/src/common/providers/base-config.provider.js.map +1 -0
  207. package/src/common/records/plugin.record.d.ts +5 -6
  208. package/src/common/records/plugin.record.js.map +1 -1
  209. package/src/common/records/prompt.record.js.map +1 -1
  210. package/src/common/records/resource.record.d.ts +17 -1
  211. package/src/common/records/resource.record.js +12 -6
  212. package/src/common/records/resource.record.js.map +1 -1
  213. package/src/common/records/tool.record.js.map +1 -1
  214. package/src/common/schemas/annotated-class.schema.d.ts +9 -9
  215. package/src/common/schemas/annotated-class.schema.js +92 -27
  216. package/src/common/schemas/annotated-class.schema.js.map +1 -1
  217. package/src/common/schemas/http-input.schema.d.ts +6 -30
  218. package/src/common/schemas/http-output.schema.d.ts +336 -1632
  219. package/src/common/schemas/http-output.schema.js +39 -1
  220. package/src/common/schemas/http-output.schema.js.map +1 -1
  221. package/src/common/tokens/front-mcp.tokens.js +4 -1
  222. package/src/common/tokens/front-mcp.tokens.js.map +1 -1
  223. package/src/common/tokens/resource.tokens.d.ts +2 -0
  224. package/src/common/tokens/resource.tokens.js +4 -1
  225. package/src/common/tokens/resource.tokens.js.map +1 -1
  226. package/src/common/tokens/tool.tokens.d.ts +2 -0
  227. package/src/common/tokens/tool.tokens.js +2 -0
  228. package/src/common/tokens/tool.tokens.js.map +1 -1
  229. package/src/common/types/auth/jwt.types.d.ts +5 -31
  230. package/src/common/types/auth/session.types.d.ts +97 -192
  231. package/src/common/types/auth/session.types.js +24 -11
  232. package/src/common/types/auth/session.types.js.map +1 -1
  233. package/src/common/types/options/auth.options.d.ts +1013 -490
  234. package/src/common/types/options/auth.options.js +554 -36
  235. package/src/common/types/options/auth.options.js.map +1 -1
  236. package/src/common/types/options/http.options.d.ts +1 -9
  237. package/src/common/types/options/logging.options.d.ts +7 -13
  238. package/src/common/types/options/logging.options.js +4 -0
  239. package/src/common/types/options/logging.options.js.map +1 -1
  240. package/src/common/types/options/server-info.options.d.ts +3 -31
  241. package/src/common/types/options/session.options.d.ts +90 -10
  242. package/src/common/types/options/session.options.js +26 -3
  243. package/src/common/types/options/session.options.js.map +1 -1
  244. package/src/common/utils/decide-request-intent.utils.d.ts +8 -46
  245. package/src/common/utils/decide-request-intent.utils.js +88 -23
  246. package/src/common/utils/decide-request-intent.utils.js.map +1 -1
  247. package/src/completion/flows/complete.flow.d.ts +89 -0
  248. package/src/completion/flows/complete.flow.js +199 -0
  249. package/src/completion/flows/complete.flow.js.map +1 -0
  250. package/src/errors/authorization-required.error.d.ts +189 -0
  251. package/src/errors/authorization-required.error.js +274 -0
  252. package/src/errors/authorization-required.error.js.map +1 -0
  253. package/src/errors/index.d.ts +2 -1
  254. package/src/errors/index.js +17 -1
  255. package/src/errors/index.js.map +1 -1
  256. package/src/errors/mcp.error.d.ts +101 -1
  257. package/src/errors/mcp.error.js +147 -2
  258. package/src/errors/mcp.error.js.map +1 -1
  259. package/src/flows/flow.instance.js +4 -3
  260. package/src/flows/flow.instance.js.map +1 -1
  261. package/src/flows/flow.registry.js.map +1 -1
  262. package/src/flows/flow.stages.js +14 -11
  263. package/src/flows/flow.stages.js.map +1 -1
  264. package/src/front-mcp/front-mcp.providers.d.ts +464 -102
  265. package/src/front-mcp/front-mcp.providers.js +3 -5
  266. package/src/front-mcp/front-mcp.providers.js.map +1 -1
  267. package/src/hooks/hook.instance.d.ts +1 -1
  268. package/src/hooks/hook.instance.js +5 -2
  269. package/src/hooks/hook.instance.js.map +1 -1
  270. package/src/hooks/hook.registry.js +7 -5
  271. package/src/hooks/hook.registry.js.map +1 -1
  272. package/src/index.d.ts +28 -9
  273. package/src/index.js +5 -1
  274. package/src/index.js.map +1 -1
  275. package/src/logger/instances/instance.logger.js +3 -2
  276. package/src/logger/instances/instance.logger.js.map +1 -1
  277. package/src/logger/logger.registry.js +7 -2
  278. package/src/logger/logger.registry.js.map +1 -1
  279. package/src/logging/flows/set-level.flow.d.ts +77 -0
  280. package/src/logging/flows/set-level.flow.js +108 -0
  281. package/src/logging/flows/set-level.flow.js.map +1 -0
  282. package/src/mcp-apps/csp.d.ts +111 -0
  283. package/src/mcp-apps/csp.js +267 -0
  284. package/src/mcp-apps/csp.js.map +1 -0
  285. package/src/mcp-apps/index.d.ts +23 -0
  286. package/src/mcp-apps/index.js +91 -0
  287. package/src/mcp-apps/index.js.map +1 -0
  288. package/src/mcp-apps/schemas.d.ts +403 -0
  289. package/src/mcp-apps/schemas.js +345 -0
  290. package/src/mcp-apps/schemas.js.map +1 -0
  291. package/src/mcp-apps/template.d.ts +94 -0
  292. package/src/mcp-apps/template.js +419 -0
  293. package/src/mcp-apps/template.js.map +1 -0
  294. package/src/mcp-apps/types.d.ts +323 -0
  295. package/src/mcp-apps/types.js +59 -0
  296. package/src/mcp-apps/types.js.map +1 -0
  297. package/src/notification/index.d.ts +1 -0
  298. package/src/notification/index.js +13 -0
  299. package/src/notification/index.js.map +1 -0
  300. package/src/notification/notification.service.d.ts +378 -0
  301. package/src/notification/notification.service.js +727 -0
  302. package/src/notification/notification.service.js.map +1 -0
  303. package/src/plugin/plugin.registry.js +12 -9
  304. package/src/plugin/plugin.registry.js.map +1 -1
  305. package/src/prompt/flows/get-prompt.flow.d.ts +248 -0
  306. package/src/prompt/flows/get-prompt.flow.js +214 -0
  307. package/src/prompt/flows/get-prompt.flow.js.map +1 -0
  308. package/src/prompt/flows/prompts-list.flow.d.ts +78 -0
  309. package/src/prompt/flows/prompts-list.flow.js +176 -0
  310. package/src/prompt/flows/prompts-list.flow.js.map +1 -0
  311. package/src/prompt/index.d.ts +7 -0
  312. package/src/prompt/index.js +17 -0
  313. package/src/prompt/index.js.map +1 -0
  314. package/src/prompt/prompt.events.d.ts +17 -0
  315. package/src/prompt/prompt.events.js +25 -0
  316. package/src/prompt/prompt.events.js.map +1 -0
  317. package/src/prompt/prompt.instance.d.ts +30 -0
  318. package/src/prompt/prompt.instance.js +120 -0
  319. package/src/prompt/prompt.instance.js.map +1 -0
  320. package/src/prompt/prompt.registry.d.ts +79 -12
  321. package/src/prompt/prompt.registry.js +360 -15
  322. package/src/prompt/prompt.registry.js.map +1 -1
  323. package/src/prompt/prompt.types.d.ts +26 -0
  324. package/src/prompt/prompt.types.js +11 -0
  325. package/src/prompt/prompt.types.js.map +1 -0
  326. package/src/prompt/prompt.utils.d.ts +26 -0
  327. package/src/prompt/prompt.utils.js +136 -0
  328. package/src/prompt/prompt.utils.js.map +1 -0
  329. package/src/provider/provider.registry.d.ts +12 -5
  330. package/src/provider/provider.registry.js +30 -138
  331. package/src/provider/provider.registry.js.map +1 -1
  332. package/src/regsitry/registry.base.d.ts +1 -1
  333. package/src/regsitry/registry.base.js.map +1 -1
  334. package/src/resource/flows/read-resource.flow.d.ts +110 -0
  335. package/src/resource/flows/read-resource.flow.js +270 -0
  336. package/src/resource/flows/read-resource.flow.js.map +1 -0
  337. package/src/resource/flows/resource-templates-list.flow.d.ts +83 -0
  338. package/src/resource/flows/resource-templates-list.flow.js +191 -0
  339. package/src/resource/flows/resource-templates-list.flow.js.map +1 -0
  340. package/src/resource/flows/resources-list.flow.d.ts +83 -0
  341. package/src/resource/flows/resources-list.flow.js +196 -0
  342. package/src/resource/flows/resources-list.flow.js.map +1 -0
  343. package/src/resource/flows/subscribe-resource.flow.d.ts +60 -0
  344. package/src/resource/flows/subscribe-resource.flow.js +123 -0
  345. package/src/resource/flows/subscribe-resource.flow.js.map +1 -0
  346. package/src/resource/flows/unsubscribe-resource.flow.d.ts +59 -0
  347. package/src/resource/flows/unsubscribe-resource.flow.js +107 -0
  348. package/src/resource/flows/unsubscribe-resource.flow.js.map +1 -0
  349. package/src/resource/index.d.ts +8 -0
  350. package/src/resource/index.js +20 -0
  351. package/src/resource/index.js.map +1 -0
  352. package/src/resource/resource.events.d.ts +24 -0
  353. package/src/resource/resource.events.js +17 -0
  354. package/src/resource/resource.events.js.map +1 -0
  355. package/src/resource/resource.instance.d.ts +35 -0
  356. package/src/resource/resource.instance.js +163 -0
  357. package/src/resource/resource.instance.js.map +1 -0
  358. package/src/resource/resource.registry.d.ts +106 -12
  359. package/src/resource/resource.registry.js +449 -13
  360. package/src/resource/resource.registry.js.map +1 -1
  361. package/src/resource/resource.types.d.ts +35 -0
  362. package/src/resource/resource.types.js +11 -0
  363. package/src/resource/resource.types.js.map +1 -0
  364. package/src/resource/resource.utils.d.ts +30 -0
  365. package/src/resource/resource.utils.js +151 -0
  366. package/src/resource/resource.utils.js.map +1 -0
  367. package/src/scope/flows/http.request.flow.d.ts +48 -330
  368. package/src/scope/flows/http.request.flow.js +306 -78
  369. package/src/scope/flows/http.request.flow.js.map +1 -1
  370. package/src/scope/scope.instance.d.ts +12 -0
  371. package/src/scope/scope.instance.js +145 -15
  372. package/src/scope/scope.instance.js.map +1 -1
  373. package/src/tool/flows/call-tool.flow.d.ts +161 -1112
  374. package/src/tool/flows/call-tool.flow.js +303 -15
  375. package/src/tool/flows/call-tool.flow.js.map +1 -1
  376. package/src/tool/flows/tools-list.flow.d.ts +51 -474
  377. package/src/tool/flows/tools-list.flow.js +121 -40
  378. package/src/tool/flows/tools-list.flow.js.map +1 -1
  379. package/src/tool/tool.events.d.ts +8 -1
  380. package/src/tool/tool.events.js.map +1 -1
  381. package/src/tool/tool.instance.d.ts +3 -1
  382. package/src/tool/tool.instance.js +17 -3
  383. package/src/tool/tool.instance.js.map +1 -1
  384. package/src/tool/tool.registry.d.ts +7 -1
  385. package/src/tool/tool.registry.js +26 -10
  386. package/src/tool/tool.registry.js.map +1 -1
  387. package/src/tool/tool.types.d.ts +4 -4
  388. package/src/tool/tool.types.js.map +1 -1
  389. package/src/tool/tool.utils.d.ts +3 -12
  390. package/src/tool/tool.utils.js +39 -193
  391. package/src/tool/tool.utils.js.map +1 -1
  392. package/src/tool/ui/index.d.ts +22 -0
  393. package/src/tool/ui/index.js +63 -0
  394. package/src/tool/ui/index.js.map +1 -0
  395. package/src/tool/ui/platform-adapters.d.ts +10 -0
  396. package/src/tool/ui/platform-adapters.js +18 -0
  397. package/src/tool/ui/platform-adapters.js.map +1 -0
  398. package/src/tool/ui/template-helpers.d.ts +46 -0
  399. package/src/tool/ui/template-helpers.js +112 -0
  400. package/src/tool/ui/template-helpers.js.map +1 -0
  401. package/src/tool/ui/ui-resource-template.d.ts +34 -0
  402. package/src/tool/ui/ui-resource-template.js +64 -0
  403. package/src/tool/ui/ui-resource-template.js.map +1 -0
  404. package/src/tool/ui/ui-resource.handler.d.ts +74 -0
  405. package/src/tool/ui/ui-resource.handler.js +129 -0
  406. package/src/tool/ui/ui-resource.handler.js.map +1 -0
  407. package/src/transport/adapters/transport.local.adapter.d.ts +2 -2
  408. package/src/transport/adapters/transport.local.adapter.js +28 -7
  409. package/src/transport/adapters/transport.local.adapter.js.map +1 -1
  410. package/src/transport/adapters/transport.sse.adapter.d.ts +2 -2
  411. package/src/transport/adapters/transport.sse.adapter.js +4 -3
  412. package/src/transport/adapters/transport.sse.adapter.js.map +1 -1
  413. package/src/transport/adapters/transport.streamable-http.adapter.d.ts +10 -3
  414. package/src/transport/adapters/transport.streamable-http.adapter.js +54 -8
  415. package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
  416. package/src/transport/flows/handle.sse.flow.d.ts +29 -63
  417. package/src/transport/flows/handle.sse.flow.js +78 -10
  418. package/src/transport/flows/handle.sse.flow.js.map +1 -1
  419. package/src/transport/flows/handle.stateless-http.flow.d.ts +29 -0
  420. package/src/transport/flows/handle.stateless-http.flow.js +102 -0
  421. package/src/transport/flows/handle.stateless-http.flow.js.map +1 -0
  422. package/src/transport/flows/handle.streamable-http.flow.d.ts +32 -64
  423. package/src/transport/flows/handle.streamable-http.flow.js +158 -26
  424. package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
  425. package/src/transport/legacy/legacy.sse.tranporter.d.ts +9 -0
  426. package/src/transport/legacy/legacy.sse.tranporter.js +17 -2
  427. package/src/transport/legacy/legacy.sse.tranporter.js.map +1 -1
  428. package/src/transport/mcp-handlers/call-tool-request.handler.js +27 -1
  429. package/src/transport/mcp-handlers/call-tool-request.handler.js.map +1 -1
  430. package/src/transport/mcp-handlers/complete-request.handler.d.ts +95 -0
  431. package/src/transport/mcp-handlers/complete-request.handler.js +11 -0
  432. package/src/transport/mcp-handlers/complete-request.handler.js.map +1 -0
  433. package/src/transport/mcp-handlers/get-prompt-request.handler.d.ts +138 -0
  434. package/src/transport/mcp-handlers/get-prompt-request.handler.js +11 -0
  435. package/src/transport/mcp-handlers/get-prompt-request.handler.js.map +1 -0
  436. package/src/transport/mcp-handlers/index.d.ts +922 -207
  437. package/src/transport/mcp-handlers/index.js +39 -2
  438. package/src/transport/mcp-handlers/index.js.map +1 -1
  439. package/src/transport/mcp-handlers/initialize-request.handler.d.ts +1 -1
  440. package/src/transport/mcp-handlers/initialize-request.handler.js +73 -7
  441. package/src/transport/mcp-handlers/initialize-request.handler.js.map +1 -1
  442. package/src/transport/mcp-handlers/list-prompts-request.handler.d.ts +80 -0
  443. package/src/transport/mcp-handlers/list-prompts-request.handler.js +11 -0
  444. package/src/transport/mcp-handlers/list-prompts-request.handler.js.map +1 -0
  445. package/src/transport/mcp-handlers/list-resource-templates-request.handler.d.ts +82 -0
  446. package/src/transport/mcp-handlers/list-resource-templates-request.handler.js +12 -0
  447. package/src/transport/mcp-handlers/list-resource-templates-request.handler.js.map +1 -0
  448. package/src/transport/mcp-handlers/list-resources-request.handler.d.ts +82 -0
  449. package/src/transport/mcp-handlers/list-resources-request.handler.js +12 -0
  450. package/src/transport/mcp-handlers/list-resources-request.handler.js.map +1 -0
  451. package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +47 -145
  452. package/src/transport/mcp-handlers/logging-set-level-request.handler.d.ts +66 -0
  453. package/src/transport/mcp-handlers/logging-set-level-request.handler.js +34 -0
  454. package/src/transport/mcp-handlers/logging-set-level-request.handler.js.map +1 -0
  455. package/src/transport/mcp-handlers/mcp-handlers.types.d.ts +3 -7
  456. package/src/transport/mcp-handlers/mcp-handlers.types.js.map +1 -1
  457. package/src/transport/mcp-handlers/read-resource-request.handler.d.ts +72 -0
  458. package/src/transport/mcp-handlers/read-resource-request.handler.js +12 -0
  459. package/src/transport/mcp-handlers/read-resource-request.handler.js.map +1 -0
  460. package/src/transport/mcp-handlers/roots-list-changed-notification.handler.d.ts +11 -0
  461. package/src/transport/mcp-handlers/roots-list-changed-notification.handler.js +26 -0
  462. package/src/transport/mcp-handlers/roots-list-changed-notification.handler.js.map +1 -0
  463. package/src/transport/mcp-handlers/subscribe-request.handler.d.ts +57 -0
  464. package/src/transport/mcp-handlers/subscribe-request.handler.js +34 -0
  465. package/src/transport/mcp-handlers/subscribe-request.handler.js.map +1 -0
  466. package/src/transport/mcp-handlers/unsubscribe-request.handler.d.ts +57 -0
  467. package/src/transport/mcp-handlers/unsubscribe-request.handler.js +34 -0
  468. package/src/transport/mcp-handlers/unsubscribe-request.handler.js.map +1 -0
  469. package/src/transport/transport.local.js +7 -2
  470. package/src/transport/transport.local.js.map +1 -1
  471. package/src/transport/transport.registry.d.ts +30 -0
  472. package/src/transport/transport.registry.js +84 -1
  473. package/src/transport/transport.registry.js.map +1 -1
  474. package/src/transport/transport.types.d.ts +3 -3
  475. package/src/transport/transport.types.js.map +1 -1
  476. package/src/utils/content.utils.d.ts +48 -0
  477. package/src/utils/content.utils.js +194 -0
  478. package/src/utils/content.utils.js.map +1 -0
  479. package/src/utils/index.d.ts +8 -0
  480. package/src/utils/index.js +55 -0
  481. package/src/utils/index.js.map +1 -0
  482. package/src/utils/lineage.utils.d.ts +40 -0
  483. package/src/utils/lineage.utils.js +82 -0
  484. package/src/utils/lineage.utils.js.map +1 -0
  485. package/src/utils/naming.utils.d.ts +46 -0
  486. package/src/utils/naming.utils.js +136 -0
  487. package/src/utils/naming.utils.js.map +1 -0
  488. package/src/utils/types.utils.d.ts +2 -2
  489. package/src/utils/types.utils.js.map +1 -1
  490. package/src/utils/uri-template.utils.d.ts +57 -0
  491. package/src/utils/uri-template.utils.js +113 -0
  492. package/src/utils/uri-template.utils.js.map +1 -0
  493. package/src/utils/uri-validation.utils.d.ts +40 -0
  494. package/src/utils/uri-validation.utils.js +76 -0
  495. package/src/utils/uri-validation.utils.js.map +1 -0
  496. package/src/__test-utils__/fixtures/hook.fixtures.d.ts +0 -46
  497. package/src/__test-utils__/fixtures/hook.fixtures.js +0 -114
  498. package/src/__test-utils__/fixtures/hook.fixtures.js.map +0 -1
  499. package/src/__test-utils__/fixtures/index.d.ts +0 -7
  500. package/src/__test-utils__/fixtures/index.js +0 -11
  501. package/src/__test-utils__/fixtures/index.js.map +0 -1
  502. package/src/__test-utils__/fixtures/plugin.fixtures.d.ts +0 -46
  503. package/src/__test-utils__/fixtures/plugin.fixtures.js +0 -127
  504. package/src/__test-utils__/fixtures/plugin.fixtures.js.map +0 -1
  505. package/src/__test-utils__/fixtures/provider.fixtures.d.ts +0 -69
  506. package/src/__test-utils__/fixtures/provider.fixtures.js +0 -131
  507. package/src/__test-utils__/fixtures/provider.fixtures.js.map +0 -1
  508. package/src/__test-utils__/fixtures/scope.fixtures.d.ts +0 -14
  509. package/src/__test-utils__/fixtures/scope.fixtures.js +0 -59
  510. package/src/__test-utils__/fixtures/scope.fixtures.js.map +0 -1
  511. package/src/__test-utils__/fixtures/tool.fixtures.d.ts +0 -36
  512. package/src/__test-utils__/fixtures/tool.fixtures.js +0 -91
  513. package/src/__test-utils__/fixtures/tool.fixtures.js.map +0 -1
  514. package/src/__test-utils__/helpers/assertion.helpers.d.ts +0 -45
  515. package/src/__test-utils__/helpers/assertion.helpers.js +0 -153
  516. package/src/__test-utils__/helpers/assertion.helpers.js.map +0 -1
  517. package/src/__test-utils__/helpers/async.helpers.d.ts +0 -48
  518. package/src/__test-utils__/helpers/async.helpers.js +0 -112
  519. package/src/__test-utils__/helpers/async.helpers.js.map +0 -1
  520. package/src/__test-utils__/helpers/index.d.ts +0 -6
  521. package/src/__test-utils__/helpers/index.js +0 -10
  522. package/src/__test-utils__/helpers/index.js.map +0 -1
  523. package/src/__test-utils__/helpers/setup.helpers.d.ts +0 -54
  524. package/src/__test-utils__/helpers/setup.helpers.js +0 -106
  525. package/src/__test-utils__/helpers/setup.helpers.js.map +0 -1
  526. package/src/__test-utils__/index.d.ts +0 -9
  527. package/src/__test-utils__/index.js +0 -14
  528. package/src/__test-utils__/index.js.map +0 -1
  529. package/src/__test-utils__/mocks/flow-instance.mock.d.ts +0 -50
  530. package/src/__test-utils__/mocks/flow-instance.mock.js +0 -72
  531. package/src/__test-utils__/mocks/flow-instance.mock.js.map +0 -1
  532. package/src/__test-utils__/mocks/hook-registry.mock.d.ts +0 -25
  533. package/src/__test-utils__/mocks/hook-registry.mock.js +0 -65
  534. package/src/__test-utils__/mocks/hook-registry.mock.js.map +0 -1
  535. package/src/__test-utils__/mocks/index.d.ts +0 -8
  536. package/src/__test-utils__/mocks/index.js +0 -12
  537. package/src/__test-utils__/mocks/index.js.map +0 -1
  538. package/src/__test-utils__/mocks/plugin-registry.mock.d.ts +0 -43
  539. package/src/__test-utils__/mocks/plugin-registry.mock.js +0 -70
  540. package/src/__test-utils__/mocks/plugin-registry.mock.js.map +0 -1
  541. package/src/__test-utils__/mocks/provider-registry.mock.d.ts +0 -39
  542. package/src/__test-utils__/mocks/provider-registry.mock.js +0 -72
  543. package/src/__test-utils__/mocks/provider-registry.mock.js.map +0 -1
  544. package/src/__test-utils__/mocks/tool-registry.mock.d.ts +0 -43
  545. package/src/__test-utils__/mocks/tool-registry.mock.js +0 -79
  546. package/src/__test-utils__/mocks/tool-registry.mock.js.map +0 -1
  547. package/src/auth/path.utils.d.ts +0 -20
  548. package/src/auth/path.utils.js +0 -71
  549. package/src/auth/path.utils.js.map +0 -1
  550. package/src/common/decorators-old/async-with.decorator.d.ts +0 -10
  551. package/src/common/decorators-old/async-with.decorator.js +0 -24
  552. package/src/common/decorators-old/async-with.decorator.js.map +0 -1
  553. package/src/common/decorators-old/auth-hook.decorator.d.ts +0 -14
  554. package/src/common/decorators-old/auth-hook.decorator.js +0 -27
  555. package/src/common/decorators-old/auth-hook.decorator.js.map +0 -1
  556. package/src/common/decorators-old/session-hook.decorator.d.ts +0 -14
  557. package/src/common/decorators-old/session-hook.decorator.js +0 -27
  558. package/src/common/decorators-old/session-hook.decorator.js.map +0 -1
@@ -0,0 +1,57 @@
1
+ import { UnsubscribeRequest, EmptyResult } from '@modelcontextprotocol/sdk/types.js';
2
+ import { McpHandlerOptions } from './mcp-handlers.types';
3
+ /**
4
+ * Handler for the resources/unsubscribe MCP request.
5
+ * Per MCP 2025-11-25 spec, this allows clients to unsubscribe from
6
+ * receiving notifications about a specific resource.
7
+ */
8
+ export default function UnsubscribeRequestHandler({ scope }: McpHandlerOptions): {
9
+ requestSchema: import("zod").ZodObject<{
10
+ method: import("zod").ZodLiteral<"resources/unsubscribe">;
11
+ params: import("zod").ZodObject<{
12
+ task: import("zod").ZodOptional<import("zod").ZodObject<{
13
+ ttl: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodNumber, import("zod").ZodNull]>>;
14
+ pollInterval: import("zod").ZodOptional<import("zod").ZodNumber>;
15
+ }, import("zod/v4/core").$loose>>;
16
+ _meta: import("zod").ZodOptional<import("zod").ZodObject<{
17
+ progressToken: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>>;
18
+ "io.modelcontextprotocol/related-task": import("zod").ZodOptional<import("zod").ZodObject<{
19
+ taskId: import("zod").ZodString;
20
+ }, import("zod/v4/core").$loose>>;
21
+ }, import("zod/v4/core").$loose>>;
22
+ uri: import("zod").ZodString;
23
+ }, import("zod/v4/core").$loose>;
24
+ }, import("zod/v4/core").$strip>;
25
+ handler: (request: UnsubscribeRequest, ctx: import("./mcp-handlers.types").McpRequestHandler<{
26
+ method: "resources/unsubscribe";
27
+ params: {
28
+ [x: string]: unknown;
29
+ uri: string;
30
+ task?: {
31
+ [x: string]: unknown;
32
+ ttl?: number | null | undefined;
33
+ pollInterval?: number | undefined;
34
+ } | undefined;
35
+ _meta?: {
36
+ [x: string]: unknown;
37
+ progressToken?: string | number | undefined;
38
+ "io.modelcontextprotocol/related-task"?: {
39
+ [x: string]: unknown;
40
+ taskId: string;
41
+ } | undefined;
42
+ } | undefined;
43
+ };
44
+ }, {
45
+ method: string;
46
+ params?: {
47
+ [x: string]: unknown;
48
+ _meta?: {
49
+ [x: string]: unknown;
50
+ "io.modelcontextprotocol/related-task"?: {
51
+ [x: string]: unknown;
52
+ taskId: string;
53
+ } | undefined;
54
+ } | undefined;
55
+ } | undefined;
56
+ }>) => Promise<EmptyResult>;
57
+ };
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = UnsubscribeRequestHandler;
4
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
5
+ /**
6
+ * Handler for the resources/unsubscribe MCP request.
7
+ * Per MCP 2025-11-25 spec, this allows clients to unsubscribe from
8
+ * receiving notifications about a specific resource.
9
+ */
10
+ function UnsubscribeRequestHandler({ scope }) {
11
+ return {
12
+ requestSchema: types_js_1.UnsubscribeRequestSchema,
13
+ handler: async (request, ctx) => {
14
+ const { uri } = request.params;
15
+ // Get session ID from auth context
16
+ const sessionId = ctx.authInfo?.sessionId;
17
+ if (!sessionId) {
18
+ scope.logger.warn('resources/unsubscribe: No session ID found in request context');
19
+ return {};
20
+ }
21
+ // Unsubscribe the session from the resource
22
+ const wasSubscribed = scope.notifications.unsubscribeResource(sessionId, uri);
23
+ if (wasSubscribed) {
24
+ scope.logger.verbose(`resources/unsubscribe: Session ${sessionId.slice(0, 20)}... unsubscribed from ${uri}`);
25
+ }
26
+ else {
27
+ scope.logger.verbose(`resources/unsubscribe: Session ${sessionId.slice(0, 20)}... was not subscribed to ${uri}`);
28
+ }
29
+ // Per MCP spec, return empty result
30
+ return {};
31
+ },
32
+ };
33
+ }
34
+ //# sourceMappingURL=unsubscribe-request.handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unsubscribe-request.handler.js","sourceRoot":"","sources":["../../../../src/transport/mcp-handlers/unsubscribe-request.handler.ts"],"names":[],"mappings":";;AAQA,4CA4BC;AApCD,iEAA+G;AAG/G;;;;GAIG;AACH,SAAwB,yBAAyB,CAAC,EAAE,KAAK,EAAqB;IAC5E,OAAO;QACL,aAAa,EAAE,mCAAwB;QACvC,OAAO,EAAE,KAAK,EAAE,OAA2B,EAAE,GAAG,EAAwB,EAAE;YACxE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;YAE/B,mCAAmC;YACnC,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC;YAC1C,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;gBACnF,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,4CAA4C;YAC5C,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAE9E,IAAI,aAAa,EAAE,CAAC;gBAClB,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,kCAAkC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,yBAAyB,GAAG,EAAE,CAAC,CAAC;YAC/G,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,MAAM,CAAC,OAAO,CAClB,kCAAkC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,6BAA6B,GAAG,EAAE,CAC3F,CAAC;YACJ,CAAC;YAED,oCAAoC;YACpC,OAAO,EAAE,CAAC;QACZ,CAAC;KACoD,CAAC;AAC1D,CAAC","sourcesContent":["import { UnsubscribeRequestSchema, UnsubscribeRequest, EmptyResult } from '@modelcontextprotocol/sdk/types.js';\nimport { McpHandler, McpHandlerOptions } from './mcp-handlers.types';\n\n/**\n * Handler for the resources/unsubscribe MCP request.\n * Per MCP 2025-11-25 spec, this allows clients to unsubscribe from\n * receiving notifications about a specific resource.\n */\nexport default function UnsubscribeRequestHandler({ scope }: McpHandlerOptions) {\n return {\n requestSchema: UnsubscribeRequestSchema,\n handler: async (request: UnsubscribeRequest, ctx): Promise<EmptyResult> => {\n const { uri } = request.params;\n\n // Get session ID from auth context\n const sessionId = ctx.authInfo?.sessionId;\n if (!sessionId) {\n scope.logger.warn('resources/unsubscribe: No session ID found in request context');\n return {};\n }\n\n // Unsubscribe the session from the resource\n const wasSubscribed = scope.notifications.unsubscribeResource(sessionId, uri);\n\n if (wasSubscribed) {\n scope.logger.verbose(`resources/unsubscribe: Session ${sessionId.slice(0, 20)}... unsubscribed from ${uri}`);\n } else {\n scope.logger.verbose(\n `resources/unsubscribe: Session ${sessionId.slice(0, 20)}... was not subscribed to ${uri}`,\n );\n }\n\n // Per MCP spec, return empty result\n return {};\n },\n } satisfies McpHandler<UnsubscribeRequest, EmptyResult>;\n}\n"]}
@@ -22,6 +22,9 @@ class LocalTransporter {
22
22
  this.adapter = new transport_sse_adapter_1.TransportSSEAdapter(scope, key, onDispose ?? defaultOnDispose, res);
23
23
  break;
24
24
  case 'streamable-http':
25
+ case 'stateless-http':
26
+ // Both streamable-http and stateless-http use the same underlying adapter
27
+ // The difference is in how the transport is managed (singleton vs per-session)
25
28
  this.adapter = new transport_streamable_http_adapter_1.TransportStreamableHttpAdapter(scope, key, onDispose ?? defaultOnDispose, res);
26
29
  break;
27
30
  default:
@@ -36,7 +39,8 @@ class LocalTransporter {
36
39
  await this.adapter.handleRequest(req, res);
37
40
  }
38
41
  catch (err) {
39
- console.error('MCP POST error:', err);
42
+ // Use safe logging to avoid Node.js 24 util.inspect bug with Zod errors
43
+ console.error('MCP POST error:', err instanceof Error ? err.message : 'Unknown error');
40
44
  res.status(500).json((0, transport_error_1.rpcError)('Internal error'));
41
45
  }
42
46
  }
@@ -49,7 +53,8 @@ class LocalTransporter {
49
53
  return this.adapter.initialize(req, res);
50
54
  }
51
55
  catch (err) {
52
- console.error('MCP POST error:', err);
56
+ // Use safe logging to avoid Node.js 24 util.inspect bug with Zod errors
57
+ console.error('MCP POST error:', err instanceof Error ? err.message : 'Unknown error');
53
58
  res.status(500).json((0, transport_error_1.rpcError)('Internal error'));
54
59
  }
55
60
  }
@@ -1 +1 @@
1
- {"version":3,"file":"transport.local.js","sourceRoot":"","sources":["../../../src/transport/transport.local.ts"],"names":[],"mappings":";;;AAEA,4EAAuE;AACvE,oGAA8F;AAC9F,uDAA6C;AAO7C,MAAa,gBAAgB;IAOwD;IAN1E,IAAI,CAAgB;IACpB,SAAS,CAAS;IAClB,SAAS,CAAS;IAEnB,OAAO,CAA4E;IAE3F,YAAY,KAAY,EAAE,GAAiB,EAAE,GAAmB,EAAmB,SAAsB;QAAtB,cAAS,GAAT,SAAS,CAAa;QACvG,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;QAE/B,MAAM,gBAAgB,GAAG,GAAG,EAAE;YAC5B,WAAW;QACb,CAAC,CAAC;QAEF,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,KAAK;gBACR,IAAI,CAAC,OAAO,GAAG,IAAI,2CAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,IAAI,gBAAgB,EAAE,GAAG,CAAC,CAAC;gBACvF,MAAM;YACR,KAAK,iBAAiB;gBACpB,IAAI,CAAC,OAAO,GAAG,IAAI,kEAA8B,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,IAAI,gBAAgB,EAAE,GAAG,CAAC,CAAC;gBAClG,MAAM;YACR;gBACE,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,IAAI,CAAC,SAAkB;QACrB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAA+B,EAAE,GAAmB;QACtE,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;YACtC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAA,0BAAQ,EAAC,gBAAgB,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAA+B,EAAE,GAAmB;QACnE,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACzB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;YACtC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAA,0BAAQ,EAAC,gBAAgB,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;CACF;AA7DD,4CA6DC","sourcesContent":["import { Transporter, TransportKey, TransportType } from './transport.types';\nimport { AuthenticatedServerRequest } from '../server/server.types';\nimport { TransportSSEAdapter } from './adapters/transport.sse.adapter';\nimport { TransportStreamableHttpAdapter } from './adapters/transport.streamable-http.adapter';\nimport { rpcError } from './transport.error';\nimport { LocalTransportAdapter } from './adapters/transport.local.adapter';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { SSEServerTransport } from './legacy/legacy.sse.tranporter';\nimport { ServerResponse } from '../common';\nimport { Scope } from '../scope';\n\nexport class LocalTransporter implements Transporter {\n readonly type: TransportType;\n readonly tokenHash: string;\n readonly sessionId: string;\n\n private adapter: LocalTransportAdapter<StreamableHTTPServerTransport | SSEServerTransport>;\n\n constructor(scope: Scope, key: TransportKey, res: ServerResponse, private readonly onDispose?: () => void) {\n this.type = key.type;\n this.tokenHash = key.tokenHash;\n\n const defaultOnDispose = () => {\n /* empty */\n };\n\n switch (this.type) {\n case 'sse':\n this.adapter = new TransportSSEAdapter(scope, key, onDispose ?? defaultOnDispose, res);\n break;\n case 'streamable-http':\n this.adapter = new TransportStreamableHttpAdapter(scope, key, onDispose ?? defaultOnDispose, res);\n break;\n default:\n throw new Error(`Unsupported transport type: ${this.type}`);\n }\n }\n\n ping(timeoutMs?: number): Promise<boolean> {\n throw new Error('Method not implemented.');\n }\n\n async handleRequest(req: AuthenticatedServerRequest, res: ServerResponse): Promise<void> {\n try {\n await this.adapter.handleRequest(req, res);\n } catch (err) {\n console.error('MCP POST error:', err);\n res.status(500).json(rpcError('Internal error'));\n }\n }\n\n async ready(): Promise<void> {\n return this.adapter.ready;\n }\n\n async initialize(req: AuthenticatedServerRequest, res: ServerResponse): Promise<void> {\n try {\n await this.adapter.ready;\n return this.adapter.initialize(req, res);\n } catch (err) {\n console.error('MCP POST error:', err);\n res.status(500).json(rpcError('Internal error'));\n }\n }\n\n async destroy(reason: string): Promise<void> {\n try {\n await this.adapter.destroy(reason);\n } finally {\n this.onDispose?.();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"transport.local.js","sourceRoot":"","sources":["../../../src/transport/transport.local.ts"],"names":[],"mappings":";;;AAEA,4EAAuE;AACvE,oGAA8F;AAC9F,uDAA6C;AAO7C,MAAa,gBAAgB;IAOwD;IAN1E,IAAI,CAAgB;IACpB,SAAS,CAAS;IAClB,SAAS,CAAS;IAEnB,OAAO,CAA4E;IAE3F,YAAY,KAAY,EAAE,GAAiB,EAAE,GAAmB,EAAmB,SAAsB;QAAtB,cAAS,GAAT,SAAS,CAAa;QACvG,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;QAE/B,MAAM,gBAAgB,GAAG,GAAG,EAAE;YAC5B,WAAW;QACb,CAAC,CAAC;QAEF,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,KAAK;gBACR,IAAI,CAAC,OAAO,GAAG,IAAI,2CAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,IAAI,gBAAgB,EAAE,GAAG,CAAC,CAAC;gBACvF,MAAM;YACR,KAAK,iBAAiB,CAAC;YACvB,KAAK,gBAAgB;gBACnB,0EAA0E;gBAC1E,+EAA+E;gBAC/E,IAAI,CAAC,OAAO,GAAG,IAAI,kEAA8B,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,IAAI,gBAAgB,EAAE,GAAG,CAAC,CAAC;gBAClG,MAAM;YACR;gBACE,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,IAAI,CAAC,SAAkB;QACrB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAA+B,EAAE,GAAmB;QACtE,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,wEAAwE;YACxE,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;YACvF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAA,0BAAQ,EAAC,gBAAgB,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAA+B,EAAE,GAAmB;QACnE,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACzB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,wEAAwE;YACxE,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;YACvF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAA,0BAAQ,EAAC,gBAAgB,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;CACF;AAlED,4CAkEC","sourcesContent":["import { Transporter, TransportKey, TransportType } from './transport.types';\nimport { AuthenticatedServerRequest } from '../server/server.types';\nimport { TransportSSEAdapter } from './adapters/transport.sse.adapter';\nimport { TransportStreamableHttpAdapter } from './adapters/transport.streamable-http.adapter';\nimport { rpcError } from './transport.error';\nimport { LocalTransportAdapter } from './adapters/transport.local.adapter';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { SSEServerTransport } from './legacy/legacy.sse.tranporter';\nimport { ServerResponse } from '../common';\nimport { Scope } from '../scope';\n\nexport class LocalTransporter implements Transporter {\n readonly type: TransportType;\n readonly tokenHash: string;\n readonly sessionId: string;\n\n private adapter: LocalTransportAdapter<StreamableHTTPServerTransport | SSEServerTransport>;\n\n constructor(scope: Scope, key: TransportKey, res: ServerResponse, private readonly onDispose?: () => void) {\n this.type = key.type;\n this.tokenHash = key.tokenHash;\n\n const defaultOnDispose = () => {\n /* empty */\n };\n\n switch (this.type) {\n case 'sse':\n this.adapter = new TransportSSEAdapter(scope, key, onDispose ?? defaultOnDispose, res);\n break;\n case 'streamable-http':\n case 'stateless-http':\n // Both streamable-http and stateless-http use the same underlying adapter\n // The difference is in how the transport is managed (singleton vs per-session)\n this.adapter = new TransportStreamableHttpAdapter(scope, key, onDispose ?? defaultOnDispose, res);\n break;\n default:\n throw new Error(`Unsupported transport type: ${this.type}`);\n }\n }\n\n ping(timeoutMs?: number): Promise<boolean> {\n throw new Error('Method not implemented.');\n }\n\n async handleRequest(req: AuthenticatedServerRequest, res: ServerResponse): Promise<void> {\n try {\n await this.adapter.handleRequest(req, res);\n } catch (err) {\n // Use safe logging to avoid Node.js 24 util.inspect bug with Zod errors\n console.error('MCP POST error:', err instanceof Error ? err.message : 'Unknown error');\n res.status(500).json(rpcError('Internal error'));\n }\n }\n\n async ready(): Promise<void> {\n return this.adapter.ready;\n }\n\n async initialize(req: AuthenticatedServerRequest, res: ServerResponse): Promise<void> {\n try {\n await this.adapter.ready;\n return this.adapter.initialize(req, res);\n } catch (err) {\n // Use safe logging to avoid Node.js 24 util.inspect bug with Zod errors\n console.error('MCP POST error:', err instanceof Error ? err.message : 'Unknown error');\n res.status(500).json(rpcError('Internal error'));\n }\n }\n\n async destroy(reason: string): Promise<void> {\n try {\n await this.adapter.destroy(reason);\n } finally {\n this.onDispose?.();\n }\n }\n}\n"]}
@@ -7,12 +7,42 @@ export declare class TransportService {
7
7
  private readonly distributed;
8
8
  private readonly bus?;
9
9
  private readonly scope;
10
+ /**
11
+ * Session history cache for tracking if sessions were ever created.
12
+ * Used to differentiate between "session never initialized" (HTTP 400) and
13
+ * "session expired/terminated" (HTTP 404) per MCP Spec 2025-11-25.
14
+ *
15
+ * Key: "type:tokenHash:sessionId", Value: creation timestamp
16
+ */
17
+ private readonly sessionHistory;
18
+ private readonly MAX_SESSION_HISTORY;
10
19
  constructor(scope: Scope);
11
20
  private initialize;
12
21
  destroy(): Promise<void>;
13
22
  getTransporter(type: TransportType, token: string, sessionId: string): Promise<Transporter | undefined>;
14
23
  createTransporter(type: TransportType, token: string, sessionId: string, res: ServerResponse): Promise<Transporter>;
15
24
  destroyTransporter(type: TransportType, token: string, sessionId: string, reason?: string): Promise<void>;
25
+ /**
26
+ * Get or create a shared singleton transport for anonymous stateless requests.
27
+ * All anonymous requests share the same transport instance.
28
+ */
29
+ getOrCreateAnonymousStatelessTransport(type: TransportType, res: ServerResponse): Promise<Transporter>;
30
+ /**
31
+ * Get or create a singleton transport for authenticated stateless requests.
32
+ * Each unique token gets its own singleton transport.
33
+ */
34
+ getOrCreateAuthenticatedStatelessTransport(type: TransportType, token: string, res: ServerResponse): Promise<Transporter>;
35
+ /**
36
+ * Check if a session was ever created (even if it's been terminated/evicted).
37
+ * Used to differentiate between "session never initialized" (HTTP 400) and
38
+ * "session expired/terminated" (HTTP 404) per MCP Spec 2025-11-25.
39
+ *
40
+ * @param type - Transport type (e.g., 'streamable-http', 'sse')
41
+ * @param token - The authorization token
42
+ * @param sessionId - The session ID to check
43
+ * @returns true if session was ever created, false otherwise
44
+ */
45
+ wasSessionCreated(type: TransportType, token: string, sessionId: string): boolean;
16
46
  private sha256;
17
47
  private keyOf;
18
48
  private ensureTypeBucket;
@@ -8,12 +8,22 @@ const transport_remote_1 = require("./transport.remote");
8
8
  const transport_local_1 = require("./transport.local");
9
9
  const handle_streamable_http_flow_1 = tslib_1.__importDefault(require("./flows/handle.streamable-http.flow"));
10
10
  const handle_sse_flow_1 = tslib_1.__importDefault(require("./flows/handle.sse.flow"));
11
+ const handle_stateless_http_flow_1 = tslib_1.__importDefault(require("./flows/handle.stateless-http.flow"));
11
12
  class TransportService {
12
13
  ready;
13
14
  byType = new Map();
14
15
  distributed;
15
16
  bus;
16
17
  scope;
18
+ /**
19
+ * Session history cache for tracking if sessions were ever created.
20
+ * Used to differentiate between "session never initialized" (HTTP 400) and
21
+ * "session expired/terminated" (HTTP 404) per MCP Spec 2025-11-25.
22
+ *
23
+ * Key: "type:tokenHash:sessionId", Value: creation timestamp
24
+ */
25
+ sessionHistory = new Map();
26
+ MAX_SESSION_HISTORY = 10000;
17
27
  constructor(scope) {
18
28
  this.scope = scope;
19
29
  this.distributed = false; // get from scope metadata
@@ -24,7 +34,7 @@ class TransportService {
24
34
  this.ready = this.initialize();
25
35
  }
26
36
  async initialize() {
27
- await this.scope.registryFlows(handle_streamable_http_flow_1.default, handle_sse_flow_1.default);
37
+ await this.scope.registryFlows(handle_streamable_http_flow_1.default, handle_sse_flow_1.default, handle_stateless_http_flow_1.default);
28
38
  }
29
39
  async destroy() {
30
40
  /* empty */
@@ -77,6 +87,67 @@ class TransportService {
77
87
  }
78
88
  throw new Error('Invalid session: cannot destroy non-existent transporter.');
79
89
  }
90
+ /**
91
+ * Get or create a shared singleton transport for anonymous stateless requests.
92
+ * All anonymous requests share the same transport instance.
93
+ */
94
+ async getOrCreateAnonymousStatelessTransport(type, res) {
95
+ const key = this.keyOf(type, '__anonymous__', '__stateless__');
96
+ const existing = this.lookupLocal(key);
97
+ if (existing)
98
+ return existing;
99
+ // Create shared transport for all anonymous requests
100
+ const transporter = new transport_local_1.LocalTransporter(this.scope, key, res, () => {
101
+ this.evictLocal(key);
102
+ if (this.distributed && this.bus) {
103
+ this.bus.revoke(key).catch(() => void 0);
104
+ }
105
+ });
106
+ await transporter.ready();
107
+ this.insertLocal(key, transporter);
108
+ if (this.distributed && this.bus) {
109
+ await this.bus.advertise(key);
110
+ }
111
+ return transporter;
112
+ }
113
+ /**
114
+ * Get or create a singleton transport for authenticated stateless requests.
115
+ * Each unique token gets its own singleton transport.
116
+ */
117
+ async getOrCreateAuthenticatedStatelessTransport(type, token, res) {
118
+ const key = this.keyOf(type, token, '__stateless__');
119
+ const existing = this.lookupLocal(key);
120
+ if (existing)
121
+ return existing;
122
+ // Create singleton transport for this token
123
+ const transporter = new transport_local_1.LocalTransporter(this.scope, key, res, () => {
124
+ this.evictLocal(key);
125
+ if (this.distributed && this.bus) {
126
+ this.bus.revoke(key).catch(() => void 0);
127
+ }
128
+ });
129
+ await transporter.ready();
130
+ this.insertLocal(key, transporter);
131
+ if (this.distributed && this.bus) {
132
+ await this.bus.advertise(key);
133
+ }
134
+ return transporter;
135
+ }
136
+ /**
137
+ * Check if a session was ever created (even if it's been terminated/evicted).
138
+ * Used to differentiate between "session never initialized" (HTTP 400) and
139
+ * "session expired/terminated" (HTTP 404) per MCP Spec 2025-11-25.
140
+ *
141
+ * @param type - Transport type (e.g., 'streamable-http', 'sse')
142
+ * @param token - The authorization token
143
+ * @param sessionId - The session ID to check
144
+ * @returns true if session was ever created, false otherwise
145
+ */
146
+ wasSessionCreated(type, token, sessionId) {
147
+ const tokenHash = this.sha256(token);
148
+ const historyKey = `${type}:${tokenHash}:${sessionId}`;
149
+ return this.sessionHistory.has(historyKey);
150
+ }
80
151
  /* --------------------------------- internals -------------------------------- */
81
152
  sha256(value) {
82
153
  return (0, crypto_1.createHash)('sha256').update(value, 'utf8').digest('hex');
@@ -119,6 +190,18 @@ class TransportService {
119
190
  const typeBucket = this.ensureTypeBucket(key.type);
120
191
  const tokenBucket = this.ensureTokenBucket(typeBucket, key.tokenHash);
121
192
  tokenBucket.set(key.sessionId, t);
193
+ // Record session creation in history for HTTP 404 detection
194
+ const historyKey = `${key.type}:${key.tokenHash}:${key.sessionId}`;
195
+ this.sessionHistory.set(historyKey, Date.now());
196
+ // Evict oldest entries if cache exceeds max size (LRU-like eviction)
197
+ if (this.sessionHistory.size > this.MAX_SESSION_HISTORY) {
198
+ const entries = [...this.sessionHistory.entries()].sort((a, b) => a[1] - b[1]);
199
+ // Remove oldest 10% of entries
200
+ const toEvict = Math.ceil(this.MAX_SESSION_HISTORY * 0.1);
201
+ for (let i = 0; i < toEvict && i < entries.length; i++) {
202
+ this.sessionHistory.delete(entries[i][0]);
203
+ }
204
+ }
122
205
  }
123
206
  evictLocal(key) {
124
207
  const typeBucket = this.byType.get(key.type);
@@ -1 +1 @@
1
- {"version":3,"file":"transport.registry.js","sourceRoot":"","sources":["../../../src/transport/transport.registry.ts"],"names":[],"mappings":";;;;AAAA,yCAAyC;AACzC,mCAAkC;AAUlC,yDAAqD;AACrD,uDAAmD;AAGnD,8GAA2E;AAC3E,sFAAoD;AAEpD,MAAa,gBAAgB;IAClB,KAAK,CAAgB;IACb,MAAM,GAA4B,IAAI,GAAG,EAAE,CAAC;IAC5C,WAAW,CAAU;IACrB,GAAG,CAAgB;IACnB,KAAK,CAAQ;IAE9B,YAAY,KAAY;QACtB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,0BAA0B;QACpD,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,0BAA0B;QAChD,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;QACjG,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;IAEjC,CAAC;IAGO,KAAK,CAAC,UAAU;QACtB,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAC5B,qCAAwB,EACxB,yBAAa,CACd,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO;QACX,WAAW;IACb,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAAmB,EAAE,KAAa,EAAE,SAAiB;QACxE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAE/C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QAExB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5C,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,IAAI,oCAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,IAAmB,EACnB,KAAa,EACb,SAAiB,EACjB,GAAmB;QAEnB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAE9B,MAAM,WAAW,GAAG,IAAI,kCAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;YAClE,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;YAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACrB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACjC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC;QAE1B,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAEnC,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,IAAmB,EAAE,KAAa,EAAE,SAAiB,EAAE,MAAe;QAC7F,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAE/C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC5B,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5C,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC1C,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IAED,kFAAkF;IAE1E,MAAM,CAAC,KAAa;QAC1B,OAAO,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClE,CAAC;IAEO,KAAK,CAAC,IAAmB,EAAE,KAAa,EAAE,SAAiB,EAAE,YAAqB;QACxF,OAAO;YACL,IAAI;YACJ,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAC7B,SAAS;YACT,YAAY;SACb,CAAC;IACJ,CAAC;IAEO,gBAAgB,CAAC,IAAmB;QAC1C,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,GAAG,EAAgC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,iBAAiB,CAAC,UAA+B,EAAE,SAAiB;QAC1E,IAAI,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;YACxC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAGO,WAAW,CAAC,GAAiB;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,UAAU;YAAE,OAAO,SAAS,CAAC;QAClC,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,WAAW;YAAE,OAAO,SAAS,CAAC;QACnC,OAAO,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAEO,WAAW,CAAC,GAAiB,EAAE,CAAc;QACnD,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;QACtE,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACpC,CAAC;IAEO,UAAU,CAAC,GAAiB;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,WAAW;YAAE,OAAO;QACzB,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAClC,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC;YAAE,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;CACF;AA1JD,4CA0JC","sourcesContent":["// server/transport/transport.registry.ts\nimport {createHash} from 'crypto';\nimport {\n TransportBus,\n Transporter,\n TransportKey,\n TransportRegistryBucket,\n TransportTokenBucket,\n TransportType,\n TransportTypeBucket,\n} from './transport.types';\nimport {RemoteTransporter} from './transport.remote';\nimport {LocalTransporter} from './transport.local';\nimport {ServerResponse} from '../common';\nimport {Scope} from '../scope';\nimport HandleStreamableHttpFlow from './flows/handle.streamable-http.flow';\nimport HandleSseFlow from './flows/handle.sse.flow';\n\nexport class TransportService {\n readonly ready: Promise<void>;\n private readonly byType: TransportRegistryBucket = new Map();\n private readonly distributed: boolean;\n private readonly bus?: TransportBus;\n private readonly scope: Scope;\n\n constructor(scope: Scope) {\n this.scope = scope;\n this.distributed = false; // get from scope metadata\n this.bus = undefined; // get from scope metadata\n if (this.distributed && !this.bus) {\n throw new Error('TransportRegistry: distributed=true requires a TransportBus implementation.');\n }\n\n this.ready = this.initialize();\n\n }\n\n\n private async initialize() {\n await this.scope.registryFlows(\n HandleStreamableHttpFlow,\n HandleSseFlow,\n );\n }\n\n async destroy() {\n /* empty */\n }\n\n async getTransporter(type: TransportType, token: string, sessionId: string): Promise<Transporter | undefined> {\n const key = this.keyOf(type, token, sessionId);\n\n const local = this.lookupLocal(key);\n if (local) return local;\n\n if (this.distributed && this.bus) {\n const location = await this.bus.lookup(key);\n if (location) {\n return new RemoteTransporter(key, this.bus);\n }\n }\n\n return undefined;\n }\n\n async createTransporter(\n type: TransportType,\n token: string,\n sessionId: string,\n res: ServerResponse,\n ): Promise<Transporter> {\n const key = this.keyOf(type, token, sessionId);\n const existing = this.lookupLocal(key);\n if (existing) return existing;\n\n const transporter = new LocalTransporter(this.scope, key, res, () => {\n key.sessionId = sessionId;\n this.evictLocal(key);\n if (this.distributed && this.bus) {\n this.bus.revoke(key).catch(() => void 0);\n }\n });\n\n await transporter.ready();\n\n this.insertLocal(key, transporter);\n\n if (this.distributed && this.bus) {\n await this.bus.advertise(key);\n }\n\n return transporter;\n }\n\n async destroyTransporter(type: TransportType, token: string, sessionId: string, reason?: string): Promise<void> {\n const key = this.keyOf(type, token, sessionId);\n\n const local = this.lookupLocal(key);\n if (local) {\n await local.destroy(reason);\n return;\n }\n\n if (this.distributed && this.bus) {\n const location = await this.bus.lookup(key);\n if (location) {\n await this.bus.destroyRemote(key, reason);\n return;\n }\n }\n\n throw new Error('Invalid session: cannot destroy non-existent transporter.');\n }\n\n /* --------------------------------- internals -------------------------------- */\n\n private sha256(value: string): string {\n return createHash('sha256').update(value, 'utf8').digest('hex');\n }\n\n private keyOf(type: TransportType, token: string, sessionId: string, sessionIdSse?: string): TransportKey {\n return {\n type,\n token,\n tokenHash: this.sha256(token),\n sessionId,\n sessionIdSse,\n };\n }\n\n private ensureTypeBucket(type: TransportType): TransportTypeBucket {\n let bucket = this.byType.get(type);\n if (!bucket) {\n bucket = new Map<string, TransportTokenBucket>();\n this.byType.set(type, bucket);\n }\n return bucket;\n }\n\n private ensureTokenBucket(typeBucket: TransportTypeBucket, tokenHash: string): TransportTokenBucket {\n let bucket = typeBucket.get(tokenHash);\n if (!bucket) {\n bucket = new Map<string, Transporter>();\n typeBucket.set(tokenHash, bucket);\n }\n return bucket;\n }\n\n\n private lookupLocal(key: TransportKey): Transporter | undefined {\n const typeBucket = this.byType.get(key.type);\n if (!typeBucket) return undefined;\n const tokenBucket = typeBucket.get(key.tokenHash);\n if (!tokenBucket) return undefined;\n return tokenBucket.get(key.sessionId);\n }\n\n private insertLocal(key: TransportKey, t: Transporter): void {\n const typeBucket = this.ensureTypeBucket(key.type);\n const tokenBucket = this.ensureTokenBucket(typeBucket, key.tokenHash);\n tokenBucket.set(key.sessionId, t);\n }\n\n private evictLocal(key: TransportKey): void {\n const typeBucket = this.byType.get(key.type);\n if (!typeBucket) return;\n const tokenBucket = typeBucket.get(key.tokenHash);\n if (!tokenBucket) return;\n tokenBucket.delete(key.sessionId);\n if (tokenBucket.size === 0) typeBucket.delete(key.tokenHash);\n if (typeBucket.size === 0) this.byType.delete(key.type);\n }\n}\n"]}
1
+ {"version":3,"file":"transport.registry.js","sourceRoot":"","sources":["../../../src/transport/transport.registry.ts"],"names":[],"mappings":"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","sourcesContent":["// server/transport/transport.registry.ts\nimport { createHash } from 'crypto';\nimport {\n TransportBus,\n Transporter,\n TransportKey,\n TransportRegistryBucket,\n TransportTokenBucket,\n TransportType,\n TransportTypeBucket,\n} from './transport.types';\nimport { RemoteTransporter } from './transport.remote';\nimport { LocalTransporter } from './transport.local';\nimport { ServerResponse } from '../common';\nimport { Scope } from '../scope';\nimport HandleStreamableHttpFlow from './flows/handle.streamable-http.flow';\nimport HandleSseFlow from './flows/handle.sse.flow';\nimport HandleStatelessHttpFlow from './flows/handle.stateless-http.flow';\n\nexport class TransportService {\n readonly ready: Promise<void>;\n private readonly byType: TransportRegistryBucket = new Map();\n private readonly distributed: boolean;\n private readonly bus?: TransportBus;\n private readonly scope: Scope;\n\n /**\n * Session history cache for tracking if sessions were ever created.\n * Used to differentiate between \"session never initialized\" (HTTP 400) and\n * \"session expired/terminated\" (HTTP 404) per MCP Spec 2025-11-25.\n *\n * Key: \"type:tokenHash:sessionId\", Value: creation timestamp\n */\n private readonly sessionHistory: Map<string, number> = new Map();\n private readonly MAX_SESSION_HISTORY = 10000;\n\n constructor(scope: Scope) {\n this.scope = scope;\n this.distributed = false; // get from scope metadata\n this.bus = undefined; // get from scope metadata\n if (this.distributed && !this.bus) {\n throw new Error('TransportRegistry: distributed=true requires a TransportBus implementation.');\n }\n\n this.ready = this.initialize();\n }\n\n private async initialize() {\n await this.scope.registryFlows(HandleStreamableHttpFlow, HandleSseFlow, HandleStatelessHttpFlow);\n }\n\n async destroy() {\n /* empty */\n }\n\n async getTransporter(type: TransportType, token: string, sessionId: string): Promise<Transporter | undefined> {\n const key = this.keyOf(type, token, sessionId);\n\n const local = this.lookupLocal(key);\n if (local) return local;\n\n if (this.distributed && this.bus) {\n const location = await this.bus.lookup(key);\n if (location) {\n return new RemoteTransporter(key, this.bus);\n }\n }\n\n return undefined;\n }\n\n async createTransporter(\n type: TransportType,\n token: string,\n sessionId: string,\n res: ServerResponse,\n ): Promise<Transporter> {\n const key = this.keyOf(type, token, sessionId);\n const existing = this.lookupLocal(key);\n if (existing) return existing;\n\n const transporter = new LocalTransporter(this.scope, key, res, () => {\n key.sessionId = sessionId;\n this.evictLocal(key);\n if (this.distributed && this.bus) {\n this.bus.revoke(key).catch(() => void 0);\n }\n });\n\n await transporter.ready();\n\n this.insertLocal(key, transporter);\n\n if (this.distributed && this.bus) {\n await this.bus.advertise(key);\n }\n\n return transporter;\n }\n\n async destroyTransporter(type: TransportType, token: string, sessionId: string, reason?: string): Promise<void> {\n const key = this.keyOf(type, token, sessionId);\n\n const local = this.lookupLocal(key);\n if (local) {\n await local.destroy(reason);\n return;\n }\n\n if (this.distributed && this.bus) {\n const location = await this.bus.lookup(key);\n if (location) {\n await this.bus.destroyRemote(key, reason);\n return;\n }\n }\n\n throw new Error('Invalid session: cannot destroy non-existent transporter.');\n }\n\n /**\n * Get or create a shared singleton transport for anonymous stateless requests.\n * All anonymous requests share the same transport instance.\n */\n async getOrCreateAnonymousStatelessTransport(type: TransportType, res: ServerResponse): Promise<Transporter> {\n const key = this.keyOf(type, '__anonymous__', '__stateless__');\n const existing = this.lookupLocal(key);\n if (existing) return existing;\n\n // Create shared transport for all anonymous requests\n const transporter = new LocalTransporter(this.scope, key, res, () => {\n this.evictLocal(key);\n if (this.distributed && this.bus) {\n this.bus.revoke(key).catch(() => void 0);\n }\n });\n\n await transporter.ready();\n this.insertLocal(key, transporter);\n\n if (this.distributed && this.bus) {\n await this.bus.advertise(key);\n }\n\n return transporter;\n }\n\n /**\n * Get or create a singleton transport for authenticated stateless requests.\n * Each unique token gets its own singleton transport.\n */\n async getOrCreateAuthenticatedStatelessTransport(\n type: TransportType,\n token: string,\n res: ServerResponse,\n ): Promise<Transporter> {\n const key = this.keyOf(type, token, '__stateless__');\n const existing = this.lookupLocal(key);\n if (existing) return existing;\n\n // Create singleton transport for this token\n const transporter = new LocalTransporter(this.scope, key, res, () => {\n this.evictLocal(key);\n if (this.distributed && this.bus) {\n this.bus.revoke(key).catch(() => void 0);\n }\n });\n\n await transporter.ready();\n this.insertLocal(key, transporter);\n\n if (this.distributed && this.bus) {\n await this.bus.advertise(key);\n }\n\n return transporter;\n }\n\n /**\n * Check if a session was ever created (even if it's been terminated/evicted).\n * Used to differentiate between \"session never initialized\" (HTTP 400) and\n * \"session expired/terminated\" (HTTP 404) per MCP Spec 2025-11-25.\n *\n * @param type - Transport type (e.g., 'streamable-http', 'sse')\n * @param token - The authorization token\n * @param sessionId - The session ID to check\n * @returns true if session was ever created, false otherwise\n */\n wasSessionCreated(type: TransportType, token: string, sessionId: string): boolean {\n const tokenHash = this.sha256(token);\n const historyKey = `${type}:${tokenHash}:${sessionId}`;\n return this.sessionHistory.has(historyKey);\n }\n\n /* --------------------------------- internals -------------------------------- */\n\n private sha256(value: string): string {\n return createHash('sha256').update(value, 'utf8').digest('hex');\n }\n\n private keyOf(type: TransportType, token: string, sessionId: string, sessionIdSse?: string): TransportKey {\n return {\n type,\n token,\n tokenHash: this.sha256(token),\n sessionId,\n sessionIdSse,\n };\n }\n\n private ensureTypeBucket(type: TransportType): TransportTypeBucket {\n let bucket = this.byType.get(type);\n if (!bucket) {\n bucket = new Map<string, TransportTokenBucket>();\n this.byType.set(type, bucket);\n }\n return bucket;\n }\n\n private ensureTokenBucket(typeBucket: TransportTypeBucket, tokenHash: string): TransportTokenBucket {\n let bucket = typeBucket.get(tokenHash);\n if (!bucket) {\n bucket = new Map<string, Transporter>();\n typeBucket.set(tokenHash, bucket);\n }\n return bucket;\n }\n\n private lookupLocal(key: TransportKey): Transporter | undefined {\n const typeBucket = this.byType.get(key.type);\n if (!typeBucket) return undefined;\n const tokenBucket = typeBucket.get(key.tokenHash);\n if (!tokenBucket) return undefined;\n return tokenBucket.get(key.sessionId);\n }\n\n private insertLocal(key: TransportKey, t: Transporter): void {\n const typeBucket = this.ensureTypeBucket(key.type);\n const tokenBucket = this.ensureTokenBucket(typeBucket, key.tokenHash);\n tokenBucket.set(key.sessionId, t);\n\n // Record session creation in history for HTTP 404 detection\n const historyKey = `${key.type}:${key.tokenHash}:${key.sessionId}`;\n this.sessionHistory.set(historyKey, Date.now());\n\n // Evict oldest entries if cache exceeds max size (LRU-like eviction)\n if (this.sessionHistory.size > this.MAX_SESSION_HISTORY) {\n const entries = [...this.sessionHistory.entries()].sort((a, b) => a[1] - b[1]);\n // Remove oldest 10% of entries\n const toEvict = Math.ceil(this.MAX_SESSION_HISTORY * 0.1);\n for (let i = 0; i < toEvict && i < entries.length; i++) {\n this.sessionHistory.delete(entries[i][0]);\n }\n }\n }\n\n private evictLocal(key: TransportKey): void {\n const typeBucket = this.byType.get(key.type);\n if (!typeBucket) return;\n const tokenBucket = typeBucket.get(key.tokenHash);\n if (!tokenBucket) return;\n tokenBucket.delete(key.sessionId);\n if (tokenBucket.size === 0) typeBucket.delete(key.tokenHash);\n if (typeBucket.size === 0) this.byType.delete(key.type);\n }\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  import { AuthenticatedServerRequest } from '../server/server.types';
2
2
  import { ElicitResult } from '@modelcontextprotocol/sdk/types.js';
3
- import { ZodObject } from 'zod';
3
+ import { ZodType } from 'zod';
4
4
  import { Infer } from '../utils/types.utils';
5
5
  import { ServerResponse } from '../common';
6
- export type TransportType = 'sse' | 'streamable-http' | 'http';
6
+ export type TransportType = 'sse' | 'streamable-http' | 'http' | 'stateless-http';
7
7
  export interface TransportKey {
8
8
  type: TransportType;
9
9
  token: string;
@@ -48,7 +48,7 @@ export interface TransportRegistryOptions {
48
48
  export type TransportTokenBucket = Map<string, Transporter>;
49
49
  export type TransportTypeBucket = Map<string, TransportTokenBucket>;
50
50
  export type TransportRegistryBucket = Map<TransportType, TransportTypeBucket>;
51
- export type TypedElicitResult<T extends ZodObject<any>> = {
51
+ export type TypedElicitResult<T extends ZodType> = {
52
52
  action: ElicitResult['action'];
53
53
  content: Infer<T>;
54
54
  };
@@ -1 +1 @@
1
- {"version":3,"file":"transport.types.js","sourceRoot":"","sources":["../../../src/transport/transport.types.ts"],"names":[],"mappings":"","sourcesContent":["import { AuthenticatedServerRequest } from '../server/server.types';\nimport { ElicitResult } from '@modelcontextprotocol/sdk/types.js';\nimport { ZodObject } from 'zod';\nimport { Infer } from '../utils/types.utils';\nimport { ServerResponse } from '../common';\n\nexport type TransportType = 'sse' | 'streamable-http' | 'http';\n\nexport interface TransportKey {\n type: TransportType;\n token: string;\n tokenHash: string;\n sessionId: string;\n sessionIdSse?: string;\n}\n\nexport interface RemoteLocation {\n nodeId: string;\n channel: string;\n}\n\nexport interface TransportBus {\n nodeId(): string;\n\n advertise(key: TransportKey): Promise<void>;\n\n revoke(key: TransportKey): Promise<void>;\n\n lookup(key: TransportKey): Promise<RemoteLocation | null>;\n\n proxyRequest(\n key: TransportKey,\n payload: {\n method?: string;\n url?: string;\n headers?: Record<string, string | string[] | undefined>;\n },\n io: {\n onResponseStart(statusCode: number, headers: Record<string, string>): void;\n onResponseChunk(chunk: Uint8Array | string): void;\n onResponseEnd(finalChunk?: Uint8Array | string): void;\n onError?(err: Error | string): void;\n },\n ): Promise<void>;\n\n destroyRemote(key: TransportKey, reason?: string): Promise<void>;\n}\n\n/* --------------------------------- API ---------------------------------- */\n\nexport interface Transporter {\n readonly type: TransportType;\n readonly tokenHash: string;\n readonly sessionId: string;\n\n initialize(req: AuthenticatedServerRequest, res: ServerResponse): Promise<void>;\n\n handleRequest(req: AuthenticatedServerRequest, res: ServerResponse): Promise<void>;\n\n destroy(reason?: string): Promise<void>;\n\n ping(timeoutMs?: number): Promise<boolean>;\n}\n\nexport interface TransportRegistryOptions {\n distributed?: boolean;\n bus?: TransportBus;\n}\n\nexport type TransportTokenBucket = Map<string, Transporter>; // sessionHash -> Transporter\nexport type TransportTypeBucket = Map<string, TransportTokenBucket>; // tokenHash -> TokenBucket\nexport type TransportRegistryBucket = Map<TransportType, TransportTypeBucket>; // tokenHash -> TokenBucket\n\nexport type TypedElicitResult<T extends ZodObject<any>> = { action: ElicitResult['action']; content: Infer<T> };\n"]}
1
+ {"version":3,"file":"transport.types.js","sourceRoot":"","sources":["../../../src/transport/transport.types.ts"],"names":[],"mappings":"","sourcesContent":["import { AuthenticatedServerRequest } from '../server/server.types';\nimport { ElicitResult } from '@modelcontextprotocol/sdk/types.js';\nimport { ZodType } from 'zod';\nimport { Infer } from '../utils/types.utils';\nimport { ServerResponse } from '../common';\n\nexport type TransportType = 'sse' | 'streamable-http' | 'http' | 'stateless-http';\n\nexport interface TransportKey {\n type: TransportType;\n token: string;\n tokenHash: string;\n sessionId: string;\n sessionIdSse?: string;\n}\n\nexport interface RemoteLocation {\n nodeId: string;\n channel: string;\n}\n\nexport interface TransportBus {\n nodeId(): string;\n\n advertise(key: TransportKey): Promise<void>;\n\n revoke(key: TransportKey): Promise<void>;\n\n lookup(key: TransportKey): Promise<RemoteLocation | null>;\n\n proxyRequest(\n key: TransportKey,\n payload: {\n method?: string;\n url?: string;\n headers?: Record<string, string | string[] | undefined>;\n },\n io: {\n onResponseStart(statusCode: number, headers: Record<string, string>): void;\n onResponseChunk(chunk: Uint8Array | string): void;\n onResponseEnd(finalChunk?: Uint8Array | string): void;\n onError?(err: Error | string): void;\n },\n ): Promise<void>;\n\n destroyRemote(key: TransportKey, reason?: string): Promise<void>;\n}\n\n/* --------------------------------- API ---------------------------------- */\n\nexport interface Transporter {\n readonly type: TransportType;\n readonly tokenHash: string;\n readonly sessionId: string;\n\n initialize(req: AuthenticatedServerRequest, res: ServerResponse): Promise<void>;\n\n handleRequest(req: AuthenticatedServerRequest, res: ServerResponse): Promise<void>;\n\n destroy(reason?: string): Promise<void>;\n\n ping(timeoutMs?: number): Promise<boolean>;\n}\n\nexport interface TransportRegistryOptions {\n distributed?: boolean;\n bus?: TransportBus;\n}\n\nexport type TransportTokenBucket = Map<string, Transporter>; // sessionHash -> Transporter\nexport type TransportTypeBucket = Map<string, TransportTokenBucket>; // tokenHash -> TokenBucket\nexport type TransportRegistryBucket = Map<TransportType, TransportTypeBucket>; // tokenHash -> TokenBucket\n\nexport type TypedElicitResult<T extends ZodType> = { action: ElicitResult['action']; content: Infer<T> };\n"]}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Sanitize arbitrary JS values into JSON-safe objects suitable for:
3
+ * - MCP `structuredContent`
4
+ * - JSON.stringify without circular reference errors
5
+ *
6
+ * Rules:
7
+ * - Drop functions and symbols.
8
+ * - BigInt → string.
9
+ * - Date → ISO string.
10
+ * - Error → { name, message, stack }.
11
+ * - Map → plain object.
12
+ * - Set → array.
13
+ * - Protect against circular references via WeakSet.
14
+ */
15
+ export declare function sanitizeToJson(value: unknown): unknown;
16
+ /**
17
+ * Convert a value to MCP structuredContent format.
18
+ * Returns Record<string, unknown> or undefined (matching MCP's structuredContent type).
19
+ * Primitives and arrays are wrapped in { value: ... }.
20
+ */
21
+ export declare function toStructuredContent(value: unknown): Record<string, unknown> | undefined;
22
+ /** MCP-compatible text resource content */
23
+ export type TextContent = {
24
+ uri: string;
25
+ mimeType?: string;
26
+ text: string;
27
+ };
28
+ /** MCP-compatible blob resource content */
29
+ export type BlobContent = {
30
+ uri: string;
31
+ mimeType?: string;
32
+ blob: string;
33
+ };
34
+ /** MCP-compatible resource content (text or blob) */
35
+ export type ResourceContent = TextContent | BlobContent;
36
+ /**
37
+ * Build a resource content item for MCP ReadResourceResult format.
38
+ * Handles both text and binary (blob) content.
39
+ *
40
+ * @param uri - The resource URI
41
+ * @param content - The content to serialize (string, Buffer, object, etc.)
42
+ * @param mimeType - Optional MIME type override
43
+ */
44
+ export declare function buildResourceContent(uri: string, content: unknown, mimeType?: string): ResourceContent;
45
+ /**
46
+ * Infer MIME type from file extension or content.
47
+ */
48
+ export declare function inferMimeType(uri: string, content?: unknown): string;