noodleseed-cli 0.1.4

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 (356) hide show
  1. package/LICENSE +176 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +625 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/config.d.ts +52 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +77 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/control-plane.d.ts +33 -0
  11. package/dist/control-plane.d.ts.map +1 -0
  12. package/dist/control-plane.js +223 -0
  13. package/dist/control-plane.js.map +1 -0
  14. package/dist/deploy.d.ts +62 -0
  15. package/dist/deploy.d.ts.map +1 -0
  16. package/dist/deploy.js +182 -0
  17. package/dist/deploy.js.map +1 -0
  18. package/dist/dev.d.ts +50 -0
  19. package/dist/dev.d.ts.map +1 -0
  20. package/dist/dev.js +223 -0
  21. package/dist/dev.js.map +1 -0
  22. package/dist/index.d.ts +6 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +6 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/validate.d.ts +37 -0
  27. package/dist/validate.d.ts.map +1 -0
  28. package/dist/validate.js +46 -0
  29. package/dist/validate.js.map +1 -0
  30. package/node_modules/@noodle-borg/auth/dist/index.d.ts +14 -0
  31. package/node_modules/@noodle-borg/auth/dist/index.d.ts.map +1 -0
  32. package/node_modules/@noodle-borg/auth/dist/index.js +14 -0
  33. package/node_modules/@noodle-borg/auth/dist/index.js.map +1 -0
  34. package/node_modules/@noodle-borg/auth/dist/jwt-issuer.d.ts +21 -0
  35. package/node_modules/@noodle-borg/auth/dist/jwt-issuer.d.ts.map +1 -0
  36. package/node_modules/@noodle-borg/auth/dist/jwt-issuer.js +24 -0
  37. package/node_modules/@noodle-borg/auth/dist/jwt-issuer.js.map +1 -0
  38. package/node_modules/@noodle-borg/auth/dist/metadata.d.ts +27 -0
  39. package/node_modules/@noodle-borg/auth/dist/metadata.d.ts.map +1 -0
  40. package/node_modules/@noodle-borg/auth/dist/metadata.js +21 -0
  41. package/node_modules/@noodle-borg/auth/dist/metadata.js.map +1 -0
  42. package/node_modules/@noodle-borg/auth/dist/signer.d.ts +45 -0
  43. package/node_modules/@noodle-borg/auth/dist/signer.d.ts.map +1 -0
  44. package/node_modules/@noodle-borg/auth/dist/signer.js +47 -0
  45. package/node_modules/@noodle-borg/auth/dist/signer.js.map +1 -0
  46. package/node_modules/@noodle-borg/auth/dist/verify.d.ts +42 -0
  47. package/node_modules/@noodle-borg/auth/dist/verify.d.ts.map +1 -0
  48. package/node_modules/@noodle-borg/auth/dist/verify.js +48 -0
  49. package/node_modules/@noodle-borg/auth/dist/verify.js.map +1 -0
  50. package/node_modules/@noodle-borg/auth/package.json +27 -0
  51. package/node_modules/@noodle-borg/authoring/dist/index.d.ts +200 -0
  52. package/node_modules/@noodle-borg/authoring/dist/index.d.ts.map +1 -0
  53. package/node_modules/@noodle-borg/authoring/dist/index.js +504 -0
  54. package/node_modules/@noodle-borg/authoring/dist/index.js.map +1 -0
  55. package/node_modules/@noodle-borg/authoring/package.json +29 -0
  56. package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +203 -0
  57. package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts.map +1 -0
  58. package/node_modules/@noodle-borg/compiler/dist/artifact/types.js +20 -0
  59. package/node_modules/@noodle-borg/compiler/dist/artifact/types.js.map +1 -0
  60. package/node_modules/@noodle-borg/compiler/dist/catalog/in-memory.d.ts +13 -0
  61. package/node_modules/@noodle-borg/compiler/dist/catalog/in-memory.d.ts.map +1 -0
  62. package/node_modules/@noodle-borg/compiler/dist/catalog/in-memory.js +19 -0
  63. package/node_modules/@noodle-borg/compiler/dist/catalog/in-memory.js.map +1 -0
  64. package/node_modules/@noodle-borg/compiler/dist/catalog/signature.d.ts +11 -0
  65. package/node_modules/@noodle-borg/compiler/dist/catalog/signature.d.ts.map +1 -0
  66. package/node_modules/@noodle-borg/compiler/dist/catalog/signature.js +31 -0
  67. package/node_modules/@noodle-borg/compiler/dist/catalog/signature.js.map +1 -0
  68. package/node_modules/@noodle-borg/compiler/dist/catalog/types.d.ts +43 -0
  69. package/node_modules/@noodle-borg/compiler/dist/catalog/types.d.ts.map +1 -0
  70. package/node_modules/@noodle-borg/compiler/dist/catalog/types.js +11 -0
  71. package/node_modules/@noodle-borg/compiler/dist/catalog/types.js.map +1 -0
  72. package/node_modules/@noodle-borg/compiler/dist/cli.d.ts +3 -0
  73. package/node_modules/@noodle-borg/compiler/dist/cli.d.ts.map +1 -0
  74. package/node_modules/@noodle-borg/compiler/dist/cli.js +19 -0
  75. package/node_modules/@noodle-borg/compiler/dist/cli.js.map +1 -0
  76. package/node_modules/@noodle-borg/compiler/dist/compile.d.ts +50 -0
  77. package/node_modules/@noodle-borg/compiler/dist/compile.d.ts.map +1 -0
  78. package/node_modules/@noodle-borg/compiler/dist/compile.js +719 -0
  79. package/node_modules/@noodle-borg/compiler/dist/compile.js.map +1 -0
  80. package/node_modules/@noodle-borg/compiler/dist/errors.d.ts +27 -0
  81. package/node_modules/@noodle-borg/compiler/dist/errors.d.ts.map +1 -0
  82. package/node_modules/@noodle-borg/compiler/dist/errors.js +2 -0
  83. package/node_modules/@noodle-borg/compiler/dist/errors.js.map +1 -0
  84. package/node_modules/@noodle-borg/compiler/dist/index.d.ts +13 -0
  85. package/node_modules/@noodle-borg/compiler/dist/index.d.ts.map +1 -0
  86. package/node_modules/@noodle-borg/compiler/dist/index.js +11 -0
  87. package/node_modules/@noodle-borg/compiler/dist/index.js.map +1 -0
  88. package/node_modules/@noodle-borg/compiler/dist/manifest/expression.d.ts +136 -0
  89. package/node_modules/@noodle-borg/compiler/dist/manifest/expression.d.ts.map +1 -0
  90. package/node_modules/@noodle-borg/compiler/dist/manifest/expression.js +552 -0
  91. package/node_modules/@noodle-borg/compiler/dist/manifest/expression.js.map +1 -0
  92. package/node_modules/@noodle-borg/compiler/dist/manifest/naming.d.ts +14 -0
  93. package/node_modules/@noodle-borg/compiler/dist/manifest/naming.d.ts.map +1 -0
  94. package/node_modules/@noodle-borg/compiler/dist/manifest/naming.js +18 -0
  95. package/node_modules/@noodle-borg/compiler/dist/manifest/naming.js.map +1 -0
  96. package/node_modules/@noodle-borg/compiler/dist/manifest/schema-refs.d.ts +24 -0
  97. package/node_modules/@noodle-borg/compiler/dist/manifest/schema-refs.d.ts.map +1 -0
  98. package/node_modules/@noodle-borg/compiler/dist/manifest/schema-refs.js +149 -0
  99. package/node_modules/@noodle-borg/compiler/dist/manifest/schema-refs.js.map +1 -0
  100. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +97 -0
  101. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts.map +1 -0
  102. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +157 -0
  103. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js.map +1 -0
  104. package/node_modules/@noodle-borg/compiler/dist/schema-export.d.ts +6 -0
  105. package/node_modules/@noodle-borg/compiler/dist/schema-export.d.ts.map +1 -0
  106. package/node_modules/@noodle-borg/compiler/dist/schema-export.js +28 -0
  107. package/node_modules/@noodle-borg/compiler/dist/schema-export.js.map +1 -0
  108. package/node_modules/@noodle-borg/compiler/dist/suggest.d.ts +41 -0
  109. package/node_modules/@noodle-borg/compiler/dist/suggest.d.ts.map +1 -0
  110. package/node_modules/@noodle-borg/compiler/dist/suggest.js +105 -0
  111. package/node_modules/@noodle-borg/compiler/dist/suggest.js.map +1 -0
  112. package/node_modules/@noodle-borg/compiler/dist/uri-template.d.ts +33 -0
  113. package/node_modules/@noodle-borg/compiler/dist/uri-template.d.ts.map +1 -0
  114. package/node_modules/@noodle-borg/compiler/dist/uri-template.js +83 -0
  115. package/node_modules/@noodle-borg/compiler/dist/uri-template.js.map +1 -0
  116. package/node_modules/@noodle-borg/compiler/package.json +32 -0
  117. package/node_modules/@noodle-borg/compute/dist/code-connector.d.ts +45 -0
  118. package/node_modules/@noodle-borg/compute/dist/code-connector.d.ts.map +1 -0
  119. package/node_modules/@noodle-borg/compute/dist/code-connector.js +53 -0
  120. package/node_modules/@noodle-borg/compute/dist/code-connector.js.map +1 -0
  121. package/node_modules/@noodle-borg/compute/dist/engine.d.ts +73 -0
  122. package/node_modules/@noodle-borg/compute/dist/engine.d.ts.map +1 -0
  123. package/node_modules/@noodle-borg/compute/dist/engine.js +31 -0
  124. package/node_modules/@noodle-borg/compute/dist/engine.js.map +1 -0
  125. package/node_modules/@noodle-borg/compute/dist/index.d.ts +4 -0
  126. package/node_modules/@noodle-borg/compute/dist/index.d.ts.map +1 -0
  127. package/node_modules/@noodle-borg/compute/dist/index.js +4 -0
  128. package/node_modules/@noodle-borg/compute/dist/index.js.map +1 -0
  129. package/node_modules/@noodle-borg/compute/dist/quickjs-engine.d.ts +31 -0
  130. package/node_modules/@noodle-borg/compute/dist/quickjs-engine.d.ts.map +1 -0
  131. package/node_modules/@noodle-borg/compute/dist/quickjs-engine.js +271 -0
  132. package/node_modules/@noodle-borg/compute/dist/quickjs-engine.js.map +1 -0
  133. package/node_modules/@noodle-borg/compute/package.json +29 -0
  134. package/node_modules/@noodle-borg/connector-defs/dist/compile.d.ts +46 -0
  135. package/node_modules/@noodle-borg/connector-defs/dist/compile.d.ts.map +1 -0
  136. package/node_modules/@noodle-borg/connector-defs/dist/compile.js +289 -0
  137. package/node_modules/@noodle-borg/connector-defs/dist/compile.js.map +1 -0
  138. package/node_modules/@noodle-borg/connector-defs/dist/index.d.ts +3 -0
  139. package/node_modules/@noodle-borg/connector-defs/dist/index.d.ts.map +1 -0
  140. package/node_modules/@noodle-borg/connector-defs/dist/index.js +3 -0
  141. package/node_modules/@noodle-borg/connector-defs/dist/index.js.map +1 -0
  142. package/node_modules/@noodle-borg/connector-defs/dist/schema.d.ts +332 -0
  143. package/node_modules/@noodle-borg/connector-defs/dist/schema.d.ts.map +1 -0
  144. package/node_modules/@noodle-borg/connector-defs/dist/schema.js +105 -0
  145. package/node_modules/@noodle-borg/connector-defs/dist/schema.js.map +1 -0
  146. package/node_modules/@noodle-borg/connector-defs/package.json +32 -0
  147. package/node_modules/@noodle-borg/connector-http/dist/http-connector.d.ts +86 -0
  148. package/node_modules/@noodle-borg/connector-http/dist/http-connector.d.ts.map +1 -0
  149. package/node_modules/@noodle-borg/connector-http/dist/http-connector.js +138 -0
  150. package/node_modules/@noodle-borg/connector-http/dist/http-connector.js.map +1 -0
  151. package/node_modules/@noodle-borg/connector-http/dist/index.d.ts +3 -0
  152. package/node_modules/@noodle-borg/connector-http/dist/index.d.ts.map +1 -0
  153. package/node_modules/@noodle-borg/connector-http/dist/index.js +3 -0
  154. package/node_modules/@noodle-borg/connector-http/dist/index.js.map +1 -0
  155. package/node_modules/@noodle-borg/connector-http/dist/ssrf.d.ts +45 -0
  156. package/node_modules/@noodle-borg/connector-http/dist/ssrf.d.ts.map +1 -0
  157. package/node_modules/@noodle-borg/connector-http/dist/ssrf.js +57 -0
  158. package/node_modules/@noodle-borg/connector-http/dist/ssrf.js.map +1 -0
  159. package/node_modules/@noodle-borg/connector-http/package.json +30 -0
  160. package/node_modules/@noodle-borg/protocol/dist/adapter.d.ts +73 -0
  161. package/node_modules/@noodle-borg/protocol/dist/adapter.d.ts.map +1 -0
  162. package/node_modules/@noodle-borg/protocol/dist/adapter.js +2 -0
  163. package/node_modules/@noodle-borg/protocol/dist/adapter.js.map +1 -0
  164. package/node_modules/@noodle-borg/protocol/dist/adapters/mcp-2025-11-25.d.ts +19 -0
  165. package/node_modules/@noodle-borg/protocol/dist/adapters/mcp-2025-11-25.d.ts.map +1 -0
  166. package/node_modules/@noodle-borg/protocol/dist/adapters/mcp-2025-11-25.js +34 -0
  167. package/node_modules/@noodle-borg/protocol/dist/adapters/mcp-2025-11-25.js.map +1 -0
  168. package/node_modules/@noodle-borg/protocol/dist/index.d.ts +5 -0
  169. package/node_modules/@noodle-borg/protocol/dist/index.d.ts.map +1 -0
  170. package/node_modules/@noodle-borg/protocol/dist/index.js +5 -0
  171. package/node_modules/@noodle-borg/protocol/dist/index.js.map +1 -0
  172. package/node_modules/@noodle-borg/protocol/dist/jsonrpc.d.ts +19 -0
  173. package/node_modules/@noodle-borg/protocol/dist/jsonrpc.d.ts.map +1 -0
  174. package/node_modules/@noodle-borg/protocol/dist/jsonrpc.js +14 -0
  175. package/node_modules/@noodle-borg/protocol/dist/jsonrpc.js.map +1 -0
  176. package/node_modules/@noodle-borg/protocol/dist/mapping.d.ts +133 -0
  177. package/node_modules/@noodle-borg/protocol/dist/mapping.d.ts.map +1 -0
  178. package/node_modules/@noodle-borg/protocol/dist/mapping.js +181 -0
  179. package/node_modules/@noodle-borg/protocol/dist/mapping.js.map +1 -0
  180. package/node_modules/@noodle-borg/protocol/dist/negotiate.d.ts +13 -0
  181. package/node_modules/@noodle-borg/protocol/dist/negotiate.d.ts.map +1 -0
  182. package/node_modules/@noodle-borg/protocol/dist/negotiate.js +18 -0
  183. package/node_modules/@noodle-borg/protocol/dist/negotiate.js.map +1 -0
  184. package/node_modules/@noodle-borg/protocol/dist/registry.d.ts +17 -0
  185. package/node_modules/@noodle-borg/protocol/dist/registry.d.ts.map +1 -0
  186. package/node_modules/@noodle-borg/protocol/dist/registry.js +33 -0
  187. package/node_modules/@noodle-borg/protocol/dist/registry.js.map +1 -0
  188. package/node_modules/@noodle-borg/protocol/dist/sdk-server.d.ts +22 -0
  189. package/node_modules/@noodle-borg/protocol/dist/sdk-server.d.ts.map +1 -0
  190. package/node_modules/@noodle-borg/protocol/dist/sdk-server.js +91 -0
  191. package/node_modules/@noodle-borg/protocol/dist/sdk-server.js.map +1 -0
  192. package/node_modules/@noodle-borg/protocol/dist/server.d.ts +38 -0
  193. package/node_modules/@noodle-borg/protocol/dist/server.d.ts.map +1 -0
  194. package/node_modules/@noodle-borg/protocol/dist/server.js +89 -0
  195. package/node_modules/@noodle-borg/protocol/dist/server.js.map +1 -0
  196. package/node_modules/@noodle-borg/protocol/dist/stateless.d.ts +14 -0
  197. package/node_modules/@noodle-borg/protocol/dist/stateless.d.ts.map +1 -0
  198. package/node_modules/@noodle-borg/protocol/dist/stateless.js +28 -0
  199. package/node_modules/@noodle-borg/protocol/dist/stateless.js.map +1 -0
  200. package/node_modules/@noodle-borg/protocol/dist/widget/bootstrap.d.ts +24 -0
  201. package/node_modules/@noodle-borg/protocol/dist/widget/bootstrap.d.ts.map +1 -0
  202. package/node_modules/@noodle-borg/protocol/dist/widget/bootstrap.js +165 -0
  203. package/node_modules/@noodle-borg/protocol/dist/widget/bootstrap.js.map +1 -0
  204. package/node_modules/@noodle-borg/protocol/dist/widget/ext-apps-bundle.d.ts +4 -0
  205. package/node_modules/@noodle-borg/protocol/dist/widget/ext-apps-bundle.d.ts.map +1 -0
  206. package/node_modules/@noodle-borg/protocol/dist/widget/ext-apps-bundle.js +10 -0
  207. package/node_modules/@noodle-borg/protocol/dist/widget/ext-apps-bundle.js.map +1 -0
  208. package/node_modules/@noodle-borg/protocol/dist/widget/inject.d.ts +8 -0
  209. package/node_modules/@noodle-borg/protocol/dist/widget/inject.d.ts.map +1 -0
  210. package/node_modules/@noodle-borg/protocol/dist/widget/inject.js +36 -0
  211. package/node_modules/@noodle-borg/protocol/dist/widget/inject.js.map +1 -0
  212. package/node_modules/@noodle-borg/protocol/package.json +29 -0
  213. package/node_modules/@noodle-borg/runtime/dist/broker/map.d.ts +29 -0
  214. package/node_modules/@noodle-borg/runtime/dist/broker/map.d.ts.map +1 -0
  215. package/node_modules/@noodle-borg/runtime/dist/broker/map.js +38 -0
  216. package/node_modules/@noodle-borg/runtime/dist/broker/map.js.map +1 -0
  217. package/node_modules/@noodle-borg/runtime/dist/broker/secret-box.d.ts +103 -0
  218. package/node_modules/@noodle-borg/runtime/dist/broker/secret-box.d.ts.map +1 -0
  219. package/node_modules/@noodle-borg/runtime/dist/broker/secret-box.js +118 -0
  220. package/node_modules/@noodle-borg/runtime/dist/broker/secret-box.js.map +1 -0
  221. package/node_modules/@noodle-borg/runtime/dist/broker/static.d.ts +12 -0
  222. package/node_modules/@noodle-borg/runtime/dist/broker/static.d.ts.map +1 -0
  223. package/node_modules/@noodle-borg/runtime/dist/broker/static.js +15 -0
  224. package/node_modules/@noodle-borg/runtime/dist/broker/static.js.map +1 -0
  225. package/node_modules/@noodle-borg/runtime/dist/broker/types.d.ts +28 -0
  226. package/node_modules/@noodle-borg/runtime/dist/broker/types.d.ts.map +1 -0
  227. package/node_modules/@noodle-borg/runtime/dist/broker/types.js +2 -0
  228. package/node_modules/@noodle-borg/runtime/dist/broker/types.js.map +1 -0
  229. package/node_modules/@noodle-borg/runtime/dist/connector/in-memory.d.ts +29 -0
  230. package/node_modules/@noodle-borg/runtime/dist/connector/in-memory.d.ts.map +1 -0
  231. package/node_modules/@noodle-borg/runtime/dist/connector/in-memory.js +37 -0
  232. package/node_modules/@noodle-borg/runtime/dist/connector/in-memory.js.map +1 -0
  233. package/node_modules/@noodle-borg/runtime/dist/connector/types.d.ts +41 -0
  234. package/node_modules/@noodle-borg/runtime/dist/connector/types.d.ts.map +1 -0
  235. package/node_modules/@noodle-borg/runtime/dist/connector/types.js +2 -0
  236. package/node_modules/@noodle-borg/runtime/dist/connector/types.js.map +1 -0
  237. package/node_modules/@noodle-borg/runtime/dist/eval/evaluate.d.ts +39 -0
  238. package/node_modules/@noodle-borg/runtime/dist/eval/evaluate.d.ts.map +1 -0
  239. package/node_modules/@noodle-borg/runtime/dist/eval/evaluate.js +117 -0
  240. package/node_modules/@noodle-borg/runtime/dist/eval/evaluate.js.map +1 -0
  241. package/node_modules/@noodle-borg/runtime/dist/execute.d.ts +47 -0
  242. package/node_modules/@noodle-borg/runtime/dist/execute.d.ts.map +1 -0
  243. package/node_modules/@noodle-borg/runtime/dist/execute.js +297 -0
  244. package/node_modules/@noodle-borg/runtime/dist/execute.js.map +1 -0
  245. package/node_modules/@noodle-borg/runtime/dist/index.d.ts +12 -0
  246. package/node_modules/@noodle-borg/runtime/dist/index.d.ts.map +1 -0
  247. package/node_modules/@noodle-borg/runtime/dist/index.js +8 -0
  248. package/node_modules/@noodle-borg/runtime/dist/index.js.map +1 -0
  249. package/node_modules/@noodle-borg/runtime/dist/policy/allow-all.d.ts +10 -0
  250. package/node_modules/@noodle-borg/runtime/dist/policy/allow-all.d.ts.map +1 -0
  251. package/node_modules/@noodle-borg/runtime/dist/policy/allow-all.js +13 -0
  252. package/node_modules/@noodle-borg/runtime/dist/policy/allow-all.js.map +1 -0
  253. package/node_modules/@noodle-borg/runtime/dist/policy/types.d.ts +25 -0
  254. package/node_modules/@noodle-borg/runtime/dist/policy/types.d.ts.map +1 -0
  255. package/node_modules/@noodle-borg/runtime/dist/policy/types.js +2 -0
  256. package/node_modules/@noodle-borg/runtime/dist/policy/types.js.map +1 -0
  257. package/node_modules/@noodle-borg/runtime/dist/result.d.ts +19 -0
  258. package/node_modules/@noodle-borg/runtime/dist/result.d.ts.map +1 -0
  259. package/node_modules/@noodle-borg/runtime/dist/result.js +2 -0
  260. package/node_modules/@noodle-borg/runtime/dist/result.js.map +1 -0
  261. package/node_modules/@noodle-borg/runtime/package.json +27 -0
  262. package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.d.ts +48 -0
  263. package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.d.ts.map +1 -0
  264. package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.js +79 -0
  265. package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.js.map +1 -0
  266. package/node_modules/@noodle-borg/service/dist/index.d.ts +7 -0
  267. package/node_modules/@noodle-borg/service/dist/index.d.ts.map +1 -0
  268. package/node_modules/@noodle-borg/service/dist/index.js +7 -0
  269. package/node_modules/@noodle-borg/service/dist/index.js.map +1 -0
  270. package/node_modules/@noodle-borg/service/dist/main.d.ts +3 -0
  271. package/node_modules/@noodle-borg/service/dist/main.d.ts.map +1 -0
  272. package/node_modules/@noodle-borg/service/dist/main.js +171 -0
  273. package/node_modules/@noodle-borg/service/dist/main.js.map +1 -0
  274. package/node_modules/@noodle-borg/service/dist/oauth/app.d.ts +14 -0
  275. package/node_modules/@noodle-borg/service/dist/oauth/app.d.ts.map +1 -0
  276. package/node_modules/@noodle-borg/service/dist/oauth/app.js +48 -0
  277. package/node_modules/@noodle-borg/service/dist/oauth/app.js.map +1 -0
  278. package/node_modules/@noodle-borg/service/dist/oauth/consent.d.ts +18 -0
  279. package/node_modules/@noodle-borg/service/dist/oauth/consent.d.ts.map +1 -0
  280. package/node_modules/@noodle-borg/service/dist/oauth/consent.js +55 -0
  281. package/node_modules/@noodle-borg/service/dist/oauth/consent.js.map +1 -0
  282. package/node_modules/@noodle-borg/service/dist/oauth/google.d.ts +31 -0
  283. package/node_modules/@noodle-borg/service/dist/oauth/google.d.ts.map +1 -0
  284. package/node_modules/@noodle-borg/service/dist/oauth/google.js +39 -0
  285. package/node_modules/@noodle-borg/service/dist/oauth/google.js.map +1 -0
  286. package/node_modules/@noodle-borg/service/dist/oauth/paths.d.ts +3 -0
  287. package/node_modules/@noodle-borg/service/dist/oauth/paths.d.ts.map +1 -0
  288. package/node_modules/@noodle-borg/service/dist/oauth/paths.js +19 -0
  289. package/node_modules/@noodle-borg/service/dist/oauth/paths.js.map +1 -0
  290. package/node_modules/@noodle-borg/service/dist/oauth/provider.d.ts +61 -0
  291. package/node_modules/@noodle-borg/service/dist/oauth/provider.d.ts.map +1 -0
  292. package/node_modules/@noodle-borg/service/dist/oauth/provider.js +313 -0
  293. package/node_modules/@noodle-borg/service/dist/oauth/provider.js.map +1 -0
  294. package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.d.ts +29 -0
  295. package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.d.ts.map +1 -0
  296. package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.js +176 -0
  297. package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.js.map +1 -0
  298. package/node_modules/@noodle-borg/service/dist/oauth/store.d.ts +85 -0
  299. package/node_modules/@noodle-borg/service/dist/oauth/store.d.ts.map +1 -0
  300. package/node_modules/@noodle-borg/service/dist/oauth/store.js +57 -0
  301. package/node_modules/@noodle-borg/service/dist/oauth/store.js.map +1 -0
  302. package/node_modules/@noodle-borg/service/dist/oauth/tokens.d.ts +8 -0
  303. package/node_modules/@noodle-borg/service/dist/oauth/tokens.d.ts.map +1 -0
  304. package/node_modules/@noodle-borg/service/dist/oauth/tokens.js +13 -0
  305. package/node_modules/@noodle-borg/service/dist/oauth/tokens.js.map +1 -0
  306. package/node_modules/@noodle-borg/service/dist/secret/kms-master-key.d.ts +36 -0
  307. package/node_modules/@noodle-borg/service/dist/secret/kms-master-key.d.ts.map +1 -0
  308. package/node_modules/@noodle-borg/service/dist/secret/kms-master-key.js +51 -0
  309. package/node_modules/@noodle-borg/service/dist/secret/kms-master-key.js.map +1 -0
  310. package/node_modules/@noodle-borg/service/dist/service.d.ts +221 -0
  311. package/node_modules/@noodle-borg/service/dist/service.d.ts.map +1 -0
  312. package/node_modules/@noodle-borg/service/dist/service.js +1163 -0
  313. package/node_modules/@noodle-borg/service/dist/service.js.map +1 -0
  314. package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.d.ts +34 -0
  315. package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.d.ts.map +1 -0
  316. package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.js +38 -0
  317. package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.js.map +1 -0
  318. package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts +56 -0
  319. package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts.map +1 -0
  320. package/node_modules/@noodle-borg/service/dist/store/postgres.js +372 -0
  321. package/node_modules/@noodle-borg/service/dist/store/postgres.js.map +1 -0
  322. package/node_modules/@noodle-borg/service/dist/store.d.ts +192 -0
  323. package/node_modules/@noodle-borg/service/dist/store.d.ts.map +1 -0
  324. package/node_modules/@noodle-borg/service/dist/store.js +230 -0
  325. package/node_modules/@noodle-borg/service/dist/store.js.map +1 -0
  326. package/node_modules/@noodle-borg/service/package.json +44 -0
  327. package/node_modules/@noodle-borg/transport-http/dist/caller-auth.d.ts +15 -0
  328. package/node_modules/@noodle-borg/transport-http/dist/caller-auth.d.ts.map +1 -0
  329. package/node_modules/@noodle-borg/transport-http/dist/caller-auth.js +38 -0
  330. package/node_modules/@noodle-borg/transport-http/dist/caller-auth.js.map +1 -0
  331. package/node_modules/@noodle-borg/transport-http/dist/examples/serve-demo.d.ts +2 -0
  332. package/node_modules/@noodle-borg/transport-http/dist/examples/serve-demo.d.ts.map +1 -0
  333. package/node_modules/@noodle-borg/transport-http/dist/examples/serve-demo.js +129 -0
  334. package/node_modules/@noodle-borg/transport-http/dist/examples/serve-demo.js.map +1 -0
  335. package/node_modules/@noodle-borg/transport-http/dist/front-door.d.ts +46 -0
  336. package/node_modules/@noodle-borg/transport-http/dist/front-door.d.ts.map +1 -0
  337. package/node_modules/@noodle-borg/transport-http/dist/front-door.js +75 -0
  338. package/node_modules/@noodle-borg/transport-http/dist/front-door.js.map +1 -0
  339. package/node_modules/@noodle-borg/transport-http/dist/handler.d.ts +142 -0
  340. package/node_modules/@noodle-borg/transport-http/dist/handler.d.ts.map +1 -0
  341. package/node_modules/@noodle-borg/transport-http/dist/handler.js +387 -0
  342. package/node_modules/@noodle-borg/transport-http/dist/handler.js.map +1 -0
  343. package/node_modules/@noodle-borg/transport-http/dist/index.d.ts +6 -0
  344. package/node_modules/@noodle-borg/transport-http/dist/index.d.ts.map +1 -0
  345. package/node_modules/@noodle-borg/transport-http/dist/index.js +6 -0
  346. package/node_modules/@noodle-borg/transport-http/dist/index.js.map +1 -0
  347. package/node_modules/@noodle-borg/transport-http/dist/logging.d.ts +41 -0
  348. package/node_modules/@noodle-borg/transport-http/dist/logging.d.ts.map +1 -0
  349. package/node_modules/@noodle-borg/transport-http/dist/logging.js +71 -0
  350. package/node_modules/@noodle-borg/transport-http/dist/logging.js.map +1 -0
  351. package/node_modules/@noodle-borg/transport-http/dist/serve.d.ts +22 -0
  352. package/node_modules/@noodle-borg/transport-http/dist/serve.d.ts.map +1 -0
  353. package/node_modules/@noodle-borg/transport-http/dist/serve.js +25 -0
  354. package/node_modules/@noodle-borg/transport-http/dist/serve.js.map +1 -0
  355. package/node_modules/@noodle-borg/transport-http/package.json +30 -0
  356. package/package.json +78 -0
@@ -0,0 +1,39 @@
1
+ import { OAuth2Client } from 'google-auth-library';
2
+ export class GoogleOAuthAuthenticator {
3
+ #config;
4
+ #client;
5
+ constructor(config) {
6
+ this.#config = config;
7
+ this.#client = new OAuth2Client({
8
+ clientId: config.clientId,
9
+ clientSecret: config.clientSecret,
10
+ redirectUri: config.redirectUri,
11
+ });
12
+ }
13
+ authorizationUrl(state) {
14
+ return this.#client.generateAuthUrl({
15
+ scope: ['openid', 'email', 'profile'],
16
+ state,
17
+ access_type: 'online',
18
+ // Force the account chooser so a returning user can pick the identity; also a UX guard against
19
+ // silently reusing a wrong session.
20
+ prompt: 'select_account',
21
+ });
22
+ }
23
+ async exchange(code) {
24
+ const { tokens } = await this.#client.getToken(code);
25
+ const idToken = tokens.id_token;
26
+ if (!idToken)
27
+ throw new Error('Google token response had no id_token');
28
+ const ticket = await this.#client.verifyIdToken({ idToken, audience: this.#config.clientId });
29
+ const payload = ticket.getPayload();
30
+ const subject = payload?.sub;
31
+ const email = payload?.email;
32
+ const emailVerified = payload?.email_verified;
33
+ if (typeof subject !== 'string' || typeof email !== 'string' || emailVerified !== true) {
34
+ throw new Error('Google identity is missing a verified subject/email');
35
+ }
36
+ return { subject, email };
37
+ }
38
+ }
39
+ //# sourceMappingURL=google.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/oauth/google.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA6BnD,MAAM,OAAO,wBAAwB;IAC1B,OAAO,CAAoB;IAC3B,OAAO,CAAe;IAE/B,YAAY,MAAyB;QACnC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,IAAI,YAAY,CAAC;YAC9B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,CAAC,KAAa;QAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC;YAClC,KAAK,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC;YACrC,KAAK;YACL,WAAW,EAAE,QAAQ;YACrB,+FAA+F;YAC/F,oCAAoC;YACpC,MAAM,EAAE,gBAAgB;SACzB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY;QACzB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9F,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,OAAO,EAAE,GAAG,CAAC;QAC7B,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC;QAC7B,MAAM,aAAa,GAAG,OAAO,EAAE,cAAc,CAAC;QAC9C,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YACvF,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ /** Whether a request path is owned by the authorization-server sub-app (delegated from the front-door). */
2
+ export declare function isAuthServerPath(pathname: string): boolean;
3
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/oauth/paths.ts"],"names":[],"mappings":"AAeA,2GAA2G;AAC3G,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1D"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Paths owned by the authorization-server sub-app (OA-2). Kept in its own dependency-free module so the
3
+ * raw-`node:http` front-door can decide delegation without importing Express — Express (and the AS app) load
4
+ * lazily, only when the authorization server is actually enabled.
5
+ */
6
+ const AUTH_SERVER_PATHS = new Set([
7
+ '/authorize',
8
+ '/token',
9
+ '/register',
10
+ '/oauth/google/callback',
11
+ '/oauth/consent',
12
+ '/.well-known/oauth-authorization-server',
13
+ '/.well-known/jwks.json',
14
+ ]);
15
+ /** Whether a request path is owned by the authorization-server sub-app (delegated from the front-door). */
16
+ export function isAuthServerPath(pathname) {
17
+ return AUTH_SERVER_PATHS.has(pathname);
18
+ }
19
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/oauth/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,iBAAiB,GAAwB,IAAI,GAAG,CAAC;IACrD,YAAY;IACZ,QAAQ;IACR,WAAW;IACX,wBAAwB;IACxB,gBAAgB;IAChB,yCAAyC;IACzC,wBAAwB;CACzB,CAAC,CAAC;AAEH,2GAA2G;AAC3G,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { OAuthRegisteredClientsStore } from '@modelcontextprotocol/sdk/server/auth/clients.js';
2
+ import type { AuthorizationParams, OAuthServerProvider } from '@modelcontextprotocol/sdk/server/auth/provider.js';
3
+ import type { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
4
+ import type { OAuthClientInformationFull, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
5
+ import { type SigningKeyProvider } from '@noodle-borg/auth';
6
+ import type { Request, Response } from 'express';
7
+ import type { GoogleAuthenticator } from './google.js';
8
+ import type { OAuthStore } from './store.js';
9
+ export interface NoodleOAuthProviderConfig {
10
+ /** The authorization server issuer (its public origin, e.g. `https://borg.noodleseed.com`). */
11
+ readonly issuer: string;
12
+ readonly store: OAuthStore;
13
+ readonly signer: SigningKeyProvider;
14
+ readonly google: GoogleAuthenticator;
15
+ /** When set, only users whose email ends with this domain may authorize (alpha gate, e.g. `@noodleseed.com`). */
16
+ readonly allowedEmailDomain?: string;
17
+ readonly accessTokenTtlSeconds?: number;
18
+ readonly refreshTokenTtlSeconds?: number;
19
+ readonly authCodeTtlSeconds?: number;
20
+ readonly pendingTtlSeconds?: number;
21
+ readonly consentTtlSeconds?: number;
22
+ }
23
+ /**
24
+ * The self-hosted OAuth authorization server provider (OA-2,
25
+ * [ADR 0042](../../../../docs/decisions/0042-self-hosted-oauth-authorization-server.md)). Implements the MCP
26
+ * SDK's {@link OAuthServerProvider}: DCR via {@link clientsStore}, an `authorize` that federates to Google,
27
+ * PKCE-validated code exchange (the SDK validates the verifier against {@link challengeForAuthorizationCode}),
28
+ * and rotating refresh tokens. Tokens are minted by `@noodle-borg/auth` and are exactly what the OA-1
29
+ * resource-server verifier validates (`iss` = this issuer, `aud` = the tenant MCP URL, `sub` = Google subject).
30
+ *
31
+ * The Google callback + consent interstitial are extra routes (`handleGoogleCallback`, `handleConsent`) the
32
+ * Express app wires alongside the SDK handlers; the confused-deputy consent step is mandatory because we
33
+ * federate all clients through one static Google client.
34
+ */
35
+ export declare class NoodleOAuthProvider implements OAuthServerProvider {
36
+ #private;
37
+ constructor(config: NoodleOAuthProviderConfig);
38
+ get clientsStore(): OAuthRegisteredClientsStore;
39
+ /** Begin authorization: persist the pending request and redirect the user to "Sign in with Google". */
40
+ authorize(client: OAuthClientInformationFull, params: AuthorizationParams, res: Response): Promise<void>;
41
+ /** Return the stored PKCE challenge for a code (non-destructive — the SDK validates the verifier against it). */
42
+ challengeForAuthorizationCode(client: OAuthClientInformationFull, authorizationCode: string): Promise<string>;
43
+ /** Redeem an authorization code (single-use) and mint the owner's tokens. PKCE was validated by the SDK. */
44
+ exchangeAuthorizationCode(client: OAuthClientInformationFull, authorizationCode: string, _codeVerifier?: string, redirectUri?: string, resource?: URL): Promise<OAuthTokens>;
45
+ /** Rotate a refresh token (single-use): mint a fresh access token and a new refresh token. */
46
+ exchangeRefreshToken(client: OAuthClientInformationFull, refreshToken: string, _scopes?: string[], resource?: URL): Promise<OAuthTokens>;
47
+ /** Verify an access token (issuer/signature/expiry). Provided for interface completeness — the data-plane
48
+ * resource server verifies with its own audience-bound verifier; this is not on the AS request path. */
49
+ verifyAccessToken(token: string): Promise<AuthInfo>;
50
+ /** RFC 8414 authorization-server metadata (plus our `jwks_uri`), served at `/.well-known/oauth-authorization-server`. */
51
+ metadata(): Record<string, unknown>;
52
+ /** The public JWKS the resource server (and external validators) read to verify access tokens. */
53
+ jwks(): Promise<{
54
+ keys: unknown[];
55
+ }>;
56
+ /** Google callback: consume the pending auth, verify the Google identity, and render the consent page. */
57
+ handleGoogleCallback(req: Request, res: Response): Promise<void>;
58
+ /** Consent decision: on approve, mint a PKCE-bound code and redirect to the client; on deny, redirect with an error. */
59
+ handleConsent(req: Request, res: Response): Promise<void>;
60
+ }
61
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/oauth/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kDAAkD,CAAC;AAMpG,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,mDAAmD,CAAC;AAE3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gDAAgD,CAAC;AAC/E,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAS7C,MAAM,WAAW,yBAAyB;IACxC,+FAA+F;IAC/F,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,iHAAiH;IACjH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAeD;;;;;;;;;;;GAWG;AACH,qBAAa,mBAAoB,YAAW,mBAAmB;;gBASjD,MAAM,EAAE,yBAAyB;IAS7C,IAAI,YAAY,IAAI,2BAA2B,CAM9C;IAED,uGAAuG;IACjG,SAAS,CACb,MAAM,EAAE,0BAA0B,EAClC,MAAM,EAAE,mBAAmB,EAC3B,GAAG,EAAE,QAAQ,GACZ,OAAO,CAAC,IAAI,CAAC;IAoBhB,iHAAiH;IAC3G,6BAA6B,CACjC,MAAM,EAAE,0BAA0B,EAClC,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,MAAM,CAAC;IAQlB,4GAA4G;IACtG,yBAAyB,CAC7B,MAAM,EAAE,0BAA0B,EAClC,iBAAiB,EAAE,MAAM,EACzB,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,GAAG,GACb,OAAO,CAAC,WAAW,CAAC;IAoBvB,8FAA8F;IACxF,oBAAoB,CACxB,MAAM,EAAE,0BAA0B,EAClC,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,EAAE,EAClB,QAAQ,CAAC,EAAE,GAAG,GACb,OAAO,CAAC,WAAW,CAAC;IAiBvB;4GACwG;IAClG,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAWzD,yHAAyH;IACzH,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAUnC,kGAAkG;IAClG,IAAI,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;IAIpC,0GAA0G;IACpG,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAyDtE,wHAAwH;IAClH,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAgHhE"}
@@ -0,0 +1,313 @@
1
+ import { InvalidGrantError, InvalidRequestError, InvalidTokenError, } from '@modelcontextprotocol/sdk/server/auth/errors.js';
2
+ import { createOAuthMetadata } from '@modelcontextprotocol/sdk/server/auth/router.js';
3
+ import { createJwtVerifier, mintAccessToken, } from '@noodle-borg/auth';
4
+ import { jwtVerify, SignJWT } from 'jose';
5
+ import { renderConsentPage } from './consent.js';
6
+ import { hashToken, randomToken } from './tokens.js';
7
+ const ONE_HOUR = 3600;
8
+ const THIRTY_DAYS = 30 * 24 * 3600;
9
+ const TEN_MINUTES = 600;
10
+ const FIVE_MINUTES = 300;
11
+ const CONSENT_PATH = '/oauth/consent';
12
+ /**
13
+ * The self-hosted OAuth authorization server provider (OA-2,
14
+ * [ADR 0042](../../../../docs/decisions/0042-self-hosted-oauth-authorization-server.md)). Implements the MCP
15
+ * SDK's {@link OAuthServerProvider}: DCR via {@link clientsStore}, an `authorize` that federates to Google,
16
+ * PKCE-validated code exchange (the SDK validates the verifier against {@link challengeForAuthorizationCode}),
17
+ * and rotating refresh tokens. Tokens are minted by `@noodle-borg/auth` and are exactly what the OA-1
18
+ * resource-server verifier validates (`iss` = this issuer, `aud` = the tenant MCP URL, `sub` = Google subject).
19
+ *
20
+ * The Google callback + consent interstitial are extra routes (`handleGoogleCallback`, `handleConsent`) the
21
+ * Express app wires alongside the SDK handlers; the confused-deputy consent step is mandatory because we
22
+ * federate all clients through one static Google client.
23
+ */
24
+ export class NoodleOAuthProvider {
25
+ #config;
26
+ #accessTtl;
27
+ #refreshTtl;
28
+ #codeTtl;
29
+ #pendingTtl;
30
+ #consentTtl;
31
+ #verifier;
32
+ constructor(config) {
33
+ this.#config = config;
34
+ this.#accessTtl = config.accessTokenTtlSeconds ?? ONE_HOUR;
35
+ this.#refreshTtl = config.refreshTokenTtlSeconds ?? THIRTY_DAYS;
36
+ this.#codeTtl = config.authCodeTtlSeconds ?? TEN_MINUTES;
37
+ this.#pendingTtl = config.pendingTtlSeconds ?? TEN_MINUTES;
38
+ this.#consentTtl = config.consentTtlSeconds ?? FIVE_MINUTES;
39
+ }
40
+ get clientsStore() {
41
+ return {
42
+ getClient: (clientId) => this.#config.store.getClient(clientId),
43
+ registerClient: (client) => this.#config.store.putClient(client),
44
+ };
45
+ }
46
+ /** Begin authorization: persist the pending request and redirect the user to "Sign in with Google". */
47
+ async authorize(client, params, res) {
48
+ // RFC 8707: the client MUST bind the token to a resource. Owner-only tokens are audience-bound to the
49
+ // tenant MCP URL, so without it we cannot mint a usable token — fail before redirecting to Google.
50
+ if (!params.resource) {
51
+ throw new InvalidRequestError('the resource parameter is required');
52
+ }
53
+ const nonce = randomToken();
54
+ await this.#config.store.createPendingAuthorization({
55
+ state: hashToken(nonce),
56
+ clientId: client.client_id,
57
+ redirectUri: params.redirectUri,
58
+ codeChallenge: params.codeChallenge,
59
+ ...(params.state !== undefined ? { clientState: params.state } : {}),
60
+ resource: params.resource.href,
61
+ ...(params.scopes && params.scopes.length > 0 ? { scope: params.scopes.join(' ') } : {}),
62
+ expiresAt: this.#nowSeconds() + this.#pendingTtl,
63
+ });
64
+ res.redirect(302, this.#config.google.authorizationUrl(nonce));
65
+ }
66
+ /** Return the stored PKCE challenge for a code (non-destructive — the SDK validates the verifier against it). */
67
+ async challengeForAuthorizationCode(client, authorizationCode) {
68
+ const record = await this.#config.store.getAuthorizationCode(hashToken(authorizationCode));
69
+ if (!record || record.clientId !== client.client_id) {
70
+ throw new InvalidGrantError('invalid authorization code');
71
+ }
72
+ return record.codeChallenge;
73
+ }
74
+ /** Redeem an authorization code (single-use) and mint the owner's tokens. PKCE was validated by the SDK. */
75
+ async exchangeAuthorizationCode(client, authorizationCode, _codeVerifier, redirectUri, resource) {
76
+ const record = await this.#config.store.redeemAuthorizationCode(hashToken(authorizationCode));
77
+ if (!record || record.clientId !== client.client_id) {
78
+ throw new InvalidGrantError('invalid authorization code');
79
+ }
80
+ if (redirectUri !== undefined && redirectUri !== record.redirectUri) {
81
+ throw new InvalidGrantError('redirect_uri does not match the authorization request');
82
+ }
83
+ if (resource !== undefined && resource.href !== record.resource) {
84
+ throw new InvalidGrantError('resource does not match the authorization request');
85
+ }
86
+ return this.#issueTokens({
87
+ clientId: client.client_id,
88
+ ownerSubject: record.ownerSubject,
89
+ resource: record.resource,
90
+ ...(record.ownerEmail !== undefined ? { ownerEmail: record.ownerEmail } : {}),
91
+ ...(record.scope !== undefined ? { scope: record.scope } : {}),
92
+ });
93
+ }
94
+ /** Rotate a refresh token (single-use): mint a fresh access token and a new refresh token. */
95
+ async exchangeRefreshToken(client, refreshToken, _scopes, resource) {
96
+ const record = await this.#config.store.consumeRefreshToken(hashToken(refreshToken));
97
+ if (!record || record.clientId !== client.client_id) {
98
+ throw new InvalidGrantError('invalid refresh token');
99
+ }
100
+ if (resource !== undefined && resource.href !== record.resource) {
101
+ throw new InvalidGrantError('resource does not match the refresh token');
102
+ }
103
+ return this.#issueTokens({
104
+ clientId: client.client_id,
105
+ ownerSubject: record.ownerSubject,
106
+ resource: record.resource,
107
+ ...(record.ownerEmail !== undefined ? { ownerEmail: record.ownerEmail } : {}),
108
+ ...(record.scope !== undefined ? { scope: record.scope } : {}),
109
+ });
110
+ }
111
+ /** Verify an access token (issuer/signature/expiry). Provided for interface completeness — the data-plane
112
+ * resource server verifies with its own audience-bound verifier; this is not on the AS request path. */
113
+ async verifyAccessToken(token) {
114
+ const identity = await this.#verify()(token);
115
+ if (!identity)
116
+ throw new InvalidTokenError('invalid or expired access token');
117
+ return {
118
+ token,
119
+ clientId: '',
120
+ scopes: [...identity.scopes],
121
+ ...(identity.expiresAt !== undefined ? { expiresAt: identity.expiresAt } : {}),
122
+ };
123
+ }
124
+ /** RFC 8414 authorization-server metadata (plus our `jwks_uri`), served at `/.well-known/oauth-authorization-server`. */
125
+ metadata() {
126
+ const issuer = trimTrailingSlash(this.#config.issuer);
127
+ const base = createOAuthMetadata({ provider: this, issuerUrl: new URL(issuer) });
128
+ // The SDK emits `issuer` as `URL.href`, which appends a trailing slash for a path-less origin
129
+ // (`https://h` → `https://h/`). RFC 8414 §3.3 requires the metadata `issuer` to be identical to the
130
+ // issuer used to build the well-known URL, and our token `iss` + the PRM `authorization_servers` entry
131
+ // use the no-slash form — so normalize it back for consistency across all three.
132
+ return { ...base, issuer, jwks_uri: `${issuer}/.well-known/jwks.json` };
133
+ }
134
+ /** The public JWKS the resource server (and external validators) read to verify access tokens. */
135
+ jwks() {
136
+ return this.#config.signer.publicJwks();
137
+ }
138
+ /** Google callback: consume the pending auth, verify the Google identity, and render the consent page. */
139
+ async handleGoogleCallback(req, res) {
140
+ if (typeof req.query.error === 'string') {
141
+ res.status(400).type('text/plain').send(`Google sign-in failed: ${req.query.error}`);
142
+ return;
143
+ }
144
+ const code = typeof req.query.code === 'string' ? req.query.code : undefined;
145
+ const state = typeof req.query.state === 'string' ? req.query.state : undefined;
146
+ if (!code || !state) {
147
+ res.status(400).type('text/plain').send('missing authorization code or state');
148
+ return;
149
+ }
150
+ const pending = await this.#config.store.consumePendingAuthorization(hashToken(state));
151
+ if (!pending) {
152
+ res.status(400).type('text/plain').send('unknown or expired authorization request');
153
+ return;
154
+ }
155
+ let identity;
156
+ try {
157
+ identity = await this.#config.google.exchange(code);
158
+ }
159
+ catch {
160
+ res.status(400).type('text/plain').send('Google authentication failed');
161
+ return;
162
+ }
163
+ if (this.#config.allowedEmailDomain &&
164
+ !identity.email.toLowerCase().endsWith(this.#config.allowedEmailDomain.toLowerCase())) {
165
+ res.status(403).type('text/plain').send('this Google account is not permitted');
166
+ return;
167
+ }
168
+ const consentToken = await this.#signConsent({
169
+ kind: 'consent',
170
+ clientId: pending.clientId,
171
+ redirectUri: pending.redirectUri,
172
+ codeChallenge: pending.codeChallenge,
173
+ resource: pending.resource,
174
+ ownerSubject: identity.subject,
175
+ ownerEmail: identity.email,
176
+ ...(pending.clientState !== undefined ? { clientState: pending.clientState } : {}),
177
+ ...(pending.scope !== undefined ? { scope: pending.scope } : {}),
178
+ });
179
+ const client = await this.#config.store.getClient(pending.clientId);
180
+ res
181
+ .status(200)
182
+ .type('html')
183
+ .send(renderConsentPage({
184
+ clientName: client?.client_name ?? pending.clientId,
185
+ resourceHost: hostOf(pending.resource),
186
+ redirectHost: hostOf(pending.redirectUri),
187
+ userEmail: identity.email,
188
+ consentToken,
189
+ consentAction: CONSENT_PATH,
190
+ }));
191
+ }
192
+ /** Consent decision: on approve, mint a PKCE-bound code and redirect to the client; on deny, redirect with an error. */
193
+ async handleConsent(req, res) {
194
+ const body = (req.body ?? {});
195
+ const consentToken = typeof body.consent_token === 'string' ? body.consent_token : undefined;
196
+ const decision = typeof body.decision === 'string' ? body.decision : undefined;
197
+ if (!consentToken) {
198
+ res.status(400).type('text/plain').send('missing consent_token');
199
+ return;
200
+ }
201
+ let claims;
202
+ try {
203
+ claims = await this.#verifyConsent(consentToken);
204
+ }
205
+ catch {
206
+ res.status(400).type('text/plain').send('invalid or expired consent');
207
+ return;
208
+ }
209
+ const redirect = new URL(claims.redirectUri);
210
+ if (decision !== 'approve') {
211
+ redirect.searchParams.set('error', 'access_denied');
212
+ if (claims.clientState !== undefined)
213
+ redirect.searchParams.set('state', claims.clientState);
214
+ res.redirect(302, redirect.href);
215
+ return;
216
+ }
217
+ const rawCode = randomToken();
218
+ await this.#config.store.createAuthorizationCode({
219
+ code: hashToken(rawCode),
220
+ clientId: claims.clientId,
221
+ codeChallenge: claims.codeChallenge,
222
+ redirectUri: claims.redirectUri,
223
+ resource: claims.resource,
224
+ ownerSubject: claims.ownerSubject,
225
+ ...(claims.ownerEmail !== undefined ? { ownerEmail: claims.ownerEmail } : {}),
226
+ ...(claims.scope !== undefined ? { scope: claims.scope } : {}),
227
+ expiresAt: this.#nowSeconds() + this.#codeTtl,
228
+ });
229
+ redirect.searchParams.set('code', rawCode);
230
+ if (claims.clientState !== undefined)
231
+ redirect.searchParams.set('state', claims.clientState);
232
+ res.redirect(302, redirect.href);
233
+ }
234
+ async #issueTokens(input) {
235
+ const access_token = await mintAccessToken(this.#config.signer, {
236
+ issuer: this.#config.issuer,
237
+ subject: input.ownerSubject,
238
+ audience: input.resource,
239
+ ...(input.ownerEmail !== undefined ? { email: input.ownerEmail } : {}),
240
+ ...(input.scope !== undefined ? { scope: input.scope } : {}),
241
+ }, this.#accessTtl);
242
+ const rawRefresh = randomToken();
243
+ await this.#config.store.createRefreshToken({
244
+ token: hashToken(rawRefresh),
245
+ clientId: input.clientId,
246
+ ownerSubject: input.ownerSubject,
247
+ resource: input.resource,
248
+ ...(input.ownerEmail !== undefined ? { ownerEmail: input.ownerEmail } : {}),
249
+ ...(input.scope !== undefined ? { scope: input.scope } : {}),
250
+ expiresAt: this.#nowSeconds() + this.#refreshTtl,
251
+ });
252
+ return {
253
+ access_token,
254
+ token_type: 'bearer',
255
+ expires_in: this.#accessTtl,
256
+ refresh_token: rawRefresh,
257
+ ...(input.scope !== undefined ? { scope: input.scope } : {}),
258
+ };
259
+ }
260
+ async #signConsent(claims) {
261
+ const key = await this.#config.signer.signingKey();
262
+ return new SignJWT({ ...claims })
263
+ .setProtectedHeader({ alg: key.alg, kid: key.kid })
264
+ .setIssuer(this.#config.issuer)
265
+ .setIssuedAt()
266
+ .setExpirationTime(`${this.#consentTtl}s`)
267
+ .sign(key.privateKey);
268
+ }
269
+ async #verifyConsent(token) {
270
+ const getKey = await this.#config.signer.verifierKey();
271
+ const { payload } = await jwtVerify(token, getKey, { issuer: this.#config.issuer });
272
+ if (!isConsentClaims(payload))
273
+ throw new Error('not a consent token');
274
+ return payload;
275
+ }
276
+ #verify() {
277
+ if (!this.#verifier) {
278
+ this.#verifier = createJwtVerifier({
279
+ issuer: this.#config.issuer,
280
+ keyResolver: this.#lazyKey,
281
+ });
282
+ }
283
+ return this.#verifier;
284
+ }
285
+ // A resolver that defers to the signer's public key on first use (the signer's key set is stable).
286
+ #lazyKey = async (header, input) => {
287
+ const getKey = await this.#config.signer.verifierKey();
288
+ return getKey(header, input);
289
+ };
290
+ #nowSeconds() {
291
+ return Math.floor(Date.now() / 1000);
292
+ }
293
+ }
294
+ function isConsentClaims(payload) {
295
+ return (payload.kind === 'consent' &&
296
+ typeof payload.clientId === 'string' &&
297
+ typeof payload.redirectUri === 'string' &&
298
+ typeof payload.codeChallenge === 'string' &&
299
+ typeof payload.resource === 'string' &&
300
+ typeof payload.ownerSubject === 'string');
301
+ }
302
+ function hostOf(url) {
303
+ try {
304
+ return new URL(url).host;
305
+ }
306
+ catch {
307
+ return url;
308
+ }
309
+ }
310
+ function trimTrailingSlash(url) {
311
+ return url.endsWith('/') ? url.slice(0, -1) : url;
312
+ }
313
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/oauth/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { OAuthClientInformationFull } from '@modelcontextprotocol/sdk/shared/auth.js';
2
+ import type { Pool } from 'pg';
3
+ import type { AuthorizationCodeRecord, OAuthStore, PendingAuthorizationRecord, RefreshTokenRecord } from './store.js';
4
+ /**
5
+ * Relational {@link OAuthStore} for the self-hosted authorization server (OA-2,
6
+ * [ADR 0042](../../../../docs/decisions/0042-self-hosted-oauth-authorization-server.md)). Shares the injected
7
+ * `pg.Pool` with {@link PostgresArtifactStore} so the AS state lives in the same strongly-consistent store
8
+ * that backs deployments — any Cloud Run instance can complete a flow another started.
9
+ *
10
+ * Single-use semantics are enforced in SQL: `DELETE … RETURNING` (codes, pending auth, refresh tokens) is
11
+ * row-atomic, so two concurrent redemptions of the same value yield exactly one winner; the loser gets zero
12
+ * rows. Expired rows are still deleted on consume (and returned as `undefined`), which doubles as cleanup.
13
+ */
14
+ export declare class PostgresOAuthStore implements OAuthStore {
15
+ #private;
16
+ constructor(pool: Pool);
17
+ /** Create the OAuth tables if absent (idempotent). Run once at startup before serving AS endpoints. */
18
+ ensureSchema(): Promise<void>;
19
+ getClient(clientId: string): Promise<OAuthClientInformationFull | undefined>;
20
+ putClient(client: OAuthClientInformationFull): Promise<OAuthClientInformationFull>;
21
+ createPendingAuthorization(record: PendingAuthorizationRecord): Promise<void>;
22
+ consumePendingAuthorization(state: string): Promise<PendingAuthorizationRecord | undefined>;
23
+ createAuthorizationCode(record: AuthorizationCodeRecord): Promise<void>;
24
+ getAuthorizationCode(code: string): Promise<AuthorizationCodeRecord | undefined>;
25
+ redeemAuthorizationCode(code: string): Promise<AuthorizationCodeRecord | undefined>;
26
+ createRefreshToken(record: RefreshTokenRecord): Promise<void>;
27
+ consumeRefreshToken(token: string): Promise<RefreshTokenRecord | undefined>;
28
+ }
29
+ //# sourceMappingURL=store-postgres.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-postgres.d.ts","sourceRoot":"","sources":["../../src/oauth/store-postgres.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AAC3F,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EACV,uBAAuB,EACvB,UAAU,EACV,0BAA0B,EAC1B,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,YAAW,UAAU;;gBAGvC,IAAI,EAAE,IAAI;IAItB,uGAAuG;IACjG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA8C7B,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC;IAQ5E,SAAS,CAAC,MAAM,EAAE,0BAA0B,GAAG,OAAO,CAAC,0BAA0B,CAAC;IASlF,0BAA0B,CAAC,MAAM,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB7E,2BAA2B,CAC/B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC;IAmB5C,uBAAuB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBvE,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC;IAShF,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC;IAUnF,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB7D,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC;CAiBlF"}