@opengeni/api-router 2.12.4-canary.3 → 2.13.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/app.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  withDefaultEnabledCapabilityMcpTools,
25
25
  workflowIdForSession,
26
26
  workspaceActorContextExempt
27
- } from "./chunk-VQCBJV4P.js";
27
+ } from "./chunk-BJWHVMOL.js";
28
28
  export {
29
29
  API_MAX_REQUEST_BODY_BYTES,
30
30
  allowedCorsOrigin,
@@ -5766,6 +5766,7 @@ import { requireLimit as requireLimit10 } from "@opengeni/core";
5766
5766
 
5767
5767
  // src/mcp/server.ts
5768
5768
  import {
5769
+ getAttemptToolCatalog as getAttemptToolCatalog2,
5769
5770
  createChannel,
5770
5771
  listChannels,
5771
5772
  getChannel,
@@ -29777,6 +29778,25 @@ function registerCapabilityDiscoveryTools(server, deps, grant, sessionId, json)
29777
29778
  const authorize = async () => {
29778
29779
  await authorizeFirstPartySession(deps, grant, sessionId, "session.first_party_mcp.call");
29779
29780
  };
29781
+ const setupProjections = async (items) => {
29782
+ const availableServerIds = /* @__PURE__ */ new Set();
29783
+ if (items.some((item) => item.enabled && item.connectionRef?.subjectScope === "subject")) {
29784
+ const claims = exactAgentCommandContext(grant, sessionId);
29785
+ const attemptCatalog = await getAttemptToolCatalog2(deps.db, {
29786
+ accountId: grant.accountId,
29787
+ workspaceId: grant.workspaceId,
29788
+ attemptId: claims.callerAttemptId
29789
+ });
29790
+ if (attemptCatalog?.sessionId === sessionId && attemptCatalog.turnId === claims.callerTurnId && attemptCatalog.executionGeneration === claims.callerExecutionGeneration) {
29791
+ for (const entry2 of attemptCatalog.entries) availableServerIds.add(entry2.identity.serverId);
29792
+ }
29793
+ }
29794
+ return await Promise.all(
29795
+ items.map(
29796
+ (item) => capabilitySetupProjection(deps, grant.workspaceId, item, availableServerIds)
29797
+ )
29798
+ );
29799
+ };
29780
29800
  server.registerTool(
29781
29801
  "capability_catalog_search",
29782
29802
  {
@@ -29794,25 +29814,24 @@ function registerCapabilityDiscoveryTools(server, deps, grant, sessionId, json)
29794
29814
  query,
29795
29815
  limit ?? 8
29796
29816
  );
29797
- const matches = await Promise.all(
29798
- ranked.map(async ({ item, matchedOn }) => ({
29799
- capabilityId: item.id,
29800
- name: item.name,
29801
- description: item.description,
29802
- kind: item.kind,
29803
- source: item.source,
29804
- category: item.category,
29805
- tags: item.tags.slice(0, 16),
29806
- providerDomain: item.providerDomain,
29807
- authKind: item.authKind,
29808
- tier: item.tier,
29809
- matchedOn,
29810
- setup: {
29811
- ...await capabilitySetupProjection(deps, grant.workspaceId, item),
29812
- requiredVariables: capabilityRequiredVariables(item)
29813
- }
29814
- }))
29815
- );
29817
+ const setups = await setupProjections(ranked.map(({ item }) => item));
29818
+ const matches = ranked.map(({ item, matchedOn }, index) => ({
29819
+ capabilityId: item.id,
29820
+ name: item.name,
29821
+ description: item.description,
29822
+ kind: item.kind,
29823
+ source: item.source,
29824
+ category: item.category,
29825
+ tags: item.tags.slice(0, 16),
29826
+ providerDomain: item.providerDomain,
29827
+ authKind: item.authKind,
29828
+ tier: item.tier,
29829
+ matchedOn,
29830
+ setup: {
29831
+ ...setups[index],
29832
+ requiredVariables: capabilityRequiredVariables(item)
29833
+ }
29834
+ }));
29816
29835
  return json({ query, matches });
29817
29836
  }
29818
29837
  );
@@ -29834,7 +29853,8 @@ function registerCapabilityDiscoveryTools(server, deps, grant, sessionId, json)
29834
29853
  if (!item || !capabilityCatalogItemIsTrustedForExposure(item)) {
29835
29854
  throw new Error("Unknown or untrusted capability; search the catalog again.");
29836
29855
  }
29837
- const setup = await capabilitySetupProjection(deps, grant.workspaceId, item);
29856
+ const [setup] = await setupProjections([item]);
29857
+ if (!setup) throw new Error("Capability setup projection is unavailable.");
29838
29858
  if (setup.status === "ready") {
29839
29859
  return json({
29840
29860
  capabilityId: item.id,
@@ -29890,7 +29910,7 @@ function registerCapabilityDiscoveryTools(server, deps, grant, sessionId, json)
29890
29910
  }
29891
29911
  );
29892
29912
  }
29893
- async function capabilitySetupProjection(deps, workspaceId, item) {
29913
+ async function capabilitySetupProjection(deps, workspaceId, item, availableServerIds) {
29894
29914
  if (item.id === "api:github-app" || item.surfaceType === "first_party_github") {
29895
29915
  const missing = githubAppMissingSettings(deps.settings);
29896
29916
  if (missing.length > 0) {
@@ -29925,6 +29945,20 @@ async function capabilitySetupProjection(deps, workspaceId, item) {
29925
29945
  detail: "A workspace admin must designate an authorized Codex Apps subscription."
29926
29946
  };
29927
29947
  }
29948
+ if (item.enabled && item.connectionRef?.subjectScope === "subject") {
29949
+ if (item.runtime.mcpServerId && availableServerIds.has(item.runtime.mcpServerId)) {
29950
+ return {
29951
+ status: "ready",
29952
+ action: null,
29953
+ detail: "This capability has tools available in this turn."
29954
+ };
29955
+ }
29956
+ return {
29957
+ status: "authorization_required",
29958
+ action: "connect",
29959
+ detail: "This capability is enabled, but its personal account is not available in this turn. The account owner must review access using Use in this conversation, then send a new message. Shared conversations require acknowledgement that results are visible to workspace members."
29960
+ };
29961
+ }
29928
29962
  if (item.enabled) {
29929
29963
  return {
29930
29964
  status: "ready",
@@ -86024,6 +86058,7 @@ import {
86024
86058
  requireAccessGrant as requireAccessGrant33,
86025
86059
  requireAccessGrantAuthorization as requireAccessGrantAuthorization23,
86026
86060
  requireFreshAccessGrant as requireFreshAccessGrant2,
86061
+ rotateSessionMcpCredentialsForRequest,
86027
86062
  hasVerifiedOwningUserAuthorization,
86028
86063
  requirePermission as requirePermission8,
86029
86064
  requireSessionAuthorization as requireSessionAuthorization11,
@@ -88601,6 +88636,26 @@ function registerSessionRoutes(app, deps) {
88601
88636
  await listSessionTurns(db, workspaceId, sessionId, boundedLimit(c.req.query("limit")))
88602
88637
  );
88603
88638
  });
88639
+ app.post("/v1/workspaces/:workspaceId/sessions/:sessionId/mcp-credentials/rotate", async (c) => {
88640
+ const workspaceId = c.req.param("workspaceId");
88641
+ const authorization = await requireAccessGrantAuthorization23(
88642
+ c,
88643
+ deps,
88644
+ workspaceId,
88645
+ "sessions:control"
88646
+ );
88647
+ const payload = await c.req.json().catch(() => null);
88648
+ c.header("cache-control", "private, no-store");
88649
+ return c.json(
88650
+ await rotateSessionMcpCredentialsForRequest(
88651
+ deps,
88652
+ authorization,
88653
+ c.req.param("sessionId"),
88654
+ payload,
88655
+ (tx) => requireFreshAccessGrant2(c, { ...deps, db: tx }, workspaceId, "sessions:control")
88656
+ )
88657
+ );
88658
+ });
88604
88659
  app.get("/v1/workspaces/:workspaceId/sessions/:sessionId/queue", async (c) => {
88605
88660
  const workspaceId = c.req.param("workspaceId");
88606
88661
  await requireAccessGrant33(c, deps, workspaceId, "sessions:read");
@@ -89942,6 +89997,8 @@ function sessionAuthorizationOperationForHttp(method, pathname, sessionId) {
89942
89997
  if (suffix === "/channel" && verb === "PUT") return "session.channel.write";
89943
89998
  if (suffix === "/variable-sets" && verb === "PUT") return "session.variable_sets.write";
89944
89999
  if (suffix === "/tool-policy" && verb === "PUT") return "session.tool_policy.write";
90000
+ if (suffix === "/mcp-credentials/rotate" && verb === "POST")
90001
+ return "session.mcp.credentials.rotate";
89945
90002
  if (/^\/mcp-servers\/[^/]+\/approval-policy$/.test(suffix) && verb === "PATCH") {
89946
90003
  return "session.mcp.approval_policy.write";
89947
90004
  }
@@ -105819,4 +105876,4 @@ export {
105819
105876
  withDefaultEnabledCapabilityMcpTools,
105820
105877
  workflowIdForSession4 as workflowIdForSession
105821
105878
  };
105822
- //# sourceMappingURL=chunk-VQCBJV4P.js.map
105879
+ //# sourceMappingURL=chunk-BJWHVMOL.js.map