@agent-vm/mcp-portal 0.0.69 → 0.0.71
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/README.md +42 -11
- package/dist/agent-bearer-token-DCtpDPCZ.js +59 -0
- package/dist/agent-bearer-token-DCtpDPCZ.js.map +1 -0
- package/dist/bin/mcp-portal.d.ts +28 -0
- package/dist/bin/mcp-portal.d.ts.map +1 -0
- package/dist/bin/mcp-portal.js +318 -0
- package/dist/bin/mcp-portal.js.map +1 -0
- package/dist/{catalog-types--gUGFPpN.d.ts → catalog-types-BVuB4Ynx.d.ts} +1 -1
- package/dist/{catalog-types--gUGFPpN.d.ts.map → catalog-types-BVuB4Ynx.d.ts.map} +1 -1
- package/dist/cli/index.d.ts +101 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +2 -0
- package/dist/core/index.d.ts +40 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +5 -0
- package/dist/hmac-env-B4shpRRB.js +20 -0
- package/dist/hmac-env-B4shpRRB.js.map +1 -0
- package/dist/hmac-token-DBqWY3-w.js +100 -0
- package/dist/hmac-token-DBqWY3-w.js.map +1 -0
- package/dist/index.d.ts +5 -485
- package/dist/index.js +4 -5
- package/dist/mcp-proxy/index.d.ts +24 -0
- package/dist/mcp-proxy/index.d.ts.map +1 -0
- package/dist/mcp-proxy/index.js +2 -0
- package/dist/portal-auth/agent-bearer-token.d.ts +22 -0
- package/dist/portal-auth/agent-bearer-token.d.ts.map +1 -0
- package/dist/portal-auth/agent-bearer-token.js +2 -0
- package/dist/portal-auth/hmac-env.d.ts +6 -0
- package/dist/portal-auth/hmac-env.d.ts.map +1 -0
- package/dist/portal-auth/hmac-env.js +2 -0
- package/dist/portal-auth/hmac-token.d.ts +40 -0
- package/dist/portal-auth/hmac-token.d.ts.map +1 -0
- package/dist/portal-auth/hmac-token.js +2 -0
- package/dist/portal-config/index.d.ts +11 -0
- package/dist/portal-config/index.d.ts.map +1 -0
- package/dist/{tool-vm → portal-config}/index.js +2 -3
- package/dist/portal-core-CZQI7Ob6.d.ts +264 -0
- package/dist/portal-core-CZQI7Ob6.d.ts.map +1 -0
- package/dist/portal-core-Cgu714CL.js +416 -0
- package/dist/portal-core-Cgu714CL.js.map +1 -0
- package/dist/portal-session-DG2CUjIo.d.ts +184 -0
- package/dist/portal-session-DG2CUjIo.d.ts.map +1 -0
- package/dist/portal-tools-DKci1szO.js +528 -0
- package/dist/portal-tools-DKci1szO.js.map +1 -0
- package/dist/resolve-agent-identity-DnC_Pmnh.js +550 -0
- package/dist/resolve-agent-identity-DnC_Pmnh.js.map +1 -0
- package/dist/resolve-agent-identity-FQL02YdW.d.ts +81 -0
- package/dist/resolve-agent-identity-FQL02YdW.d.ts.map +1 -0
- package/dist/serve-command-D3SlETy_.js +358 -0
- package/dist/serve-command-D3SlETy_.js.map +1 -0
- package/dist/testing/fake-upstream-mcp-server.d.ts +5 -2
- package/dist/testing/fake-upstream-mcp-server.d.ts.map +1 -1
- package/dist/testing/fake-upstream-mcp-server.js +14 -4
- package/dist/testing/fake-upstream-mcp-server.js.map +1 -1
- package/dist/typescript-artifact-BVLt3Ifd.js +60 -0
- package/dist/typescript-artifact-BVLt3Ifd.js.map +1 -0
- package/dist/upstream-mcp-client-runtime-JlsfTm7_.js +760 -0
- package/dist/upstream-mcp-client-runtime-JlsfTm7_.js.map +1 -0
- package/dist/upstream-response-middleware-1MZnAD9C.d.ts +115 -0
- package/dist/upstream-response-middleware-1MZnAD9C.d.ts.map +1 -0
- package/dist/upstream-response-middleware-BjUWZ2G8.js +172 -0
- package/dist/upstream-response-middleware-BjUWZ2G8.js.map +1 -0
- package/dist/{index-BcI9c8sg.d.ts → zod-schema-loader-DLGQpYFD.d.ts} +3 -9
- package/dist/zod-schema-loader-DLGQpYFD.d.ts.map +1 -0
- package/dist/{typescript-artifact-BqU8okQy.js → zod-schema-loader-yNekKNpm.js} +85 -55
- package/dist/zod-schema-loader-yNekKNpm.js.map +1 -0
- package/package.json +30 -13
- package/dist/bin/agent-vm-mcp-portal.d.ts +0 -10
- package/dist/bin/agent-vm-mcp-portal.d.ts.map +0 -1
- package/dist/bin/agent-vm-mcp-portal.js +0 -56
- package/dist/bin/agent-vm-mcp-portal.js.map +0 -1
- package/dist/bin/portal-server.d.ts +0 -55
- package/dist/bin/portal-server.d.ts.map +0 -1
- package/dist/bin/portal-server.js +0 -289
- package/dist/bin/portal-server.js.map +0 -1
- package/dist/index-BcI9c8sg.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/tool-vm/index.d.ts +0 -2
- package/dist/tool-vm-ihnzDyjJ.js +0 -3
- package/dist/typescript-artifact-BqU8okQy.js.map +0 -1
- package/dist/upstream-mcp-client-runtime-DiBCBsDj.js +0 -1729
- package/dist/upstream-mcp-client-runtime-DiBCBsDj.js.map +0 -1
- package/dist/zod-schema-loader-CDDtoRE1.js +0 -90
- 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
|
|
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
|
-
-
|
|
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
|
-
|
|
16
|
-
|
|
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
|
-
|
|
19
|
+
External MCP clients can use the proxy command:
|
|
19
20
|
|
|
20
21
|
```text
|
|
21
|
-
|
|
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`:
|
|
28
|
+
- `mcp-portal.config.jsonc`: agents, profiles, policy, and optional external proxy auth.
|
|
29
|
+
|
|
30
|
+
External `serve` resolves `source: "1password"` refs through `@agent-vm/secret-management`.
|
|
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/
|
|
32
|
-
- `src/mcp-
|
|
33
|
-
- `src/mcp-
|
|
34
|
-
- `src/
|
|
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/secret-management";
|
|
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-D3SlETy_.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/secret-management';\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
|
|
44
|
+
//# sourceMappingURL=catalog-types-BVuB4Ynx.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-types
|
|
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"}
|