@opengeni/core 4.0.3-canary.36079201993001 → 4.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/core",
3
- "version": "4.0.3-canary.36079201993001",
3
+ "version": "4.0.3",
4
4
  "description": "OpenGeni framework-agnostic core: the domain, access, and billing layers (neutral access, off-HTTP V2 surface). Behavior-preserving extraction from apps/api — keeps Hono's HTTPException for error throwing (typed-errors cleanup deferred).",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -50,17 +50,17 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@modelcontextprotocol/sdk": "^1.29.0",
53
- "@opengeni/capabilities": "^0.3.4-canary.36079201993001",
54
- "@opengeni/codex": "^0.2.26-canary.36079201993001",
55
- "@opengeni/config": "^2.1.1-canary.36079201993001",
56
- "@opengeni/contracts": "^5.1.1-canary.36079201993001",
57
- "@opengeni/db": "^6.0.3-canary.36079201993001",
58
- "@opengeni/documents": "^0.8.34-canary.36079201993001",
59
- "@opengeni/events": "^0.4.32-canary.36079201993001",
60
- "@opengeni/network": "^0.3.1-canary.36079201993001",
61
- "@opengeni/observability": "^0.8.32-canary.36079201993001",
62
- "@opengeni/runtime": "^4.0.3-canary.36079201993001",
63
- "@opengeni/storage": "^0.2.133-canary.36079201993001",
53
+ "@opengeni/capabilities": "^0.3.4",
54
+ "@opengeni/codex": "^0.2.26",
55
+ "@opengeni/config": "^2.1.1",
56
+ "@opengeni/contracts": "^5.1.1",
57
+ "@opengeni/db": "^6.0.3",
58
+ "@opengeni/documents": "^0.8.34",
59
+ "@opengeni/events": "^0.4.32",
60
+ "@opengeni/network": "^0.3.1",
61
+ "@opengeni/observability": "^0.8.32",
62
+ "@opengeni/runtime": "^4.0.3",
63
+ "@opengeni/storage": "^0.2.133",
64
64
  "hono": "^4.12.18",
65
65
  "zod": "^4.2.1"
66
66
  },
@@ -27,11 +27,6 @@ import {
27
27
  import { requireVariableSetEncryption } from "../domain/environments";
28
28
  import { normalizedSessionMcpCredentialHeaders } from "../domain/sessions";
29
29
  import { externalContinuationCommitAuthorizer } from "./external-continuation";
30
- import {
31
- listOwnConnectionAccountsForGrant,
32
- personalConnectionDelegationSourceForGrant,
33
- } from "../domain/personal-connection-delegations";
34
- import { nativeSessionConnectionReplacement } from "../domain/session-native-connection-replacement";
35
30
 
36
31
  /** HMAC domains separate request identity from key availability. The key tag
37
32
  * carries no request material and neither fingerprint is returned publicly. */
@@ -85,20 +80,11 @@ export async function rotateSessionMcpCredentialsForRequest(
85
80
  id: update.id,
86
81
  expectedCredentialVersion: update.expectedCredentialVersion,
87
82
  expectedServerUrl: update.expectedServerUrl,
88
- ...("nativeConnectionId" in update
89
- ? {
90
- nativeConnectionId: update.nativeConnectionId,
91
- ...(update.replacementServerUrl
92
- ? { replacementServerUrl: update.replacementServerUrl }
93
- : {}),
94
- }
95
- : {
96
- headers: Object.fromEntries(
97
- Object.entries(normalizedSessionMcpCredentialHeaders(update.headers))
98
- .map(([name, value]) => [name.toLowerCase(), value] as const)
99
- .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0)),
100
- ),
101
- }),
83
+ headers: Object.fromEntries(
84
+ Object.entries(normalizedSessionMcpCredentialHeaders(update.headers))
85
+ .map(([name, value]) => [name.toLowerCase(), value] as const)
86
+ .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0)),
87
+ ),
102
88
  }))
103
89
  .sort((left, right) => (left.id < right.id ? -1 : left.id > right.id ? 1 : 0)),
104
90
  };
@@ -116,45 +102,20 @@ export async function rotateSessionMcpCredentialsForRequest(
116
102
  actorType: grant.principalKind === "service" ? ("service" as const) : ("human" as const),
117
103
  };
118
104
  const externalAuthorize = externalContinuationCommitAuthorizer(authorization);
119
- let authorizedGrant = grant;
120
105
  try {
121
106
  return await rotateSessionMcpCredentialsAtomically(deps.db, {
122
107
  ...scope,
123
108
  operationKey: request.operationKey,
124
109
  ...sessionMcpRotationFingerprint(encryptionKey, scope, request),
125
- updates: request.updates.map((update) =>
126
- "nativeConnectionId" in update
127
- ? update
128
- : {
129
- id: update.id,
130
- expectedCredentialVersion: update.expectedCredentialVersion,
131
- expectedServerUrl: update.expectedServerUrl,
132
- headersEncrypted: Object.fromEntries(
133
- Object.entries(update.headers).map(([name, value]) => [
134
- name,
135
- encryptVariableSetValue(encryptionKey, value),
136
- ]),
137
- ),
138
- },
139
- ),
140
- resolveNativeConnection: async (tx, server, nativeConnectionId, replacementServerUrl) => {
141
- const connections = await listOwnConnectionAccountsForGrant(tx, authorizedGrant);
142
- const source = personalConnectionDelegationSourceForGrant(authorizedGrant);
143
- try {
144
- return nativeSessionConnectionReplacement({
145
- accountId: grant.accountId,
146
- workspaceId: grant.workspaceId,
147
- subjectId: source.kind === "subject" ? source.subjectId : null,
148
- serverUrl: server.url,
149
- ...(replacementServerUrl ? { replacementServerUrl } : {}),
150
- currentRef: server.connectionRef,
151
- nativeConnectionId,
152
- connections,
153
- });
154
- } catch {
155
- throw new SessionMcpCredentialRotationError("connection_unavailable");
156
- }
157
- },
110
+ updates: request.updates.map(({ headers, ...update }) => ({
111
+ ...update,
112
+ headersEncrypted: Object.fromEntries(
113
+ Object.entries(headers).map(([name, value]) => [
114
+ name,
115
+ encryptVariableSetValue(encryptionKey, value),
116
+ ]),
117
+ ),
118
+ })),
158
119
  authorize: async (tx) => {
159
120
  await externalAuthorize?.(tx);
160
121
  const fresh = await reauthorize(tx);
@@ -184,7 +145,6 @@ export async function rotateSessionMcpCredentialsForRequest(
184
145
  operation: "session.mcp.credentials.rotate",
185
146
  surface: "http",
186
147
  });
187
- authorizedGrant = fresh;
188
148
  },
189
149
  });
190
150
  } catch (error) {
@@ -202,9 +162,7 @@ export async function rotateSessionMcpCredentialsForRequest(
202
162
  ? 403
203
163
  : error.code === "not_found"
204
164
  ? 404
205
- : error.code === "invalid_request" ||
206
- error.code === "brokered_server" ||
207
- error.code === "connection_unavailable"
165
+ : error.code === "invalid_request" || error.code === "brokered_server"
208
166
  ? 422
209
167
  : 409;
210
168
  throw new HTTPException(status, { message: `credential_rotation_${error.code}` });
@@ -4,7 +4,6 @@ import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
4
4
  import { isDeepStrictEqual } from "node:util";
5
5
  import { withLockedCapabilityInstallation } from "@opengeni/db/capability-reconciliation";
6
6
  import { environmentsEncryptionKeyBytes, type Settings } from "@opengeni/config";
7
- import { pinnedFetch } from "@opengeni/network";
8
7
  import {
9
8
  CapabilityCatalogItem,
10
9
  capabilityCatalogItemIsTrustedForExposure,
@@ -345,12 +344,7 @@ export async function prepareCapabilityEnable(input: EnableCapabilityInput) {
345
344
  ...installationMetadata,
346
345
  ...(connectionRef && !headers
347
346
  ? authDeferredMcpConnectivity()
348
- : await validateMcpCapabilityConnection(
349
- item,
350
- input.probeMcpServer,
351
- headers ?? undefined,
352
- input.settings,
353
- )),
347
+ : await validateMcpCapabilityConnection(item, input.probeMcpServer, headers ?? undefined)),
354
348
  };
355
349
  if (connectionRef) {
356
350
  installationConfig.connectionRef = connectionRef;
@@ -675,7 +669,6 @@ export type McpCapabilityProbeInput = {
675
669
  url: string;
676
670
  timeoutMs: number;
677
671
  headers?: Record<string, string>;
678
- settings?: Settings;
679
672
  };
680
673
 
681
674
  export type McpCapabilityProbeResult = {
@@ -690,7 +683,6 @@ export async function validateMcpCapabilityConnection(
690
683
  item: CapabilityCatalogItem,
691
684
  probe: McpCapabilityProbe = probeStreamableHttpMcpServer,
692
685
  headers?: Record<string, string>,
693
- settings?: Settings,
694
686
  ): Promise<Record<string, unknown>> {
695
687
  if (item.kind !== "mcp") {
696
688
  return {};
@@ -707,7 +699,6 @@ export async function validateMcpCapabilityConnection(
707
699
  url: item.endpointUrl,
708
700
  timeoutMs: mcpCapabilityProbeTimeoutMs,
709
701
  ...(headers ? { headers } : {}),
710
- ...(settings ? { settings } : {}),
711
702
  });
712
703
  return {
713
704
  mcpConnectivity: {
@@ -726,8 +717,6 @@ export async function validateMcpCapabilityConnection(
726
717
  async function probeStreamableHttpMcpServer(
727
718
  input: McpCapabilityProbeInput,
728
719
  ): Promise<McpCapabilityProbeResult> {
729
- const settings = input.settings;
730
- if (!settings) throw new Error("Network policy is unavailable for MCP validation");
731
720
  const controller = new AbortController();
732
721
  const timeout = setTimeout(() => controller.abort(), input.timeoutMs);
733
722
  const client = new Client(
@@ -740,11 +729,6 @@ async function probeStreamableHttpMcpServer(
740
729
  signal: controller.signal,
741
730
  ...(input.headers ? { headers: input.headers } : {}),
742
731
  },
743
- fetch: (url, init) =>
744
- pinnedFetch(url, init, settings, {
745
- label: "MCP capability probe",
746
- requireHttpsOutsideLocalTest: true,
747
- }),
748
732
  });
749
733
  await client.connect(transport as unknown as Transport, {
750
734
  timeout: input.timeoutMs,
@@ -1,14 +0,0 @@
1
- import type { ConnectionMetadata, McpServerConnectionRef } from "@opengeni/contracts";
2
- /** Selection is restricted to the caller's already-authorized inventory. This
3
- * projection grants no execution authority: subsequent admission and physical
4
- * credential use still validate the exact native account normally. */
5
- export declare function nativeSessionConnectionReplacement(input: {
6
- accountId: string;
7
- workspaceId: string;
8
- subjectId: string | null;
9
- serverUrl: string;
10
- replacementServerUrl?: string;
11
- currentRef: McpServerConnectionRef | null;
12
- nativeConnectionId: string;
13
- connections: ConnectionMetadata[];
14
- }): McpServerConnectionRef;
@@ -1,64 +0,0 @@
1
- import type { ConnectionMetadata, McpServerConnectionRef } from "@opengeni/contracts";
2
- import { connectionMetadataMatchesBinding } from "@opengeni/db/session-mcp-credential-rotation";
3
-
4
- /** Selection is restricted to the caller's already-authorized inventory. This
5
- * projection grants no execution authority: subsequent admission and physical
6
- * credential use still validate the exact native account normally. */
7
- export function nativeSessionConnectionReplacement(input: {
8
- accountId: string;
9
- workspaceId: string;
10
- subjectId: string | null;
11
- serverUrl: string;
12
- replacementServerUrl?: string;
13
- currentRef: McpServerConnectionRef | null;
14
- nativeConnectionId: string;
15
- connections: ConnectionMetadata[];
16
- }): McpServerConnectionRef {
17
- const connection = input.connections.find(
18
- (candidate) => candidate.id === input.nativeConnectionId,
19
- );
20
- if (
21
- !connection ||
22
- connection.accountId !== input.accountId ||
23
- connection.status !== "active" ||
24
- (connection.subjectId === null
25
- ? connection.workspaceId !== input.workspaceId
26
- : !input.subjectId || connection.subjectId !== input.subjectId || !connection.authorityId)
27
- ) {
28
- throw new Error("native connection unavailable");
29
- }
30
- const {
31
- authoritySource: _authoritySource,
32
- hostBinding: _hostBinding,
33
- accountSelection: _accountSelection,
34
- ...retained
35
- } = input.currentRef ?? {};
36
- // Preserve provider, resource, scope and selected-resource restrictions.
37
- // Retired host identity is never interpreted as a native connection ID.
38
- if (
39
- input.currentRef &&
40
- input.currentRef.providerDomain.toLowerCase() !== connection.providerDomain.toLowerCase()
41
- )
42
- throw new Error("native connection provider mismatch");
43
- const ref: McpServerConnectionRef = {
44
- ...retained,
45
- ...(!input.currentRef?.resource && typeof connection.metadata.resource === "string"
46
- ? { resource: connection.metadata.resource }
47
- : {}),
48
- connectionId: connection.id,
49
- providerDomain: connection.providerDomain,
50
- kind: connection.kind,
51
- subjectScope: connection.subjectId === null ? "workspace" : "subject",
52
- };
53
- const destination = input.replacementServerUrl ?? input.serverUrl;
54
- // A redirect must be explicitly requested and bound in the account metadata;
55
- // the broker's legacy provider-host fallback is insufficient for rebinding.
56
- if (
57
- input.replacementServerUrl &&
58
- (typeof connection.metadata.mcpUrl !== "string" || !connection.metadata.mcpUrl.trim())
59
- )
60
- throw new Error("native connection destination unavailable");
61
- if (!connectionMetadataMatchesBinding(connection, ref, destination))
62
- throw new Error("native connection binding mismatch");
63
- return ref;
64
- }