@opengeni/api-router 3.0.1 → 3.0.2-canary.38894290271001

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 (546) hide show
  1. package/dist/access-grant-rls.d.ts +8 -1
  2. package/dist/admission-trace.d.ts +8 -0
  3. package/dist/app.d.ts +50 -3
  4. package/dist/app.js +10 -1
  5. package/dist/artifact-catalog-cursor.d.ts +1 -0
  6. package/dist/attached-browser-viewer.d.ts +11 -0
  7. package/dist/auth/managed-auth-attempt-context.d.ts +2 -0
  8. package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
  9. package/dist/auth/managed-auth-session-adapter.d.ts +9 -1
  10. package/dist/auth/managed-auth.d.ts +72 -5
  11. package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
  12. package/dist/auth/new-signups-gate.d.ts +23 -0
  13. package/dist/auth/signup-funnel-metrics.d.ts +44 -0
  14. package/dist/azure-live.d.ts +28 -0
  15. package/dist/browser-action-fences.d.ts +13 -0
  16. package/dist/browser-controller-authority.d.ts +1 -61
  17. package/dist/browser-ephemeral.d.ts +5 -0
  18. package/dist/browser-lost-runtime-end.d.ts +24 -0
  19. package/dist/browser-state-authority.d.ts +1 -27
  20. package/dist/{chunk-AJ62T5QN.js → chunk-GBUJ2DYZ.js} +80507 -39878
  21. package/dist/chunk-GBUJ2DYZ.js.map +1 -0
  22. package/dist/chunk-OGQDXVXY.js +18 -0
  23. package/dist/chunk-OGQDXVXY.js.map +1 -0
  24. package/dist/claude-default-models.d.ts +19 -0
  25. package/dist/claude-subscription-core.d.ts +50 -0
  26. package/dist/claude-subscription-oauth.d.ts +36 -0
  27. package/dist/claude-subscription-profile.d.ts +9 -0
  28. package/dist/claude-subscription-usage.d.ts +6 -0
  29. package/dist/claude-workspace-connection.d.ts +15 -0
  30. package/dist/codemode.d.ts +40 -5
  31. package/dist/codex-realtime.d.ts +29 -3
  32. package/dist/codex-session-pointers.d.ts +19 -0
  33. package/dist/connection-ownership.d.ts +6 -3
  34. package/dist/controller-data-plane.d.ts +16 -0
  35. package/dist/credit-promotion-snapshot.d.ts +6 -0
  36. package/dist/editable-artifact-source-session.d.ts +3 -0
  37. package/dist/editable-artifact-websocket.d.ts +5 -3
  38. package/dist/fatal-process-boundary.d.ts +9 -1
  39. package/dist/github-access.d.ts +7 -1
  40. package/dist/github-browser-flow.d.ts +1 -1
  41. package/dist/http/acting-person.d.ts +36 -0
  42. package/dist/http/api-contract-compat.d.ts +19 -0
  43. package/dist/http/api-error.d.ts +50 -1
  44. package/dist/http/auth.d.ts +8 -1
  45. package/dist/http/cors.d.ts +12 -0
  46. package/dist/http/deprecation.d.ts +42 -0
  47. package/dist/http/keyed-admission.d.ts +12 -0
  48. package/dist/http/local-browser-boundary.d.ts +72 -0
  49. package/dist/http/metrics-listener.d.ts +22 -0
  50. package/dist/http/path-identifier.d.ts +17 -0
  51. package/dist/http/registered-route-label.d.ts +16 -0
  52. package/dist/http/rejection-telemetry.d.ts +34 -0
  53. package/dist/http/request-body.d.ts +27 -0
  54. package/dist/http/request-source.d.ts +41 -3
  55. package/dist/http/sse.d.ts +12 -1
  56. package/dist/http/unmatched-route.d.ts +18 -0
  57. package/dist/http/user-content.d.ts +36 -0
  58. package/dist/http/variable-sets-removed.d.ts +41 -0
  59. package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
  60. package/dist/index.js +1279 -108
  61. package/dist/index.js.map +1 -1
  62. package/dist/integration-connect-metrics.d.ts +35 -0
  63. package/dist/integration-endpoint-test.d.ts +20 -0
  64. package/dist/integrations/api-integrations.d.ts +2 -2
  65. package/dist/integrations/atlassian.d.ts +8 -3
  66. package/dist/integrations/fiken.d.ts +3 -1
  67. package/dist/integrations/github-lens-connect.d.ts +37 -66
  68. package/dist/integrations/google-drive.d.ts +2 -0
  69. package/dist/integrations/integration-commit-authority.d.ts +13 -0
  70. package/dist/integrations/marketplace-plugin.d.ts +43 -43
  71. package/dist/integrations/oauth-client.d.ts +171 -12
  72. package/dist/integrations/oauth-profiles.d.ts +42 -13
  73. package/dist/integrations/onepassword-vault-provider.d.ts +9 -0
  74. package/dist/integrations/slack-bot.d.ts +285 -7
  75. package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
  76. package/dist/integrations/slack-interactions.d.ts +89 -10
  77. package/dist/integrations/slack-mrkdwn.d.ts +41 -0
  78. package/dist/integrations/slack-routing.d.ts +1 -1
  79. package/dist/integrations/slack-session-defaults.d.ts +58 -0
  80. package/dist/integrations/slack-task-file-upload.d.ts +36 -0
  81. package/dist/integrations/slack-tool-review.d.ts +5 -0
  82. package/dist/interaction-agent-access.d.ts +13 -8
  83. package/dist/interaction-agent-version.d.ts +21 -0
  84. package/dist/interaction-holder-heartbeat.d.ts +5 -0
  85. package/dist/interaction-metrics.d.ts +27 -2
  86. package/dist/interaction-route-stages.d.ts +25 -0
  87. package/dist/interaction-secrets-vault.d.ts +20 -0
  88. package/dist/interaction-secrets.d.ts +103 -0
  89. package/dist/mcp/action-catalog-types.d.ts +14 -0
  90. package/dist/mcp/action-catalog.gen.d.ts +2 -0
  91. package/dist/mcp/action-descriptions.d.ts +4 -0
  92. package/dist/mcp/action-schema-imports.gen.d.ts +1 -0
  93. package/dist/mcp/capability-account-readiness.d.ts +7 -0
  94. package/dist/mcp/child-read-evidence.d.ts +9 -0
  95. package/dist/mcp/company-profile-agent-admin.d.ts +12 -0
  96. package/dist/mcp/contract-input.d.ts +13 -0
  97. package/dist/mcp/documents.d.ts +2 -0
  98. package/dist/mcp/first-party-tool-permissions.d.ts +3 -606
  99. package/dist/mcp/notification-tools.d.ts +26 -0
  100. package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
  101. package/dist/mcp/scheduled-task-input.d.ts +1309 -0
  102. package/dist/mcp/scheduled-task-view.d.ts +217 -3
  103. package/dist/mcp/secret-tools.d.ts +14 -0
  104. package/dist/mcp/server.d.ts +108 -5
  105. package/dist/mcp/session-admin-access-tools.d.ts +33 -0
  106. package/dist/mcp/session-event-errors.d.ts +28 -0
  107. package/dist/mcp/session-event-view.d.ts +62 -0
  108. package/dist/mcp/session-view.d.ts +15 -0
  109. package/dist/mcp/session-wait.d.ts +18 -0
  110. package/dist/mcp/site-agent-clamp-tools.d.ts +38 -0
  111. package/dist/mcp/site-data-tools.d.ts +22 -0
  112. package/dist/mcp/site-publication-tools.d.ts +19 -0
  113. package/dist/mcp/site-sql-tools.d.ts +27 -0
  114. package/dist/mcp-oauth.d.ts +37 -4
  115. package/dist/model-calls/chat-completions.d.ts +87 -0
  116. package/dist/model-calls/pending-usage-settlements.d.ts +57 -0
  117. package/dist/model-calls/service.d.ts +36 -0
  118. package/dist/model-catalog.d.ts +9 -3
  119. package/dist/native-push-dispatch.d.ts +69 -0
  120. package/dist/observability.d.ts +3 -1
  121. package/dist/organization-mcp.d.ts +82 -0
  122. package/dist/prepared-mcp-actor.d.ts +77 -0
  123. package/dist/prepared-mcp-permissions.d.ts +8 -0
  124. package/dist/routes/analytics-consent.d.ts +26 -0
  125. package/dist/routes/api-integrations.d.ts +11 -0
  126. package/dist/routes/api-keys.d.ts +7 -7
  127. package/dist/routes/automations.d.ts +2 -0
  128. package/dist/routes/billing.d.ts +59 -0
  129. package/dist/routes/browser-sessions.d.ts +65 -2
  130. package/dist/routes/chat-completions.d.ts +11 -0
  131. package/dist/routes/claude-core-usage.d.ts +20 -0
  132. package/dist/routes/claude-subscription-accounts.d.ts +3 -0
  133. package/dist/routes/claude-subscription-oauth.d.ts +3 -0
  134. package/dist/routes/client-errors.d.ts +182 -0
  135. package/dist/routes/codex-core.d.ts +401 -0
  136. package/dist/routes/codex.d.ts +64 -2
  137. package/dist/routes/computer-sessions.d.ts +6 -1
  138. package/dist/routes/desktop-distribution.d.ts +32 -0
  139. package/dist/routes/github-browser-fonts.gen.d.ts +2 -0
  140. package/dist/routes/github-browser-pages.d.ts +27 -0
  141. package/dist/routes/inbox.d.ts +13 -0
  142. package/dist/routes/insights-response-cache.d.ts +10 -0
  143. package/dist/routes/insights-usage.d.ts +12 -0
  144. package/dist/routes/insights.d.ts +28 -0
  145. package/dist/routes/interaction-placement-message.d.ts +7 -0
  146. package/dist/routes/managed-sign-in-methods.d.ts +6 -0
  147. package/dist/routes/model-account-choice.d.ts +13 -0
  148. package/dist/routes/model-account-settings.d.ts +19 -0
  149. package/dist/routes/native-app-auth.d.ts +12 -0
  150. package/dist/routes/organization-integration-policy.d.ts +8 -0
  151. package/dist/routes/organization-integrations.d.ts +6 -0
  152. package/dist/routes/organization-mcp-connections.d.ts +3 -0
  153. package/dist/routes/organization-model-defaults.d.ts +9 -0
  154. package/dist/routes/organization-service-accounts.d.ts +3 -0
  155. package/dist/routes/personal-api-keys.d.ts +3 -0
  156. package/dist/routes/session-admin-access.d.ts +3 -0
  157. package/dist/routes/session-artifact-associations.d.ts +4 -0
  158. package/dist/routes/session-history-imports.d.ts +20 -0
  159. package/dist/routes/sessions.d.ts +38 -2
  160. package/dist/routes/site-data.d.ts +18 -0
  161. package/dist/routes/site-publishing.d.ts +5 -0
  162. package/dist/routes/site-runtime.d.ts +31 -0
  163. package/dist/routes/site-sql.d.ts +16 -0
  164. package/dist/routes/slack-bot-access.d.ts +3 -0
  165. package/dist/routes/subscription-account-pools.d.ts +21 -0
  166. package/dist/routes/subscription-core-http.d.ts +5 -0
  167. package/dist/routes/subscription-pool-access.d.ts +37 -0
  168. package/dist/routes/subscription-pool-core.d.ts +153 -0
  169. package/dist/routes/supergrok.d.ts +6 -6
  170. package/dist/routes/usage-allowances.d.ts +12 -0
  171. package/dist/routes/variable-sets-removed.d.ts +2 -0
  172. package/dist/routes/vault-providers.d.ts +34 -0
  173. package/dist/routes/vaults.d.ts +3 -0
  174. package/dist/routes/workspace-integrations.d.ts +35 -0
  175. package/dist/routes/workspace-model-providers.d.ts +4 -0
  176. package/dist/routes/workspaces.d.ts +11 -2
  177. package/dist/sandbox/agent-update.d.ts +64 -0
  178. package/dist/sandbox/auth-callout.d.ts +8 -0
  179. package/dist/sandbox/channel-a.d.ts +15 -1
  180. package/dist/sandbox/enrollment.d.ts +26 -4
  181. package/dist/sandbox/machine-audience.d.ts +29 -0
  182. package/dist/sandbox/machines.d.ts +15 -2
  183. package/dist/sandbox/metrics-ingestion.d.ts +6 -2
  184. package/dist/sandbox/screen-control.d.ts +85 -0
  185. package/dist/sandbox/viewer.d.ts +5 -1
  186. package/dist/sandbox-file-artifacts.d.ts +17 -1
  187. package/dist/scheduled-task-blockers.d.ts +39 -0
  188. package/dist/scheduled-task-deletion.d.ts +3 -4
  189. package/dist/scheduled-task-lifecycle.d.ts +14 -0
  190. package/dist/secret-answers.d.ts +40 -0
  191. package/dist/session-create-observability.d.ts +5 -0
  192. package/dist/session-event-view-36GO3IL7.js +528 -0
  193. package/dist/session-event-view-36GO3IL7.js.map +1 -0
  194. package/dist/signed-state-secret.d.ts +18 -0
  195. package/dist/site-agent-guard.d.ts +53 -0
  196. package/dist/site-data/operations.d.ts +103 -0
  197. package/dist/site-data/service.d.ts +203 -0
  198. package/dist/site-frame-guard.d.ts +32 -0
  199. package/dist/site-publishing/agent-data-tools.d.ts +84 -0
  200. package/dist/site-publishing/agent-model.d.ts +58 -0
  201. package/dist/site-publishing/agent-session.d.ts +16 -0
  202. package/dist/site-publishing/content-scanner.d.ts +31 -0
  203. package/dist/site-publishing/edge-sync.d.ts +48 -0
  204. package/dist/site-publishing/gateway-signature.d.ts +56 -0
  205. package/dist/site-publishing/limits.d.ts +63 -0
  206. package/dist/site-publishing/page-tool-authority.d.ts +30 -0
  207. package/dist/site-publishing/platform-usage.d.ts +113 -0
  208. package/dist/site-publishing/platform.d.ts +21 -0
  209. package/dist/site-publishing/readiness.d.ts +62 -0
  210. package/dist/site-publishing/runtime.d.ts +179 -0
  211. package/dist/site-publishing/service.d.ts +264 -0
  212. package/dist/site-publishing/session-events.d.ts +22 -0
  213. package/dist/site-publishing/session-views.d.ts +36 -0
  214. package/dist/site-publishing/viewer.d.ts +40 -0
  215. package/dist/site-session-origin.d.ts +31 -6
  216. package/dist/site-sql/format.d.ts +47 -0
  217. package/dist/site-sql/gateway.d.ts +50 -0
  218. package/dist/site-sql/service.d.ts +213 -0
  219. package/dist/temporal-schedule-sync.d.ts +26 -0
  220. package/dist/transcription/billing-refusal.d.ts +8 -0
  221. package/dist/transcription/normalize.d.ts +23 -0
  222. package/dist/transcription/providers/azure-mai.d.ts +12 -0
  223. package/dist/transcription/providers/azure-openai.d.ts +4 -0
  224. package/dist/transcription/providers/openai.d.ts +16 -0
  225. package/dist/transcription/providers/subscription-core.d.ts +39 -0
  226. package/dist/transcription/service.d.ts +10 -1
  227. package/dist/transcription/wav-duration.d.ts +8 -0
  228. package/dist/workspace-tool-gateway-attestations.d.ts +37 -0
  229. package/dist/workspace-tool-gateway-observability.d.ts +16 -0
  230. package/dist/workspace-tool-gateway-secrets.d.ts +27 -0
  231. package/dist/workspace-tool-gateway.d.ts +102 -6
  232. package/dist/workspace-tool-target-fence.d.ts +116 -0
  233. package/dist/workspace-tool-target.d.ts +225 -0
  234. package/dist/workspace-webhook-dispatch.d.ts +26 -0
  235. package/dist/xai-subscription-core.d.ts +60 -0
  236. package/package.json +25 -20
  237. package/src/access-grant-rls.ts +64 -14
  238. package/src/admission-trace.ts +14 -0
  239. package/src/app.ts +1684 -252
  240. package/src/artifact-catalog-cursor.ts +1 -0
  241. package/src/attached-browser-viewer.ts +26 -0
  242. package/src/auth/managed-auth-attempt-context.ts +9 -0
  243. package/src/auth/managed-auth-rate-limits.ts +252 -0
  244. package/src/auth/managed-auth-session-adapter.ts +64 -29
  245. package/src/auth/managed-auth.ts +303 -35
  246. package/src/auth/managed-email.ts +18 -1
  247. package/src/auth/managed-sign-in-notifications.ts +81 -0
  248. package/src/auth/new-signups-gate.ts +49 -0
  249. package/src/auth/organization-user-setup.ts +3 -3
  250. package/src/auth/signup-funnel-metrics.ts +164 -0
  251. package/src/azure-live.ts +103 -0
  252. package/src/browser-action-fences.ts +45 -0
  253. package/src/browser-controller-authority.ts +1 -186
  254. package/src/browser-ephemeral.ts +39 -0
  255. package/src/browser-lost-runtime-end.ts +71 -0
  256. package/src/browser-state-authority.ts +1 -236
  257. package/src/claude-default-models.ts +37 -0
  258. package/src/claude-subscription-core.ts +154 -0
  259. package/src/claude-subscription-oauth.ts +352 -0
  260. package/src/claude-subscription-profile.ts +73 -0
  261. package/src/claude-subscription-usage.ts +51 -0
  262. package/src/claude-workspace-connection.ts +82 -0
  263. package/src/codemode.ts +236 -39
  264. package/src/codex-realtime.ts +181 -53
  265. package/src/codex-session-pointers.ts +80 -0
  266. package/src/company-brain-okf.ts +1 -1
  267. package/src/connected-machine-computer-access.ts +2 -1
  268. package/src/connection-ownership.ts +19 -13
  269. package/src/controller-data-plane.ts +34 -0
  270. package/src/credit-promotion-snapshot.ts +36 -0
  271. package/src/editable-artifact-production.ts +10 -0
  272. package/src/editable-artifact-source-session.ts +123 -0
  273. package/src/editable-artifact-websocket.ts +16 -3
  274. package/src/fatal-process-boundary.ts +67 -3
  275. package/src/gateway-realtime.ts +12 -8
  276. package/src/github-access.ts +31 -5
  277. package/src/github-browser-flow.ts +1 -1
  278. package/src/http/acting-person.ts +105 -0
  279. package/src/http/api-contract-compat.ts +49 -0
  280. package/src/http/api-error.ts +210 -2
  281. package/src/http/auth.ts +68 -4
  282. package/src/http/cors.ts +37 -5
  283. package/src/http/deprecation.ts +118 -0
  284. package/src/http/keyed-admission.ts +29 -0
  285. package/src/http/local-browser-boundary.ts +343 -0
  286. package/src/http/metrics-listener.ts +57 -0
  287. package/src/http/path-identifier.ts +54 -0
  288. package/src/http/registered-route-label.ts +34 -0
  289. package/src/http/rejection-telemetry.ts +120 -0
  290. package/src/http/request-body.ts +127 -0
  291. package/src/http/request-source.ts +154 -13
  292. package/src/http/sse.ts +88 -28
  293. package/src/http/unmatched-route.ts +60 -0
  294. package/src/http/user-content.ts +158 -0
  295. package/src/http/variable-sets-removed.ts +122 -0
  296. package/src/http/websocket-upgrade-dispatch.ts +29 -0
  297. package/src/index.ts +107 -57
  298. package/src/integration-connect-metrics.ts +228 -0
  299. package/src/integration-endpoint-test.ts +291 -0
  300. package/src/integrations/api-integrations.ts +81 -7
  301. package/src/integrations/atlassian.ts +202 -83
  302. package/src/integrations/fiken.ts +66 -38
  303. package/src/integrations/github-app-connect.ts +64 -18
  304. package/src/integrations/github-lens-connect.ts +8 -29
  305. package/src/integrations/google-drive.ts +448 -152
  306. package/src/integrations/integration-commit-authority.ts +69 -0
  307. package/src/integrations/marketplace-plugin.ts +1 -1
  308. package/src/integrations/oauth-client.ts +733 -193
  309. package/src/integrations/oauth-profiles.ts +116 -45
  310. package/src/integrations/onepassword-vault-provider.ts +16 -0
  311. package/src/integrations/personal-github-repositories.ts +1 -1
  312. package/src/integrations/personal-github.ts +61 -35
  313. package/src/integrations/provider-oauth.ts +67 -85
  314. package/src/integrations/slack-app-home.ts +5 -5
  315. package/src/integrations/slack-bot.ts +893 -201
  316. package/src/integrations/slack-file-upload-flow.ts +147 -0
  317. package/src/integrations/slack-install.ts +7 -7
  318. package/src/integrations/slack-interactions.ts +1589 -299
  319. package/src/integrations/slack-mrkdwn.ts +193 -0
  320. package/src/integrations/slack-routing.ts +2 -2
  321. package/src/integrations/slack-session-defaults.ts +224 -0
  322. package/src/integrations/slack-task-file-upload.ts +323 -0
  323. package/src/integrations/slack-tool-review.ts +65 -0
  324. package/src/integrations/social-oauth.ts +90 -58
  325. package/src/interaction-agent-access.ts +40 -20
  326. package/src/interaction-agent-version.ts +85 -0
  327. package/src/interaction-holder-heartbeat.ts +24 -8
  328. package/src/interaction-metrics.ts +164 -2
  329. package/src/interaction-route-stages.ts +94 -0
  330. package/src/interaction-secrets-vault.ts +213 -0
  331. package/src/interaction-secrets.ts +426 -0
  332. package/src/mcp/action-catalog-types.ts +14 -0
  333. package/src/mcp/action-catalog.gen.ts +8014 -0
  334. package/src/mcp/action-descriptions.ts +299 -0
  335. package/src/mcp/action-schema-imports.gen.ts +304 -0
  336. package/src/mcp/capability-account-readiness.ts +17 -0
  337. package/src/mcp/child-read-evidence.ts +19 -0
  338. package/src/mcp/company-profile-agent-admin.ts +13 -0
  339. package/src/mcp/contract-input.ts +165 -0
  340. package/src/mcp/documents.ts +9 -2
  341. package/src/mcp/editable-artifacts.ts +29 -11
  342. package/src/mcp/files.ts +5 -1
  343. package/src/mcp/first-party-tool-permissions.ts +7 -285
  344. package/src/mcp/knowledge-entries.ts +108 -34
  345. package/src/mcp/notification-tools.ts +480 -0
  346. package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
  347. package/src/mcp/scheduled-task-input.ts +89 -0
  348. package/src/mcp/scheduled-task-view.ts +63 -3
  349. package/src/mcp/secret-tools.ts +185 -0
  350. package/src/mcp/server.ts +2213 -1116
  351. package/src/mcp/session-admin-access-tools.ts +163 -0
  352. package/src/mcp/session-event-errors.ts +123 -0
  353. package/src/mcp/session-event-view.ts +395 -13
  354. package/src/mcp/session-view.ts +3 -0
  355. package/src/mcp/session-wait.ts +67 -7
  356. package/src/mcp/site-agent-clamp-tools.ts +140 -0
  357. package/src/mcp/site-data-tools.ts +339 -0
  358. package/src/mcp/site-publication-tools.ts +201 -0
  359. package/src/mcp/site-sql-tools.ts +427 -0
  360. package/src/mcp-oauth.ts +635 -45
  361. package/src/model-calls/chat-completions.ts +352 -0
  362. package/src/model-calls/pending-usage-settlements.ts +125 -0
  363. package/src/model-calls/service.ts +694 -0
  364. package/src/model-catalog.ts +68 -17
  365. package/src/native-push-dispatch.ts +457 -0
  366. package/src/observability.ts +15 -1
  367. package/src/organization-mcp.ts +485 -0
  368. package/src/prepared-mcp-actor.ts +154 -0
  369. package/src/prepared-mcp-permissions.ts +38 -0
  370. package/src/routes/analytics-consent.ts +123 -0
  371. package/src/routes/api-integrations.ts +268 -9
  372. package/src/routes/api-keys.ts +164 -25
  373. package/src/routes/artifact-catalog.ts +111 -0
  374. package/src/routes/automations.ts +163 -90
  375. package/src/routes/billing.ts +535 -59
  376. package/src/routes/browser-sessions.ts +966 -342
  377. package/src/routes/canonical-human-identities.ts +61 -0
  378. package/src/routes/capabilities.ts +112 -5
  379. package/src/routes/channels.ts +4 -3
  380. package/src/routes/chat-completions.ts +235 -0
  381. package/src/routes/claude-core-usage.ts +147 -0
  382. package/src/routes/claude-subscription-accounts.ts +233 -0
  383. package/src/routes/claude-subscription-oauth.ts +175 -0
  384. package/src/routes/client-errors.ts +394 -0
  385. package/src/routes/codex-core.ts +687 -0
  386. package/src/routes/codex.ts +1277 -1119
  387. package/src/routes/company-brain.ts +4 -0
  388. package/src/routes/computer-sessions.ts +319 -85
  389. package/src/routes/connect.ts +277 -175
  390. package/src/routes/connections.ts +690 -363
  391. package/src/routes/desktop-distribution.ts +217 -0
  392. package/src/routes/documents.ts +13 -7
  393. package/src/routes/editable-artifacts.ts +74 -4
  394. package/src/routes/enrollments.ts +110 -16
  395. package/src/routes/external-identity-links.ts +13 -12
  396. package/src/routes/files.ts +41 -16
  397. package/src/routes/github-browser-fonts.gen.ts +12 -0
  398. package/src/routes/github-browser-pages.ts +258 -0
  399. package/src/routes/github.ts +200 -75
  400. package/src/routes/inbox.ts +353 -0
  401. package/src/routes/insights-response-cache.ts +83 -0
  402. package/src/routes/insights-usage.ts +345 -0
  403. package/src/routes/insights.ts +103 -8
  404. package/src/routes/install.ts +51 -10
  405. package/src/routes/integration-facets.ts +70 -28
  406. package/src/routes/interaction-placement-message.ts +12 -0
  407. package/src/routes/knowledge.ts +136 -27
  408. package/src/routes/machines.ts +189 -135
  409. package/src/routes/managed-auth-session-sets.ts +43 -10
  410. package/src/routes/managed-onboarding.ts +39 -19
  411. package/src/routes/managed-sign-in-methods.ts +433 -0
  412. package/src/routes/memory-slack-publications.ts +3 -2
  413. package/src/routes/model-account-choice.ts +194 -0
  414. package/src/routes/model-account-settings.ts +235 -0
  415. package/src/routes/model-connection-access.ts +210 -48
  416. package/src/routes/native-app-auth.ts +296 -0
  417. package/src/routes/organization-integration-policy.ts +116 -0
  418. package/src/routes/organization-integrations.ts +326 -0
  419. package/src/routes/organization-mcp-connections.ts +183 -0
  420. package/src/routes/organization-memberships.ts +205 -19
  421. package/src/routes/organization-model-defaults.ts +110 -0
  422. package/src/routes/organization-model-providers.ts +74 -3
  423. package/src/routes/organization-service-accounts.ts +128 -0
  424. package/src/routes/organization-sessions.ts +21 -5
  425. package/src/routes/personal-api-keys.ts +184 -0
  426. package/src/routes/personal-github-git-broker.ts +2 -2
  427. package/src/routes/personal-github.ts +9 -4
  428. package/src/routes/plugins.ts +46 -7
  429. package/src/routes/pr-review-github.ts +105 -118
  430. package/src/routes/pr-review.ts +88 -82
  431. package/src/routes/preference-registry.ts +18 -0
  432. package/src/routes/rigs.ts +48 -13
  433. package/src/routes/scheduled-tasks.ts +347 -27
  434. package/src/routes/session-admin-access.ts +271 -0
  435. package/src/routes/session-artifact-associations.ts +164 -0
  436. package/src/routes/session-history-imports.ts +305 -0
  437. package/src/routes/sessions.ts +1682 -363
  438. package/src/routes/site-data.ts +340 -0
  439. package/src/routes/site-publishing.ts +584 -0
  440. package/src/routes/site-runtime.ts +1944 -0
  441. package/src/routes/site-sql.ts +263 -0
  442. package/src/routes/skill-content.ts +72 -7
  443. package/src/routes/skills.ts +5 -4
  444. package/src/routes/slack-bot-access.ts +108 -0
  445. package/src/routes/social.ts +27 -15
  446. package/src/routes/subscription-account-pools.ts +209 -0
  447. package/src/routes/subscription-core-http.ts +18 -0
  448. package/src/routes/subscription-pool-access.ts +180 -0
  449. package/src/routes/subscription-pool-core.ts +552 -0
  450. package/src/routes/supergrok.ts +174 -655
  451. package/src/routes/transcription-recordings.ts +71 -4
  452. package/src/routes/transcriptions.ts +26 -2
  453. package/src/routes/usage-allowances.ts +381 -0
  454. package/src/routes/variable-sets-removed.ts +19 -0
  455. package/src/routes/vault-providers.ts +782 -0
  456. package/src/routes/vaults.ts +421 -0
  457. package/src/routes/video-generation.ts +30 -12
  458. package/src/routes/workspace-artifacts.ts +165 -53
  459. package/src/routes/workspace-integrations.ts +576 -0
  460. package/src/routes/workspace-model-providers.ts +148 -0
  461. package/src/routes/workspace-state.ts +4 -0
  462. package/src/routes/workspaces.ts +625 -117
  463. package/src/sandbox/agent-update.ts +315 -0
  464. package/src/sandbox/auth-callout.ts +104 -21
  465. package/src/sandbox/channel-a.ts +150 -49
  466. package/src/sandbox/enrollment.ts +131 -22
  467. package/src/sandbox/machine-audience.ts +192 -0
  468. package/src/sandbox/machines.ts +75 -31
  469. package/src/sandbox/metrics-ingestion.ts +133 -2
  470. package/src/sandbox/rematerialize.ts +51 -21
  471. package/src/sandbox/screen-control.ts +289 -0
  472. package/src/sandbox/viewer.ts +33 -58
  473. package/src/sandbox-file-artifacts.ts +53 -27
  474. package/src/scheduled-task-blockers.ts +293 -0
  475. package/src/scheduled-task-deletion.ts +13 -3
  476. package/src/scheduled-task-lifecycle.ts +84 -0
  477. package/src/secret-answers.ts +119 -0
  478. package/src/session-create-observability.ts +46 -0
  479. package/src/session-realtime-context.ts +26 -4
  480. package/src/signed-state-secret.ts +58 -0
  481. package/src/site-agent-guard.ts +261 -0
  482. package/src/site-data/operations.ts +777 -0
  483. package/src/site-data/service.ts +1043 -0
  484. package/src/site-frame-guard.ts +107 -0
  485. package/src/site-publishing/agent-data-tools.ts +250 -0
  486. package/src/site-publishing/agent-model.ts +127 -0
  487. package/src/site-publishing/agent-session.ts +148 -0
  488. package/src/site-publishing/content-scanner.ts +93 -0
  489. package/src/site-publishing/edge-sync.ts +148 -0
  490. package/src/site-publishing/gateway-signature.ts +198 -0
  491. package/src/site-publishing/limits.ts +315 -0
  492. package/src/site-publishing/page-tool-authority.ts +111 -0
  493. package/src/site-publishing/platform-usage.ts +479 -0
  494. package/src/site-publishing/platform.ts +98 -0
  495. package/src/site-publishing/readiness.ts +330 -0
  496. package/src/site-publishing/runtime.ts +831 -0
  497. package/src/site-publishing/service.ts +1282 -0
  498. package/src/site-publishing/session-events.ts +262 -0
  499. package/src/site-publishing/session-views.ts +262 -0
  500. package/src/site-publishing/viewer.ts +75 -0
  501. package/src/site-session-origin.ts +91 -6
  502. package/src/site-sql/format.ts +134 -0
  503. package/src/site-sql/gateway.ts +168 -0
  504. package/src/site-sql/service.ts +1636 -0
  505. package/src/site-uploads.ts +27 -5
  506. package/src/temporal-schedule-sync.ts +74 -0
  507. package/src/transcription/billing-refusal.ts +14 -0
  508. package/src/transcription/normalize.ts +77 -0
  509. package/src/transcription/providers/azure-mai.ts +98 -0
  510. package/src/transcription/providers/azure-openai.ts +16 -7
  511. package/src/transcription/providers/codex-subscription.ts +190 -67
  512. package/src/transcription/providers/openai.ts +79 -5
  513. package/src/transcription/providers/subscription-core.ts +125 -0
  514. package/src/transcription/providers/xai-subscription.ts +81 -83
  515. package/src/transcription/segmenter.ts +7 -1
  516. package/src/transcription/service.ts +239 -10
  517. package/src/transcription/wav-duration.ts +39 -0
  518. package/src/workspace-deletion.ts +25 -1
  519. package/src/workspace-tool-gateway-attestations.ts +133 -0
  520. package/src/workspace-tool-gateway-observability.ts +64 -0
  521. package/src/workspace-tool-gateway-secrets.ts +104 -0
  522. package/src/workspace-tool-gateway.ts +921 -103
  523. package/src/workspace-tool-target-fence.ts +380 -0
  524. package/src/workspace-tool-target.ts +554 -0
  525. package/src/workspace-webhook-dispatch.ts +225 -0
  526. package/src/xai-realtime.ts +85 -81
  527. package/src/xai-subscription-core.ts +172 -0
  528. package/dist/browser-auth-broker.d.ts +0 -20
  529. package/dist/chunk-AJ62T5QN.js.map +0 -1
  530. package/dist/connection-authority-owner.d.ts +0 -59
  531. package/dist/routes/connection-authorities.d.ts +0 -3
  532. package/dist/routes/environments.d.ts +0 -5
  533. package/dist/routes/host-mcp-bindings.d.ts +0 -5
  534. package/dist/routes/host-mcp-resolvers.d.ts +0 -3
  535. package/dist/routes/packs.d.ts +0 -3
  536. package/dist/session-event-view-MU3HMNV3.js +0 -264
  537. package/dist/session-event-view-MU3HMNV3.js.map +0 -1
  538. package/dist/xai-subscription-auth.d.ts +0 -23
  539. package/src/browser-auth-broker.ts +0 -155
  540. package/src/connection-authority-owner.ts +0 -61
  541. package/src/routes/connection-authorities.ts +0 -139
  542. package/src/routes/environments.ts +0 -388
  543. package/src/routes/host-mcp-bindings.ts +0 -122
  544. package/src/routes/host-mcp-resolvers.ts +0 -41
  545. package/src/routes/packs.ts +0 -784
  546. package/src/xai-subscription-auth.ts +0 -139
@@ -0,0 +1,485 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import {
3
+ CallToolRequestSchema,
4
+ ListToolsRequestSchema,
5
+ type CallToolResult,
6
+ type Icon,
7
+ } from "@modelcontextprotocol/sdk/types.js";
8
+ import {
9
+ isReadOnlyPermissionSet,
10
+ OPENGENI_API_CONTRACT_HEADER,
11
+ OPENGENI_API_CONTRACT_REVISION,
12
+ type OrganizationAccessPolicy,
13
+ } from "@opengeni/contracts";
14
+ import { stampDelegatedHumanAuthorization } from "@opengeni/core";
15
+ import { z } from "zod";
16
+
17
+ import type { ActionCatalogEntry } from "./mcp/action-catalog-types";
18
+ import { ACTION_CATALOG } from "./mcp/action-catalog.gen";
19
+ import { ACTION_REQUEST_SCHEMAS } from "./mcp/action-schema-imports.gen";
20
+ import { actionDescription } from "./mcp/action-descriptions";
21
+
22
+ /* ----------------------------------------------------------------------------
23
+ The organization MCP server (`/v1/mcp`).
24
+
25
+ Every public API action is reachable through three tools: find an action,
26
+ describe it, run it. A call runs the real route in this process as the
27
+ caller, so the route's own permission checks decide, exactly as for the
28
+ app:
29
+
30
+ - a person who signed in (MCP OAuth): the request carries the verified
31
+ person proof, re-resolving their live access and capping it by the
32
+ connection's access setting on every call;
33
+ - an organization API key: the request carries that key.
34
+
35
+ The proof lives on the exact Request object in process memory; nothing a
36
+ client sends can create it.
37
+ -------------------------------------------------------------------------- */
38
+
39
+ export type OrganizationMcpCaller =
40
+ | {
41
+ kind: "person";
42
+ accountId: string;
43
+ subjectId: string;
44
+ access: OrganizationAccessPolicy;
45
+ }
46
+ | { kind: "key"; authorization: string; accessKey: string | null };
47
+
48
+ /**
49
+ * Requests that only read but are sent as POST (a search query or a file path
50
+ * in the body). Read only connections may run them; each route still checks
51
+ * its own read permission.
52
+ */
53
+ export const READ_ONLY_POST_ACTIONS: ReadonlySet<string> = new Set([
54
+ "/v1/workspaces/:workspaceId/knowledge/search",
55
+ "/v1/workspaces/:workspaceId/knowledge/entries/search",
56
+ "/v1/workspaces/:workspaceId/document-bases/:baseId/search",
57
+ "/v1/workspaces/:workspaceId/sessions/:sessionId/fs/read",
58
+ "/v1/workspaces/:workspaceId/sessions/:sessionId/git/diff",
59
+ "/v1/workspaces/:workspaceId/integrations/preview",
60
+ "/v1/workspaces/:workspaceId/plugins/preview",
61
+ "/v1/workspaces/:workspaceId/skills/preview",
62
+ "/v1/organizations/:organizationId/external-identities/lookup",
63
+ ]);
64
+
65
+ const MAX_RESPONSE_BYTES = 256 * 1024;
66
+ const STREAM_READ_MS = 2_000;
67
+
68
+ export const OrganizationActionSearchInput = z
69
+ .object({
70
+ query: z.string().max(200).default(""),
71
+ limit: z.number().int().min(1).max(50).default(20),
72
+ offset: z.number().int().min(0).default(0),
73
+ })
74
+ .strict();
75
+ export const OrganizationActionDescribeInput = z
76
+ .object({ id: z.string().min(1).max(300) })
77
+ .strict();
78
+ export const OrganizationActionCallInput = z
79
+ .object({
80
+ id: z.string().min(1).max(300),
81
+ pathParameters: z.record(z.string(), z.string().min(1).max(1024)).default({}),
82
+ query: z
83
+ .record(
84
+ z.string(),
85
+ z.union([z.string(), z.number(), z.boolean(), z.array(z.union([z.string(), z.number()]))]),
86
+ )
87
+ .default({}),
88
+ body: z.unknown().optional(),
89
+ })
90
+ .strict();
91
+ const SearchInput = OrganizationActionSearchInput;
92
+ const DescribeInput = OrganizationActionDescribeInput;
93
+ const CallInput = OrganizationActionCallInput;
94
+
95
+ const TOOLS = [
96
+ {
97
+ name: "opengeni_actions_search",
98
+ title: "Find Opengeni actions",
99
+ description:
100
+ "Search every action available in Opengeni: sessions and chats, workspaces, people, knowledge, files, schedules, connections, models, keys, billing and settings. Returns action ids to describe and call. An empty query lists everything, page by page.",
101
+ inputSchema: z.toJSONSchema(SearchInput, { io: "input" }),
102
+ annotations: { readOnlyHint: true },
103
+ },
104
+ {
105
+ name: "opengeni_action_describe",
106
+ title: "Describe an Opengeni action",
107
+ description:
108
+ "Show an action's method, path, path parameters and the JSON schema of its input, so it can be called correctly.",
109
+ inputSchema: z.toJSONSchema(DescribeInput, { io: "input" }),
110
+ annotations: { readOnlyHint: true },
111
+ },
112
+ {
113
+ name: "opengeni_action_call",
114
+ title: "Run an Opengeni action",
115
+ description:
116
+ "Run one Opengeni action as this connection, with exactly the access it was given. Pass path parameters (for example workspaceId), query parameters and a JSON body. Returns the HTTP status and response.",
117
+ inputSchema: z.toJSONSchema(CallInput, { io: "input" }),
118
+ annotations: { readOnlyHint: false, openWorldHint: false },
119
+ },
120
+ ] as const;
121
+
122
+ /** The brand mark from `apps/web/public/favicon.svg`. */
123
+ const BRAND_MARK_PATH =
124
+ "M251 83.5966L207 109L163 83.5966L119 109L75 83.5966L141 45.4915A44 44 0 0 1 185 45.4915ZM185.25 172.3642A44.5 44.5 0 0 1 140.75 172.3642L75 134.4034L119 109L163 134.4034L207 109L251 134.4034Z";
125
+
126
+ function brandMarkSvgDataUri(fill: string): string {
127
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="71 17 184 184" width="184" height="184"><path fill="${fill}" d="${BRAND_MARK_PATH}"/></svg>`;
128
+ return `data:image/svg+xml;base64,${Buffer.from(svg).toString("base64")}`;
129
+ }
130
+
131
+ /**
132
+ * MCP `serverInfo.icons` (spec 2025-11-25). Self-contained data URIs work for
133
+ * every deployment; the web app's PNG is added when its public origin is known.
134
+ */
135
+ export function organizationMcpIcons(publicOrigin: string | null): Icon[] {
136
+ const icons: Icon[] = [
137
+ {
138
+ src: brandMarkSvgDataUri("#111111"),
139
+ mimeType: "image/svg+xml",
140
+ sizes: ["any"],
141
+ theme: "light",
142
+ },
143
+ {
144
+ src: brandMarkSvgDataUri("#FFFFFF"),
145
+ mimeType: "image/svg+xml",
146
+ sizes: ["any"],
147
+ theme: "dark",
148
+ },
149
+ ];
150
+ if (publicOrigin) {
151
+ icons.push({
152
+ src: new URL("/icon-512.png", publicOrigin).href,
153
+ mimeType: "image/png",
154
+ sizes: ["512x512"],
155
+ theme: "light",
156
+ });
157
+ }
158
+ return icons;
159
+ }
160
+
161
+ export type OrganizationActionContext = {
162
+ caller: OrganizationMcpCaller;
163
+ /** This API's own origin; the call never leaves the process. */
164
+ origin: string;
165
+ /** The web app's public origin, when configured; serves the PNG icon. */
166
+ publicOrigin?: string | null;
167
+ dispatch: (request: Request) => Promise<Response>;
168
+ signal?: AbortSignal;
169
+ };
170
+
171
+ export function buildOrganizationMcpServer(input: OrganizationActionContext): Server {
172
+ const server = new Server(
173
+ {
174
+ name: "opengeni",
175
+ title: "Opengeni",
176
+ version: "1.0.0",
177
+ websiteUrl: "https://opengeni.ai",
178
+ icons: organizationMcpIcons(input.publicOrigin ?? null),
179
+ },
180
+ {
181
+ capabilities: { tools: {} },
182
+ instructions:
183
+ "Opengeni actions: use opengeni_actions_search to find what you need, opengeni_action_describe for its inputs, then opengeni_action_call. Most actions take a workspaceId path parameter; list workspaces first (search 'workspaces').",
184
+ },
185
+ );
186
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
187
+ tools: TOOLS.map((tool) => ({ ...tool, inputSchema: tool.inputSchema as never })),
188
+ }));
189
+ server.setRequestHandler(CallToolRequestSchema, async (request): Promise<CallToolResult> => {
190
+ const args = request.params.arguments ?? {};
191
+ switch (request.params.name) {
192
+ case "opengeni_actions_search": {
193
+ const parsed = SearchInput.safeParse(args);
194
+ if (!parsed.success) return invalid(parsed.error);
195
+ return json(searchActions(parsed.data));
196
+ }
197
+ case "opengeni_action_describe": {
198
+ const parsed = DescribeInput.safeParse(args);
199
+ if (!parsed.success) return invalid(parsed.error);
200
+ return describeActionResult(parsed.data.id);
201
+ }
202
+ case "opengeni_action_call": {
203
+ const parsed = CallInput.safeParse(args);
204
+ if (!parsed.success) return invalid(parsed.error);
205
+ return await callOrganizationAction(input, parsed.data);
206
+ }
207
+ default:
208
+ return failure(`Unknown tool ${request.params.name}.`);
209
+ }
210
+ });
211
+ return server;
212
+ }
213
+
214
+ export function findAction(id: string): ActionCatalogEntry | undefined {
215
+ const trimmed = id.trim();
216
+ return ACTION_CATALOG.find(
217
+ (entry) => entry.id === trimmed || `${entry.method} ${entry.path}` === trimmed,
218
+ );
219
+ }
220
+
221
+ function words(value: string): string[] {
222
+ return value
223
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
224
+ .toLowerCase()
225
+ .split(/[^a-z0-9]+/u)
226
+ .filter(Boolean);
227
+ }
228
+
229
+ /** Actions an MCP caller can complete: browser-only ones are left out. */
230
+ const CALLABLE_ACTIONS = ACTION_CATALOG.filter((entry) => !entry.browserOnly);
231
+ const DESCRIPTIONS = new Map(
232
+ CALLABLE_ACTIONS.map((entry) => [entry.id, actionDescription(entry)] as const),
233
+ );
234
+
235
+ export function searchActions(input: { query: string; limit: number; offset: number }) {
236
+ // Singular and plural match ("workspace" finds listWorkspaces).
237
+ const stem = (word: string) =>
238
+ word.endsWith("ies") ? `${word.slice(0, -3)}y` : word.replace(/(?<!s)s$/u, "");
239
+ const wanted = words(input.query).map(stem);
240
+ // "workspaces" asks for a list; prefer list actions on a plural query.
241
+ const plural = words(input.query).some((word) => /[^s]s$/u.test(word));
242
+ const scored = CALLABLE_ACTIONS.map((entry) => {
243
+ // A word in the action's name matters far more than one in its path:
244
+ // nearly every path contains "workspaces".
245
+ const name = words(entry.id).map(stem);
246
+ const path = [...words(entry.path.replace(/:\w+/g, "")), entry.method.toLowerCase()].map(stem);
247
+ // A described action also matches the words people use for it
248
+ // ("pause", "primary", "reset"), below a name match.
249
+ const described = words(DESCRIPTIONS.get(entry.id) ?? "").map(stem);
250
+ const score = wanted.reduce(
251
+ (total, word) =>
252
+ total +
253
+ (name.includes(word)
254
+ ? 4
255
+ : name.some((token) => token.startsWith(word))
256
+ ? 3
257
+ : path.includes(word)
258
+ ? 1
259
+ : path.some((token) => token.startsWith(word))
260
+ ? 0.5
261
+ : described.includes(word)
262
+ ? 0.5
263
+ : 0),
264
+ 0,
265
+ );
266
+ return {
267
+ entry,
268
+ score: score + (plural && score > 0 && name[0] === "list" ? 0.5 : 0),
269
+ size: name.length,
270
+ };
271
+ }).filter((candidate) => wanted.length === 0 || candidate.score > 0);
272
+ scored.sort(
273
+ (left, right) =>
274
+ right.score - left.score ||
275
+ left.size - right.size ||
276
+ // On a tie, reads come before writes.
277
+ Number(left.entry.method !== "GET") - Number(right.entry.method !== "GET") ||
278
+ left.entry.id.localeCompare(right.entry.id),
279
+ );
280
+ return {
281
+ total: scored.length,
282
+ offset: input.offset,
283
+ actions: scored.slice(input.offset, input.offset + input.limit).map(({ entry }) => {
284
+ const description = DESCRIPTIONS.get(entry.id);
285
+ return {
286
+ id: entry.id,
287
+ method: entry.method,
288
+ path: entry.path,
289
+ ...(description ? { description } : {}),
290
+ };
291
+ }),
292
+ };
293
+ }
294
+
295
+ function pathParameters(path: string): string[] {
296
+ return [...path.matchAll(/:(\w+)/g)].map((match) => match[1]!);
297
+ }
298
+
299
+ function schemaFor(name: string): unknown {
300
+ const candidate = ACTION_REQUEST_SCHEMAS[name];
301
+ if (!(candidate instanceof z.ZodType)) return null;
302
+ try {
303
+ return z.toJSONSchema(candidate, { io: "input", unrepresentable: "any" });
304
+ } catch {
305
+ return null;
306
+ }
307
+ }
308
+
309
+ /** The describe tool's answer for an action id, or why it can't be used. */
310
+ export function describeActionResult(id: string): CallToolResult {
311
+ const entry = findAction(id);
312
+ if (!entry) return failure(`No action "${id}". Search for it first.`);
313
+ if (entry.browserOnly) return browserOnly(entry);
314
+ return json(describeAction(entry));
315
+ }
316
+
317
+ export function describeAction(entry: ActionCatalogEntry) {
318
+ const reads = entry.method === "GET" || entry.method === "HEAD";
319
+ const description = actionDescription(entry);
320
+ return {
321
+ id: entry.id,
322
+ method: entry.method,
323
+ path: entry.path,
324
+ ...(description ? { description } : {}),
325
+ pathParameters: pathParameters(entry.path),
326
+ input: entry.request.map((name) => ({
327
+ name,
328
+ in: reads ? "query" : "body",
329
+ schema: schemaFor(name),
330
+ })),
331
+ response: entry.response,
332
+ };
333
+ }
334
+
335
+ /** Run one public action in process as the caller; the route's own checks decide. */
336
+ export async function callOrganizationAction(
337
+ context: OrganizationActionContext,
338
+ input: z.infer<typeof OrganizationActionCallInput>,
339
+ ): Promise<CallToolResult> {
340
+ const entry = findAction(input.id);
341
+ if (!entry) return failure(`No action "${input.id}". Search for it first.`);
342
+ if (entry.browserOnly) return browserOnly(entry);
343
+ const reads = entry.method === "GET" || entry.method === "HEAD";
344
+ if (
345
+ context.caller.kind === "person" &&
346
+ !reads &&
347
+ !READ_ONLY_POST_ACTIONS.has(entry.path) &&
348
+ isReadOnlyPermissionSet(context.caller.access.permissions)
349
+ ) {
350
+ return failure("This connection is read only, so it can't change anything.");
351
+ }
352
+ let path = entry.path;
353
+ for (const name of pathParameters(entry.path)) {
354
+ const value = input.pathParameters[name];
355
+ if (!value) return failure(`Missing path parameter ${name}.`);
356
+ // Encoding leaves "." alone, so a dot segment would reach another route.
357
+ if (value === "." || value === "..") return failure(`Invalid path parameter ${name}.`);
358
+ path = path.replace(`:${name}`, encodeURIComponent(value));
359
+ }
360
+ const url = new URL(path, context.origin);
361
+ if (url.pathname !== path) return failure("Invalid path parameters.");
362
+ for (const [key, value] of Object.entries(input.query)) {
363
+ for (const each of Array.isArray(value) ? value : [value])
364
+ url.searchParams.append(key, String(each));
365
+ }
366
+ const headers = new Headers({
367
+ accept: "application/json",
368
+ [OPENGENI_API_CONTRACT_HEADER]: OPENGENI_API_CONTRACT_REVISION,
369
+ });
370
+ if (context.caller.kind === "key") {
371
+ headers.set("authorization", context.caller.authorization);
372
+ if (context.caller.accessKey) headers.set("x-opengeni-access-key", context.caller.accessKey);
373
+ }
374
+ const body = reads ? undefined : JSON.stringify(input.body ?? {});
375
+ if (body !== undefined) {
376
+ headers.set("content-type", "application/json");
377
+ // Exact length: the body-limit middleware otherwise rebuilds the Request,
378
+ // and the person proof lives on this exact object.
379
+ headers.set("content-length", String(Buffer.byteLength(body)));
380
+ }
381
+ const request = new Request(url, {
382
+ method: entry.method,
383
+ headers,
384
+ ...(body !== undefined ? { body } : {}),
385
+ ...(context.signal ? { signal: context.signal } : {}),
386
+ redirect: "manual",
387
+ });
388
+ if (context.caller.kind === "person") {
389
+ stampDelegatedHumanAuthorization(request, {
390
+ organizationId: context.caller.accountId,
391
+ subjectId: context.caller.subjectId,
392
+ permissions: context.caller.access.permissions,
393
+ workspaceScope: context.caller.access.workspaceScope,
394
+ });
395
+ }
396
+ const response = await context.dispatch(request);
397
+ return await toolResult(response);
398
+ }
399
+
400
+ async function toolResult(response: Response): Promise<CallToolResult> {
401
+ const status = response.status;
402
+ const location = response.headers.get("location");
403
+ if (status >= 300 && status < 400 && location) {
404
+ await response.body?.cancel();
405
+ return json({
406
+ status,
407
+ openInBrowser: location,
408
+ hint: "Open this link in a browser to finish.",
409
+ });
410
+ }
411
+ const contentType = response.headers.get("content-type") ?? "";
412
+ const result: Record<string, unknown> = { status };
413
+ if (/text\/event-stream/i.test(contentType)) {
414
+ result.events = await readStream(response);
415
+ } else {
416
+ const bytes = new Uint8Array(await response.arrayBuffer());
417
+ const truncated = bytes.byteLength > MAX_RESPONSE_BYTES;
418
+ const kept = truncated ? bytes.slice(0, MAX_RESPONSE_BYTES) : bytes;
419
+ if (/json/i.test(contentType) && !truncated) {
420
+ result.body = JSON.parse(new TextDecoder().decode(kept) || "null");
421
+ } else if (/^text\/|json|xml|yaml|javascript/i.test(contentType) || contentType === "") {
422
+ result.body = new TextDecoder().decode(kept);
423
+ } else {
424
+ result.contentType = contentType;
425
+ result.base64 = Buffer.from(kept).toString("base64");
426
+ }
427
+ if (truncated)
428
+ result.truncated = { returnedBytes: MAX_RESPONSE_BYTES, totalBytes: bytes.byteLength };
429
+ }
430
+ if (
431
+ (status === 401 || status === 403) &&
432
+ /human|browser|cookie|same-origin/i.test(JSON.stringify(result.body ?? ""))
433
+ ) {
434
+ result.hint = "This action has to be done by the person in the Opengeni app in a browser.";
435
+ }
436
+ return {
437
+ content: [{ type: "text", text: JSON.stringify(result) }],
438
+ ...(status >= 400 ? { isError: true } : {}),
439
+ };
440
+ }
441
+
442
+ async function readStream(response: Response): Promise<string> {
443
+ const reader = response.body?.getReader();
444
+ if (!reader) return "";
445
+ const decoder = new TextDecoder();
446
+ let text = "";
447
+ const deadline = Date.now() + STREAM_READ_MS;
448
+ try {
449
+ while (Date.now() < deadline && text.length < MAX_RESPONSE_BYTES) {
450
+ const next = await Promise.race([
451
+ reader.read(),
452
+ new Promise<{ done: true; value: undefined }>((resolve) =>
453
+ setTimeout(
454
+ () => resolve({ done: true, value: undefined }),
455
+ Math.max(0, deadline - Date.now()),
456
+ ),
457
+ ),
458
+ ]);
459
+ if (next.done) break;
460
+ text += decoder.decode(next.value, { stream: true });
461
+ }
462
+ } finally {
463
+ await reader.cancel().catch(() => undefined);
464
+ }
465
+ return text;
466
+ }
467
+
468
+ function json(value: unknown): CallToolResult {
469
+ return { content: [{ type: "text", text: JSON.stringify(value) }] };
470
+ }
471
+
472
+ /** A browser-only action: say why, and that the person has to do it. */
473
+ function browserOnly(entry: ActionCatalogEntry): CallToolResult {
474
+ return failure(
475
+ `${entry.id} isn't available to connected agents or API keys: ${entry.browserOnly}. The person has to do it in the Opengeni app in a browser.`,
476
+ );
477
+ }
478
+
479
+ function failure(message: string): CallToolResult {
480
+ return { content: [{ type: "text", text: message }], isError: true };
481
+ }
482
+
483
+ function invalid(error: z.ZodError): CallToolResult {
484
+ return failure(`Invalid input: ${z.prettifyError(error)}`);
485
+ }
@@ -0,0 +1,154 @@
1
+ import {
2
+ DEFAULT_FIRST_PARTY_MCP_PERMISSIONS,
3
+ readTurnExecutionPolicyV1,
4
+ resolveAgentToolFamilies,
5
+ type AccessGrant,
6
+ } from "@opengeni/contracts";
7
+ import type { ConnectAttempt } from "@opengeni/contracts/connect";
8
+ import {
9
+ getActiveSessionTurnForExecution,
10
+ getAttemptToolCatalog,
11
+ getSession,
12
+ requireWorkspace,
13
+ lockTurnAttemptWriteFenceTx,
14
+ resolveInitiatingHuman,
15
+ type Database,
16
+ } from "@opengeni/db";
17
+ import { withOrganizationIntegrationPolicyFence } from "@opengeni/db/organization-integration-policy";
18
+ import {
19
+ externalActorContinuationForAuthorization,
20
+ hasPermission,
21
+ isDeveloperSetupGrant,
22
+ requireSessionAuthorization,
23
+ type AccessGrantAuthorization,
24
+ type ApiRouteDeps,
25
+ } from "@opengeni/core";
26
+ import { requireConnectOwnerAuthority } from "./integrations/connect-authority";
27
+ import {
28
+ isPersonalConnectionOwnerPrincipal,
29
+ isPersonalConnectionOwnerSubject,
30
+ } from "./connection-ownership";
31
+ import { codemodeAuthorityForGrant, requireMatchingCodemodeCatalog } from "./codemode";
32
+ import { PREPARED_MCP_PERMISSIONS, preparedMcpProxyPermissions } from "./prepared-mcp-permissions";
33
+ import { resolveSessionFirstPartyMcpTools } from "@opengeni/config";
34
+ import { HTTPException } from "hono/http-exception";
35
+
36
+ /** The normal browser and the exact agent attempt share Connect storage and
37
+ * verification. This adapter is ONLY for prepared MCP keys, never interactive
38
+ * OAuth, arbitrary native connections, or a caller-supplied owner identity. */
39
+ export async function connectRequestActor(
40
+ deps: ApiRouteDeps,
41
+ authorization: AccessGrantAuthorization,
42
+ ) {
43
+ if (!authorization.contextIntegrity)
44
+ throw new HTTPException(403, { message: "Verified Connect authority required" });
45
+ const grant = authorization.grant;
46
+ const continuation = externalActorContinuationForAuthorization(authorization);
47
+ const ordinary = {
48
+ accountId: grant.accountId,
49
+ workspaceId: grant.workspaceId,
50
+ subjectId: grant.subjectId,
51
+ personalOwnerVerified: isPersonalConnectionOwnerPrincipal(authorization),
52
+ ...(continuation ? { externalContinuation: continuation } : {}),
53
+ };
54
+ if (grant.principalKind !== "agent_attempt")
55
+ return {
56
+ scope: ordinary,
57
+ grant,
58
+ beforeOperation: undefined,
59
+ preparedOnly: false,
60
+ };
61
+ const authority = codemodeAuthorityForGrant(grant);
62
+ if (
63
+ !authority ||
64
+ isDeveloperSetupGrant(grant) ||
65
+ PREPARED_MCP_PERMISSIONS.some((permission) => !hasPermission(grant.permissions, permission))
66
+ )
67
+ throw new HTTPException(403, { message: "Prepared MCP setup authority required" });
68
+ await requireSessionAuthorization(deps, grant, {
69
+ sessionId: authority.sessionId,
70
+ operation: "session.first_party_mcp.call",
71
+ surface: "first_party_mcp",
72
+ });
73
+ const turn = await getActiveSessionTurnForExecution(
74
+ deps.db,
75
+ authority.workspaceId,
76
+ authority.sessionId,
77
+ );
78
+ // No creator, current browser user, raw metadata, or historical fallback.
79
+ const owner = turn?.initiatingHumanSubjectId;
80
+ if (
81
+ !turn ||
82
+ turn.id !== authority.turnId ||
83
+ turn.activeAttemptId !== authority.attemptId ||
84
+ turn.executionGeneration !== authority.executionGeneration ||
85
+ !owner ||
86
+ !isPersonalConnectionOwnerSubject(owner)
87
+ )
88
+ throw new HTTPException(403, { message: "Prepared MCP setup requires an exact causal owner" });
89
+ const scope = {
90
+ accountId: grant.accountId,
91
+ workspaceId: grant.workspaceId,
92
+ subjectId: owner,
93
+ personalOwnerVerified: true,
94
+ };
95
+ const beforeOperation = async (tx: Database) => {
96
+ // Organization policy is already locked by the caller. Live membership
97
+ // precedes workspace/session/turn locks and remains held through commit.
98
+ for (const permission of PREPARED_MCP_PERMISSIONS)
99
+ await requireConnectOwnerAuthority(tx, scope, permission);
100
+ const fence = await lockTurnAttemptWriteFenceTx(tx, authority);
101
+ if (
102
+ !fence.allowed ||
103
+ fence.turn.initiatingHumanSubjectId !== owner ||
104
+ fence.turn.accountId !== grant.accountId
105
+ )
106
+ throw new HTTPException(403, { message: "The setup execution attempt is no longer active" });
107
+ for (const metadata of [fence.turn.metadata, fence.session.metadata]) {
108
+ const policy = readTurnExecutionPolicyV1(metadata);
109
+ if (policy.kind === "valid" && policy.policy.credentialRestriction)
110
+ throw new HTTPException(403, { message: "This execution cannot configure credentials" });
111
+ }
112
+ const session = await getSession(tx, authority.workspaceId, authority.sessionId);
113
+ const catalog = requireMatchingCodemodeCatalog(
114
+ authority,
115
+ await getAttemptToolCatalog(tx, authority),
116
+ );
117
+ const selected =
118
+ session &&
119
+ resolveSessionFirstPartyMcpTools(
120
+ deps.settings,
121
+ session,
122
+ (await requireWorkspace(tx, authority.workspaceId)).settings,
123
+ );
124
+ const admitted =
125
+ session &&
126
+ preparedMcpProxyPermissions(
127
+ catalog,
128
+ session.firstPartyMcpPermissions ?? [...DEFAULT_FIRST_PARTY_MCP_PERMISSIONS],
129
+ );
130
+ if (
131
+ !selected?.includes("custom_mcp_setup_request") ||
132
+ !resolveAgentToolFamilies(session?.agent).allowsFirstPartyTool("custom_mcp_setup_request") ||
133
+ !admitted ||
134
+ PREPARED_MCP_PERMISSIONS.some((permission) => !admitted.includes(permission)) ||
135
+ !(await resolveInitiatingHuman(tx, scope, owner, authority.turnId))
136
+ )
137
+ throw new HTTPException(403, {
138
+ message: "Prepared MCP setup is not allowed by this attempt",
139
+ });
140
+ };
141
+ await withOrganizationIntegrationPolicyFence(deps.db, scope, (tx) => beforeOperation(tx));
142
+ // Internal resource lookup only. The authenticated principal stays an agent;
143
+ // no human_session token or ambient personal-connection delegation is minted.
144
+ const ownerGrant: AccessGrant = { ...grant, subjectId: owner };
145
+ return { scope, grant: ownerGrant, beforeOperation, preparedOnly: true };
146
+ }
147
+
148
+ export function assertAgentPreparedConnect(
149
+ actor: { preparedOnly: boolean },
150
+ attempt: Pick<ConnectAttempt, "providerId" | "mcpSetup">,
151
+ ): void {
152
+ if (actor.preparedOnly && (attempt.providerId !== "mcp-headers" || !attempt.mcpSetup))
153
+ throw new HTTPException(403, { message: "Agent setup is limited to prepared MCP credentials" });
154
+ }
@@ -0,0 +1,38 @@
1
+ import type { AttemptToolCatalog, Permission } from "@opengeni/contracts";
2
+
3
+ export const PREPARED_MCP_PERMISSIONS = [
4
+ "connections:read",
5
+ "connections:write",
6
+ "capabilities:manage",
7
+ ] as const satisfies readonly Permission[];
8
+
9
+ /** Only the existing native Connect resource can receive setup permissions.
10
+ * This never expands SDK access to unrelated credential or settings routes. */
11
+ export function isPreparedMcpConnectPath(path: string, method: string): boolean {
12
+ const match =
13
+ /^\/v1\/workspaces\/[^/]+\/connect\/attempts(?:\/([0-9a-f-]{36})(?:\/(advance|cancel))?)?$/.exec(
14
+ path,
15
+ );
16
+ return Boolean(
17
+ match && (method === "GET" ? !match[2] : method === "POST" && (!match[1] || match[2])),
18
+ );
19
+ }
20
+
21
+ /** The accepted tool must be present without an outstanding human-review gate.
22
+ * A session/settings edit can remove authority but cannot add it to this attempt. */
23
+ export function preparedMcpProxyPermissions(
24
+ catalog: AttemptToolCatalog,
25
+ livePermissions: readonly Permission[],
26
+ ): Permission[] {
27
+ const entry = catalog.entries.find(
28
+ (item) =>
29
+ item.identity.serverId === "opengeni" &&
30
+ item.identity.toolName === "custom_mcp_setup_request",
31
+ );
32
+ if (!entry || entry.approval !== "none") return [];
33
+ return PREPARED_MCP_PERMISSIONS.filter(
34
+ (permission) =>
35
+ catalog.firstPartyMcpPermissions?.includes(permission) &&
36
+ livePermissions.includes(permission),
37
+ );
38
+ }