@frontmcp/sdk 0.4.0 → 0.5.0

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 +78 -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 +326 -1630
  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 +74 -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 +62 -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 +153 -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 +67 -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 +91 -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 +64 -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 +64 -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 +45 -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 +44 -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 +64 -1110
  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 +32 -473
  377. package/src/tool/flows/tools-list.flow.js +111 -10
  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 +69 -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 +87 -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 +517 -208
  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 +54 -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 +51 -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 +51 -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 +19 -146
  452. package/src/transport/mcp-handlers/logging-set-level-request.handler.d.ts +46 -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 +46 -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 +37 -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 +37 -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
@@ -10,6 +10,7 @@ exports.intentSchema = zod_1.z.union([
10
10
  zod_1.z.literal('streamable-http'),
11
11
  zod_1.z.literal('stateful-http'),
12
12
  zod_1.z.literal('stateless-http'),
13
+ zod_1.z.literal('delete-session'),
13
14
  zod_1.z.literal('unknown'),
14
15
  ]);
15
16
  exports.decisionSchema = zod_1.z.object({
@@ -53,12 +54,13 @@ bit 10 LEGACY_EN (config: enableLegacySSE)
53
54
  ----------------------------------------------------------------------------- */
54
55
  // --- Channels ---------------------------------------------------------------
55
56
  const CH_OTHER = 0b000;
56
- const CH_GET_SSE = 0b001;
57
+ const CH_GET_SSE = 0b001; // GET / + SSE (not handled, forward to next middleware)
57
58
  const CH_POST_INIT_JSON = 0b010;
58
59
  const CH_POST_INIT_SSE = 0b011;
59
60
  const CH_POST_JSON = 0b100;
60
61
  const CH_POST_SSE = 0b101;
61
- const CH_POST_MESSAGE = 0b110; // NEW: POST /message (legacy bridge)
62
+ const CH_POST_MESSAGE = 0b110; // POST /message (legacy bridge)
63
+ const CH_GET_SSE_PATH = 0b111; // GET /sse path (legacy SSE initialize)
62
64
  const CH_MASK = 0b00000111;
63
65
  // --- Flags ------------------------------------------------------------------
64
66
  const B_HAS_SESSION = 1 << 3; // 8
@@ -86,6 +88,10 @@ function pathOf(req) {
86
88
  return String(raw).split('?')[0] || '/';
87
89
  }
88
90
  }
91
+ // Check if path is the legacy SSE path (/sse)
92
+ function isLegacySsePath(path) {
93
+ return path === '/sse' || path.endsWith('/sse');
94
+ }
89
95
  /** Optionally extract transportType from base64 JSON session id, if you embed it. */
90
96
  function tryDecodeTransportType(sessionId) {
91
97
  if (!sessionId)
@@ -110,20 +116,23 @@ function computeBitmap(req, cfg) {
110
116
  const acceptSSE = wantsSSE(accept);
111
117
  const acceptJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);
112
118
  const init = method === 'POST' && isInitialize(req.body);
113
- const postToMessage = method === 'POST' && path === '/message';
119
+ const postToMessage = method === 'POST' && (path === '/message' || path.endsWith('/message'));
120
+ const getToSsePath = method === 'GET' && isLegacySsePath(path);
114
121
  const channel = method === 'POST' && postToMessage
115
122
  ? CH_POST_MESSAGE
116
- : method === 'GET' && acceptSSE
117
- ? CH_GET_SSE
118
- : method === 'POST' && init && acceptSSE
119
- ? CH_POST_INIT_SSE
120
- : method === 'POST' && init && acceptJSON
121
- ? CH_POST_INIT_JSON
122
- : method === 'POST' && !init && acceptSSE
123
- ? CH_POST_SSE
124
- : method === 'POST' && !init && acceptJSON
125
- ? CH_POST_JSON
126
- : CH_OTHER;
123
+ : getToSsePath && acceptSSE
124
+ ? CH_GET_SSE_PATH // GET /sse → legacy SSE channel
125
+ : method === 'GET' && acceptSSE
126
+ ? CH_GET_SSE // GET / + SSE → forward to next middleware (unknown)
127
+ : method === 'POST' && init && acceptSSE
128
+ ? CH_POST_INIT_SSE
129
+ : method === 'POST' && init && acceptJSON
130
+ ? CH_POST_INIT_JSON
131
+ : method === 'POST' && !init && acceptSSE
132
+ ? CH_POST_SSE
133
+ : method === 'POST' && !init && acceptJSON
134
+ ? CH_POST_JSON
135
+ : CH_OTHER;
127
136
  let flags = 0;
128
137
  if (sessionId)
129
138
  flags |= B_HAS_SESSION;
@@ -145,21 +154,47 @@ function computeBitmap(req, cfg) {
145
154
  }
146
155
  // --- Rules (merged semantics) -----------------------------------------------
147
156
  const RULES = [
148
- // A) Legacy SSE (GET SSE without session) → requires legacy enabled
157
+ // A) Legacy SSE via GET /sse path (without session) → requires legacy enabled
149
158
  {
150
159
  care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,
151
- match: CH_GET_SSE | B_LEGACY_EN, // HAS_SESSION must be 0; it's in 'care' but not in 'match'
152
- outcome: { intent: 'legacy-sse', reason: 'GET SSE without Mcp-Session-Id → legacy SSE.' },
160
+ match: CH_GET_SSE_PATH | B_LEGACY_EN, // HAS_SESSION must be 0; it's in 'care' but not in 'match'
161
+ outcome: { intent: 'legacy-sse', reason: 'GET /sse without Mcp-Session-Id → legacy SSE.' },
153
162
  },
154
163
  {
155
164
  care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,
156
- match: CH_GET_SSE /* legacy disabled; HAS_SESSION=0 */,
165
+ match: CH_GET_SSE_PATH /* legacy disabled; HAS_SESSION=0 */,
157
166
  outcome: {
158
167
  intent: 'unknown',
159
168
  reason: 'Legacy SSE disabled.',
160
169
  recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },
161
170
  },
162
171
  },
172
+ // A2) GET / + SSE (not /sse path) with session ID → SSE listener for streamable-http
173
+ // Per MCP 2025-11-25 spec, clients can open SSE stream via GET with session ID
174
+ {
175
+ care: CH_MASK | B_HAS_SESSION | B_SSE_LISTENER_EN | B_STREAMABLE_EN,
176
+ match: CH_GET_SSE | B_HAS_SESSION | B_SSE_LISTENER_EN | B_STREAMABLE_EN,
177
+ outcome: { intent: 'streamable-http', reason: 'GET / with session ID → SSE listener for streamable-http.' },
178
+ },
179
+ // A2b) GET / + SSE with session but listener/streamable disabled
180
+ {
181
+ care: CH_MASK | B_HAS_SESSION | B_SSE_LISTENER_EN,
182
+ match: CH_GET_SSE | B_HAS_SESSION /* listener disabled */,
183
+ outcome: {
184
+ intent: 'unknown',
185
+ reason: 'SSE listener disabled for GET / requests.',
186
+ recommendation: { httpStatus: 405, message: 'SSE listener disabled' },
187
+ },
188
+ },
189
+ // A2c) GET / + SSE without session → forward to next middleware
190
+ {
191
+ care: CH_MASK | B_HAS_SESSION,
192
+ match: CH_GET_SSE /* no session */,
193
+ outcome: {
194
+ intent: 'unknown',
195
+ reason: 'GET / with SSE requires session for MCP transport.',
196
+ },
197
+ },
163
198
  // B) Legacy SSE: POST /message WITH session id
164
199
  {
165
200
  care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,
@@ -175,10 +210,10 @@ const RULES = [
175
210
  recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },
176
211
  },
177
212
  },
178
- // C) Modern SSE (GET SSE with session) → requires SSE listener enabled
213
+ // C) Modern SSE (GET /sse with session) → requires SSE listener enabled
179
214
  {
180
215
  care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,
181
- match: CH_GET_SSE | B_HAS_SESSION /* listener disabled */,
216
+ match: CH_GET_SSE_PATH | B_HAS_SESSION /* listener disabled */,
182
217
  outcome: {
183
218
  intent: 'unknown',
184
219
  reason: 'SSE listener disabled.',
@@ -187,10 +222,16 @@ const RULES = [
187
222
  },
188
223
  {
189
224
  care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,
190
- match: CH_GET_SSE | B_SSE_LISTENER_EN | B_HAS_SESSION,
191
- outcome: { intent: 'sse', reason: 'GET SSE with Mcp-Session-Id.' },
225
+ match: CH_GET_SSE_PATH | B_SSE_LISTENER_EN | B_HAS_SESSION,
226
+ outcome: { intent: 'sse', reason: 'GET /sse with Mcp-Session-Id.' },
192
227
  },
193
228
  // D) Initialize (POST → SSE)
229
+ // D1) Stateless initialize (no session, stateless enabled) - must come before streamable rules
230
+ {
231
+ care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
232
+ match: CH_POST_INIT_SSE | B_STATELESS_EN /* no session */,
233
+ outcome: { intent: 'stateless-http', reason: 'Stateless initialize (no session).' },
234
+ },
194
235
  {
195
236
  care: CH_MASK | B_STREAMABLE_EN,
196
237
  match: CH_POST_INIT_SSE /* streamable disabled */,
@@ -206,6 +247,12 @@ const RULES = [
206
247
  outcome: { intent: 'streamable-http', reason: 'Initialize with SSE.' },
207
248
  },
208
249
  // E) Initialize (POST → JSON)
250
+ // E1) Stateless initialize JSON (no session, stateless enabled) - must come before stateful rules
251
+ {
252
+ care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
253
+ match: CH_POST_INIT_JSON | B_STATELESS_EN /* no session */,
254
+ outcome: { intent: 'stateless-http', reason: 'Stateless initialize JSON (no session).' },
255
+ },
209
256
  {
210
257
  care: CH_MASK | B_STREAMABLE_EN,
211
258
  match: CH_POST_INIT_JSON /* streamable disabled */,
@@ -292,9 +339,27 @@ const RULES = [
292
339
  // --- Public API --------------------------------------------------------------
293
340
  function decideIntent(req, cfg) {
294
341
  const reasons = [];
342
+ const method = req.method.toUpperCase();
343
+ // Handle HTTP DELETE for session termination (MCP 2025-11-25 spec)
344
+ if (method === 'DELETE') {
345
+ const sessionId = h(req, 'mcp-session-id');
346
+ if (!sessionId) {
347
+ return {
348
+ intent: 'unknown',
349
+ reasons: ['DELETE requires Mcp-Session-Id header.'],
350
+ recommendation: { httpStatus: 400, message: 'Session ID required for DELETE' },
351
+ debug: { key: 0, channel: 0, flags: 0 },
352
+ };
353
+ }
354
+ return {
355
+ intent: 'delete-session',
356
+ reasons: ['DELETE with Mcp-Session-Id → session termination.'],
357
+ debug: { key: 0, channel: 0, flags: sessionId ? B_HAS_SESSION : 0 },
358
+ };
359
+ }
295
360
  const { key, channel, flags, init } = computeBitmap(req, cfg);
296
361
  // Optional strict Accept validation for POST (incl. /message)
297
- if (req.method.toUpperCase() === 'POST') {
362
+ if (method === 'POST') {
298
363
  const accept = h(req, 'accept');
299
364
  const acceptsSSE = wantsSSE(accept);
300
365
  const acceptsJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);
@@ -1 +1 @@
1
- {"version":3,"file":"decide-request-intent.utils.js","sourceRoot":"","sources":["../../../../src/common/utils/decide-request-intent.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {ServerRequest} from \"../interfaces\";\n\n/* --------------------------------- Schemas --------------------------------- */\n\nexport const intentSchema = z.union([\n z.literal('legacy-sse'),\n z.literal('sse'),\n z.literal('streamable-http'),\n z.literal('stateful-http'),\n z.literal('stateless-http'),\n z.literal('unknown'),\n]);\n\nexport const decisionSchema = z.object({\n intent: intentSchema,\n reasons: z.array(z.string()),\n recommendation: z\n .object({\n httpStatus: z.number(),\n message: z.string(),\n })\n .optional(),\n // Echo back bits for debugging/telemetry if you like\n debug: z\n .object({\n key: z.number(),\n channel: z.number(),\n flags: z.number(),\n })\n .optional(),\n});\n\nexport type HttpRequestIntent =\n | 'legacy-sse'\n | 'sse'\n | 'streamable-http'\n | 'stateful-http'\n | 'stateless-http';\n\nexport type Intent = HttpRequestIntent | 'unknown';\n\nexport type Decision = {\n intent: Intent;\n reasons: string[];\n recommendation?: { httpStatus: number; message: string };\n // Echo back bits for debugging/telemetry if you like\n debug?: { key: number; channel: number; flags: number };\n};\n\nexport interface Config {\n enableLegacySSE: boolean;\n enableSseListener: boolean;\n enableStreamableHttp: boolean;\n enableStatefulHttp: boolean;\n enableStatelessHttp: boolean;\n requireSessionForStreamable: boolean;\n tolerateMissingAccept: boolean;\n}\n\n/* ------------------------------- Bit layout ---------------------------------\n\nbits 0..2 CHANNEL\n 000 OTHER\n 001 GET_SSE (GET + Accept: text/event-stream)\n 010 POST_INIT_JSON (POST initialize + Accept: application/json or default JSON)\n 011 POST_INIT_SSE (POST initialize + Accept: text/event-stream)\n 100 POST_JSON (POST non-init + Accept: application/json or default JSON)\n 101 POST_SSE (POST non-init + Accept: text/event-stream)\n 110 POST_MESSAGE (POST to /message) ← legacy bridge\n\nbit 3 HAS_SESSION (Mcp-Session-Id present)\nbit 4 STATELESS_EN (config: enableStatelessHttp)\nbit 5 REQ_SESSION (config: requireSessionForStreamable)\nbit 6 LEGACY_HINT (x-legacy-sse=true OR session.transportType=legacy-sse)\nbit 7 SSE_LISTENER_EN (config: enableSseListener)\nbit 8 STREAMABLE_EN (config: enableStreamableHttp)\nbit 9 STATEFUL_EN (config: enableStatefulHttp)\nbit 10 LEGACY_EN (config: enableLegacySSE)\n\n----------------------------------------------------------------------------- */\n\n// --- Channels ---------------------------------------------------------------\n\nconst CH_OTHER = 0b000;\nconst CH_GET_SSE = 0b001;\nconst CH_POST_INIT_JSON = 0b010;\nconst CH_POST_INIT_SSE = 0b011;\nconst CH_POST_JSON = 0b100;\nconst CH_POST_SSE = 0b101;\nconst CH_POST_MESSAGE = 0b110; // NEW: POST /message (legacy bridge)\n\nconst CH_MASK = 0b00000111;\n\n// --- Flags ------------------------------------------------------------------\n\nconst B_HAS_SESSION = 1 << 3; // 8\nconst B_STATELESS_EN = 1 << 4; // 16\nconst B_REQ_SESSION = 1 << 5; // 32\nconst B_LEGACY_HINT = 1 << 6; // 64 (kept for telemetry; not required by merged rules)\nconst B_SSE_LISTENER_EN = 1 << 7; // 128\nconst B_STREAMABLE_EN = 1 << 8; // 256\nconst B_STATEFUL_EN = 1 << 9; // 512\nconst B_LEGACY_EN = 1 << 10; // 1024\n\n// --- Minimal helpers ---------------------------------------------------------\n\nconst h = (req: ServerRequest, name: string) =>\n Object.entries(req.headers).find(([k]) => k.toLowerCase() === name.toLowerCase())?.[1];\n\nconst wantsSSE = (accept?: string) => (accept ?? '').toLowerCase().includes('text/event-stream');\nconst wantsJSON = (accept?: string) => (accept ?? '').toLowerCase().includes('application/json');\nconst isInitialize = (body: unknown) =>\n !!body && typeof body === 'object' && (body as any).method === 'initialize';\n\n// Robust path extractor (supports absolute/relative)\nfunction pathOf(req: ServerRequest): string {\n const anyReq = req as any;\n const raw = anyReq.path ?? anyReq.pathname ?? anyReq.url ?? '/';\n try {\n const u = new URL(String(raw), 'http://local');\n return u.pathname || '/';\n } catch {\n return String(raw).split('?')[0] || '/';\n }\n}\n\n/** Optionally extract transportType from base64 JSON session id, if you embed it. */\nfunction tryDecodeTransportType(sessionId?: string): string | undefined {\n if (!sessionId) return;\n try {\n const b64 = sessionId.replace(/-/g, '+').replace(/_/g, '/');\n const obj = JSON.parse(Buffer.from(b64, 'base64').toString('utf8'));\n return obj?.transportType;\n } catch {\n return;\n }\n}\n\n// --- Build the 11-bit key ----------------------------------------------------\n\nfunction computeBitmap(req: ServerRequest, cfg: Config) {\n const method = req.method.toUpperCase();\n const accept = h(req, 'accept');\n const sessionId = h(req, 'mcp-session-id');\n const legacyHeader = h(req, 'x-legacy-sse') === 'true';\n const transportType = tryDecodeTransportType(sessionId);\n const path = pathOf(req);\n\n const acceptSSE = wantsSSE(accept);\n const acceptJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);\n const init = method === 'POST' && isInitialize(req.body);\n const postToMessage = method === 'POST' && path === '/message';\n\n const channel =\n method === 'POST' && postToMessage\n ? CH_POST_MESSAGE\n : method === 'GET' && acceptSSE\n ? CH_GET_SSE\n : method === 'POST' && init && acceptSSE\n ? CH_POST_INIT_SSE\n : method === 'POST' && init && acceptJSON\n ? CH_POST_INIT_JSON\n : method === 'POST' && !init && acceptSSE\n ? CH_POST_SSE\n : method === 'POST' && !init && acceptJSON\n ? CH_POST_JSON\n : CH_OTHER;\n\n let flags = 0;\n if (sessionId) flags |= B_HAS_SESSION;\n if (cfg.enableStatelessHttp) flags |= B_STATELESS_EN;\n if (cfg.requireSessionForStreamable) flags |= B_REQ_SESSION;\n if (legacyHeader || transportType === 'legacy-sse') flags |= B_LEGACY_HINT; // informational\n if (cfg.enableSseListener) flags |= B_SSE_LISTENER_EN;\n if (cfg.enableStreamableHttp) flags |= B_STREAMABLE_EN;\n if (cfg.enableStatefulHttp) flags |= B_STATEFUL_EN;\n if (cfg.enableLegacySSE) flags |= B_LEGACY_EN;\n\n return { key: (channel & CH_MASK) | flags, channel, flags, init };\n}\n\n// --- Rule definition ---------------------------------------------------------\n\ntype Rule = {\n care: number; // which bits matter\n match: number; // the exact bit pattern to match (after masking)\n outcome: Omit<Decision, 'reasons' | 'debug'> & { reason: string };\n};\n\n// --- Rules (merged semantics) -----------------------------------------------\n\nconst RULES: Rule[] = [\n // A) Legacy SSE (GET SSE without session) → requires legacy enabled\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_GET_SSE | B_LEGACY_EN, // HAS_SESSION must be 0; it's in 'care' but not in 'match'\n outcome: { intent: 'legacy-sse', reason: 'GET SSE without Mcp-Session-Id → legacy SSE.' },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_GET_SSE /* legacy disabled; HAS_SESSION=0 */,\n outcome: {\n intent: 'unknown',\n reason: 'Legacy SSE disabled.',\n recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },\n },\n },\n\n // B) Legacy SSE: POST /message WITH session id\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_POST_MESSAGE | B_HAS_SESSION | B_LEGACY_EN,\n outcome: { intent: 'legacy-sse', reason: 'POST /message with Mcp-Session-Id → legacy SSE bridge.' },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_POST_MESSAGE | B_HAS_SESSION /* legacy disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Legacy /message endpoint disabled.',\n recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },\n },\n },\n\n // C) Modern SSE (GET SSE with session) → requires SSE listener enabled\n {\n care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,\n match: CH_GET_SSE | B_HAS_SESSION /* listener disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'SSE listener disabled.',\n recommendation: { httpStatus: 405, message: 'SSE listener disabled' },\n },\n },\n {\n care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,\n match: CH_GET_SSE | B_SSE_LISTENER_EN | B_HAS_SESSION,\n outcome: { intent: 'sse', reason: 'GET SSE with Mcp-Session-Id.' },\n },\n\n // D) Initialize (POST → SSE)\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_SSE /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Streamable HTTP disabled.',\n recommendation: { httpStatus: 405, message: 'Streamable HTTP disabled' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_SSE | B_STREAMABLE_EN,\n outcome: { intent: 'streamable-http', reason: 'Initialize with SSE.' },\n },\n\n // E) Initialize (POST → JSON)\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_JSON /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'JSON mode disabled.',\n recommendation: { httpStatus: 405, message: 'JSON mode disabled' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_JSON | B_STREAMABLE_EN,\n outcome: { intent: 'stateful-http', reason: 'Initialize with JSON.' },\n },\n\n // F) POST non-init → SSE\n {\n care: CH_MASK | B_REQ_SESSION | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_SSE | B_REQ_SESSION /* !HAS_SESSION & !STATELESS_EN */,\n outcome: {\n intent: 'unknown',\n reason: 'POST SSE requires session.',\n recommendation: { httpStatus: 400, message: 'Initialize required (no Mcp-Session-Id)' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_SSE /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Streamable HTTP disabled.',\n recommendation: { httpStatus: 405, message: 'Streamable HTTP disabled' },\n },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_SSE | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless short-lived SSE.' },\n },\n {\n care: CH_MASK,\n match: CH_POST_SSE,\n outcome: { intent: 'streamable-http', reason: 'Short-lived SSE for this request.' },\n },\n\n // G) POST non-init → JSON\n {\n care: CH_MASK | B_REQ_SESSION | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_JSON | B_REQ_SESSION /* !HAS_SESSION & !STATELESS_EN */,\n outcome: {\n intent: 'unknown',\n reason: 'POST JSON requires session.',\n recommendation: { httpStatus: 400, message: 'Initialize required (no Mcp-Session-Id)' },\n },\n },\n {\n care: CH_MASK | B_STATEFUL_EN | B_STREAMABLE_EN,\n match: CH_POST_JSON /* neither enabled */,\n outcome: {\n intent: 'unknown',\n reason: 'JSON mode disabled.',\n recommendation: { httpStatus: 405, message: 'JSON mode disabled' },\n },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_JSON | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless JSON request.' },\n },\n {\n care: CH_MASK,\n match: CH_POST_JSON,\n outcome: { intent: 'stateful-http', reason: 'Aggregated JSON response.' },\n },\n\n // H) Fallback\n {\n care: CH_MASK,\n match: CH_OTHER,\n outcome: {\n intent: 'unknown',\n reason: 'Method/Accept not allowed.',\n recommendation: { httpStatus: 405, message: 'Method/Accept not allowed' },\n },\n },\n];\n\n// --- Public API --------------------------------------------------------------\n\nexport function decideIntent(req: ServerRequest, cfg: Config): Decision {\n const reasons: string[] = [];\n const { key, channel, flags, init } = computeBitmap(req, cfg);\n\n // Optional strict Accept validation for POST (incl. /message)\n if (req.method.toUpperCase() === 'POST') {\n const accept = h(req, 'accept');\n const acceptsSSE = wantsSSE(accept);\n const acceptsJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);\n if (!acceptsSSE && !acceptsJSON) {\n return {\n intent: 'unknown',\n reasons: ['Client must accept application/json or text/event-stream.'],\n recommendation: { httpStatus: 406, message: 'Not acceptable' },\n debug: { key, channel, flags },\n };\n }\n }\n\n for (const rule of RULES) {\n if ((key & rule.care) === rule.match) {\n const { reason, ...rest } = rule.outcome;\n reasons.push(reason);\n if (init) reasons.push('Initialize body detected.');\n return { ...rest, reasons, debug: { key, channel, flags } };\n }\n }\n\n return {\n intent: 'unknown',\n reasons: ['No matching rule.'],\n recommendation: { httpStatus: 500, message: 'Unroutable request' },\n debug: { key, channel, flags },\n };\n}"]}
1
+ {"version":3,"file":"decide-request-intent.utils.js","sourceRoot":"","sources":["../../../../src/common/utils/decide-request-intent.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { ServerRequest } from '../interfaces';\n\n/* --------------------------------- Schemas --------------------------------- */\n\nexport const intentSchema = z.union([\n z.literal('legacy-sse'),\n z.literal('sse'),\n z.literal('streamable-http'),\n z.literal('stateful-http'),\n z.literal('stateless-http'),\n z.literal('delete-session'),\n z.literal('unknown'),\n]);\n\nexport const decisionSchema = z.object({\n intent: intentSchema,\n reasons: z.array(z.string()),\n recommendation: z\n .object({\n httpStatus: z.number(),\n message: z.string(),\n })\n .optional(),\n // Echo back bits for debugging/telemetry if you like\n debug: z\n .object({\n key: z.number(),\n channel: z.number(),\n flags: z.number(),\n })\n .optional(),\n});\n\nexport type HttpRequestIntent =\n | 'legacy-sse'\n | 'sse'\n | 'streamable-http'\n | 'stateful-http'\n | 'stateless-http'\n | 'delete-session';\n\nexport type Intent = HttpRequestIntent | 'unknown';\n\nexport type Decision = {\n intent: Intent;\n reasons: string[];\n recommendation?: { httpStatus: number; message: string };\n // Echo back bits for debugging/telemetry if you like\n debug?: { key: number; channel: number; flags: number };\n};\n\nexport interface Config {\n enableLegacySSE: boolean;\n enableSseListener: boolean;\n enableStreamableHttp: boolean;\n enableStatefulHttp: boolean;\n enableStatelessHttp: boolean;\n requireSessionForStreamable: boolean;\n tolerateMissingAccept: boolean;\n}\n\n/* ------------------------------- Bit layout ---------------------------------\n\nbits 0..2 CHANNEL\n 000 OTHER\n 001 GET_SSE (GET + Accept: text/event-stream)\n 010 POST_INIT_JSON (POST initialize + Accept: application/json or default JSON)\n 011 POST_INIT_SSE (POST initialize + Accept: text/event-stream)\n 100 POST_JSON (POST non-init + Accept: application/json or default JSON)\n 101 POST_SSE (POST non-init + Accept: text/event-stream)\n 110 POST_MESSAGE (POST to /message) ← legacy bridge\n\nbit 3 HAS_SESSION (Mcp-Session-Id present)\nbit 4 STATELESS_EN (config: enableStatelessHttp)\nbit 5 REQ_SESSION (config: requireSessionForStreamable)\nbit 6 LEGACY_HINT (x-legacy-sse=true OR session.transportType=legacy-sse)\nbit 7 SSE_LISTENER_EN (config: enableSseListener)\nbit 8 STREAMABLE_EN (config: enableStreamableHttp)\nbit 9 STATEFUL_EN (config: enableStatefulHttp)\nbit 10 LEGACY_EN (config: enableLegacySSE)\n\n----------------------------------------------------------------------------- */\n\n// --- Channels ---------------------------------------------------------------\n\nconst CH_OTHER = 0b000;\nconst CH_GET_SSE = 0b001; // GET / + SSE (not handled, forward to next middleware)\nconst CH_POST_INIT_JSON = 0b010;\nconst CH_POST_INIT_SSE = 0b011;\nconst CH_POST_JSON = 0b100;\nconst CH_POST_SSE = 0b101;\nconst CH_POST_MESSAGE = 0b110; // POST /message (legacy bridge)\nconst CH_GET_SSE_PATH = 0b111; // GET /sse path (legacy SSE initialize)\n\nconst CH_MASK = 0b00000111;\n\n// --- Flags ------------------------------------------------------------------\n\nconst B_HAS_SESSION = 1 << 3; // 8\nconst B_STATELESS_EN = 1 << 4; // 16\nconst B_REQ_SESSION = 1 << 5; // 32\nconst B_LEGACY_HINT = 1 << 6; // 64 (kept for telemetry; not required by merged rules)\nconst B_SSE_LISTENER_EN = 1 << 7; // 128\nconst B_STREAMABLE_EN = 1 << 8; // 256\nconst B_STATEFUL_EN = 1 << 9; // 512\nconst B_LEGACY_EN = 1 << 10; // 1024\n\n// --- Minimal helpers ---------------------------------------------------------\n\nconst h = (req: ServerRequest, name: string) =>\n Object.entries(req.headers).find(([k]) => k.toLowerCase() === name.toLowerCase())?.[1];\n\nconst wantsSSE = (accept?: string) => (accept ?? '').toLowerCase().includes('text/event-stream');\nconst wantsJSON = (accept?: string) => (accept ?? '').toLowerCase().includes('application/json');\nconst isInitialize = (body: unknown) => !!body && typeof body === 'object' && (body as any).method === 'initialize';\n\n// Robust path extractor (supports absolute/relative)\nfunction pathOf(req: ServerRequest): string {\n const anyReq = req as any;\n const raw = anyReq.path ?? anyReq.pathname ?? anyReq.url ?? '/';\n try {\n const u = new URL(String(raw), 'http://local');\n return u.pathname || '/';\n } catch {\n return String(raw).split('?')[0] || '/';\n }\n}\n\n// Check if path is the legacy SSE path (/sse)\nfunction isLegacySsePath(path: string): boolean {\n return path === '/sse' || path.endsWith('/sse');\n}\n\n/** Optionally extract transportType from base64 JSON session id, if you embed it. */\nfunction tryDecodeTransportType(sessionId?: string): string | undefined {\n if (!sessionId) return;\n try {\n const b64 = sessionId.replace(/-/g, '+').replace(/_/g, '/');\n const obj = JSON.parse(Buffer.from(b64, 'base64').toString('utf8'));\n return obj?.transportType;\n } catch {\n return;\n }\n}\n\n// --- Build the 11-bit key ----------------------------------------------------\n\nfunction computeBitmap(req: ServerRequest, cfg: Config) {\n const method = req.method.toUpperCase();\n const accept = h(req, 'accept');\n const sessionId = h(req, 'mcp-session-id');\n const legacyHeader = h(req, 'x-legacy-sse') === 'true';\n const transportType = tryDecodeTransportType(sessionId);\n const path = pathOf(req);\n\n const acceptSSE = wantsSSE(accept);\n const acceptJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);\n const init = method === 'POST' && isInitialize(req.body);\n const postToMessage = method === 'POST' && (path === '/message' || path.endsWith('/message'));\n const getToSsePath = method === 'GET' && isLegacySsePath(path);\n\n const channel =\n method === 'POST' && postToMessage\n ? CH_POST_MESSAGE\n : getToSsePath && acceptSSE\n ? CH_GET_SSE_PATH // GET /sse → legacy SSE channel\n : method === 'GET' && acceptSSE\n ? CH_GET_SSE // GET / + SSE → forward to next middleware (unknown)\n : method === 'POST' && init && acceptSSE\n ? CH_POST_INIT_SSE\n : method === 'POST' && init && acceptJSON\n ? CH_POST_INIT_JSON\n : method === 'POST' && !init && acceptSSE\n ? CH_POST_SSE\n : method === 'POST' && !init && acceptJSON\n ? CH_POST_JSON\n : CH_OTHER;\n\n let flags = 0;\n if (sessionId) flags |= B_HAS_SESSION;\n if (cfg.enableStatelessHttp) flags |= B_STATELESS_EN;\n if (cfg.requireSessionForStreamable) flags |= B_REQ_SESSION;\n if (legacyHeader || transportType === 'legacy-sse') flags |= B_LEGACY_HINT; // informational\n if (cfg.enableSseListener) flags |= B_SSE_LISTENER_EN;\n if (cfg.enableStreamableHttp) flags |= B_STREAMABLE_EN;\n if (cfg.enableStatefulHttp) flags |= B_STATEFUL_EN;\n if (cfg.enableLegacySSE) flags |= B_LEGACY_EN;\n\n return { key: (channel & CH_MASK) | flags, channel, flags, init };\n}\n\n// --- Rule definition ---------------------------------------------------------\n\ntype Rule = {\n care: number; // which bits matter\n match: number; // the exact bit pattern to match (after masking)\n outcome: Omit<Decision, 'reasons' | 'debug'> & { reason: string };\n};\n\n// --- Rules (merged semantics) -----------------------------------------------\n\nconst RULES: Rule[] = [\n // A) Legacy SSE via GET /sse path (without session) → requires legacy enabled\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_GET_SSE_PATH | B_LEGACY_EN, // HAS_SESSION must be 0; it's in 'care' but not in 'match'\n outcome: { intent: 'legacy-sse', reason: 'GET /sse without Mcp-Session-Id → legacy SSE.' },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_GET_SSE_PATH /* legacy disabled; HAS_SESSION=0 */,\n outcome: {\n intent: 'unknown',\n reason: 'Legacy SSE disabled.',\n recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },\n },\n },\n\n // A2) GET / + SSE (not /sse path) with session ID → SSE listener for streamable-http\n // Per MCP 2025-11-25 spec, clients can open SSE stream via GET with session ID\n {\n care: CH_MASK | B_HAS_SESSION | B_SSE_LISTENER_EN | B_STREAMABLE_EN,\n match: CH_GET_SSE | B_HAS_SESSION | B_SSE_LISTENER_EN | B_STREAMABLE_EN,\n outcome: { intent: 'streamable-http', reason: 'GET / with session ID → SSE listener for streamable-http.' },\n },\n // A2b) GET / + SSE with session but listener/streamable disabled\n {\n care: CH_MASK | B_HAS_SESSION | B_SSE_LISTENER_EN,\n match: CH_GET_SSE | B_HAS_SESSION /* listener disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'SSE listener disabled for GET / requests.',\n recommendation: { httpStatus: 405, message: 'SSE listener disabled' },\n },\n },\n // A2c) GET / + SSE without session → forward to next middleware\n {\n care: CH_MASK | B_HAS_SESSION,\n match: CH_GET_SSE /* no session */,\n outcome: {\n intent: 'unknown',\n reason: 'GET / with SSE requires session for MCP transport.',\n },\n },\n\n // B) Legacy SSE: POST /message WITH session id\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_POST_MESSAGE | B_HAS_SESSION | B_LEGACY_EN,\n outcome: { intent: 'legacy-sse', reason: 'POST /message with Mcp-Session-Id → legacy SSE bridge.' },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_POST_MESSAGE | B_HAS_SESSION /* legacy disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Legacy /message endpoint disabled.',\n recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },\n },\n },\n\n // C) Modern SSE (GET /sse with session) → requires SSE listener enabled\n {\n care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,\n match: CH_GET_SSE_PATH | B_HAS_SESSION /* listener disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'SSE listener disabled.',\n recommendation: { httpStatus: 405, message: 'SSE listener disabled' },\n },\n },\n {\n care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,\n match: CH_GET_SSE_PATH | B_SSE_LISTENER_EN | B_HAS_SESSION,\n outcome: { intent: 'sse', reason: 'GET /sse with Mcp-Session-Id.' },\n },\n\n // D) Initialize (POST → SSE)\n // D1) Stateless initialize (no session, stateless enabled) - must come before streamable rules\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_INIT_SSE | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless initialize (no session).' },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_SSE /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Streamable HTTP disabled.',\n recommendation: { httpStatus: 405, message: 'Streamable HTTP disabled' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_SSE | B_STREAMABLE_EN,\n outcome: { intent: 'streamable-http', reason: 'Initialize with SSE.' },\n },\n\n // E) Initialize (POST → JSON)\n // E1) Stateless initialize JSON (no session, stateless enabled) - must come before stateful rules\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_INIT_JSON | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless initialize JSON (no session).' },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_JSON /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'JSON mode disabled.',\n recommendation: { httpStatus: 405, message: 'JSON mode disabled' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_JSON | B_STREAMABLE_EN,\n outcome: { intent: 'stateful-http', reason: 'Initialize with JSON.' },\n },\n\n // F) POST non-init → SSE\n {\n care: CH_MASK | B_REQ_SESSION | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_SSE | B_REQ_SESSION /* !HAS_SESSION & !STATELESS_EN */,\n outcome: {\n intent: 'unknown',\n reason: 'POST SSE requires session.',\n recommendation: { httpStatus: 400, message: 'Initialize required (no Mcp-Session-Id)' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_SSE /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Streamable HTTP disabled.',\n recommendation: { httpStatus: 405, message: 'Streamable HTTP disabled' },\n },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_SSE | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless short-lived SSE.' },\n },\n {\n care: CH_MASK,\n match: CH_POST_SSE,\n outcome: { intent: 'streamable-http', reason: 'Short-lived SSE for this request.' },\n },\n\n // G) POST non-init → JSON\n {\n care: CH_MASK | B_REQ_SESSION | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_JSON | B_REQ_SESSION /* !HAS_SESSION & !STATELESS_EN */,\n outcome: {\n intent: 'unknown',\n reason: 'POST JSON requires session.',\n recommendation: { httpStatus: 400, message: 'Initialize required (no Mcp-Session-Id)' },\n },\n },\n {\n care: CH_MASK | B_STATEFUL_EN | B_STREAMABLE_EN,\n match: CH_POST_JSON /* neither enabled */,\n outcome: {\n intent: 'unknown',\n reason: 'JSON mode disabled.',\n recommendation: { httpStatus: 405, message: 'JSON mode disabled' },\n },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_JSON | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless JSON request.' },\n },\n {\n care: CH_MASK,\n match: CH_POST_JSON,\n outcome: { intent: 'stateful-http', reason: 'Aggregated JSON response.' },\n },\n\n // H) Fallback\n {\n care: CH_MASK,\n match: CH_OTHER,\n outcome: {\n intent: 'unknown',\n reason: 'Method/Accept not allowed.',\n recommendation: { httpStatus: 405, message: 'Method/Accept not allowed' },\n },\n },\n];\n\n// --- Public API --------------------------------------------------------------\n\nexport function decideIntent(req: ServerRequest, cfg: Config): Decision {\n const reasons: string[] = [];\n const method = req.method.toUpperCase();\n\n // Handle HTTP DELETE for session termination (MCP 2025-11-25 spec)\n if (method === 'DELETE') {\n const sessionId = h(req, 'mcp-session-id');\n if (!sessionId) {\n return {\n intent: 'unknown',\n reasons: ['DELETE requires Mcp-Session-Id header.'],\n recommendation: { httpStatus: 400, message: 'Session ID required for DELETE' },\n debug: { key: 0, channel: 0, flags: 0 },\n };\n }\n return {\n intent: 'delete-session',\n reasons: ['DELETE with Mcp-Session-Id → session termination.'],\n debug: { key: 0, channel: 0, flags: sessionId ? B_HAS_SESSION : 0 },\n };\n }\n\n const { key, channel, flags, init } = computeBitmap(req, cfg);\n\n // Optional strict Accept validation for POST (incl. /message)\n if (method === 'POST') {\n const accept = h(req, 'accept');\n const acceptsSSE = wantsSSE(accept);\n const acceptsJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);\n if (!acceptsSSE && !acceptsJSON) {\n return {\n intent: 'unknown',\n reasons: ['Client must accept application/json or text/event-stream.'],\n recommendation: { httpStatus: 406, message: 'Not acceptable' },\n debug: { key, channel, flags },\n };\n }\n }\n\n for (const rule of RULES) {\n if ((key & rule.care) === rule.match) {\n const { reason, ...rest } = rule.outcome;\n reasons.push(reason);\n if (init) reasons.push('Initialize body detected.');\n return { ...rest, reasons, debug: { key, channel, flags } };\n }\n }\n\n return {\n intent: 'unknown',\n reasons: ['No matching rule.'],\n recommendation: { httpStatus: 500, message: 'Unroutable request' },\n debug: { key, channel, flags },\n };\n}\n"]}
@@ -0,0 +1,74 @@
1
+ import { FlowBase, FlowRunOptions } from '../../common';
2
+ import { z } from 'zod';
3
+ declare const inputSchema: z.ZodObject<{
4
+ request: z.ZodObject<{
5
+ method: z.ZodLiteral<"completion/complete">;
6
+ params: z.ZodObject<{
7
+ _meta: z.ZodOptional<z.ZodObject<{
8
+ progressToken: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
9
+ }, z.core.$loose>>;
10
+ ref: z.ZodUnion<readonly [z.ZodObject<{
11
+ type: z.ZodLiteral<"ref/prompt">;
12
+ name: z.ZodString;
13
+ }, z.core.$strip>, z.ZodObject<{
14
+ type: z.ZodLiteral<"ref/resource">;
15
+ uri: z.ZodString;
16
+ }, z.core.$strip>]>;
17
+ argument: z.ZodObject<{
18
+ name: z.ZodString;
19
+ value: z.ZodString;
20
+ }, z.core.$strip>;
21
+ context: z.ZodOptional<z.ZodObject<{
22
+ arguments: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
23
+ }, z.core.$strip>>;
24
+ }, z.core.$loose>;
25
+ }, z.core.$strip>;
26
+ ctx: z.ZodUnknown;
27
+ }, z.core.$strip>;
28
+ declare const outputSchema: z.ZodObject<{
29
+ _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
30
+ completion: z.ZodObject<{
31
+ values: z.ZodArray<z.ZodString>;
32
+ total: z.ZodOptional<z.ZodNumber>;
33
+ hasMore: z.ZodOptional<z.ZodBoolean>;
34
+ }, z.core.$loose>;
35
+ }, z.core.$loose>;
36
+ declare const stateSchema: z.ZodObject<{
37
+ ref: z.ZodDiscriminatedUnion<[z.ZodObject<{
38
+ type: z.ZodLiteral<"ref/prompt">;
39
+ name: z.ZodString;
40
+ }, z.core.$strip>, z.ZodObject<{
41
+ type: z.ZodLiteral<"ref/resource">;
42
+ uri: z.ZodString;
43
+ }, z.core.$strip>], "type">;
44
+ argument: z.ZodObject<{
45
+ name: z.ZodString;
46
+ value: z.ZodString;
47
+ }, z.core.$strip>;
48
+ output: z.ZodObject<{
49
+ _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
50
+ completion: z.ZodObject<{
51
+ values: z.ZodArray<z.ZodString>;
52
+ total: z.ZodOptional<z.ZodNumber>;
53
+ hasMore: z.ZodOptional<z.ZodBoolean>;
54
+ }, z.core.$loose>;
55
+ }, z.core.$loose>;
56
+ }, z.core.$strip>;
57
+ declare const plan: {
58
+ readonly pre: ["parseInput"];
59
+ readonly execute: ["complete"];
60
+ readonly finalize: ["finalize"];
61
+ };
62
+ declare global {
63
+ interface ExtendFlows {
64
+ 'completion:complete': FlowRunOptions<CompleteFlow, typeof plan, typeof inputSchema, typeof outputSchema, typeof stateSchema>;
65
+ }
66
+ }
67
+ declare const name: "completion:complete";
68
+ export default class CompleteFlow extends FlowBase<typeof name> {
69
+ logger: import("../../common").FrontMcpLogger;
70
+ parseInput(): Promise<void>;
71
+ complete(): Promise<void>;
72
+ finalize(): Promise<void>;
73
+ }
74
+ export {};
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ // file: libs/sdk/src/completion/flows/complete.flow.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("../../common");
6
+ const zod_1 = require("zod");
7
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
8
+ const errors_1 = require("../../errors");
9
+ const ui_1 = require("../../tool/ui");
10
+ const inputSchema = zod_1.z.object({
11
+ request: types_js_1.CompleteRequestSchema,
12
+ ctx: zod_1.z.unknown(),
13
+ });
14
+ const outputSchema = types_js_1.CompleteResultSchema;
15
+ /**
16
+ * Reference types for completion requests
17
+ */
18
+ const PromptRefSchema = zod_1.z.object({
19
+ type: zod_1.z.literal('ref/prompt'),
20
+ name: zod_1.z.string(),
21
+ });
22
+ const ResourceRefSchema = zod_1.z.object({
23
+ type: zod_1.z.literal('ref/resource'),
24
+ uri: zod_1.z.string(),
25
+ });
26
+ const stateSchema = zod_1.z.object({
27
+ ref: zod_1.z.discriminatedUnion('type', [PromptRefSchema, ResourceRefSchema]),
28
+ argument: zod_1.z.object({
29
+ name: zod_1.z.string(),
30
+ value: zod_1.z.string(),
31
+ }),
32
+ output: outputSchema,
33
+ });
34
+ const plan = {
35
+ pre: ['parseInput'],
36
+ execute: ['complete'],
37
+ finalize: ['finalize'],
38
+ };
39
+ const name = 'completion:complete';
40
+ const { Stage } = (0, common_1.FlowHooksOf)(name);
41
+ let CompleteFlow = class CompleteFlow extends common_1.FlowBase {
42
+ logger = this.scopeLogger.child('CompleteFlow');
43
+ async parseInput() {
44
+ this.logger.verbose('parseInput:start');
45
+ let method;
46
+ let params;
47
+ try {
48
+ const inputData = inputSchema.parse(this.rawInput);
49
+ method = inputData.request.method;
50
+ params = inputData.request.params;
51
+ }
52
+ catch (e) {
53
+ throw new errors_1.InvalidInputError('Invalid Input', e instanceof zod_1.z.ZodError ? e.issues : undefined);
54
+ }
55
+ if (method !== 'completion/complete') {
56
+ this.logger.warn(`parseInput: invalid method "${method}"`);
57
+ throw new errors_1.InvalidMethodError(method, 'completion/complete');
58
+ }
59
+ const { ref, argument } = params;
60
+ // Validate ref structure
61
+ if (!ref || !ref.type) {
62
+ throw new errors_1.InvalidInputError('Reference (ref) is required with type field');
63
+ }
64
+ if (ref.type !== 'ref/prompt' && ref.type !== 'ref/resource') {
65
+ // Cast needed because TypeScript exhaustively checks ref.type, making it 'never' in this branch
66
+ throw new errors_1.InvalidInputError(`Invalid reference type: ${ref.type}. Expected "ref/prompt" or "ref/resource"`);
67
+ }
68
+ // Validate argument structure
69
+ if (!argument || typeof argument.name !== 'string' || typeof argument.value !== 'string') {
70
+ throw new errors_1.InvalidInputError('Argument must have "name" and "value" string fields');
71
+ }
72
+ this.state.set({ ref, argument });
73
+ this.logger.verbose('parseInput:done');
74
+ }
75
+ async complete() {
76
+ this.logger.verbose('complete:start');
77
+ const { ref, argument } = this.state.required;
78
+ let values = [];
79
+ let total;
80
+ let hasMore;
81
+ if (ref.type === 'ref/prompt') {
82
+ // Get completion suggestions for a prompt argument
83
+ const { name: promptName } = ref;
84
+ const { name: argName, value: argValue } = argument;
85
+ this.logger.debug(`complete: prompt completion for "${promptName}" argument "${argName}" with value "${argValue}"`);
86
+ // Look up the prompt in the registry
87
+ const prompt = this.scope.prompts.findByName(promptName);
88
+ if (prompt) {
89
+ // Check if the prompt instance has a completer for this argument
90
+ // Completion support is optional - prompts can implement getArgumentCompleter to provide suggestions
91
+ const instance = prompt; // PromptInstance may have completer method
92
+ if (typeof instance.getArgumentCompleter === 'function') {
93
+ const completer = instance.getArgumentCompleter(argName);
94
+ if (completer) {
95
+ try {
96
+ const result = await completer(argValue);
97
+ values = result.values || [];
98
+ total = result.total;
99
+ hasMore = result.hasMore;
100
+ }
101
+ catch (e) {
102
+ this.logger.warn(`complete: completer failed for prompt "${promptName}" argument "${argName}": ${e}`);
103
+ }
104
+ }
105
+ }
106
+ }
107
+ else {
108
+ this.logger.debug(`complete: prompt "${promptName}" not found`);
109
+ }
110
+ }
111
+ else if (ref.type === 'ref/resource') {
112
+ // Get completion suggestions for a resource template URI
113
+ const { uri } = ref;
114
+ const { name: argName, value: argValue } = argument;
115
+ this.logger.debug(`complete: resource completion for URI "${uri}" argument "${argName}" with value "${argValue}"`);
116
+ // Special handling for ui:// widget URIs - complete with tool names that have UI config
117
+ if (uri.startsWith('ui://widget/') && argName === 'toolName') {
118
+ const toolsWithUI = this.scope.tools.getTools().filter((t) => (0, ui_1.hasUIConfig)(t.metadata));
119
+ const toolNames = toolsWithUI.map((t) => t.metadata.id ?? t.metadata.name);
120
+ // Filter by prefix if value is provided
121
+ const prefix = argValue.toLowerCase();
122
+ values = toolNames.filter((name) => name.toLowerCase().startsWith(prefix));
123
+ total = values.length;
124
+ this.logger.debug(`complete: found ${values.length} tools with UI config matching "${argValue}"`);
125
+ }
126
+ else {
127
+ // Look up the resource template in the registry by URI
128
+ const resourceMatch = this.scope.resources.findResourceForUri(uri);
129
+ if (resourceMatch) {
130
+ // Check if the resource instance has a completer for this argument
131
+ // Completion support is optional - resources can implement getArgumentCompleter to provide suggestions
132
+ const instance = resourceMatch.instance; // ResourceInstance may have completer method
133
+ if (typeof instance.getArgumentCompleter === 'function') {
134
+ const completer = instance.getArgumentCompleter(argName);
135
+ if (completer) {
136
+ try {
137
+ const result = await completer(argValue);
138
+ values = result.values || [];
139
+ total = result.total;
140
+ hasMore = result.hasMore;
141
+ }
142
+ catch (e) {
143
+ this.logger.warn(`complete: completer failed for resource "${uri}" argument "${argName}": ${e}`);
144
+ }
145
+ }
146
+ }
147
+ }
148
+ else {
149
+ this.logger.debug(`complete: resource "${uri}" not found`);
150
+ }
151
+ }
152
+ }
153
+ // Build the completion result
154
+ const completion = { values };
155
+ if (total !== undefined) {
156
+ completion.total = total;
157
+ }
158
+ if (hasMore !== undefined) {
159
+ completion.hasMore = hasMore;
160
+ }
161
+ this.state.set({ output: { completion } });
162
+ this.logger.verbose('complete:done');
163
+ }
164
+ async finalize() {
165
+ this.logger.verbose('finalize:start');
166
+ const { output } = this.state.required;
167
+ this.respond(output);
168
+ this.logger.verbose('finalize:done');
169
+ }
170
+ };
171
+ tslib_1.__decorate([
172
+ Stage('parseInput'),
173
+ tslib_1.__metadata("design:type", Function),
174
+ tslib_1.__metadata("design:paramtypes", []),
175
+ tslib_1.__metadata("design:returntype", Promise)
176
+ ], CompleteFlow.prototype, "parseInput", null);
177
+ tslib_1.__decorate([
178
+ Stage('complete'),
179
+ tslib_1.__metadata("design:type", Function),
180
+ tslib_1.__metadata("design:paramtypes", []),
181
+ tslib_1.__metadata("design:returntype", Promise)
182
+ ], CompleteFlow.prototype, "complete", null);
183
+ tslib_1.__decorate([
184
+ Stage('finalize'),
185
+ tslib_1.__metadata("design:type", Function),
186
+ tslib_1.__metadata("design:paramtypes", []),
187
+ tslib_1.__metadata("design:returntype", Promise)
188
+ ], CompleteFlow.prototype, "finalize", null);
189
+ CompleteFlow = tslib_1.__decorate([
190
+ (0, common_1.Flow)({
191
+ name,
192
+ plan,
193
+ inputSchema,
194
+ outputSchema,
195
+ access: 'authorized',
196
+ })
197
+ ], CompleteFlow);
198
+ exports.default = CompleteFlow;
199
+ //# sourceMappingURL=complete.flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complete.flow.js","sourceRoot":"","sources":["../../../../src/completion/flows/complete.flow.ts"],"names":[],"mappings":"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","sourcesContent":["// file: libs/sdk/src/completion/flows/complete.flow.ts\n\nimport { Flow, FlowBase, FlowHooksOf, FlowPlan, FlowRunOptions } from '../../common';\nimport { z } from 'zod';\nimport { CompleteRequestSchema, CompleteResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { InvalidMethodError, InvalidInputError } from '../../errors';\nimport { hasUIConfig } from '../../tool/ui';\n\nconst inputSchema = z.object({\n request: CompleteRequestSchema,\n ctx: z.unknown(),\n});\n\nconst outputSchema = CompleteResultSchema;\n\n/**\n * Reference types for completion requests\n */\nconst PromptRefSchema = z.object({\n type: z.literal('ref/prompt'),\n name: z.string(),\n});\n\nconst ResourceRefSchema = z.object({\n type: z.literal('ref/resource'),\n uri: z.string(),\n});\n\nconst stateSchema = z.object({\n ref: z.discriminatedUnion('type', [PromptRefSchema, ResourceRefSchema]),\n argument: z.object({\n name: z.string(),\n value: z.string(),\n }),\n output: outputSchema,\n});\n\nconst plan = {\n pre: ['parseInput'],\n execute: ['complete'],\n finalize: ['finalize'],\n} as const satisfies FlowPlan<string>;\n\ndeclare global {\n interface ExtendFlows {\n 'completion:complete': FlowRunOptions<\n CompleteFlow,\n typeof plan,\n typeof inputSchema,\n typeof outputSchema,\n typeof stateSchema\n >;\n }\n}\n\nconst name = 'completion:complete' as const;\nconst { Stage } = FlowHooksOf<'completion:complete'>(name);\n\n@Flow({\n name,\n plan,\n inputSchema,\n outputSchema,\n access: 'authorized',\n})\nexport default class CompleteFlow extends FlowBase<typeof name> {\n logger = this.scopeLogger.child('CompleteFlow');\n\n @Stage('parseInput')\n async parseInput() {\n this.logger.verbose('parseInput:start');\n\n let method!: string;\n let params: z.infer<typeof CompleteRequestSchema>['params'];\n try {\n const inputData = inputSchema.parse(this.rawInput);\n method = inputData.request.method;\n params = inputData.request.params;\n } catch (e) {\n throw new InvalidInputError('Invalid Input', e instanceof z.ZodError ? e.issues : undefined);\n }\n\n if (method !== 'completion/complete') {\n this.logger.warn(`parseInput: invalid method \"${method}\"`);\n throw new InvalidMethodError(method, 'completion/complete');\n }\n\n const { ref, argument } = params;\n\n // Validate ref structure\n if (!ref || !ref.type) {\n throw new InvalidInputError('Reference (ref) is required with type field');\n }\n\n if (ref.type !== 'ref/prompt' && ref.type !== 'ref/resource') {\n // Cast needed because TypeScript exhaustively checks ref.type, making it 'never' in this branch\n throw new InvalidInputError(\n `Invalid reference type: ${(ref as { type: string }).type}. Expected \"ref/prompt\" or \"ref/resource\"`,\n );\n }\n\n // Validate argument structure\n if (!argument || typeof argument.name !== 'string' || typeof argument.value !== 'string') {\n throw new InvalidInputError('Argument must have \"name\" and \"value\" string fields');\n }\n\n this.state.set({ ref, argument });\n this.logger.verbose('parseInput:done');\n }\n\n @Stage('complete')\n async complete() {\n this.logger.verbose('complete:start');\n const { ref, argument } = this.state.required;\n\n let values: string[] = [];\n let total: number | undefined;\n let hasMore: boolean | undefined;\n\n if (ref.type === 'ref/prompt') {\n // Get completion suggestions for a prompt argument\n const { name: promptName } = ref;\n const { name: argName, value: argValue } = argument;\n\n this.logger.debug(\n `complete: prompt completion for \"${promptName}\" argument \"${argName}\" with value \"${argValue}\"`,\n );\n\n // Look up the prompt in the registry\n const prompt = this.scope.prompts.findByName(promptName);\n\n if (prompt) {\n // Check if the prompt instance has a completer for this argument\n // Completion support is optional - prompts can implement getArgumentCompleter to provide suggestions\n const instance = prompt as any; // PromptInstance may have completer method\n if (typeof instance.getArgumentCompleter === 'function') {\n const completer = instance.getArgumentCompleter(argName);\n if (completer) {\n try {\n const result = await completer(argValue);\n values = result.values || [];\n total = result.total;\n hasMore = result.hasMore;\n } catch (e) {\n this.logger.warn(`complete: completer failed for prompt \"${promptName}\" argument \"${argName}\": ${e}`);\n }\n }\n }\n } else {\n this.logger.debug(`complete: prompt \"${promptName}\" not found`);\n }\n } else if (ref.type === 'ref/resource') {\n // Get completion suggestions for a resource template URI\n const { uri } = ref;\n const { name: argName, value: argValue } = argument;\n\n this.logger.debug(\n `complete: resource completion for URI \"${uri}\" argument \"${argName}\" with value \"${argValue}\"`,\n );\n\n // Special handling for ui:// widget URIs - complete with tool names that have UI config\n if (uri.startsWith('ui://widget/') && argName === 'toolName') {\n const toolsWithUI = this.scope.tools.getTools().filter((t) => hasUIConfig(t.metadata));\n const toolNames = toolsWithUI.map((t) => t.metadata.id ?? t.metadata.name);\n\n // Filter by prefix if value is provided\n const prefix = argValue.toLowerCase();\n values = toolNames.filter((name) => name.toLowerCase().startsWith(prefix));\n total = values.length;\n\n this.logger.debug(`complete: found ${values.length} tools with UI config matching \"${argValue}\"`);\n } else {\n // Look up the resource template in the registry by URI\n const resourceMatch = this.scope.resources.findResourceForUri(uri);\n\n if (resourceMatch) {\n // Check if the resource instance has a completer for this argument\n // Completion support is optional - resources can implement getArgumentCompleter to provide suggestions\n const instance = resourceMatch.instance as any; // ResourceInstance may have completer method\n if (typeof instance.getArgumentCompleter === 'function') {\n const completer = instance.getArgumentCompleter(argName);\n if (completer) {\n try {\n const result = await completer(argValue);\n values = result.values || [];\n total = result.total;\n hasMore = result.hasMore;\n } catch (e) {\n this.logger.warn(`complete: completer failed for resource \"${uri}\" argument \"${argName}\": ${e}`);\n }\n }\n }\n } else {\n this.logger.debug(`complete: resource \"${uri}\" not found`);\n }\n }\n }\n\n // Build the completion result\n const completion: { values: string[]; total?: number; hasMore?: boolean } = { values };\n if (total !== undefined) {\n completion.total = total;\n }\n if (hasMore !== undefined) {\n completion.hasMore = hasMore;\n }\n\n this.state.set({ output: { completion } });\n this.logger.verbose('complete:done');\n }\n\n @Stage('finalize')\n async finalize() {\n this.logger.verbose('finalize:start');\n const { output } = this.state.required;\n this.respond(output);\n this.logger.verbose('finalize:done');\n }\n}\n"]}