@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
@@ -8,7 +8,7 @@ const tslib_1 = require("tslib");
8
8
  *
9
9
  * When: Start of the flow.
10
10
  *
11
- * Purpose: Authenticate the user and obtain consent; returns an authorization code to the clients redirect URI.
11
+ * Purpose: Authenticate the user and obtain consent; returns an authorization code to the client's redirect URI.
12
12
  *
13
13
  * Notes: Must support PKCE. Implicit/Hybrid are out in OAuth 2.1.
14
14
  */
@@ -21,6 +21,7 @@ const tslib_1 = require("tslib");
21
21
  */
22
22
  const common_1 = require("../../common");
23
23
  const zod_1 = require("zod");
24
+ const ui_1 = require("../ui");
24
25
  /**
25
26
  * Quick checklist (security & correctness)
26
27
  * - PKCE (S256) required for public clients (and basically for all).
@@ -33,16 +34,81 @@ const zod_1 = require("zod");
33
34
  * - Publish discovery and JWKS, rotate keys safely.
34
35
  * - Decide JWT vs opaque access tokens; provide introspection if opaque.
35
36
  */
37
+ // ============================================
38
+ // OAuth 2.1 Authorization Request Schemas
39
+ // ============================================
40
+ /**
41
+ * RFC 7636 PKCE: code_challenge is base64url(sha256(code_verifier))
42
+ * Must be 43-128 characters of A-Za-z0-9-._~
43
+ */
44
+ const pkceChallengeSchema = zod_1.z
45
+ .string()
46
+ .min(43, 'code_challenge must be at least 43 characters')
47
+ .max(128, 'code_challenge must be at most 128 characters')
48
+ .regex(/^[A-Za-z0-9_-]+$/, 'code_challenge must contain only A-Za-z0-9-_');
49
+ /**
50
+ * OAuth 2.1 requires S256 only (plain is deprecated)
51
+ */
52
+ const codeChallengeMethodSchema = zod_1.z.literal('S256', {
53
+ message: 'code_challenge_method must be "S256" (OAuth 2.1)',
54
+ });
55
+ /**
56
+ * OAuth 2.1 authorization code flow only
57
+ */
58
+ const responseTypeSchema = zod_1.z.literal('code', {
59
+ message: 'response_type must be "code" (OAuth 2.1)',
60
+ });
61
+ /**
62
+ * Validated OAuth authorization request for orchestrated mode
63
+ */
64
+ const oauthAuthorizeRequestSchema = zod_1.z.object({
65
+ response_type: responseTypeSchema,
66
+ client_id: zod_1.z.string().min(1, 'client_id is required'),
67
+ redirect_uri: zod_1.z.string().url('redirect_uri must be a valid URL'),
68
+ code_challenge: pkceChallengeSchema,
69
+ code_challenge_method: codeChallengeMethodSchema.optional().default('S256'),
70
+ scope: zod_1.z.string().optional(),
71
+ state: zod_1.z.string().optional(),
72
+ resource: zod_1.z.string().url().optional(),
73
+ });
74
+ /**
75
+ * Minimal request for anonymous/default provider mode
76
+ */
77
+ const anonymousAuthorizeRequestSchema = zod_1.z.object({
78
+ redirect_uri: zod_1.z.string().url('redirect_uri is required'),
79
+ state: zod_1.z.string().optional(),
80
+ });
81
+ // ============================================
82
+ // Flow Schemas
83
+ // ============================================
36
84
  const inputSchema = common_1.httpInputSchema;
37
85
  const stateSchema = zod_1.z.object({
38
- isDefaultAuthProvider: zod_1.z.boolean().describe("If FrontMcp initialized without auth options"),
39
- isOrchestrated: zod_1.z.boolean().describe("If FrontMcp is orchestrated (local oauth proxy, remote oauth proxy)"),
86
+ isDefaultAuthProvider: zod_1.z.boolean().describe('If FrontMcp initialized without auth options'),
87
+ isOrchestrated: zod_1.z.boolean().describe('If FrontMcp is orchestrated (local oauth proxy, remote oauth proxy)'),
40
88
  allowAnonymous: zod_1.z.boolean().describe('Allow anonymous access, force orchestrated mode'),
41
- redirectUri: zod_1.z.string().optional().describe('Oauth Redirect url')
89
+ // Validated OAuth request (after validation)
90
+ validatedRequest: oauthAuthorizeRequestSchema.optional(),
91
+ // Raw parameters for error handling
92
+ rawRedirectUri: zod_1.z.string().optional(),
93
+ rawState: zod_1.z.string().optional(),
94
+ // Validation errors
95
+ validationErrors: zod_1.z.array(zod_1.z.string()).optional(),
96
+ // Pending authorization ID (for login flow)
97
+ pendingAuthId: zod_1.z.string().optional(),
98
+ // Progressive/Incremental Authorization
99
+ isIncrementalAuth: zod_1.z.boolean().default(false).describe('Whether this is an incremental auth request'),
100
+ targetAppId: zod_1.z.string().optional().describe('Target app ID for incremental authorization'),
101
+ targetToolId: zod_1.z.string().optional().describe('Target tool ID that triggered the incremental auth'),
102
+ existingSessionId: zod_1.z.string().optional().describe('Existing session ID for incremental auth'),
103
+ // Federated Login (multi-provider)
104
+ requiresFederatedLogin: zod_1.z.boolean().default(false).describe('Whether this auth requires federated login UI'),
105
+ // Consent Flow
106
+ requiresConsent: zod_1.z.boolean().default(false).describe('Whether consent flow is enabled'),
42
107
  });
43
108
  const outputSchema = zod_1.z.union([
44
109
  common_1.HttpRedirectSchema, // for account/login or oauth/callback
45
110
  common_1.HttpTextSchema,
111
+ common_1.HttpHtmlSchema, // for login page
46
112
  ]);
47
113
  const plan = {
48
114
  pre: [
@@ -50,55 +116,657 @@ const plan = {
50
116
  'validateInput',
51
117
  'checkIfAuthorized', // used for direct code generation if refresh-token is provided
52
118
  ],
53
- execute: [
54
- 'prepareAuthorizationRequest',
55
- 'buildAuthorizeOutput'
56
- ],
57
- post: [
58
- 'validateOutput',
59
- ],
119
+ execute: ['prepareAuthorizationRequest', 'buildAuthorizeOutput'],
120
+ post: ['validateOutput'],
60
121
  };
61
122
  const name = 'oauth:authorize';
62
123
  const Stage = (0, common_1.StageHookOf)(name);
63
124
  let OauthAuthorizeFlow = class OauthAuthorizeFlow extends common_1.FlowBase {
125
+ logger = this.scope.logger.child('OauthAuthorizeFlow');
64
126
  async parseInput() {
65
127
  const { metadata } = this.scope;
66
128
  const { request } = this.rawInput;
67
- const redirectUri = request.query['redirect_uri'];
68
- if (!metadata.auth) {
69
- this.state.set({
70
- isOrchestrated: true,
71
- allowAnonymous: true,
72
- isDefaultAuthProvider: true,
73
- redirectUri,
74
- });
129
+ // Store raw params for error handling (redirect_uri and state needed for error responses)
130
+ const rawRedirectUri = request.query['redirect_uri'];
131
+ const rawState = request.query['state'];
132
+ // Progressive/Incremental Authorization Parameters
133
+ const targetAppId = request.query['app'];
134
+ const targetToolId = request.query['tool'];
135
+ const existingSessionId = request.query['session_id'];
136
+ const mode = request.query['mode'];
137
+ const isIncrementalAuth = mode === 'incremental' || !!targetAppId;
138
+ const isDefaultAuthProvider = !metadata.auth;
139
+ // Check if orchestrated mode with multiple providers (requires federated login)
140
+ // This is determined by checking if there are multiple apps with different auth providers
141
+ let requiresFederatedLogin = false;
142
+ if (metadata.auth && (0, common_1.isOrchestratedMode)(metadata.auth)) {
143
+ // Check if scope has apps with different auth providers
144
+ const apps = this.scope.apps.getApps();
145
+ const appsWithAuth = apps.filter((app) => app.metadata.auth);
146
+ requiresFederatedLogin = appsWithAuth.length > 0;
147
+ }
148
+ // Check if consent flow is enabled
149
+ let requiresConsent = false;
150
+ if (metadata.auth && (0, common_1.isOrchestratedMode)(metadata.auth)) {
151
+ const consentConfig = metadata.auth.consent;
152
+ requiresConsent = consentConfig?.enabled === true;
153
+ }
154
+ this.state.set({
155
+ isOrchestrated: true,
156
+ allowAnonymous: isDefaultAuthProvider,
157
+ isDefaultAuthProvider,
158
+ rawRedirectUri,
159
+ rawState,
160
+ // Progressive/Incremental Authorization
161
+ isIncrementalAuth,
162
+ targetAppId,
163
+ targetToolId,
164
+ existingSessionId,
165
+ // Federated Login
166
+ requiresFederatedLogin,
167
+ // Consent Flow
168
+ requiresConsent,
169
+ });
170
+ if (isIncrementalAuth) {
171
+ this.logger.info(`Incremental authorization requested for app: ${targetAppId}, tool: ${targetToolId}`);
172
+ }
173
+ if (requiresFederatedLogin) {
174
+ this.logger.info(`Federated login required: Multiple auth providers detected`);
75
175
  }
76
- else {
77
- this.next();
176
+ if (requiresConsent) {
177
+ this.logger.info(`Consent flow enabled: User will select tools to expose`);
78
178
  }
79
179
  }
80
180
  async validateInput() {
81
- if (this.state.isDefaultAuthProvider) {
82
- const redirectUri = `${this.state.required.redirectUri}?code=anonymous`;
83
- this.respond(common_1.httpRespond.redirect(redirectUri));
181
+ const { isDefaultAuthProvider, rawRedirectUri, rawState } = this.state;
182
+ const { request } = this.rawInput;
183
+ // Handle default anonymous provider - minimal validation
184
+ if (isDefaultAuthProvider) {
185
+ const result = anonymousAuthorizeRequestSchema.safeParse({
186
+ redirect_uri: rawRedirectUri,
187
+ state: rawState,
188
+ });
189
+ if (!result.success) {
190
+ const errors = this.formatZodErrors(result.error);
191
+ this.logger.warn(`Anonymous authorization request validation failed: ${errors.join(', ')}`);
192
+ this.respond(common_1.httpRespond.html(this.renderErrorPage('invalid_request', errors.join('; ')), 400));
193
+ return;
194
+ }
195
+ // Redirect with anonymous code
196
+ const url = new URL(result.data.redirect_uri);
197
+ url.searchParams.set('code', 'anonymous');
198
+ if (result.data.state) {
199
+ url.searchParams.set('state', result.data.state);
200
+ }
201
+ this.respond(common_1.httpRespond.redirect(url.toString()));
202
+ return;
84
203
  }
85
- /**
86
- * check if redirect url valid
87
- * check allowed origin
88
- * check if valid authorize request (scope/challenge/state)
89
- */
204
+ // Orchestrated mode - full OAuth 2.1 validation
205
+ const result = oauthAuthorizeRequestSchema.safeParse({
206
+ response_type: request.query['response_type'],
207
+ client_id: request.query['client_id'],
208
+ redirect_uri: rawRedirectUri,
209
+ code_challenge: request.query['code_challenge'],
210
+ code_challenge_method: request.query['code_challenge_method'] ?? 'S256',
211
+ scope: request.query['scope'],
212
+ state: rawState,
213
+ resource: request.query['resource'],
214
+ });
215
+ if (!result.success) {
216
+ const errors = this.formatZodErrors(result.error);
217
+ this.logger.warn(`Authorization request validation failed: ${errors.join(', ')}`);
218
+ this.respondWithError(errors, rawRedirectUri, rawState);
219
+ return;
220
+ }
221
+ // Store validated request
222
+ this.state.set('validatedRequest', result.data);
90
223
  }
91
224
  async checkIfAuthorized() {
92
- // TBD
225
+ // TODO: Check if user is already authorized (has valid session cookie)
226
+ // If yes, skip login and directly generate authorization code
227
+ // For now, always proceed to login
93
228
  }
94
229
  async prepareAuthorizationRequest() {
95
- // TBD
230
+ const { validatedRequest, isIncrementalAuth, targetAppId, targetToolId, existingSessionId, requiresFederatedLogin, requiresConsent, } = this.state;
231
+ const { metadata } = this.scope;
232
+ if (!validatedRequest) {
233
+ // Should not reach here if validation passed
234
+ return;
235
+ }
236
+ // Store pending authorization request
237
+ const auth = this.scope.auth;
238
+ if (!auth || !('authorizationStore' in auth)) {
239
+ this.respond(common_1.httpRespond.html(this.renderErrorPage('server_error', 'Authorization not configured'), 500));
240
+ return;
241
+ }
242
+ const localAuth = auth;
243
+ const store = localAuth.authorizationStore;
244
+ // Build federated login state if multiple providers
245
+ let federatedLogin;
246
+ if (requiresFederatedLogin) {
247
+ // Build provider IDs from apps with auth
248
+ const apps = this.scope.apps.getApps();
249
+ const providerIds = [];
250
+ // Add parent provider
251
+ if (metadata.auth && (0, common_1.isOrchestratedMode)(metadata.auth)) {
252
+ providerIds.push('__parent__');
253
+ }
254
+ // Add app-level providers
255
+ for (const app of apps) {
256
+ if (app.metadata.auth) {
257
+ providerIds.push(app.metadata.id || app.metadata.name);
258
+ }
259
+ }
260
+ federatedLogin = {
261
+ providerIds,
262
+ selectedProviderIds: undefined,
263
+ skippedProviderIds: undefined,
264
+ };
265
+ }
266
+ // Build consent state if enabled
267
+ let consent;
268
+ if (requiresConsent) {
269
+ // Get all available tools from the scope
270
+ const tools = this.scope.tools.getTools();
271
+ const availableToolIds = tools.map((t) => t.metadata.id).filter((id) => id !== undefined);
272
+ consent = {
273
+ enabled: true,
274
+ availableToolIds,
275
+ selectedToolIds: undefined,
276
+ consentCompleted: false,
277
+ };
278
+ }
279
+ const pendingRecord = store.createPendingRecord({
280
+ clientId: validatedRequest.client_id,
281
+ redirectUri: validatedRequest.redirect_uri,
282
+ scopes: validatedRequest.scope ? validatedRequest.scope.split(' ') : [],
283
+ pkce: {
284
+ challenge: validatedRequest.code_challenge,
285
+ method: 'S256',
286
+ },
287
+ state: validatedRequest.state,
288
+ resource: validatedRequest.resource,
289
+ // Progressive/Incremental Authorization Fields
290
+ isIncremental: isIncrementalAuth,
291
+ targetAppId,
292
+ targetToolId,
293
+ existingSessionId,
294
+ // Federated Login State
295
+ federatedLogin,
296
+ // Consent State
297
+ consent,
298
+ });
299
+ await localAuth.authorizationStore.storePendingAuthorization(pendingRecord);
300
+ this.logger.info(`Pending authorization created: ${pendingRecord.id}${isIncrementalAuth ? ` (incremental for app: ${targetAppId})` : ''}${requiresFederatedLogin ? ' (federated)' : ''}${requiresConsent ? ' (consent enabled)' : ''}`);
301
+ this.state.set('pendingAuthId', pendingRecord.id);
96
302
  }
97
303
  async buildAuthorizeOutput() {
98
- // TBD
304
+ const { pendingAuthId, validatedRequest, isIncrementalAuth, targetAppId, targetToolId, requiresFederatedLogin } = this.state;
305
+ if (!validatedRequest || !pendingAuthId) {
306
+ return;
307
+ }
308
+ // For incremental auth, render a single-app authorization page
309
+ if (isIncrementalAuth && targetAppId) {
310
+ const apps = this.scope.apps.getApps();
311
+ const app = apps.find((a) => a.metadata.id === targetAppId);
312
+ const appName = app?.metadata?.name || targetAppId;
313
+ const appDescription = app?.metadata?.description;
314
+ const incrementalAuthHtml = this.renderIncrementalAuthPage({
315
+ pendingAuthId,
316
+ appId: targetAppId,
317
+ appName,
318
+ appDescription,
319
+ toolId: targetToolId,
320
+ redirectUri: validatedRequest.redirect_uri,
321
+ });
322
+ this.respond(common_1.httpRespond.html(incrementalAuthHtml));
323
+ return;
324
+ }
325
+ // For federated login (multiple providers), render provider selection page
326
+ if (requiresFederatedLogin) {
327
+ const apps = this.scope.apps.getApps();
328
+ const providers = [];
329
+ // Add parent provider
330
+ const { metadata } = this.scope;
331
+ if (metadata.auth && (0, common_1.isOrchestratedMode)(metadata.auth)) {
332
+ providers.push({
333
+ id: '__parent__',
334
+ mode: metadata.auth.mode,
335
+ appIds: ['__parent__'],
336
+ scopes: [],
337
+ isParentProvider: true,
338
+ });
339
+ }
340
+ // Add app-level providers
341
+ for (const app of apps) {
342
+ if (app.metadata.auth) {
343
+ providers.push({
344
+ id: app.metadata.id || app.metadata.name,
345
+ providerUrl: app.metadata.auth.mode === 'transparent' ? app.metadata.auth.remote.provider : undefined,
346
+ mode: app.metadata.auth.mode,
347
+ appIds: [app.metadata.id || app.metadata.name],
348
+ scopes: [],
349
+ isParentProvider: false,
350
+ });
351
+ }
352
+ }
353
+ const detection = {
354
+ providers: new Map(providers.map((p) => [p.id, p])),
355
+ requiresOrchestration: true,
356
+ parentProviderId: '__parent__',
357
+ childProviderIds: providers.filter((p) => !p.isParentProvider).map((p) => p.id),
358
+ uniqueProviderCount: providers.length,
359
+ validationErrors: [],
360
+ warnings: [],
361
+ };
362
+ const federatedLoginHtml = this.renderFederatedLoginPage({
363
+ pendingAuthId,
364
+ detection,
365
+ clientId: validatedRequest.client_id,
366
+ redirectUri: validatedRequest.redirect_uri,
367
+ });
368
+ this.respond(common_1.httpRespond.html(federatedLoginHtml));
369
+ return;
370
+ }
371
+ // Render a simple login page for full authorization
372
+ // In production, this would redirect to a proper login UI
373
+ const loginHtml = this.renderLoginPage({
374
+ pendingAuthId,
375
+ clientId: validatedRequest.client_id,
376
+ scope: validatedRequest.scope ?? '',
377
+ redirectUri: validatedRequest.redirect_uri,
378
+ });
379
+ this.respond(common_1.httpRespond.html(loginHtml));
99
380
  }
100
381
  async validateOutput() {
101
- // TBD
382
+ // Output validation is handled by schema
383
+ }
384
+ /**
385
+ * Format Zod errors into human-readable strings
386
+ */
387
+ formatZodErrors(error) {
388
+ return error.issues.map((err) => {
389
+ const path = err.path.length > 0 ? `${err.path.join('.')}: ` : '';
390
+ return `${path}${err.message}`;
391
+ });
392
+ }
393
+ /**
394
+ * Respond with OAuth error - redirect if possible, otherwise show error page
395
+ */
396
+ respondWithError(errors, redirectUri, state) {
397
+ const errorDescription = errors.join('; ');
398
+ // Try to redirect with error if we have a valid redirect_uri
399
+ if (redirectUri) {
400
+ try {
401
+ const url = new URL(redirectUri);
402
+ url.searchParams.set('error', 'invalid_request');
403
+ url.searchParams.set('error_description', errorDescription);
404
+ if (state) {
405
+ url.searchParams.set('state', state);
406
+ }
407
+ this.respond(common_1.httpRespond.redirect(url.toString()));
408
+ return;
409
+ }
410
+ catch {
411
+ // Invalid redirect_uri, fall through to error page
412
+ }
413
+ }
414
+ this.respond(common_1.httpRespond.html(this.renderErrorPage('invalid_request', errorDescription), 400));
415
+ }
416
+ /**
417
+ * Render a simple login page using HTMX templates
418
+ */
419
+ renderLoginPage(params) {
420
+ const { pendingAuthId, clientId, scope } = params;
421
+ const callbackPath = `${this.scope.fullPath}/oauth/callback`;
422
+ return (0, ui_1.buildLoginPage)({
423
+ clientName: clientId,
424
+ scope,
425
+ pendingAuthId,
426
+ callbackPath,
427
+ });
428
+ }
429
+ /**
430
+ * Render incremental authorization page for a single app using HTMX templates
431
+ */
432
+ renderIncrementalAuthPage(params) {
433
+ const { pendingAuthId, appId, appName, appDescription, toolId } = params;
434
+ const callbackPath = `${this.scope.fullPath}/oauth/callback`;
435
+ const app = {
436
+ appId,
437
+ appName,
438
+ description: appDescription,
439
+ };
440
+ return (0, ui_1.buildIncrementalAuthPage)({
441
+ app,
442
+ toolId: toolId || 'unknown tool',
443
+ sessionHint: pendingAuthId,
444
+ callbackPath,
445
+ });
446
+ }
447
+ /**
448
+ * Render federated login page for multiple auth providers using HTMX templates
449
+ */
450
+ renderFederatedLoginPage(params) {
451
+ const { pendingAuthId, detection, clientId } = params;
452
+ const callbackPath = `${this.scope.fullPath}/oauth/callback`;
453
+ // Convert detection providers to ProviderCard format
454
+ const providers = [...detection.providers.values()].map((provider) => ({
455
+ providerId: provider.id,
456
+ providerName: provider.id,
457
+ providerUrl: provider.providerUrl,
458
+ mode: provider.mode,
459
+ appIds: provider.appIds.filter((id) => id !== '__parent__'),
460
+ isPrimary: provider.isParentProvider,
461
+ }));
462
+ return (0, ui_1.buildFederatedLoginPage)({
463
+ providers,
464
+ clientName: clientId,
465
+ pendingAuthId,
466
+ csrfToken: '', // No CSRF needed for GET form
467
+ callbackPath,
468
+ });
469
+ }
470
+ /**
471
+ * Render consent page for tool selection
472
+ * This is a placeholder - in production, use Juris/Svelte for the UI
473
+ */
474
+ renderConsentPage(params) {
475
+ const { pendingAuthId, tools, userEmail, userName } = params;
476
+ const callbackPath = `${this.scope.fullPath}/oauth/consent`;
477
+ // Group tools by app
478
+ const toolsByApp = tools.reduce((acc, tool) => {
479
+ if (!acc[tool.appId]) {
480
+ acc[tool.appId] = { appName: tool.appName, tools: [] };
481
+ }
482
+ acc[tool.appId].tools.push(tool);
483
+ return acc;
484
+ }, {});
485
+ // Build tool cards HTML grouped by app
486
+ const appGroupsHtml = Object.entries(toolsByApp)
487
+ .map(([appId, { appName, tools: appTools }]) => {
488
+ const toolCardsHtml = appTools
489
+ .map((tool) => `
490
+ <label class="tool-card">
491
+ <input type="checkbox" name="tools" value="${(0, ui_1.escapeHtml)(tool.id)}" checked>
492
+ <div class="tool-content">
493
+ <div class="tool-name">${(0, ui_1.escapeHtml)(tool.name)}</div>
494
+ ${tool.description ? `<div class="tool-description">${(0, ui_1.escapeHtml)(tool.description)}</div>` : ''}
495
+ </div>
496
+ </label>
497
+ `)
498
+ .join('');
499
+ return `
500
+ <div class="app-group">
501
+ <div class="app-group-header">
502
+ <span class="app-group-icon">${(0, ui_1.escapeHtml)(appName.charAt(0).toUpperCase())}</span>
503
+ <span class="app-group-name">${(0, ui_1.escapeHtml)(appName)}</span>
504
+ <button type="button" class="toggle-app" data-app-id="${(0, ui_1.escapeHtml)(appId)}" onclick="toggleAppTools(this.dataset.appId)">Toggle All</button>
505
+ </div>
506
+ <div class="app-tools" data-app="${(0, ui_1.escapeHtml)(appId)}">
507
+ ${toolCardsHtml}
508
+ </div>
509
+ </div>
510
+ `;
511
+ })
512
+ .join('');
513
+ return `<!DOCTYPE html>
514
+ <html lang="en">
515
+ <head>
516
+ <meta charset="UTF-8">
517
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
518
+ <title>Select Tools - FrontMCP</title>
519
+ <style>
520
+ * { box-sizing: border-box; margin: 0; padding: 0; }
521
+ body {
522
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
523
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
524
+ min-height: 100vh;
525
+ display: flex;
526
+ align-items: center;
527
+ justify-content: center;
528
+ padding: 20px;
529
+ }
530
+ .consent-container {
531
+ background: white;
532
+ padding: 40px;
533
+ border-radius: 12px;
534
+ box-shadow: 0 10px 40px rgba(0,0,0,0.2);
535
+ width: 100%;
536
+ max-width: 700px;
537
+ max-height: 90vh;
538
+ overflow-y: auto;
539
+ }
540
+ h1 { color: #333; margin-bottom: 10px; font-size: 24px; }
541
+ .subtitle { color: #666; margin-bottom: 20px; font-size: 14px; line-height: 1.5; }
542
+ .user-info {
543
+ background: #f8f9fa;
544
+ padding: 12px 16px;
545
+ border-radius: 8px;
546
+ margin-bottom: 24px;
547
+ font-size: 14px;
548
+ }
549
+ .user-info strong { color: #333; }
550
+ .select-controls {
551
+ display: flex;
552
+ gap: 16px;
553
+ margin-bottom: 16px;
554
+ align-items: center;
555
+ }
556
+ .select-controls label {
557
+ display: flex;
558
+ align-items: center;
559
+ gap: 8px;
560
+ font-size: 14px;
561
+ color: #666;
562
+ cursor: pointer;
563
+ }
564
+ .app-group {
565
+ background: #f8f9fa;
566
+ border-radius: 12px;
567
+ margin-bottom: 16px;
568
+ overflow: hidden;
569
+ }
570
+ .app-group-header {
571
+ display: flex;
572
+ align-items: center;
573
+ gap: 12px;
574
+ padding: 16px;
575
+ background: #e9ecef;
576
+ }
577
+ .app-group-icon {
578
+ width: 32px;
579
+ height: 32px;
580
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
581
+ border-radius: 8px;
582
+ display: flex;
583
+ align-items: center;
584
+ justify-content: center;
585
+ color: white;
586
+ font-weight: 600;
587
+ }
588
+ .app-group-name { font-weight: 600; color: #333; flex: 1; }
589
+ .toggle-app {
590
+ padding: 6px 12px;
591
+ background: white;
592
+ border: 1px solid #ddd;
593
+ border-radius: 6px;
594
+ font-size: 12px;
595
+ cursor: pointer;
596
+ }
597
+ .toggle-app:hover { background: #f0f0f0; }
598
+ .app-tools { padding: 12px; }
599
+ .tool-card {
600
+ display: flex;
601
+ align-items: flex-start;
602
+ gap: 12px;
603
+ padding: 12px;
604
+ background: white;
605
+ border-radius: 8px;
606
+ margin-bottom: 8px;
607
+ cursor: pointer;
608
+ transition: all 0.2s;
609
+ }
610
+ .tool-card:hover { background: #f0f4ff; }
611
+ .tool-card:last-child { margin-bottom: 0; }
612
+ .tool-card input { margin-top: 2px; }
613
+ .tool-content { flex: 1; }
614
+ .tool-name { font-weight: 500; color: #333; font-size: 14px; }
615
+ .tool-description { font-size: 12px; color: #666; margin-top: 4px; }
616
+ .button-group { display: flex; gap: 12px; margin-top: 24px; }
617
+ button {
618
+ flex: 1;
619
+ padding: 14px;
620
+ border: none;
621
+ border-radius: 8px;
622
+ font-size: 16px;
623
+ font-weight: 600;
624
+ cursor: pointer;
625
+ transition: transform 0.2s, box-shadow 0.2s;
626
+ }
627
+ .btn-confirm {
628
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
629
+ color: white;
630
+ }
631
+ .btn-confirm:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4); }
632
+ .btn-cancel {
633
+ background: #e5e7eb;
634
+ color: #374151;
635
+ }
636
+ .btn-cancel:hover { background: #d1d5db; }
637
+ .selection-summary {
638
+ background: #f0f9ff;
639
+ border: 1px solid #bae6fd;
640
+ border-radius: 8px;
641
+ padding: 12px 16px;
642
+ margin-top: 16px;
643
+ font-size: 13px;
644
+ color: #0369a1;
645
+ }
646
+ </style>
647
+ </head>
648
+ <body>
649
+ <div class="consent-container">
650
+ <h1>Select Tools to Enable</h1>
651
+ <p class="subtitle">
652
+ Choose which tools you want to make available to the AI assistant.
653
+ You can enable or disable tools at any time.
654
+ </p>
655
+
656
+ ${userEmail || userName
657
+ ? `
658
+ <div class="user-info">
659
+ Logged in as: <strong>${(0, ui_1.escapeHtml)(userName || userEmail || '')}</strong>
660
+ </div>
661
+ `
662
+ : ''}
663
+
664
+ <form action="${(0, ui_1.escapeHtml)(callbackPath)}" method="POST" id="consent-form">
665
+ <input type="hidden" name="pending_auth_id" value="${(0, ui_1.escapeHtml)(pendingAuthId)}">
666
+
667
+ <div class="select-controls">
668
+ <label>
669
+ <input type="checkbox" id="select-all" onchange="toggleAllTools(this)" checked>
670
+ Select all tools
671
+ </label>
672
+ <span style="color: #999; font-size: 12px;" id="selection-count">${tools.length} of ${tools.length} selected</span>
673
+ </div>
674
+
675
+ ${appGroupsHtml}
676
+
677
+ <div class="selection-summary" id="selection-summary">
678
+ Selected tools will be available to the AI assistant.
679
+ </div>
680
+
681
+ <div class="button-group">
682
+ <button type="button" class="btn-cancel" onclick="history.back()">Cancel</button>
683
+ <button type="submit" class="btn-confirm">Confirm Selection</button>
684
+ </div>
685
+ </form>
686
+ </div>
687
+
688
+ <script>
689
+ function toggleAllTools(checkbox) {
690
+ const checkboxes = document.querySelectorAll('input[name="tools"]');
691
+ checkboxes.forEach(cb => cb.checked = checkbox.checked);
692
+ updateCount();
693
+ }
694
+
695
+ function toggleAppTools(appId) {
696
+ const container = document.querySelector(\`.app-tools[data-app="\${appId}"]\`);
697
+ const checkboxes = container.querySelectorAll('input[name="tools"]');
698
+ const allChecked = [...checkboxes].every(cb => cb.checked);
699
+ checkboxes.forEach(cb => cb.checked = !allChecked);
700
+ updateSelectAll();
701
+ updateCount();
702
+ }
703
+
704
+ function updateSelectAll() {
705
+ const all = document.querySelectorAll('input[name="tools"]');
706
+ const checked = document.querySelectorAll('input[name="tools"]:checked');
707
+ document.getElementById('select-all').checked = all.length === checked.length;
708
+ }
709
+
710
+ function updateCount() {
711
+ const all = document.querySelectorAll('input[name="tools"]');
712
+ const checked = document.querySelectorAll('input[name="tools"]:checked');
713
+ document.getElementById('selection-count').textContent = \`\${checked.length} of \${all.length} selected\`;
714
+ }
715
+
716
+ // Add change listeners to all tool checkboxes
717
+ document.querySelectorAll('input[name="tools"]').forEach(cb => {
718
+ cb.addEventListener('change', () => {
719
+ updateSelectAll();
720
+ updateCount();
721
+ });
722
+ });
723
+ </script>
724
+ </body>
725
+ </html>`;
726
+ }
727
+ /**
728
+ * Render an error page
729
+ */
730
+ renderErrorPage(error, description) {
731
+ return `<!DOCTYPE html>
732
+ <html lang="en">
733
+ <head>
734
+ <meta charset="UTF-8">
735
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
736
+ <title>Authorization Error</title>
737
+ <style>
738
+ body {
739
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
740
+ background: #f5f5f5;
741
+ min-height: 100vh;
742
+ display: flex;
743
+ align-items: center;
744
+ justify-content: center;
745
+ padding: 20px;
746
+ }
747
+ .error-container {
748
+ background: white;
749
+ padding: 40px;
750
+ border-radius: 12px;
751
+ box-shadow: 0 4px 20px rgba(0,0,0,0.1);
752
+ max-width: 500px;
753
+ text-align: center;
754
+ }
755
+ .error-icon { font-size: 48px; margin-bottom: 20px; }
756
+ h1 { color: #e53e3e; margin-bottom: 10px; }
757
+ p { color: #666; line-height: 1.6; }
758
+ .error-code { font-family: monospace; background: #f5f5f5; padding: 4px 8px; border-radius: 4px; }
759
+ </style>
760
+ </head>
761
+ <body>
762
+ <div class="error-container">
763
+ <div class="error-icon">⚠️</div>
764
+ <h1>Authorization Error</h1>
765
+ <p><span class="error-code">${(0, ui_1.escapeHtml)(error)}</span></p>
766
+ <p>${(0, ui_1.escapeHtml)(description)}</p>
767
+ </div>
768
+ </body>
769
+ </html>`;
102
770
  }
103
771
  };
104
772
  tslib_1.__decorate([