@agent-vm/mcp-portal 0.0.69 → 0.0.70

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 (84) hide show
  1. package/README.md +42 -11
  2. package/dist/agent-bearer-token-DCtpDPCZ.js +59 -0
  3. package/dist/agent-bearer-token-DCtpDPCZ.js.map +1 -0
  4. package/dist/bin/mcp-portal.d.ts +28 -0
  5. package/dist/bin/mcp-portal.d.ts.map +1 -0
  6. package/dist/bin/mcp-portal.js +318 -0
  7. package/dist/bin/mcp-portal.js.map +1 -0
  8. package/dist/{catalog-types--gUGFPpN.d.ts → catalog-types-BVuB4Ynx.d.ts} +1 -1
  9. package/dist/{catalog-types--gUGFPpN.d.ts.map → catalog-types-BVuB4Ynx.d.ts.map} +1 -1
  10. package/dist/cli/index.d.ts +101 -0
  11. package/dist/cli/index.d.ts.map +1 -0
  12. package/dist/cli/index.js +2 -0
  13. package/dist/core/index.d.ts +40 -0
  14. package/dist/core/index.d.ts.map +1 -0
  15. package/dist/core/index.js +5 -0
  16. package/dist/hmac-env-B4shpRRB.js +20 -0
  17. package/dist/hmac-env-B4shpRRB.js.map +1 -0
  18. package/dist/hmac-token-DBqWY3-w.js +100 -0
  19. package/dist/hmac-token-DBqWY3-w.js.map +1 -0
  20. package/dist/index.d.ts +5 -485
  21. package/dist/index.js +4 -5
  22. package/dist/mcp-proxy/index.d.ts +24 -0
  23. package/dist/mcp-proxy/index.d.ts.map +1 -0
  24. package/dist/mcp-proxy/index.js +2 -0
  25. package/dist/portal-auth/agent-bearer-token.d.ts +22 -0
  26. package/dist/portal-auth/agent-bearer-token.d.ts.map +1 -0
  27. package/dist/portal-auth/agent-bearer-token.js +2 -0
  28. package/dist/portal-auth/hmac-env.d.ts +6 -0
  29. package/dist/portal-auth/hmac-env.d.ts.map +1 -0
  30. package/dist/portal-auth/hmac-env.js +2 -0
  31. package/dist/portal-auth/hmac-token.d.ts +40 -0
  32. package/dist/portal-auth/hmac-token.d.ts.map +1 -0
  33. package/dist/portal-auth/hmac-token.js +2 -0
  34. package/dist/portal-config/index.d.ts +11 -0
  35. package/dist/portal-config/index.d.ts.map +1 -0
  36. package/dist/{tool-vm → portal-config}/index.js +2 -3
  37. package/dist/portal-core-CZQI7Ob6.d.ts +264 -0
  38. package/dist/portal-core-CZQI7Ob6.d.ts.map +1 -0
  39. package/dist/portal-core-Cgu714CL.js +416 -0
  40. package/dist/portal-core-Cgu714CL.js.map +1 -0
  41. package/dist/portal-session-DG2CUjIo.d.ts +184 -0
  42. package/dist/portal-session-DG2CUjIo.d.ts.map +1 -0
  43. package/dist/portal-tools-DKci1szO.js +528 -0
  44. package/dist/portal-tools-DKci1szO.js.map +1 -0
  45. package/dist/resolve-agent-identity-DnC_Pmnh.js +550 -0
  46. package/dist/resolve-agent-identity-DnC_Pmnh.js.map +1 -0
  47. package/dist/resolve-agent-identity-FQL02YdW.d.ts +81 -0
  48. package/dist/resolve-agent-identity-FQL02YdW.d.ts.map +1 -0
  49. package/dist/serve-command-CnSMUybd.js +358 -0
  50. package/dist/serve-command-CnSMUybd.js.map +1 -0
  51. package/dist/testing/fake-upstream-mcp-server.d.ts +5 -2
  52. package/dist/testing/fake-upstream-mcp-server.d.ts.map +1 -1
  53. package/dist/testing/fake-upstream-mcp-server.js +14 -4
  54. package/dist/testing/fake-upstream-mcp-server.js.map +1 -1
  55. package/dist/typescript-artifact-BVLt3Ifd.js +60 -0
  56. package/dist/typescript-artifact-BVLt3Ifd.js.map +1 -0
  57. package/dist/upstream-mcp-client-runtime-JlsfTm7_.js +760 -0
  58. package/dist/upstream-mcp-client-runtime-JlsfTm7_.js.map +1 -0
  59. package/dist/upstream-response-middleware-1MZnAD9C.d.ts +115 -0
  60. package/dist/upstream-response-middleware-1MZnAD9C.d.ts.map +1 -0
  61. package/dist/upstream-response-middleware-BjUWZ2G8.js +172 -0
  62. package/dist/upstream-response-middleware-BjUWZ2G8.js.map +1 -0
  63. package/dist/{index-BcI9c8sg.d.ts → zod-schema-loader-DLGQpYFD.d.ts} +3 -9
  64. package/dist/zod-schema-loader-DLGQpYFD.d.ts.map +1 -0
  65. package/dist/{typescript-artifact-BqU8okQy.js → zod-schema-loader-yNekKNpm.js} +85 -55
  66. package/dist/zod-schema-loader-yNekKNpm.js.map +1 -0
  67. package/package.json +30 -13
  68. package/dist/bin/agent-vm-mcp-portal.d.ts +0 -10
  69. package/dist/bin/agent-vm-mcp-portal.d.ts.map +0 -1
  70. package/dist/bin/agent-vm-mcp-portal.js +0 -56
  71. package/dist/bin/agent-vm-mcp-portal.js.map +0 -1
  72. package/dist/bin/portal-server.d.ts +0 -55
  73. package/dist/bin/portal-server.d.ts.map +0 -1
  74. package/dist/bin/portal-server.js +0 -289
  75. package/dist/bin/portal-server.js.map +0 -1
  76. package/dist/index-BcI9c8sg.d.ts.map +0 -1
  77. package/dist/index.d.ts.map +0 -1
  78. package/dist/tool-vm/index.d.ts +0 -2
  79. package/dist/tool-vm-ihnzDyjJ.js +0 -3
  80. package/dist/typescript-artifact-BqU8okQy.js.map +0 -1
  81. package/dist/upstream-mcp-client-runtime-DiBCBsDj.js +0 -1729
  82. package/dist/upstream-mcp-client-runtime-DiBCBsDj.js.map +0 -1
  83. package/dist/zod-schema-loader-CDDtoRE1.js +0 -90
  84. package/dist/zod-schema-loader-CDDtoRE1.js.map +0 -1
package/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # @agent-vm/mcp-portal
2
2
 
3
- Agent-scoped MCP Portal server and Tool VM helpers.
3
+ Agent-scoped MCP Portal core library, external proxy, CLI, and Tool VM helpers.
4
4
 
5
5
  ## What This Package Owns
6
6
 
7
- - The standalone `agent-vm-mcp-portal-server` HTTP MCP server.
7
+ - `/core`, the adapter-neutral portal execution library used by OpenClaw.
8
+ - `mcp-portal mcp-proxy serve`, the external `/mcp-proxy` MCP server command.
8
9
  - The four model-facing portal tools: `mcp_portal_list`, `mcp_portal_search`, `mcp_portal_describe`, and `mcp_portal_call`.
9
10
  - JSON-Schema-derived Zod validation before upstream tool calls.
10
11
  - HMAC approval-token verification for portal calls that OpenClaw approved.
@@ -12,23 +13,53 @@ Agent-scoped MCP Portal server and Tool VM helpers.
12
13
 
13
14
  ## Runtime Shape
14
15
 
15
- The server is launched in the OpenClaw gateway VM and listens on a loopback port,
16
- normally `127.0.0.1:18790`.
16
+ Managed OpenClaw loads `/core` in process from a controller-materialized
17
+ effective config directory. It does not launch a portal server in the gateway VM.
17
18
 
18
- Each agent receives a distinct MCP URL:
19
+ External MCP clients can use the proxy command:
19
20
 
20
21
  ```text
21
- http://127.0.0.1:18790/agents/<agentId>/mcp
22
+ mcp-portal mcp-proxy serve --config-dir <dir>
22
23
  ```
23
24
 
24
25
  The portal loads two files from `--config-dir`:
25
26
 
26
27
  - `mcp.config.jsonc`: upstream MCP provider catalog and credentials.
27
- - `mcp-portal.config.jsonc`: portal access header, agents, profiles, and policy.
28
+ - `mcp-portal.config.jsonc`: agents, profiles, policy, and optional external proxy auth.
29
+
30
+ External `serve` resolves `source: "1password"` refs through `@agent-vm/secrets`.
31
+ Use `AGENT_VM_MCP_PORTAL_OP_TOKEN_SOURCE=env`, `op-cli`, or `keychain` plus the
32
+ matching source-specific env settings when the proxy host needs 1Password
33
+ access. If no token source is configured, env-only configs still work. The
34
+ built-in HTTP bearer server is loopback-only; use a TLS reverse proxy and
35
+ `mcp-portal mcp-proxy print-client-config --proxy-url <url>` for public
36
+ endpoints. The printed client config contains bearer credential material on
37
+ stdout. Treat it like an API token, keep it out of logs and commits, and rotate
38
+ `credentialVersion` or the portal `masterKey` to revoke issued credentials.
39
+
40
+ `mcp-proxy serve` keeps approval-token replay state in process. Run one serving
41
+ process per external endpoint unless a future shared replay store is added.
42
+ Restarting the process clears consumed approval JTIs, so approval token TTLs
43
+ must stay short.
44
+
45
+ Managed OpenClaw materialization rewrites provider secrets to environment
46
+ references in the effective MCP config. Plaintext provider values flow only into
47
+ runtime environment variables for `injection: "env"` or into host-mediated
48
+ runtime secret state for `injection: "http-mediation"`; they are not written to
49
+ the generated config files.
50
+
51
+ Upstream MCP provider URLs are deployment-owned config. The schema rejects
52
+ non-HTTP schemes, but it intentionally allows loopback and private-network HTTP
53
+ targets because local sidecars and private service MCP providers are supported.
54
+ Do not load provider config from untrusted sources. If a future workflow imports
55
+ less-trusted provider definitions, put an explicit per-provider network
56
+ allowlist in front of private-network targets instead of blanket-blocking
57
+ loopback.
28
58
 
29
59
  ## Start Reading
30
60
 
31
- - `src/bin/portal-server.ts` for CLI boot and config loading.
32
- - `src/mcp-server/portal-http-server.ts` for Hono routing and MCP transport.
33
- - `src/mcp-server/portal-tools.ts` for portal tool behavior.
34
- - `src/auth/hmac-token.ts` for approval-token signing and verification.
61
+ - `src/core/portal-core.ts` for adapter-neutral execution.
62
+ - `src/bin/mcp-portal.ts` for CLI commands.
63
+ - `src/mcp-proxy/portal-http-server.ts` for Hono routing and MCP transport.
64
+ - `src/core/portal-tools.ts` for portal tool behavior.
65
+ - `src/portal-auth/hmac-token.ts` for approval-token signing and verification.
@@ -0,0 +1,59 @@
1
+ import { createHash, createHmac, timingSafeEqual } from "node:crypto";
2
+ //#region src/portal-auth/agent-bearer-token.ts
3
+ const bearerPurposePrefix = "mcp-proxy:agent:";
4
+ const minimumMasterKeyBytes = 32;
5
+ const base64UrlPattern = /^[A-Za-z0-9_-]+$/u;
6
+ function decodePortalMasterKey(encodedMasterKey) {
7
+ const trimmedMasterKey = encodedMasterKey.trim();
8
+ if (!base64UrlPattern.test(trimmedMasterKey)) throw new Error("MCP Portal masterKey must be base64url-encoded key material.");
9
+ const masterKey = Buffer.from(trimmedMasterKey, "base64url");
10
+ if (masterKey.length < minimumMasterKeyBytes) throw new Error(`MCP Portal masterKey must decode to at least ${String(minimumMasterKeyBytes)} bytes.`);
11
+ if (masterKey.toString("base64url") !== trimmedMasterKey) throw new Error("MCP Portal masterKey must be canonical base64url without padding.");
12
+ return masterKey;
13
+ }
14
+ function deriveAgentBearerToken(props) {
15
+ return createHmac("sha256", props.masterKey).update(`${bearerPurposePrefix}${props.agentId}:v${String(props.credentialVersion)}`).digest("base64url");
16
+ }
17
+ function formatMasterKeyFingerprint(masterKey) {
18
+ return `sha256:${createHash("sha256").update(masterKey).digest("base64url")}`;
19
+ }
20
+ function timingSafeEqualToken(left, right) {
21
+ const leftBuffer = Buffer.from(left);
22
+ const rightBuffer = Buffer.from(right);
23
+ return leftBuffer.length === rightBuffer.length && timingSafeEqual(leftBuffer, rightBuffer);
24
+ }
25
+ function mismatchedTokenWithExpectedLength(expectedToken) {
26
+ return `${expectedToken.startsWith("A") ? "B" : "A"}${expectedToken.slice(1)}`;
27
+ }
28
+ function verifyAgentBearerAuthorization(props) {
29
+ const expectedToken = deriveAgentBearerToken({
30
+ agentId: props.agentId,
31
+ credentialVersion: props.credentialVersion,
32
+ masterKey: props.masterKey
33
+ });
34
+ const mismatchedToken = mismatchedTokenWithExpectedLength(expectedToken);
35
+ if (props.authorizationHeader === void 0) {
36
+ timingSafeEqualToken(mismatchedToken, expectedToken);
37
+ return {
38
+ ok: false,
39
+ reason: "missing"
40
+ };
41
+ }
42
+ const [scheme, token, extra] = props.authorizationHeader.split(/\s+/u);
43
+ if (scheme !== "Bearer" || token === void 0 || token.length === 0 || extra !== void 0) {
44
+ timingSafeEqualToken(mismatchedToken, expectedToken);
45
+ return {
46
+ ok: false,
47
+ reason: "malformed"
48
+ };
49
+ }
50
+ if (!timingSafeEqualToken(token.length === expectedToken.length ? token : mismatchedToken, expectedToken)) return {
51
+ ok: false,
52
+ reason: "signature-mismatch"
53
+ };
54
+ return { ok: true };
55
+ }
56
+ //#endregion
57
+ export { verifyAgentBearerAuthorization as i, deriveAgentBearerToken as n, formatMasterKeyFingerprint as r, decodePortalMasterKey as t };
58
+
59
+ //# sourceMappingURL=agent-bearer-token-DCtpDPCZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-bearer-token-DCtpDPCZ.js","names":[],"sources":["../src/portal-auth/agent-bearer-token.ts"],"sourcesContent":["import { createHash, createHmac, timingSafeEqual } from 'node:crypto';\n\nexport interface DeriveAgentBearerTokenProps {\n\treadonly agentId: string;\n\treadonly credentialVersion: number;\n\treadonly masterKey: Buffer;\n}\n\nexport interface VerifyAgentBearerAuthorizationProps extends DeriveAgentBearerTokenProps {\n\treadonly authorizationHeader: string | undefined;\n}\n\nexport type VerifyAgentBearerAuthorizationResult =\n\t| { readonly ok: true }\n\t| { readonly ok: false; readonly reason: 'malformed' | 'missing' | 'signature-mismatch' };\n\nconst bearerPurposePrefix = 'mcp-proxy:agent:';\nconst minimumMasterKeyBytes = 32;\nconst base64UrlPattern = /^[A-Za-z0-9_-]+$/u;\n\nexport function decodePortalMasterKey(encodedMasterKey: string): Buffer {\n\tconst trimmedMasterKey = encodedMasterKey.trim();\n\tif (!base64UrlPattern.test(trimmedMasterKey)) {\n\t\tthrow new Error('MCP Portal masterKey must be base64url-encoded key material.');\n\t}\n\tconst masterKey = Buffer.from(trimmedMasterKey, 'base64url');\n\tif (masterKey.length < minimumMasterKeyBytes) {\n\t\tthrow new Error(\n\t\t\t`MCP Portal masterKey must decode to at least ${String(minimumMasterKeyBytes)} bytes.`,\n\t\t);\n\t}\n\tif (masterKey.toString('base64url') !== trimmedMasterKey) {\n\t\tthrow new Error('MCP Portal masterKey must be canonical base64url without padding.');\n\t}\n\treturn masterKey;\n}\n\nexport function deriveAgentBearerToken(props: DeriveAgentBearerTokenProps): string {\n\treturn createHmac('sha256', props.masterKey)\n\t\t.update(`${bearerPurposePrefix}${props.agentId}:v${String(props.credentialVersion)}`)\n\t\t.digest('base64url');\n}\n\nexport function formatMasterKeyFingerprint(masterKey: Buffer): string {\n\treturn `sha256:${createHash('sha256').update(masterKey).digest('base64url')}`;\n}\n\nfunction timingSafeEqualToken(left: string, right: string): boolean {\n\tconst leftBuffer = Buffer.from(left);\n\tconst rightBuffer = Buffer.from(right);\n\treturn leftBuffer.length === rightBuffer.length && timingSafeEqual(leftBuffer, rightBuffer);\n}\n\nfunction mismatchedTokenWithExpectedLength(expectedToken: string): string {\n\tconst replacementPrefix = expectedToken.startsWith('A') ? 'B' : 'A';\n\treturn `${replacementPrefix}${expectedToken.slice(1)}`;\n}\n\nexport function verifyAgentBearerAuthorization(\n\tprops: VerifyAgentBearerAuthorizationProps,\n): VerifyAgentBearerAuthorizationResult {\n\tconst expectedToken = deriveAgentBearerToken({\n\t\tagentId: props.agentId,\n\t\tcredentialVersion: props.credentialVersion,\n\t\tmasterKey: props.masterKey,\n\t});\n\tconst mismatchedToken = mismatchedTokenWithExpectedLength(expectedToken);\n\n\tif (props.authorizationHeader === undefined) {\n\t\ttimingSafeEqualToken(mismatchedToken, expectedToken);\n\t\treturn { ok: false, reason: 'missing' };\n\t}\n\tconst [scheme, token, extra] = props.authorizationHeader.split(/\\s+/u);\n\tif (scheme !== 'Bearer' || token === undefined || token.length === 0 || extra !== undefined) {\n\t\ttimingSafeEqualToken(mismatchedToken, expectedToken);\n\t\treturn { ok: false, reason: 'malformed' };\n\t}\n\tconst comparableToken = token.length === expectedToken.length ? token : mismatchedToken;\n\tif (!timingSafeEqualToken(comparableToken, expectedToken)) {\n\t\treturn { ok: false, reason: 'signature-mismatch' };\n\t}\n\treturn { ok: true };\n}\n"],"mappings":";;AAgBA,MAAM,sBAAsB;AAC5B,MAAM,wBAAwB;AAC9B,MAAM,mBAAmB;AAEzB,SAAgB,sBAAsB,kBAAkC;CACvE,MAAM,mBAAmB,iBAAiB,MAAM;CAChD,IAAI,CAAC,iBAAiB,KAAK,iBAAiB,EAC3C,MAAM,IAAI,MAAM,+DAA+D;CAEhF,MAAM,YAAY,OAAO,KAAK,kBAAkB,YAAY;CAC5D,IAAI,UAAU,SAAS,uBACtB,MAAM,IAAI,MACT,gDAAgD,OAAO,sBAAsB,CAAC,SAC9E;CAEF,IAAI,UAAU,SAAS,YAAY,KAAK,kBACvC,MAAM,IAAI,MAAM,oEAAoE;CAErF,OAAO;;AAGR,SAAgB,uBAAuB,OAA4C;CAClF,OAAO,WAAW,UAAU,MAAM,UAAU,CAC1C,OAAO,GAAG,sBAAsB,MAAM,QAAQ,IAAI,OAAO,MAAM,kBAAkB,GAAG,CACpF,OAAO,YAAY;;AAGtB,SAAgB,2BAA2B,WAA2B;CACrE,OAAO,UAAU,WAAW,SAAS,CAAC,OAAO,UAAU,CAAC,OAAO,YAAY;;AAG5E,SAAS,qBAAqB,MAAc,OAAwB;CACnE,MAAM,aAAa,OAAO,KAAK,KAAK;CACpC,MAAM,cAAc,OAAO,KAAK,MAAM;CACtC,OAAO,WAAW,WAAW,YAAY,UAAU,gBAAgB,YAAY,YAAY;;AAG5F,SAAS,kCAAkC,eAA+B;CAEzE,OAAO,GADmB,cAAc,WAAW,IAAI,GAAG,MAAM,MAClC,cAAc,MAAM,EAAE;;AAGrD,SAAgB,+BACf,OACuC;CACvC,MAAM,gBAAgB,uBAAuB;EAC5C,SAAS,MAAM;EACf,mBAAmB,MAAM;EACzB,WAAW,MAAM;EACjB,CAAC;CACF,MAAM,kBAAkB,kCAAkC,cAAc;CAExE,IAAI,MAAM,wBAAwB,KAAA,GAAW;EAC5C,qBAAqB,iBAAiB,cAAc;EACpD,OAAO;GAAE,IAAI;GAAO,QAAQ;GAAW;;CAExC,MAAM,CAAC,QAAQ,OAAO,SAAS,MAAM,oBAAoB,MAAM,OAAO;CACtE,IAAI,WAAW,YAAY,UAAU,KAAA,KAAa,MAAM,WAAW,KAAK,UAAU,KAAA,GAAW;EAC5F,qBAAqB,iBAAiB,cAAc;EACpD,OAAO;GAAE,IAAI;GAAO,QAAQ;GAAa;;CAG1C,IAAI,CAAC,qBADmB,MAAM,WAAW,cAAc,SAAS,QAAQ,iBAC7B,cAAc,EACxD,OAAO;EAAE,IAAI;EAAO,QAAQ;EAAsB;CAEnD,OAAO,EAAE,IAAI,MAAM"}
@@ -0,0 +1,28 @@
1
+ import { n as PortalToolRecord } from "../catalog-types-BVuB4Ynx.js";
2
+ import { SecretResolver } from "@agent-vm/secrets";
3
+
4
+ //#region src/bin/mcp-portal.d.ts
5
+ interface PortalCatalogFile {
6
+ readonly tools: readonly PortalToolRecord[];
7
+ }
8
+ interface AgentVmMcpPortalRuntimeProps {
9
+ readonly env?: Readonly<Record<string, string | undefined>>;
10
+ readonly secretResolver?: SecretResolver;
11
+ }
12
+ type PortalShutdownSignal = 'SIGINT' | 'SIGTERM';
13
+ interface PortalSignalTarget {
14
+ readonly off: (signal: PortalShutdownSignal, listener: () => void) => void;
15
+ readonly once: (signal: PortalShutdownSignal, listener: () => void) => void;
16
+ }
17
+ interface RunningPortalServer {
18
+ readonly close: () => Promise<void>;
19
+ }
20
+ declare function waitUntilPortalServerShutdown(props: {
21
+ readonly server: RunningPortalServer;
22
+ readonly signalTarget?: PortalSignalTarget;
23
+ }): Promise<void>;
24
+ declare function runMcpPortal(args: readonly string[], props?: AgentVmMcpPortalRuntimeProps): Promise<number>;
25
+ declare function shouldRunMcpPortalEntrypoint(argvPath: string | undefined): boolean;
26
+ //#endregion
27
+ export { AgentVmMcpPortalRuntimeProps, PortalCatalogFile, RunningPortalServer, runMcpPortal, shouldRunMcpPortalEntrypoint, waitUntilPortalServerShutdown };
28
+ //# sourceMappingURL=mcp-portal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-portal.d.ts","names":[],"sources":["../../src/bin/mcp-portal.ts"],"mappings":";;;;UAiDiB,iBAAA;EAAA,SACP,KAAA,WAAgB,gBAAA;AAAA;AAAA,UAGT,4BAAA;EAAA,SACP,GAAA,GAAM,QAAA,CAAS,MAAA;EAAA,SACf,cAAA,GAAiB,cAAA;AAAA;AAAA,KAgMtB,oBAAA;AAAA,UACK,kBAAA;EAAA,SACA,GAAA,GAAM,MAAA,EAAQ,oBAAA,EAAsB,QAAA;EAAA,SACpC,IAAA,GAAO,MAAA,EAAQ,oBAAA,EAAsB,QAAA;AAAA;AAAA,UAG9B,mBAAA;EAAA,SACP,KAAA,QAAa,OAAA;AAAA;AAAA,iBAsBD,6BAAA,CAA8B,KAAA;EAAA,SAC1C,MAAA,EAAQ,mBAAA;EAAA,SACR,YAAA,GAAe,kBAAA;AAAA,IACrB,OAAA;AAAA,iBAwHkB,YAAA,CACrB,IAAA,qBACA,KAAA,GAAO,4BAAA,GACL,OAAA;AAAA,iBA2Fa,4BAAA,CAA6B,QAAA"}
@@ -0,0 +1,318 @@
1
+ #!/usr/bin/env node
2
+ import { a as portalToolRecordSchema } from "../zod-schema-loader-yNekKNpm.js";
3
+ import { t as createUpstreamMcpClientRuntime } from "../upstream-mcp-client-runtime-JlsfTm7_.js";
4
+ import { i as resolveUpstreamServers, n as createPortalCore } from "../portal-core-Cgu714CL.js";
5
+ import { t as generateTypescriptCatalogArtifact } from "../typescript-artifact-BVLt3Ifd.js";
6
+ import { n as deriveAgentBearerToken, r as formatMasterKeyFingerprint, t as decodePortalMasterKey } from "../agent-bearer-token-DCtpDPCZ.js";
7
+ import { i as resolveAgentHmacKeys, n as createPortalApprovalVerifier, t as createPortalAgentRuntimeRecords } from "../resolve-agent-identity-DnC_Pmnh.js";
8
+ import { c as resolveSecretValue, i as deriveApprovalHmacKeysFromMasterKey, n as buildProfilePolicyMaps, o as parsePortalServerCliArgs, r as createServeSecretResolver, s as startPortalServer } from "../serve-command-CnSMUybd.js";
9
+ import { t as parseHmacKeysFromEnv } from "../hmac-env-B4shpRRB.js";
10
+ import { z } from "zod";
11
+ import { loadMcpConfig, loadMcpPortalConfig } from "@agent-vm/config-contracts";
12
+ import { basename, join } from "node:path";
13
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
14
+ //#region src/bin/mcp-portal.ts
15
+ const catalogFileSchema = z.object({ tools: z.array(portalToolRecordSchema) }).strict();
16
+ async function readCatalogFile(catalogPath) {
17
+ const rawCatalog = await readFile(catalogPath, "utf-8");
18
+ const parsedJson = JSON.parse(rawCatalog);
19
+ return catalogFileSchema.parse(parsedJson);
20
+ }
21
+ function parseOutputDirectory(args) {
22
+ const outputFlagIndex = args.indexOf("--out");
23
+ if (outputFlagIndex === -1) return null;
24
+ return args[outputFlagIndex + 1] ?? null;
25
+ }
26
+ function printUsage() {
27
+ process.stderr.write("Usage: mcp-portal validate <catalog.json>\n");
28
+ process.stderr.write("Usage: mcp-portal generate-helper <catalog.json> --out <directory>\n");
29
+ process.stderr.write("Usage: mcp-portal mcp-proxy serve --config-dir <directory> [--port <port>]\n");
30
+ process.stderr.write("Usage: mcp-portal call --config-dir <directory> --agent <agent-id> --input <request.json> [--tool <portal-tool-name>]\n");
31
+ process.stderr.write("Usage: mcp-portal mcp-proxy print-client-config --config-dir <directory> --agent <agent-id> --master-key-fingerprint <sha256:...> [--proxy-url <url>]\n");
32
+ }
33
+ function readFlag(args, name) {
34
+ const index = args.indexOf(name);
35
+ if (index === -1) return null;
36
+ return args[index + 1] ?? null;
37
+ }
38
+ function normalizeCredentialProxyUrl(value) {
39
+ const url = new URL(value);
40
+ if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error(`Invalid --proxy-url protocol "${url.protocol}". Expected http or https.`);
41
+ return url.toString();
42
+ }
43
+ async function createCliSecretResolver(props) {
44
+ return props.secretResolver ?? await createServeSecretResolver(props.env);
45
+ }
46
+ function serverNameForClientConfig(agentId) {
47
+ return `mcp-portal-${agentId.replaceAll(/[^A-Za-z0-9_-]/gu, "-")}`;
48
+ }
49
+ function printCredentialMaterialWarning() {
50
+ process.stderr.write([
51
+ "WARNING: MCP Portal client config is bearer credential material.",
52
+ "WARNING: Treat stdout like an API token. Do not paste it into logs, commits, or chat.",
53
+ "WARNING: The token is per-agent and remains valid until credentialVersion or masterKey rotation.",
54
+ ""
55
+ ].join("\n"));
56
+ }
57
+ function printDisabledCredentialWriter() {
58
+ process.stderr.write([
59
+ "mcp-portal: mcp-proxy write-credential is disabled because it persists bearer credentials.",
60
+ "Use mcp-portal mcp-proxy print-client-config and decide explicitly where stdout is stored.",
61
+ ""
62
+ ].join("\n"));
63
+ return 1;
64
+ }
65
+ async function printClientConfig(args, runtimeProps) {
66
+ const configDir = readFlag(args, "--config-dir");
67
+ const agentId = readFlag(args, "--agent");
68
+ const expectedFingerprint = readFlag(args, "--master-key-fingerprint");
69
+ const proxyUrlOverride = readFlag(args, "--proxy-url");
70
+ if (configDir === null || agentId === null || expectedFingerprint === null) {
71
+ printUsage();
72
+ return 1;
73
+ }
74
+ const portalConfig = await loadMcpPortalConfig(join(configDir, "mcp-portal.config.jsonc"));
75
+ if (portalConfig.externalAuth === void 0) throw new Error("print-client-config requires externalAuth.masterKey.");
76
+ if (portalConfig.mcpProxy === void 0 && proxyUrlOverride === null) throw new Error("print-client-config requires mcpProxy server settings or --proxy-url.");
77
+ if (portalConfig.agents[agentId] === void 0) throw new Error(`Unknown MCP Portal agent "${agentId}".`);
78
+ const secretResolver = await createCliSecretResolver(runtimeProps);
79
+ const masterKey = decodePortalMasterKey(await resolveSecretValue(portalConfig.externalAuth.masterKey, {
80
+ env: runtimeProps.env,
81
+ secretResolver
82
+ }));
83
+ const actualFingerprint = formatMasterKeyFingerprint(masterKey);
84
+ if (actualFingerprint !== expectedFingerprint) throw new Error(`Master-key fingerprint mismatch. Expected ${expectedFingerprint}; resolved ${actualFingerprint}.`);
85
+ const agentConfig = portalConfig.agents[agentId];
86
+ const bearer = deriveAgentBearerToken({
87
+ agentId,
88
+ credentialVersion: agentConfig.credentialVersion,
89
+ masterKey
90
+ });
91
+ const proxyUrl = proxyUrlOverride === null ? credentialProxyUrlFromConfig(requireCredentialMcpProxy(portalConfig.mcpProxy), agentId) : normalizeCredentialProxyUrl(proxyUrlOverride);
92
+ const authorizationHeaderName = portalConfig.mcpProxy?.auth.headerName ?? "authorization";
93
+ const authorizationHeaderValue = `Bearer ${bearer}`;
94
+ const clientConfig = {
95
+ agentId,
96
+ authorizationHeaderName,
97
+ authorizationHeaderValue,
98
+ kind: "mcp-portal-client-config",
99
+ masterKeyFingerprint: actualFingerprint,
100
+ mcpServers: { [serverNameForClientConfig(agentId)]: {
101
+ headers: { [authorizationHeaderName]: authorizationHeaderValue },
102
+ type: "streamable-http",
103
+ url: proxyUrl
104
+ } },
105
+ proxyUrl,
106
+ schemaVersion: 1
107
+ };
108
+ printCredentialMaterialWarning();
109
+ process.stdout.write(`${JSON.stringify(clientConfig, null, " ")}\n`);
110
+ return 0;
111
+ }
112
+ function requireCredentialMcpProxy(mcpProxy) {
113
+ if (mcpProxy === void 0) throw new Error("print-client-config requires mcpProxy server settings or --proxy-url.");
114
+ return mcpProxy;
115
+ }
116
+ function credentialProxyUrlFromConfig(mcpProxy, agentId) {
117
+ return `http://${mcpProxy.server.host.includes(":") ? `[${mcpProxy.server.host.replace(/^\[|\]$/gu, "")}]` : mcpProxy.server.host}:${String(mcpProxy.server.port)}/agents/${encodeURIComponent(agentId)}/mcp`;
118
+ }
119
+ const portalCoreToolNames = new Set([
120
+ "mcp_portal_list",
121
+ "mcp_portal_search",
122
+ "mcp_portal_describe",
123
+ "mcp_portal_call"
124
+ ]);
125
+ function waitForPortalShutdownSignal(signalTarget = process) {
126
+ const signals = ["SIGINT", "SIGTERM"];
127
+ return new Promise((resolve) => {
128
+ const listeners = /* @__PURE__ */ new Map();
129
+ for (const signal of signals) {
130
+ const listener = () => {
131
+ for (const [registeredSignal, registeredListener] of listeners) signalTarget.off(registeredSignal, registeredListener);
132
+ resolve(signal);
133
+ };
134
+ listeners.set(signal, listener);
135
+ signalTarget.once(signal, listener);
136
+ }
137
+ });
138
+ }
139
+ async function waitUntilPortalServerShutdown(props) {
140
+ try {
141
+ await waitForPortalShutdownSignal(props.signalTarget);
142
+ } finally {
143
+ await props.server.close();
144
+ }
145
+ }
146
+ function isPortalCoreToolName(value) {
147
+ return portalCoreToolNames.has(value);
148
+ }
149
+ function parsePortalCoreToolName(value) {
150
+ const toolName = value ?? "mcp_portal_call";
151
+ if (!isPortalCoreToolName(toolName)) throw new Error(`Unknown MCP Portal tool "${toolName}".`);
152
+ return toolName;
153
+ }
154
+ function writePortalCoreEventToStderr(event) {
155
+ if (event.kind === "progress" && event.message !== void 0) {
156
+ process.stderr.write(`${event.message}\n`);
157
+ return;
158
+ }
159
+ if (event.kind === "partial_content") {
160
+ const message = event.content.type === "text" ? event.content.text : JSON.stringify(event.content.value);
161
+ process.stderr.write(`${message}\n`);
162
+ return;
163
+ }
164
+ if (event.kind === "upstream_notification") process.stderr.write(`upstream notification ${event.method}\n`);
165
+ }
166
+ async function resolveCliApprovalHmacKeys(props) {
167
+ if (props.portalConfig.externalAuth !== void 0) {
168
+ const masterKey = decodePortalMasterKey(await props.resolveSecret(props.portalConfig.externalAuth.masterKey));
169
+ return deriveApprovalHmacKeysFromMasterKey({
170
+ agentIds: props.agentIds,
171
+ masterKey
172
+ });
173
+ }
174
+ return await resolveAgentHmacKeys({
175
+ agents: props.portalConfig.agents,
176
+ envKeys: parseHmacKeysFromEnv(props.env),
177
+ resolveSecret: props.resolveSecret
178
+ });
179
+ }
180
+ async function runCallCommand(args, runtimeProps) {
181
+ const configDir = readFlag(args, "--config-dir");
182
+ const agentId = readFlag(args, "--agent");
183
+ const inputPath = readFlag(args, "--input");
184
+ if (configDir === null || agentId === null || inputPath === null) {
185
+ printUsage();
186
+ return 1;
187
+ }
188
+ const toolName = parsePortalCoreToolName(readFlag(args, "--tool"));
189
+ const input = JSON.parse(await readFile(inputPath, "utf8"));
190
+ const secretResolver = await createCliSecretResolver(runtimeProps);
191
+ const resolveSecret = (secret) => resolveSecretValue(secret, {
192
+ env: runtimeProps.env,
193
+ secretResolver
194
+ });
195
+ const [mcpConfig, portalConfig] = await Promise.all([loadMcpConfig(join(configDir, "mcp.config.jsonc")), loadMcpPortalConfig(join(configDir, "mcp-portal.config.jsonc"))]);
196
+ if (portalConfig.agents[agentId] === void 0) throw new Error(`Unknown MCP Portal agent "${agentId}".`);
197
+ const verifyApproval = createPortalApprovalVerifier({ records: createPortalAgentRuntimeRecords({
198
+ hmacKeys: await resolveCliApprovalHmacKeys({
199
+ agentIds: Object.keys(portalConfig.agents),
200
+ env: runtimeProps.env,
201
+ portalConfig,
202
+ resolveSecret
203
+ }),
204
+ portalConfig
205
+ }) });
206
+ const upstreamServers = await resolveUpstreamServers({
207
+ config: mcpConfig,
208
+ resolveSecret
209
+ });
210
+ const upstreamRuntime = createUpstreamMcpClientRuntime({ servers: upstreamServers });
211
+ const profilePolicyMaps = buildProfilePolicyMaps(portalConfig);
212
+ const core = createPortalCore({
213
+ accessPolicy: {
214
+ defaultPolicy: "deny-all",
215
+ enabledNamespacesByAgent: profilePolicyMaps.enabledNamespacesByAgent,
216
+ enabledToolsByAgent: profilePolicyMaps.enabledToolsByAgent,
217
+ hiddenToolsByAgent: profilePolicyMaps.hiddenToolsByAgent
218
+ },
219
+ approval: (calls, scope, approvalToken) => verifyApproval(calls, scope.agentId, approvalToken),
220
+ catalogTtlMs: profilePolicyMaps.cacheTtlMs,
221
+ runtime: {
222
+ ...upstreamRuntime,
223
+ callUpstreamTool: upstreamRuntime.callTool
224
+ },
225
+ upstreamNamespaces: upstreamServers.map((server) => server.namespace)
226
+ });
227
+ try {
228
+ const scope = core.createAgentScope({
229
+ agentId,
230
+ agentScopeId: agentId,
231
+ source: "cli-operator"
232
+ });
233
+ const result = await core.collectPortalCoreResult(core.callStream({
234
+ input,
235
+ scope,
236
+ toolName
237
+ }), { onEvent: writePortalCoreEventToStderr });
238
+ process.stdout.write(`${JSON.stringify(result, null, " ")}\n`);
239
+ return 0;
240
+ } finally {
241
+ await core.close();
242
+ }
243
+ }
244
+ async function runMcpPortal(args, props = {}) {
245
+ const [command, catalogPath, ...restArgs] = args;
246
+ const runtimeProps = {
247
+ env: props.env ?? process.env,
248
+ ...props.secretResolver !== void 0 ? { secretResolver: props.secretResolver } : {}
249
+ };
250
+ if (!command) {
251
+ printUsage();
252
+ return 1;
253
+ }
254
+ try {
255
+ if (command === "mcp-proxy") {
256
+ const [mcpProxyCommand, ...mcpProxyArgs] = args.slice(1);
257
+ if (mcpProxyCommand === "serve") {
258
+ const injectedSecretResolver = runtimeProps.secretResolver;
259
+ await waitUntilPortalServerShutdown({ server: await startPortalServer({
260
+ args: parsePortalServerCliArgs(mcpProxyArgs),
261
+ env: runtimeProps.env,
262
+ ...injectedSecretResolver !== void 0 ? { resolveSecret: (secret) => resolveSecretValue(secret, {
263
+ env: runtimeProps.env,
264
+ secretResolver: injectedSecretResolver
265
+ }) } : {}
266
+ }) });
267
+ return 0;
268
+ }
269
+ if (mcpProxyCommand === "write-credential") return printDisabledCredentialWriter();
270
+ if (mcpProxyCommand === "print-client-config") return await printClientConfig(mcpProxyArgs, runtimeProps);
271
+ printUsage();
272
+ return 1;
273
+ }
274
+ if (command === "serve") {
275
+ printUsage();
276
+ return 1;
277
+ }
278
+ if (command === "write-credential") {
279
+ printUsage();
280
+ return 1;
281
+ }
282
+ if (command === "call") return await runCallCommand(args.slice(1), runtimeProps);
283
+ if (!catalogPath) {
284
+ printUsage();
285
+ return 1;
286
+ }
287
+ const catalog = await readCatalogFile(catalogPath);
288
+ switch (command) {
289
+ case "validate": return 0;
290
+ case "generate-helper": {
291
+ const outputDirectory = parseOutputDirectory(restArgs);
292
+ if (!outputDirectory) {
293
+ printUsage();
294
+ return 1;
295
+ }
296
+ await mkdir(outputDirectory, { recursive: true });
297
+ await writeFile(join(outputDirectory, "catalog.json"), JSON.stringify(catalog, null, " "));
298
+ await writeFile(join(outputDirectory, "catalog.ts"), generateTypescriptCatalogArtifact(catalog));
299
+ return 0;
300
+ }
301
+ default:
302
+ printUsage();
303
+ return 1;
304
+ }
305
+ } catch (error) {
306
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
307
+ return 1;
308
+ }
309
+ }
310
+ function shouldRunMcpPortalEntrypoint(argvPath) {
311
+ const entrypointName = argvPath === void 0 ? void 0 : basename(argvPath);
312
+ return entrypointName === "mcp-portal" || entrypointName === "mcp-portal.js" || entrypointName === "mcp-portal.ts";
313
+ }
314
+ if (shouldRunMcpPortalEntrypoint(process.argv[1])) process.exitCode = await runMcpPortal(process.argv.slice(2));
315
+ //#endregion
316
+ export { runMcpPortal, shouldRunMcpPortalEntrypoint, waitUntilPortalServerShutdown };
317
+
318
+ //# sourceMappingURL=mcp-portal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-portal.js","names":[],"sources":["../../src/bin/mcp-portal.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\n\nimport {\n\tloadMcpConfig,\n\tloadMcpPortalConfig,\n\ttype McpPortalConfig,\n\ttype SecretValue,\n} from '@agent-vm/config-contracts';\nimport type { SecretResolver } from '@agent-vm/secrets';\nimport { z } from 'zod';\n\nimport { portalToolRecordSchema, type PortalToolRecord } from '../catalog-types.js';\nimport {\n\tbuildProfilePolicyMaps,\n\tcreateServeSecretResolver,\n\tderiveApprovalHmacKeysFromMasterKey,\n\tparsePortalServerCliArgs,\n\tstartPortalServer,\n} from '../cli/serve-command.js';\nimport {\n\tcreatePortalCore,\n\ttype PortalCoreEvent,\n\ttype PortalCoreToolName,\n} from '../core/portal-core.js';\nimport { resolveUpstreamServers } from '../core/provider-runtime.js';\nimport {\n\tcreatePortalAgentRuntimeRecords,\n\tcreatePortalApprovalVerifier,\n\tresolveAgentHmacKeys,\n} from '../mcp-proxy/resolve-agent-identity.js';\nimport {\n\tdecodePortalMasterKey,\n\tderiveAgentBearerToken,\n\tformatMasterKeyFingerprint,\n} from '../portal-auth/agent-bearer-token.js';\nimport { parseHmacKeysFromEnv } from '../portal-auth/hmac-env.js';\nimport { generateTypescriptCatalogArtifact } from '../portal-config/typescript-artifact.js';\nimport { createUpstreamMcpClientRuntime } from '../upstream-mcp-client-runtime.js';\nimport { resolveSecretValue } from './secret-value-resolver.js';\n\nconst catalogFileSchema = z\n\t.object({\n\t\ttools: z.array(portalToolRecordSchema),\n\t})\n\t.strict();\n\nexport interface PortalCatalogFile {\n\treadonly tools: readonly PortalToolRecord[];\n}\n\nexport interface AgentVmMcpPortalRuntimeProps {\n\treadonly env?: Readonly<Record<string, string | undefined>>;\n\treadonly secretResolver?: SecretResolver;\n}\n\nasync function readCatalogFile(catalogPath: string): Promise<PortalCatalogFile> {\n\tconst rawCatalog = await readFile(catalogPath, 'utf-8');\n\tconst parsedJson = JSON.parse(rawCatalog) as unknown;\n\treturn catalogFileSchema.parse(parsedJson);\n}\n\nfunction parseOutputDirectory(args: readonly string[]): string | null {\n\tconst outputFlagIndex = args.indexOf('--out');\n\tif (outputFlagIndex === -1) {\n\t\treturn null;\n\t}\n\n\treturn args[outputFlagIndex + 1] ?? null;\n}\n\nfunction printUsage(): void {\n\tprocess.stderr.write('Usage: mcp-portal validate <catalog.json>\\n');\n\tprocess.stderr.write('Usage: mcp-portal generate-helper <catalog.json> --out <directory>\\n');\n\tprocess.stderr.write(\n\t\t'Usage: mcp-portal mcp-proxy serve --config-dir <directory> [--port <port>]\\n',\n\t);\n\tprocess.stderr.write(\n\t\t'Usage: mcp-portal call --config-dir <directory> --agent <agent-id> --input <request.json> [--tool <portal-tool-name>]\\n',\n\t);\n\tprocess.stderr.write(\n\t\t'Usage: mcp-portal mcp-proxy print-client-config --config-dir <directory> --agent <agent-id> --master-key-fingerprint <sha256:...> [--proxy-url <url>]\\n',\n\t);\n}\n\nfunction readFlag(args: readonly string[], name: string): string | null {\n\tconst index = args.indexOf(name);\n\tif (index === -1) {\n\t\treturn null;\n\t}\n\treturn args[index + 1] ?? null;\n}\n\nfunction normalizeCredentialProxyUrl(value: string): string {\n\tconst url = new URL(value);\n\tif (url.protocol !== 'http:' && url.protocol !== 'https:') {\n\t\tthrow new Error(`Invalid --proxy-url protocol \"${url.protocol}\". Expected http or https.`);\n\t}\n\treturn url.toString();\n}\n\ntype RequiredPortalRuntimeProps = Required<Pick<AgentVmMcpPortalRuntimeProps, 'env'>> &\n\tPick<AgentVmMcpPortalRuntimeProps, 'secretResolver'>;\n\nasync function createCliSecretResolver(props: RequiredPortalRuntimeProps): Promise<SecretResolver> {\n\treturn props.secretResolver ?? (await createServeSecretResolver(props.env));\n}\n\ninterface McpPortalClientConfigServer {\n\treadonly headers: Readonly<Record<string, string>>;\n\treadonly type: 'streamable-http';\n\treadonly url: string;\n}\n\ninterface McpPortalClientConfig {\n\treadonly agentId: string;\n\treadonly authorizationHeaderName: string;\n\treadonly authorizationHeaderValue: string;\n\treadonly kind: 'mcp-portal-client-config';\n\treadonly masterKeyFingerprint: string;\n\treadonly mcpServers: Readonly<Record<string, McpPortalClientConfigServer>>;\n\treadonly proxyUrl: string;\n\treadonly schemaVersion: 1;\n}\n\nfunction serverNameForClientConfig(agentId: string): string {\n\treturn `mcp-portal-${agentId.replaceAll(/[^A-Za-z0-9_-]/gu, '-')}`;\n}\n\nfunction printCredentialMaterialWarning(): void {\n\tprocess.stderr.write(\n\t\t[\n\t\t\t'WARNING: MCP Portal client config is bearer credential material.',\n\t\t\t'WARNING: Treat stdout like an API token. Do not paste it into logs, commits, or chat.',\n\t\t\t'WARNING: The token is per-agent and remains valid until credentialVersion or masterKey rotation.',\n\t\t\t'',\n\t\t].join('\\n'),\n\t);\n}\n\nfunction printDisabledCredentialWriter(): number {\n\tprocess.stderr.write(\n\t\t[\n\t\t\t'mcp-portal: mcp-proxy write-credential is disabled because it persists bearer credentials.',\n\t\t\t'Use mcp-portal mcp-proxy print-client-config and decide explicitly where stdout is stored.',\n\t\t\t'',\n\t\t].join('\\n'),\n\t);\n\treturn 1;\n}\n\nasync function printClientConfig(\n\targs: readonly string[],\n\truntimeProps: RequiredPortalRuntimeProps,\n): Promise<number> {\n\tconst configDir = readFlag(args, '--config-dir');\n\tconst agentId = readFlag(args, '--agent');\n\tconst expectedFingerprint = readFlag(args, '--master-key-fingerprint');\n\tconst proxyUrlOverride = readFlag(args, '--proxy-url');\n\tif (configDir === null || agentId === null || expectedFingerprint === null) {\n\t\tprintUsage();\n\t\treturn 1;\n\t}\n\tconst portalConfig = await loadMcpPortalConfig(join(configDir, 'mcp-portal.config.jsonc'));\n\tif (portalConfig.externalAuth === undefined) {\n\t\tthrow new Error('print-client-config requires externalAuth.masterKey.');\n\t}\n\tif (portalConfig.mcpProxy === undefined && proxyUrlOverride === null) {\n\t\tthrow new Error('print-client-config requires mcpProxy server settings or --proxy-url.');\n\t}\n\tif (portalConfig.agents[agentId] === undefined) {\n\t\tthrow new Error(`Unknown MCP Portal agent \"${agentId}\".`);\n\t}\n\tconst secretResolver = await createCliSecretResolver(runtimeProps);\n\tconst masterKey = decodePortalMasterKey(\n\t\tawait resolveSecretValue(portalConfig.externalAuth.masterKey, {\n\t\t\tenv: runtimeProps.env,\n\t\t\tsecretResolver,\n\t\t}),\n\t);\n\tconst actualFingerprint = formatMasterKeyFingerprint(masterKey);\n\tif (actualFingerprint !== expectedFingerprint) {\n\t\tthrow new Error(\n\t\t\t`Master-key fingerprint mismatch. Expected ${expectedFingerprint}; resolved ${actualFingerprint}.`,\n\t\t);\n\t}\n\tconst agentConfig = portalConfig.agents[agentId];\n\tconst bearer = deriveAgentBearerToken({\n\t\tagentId,\n\t\tcredentialVersion: agentConfig.credentialVersion,\n\t\tmasterKey,\n\t});\n\tconst proxyUrl =\n\t\tproxyUrlOverride === null\n\t\t\t? credentialProxyUrlFromConfig(requireCredentialMcpProxy(portalConfig.mcpProxy), agentId)\n\t\t\t: normalizeCredentialProxyUrl(proxyUrlOverride);\n\tconst authorizationHeaderName = portalConfig.mcpProxy?.auth.headerName ?? 'authorization';\n\tconst authorizationHeaderValue = `Bearer ${bearer}`;\n\tconst clientConfig = {\n\t\tagentId,\n\t\tauthorizationHeaderName,\n\t\tauthorizationHeaderValue,\n\t\tkind: 'mcp-portal-client-config',\n\t\tmasterKeyFingerprint: actualFingerprint,\n\t\tmcpServers: {\n\t\t\t[serverNameForClientConfig(agentId)]: {\n\t\t\t\theaders: { [authorizationHeaderName]: authorizationHeaderValue },\n\t\t\t\ttype: 'streamable-http',\n\t\t\t\turl: proxyUrl,\n\t\t\t},\n\t\t},\n\t\tproxyUrl,\n\t\tschemaVersion: 1,\n\t} satisfies McpPortalClientConfig;\n\tprintCredentialMaterialWarning();\n\tprocess.stdout.write(`${JSON.stringify(clientConfig, null, '\\t')}\\n`);\n\treturn 0;\n}\n\nfunction requireCredentialMcpProxy(\n\tmcpProxy: McpPortalConfig['mcpProxy'],\n): NonNullable<McpPortalConfig['mcpProxy']> {\n\tif (mcpProxy === undefined) {\n\t\tthrow new Error('print-client-config requires mcpProxy server settings or --proxy-url.');\n\t}\n\treturn mcpProxy;\n}\n\nfunction credentialProxyUrlFromConfig(\n\tmcpProxy: NonNullable<McpPortalConfig['mcpProxy']>,\n\tagentId: string,\n): string {\n\tconst host = mcpProxy.server.host.includes(':')\n\t\t? `[${mcpProxy.server.host.replace(/^\\[|\\]$/gu, '')}]`\n\t\t: mcpProxy.server.host;\n\treturn `http://${host}:${String(mcpProxy.server.port)}/agents/${encodeURIComponent(agentId)}/mcp`;\n}\n\nconst portalCoreToolNames = new Set<string>([\n\t'mcp_portal_list',\n\t'mcp_portal_search',\n\t'mcp_portal_describe',\n\t'mcp_portal_call',\n]);\n\ntype PortalShutdownSignal = 'SIGINT' | 'SIGTERM';\ninterface PortalSignalTarget {\n\treadonly off: (signal: PortalShutdownSignal, listener: () => void) => void;\n\treadonly once: (signal: PortalShutdownSignal, listener: () => void) => void;\n}\n\nexport interface RunningPortalServer {\n\treadonly close: () => Promise<void>;\n}\n\nfunction waitForPortalShutdownSignal(\n\tsignalTarget: PortalSignalTarget = process,\n): Promise<PortalShutdownSignal> {\n\tconst signals = ['SIGINT', 'SIGTERM'] satisfies readonly PortalShutdownSignal[];\n\treturn new Promise((resolve) => {\n\t\tconst listeners = new Map<PortalShutdownSignal, () => void>();\n\t\tfor (const signal of signals) {\n\t\t\tconst listener = (): void => {\n\t\t\t\tfor (const [registeredSignal, registeredListener] of listeners) {\n\t\t\t\t\tsignalTarget.off(registeredSignal, registeredListener);\n\t\t\t\t}\n\t\t\t\tresolve(signal);\n\t\t\t};\n\t\t\tlisteners.set(signal, listener);\n\t\t\tsignalTarget.once(signal, listener);\n\t\t}\n\t});\n}\n\nexport async function waitUntilPortalServerShutdown(props: {\n\treadonly server: RunningPortalServer;\n\treadonly signalTarget?: PortalSignalTarget;\n}): Promise<void> {\n\ttry {\n\t\tawait waitForPortalShutdownSignal(props.signalTarget);\n\t} finally {\n\t\tawait props.server.close();\n\t}\n}\n\nfunction isPortalCoreToolName(value: string): value is PortalCoreToolName {\n\treturn portalCoreToolNames.has(value);\n}\n\nfunction parsePortalCoreToolName(value: string | null): PortalCoreToolName {\n\tconst toolName = value ?? 'mcp_portal_call';\n\tif (!isPortalCoreToolName(toolName)) {\n\t\tthrow new Error(`Unknown MCP Portal tool \"${toolName}\".`);\n\t}\n\treturn toolName;\n}\n\nfunction writePortalCoreEventToStderr(event: PortalCoreEvent): void {\n\tif (event.kind === 'progress' && event.message !== undefined) {\n\t\tprocess.stderr.write(`${event.message}\\n`);\n\t\treturn;\n\t}\n\tif (event.kind === 'partial_content') {\n\t\tconst message =\n\t\t\tevent.content.type === 'text' ? event.content.text : JSON.stringify(event.content.value);\n\t\tprocess.stderr.write(`${message}\\n`);\n\t\treturn;\n\t}\n\tif (event.kind === 'upstream_notification') {\n\t\tprocess.stderr.write(`upstream notification ${event.method}\\n`);\n\t}\n}\n\nasync function resolveCliApprovalHmacKeys(props: {\n\treadonly agentIds: readonly string[];\n\treadonly env: Readonly<Record<string, string | undefined>>;\n\treadonly portalConfig: Awaited<ReturnType<typeof loadMcpPortalConfig>>;\n\treadonly resolveSecret: (secret: SecretValue) => Promise<string>;\n}): Promise<ReadonlyMap<string, Buffer>> {\n\tif (props.portalConfig.externalAuth !== undefined) {\n\t\tconst masterKey = decodePortalMasterKey(\n\t\t\tawait props.resolveSecret(props.portalConfig.externalAuth.masterKey),\n\t\t);\n\t\treturn deriveApprovalHmacKeysFromMasterKey({ agentIds: props.agentIds, masterKey });\n\t}\n\treturn await resolveAgentHmacKeys({\n\t\tagents: props.portalConfig.agents,\n\t\tenvKeys: parseHmacKeysFromEnv(props.env),\n\t\tresolveSecret: props.resolveSecret,\n\t});\n}\n\nasync function runCallCommand(\n\targs: readonly string[],\n\truntimeProps: RequiredPortalRuntimeProps,\n): Promise<number> {\n\tconst configDir = readFlag(args, '--config-dir');\n\tconst agentId = readFlag(args, '--agent');\n\tconst inputPath = readFlag(args, '--input');\n\tif (configDir === null || agentId === null || inputPath === null) {\n\t\tprintUsage();\n\t\treturn 1;\n\t}\n\tconst toolName = parsePortalCoreToolName(readFlag(args, '--tool'));\n\tconst input = JSON.parse(await readFile(inputPath, 'utf8')) as unknown;\n\tconst secretResolver = await createCliSecretResolver(runtimeProps);\n\tconst resolveSecret = (secret: SecretValue): Promise<string> =>\n\t\tresolveSecretValue(secret, { env: runtimeProps.env, secretResolver });\n\tconst [mcpConfig, portalConfig] = await Promise.all([\n\t\tloadMcpConfig(join(configDir, 'mcp.config.jsonc')),\n\t\tloadMcpPortalConfig(join(configDir, 'mcp-portal.config.jsonc')),\n\t]);\n\tif (portalConfig.agents[agentId] === undefined) {\n\t\tthrow new Error(`Unknown MCP Portal agent \"${agentId}\".`);\n\t}\n\tconst hmacKeys = await resolveCliApprovalHmacKeys({\n\t\tagentIds: Object.keys(portalConfig.agents),\n\t\tenv: runtimeProps.env,\n\t\tportalConfig,\n\t\tresolveSecret,\n\t});\n\tconst agentRecords = createPortalAgentRuntimeRecords({ hmacKeys, portalConfig });\n\tconst verifyApproval = createPortalApprovalVerifier({ records: agentRecords });\n\tconst upstreamServers = await resolveUpstreamServers({ config: mcpConfig, resolveSecret });\n\tconst upstreamRuntime = createUpstreamMcpClientRuntime({ servers: upstreamServers });\n\tconst profilePolicyMaps = buildProfilePolicyMaps(portalConfig);\n\tconst core = createPortalCore({\n\t\taccessPolicy: {\n\t\t\tdefaultPolicy: 'deny-all',\n\t\t\tenabledNamespacesByAgent: profilePolicyMaps.enabledNamespacesByAgent,\n\t\t\tenabledToolsByAgent: profilePolicyMaps.enabledToolsByAgent,\n\t\t\thiddenToolsByAgent: profilePolicyMaps.hiddenToolsByAgent,\n\t\t},\n\t\tapproval: (calls, scope, approvalToken) => verifyApproval(calls, scope.agentId, approvalToken),\n\t\tcatalogTtlMs: profilePolicyMaps.cacheTtlMs,\n\t\truntime: {\n\t\t\t...upstreamRuntime,\n\t\t\tcallUpstreamTool: upstreamRuntime.callTool,\n\t\t},\n\t\tupstreamNamespaces: upstreamServers.map((server) => server.namespace),\n\t});\n\ttry {\n\t\tconst scope = core.createAgentScope({\n\t\t\tagentId,\n\t\t\tagentScopeId: agentId,\n\t\t\tsource: 'cli-operator',\n\t\t});\n\t\tconst result = await core.collectPortalCoreResult(core.callStream({ input, scope, toolName }), {\n\t\t\tonEvent: writePortalCoreEventToStderr,\n\t\t});\n\t\tprocess.stdout.write(`${JSON.stringify(result, null, '\\t')}\\n`);\n\t\treturn 0;\n\t} finally {\n\t\tawait core.close();\n\t}\n}\n\nexport async function runMcpPortal(\n\targs: readonly string[],\n\tprops: AgentVmMcpPortalRuntimeProps = {},\n): Promise<number> {\n\tconst [command, catalogPath, ...restArgs] = args;\n\tconst runtimeProps = {\n\t\tenv: props.env ?? process.env,\n\t\t...(props.secretResolver !== undefined ? { secretResolver: props.secretResolver } : {}),\n\t};\n\tif (!command) {\n\t\tprintUsage();\n\t\treturn 1;\n\t}\n\n\ttry {\n\t\tif (command === 'mcp-proxy') {\n\t\t\tconst [mcpProxyCommand, ...mcpProxyArgs] = args.slice(1);\n\t\t\tif (mcpProxyCommand === 'serve') {\n\t\t\t\tconst injectedSecretResolver = runtimeProps.secretResolver;\n\t\t\t\tconst server = await startPortalServer({\n\t\t\t\t\targs: parsePortalServerCliArgs(mcpProxyArgs),\n\t\t\t\t\tenv: runtimeProps.env,\n\t\t\t\t\t...(injectedSecretResolver !== undefined\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tresolveSecret: (secret) =>\n\t\t\t\t\t\t\t\t\tresolveSecretValue(secret, {\n\t\t\t\t\t\t\t\t\t\tenv: runtimeProps.env,\n\t\t\t\t\t\t\t\t\t\tsecretResolver: injectedSecretResolver,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {}),\n\t\t\t\t});\n\t\t\t\tawait waitUntilPortalServerShutdown({ server });\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (mcpProxyCommand === 'write-credential') {\n\t\t\t\treturn printDisabledCredentialWriter();\n\t\t\t}\n\t\t\tif (mcpProxyCommand === 'print-client-config') {\n\t\t\t\treturn await printClientConfig(mcpProxyArgs, runtimeProps);\n\t\t\t}\n\t\t\tprintUsage();\n\t\t\treturn 1;\n\t\t}\n\t\tif (command === 'serve') {\n\t\t\tprintUsage();\n\t\t\treturn 1;\n\t\t}\n\t\tif (command === 'write-credential') {\n\t\t\tprintUsage();\n\t\t\treturn 1;\n\t\t}\n\t\tif (command === 'call') {\n\t\t\treturn await runCallCommand(args.slice(1), runtimeProps);\n\t\t}\n\t\tif (!catalogPath) {\n\t\t\tprintUsage();\n\t\t\treturn 1;\n\t\t}\n\t\tconst catalog = await readCatalogFile(catalogPath);\n\t\tswitch (command) {\n\t\t\tcase 'validate':\n\t\t\t\treturn 0;\n\t\t\tcase 'generate-helper': {\n\t\t\t\tconst outputDirectory = parseOutputDirectory(restArgs);\n\t\t\t\tif (!outputDirectory) {\n\t\t\t\t\tprintUsage();\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\n\t\t\t\tawait mkdir(outputDirectory, { recursive: true });\n\t\t\t\tawait writeFile(join(outputDirectory, 'catalog.json'), JSON.stringify(catalog, null, '\\t'));\n\t\t\t\tawait writeFile(\n\t\t\t\t\tjoin(outputDirectory, 'catalog.ts'),\n\t\t\t\t\tgenerateTypescriptCatalogArtifact(catalog),\n\t\t\t\t);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tprintUsage();\n\t\t\t\treturn 1;\n\t\t}\n\t} catch (error) {\n\t\tprocess.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n\t\treturn 1;\n\t}\n}\n\n/*\n * Command-shape note: top-level `serve` and credential commands are\n * intentionally rejected. The public CLI shape is `mcp-portal mcp-proxy ...`\n * so the command mirrors the library adapter boundary.\n */\n\nexport function shouldRunMcpPortalEntrypoint(argvPath: string | undefined): boolean {\n\tconst entrypointName = argvPath === undefined ? undefined : basename(argvPath);\n\treturn (\n\t\tentrypointName === 'mcp-portal' ||\n\t\tentrypointName === 'mcp-portal.js' ||\n\t\tentrypointName === 'mcp-portal.ts'\n\t);\n}\n\nif (shouldRunMcpPortalEntrypoint(process.argv[1])) {\n\tprocess.exitCode = await runMcpPortal(process.argv.slice(2));\n}\n"],"mappings":"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"}
@@ -41,4 +41,4 @@ type PortalToolRecord = z.infer<typeof portalToolRecordSchema>;
41
41
  type PortalToolAnnotations = z.infer<typeof portalToolAnnotationsSchema>;
42
42
  //#endregion
43
43
  export { safeToolMetadataSchema as a, JsonPrimitive as c, isJsonObject as d, jsonObjectSchema as f, portalToolRecordSchema as i, JsonValue as l, PortalToolRecord as n, JsonArray as o, jsonValueSchema as p, portalToolAnnotationsSchema as r, JsonObject as s, PortalToolAnnotations as t, assertJsonObject as u };
44
- //# sourceMappingURL=catalog-types--gUGFPpN.d.ts.map
44
+ //# sourceMappingURL=catalog-types-BVuB4Ynx.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-types--gUGFPpN.d.ts","names":[],"sources":["../src/json-schema.ts","../src/catalog-types.ts"],"mappings":";;;KAEY,aAAA;AAAA,KACA,SAAA,GAAY,SAAA;AAAA,KACZ,UAAA;EAAA,CAAgB,GAAA,WAAc,SAAA;AAAA;AAAA,KAC9B,SAAA,GAAY,SAAA,GAAY,UAAA,GAAa,aAAA;AAAA,cAEpC,eAAA,EAAiB,CAAA,CAAE,OAAA,CAAQ,SAAA;AAAA,cAW3B,gBAAA,EAAkB,CAAA,CAAE,OAAA,CAAQ,UAAA;AAAA,iBAEzB,YAAA,CAAa,KAAA,YAAiB,KAAA,IAAS,UAAA;AAAA,iBAIvC,gBAAA,CAAiB,KAAA,WAAgB,KAAA,WAAgB,UAAA;;;cCmBpD,2BAAA,EAA2B,CAAA,CAAA,WAAA,CAAA,CAAA,CAAA,SAAA;;;;;;;cAW3B,sBAAA,EAAsB,CAAA,CAAA,WAAA,CAAA,CAAA,CAAA,OAAA,CAAA,UAAA,WAAA,CAAA,CAAA,IAAA,CAAA,iBAAA,CAAA,UAAA;AAAA,cAgBtB,sBAAA,EAAsB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;KAavB,gBAAA,GAAmB,CAAA,CAAE,KAAA,QAAa,sBAAA;AAAA,KAClC,qBAAA,GAAwB,CAAA,CAAE,KAAA,QAAa,2BAAA"}
1
+ {"version":3,"file":"catalog-types-BVuB4Ynx.d.ts","names":[],"sources":["../src/json-schema.ts","../src/catalog-types.ts"],"mappings":";;;KAEY,aAAA;AAAA,KACA,SAAA,GAAY,SAAA;AAAA,KACZ,UAAA;EAAA,CAAgB,GAAA,WAAc,SAAA;AAAA;AAAA,KAC9B,SAAA,GAAY,SAAA,GAAY,UAAA,GAAa,aAAA;AAAA,cAEpC,eAAA,EAAiB,CAAA,CAAE,OAAA,CAAQ,SAAA;AAAA,cAW3B,gBAAA,EAAkB,CAAA,CAAE,OAAA,CAAQ,UAAA;AAAA,iBAEzB,YAAA,CAAa,KAAA,YAAiB,KAAA,IAAS,UAAA;AAAA,iBAIvC,gBAAA,CAAiB,KAAA,WAAgB,KAAA,WAAgB,UAAA;;;cCmBpD,2BAAA,EAA2B,CAAA,CAAA,WAAA,CAAA,CAAA,CAAA,SAAA;;;;;;;cAW3B,sBAAA,EAAsB,CAAA,CAAA,WAAA,CAAA,CAAA,CAAA,OAAA,CAAA,UAAA,WAAA,CAAA,CAAA,IAAA,CAAA,iBAAA,CAAA,UAAA;AAAA,cAgBtB,sBAAA,EAAsB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;KAavB,gBAAA,GAAmB,CAAA,CAAE,KAAA,QAAa,sBAAA;AAAA,KAClC,qBAAA,GAAwB,CAAA,CAAE,KAAA,QAAa,2BAAA"}