@cyanmycelium/mcp-broker 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mcp-broker.example/README.md +3 -3
- package/README.md +6 -2
- package/dist/bin.d.ts +0 -1
- package/dist/bin.js +176 -253
- package/dist/bin.js.map +1 -1
- package/dist/chunk-FTDKH2C4.js +3670 -0
- package/dist/chunk-FTDKH2C4.js.map +1 -0
- package/dist/{broker/grammars → grammars}/claude/en.json +1 -1
- package/dist/{broker/grammars → grammars}/claude/fr.json +1 -1
- package/dist/index.d.ts +1790 -22
- package/dist/index.js +2 -18
- package/dist/index.js.map +1 -1
- package/package.json +9 -7
- package/scripts/copy-assets.mjs +16 -10
- package/scripts/gen-cert.mjs +5 -5
- package/scripts/pack-mcpb.mjs +5 -5
- package/scripts/sign-bundle.mjs +6 -6
- package/src/auth/auth.config.ts +3 -3
- package/src/auth/auth.types.ts +34 -59
- package/src/auth/http.auth.ts +18 -22
- package/src/auth/index.ts +12 -12
- package/src/auth/jwt.validator.ts +3 -3
- package/src/auth/provider.auth.ts +1 -1
- package/src/auth/resource.metadata.ts +14 -21
- package/src/authorization/audit.ts +2 -2
- package/src/authorization/capability.classifier.ts +1 -1
- package/src/authorization/index.ts +13 -13
- package/src/authorization/policy.engine.ts +3 -3
- package/src/authorization/policy.types.ts +1 -1
- package/src/authorization/runtime.ts +5 -5
- package/src/authorization/slot.resource.ts +1 -1
- package/src/authorization/subject.mapper.ts +1 -1
- package/src/bin.ts +38 -8
- package/src/broker/adapters/broker.adapter.info.ts +1 -1
- package/src/broker/adapters/broker.adapter.providers.ts +1 -1
- package/src/broker/aggregate/aggregate.catalog.ts +1 -1
- package/src/broker/aggregate/aggregate.server.ts +7 -7
- package/src/broker/aggregate/provider.client.session.ts +2 -2
- package/src/broker/behaviors/broker.behavior.info.ts +3 -3
- package/src/broker/behaviors/broker.behavior.providers.ts +5 -5
- package/src/broker/broker.grammars.ts +9 -9
- package/src/broker/broker.server.ts +6 -6
- package/src/broker/grammars/claude/en.json +1 -1
- package/src/broker/grammars/claude/fr.json +1 -1
- package/src/broker/index.ts +9 -9
- package/src/config.ts +25 -3
- package/src/index.ts +24 -24
- package/src/{mcpb.loader.ts → mcpb/mcpb.loader.ts} +11 -11
- package/src/{mcpb.unzip.ts → mcpb/mcpb.unzip.ts} +2 -2
- package/src/remote.transports.ts +3 -3
- package/src/remote.upstream.ts +3 -3
- package/src/stdio.upstream.ts +2 -2
- package/src/upstream.ts +2 -2
- package/src/ws/ws.interfaces.ts +357 -0
- package/src/{ws.tunnel.builder.ts → ws/ws.tunnel.builder.ts} +28 -5
- package/src/{ws.tunnel.ts → ws/ws.tunnel.ts} +231 -467
- package/web/README.md +3 -3
- package/web/broker-self-mcp.html +9 -9
- package/web/css/styles.css +1 -1
- package/web/demos/DemoPlaceholder.html +6 -6
- package/web/demos/broker-explorer/css/app.css +1 -1
- package/web/demos/broker-explorer/index.html +2 -2
- package/web/demos/broker-explorer/js/app.js +4 -4
- package/web/demos/broker-explorer/js/mcp-ws-client.js +2 -2
- package/web/demos/oauth-lab/README.md +26 -0
- package/web/demos/oauth-lab/config.json +1 -0
- package/web/demos/oauth-lab/js/app.js +40 -16
- package/web/demos/oauth-lab/server/smoke-test.mjs +57 -10
- package/web/demos/provider-tunnel/css/app.css +1 -1
- package/web/demos/provider-tunnel/index.html +3 -3
- package/web/demos/provider-tunnel/js/app.js +10 -10
- package/web/demos/provider-tunnel/js/toolbox-server.js +5 -5
- package/web/index.html +11 -11
- package/web/js/lib/broker-tunnel.js +12 -12
- package/dist/auth/auth.config.d.ts +0 -40
- package/dist/auth/auth.config.js +0 -62
- package/dist/auth/auth.config.js.map +0 -1
- package/dist/auth/auth.types.d.ts +0 -119
- package/dist/auth/auth.types.js +0 -38
- package/dist/auth/auth.types.js.map +0 -1
- package/dist/auth/http.auth.d.ts +0 -51
- package/dist/auth/http.auth.js +0 -121
- package/dist/auth/http.auth.js.map +0 -1
- package/dist/auth/index.d.ts +0 -16
- package/dist/auth/index.js +0 -12
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/jwt.validator.d.ts +0 -35
- package/dist/auth/jwt.validator.js +0 -46
- package/dist/auth/jwt.validator.js.map +0 -1
- package/dist/auth/provider.auth.d.ts +0 -51
- package/dist/auth/provider.auth.js +0 -80
- package/dist/auth/provider.auth.js.map +0 -1
- package/dist/auth/resource.metadata.d.ts +0 -32
- package/dist/auth/resource.metadata.js +0 -26
- package/dist/auth/resource.metadata.js.map +0 -1
- package/dist/authorization/audit.d.ts +0 -14
- package/dist/authorization/audit.js +0 -20
- package/dist/authorization/audit.js.map +0 -1
- package/dist/authorization/capability.classifier.d.ts +0 -30
- package/dist/authorization/capability.classifier.js +0 -85
- package/dist/authorization/capability.classifier.js.map +0 -1
- package/dist/authorization/index.d.ts +0 -13
- package/dist/authorization/index.js +0 -8
- package/dist/authorization/index.js.map +0 -1
- package/dist/authorization/policy.engine.d.ts +0 -11
- package/dist/authorization/policy.engine.js +0 -192
- package/dist/authorization/policy.engine.js.map +0 -1
- package/dist/authorization/policy.types.d.ts +0 -92
- package/dist/authorization/policy.types.js +0 -2
- package/dist/authorization/policy.types.js.map +0 -1
- package/dist/authorization/resource.path.d.ts +0 -27
- package/dist/authorization/resource.path.js +0 -122
- package/dist/authorization/resource.path.js.map +0 -1
- package/dist/authorization/runtime.d.ts +0 -22
- package/dist/authorization/runtime.js +0 -34
- package/dist/authorization/runtime.js.map +0 -1
- package/dist/authorization/slot.resource.d.ts +0 -12
- package/dist/authorization/slot.resource.js +0 -41
- package/dist/authorization/slot.resource.js.map +0 -1
- package/dist/authorization/subject.mapper.d.ts +0 -15
- package/dist/authorization/subject.mapper.js +0 -67
- package/dist/authorization/subject.mapper.js.map +0 -1
- package/dist/broker/adapters/broker.adapter.info.d.ts +0 -16
- package/dist/broker/adapters/broker.adapter.info.js +0 -43
- package/dist/broker/adapters/broker.adapter.info.js.map +0 -1
- package/dist/broker/adapters/broker.adapter.providers.d.ts +0 -18
- package/dist/broker/adapters/broker.adapter.providers.js +0 -61
- package/dist/broker/adapters/broker.adapter.providers.js.map +0 -1
- package/dist/broker/aggregate/aggregate.catalog.d.ts +0 -66
- package/dist/broker/aggregate/aggregate.catalog.js +0 -119
- package/dist/broker/aggregate/aggregate.catalog.js.map +0 -1
- package/dist/broker/aggregate/aggregate.server.d.ts +0 -66
- package/dist/broker/aggregate/aggregate.server.js +0 -257
- package/dist/broker/aggregate/aggregate.server.js.map +0 -1
- package/dist/broker/aggregate/provider.client.session.d.ts +0 -52
- package/dist/broker/aggregate/provider.client.session.js +0 -140
- package/dist/broker/aggregate/provider.client.session.js.map +0 -1
- package/dist/broker/behaviors/broker.behavior.info.d.ts +0 -15
- package/dist/broker/behaviors/broker.behavior.info.js +0 -41
- package/dist/broker/behaviors/broker.behavior.info.js.map +0 -1
- package/dist/broker/behaviors/broker.behavior.providers.d.ts +0 -19
- package/dist/broker/behaviors/broker.behavior.providers.js +0 -69
- package/dist/broker/behaviors/broker.behavior.providers.js.map +0 -1
- package/dist/broker/broker.context.d.ts +0 -63
- package/dist/broker/broker.context.js +0 -2
- package/dist/broker/broker.context.js.map +0 -1
- package/dist/broker/broker.grammars.d.ts +0 -132
- package/dist/broker/broker.grammars.js +0 -229
- package/dist/broker/broker.grammars.js.map +0 -1
- package/dist/broker/broker.server.d.ts +0 -68
- package/dist/broker/broker.server.js +0 -73
- package/dist/broker/broker.server.js.map +0 -1
- package/dist/broker/index.d.ts +0 -9
- package/dist/broker/index.js +0 -7
- package/dist/broker/index.js.map +0 -1
- package/dist/config.d.ts +0 -182
- package/dist/config.js +0 -61
- package/dist/config.js.map +0 -1
- package/dist/mcpb.loader.d.ts +0 -26
- package/dist/mcpb.loader.js +0 -161
- package/dist/mcpb.loader.js.map +0 -1
- package/dist/mcpb.unzip.d.ts +0 -6
- package/dist/mcpb.unzip.js +0 -95
- package/dist/mcpb.unzip.js.map +0 -1
- package/dist/remote.transports.d.ts +0 -18
- package/dist/remote.transports.js +0 -297
- package/dist/remote.transports.js.map +0 -1
- package/dist/remote.upstream.d.ts +0 -38
- package/dist/remote.upstream.js +0 -52
- package/dist/remote.upstream.js.map +0 -1
- package/dist/stdio.upstream.d.ts +0 -47
- package/dist/stdio.upstream.js +0 -85
- package/dist/stdio.upstream.js.map +0 -1
- package/dist/upstream.d.ts +0 -35
- package/dist/upstream.js +0 -2
- package/dist/upstream.js.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.js +0 -9
- package/dist/version.js.map +0 -1
- package/dist/ws.tunnel.builder.d.ts +0 -176
- package/dist/ws.tunnel.builder.js +0 -271
- package/dist/ws.tunnel.builder.js.map +0 -1
- package/dist/ws.tunnel.d.ts +0 -455
- package/dist/ws.tunnel.js +0 -1425
- package/dist/ws.tunnel.js.map +0 -1
- /package/dist/{broker/grammars → grammars}/default/en.json +0 -0
- /package/dist/{broker/grammars → grammars}/default/fr.json +0 -0
- /package/dist/{broker/grammars → grammars}/default/zh.json +0 -0
|
@@ -31,7 +31,7 @@ Property-by-property educational guides:
|
|
|
31
31
|
└── index.html
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
A ready-made instance UI lives at [`node/web/`](../web/)
|
|
34
|
+
A ready-made instance UI lives at [`node/web/`](../web/), point a `www`
|
|
35
35
|
mount at it (`"dir": "../web"`) to serve it. See [`node/web/README.md`](../web/README.md).
|
|
36
36
|
|
|
37
37
|
## Path resolution
|
|
@@ -41,14 +41,14 @@ config file** (i.e. `.mcp-broker/`). So `"certs/cert.pem"` in the config
|
|
|
41
41
|
points at `.mcp-broker/certs/cert.pem`. The folder is self-contained.
|
|
42
42
|
|
|
43
43
|
Env vars (`MCP_BROKER_TLS_CERT`, `MCP_BROKER_WWW_DIR`, ...) are still
|
|
44
|
-
resolved against `process.cwd()
|
|
44
|
+
resolved against `process.cwd()`: they are the deploy-time override
|
|
45
45
|
mechanism and not tied to the config file's location.
|
|
46
46
|
|
|
47
47
|
## `.mcpb` bundles
|
|
48
48
|
|
|
49
49
|
`mcpbBundles` entries load local `.mcpb` bundles as stdio provider slots.
|
|
50
50
|
Each bundle is verified against a **detached signature** before it is
|
|
51
|
-
unpacked and run
|
|
51
|
+
unpacked and run: the broker never spawns an unverified bundle.
|
|
52
52
|
|
|
53
53
|
1. Generate a signing key pair (once):
|
|
54
54
|
`node ../scripts/sign-bundle.mjs keygen bundles`
|
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ The broker starts on `http://localhost:3000` by default.
|
|
|
32
32
|
|
|
33
33
|
Two sources, env vars **always win** over the file. The file is the static baseline you ship with the broker; env vars are deploy-specific overrides.
|
|
34
34
|
|
|
35
|
-
### Option A
|
|
35
|
+
### Option A: `.mcp-broker/` folder (recommended)
|
|
36
36
|
|
|
37
37
|
Drop a `.mcp-broker/` folder next to where you launch the broker. Paths
|
|
38
38
|
inside `config.json` are resolved against this folder, so it stays
|
|
@@ -79,7 +79,7 @@ cp -r node_modules/@cyanmycelium/mcp-broker/.mcp-broker.example .mcp-broker
|
|
|
79
79
|
|
|
80
80
|
Full reference (every field, defaults, recipes, grammar overrides): **[docs/config.md](docs/config.md)**.
|
|
81
81
|
|
|
82
|
-
### Option B
|
|
82
|
+
### Option B: Environment variables
|
|
83
83
|
|
|
84
84
|
| Variable | Default | Notes |
|
|
85
85
|
|---|---|---|
|
|
@@ -111,6 +111,10 @@ providers, and filter the `_all` aggregate per caller.
|
|
|
111
111
|
|
|
112
112
|
Enabled via the `auth` config block (or env vars). Minimal `.mcp-broker/config.json`:
|
|
113
113
|
|
|
114
|
+
The resource paths below use a compact ISA-95 / IEC 62264-aligned industrial
|
|
115
|
+
profile. The engine remains domain-neutral, does not claim full ISA-95
|
|
116
|
+
compliance, and can map UMD-style namespaces through `slotResources`.
|
|
117
|
+
|
|
114
118
|
```json
|
|
115
119
|
{
|
|
116
120
|
"auth": {
|
package/dist/bin.d.ts
CHANGED
package/dist/bin.js
CHANGED
|
@@ -1,77 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* a. `MCP_BROKER_CONFIG` env var.
|
|
10
|
-
* b. `./.mcp-broker/config.json` in the current working directory.
|
|
11
|
-
* c. `./mcp-broker.config.json` (legacy, with a deprecation warning).
|
|
12
|
-
* 3. Built-in defaults.
|
|
13
|
-
*
|
|
14
|
-
* ## Path resolution
|
|
15
|
-
*
|
|
16
|
-
* - Env-var paths (`MCP_BROKER_*_DIR`, `MCP_BROKER_TLS_*`) are resolved
|
|
17
|
-
* against `process.cwd()`.
|
|
18
|
-
* - Config-file paths (`tls.cert`, `www.mounts[*].dir`, `stdioUpstreams[*]`,
|
|
19
|
-
* `mcpbBundles[*]`) are resolved against the **config file's directory** — so a config in
|
|
20
|
-
* `./.mcp-broker/config.json` referring to `"certs/cert.pem"` points at
|
|
21
|
-
* `./.mcp-broker/certs/cert.pem`. The folder is self-contained.
|
|
22
|
-
*
|
|
23
|
-
* ## Local grammar overrides
|
|
24
|
-
*
|
|
25
|
-
* When `.mcp-broker/grammars/<userAgent>/<locale>.json` files exist next to
|
|
26
|
-
* the config file, they are merged **on top of** the packaged grammars. Lets
|
|
27
|
-
* users customize tool/resource descriptions for their organization without
|
|
28
|
-
* forking the package.
|
|
29
|
-
*
|
|
30
|
-
* ## Environment variables
|
|
31
|
-
*
|
|
32
|
-
* | Variable | Default | Notes |
|
|
33
|
-
* |--------------------------------|----------|--------------------------------------------------------|
|
|
34
|
-
* | MCP_BROKER_CONFIG | (none) | Path to a JSON config file (see above). |
|
|
35
|
-
* | MCP_BROKER_PORT | 3000 | |
|
|
36
|
-
* | MCP_BROKER_HOST | 0.0.0.0 | |
|
|
37
|
-
* | MCP_BROKER_PROVIDER_PATH | /provider| Prefix for provider WS |
|
|
38
|
-
* | MCP_BROKER_CLIENT_PATH | / | Prefix for raw WS clients |
|
|
39
|
-
* | MCP_BROKER_MCP_PATH | /mcp | Suffix for Streamable HTTP transport |
|
|
40
|
-
* | MCP_BROKER_WWW_DIR | (none) | Ergonomic shortcut: mount this directory at "/" |
|
|
41
|
-
* | MCP_BROKER_BUNDLE_DIR | (none) | Ergonomic shortcut: mount this directory at "/bundle" |
|
|
42
|
-
* | MCP_BROKER_OPEN | (unset) | "1" to auto-launch the default browser at the root URL |
|
|
43
|
-
* | MCP_BROKER_TLS_CERT | (none) | Path to a PEM TLS certificate |
|
|
44
|
-
* | MCP_BROKER_TLS_KEY | (none) | Path to a PEM private key |
|
|
45
|
-
* | MCP_BROKER_PROTOCOL | auto | "http" to force plain, "https" to force TLS, otherwise |
|
|
46
|
-
* | | | TLS is enabled iff cert+key are both set |
|
|
47
|
-
* | MCP_BROKER_STDIO_PROVIDER | (none) | When set, stdin/stdout carry JSON-RPC for the named |
|
|
48
|
-
* | | | provider (Claude Desktop bridge). |
|
|
49
|
-
* | MCP_BROKER_LOCALE | en | Locale used for tool descriptions on the `_broker` |
|
|
50
|
-
* | | | slot. ISO 639-1 base; regional variants accepted. |
|
|
51
|
-
*/
|
|
52
|
-
import * as fs from "fs";
|
|
53
|
-
import * as path from "path";
|
|
54
|
-
import open from "open";
|
|
55
|
-
import { WsTunnelBuilder } from "./index.js";
|
|
56
|
-
import { loadBrokerConfig } from "./config.js";
|
|
57
|
-
import { loadMcpbBundle } from "./mcpb.loader.js";
|
|
58
|
-
// ---------------------------------------------------------------------------
|
|
59
|
-
// Configuration
|
|
60
|
-
// ---------------------------------------------------------------------------
|
|
61
|
-
const { config, baseDir } = loadBrokerConfig();
|
|
62
|
-
const cwd = process.cwd();
|
|
63
|
-
/**
|
|
64
|
-
* Fills an env var from the config file when the env var is not already set.
|
|
65
|
-
* Used for **non-path** scalars — path-bearing fields are read directly so
|
|
66
|
-
* they can be resolved against `baseDir` (config file's directory) instead
|
|
67
|
-
* of `cwd` (deploy environment).
|
|
68
|
-
*/
|
|
2
|
+
import { loadBrokerConfig, WsTunnelBuilder, loadMcpbBundle } from './chunk-FTDKH2C4.js';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import open from 'open';
|
|
6
|
+
|
|
7
|
+
var { config, baseDir } = loadBrokerConfig();
|
|
8
|
+
var cwd = process.cwd();
|
|
69
9
|
function envFromConfig(envName, configValue) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return;
|
|
74
|
-
process.env[envName] = String(configValue);
|
|
10
|
+
if (configValue === void 0 || configValue === null) return;
|
|
11
|
+
if (process.env[envName] !== void 0 && process.env[envName] !== "") return;
|
|
12
|
+
process.env[envName] = String(configValue);
|
|
75
13
|
}
|
|
76
14
|
envFromConfig("MCP_BROKER_PORT", config.port);
|
|
77
15
|
envFromConfig("MCP_BROKER_HOST", config.host);
|
|
@@ -81,204 +19,189 @@ envFromConfig("MCP_BROKER_STDIO_PROVIDER", config.stdioProvider);
|
|
|
81
19
|
envFromConfig("MCP_BROKER_PROVIDER_PATH", config.paths?.provider);
|
|
82
20
|
envFromConfig("MCP_BROKER_CLIENT_PATH", config.paths?.client);
|
|
83
21
|
envFromConfig("MCP_BROKER_MCP_PATH", config.paths?.mcp);
|
|
84
|
-
envFromConfig("MCP_BROKER_OPEN", config.www?.open === true ? "1" :
|
|
85
|
-
envFromConfig("MCP_BROKER_AUTH_ENABLED", config.auth?.enabled === true ? "1" :
|
|
22
|
+
envFromConfig("MCP_BROKER_OPEN", config.www?.open === true ? "1" : void 0);
|
|
23
|
+
envFromConfig("MCP_BROKER_AUTH_ENABLED", config.auth?.enabled === true ? "1" : void 0);
|
|
86
24
|
envFromConfig("MCP_BROKER_PUBLIC_BASE_URL", config.auth?.publicBaseUrl);
|
|
87
25
|
envFromConfig("MCP_BROKER_JWKS", config.auth?.jwks);
|
|
88
26
|
envFromConfig("MCP_BROKER_ISSUER", config.auth?.issuer);
|
|
89
27
|
envFromConfig("MCP_BROKER_PROVIDER_SECRET", config.auth?.providerSecret);
|
|
90
|
-
|
|
91
|
-
// In stdio mode stdout is reserved for JSON-RPC — redirect all console output to stderr.
|
|
28
|
+
var stdioProvider = process.env["MCP_BROKER_STDIO_PROVIDER"];
|
|
92
29
|
if (stdioProvider) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
30
|
+
const toStderr = (...args) => process.stderr.write(args.join(" ") + "\n");
|
|
31
|
+
console.log = toStderr;
|
|
32
|
+
console.info = toStderr;
|
|
33
|
+
console.warn = toStderr;
|
|
34
|
+
console.error = toStderr;
|
|
98
35
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
console.error(`[mcp-broker] Invalid MCP_BROKER_PROTOCOL="${protocolOverride}". Use "http" or "https".`);
|
|
112
|
-
process.exit(1);
|
|
36
|
+
var port = parseInt(process.env["MCP_BROKER_PORT"] ?? "3000", 10);
|
|
37
|
+
var host = process.env["MCP_BROKER_HOST"];
|
|
38
|
+
var providerPath = process.env["MCP_BROKER_PROVIDER_PATH"] ?? "/provider";
|
|
39
|
+
var clientPath = process.env["MCP_BROKER_CLIENT_PATH"] ?? "/";
|
|
40
|
+
var mcpPath = process.env["MCP_BROKER_MCP_PATH"] ?? "/mcp";
|
|
41
|
+
var ssePath = config.paths?.sse ?? "/sse";
|
|
42
|
+
var tlsCertPath = process.env["MCP_BROKER_TLS_CERT"] ? path.resolve(cwd, process.env["MCP_BROKER_TLS_CERT"]) : config.tls?.cert ? path.resolve(baseDir, config.tls.cert) : null;
|
|
43
|
+
var tlsKeyPath = process.env["MCP_BROKER_TLS_KEY"] ? path.resolve(cwd, process.env["MCP_BROKER_TLS_KEY"]) : config.tls?.key ? path.resolve(baseDir, config.tls.key) : null;
|
|
44
|
+
var protocolOverride = process.env["MCP_BROKER_PROTOCOL"]?.toLowerCase();
|
|
45
|
+
if (protocolOverride !== void 0 && protocolOverride !== "http" && protocolOverride !== "https") {
|
|
46
|
+
console.error(`[mcp-broker] Invalid MCP_BROKER_PROTOCOL="${protocolOverride}". Use "http" or "https".`);
|
|
47
|
+
process.exit(1);
|
|
113
48
|
}
|
|
114
49
|
if (protocolOverride === "https" && (!tlsCertPath || !tlsKeyPath)) {
|
|
115
|
-
|
|
116
|
-
|
|
50
|
+
console.error("[mcp-broker] MCP_BROKER_PROTOCOL=https requires TLS cert+key (via config.tls or MCP_BROKER_TLS_CERT/KEY).");
|
|
51
|
+
process.exit(1);
|
|
117
52
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
53
|
+
var useTls = protocolOverride === "http" ? false : protocolOverride === "https" ? true : !!(tlsCertPath && tlsKeyPath);
|
|
54
|
+
var envOrigins = process.env["MCP_BROKER_ALLOWED_ORIGINS"]?.split(",").map((origin) => origin.trim()).filter(Boolean);
|
|
55
|
+
var allowedOrigins;
|
|
56
|
+
if (envOrigins?.length) {
|
|
57
|
+
allowedOrigins = envOrigins;
|
|
58
|
+
} else if (Array.isArray(config.allowedOrigins)) {
|
|
59
|
+
allowedOrigins = config.allowedOrigins;
|
|
60
|
+
} else if (config.allowedOrigins) {
|
|
61
|
+
try {
|
|
62
|
+
allowedOrigins = new RegExp(config.allowedOrigins.pattern, config.allowedOrigins.flags);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
console.error(`[mcp-broker] Ignoring allowedOrigins.pattern: ${err.message}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
var envWwwDir = process.env["MCP_BROKER_WWW_DIR"] ? path.resolve(cwd, process.env["MCP_BROKER_WWW_DIR"]) : null;
|
|
68
|
+
var envBundleDir = process.env["MCP_BROKER_BUNDLE_DIR"] ? path.resolve(cwd, process.env["MCP_BROKER_BUNDLE_DIR"]) : null;
|
|
125
69
|
async function main() {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
builder.withStaticMount(mount.urlPrefix, abs);
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
console.warn(`[mcp-broker] www.mounts entry "${mount.urlPrefix}" → ${abs} skipped (directory not found).`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
// ── Stdio upstreams ──────────────────────────────────────────────────────
|
|
160
|
-
if (config.stdioUpstreams) {
|
|
161
|
-
for (const u of config.stdioUpstreams) {
|
|
162
|
-
builder.withStdioUpstream({
|
|
163
|
-
name: u.name,
|
|
164
|
-
command: u.command,
|
|
165
|
-
args: u.args,
|
|
166
|
-
env: u.env,
|
|
167
|
-
aggregate: u.aggregate,
|
|
168
|
-
});
|
|
169
|
-
}
|
|
70
|
+
const localGrammarsDir = path.join(baseDir, "grammars");
|
|
71
|
+
const hasLocalGrammars = fs.existsSync(localGrammarsDir);
|
|
72
|
+
const builder = new WsTunnelBuilder().withPort(port).withProviderPath(providerPath).withClientPath(clientPath).withMcpPath(mcpPath);
|
|
73
|
+
if (host) {
|
|
74
|
+
builder.withHost(host);
|
|
75
|
+
}
|
|
76
|
+
if (useTls) {
|
|
77
|
+
builder.withTlsFiles(tlsCertPath, tlsKeyPath);
|
|
78
|
+
}
|
|
79
|
+
if (allowedOrigins) {
|
|
80
|
+
builder.withAllowedOrigins(allowedOrigins);
|
|
81
|
+
}
|
|
82
|
+
if (envBundleDir && fs.existsSync(envBundleDir)) {
|
|
83
|
+
builder.withStaticMount("/bundle", envBundleDir);
|
|
84
|
+
}
|
|
85
|
+
if (envWwwDir && fs.existsSync(envWwwDir)) {
|
|
86
|
+
builder.withStaticMount("/", envWwwDir);
|
|
87
|
+
}
|
|
88
|
+
if (config.www?.mounts) {
|
|
89
|
+
for (const mount of config.www.mounts) {
|
|
90
|
+
const abs = path.resolve(baseDir, mount.dir);
|
|
91
|
+
if (fs.existsSync(abs)) {
|
|
92
|
+
builder.withStaticMount(mount.urlPrefix, abs);
|
|
93
|
+
} else {
|
|
94
|
+
console.warn(`[mcp-broker] www.mounts entry "${mount.urlPrefix}" \u2192 ${abs} skipped (directory not found).`);
|
|
95
|
+
}
|
|
170
96
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
97
|
+
}
|
|
98
|
+
if (config.stdioUpstreams) {
|
|
99
|
+
for (const u of config.stdioUpstreams) {
|
|
100
|
+
builder.withStdioUpstream({
|
|
101
|
+
name: u.name,
|
|
102
|
+
command: u.command,
|
|
103
|
+
args: u.args,
|
|
104
|
+
env: u.env,
|
|
105
|
+
aggregate: u.aggregate
|
|
106
|
+
});
|
|
178
107
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (config.mcpbBundles) {
|
|
184
|
-
for (const b of config.mcpbBundles) {
|
|
185
|
-
const upstream = await loadMcpbBundle(b, baseDir);
|
|
186
|
-
if (upstream) {
|
|
187
|
-
builder.withStdioUpstream(upstream);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
108
|
+
}
|
|
109
|
+
if (config.mcpServers) {
|
|
110
|
+
for (const s of config.mcpServers) {
|
|
111
|
+
builder.withRemoteUpstream({ ...s, aggregate: s.aggregate ?? true });
|
|
190
112
|
}
|
|
191
|
-
|
|
192
|
-
|
|
113
|
+
}
|
|
114
|
+
if (config.mcpbBundles) {
|
|
115
|
+
for (const b of config.mcpbBundles) {
|
|
116
|
+
const upstream = await loadMcpbBundle(b, baseDir);
|
|
117
|
+
if (upstream) {
|
|
118
|
+
builder.withStdioUpstream(upstream);
|
|
119
|
+
}
|
|
193
120
|
}
|
|
194
|
-
|
|
195
|
-
|
|
121
|
+
}
|
|
122
|
+
if (stdioProvider) {
|
|
123
|
+
builder.withStdioClient(stdioProvider);
|
|
124
|
+
}
|
|
125
|
+
if (hasLocalGrammars) {
|
|
126
|
+
builder.withBrokerLocalGrammarsDir(localGrammarsDir);
|
|
127
|
+
}
|
|
128
|
+
const authEnabledEnv = process.env["MCP_BROKER_AUTH_ENABLED"];
|
|
129
|
+
const authEnabled = authEnabledEnv === "1" || authEnabledEnv === "true";
|
|
130
|
+
if (authEnabled) {
|
|
131
|
+
const publicBaseUrl = process.env["MCP_BROKER_PUBLIC_BASE_URL"];
|
|
132
|
+
const jwks = process.env["MCP_BROKER_JWKS"];
|
|
133
|
+
const issuer = process.env["MCP_BROKER_ISSUER"];
|
|
134
|
+
const authorizationServers = config.auth?.authorizationServers ?? (issuer ? [issuer] : []);
|
|
135
|
+
if (!publicBaseUrl || !jwks || authorizationServers.length === 0) {
|
|
136
|
+
console.error(
|
|
137
|
+
"[mcp-broker] auth.enabled requires publicBaseUrl, jwks, and at least one authorizationServers entry (or issuer). Set them via config.auth or MCP_BROKER_PUBLIC_BASE_URL / MCP_BROKER_JWKS / MCP_BROKER_ISSUER."
|
|
138
|
+
);
|
|
139
|
+
process.exit(1);
|
|
196
140
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
const mcpSuffix = mcpPath.replace(/^\//, "");
|
|
247
|
-
const sseSuffix = ssePath.replace(/^\//, "");
|
|
248
|
-
const hasWwwRoot = !!(envWwwDir && fs.existsSync(envWwwDir)) || (config.www?.mounts ?? []).some((m) => m.urlPrefix === "/");
|
|
141
|
+
builder.withJwtAuth({
|
|
142
|
+
publicBaseUrl,
|
|
143
|
+
authorizationServers,
|
|
144
|
+
jwksUri: jwks,
|
|
145
|
+
issuer,
|
|
146
|
+
scopesSupported: config.auth?.scopesSupported,
|
|
147
|
+
requiredScopes: config.auth?.requiredScopes,
|
|
148
|
+
perSlotScopes: config.auth?.perSlotScopes,
|
|
149
|
+
providerScopes: config.auth?.providerScopes,
|
|
150
|
+
subjectMapping: config.auth?.subjectMapping,
|
|
151
|
+
roles: config.auth?.roles,
|
|
152
|
+
assignments: config.auth?.assignments,
|
|
153
|
+
denies: config.auth?.denies,
|
|
154
|
+
slotResources: config.auth?.slotResources,
|
|
155
|
+
toolCapabilities: config.auth?.toolCapabilities,
|
|
156
|
+
providerToolCapabilities: config.auth?.providerToolCapabilities,
|
|
157
|
+
audit: config.auth?.audit
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
const providerSecret = process.env["MCP_BROKER_PROVIDER_SECRET"];
|
|
161
|
+
if (providerSecret) {
|
|
162
|
+
builder.withProviderSecret(providerSecret);
|
|
163
|
+
}
|
|
164
|
+
const tunnel = builder.build();
|
|
165
|
+
await tunnel.start();
|
|
166
|
+
const httpScheme = useTls ? "https" : "http";
|
|
167
|
+
const wsScheme = useTls ? "wss" : "ws";
|
|
168
|
+
const hr = "\u2500".repeat(64);
|
|
169
|
+
const localhost = `${httpScheme}://localhost:${port}`;
|
|
170
|
+
const mcpSuffix = mcpPath.replace(/^\//, "");
|
|
171
|
+
const sseSuffix = ssePath.replace(/^\//, "");
|
|
172
|
+
const hasWwwRoot = !!(envWwwDir && fs.existsSync(envWwwDir)) || (config.www?.mounts ?? []).some((m) => m.urlPrefix === "/");
|
|
173
|
+
console.log();
|
|
174
|
+
console.log(`\u2699\uFE0F mcp-broker started${useTls ? " (TLS)" : ""}`);
|
|
175
|
+
console.log(hr);
|
|
176
|
+
console.log(`\u{1F4E1} Provider WebSocket ${wsScheme}://localhost:${port}${providerPath}/<name>`);
|
|
177
|
+
console.log(`\u{1F50C} MCP (Streamable HTTP) ${localhost}/<name>/${mcpSuffix}`);
|
|
178
|
+
console.log(`\u{1F4FA} Legacy SSE ${localhost}/<name>/${sseSuffix}`);
|
|
179
|
+
if (hasLocalGrammars) {
|
|
180
|
+
console.log(`\u{1F310} Local grammars ${localGrammarsDir}`);
|
|
181
|
+
}
|
|
182
|
+
console.log(`\u{1F510} Authorization ${authEnabled ? "OAuth 2.1 (Bearer required)" : "disabled (trusted network only)"}`);
|
|
183
|
+
console.log(`\u{1F6E1}\uFE0F Provider auth ${providerSecret ? "shared secret required" : "disabled"}`);
|
|
184
|
+
console.log(hr);
|
|
185
|
+
console.log(` Press Ctrl+C to stop.`);
|
|
186
|
+
console.log();
|
|
187
|
+
if (hasWwwRoot && process.env["MCP_BROKER_OPEN"] === "1") {
|
|
188
|
+
const url = `${localhost}/`;
|
|
189
|
+
console.log(`\u{1F680} Opening browser: ${url}`);
|
|
249
190
|
console.log();
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
console.log(
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
console.log(hr);
|
|
261
|
-
console.log(` Press Ctrl+C to stop.`);
|
|
262
|
-
console.log();
|
|
263
|
-
// Auto-launch browser only if explicitly opted in via MCP_BROKER_OPEN=1
|
|
264
|
-
// AND a mount at "/" is configured.
|
|
265
|
-
if (hasWwwRoot && process.env["MCP_BROKER_OPEN"] === "1") {
|
|
266
|
-
const url = `${localhost}/`;
|
|
267
|
-
console.log(`🚀 Opening browser: ${url}`);
|
|
268
|
-
console.log();
|
|
269
|
-
await open(url);
|
|
270
|
-
}
|
|
271
|
-
// ── Signal handlers ─────────────────────────────────────────────────────
|
|
272
|
-
const shutdown = async (signal) => {
|
|
273
|
-
console.log(`\n⛔ ${signal} received — shutting down…`);
|
|
274
|
-
await tunnel.stop();
|
|
275
|
-
process.exit(0);
|
|
276
|
-
};
|
|
277
|
-
process.on("SIGINT", () => void shutdown("SIGINT"));
|
|
278
|
-
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
|
191
|
+
await open(url);
|
|
192
|
+
}
|
|
193
|
+
const shutdown = async (signal) => {
|
|
194
|
+
console.log(`
|
|
195
|
+
\u26D4 ${signal} received, shutting down\u2026`);
|
|
196
|
+
await tunnel.stop();
|
|
197
|
+
process.exit(0);
|
|
198
|
+
};
|
|
199
|
+
process.on("SIGINT", () => void shutdown("SIGINT"));
|
|
200
|
+
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
|
279
201
|
}
|
|
280
202
|
main().catch((err) => {
|
|
281
|
-
|
|
282
|
-
|
|
203
|
+
console.error("[mcp-broker] Fatal error:", err);
|
|
204
|
+
process.exit(1);
|
|
283
205
|
});
|
|
206
|
+
//# sourceMappingURL=bin.js.map
|
|
284
207
|
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/bin.ts"],"names":[],"mappings":"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","file":"bin.js","sourcesContent":["#!/usr/bin/env node\n/**\n * Standalone entry-point that starts the mcp-broker WebSocket server.\n *\n * ## Configuration sources (highest priority first)\n *\n * 1. Environment variables (`MCP_BROKER_*`).\n * 2. JSON config file. Resolved in order:\n * a. `MCP_BROKER_CONFIG` env var.\n * b. `./.mcp-broker/config.json` in the current working directory.\n * c. `./mcp-broker.config.json` (legacy, with a deprecation warning).\n * 3. Built-in defaults.\n *\n * ## Path resolution\n *\n * - Env-var paths (`MCP_BROKER_*_DIR`, `MCP_BROKER_TLS_*`) are resolved\n * against `process.cwd()`.\n * - Config-file paths (`tls.cert`, `www.mounts[*].dir`, `stdioUpstreams[*]`,\n * `mcpbBundles[*]`) are resolved against the **config file's directory**: so a config in\n * `./.mcp-broker/config.json` referring to `\"certs/cert.pem\"` points at\n * `./.mcp-broker/certs/cert.pem`. The folder is self-contained.\n *\n * ## Local grammar overrides\n *\n * When `.mcp-broker/grammars/<userAgent>/<locale>.json` files exist next to\n * the config file, they are merged **on top of** the packaged grammars. Lets\n * users customize tool/resource descriptions for their organization without\n * forking the package.\n *\n * ## Environment variables\n *\n * | Variable | Default | Notes |\n * |--------------------------------|----------|--------------------------------------------------------|\n * | MCP_BROKER_CONFIG | (none) | Path to a JSON config file (see above). |\n * | MCP_BROKER_PORT | 3000 | |\n * | MCP_BROKER_HOST | 0.0.0.0 | |\n * | MCP_BROKER_PROVIDER_PATH | /provider| Prefix for provider WS |\n * | MCP_BROKER_CLIENT_PATH | / | Prefix for raw WS clients |\n * | MCP_BROKER_MCP_PATH | /mcp | Suffix for Streamable HTTP transport |\n * | MCP_BROKER_WWW_DIR | (none) | Ergonomic shortcut: mount this directory at \"/\" |\n * | MCP_BROKER_BUNDLE_DIR | (none) | Ergonomic shortcut: mount this directory at \"/bundle\" |\n * | MCP_BROKER_OPEN | (unset) | \"1\" to auto-launch the default browser at the root URL |\n * | MCP_BROKER_TLS_CERT | (none) | Path to a PEM TLS certificate |\n * | MCP_BROKER_TLS_KEY | (none) | Path to a PEM private key |\n * | MCP_BROKER_PROTOCOL | auto | \"http\" to force plain, \"https\" to force TLS, otherwise |\n * | | | TLS is enabled iff cert+key are both set |\n * | MCP_BROKER_STDIO_PROVIDER | (none) | When set, stdin/stdout carry JSON-RPC for the named |\n * | | | provider (Claude Desktop bridge). |\n * | MCP_BROKER_LOCALE | en | Locale used for tool descriptions on the `_broker` |\n * | | | slot. ISO 639-1 base; regional variants accepted. |\n * | MCP_BROKER_ALLOWED_ORIGINS | (none) | Comma-separated browser origins allowed on |\n * | | | `/<slot>/mcp`. None means no browser origin passes. |\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport open from \"open\";\nimport { WsTunnelBuilder } from \"./index\";\nimport { loadBrokerConfig } from \"./config\";\nimport { loadMcpbBundle } from \"./mcpb/mcpb.loader\";\n\n// ---------------------------------------------------------------------------\n// Configuration\n// ---------------------------------------------------------------------------\n\nconst { config, baseDir } = loadBrokerConfig();\nconst cwd = process.cwd();\n\n/**\n * Fills an env var from the config file when the env var is not already set.\n * Used for **non-path** scalars, path-bearing fields are read directly so\n * they can be resolved against `baseDir` (config file's directory) instead\n * of `cwd` (deploy environment).\n */\nfunction envFromConfig(envName: string, configValue: string | number | boolean | undefined): void {\n if (configValue === undefined || configValue === null) return;\n if (process.env[envName] !== undefined && process.env[envName] !== \"\") return;\n process.env[envName] = String(configValue);\n}\n\nenvFromConfig(\"MCP_BROKER_PORT\", config.port);\nenvFromConfig(\"MCP_BROKER_HOST\", config.host);\nenvFromConfig(\"MCP_BROKER_PROTOCOL\", config.protocol);\nenvFromConfig(\"MCP_BROKER_LOCALE\", config.locale);\nenvFromConfig(\"MCP_BROKER_STDIO_PROVIDER\", config.stdioProvider);\nenvFromConfig(\"MCP_BROKER_PROVIDER_PATH\", config.paths?.provider);\nenvFromConfig(\"MCP_BROKER_CLIENT_PATH\", config.paths?.client);\nenvFromConfig(\"MCP_BROKER_MCP_PATH\", config.paths?.mcp);\nenvFromConfig(\"MCP_BROKER_OPEN\", config.www?.open === true ? \"1\" : undefined);\nenvFromConfig(\"MCP_BROKER_AUTH_ENABLED\", config.auth?.enabled === true ? \"1\" : undefined);\nenvFromConfig(\"MCP_BROKER_PUBLIC_BASE_URL\", config.auth?.publicBaseUrl);\nenvFromConfig(\"MCP_BROKER_JWKS\", config.auth?.jwks);\nenvFromConfig(\"MCP_BROKER_ISSUER\", config.auth?.issuer);\nenvFromConfig(\"MCP_BROKER_PROVIDER_SECRET\", config.auth?.providerSecret);\n\nconst stdioProvider = process.env[\"MCP_BROKER_STDIO_PROVIDER\"];\n\n// In stdio mode stdout is reserved for JSON-RPC, redirect all console output to stderr.\nif (stdioProvider) {\n const toStderr = (...args: unknown[]) => process.stderr.write(args.join(\" \") + \"\\n\");\n console.log = toStderr;\n console.info = toStderr;\n console.warn = toStderr;\n console.error = toStderr;\n}\n\nconst port = parseInt(process.env[\"MCP_BROKER_PORT\"] ?? \"3000\", 10);\nconst host = process.env[\"MCP_BROKER_HOST\"];\nconst providerPath = process.env[\"MCP_BROKER_PROVIDER_PATH\"] ?? \"/provider\";\nconst clientPath = process.env[\"MCP_BROKER_CLIENT_PATH\"] ?? \"/\";\nconst mcpPath = process.env[\"MCP_BROKER_MCP_PATH\"] ?? \"/mcp\";\nconst ssePath = config.paths?.sse ?? \"/sse\";\n\n// ── TLS material ─────────────────────────────────────────────────────────────\n// Env var (relative to cwd) wins over config (relative to baseDir).\nconst tlsCertPath = process.env[\"MCP_BROKER_TLS_CERT\"] ? path.resolve(cwd, process.env[\"MCP_BROKER_TLS_CERT\"]) : config.tls?.cert ? path.resolve(baseDir, config.tls.cert) : null;\nconst tlsKeyPath = process.env[\"MCP_BROKER_TLS_KEY\"] ? path.resolve(cwd, process.env[\"MCP_BROKER_TLS_KEY\"]) : config.tls?.key ? path.resolve(baseDir, config.tls.key) : null;\n\nconst protocolOverride = process.env[\"MCP_BROKER_PROTOCOL\"]?.toLowerCase();\nif (protocolOverride !== undefined && protocolOverride !== \"http\" && protocolOverride !== \"https\") {\n console.error(`[mcp-broker] Invalid MCP_BROKER_PROTOCOL=\"${protocolOverride}\". Use \"http\" or \"https\".`);\n process.exit(1);\n}\nif (protocolOverride === \"https\" && (!tlsCertPath || !tlsKeyPath)) {\n console.error(\"[mcp-broker] MCP_BROKER_PROTOCOL=https requires TLS cert+key (via config.tls or MCP_BROKER_TLS_CERT/KEY).\");\n process.exit(1);\n}\n\nconst useTls = protocolOverride === \"http\" ? false : protocolOverride === \"https\" ? true : !!(tlsCertPath && tlsKeyPath);\n\n// ── Allowed browser origins for /<slot>/mcp ──────────────────────────────────\n// Absent leaves the endpoint closed to browsers, which is the safe default.\n// The env var only carries the list form; a pattern needs the config file,\n// since a regular expression cannot survive comma-splitting.\nconst envOrigins = process.env[\"MCP_BROKER_ALLOWED_ORIGINS\"]\n ?.split(\",\")\n .map((origin) => origin.trim())\n .filter(Boolean);\n\nlet allowedOrigins: readonly string[] | RegExp | undefined;\nif (envOrigins?.length) {\n allowedOrigins = envOrigins;\n} else if (Array.isArray(config.allowedOrigins)) {\n allowedOrigins = config.allowedOrigins;\n} else if (config.allowedOrigins) {\n try {\n allowedOrigins = new RegExp(config.allowedOrigins.pattern, config.allowedOrigins.flags);\n } catch (err) {\n // Falling back to the closed default rather than starting with a rule\n // the operator believes is in force but which never compiled.\n console.error(`[mcp-broker] Ignoring allowedOrigins.pattern: ${(err as Error).message}`);\n }\n}\n\n// ── Env-var static mount shortcuts (relative to cwd) ─────────────────────────\nconst envWwwDir = process.env[\"MCP_BROKER_WWW_DIR\"] ? path.resolve(cwd, process.env[\"MCP_BROKER_WWW_DIR\"]) : null;\nconst envBundleDir = process.env[\"MCP_BROKER_BUNDLE_DIR\"] ? path.resolve(cwd, process.env[\"MCP_BROKER_BUNDLE_DIR\"]) : null;\n\n// ---------------------------------------------------------------------------\n// Server bootstrap\n// ---------------------------------------------------------------------------\n\nasync function main(): Promise<void> {\n // Local grammar overrides: when `<baseDir>/grammars/` exists, the broker\n // server merges those JSON files on top of the packaged grammars.\n const localGrammarsDir = path.join(baseDir, \"grammars\");\n const hasLocalGrammars = fs.existsSync(localGrammarsDir);\n\n const builder = new WsTunnelBuilder().withPort(port).withProviderPath(providerPath).withClientPath(clientPath).withMcpPath(mcpPath);\n\n if (host) {\n builder.withHost(host);\n }\n\n if (useTls) {\n builder.withTlsFiles(tlsCertPath!, tlsKeyPath!);\n }\n\n if (allowedOrigins) {\n builder.withAllowedOrigins(allowedOrigins);\n }\n\n // ── Static mounts ────────────────────────────────────────────────────────\n // First the env-var shortcuts (relative to cwd), then the config `www.mounts`\n // (relative to baseDir). Order matters: /bundle before / so the prefix router\n // can distinguish them. Subsequent registrations contribute additional mounts;\n // longest-prefix match wins at runtime.\n if (envBundleDir && fs.existsSync(envBundleDir)) {\n builder.withStaticMount(\"/bundle\", envBundleDir);\n }\n if (envWwwDir && fs.existsSync(envWwwDir)) {\n builder.withStaticMount(\"/\", envWwwDir);\n }\n if (config.www?.mounts) {\n for (const mount of config.www.mounts) {\n const abs = path.resolve(baseDir, mount.dir);\n if (fs.existsSync(abs)) {\n builder.withStaticMount(mount.urlPrefix, abs);\n } else {\n console.warn(`[mcp-broker] www.mounts entry \"${mount.urlPrefix}\" → ${abs} skipped (directory not found).`);\n }\n }\n }\n\n // ── Stdio upstreams ──────────────────────────────────────────────────────\n if (config.stdioUpstreams) {\n for (const u of config.stdioUpstreams) {\n builder.withStdioUpstream({\n name: u.name,\n command: u.command,\n args: u.args,\n env: u.env as NodeJS.ProcessEnv | undefined,\n aggregate: u.aggregate,\n });\n }\n }\n\n // ── Remote MCP server upstreams (reached by URL) ─────────────────────────\n // Config-discovered remote servers join the `_all` aggregate by default;\n // an explicit `aggregate: false` opts an entry out.\n if (config.mcpServers) {\n for (const s of config.mcpServers) {\n builder.withRemoteUpstream({ ...s, aggregate: s.aggregate ?? true });\n }\n }\n\n // ── Local `.mcpb` bundles ────────────────────────────────────────────────\n // Each bundle is signature-verified and unpacked before it is wired in as a\n // stdio upstream. A refused bundle is skipped (loadMcpbBundle logs why); it\n // never spawns a process. Bundles join `_all` by default (opt-out per entry).\n if (config.mcpbBundles) {\n for (const b of config.mcpbBundles) {\n const upstream = await loadMcpbBundle(b, baseDir);\n if (upstream) {\n builder.withStdioUpstream(upstream);\n }\n }\n }\n\n if (stdioProvider) {\n builder.withStdioClient(stdioProvider);\n }\n\n if (hasLocalGrammars) {\n builder.withBrokerLocalGrammarsDir(localGrammarsDir);\n }\n\n // ── Authorization (OAuth 2.1 resource server) ────────────────────────────\n // Opt-in: only wired when MCP_BROKER_AUTH_ENABLED / config.auth.enabled is on.\n // Env scalars win over config; array/object fields are read from config.\n const authEnabledEnv = process.env[\"MCP_BROKER_AUTH_ENABLED\"];\n const authEnabled = authEnabledEnv === \"1\" || authEnabledEnv === \"true\";\n if (authEnabled) {\n const publicBaseUrl = process.env[\"MCP_BROKER_PUBLIC_BASE_URL\"];\n const jwks = process.env[\"MCP_BROKER_JWKS\"];\n const issuer = process.env[\"MCP_BROKER_ISSUER\"];\n const authorizationServers = config.auth?.authorizationServers ?? (issuer ? [issuer] : []);\n if (!publicBaseUrl || !jwks || authorizationServers.length === 0) {\n console.error(\n \"[mcp-broker] auth.enabled requires publicBaseUrl, jwks, and at least one \" +\n \"authorizationServers entry (or issuer). Set them via config.auth or \" +\n \"MCP_BROKER_PUBLIC_BASE_URL / MCP_BROKER_JWKS / MCP_BROKER_ISSUER.\"\n );\n process.exit(1);\n }\n builder.withJwtAuth({\n publicBaseUrl,\n authorizationServers,\n jwksUri: jwks,\n issuer,\n scopesSupported: config.auth?.scopesSupported,\n requiredScopes: config.auth?.requiredScopes,\n perSlotScopes: config.auth?.perSlotScopes,\n providerScopes: config.auth?.providerScopes,\n subjectMapping: config.auth?.subjectMapping,\n roles: config.auth?.roles,\n assignments: config.auth?.assignments,\n denies: config.auth?.denies,\n slotResources: config.auth?.slotResources,\n toolCapabilities: config.auth?.toolCapabilities,\n providerToolCapabilities: config.auth?.providerToolCapabilities,\n audit: config.auth?.audit,\n });\n }\n\n // ── Provider authentication (independent of client OAuth) ────────────────\n // Requires every provider connecting to /provider/<slot> or /providers to\n // present the shared secret, closes off slot occupation by strangers.\n const providerSecret = process.env[\"MCP_BROKER_PROVIDER_SECRET\"];\n if (providerSecret) {\n builder.withProviderSecret(providerSecret);\n }\n\n const tunnel = builder.build();\n await tunnel.start();\n\n // ── Startup banner ──────────────────────────────────────────────────────\n const httpScheme = useTls ? \"https\" : \"http\";\n const wsScheme = useTls ? \"wss\" : \"ws\";\n const hr = \"─\".repeat(64);\n const localhost = `${httpScheme}://localhost:${port}`;\n const mcpSuffix = mcpPath.replace(/^\\//, \"\");\n const sseSuffix = ssePath.replace(/^\\//, \"\");\n const hasWwwRoot = !!(envWwwDir && fs.existsSync(envWwwDir)) || (config.www?.mounts ?? []).some((m) => m.urlPrefix === \"/\");\n\n console.log();\n console.log(`⚙️ mcp-broker started${useTls ? \" (TLS)\" : \"\"}`);\n console.log(hr);\n console.log(`📡 Provider WebSocket ${wsScheme}://localhost:${port}${providerPath}/<name>`);\n console.log(`🔌 MCP (Streamable HTTP) ${localhost}/<name>/${mcpSuffix}`);\n console.log(`📺 Legacy SSE ${localhost}/<name>/${sseSuffix}`);\n if (hasLocalGrammars) {\n console.log(`🌐 Local grammars ${localGrammarsDir}`);\n }\n console.log(`🔐 Authorization ${authEnabled ? \"OAuth 2.1 (Bearer required)\" : \"disabled (trusted network only)\"}`);\n console.log(`🛡️ Provider auth ${providerSecret ? \"shared secret required\" : \"disabled\"}`);\n console.log(hr);\n console.log(` Press Ctrl+C to stop.`);\n console.log();\n\n // Auto-launch browser only if explicitly opted in via MCP_BROKER_OPEN=1\n // AND a mount at \"/\" is configured.\n if (hasWwwRoot && process.env[\"MCP_BROKER_OPEN\"] === \"1\") {\n const url = `${localhost}/`;\n console.log(`🚀 Opening browser: ${url}`);\n console.log();\n await open(url);\n }\n\n // ── Signal handlers ─────────────────────────────────────────────────────\n const shutdown = async (signal: string): Promise<void> => {\n console.log(`\\n⛔ ${signal} received, shutting down…`);\n await tunnel.stop();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", () => void shutdown(\"SIGINT\"));\n process.on(\"SIGTERM\", () => void shutdown(\"SIGTERM\"));\n}\n\nmain().catch((err: unknown) => {\n console.error(\"[mcp-broker] Fatal error:\", err);\n process.exit(1);\n});\n"]}
|