@cyanmycelium/mcp-broker 0.1.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 +53 -0
- package/.mcp-broker.example/config.json +32 -0
- package/.mcp-broker.example/grammars/claude/fr.json +7 -0
- package/LICENSE +201 -0
- package/README.md +253 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +208 -0
- package/dist/bin.js.map +1 -0
- package/dist/broker/adapters/broker.adapter.info.d.ts +16 -0
- package/dist/broker/adapters/broker.adapter.info.js +43 -0
- package/dist/broker/adapters/broker.adapter.info.js.map +1 -0
- package/dist/broker/adapters/broker.adapter.providers.d.ts +18 -0
- package/dist/broker/adapters/broker.adapter.providers.js +61 -0
- package/dist/broker/adapters/broker.adapter.providers.js.map +1 -0
- package/dist/broker/behaviors/broker.behavior.info.d.ts +15 -0
- package/dist/broker/behaviors/broker.behavior.info.js +41 -0
- package/dist/broker/behaviors/broker.behavior.info.js.map +1 -0
- package/dist/broker/behaviors/broker.behavior.providers.d.ts +19 -0
- package/dist/broker/behaviors/broker.behavior.providers.js +69 -0
- package/dist/broker/behaviors/broker.behavior.providers.js.map +1 -0
- package/dist/broker/broker.context.d.ts +59 -0
- package/dist/broker/broker.context.js +2 -0
- package/dist/broker/broker.context.js.map +1 -0
- package/dist/broker/broker.grammars.d.ts +166 -0
- package/dist/broker/broker.grammars.js +258 -0
- package/dist/broker/broker.grammars.js.map +1 -0
- package/dist/broker/broker.server.d.ts +64 -0
- package/dist/broker/broker.server.js +111 -0
- package/dist/broker/broker.server.js.map +1 -0
- package/dist/broker/grammars/claude/en.json +16 -0
- package/dist/broker/grammars/claude/fr.json +16 -0
- package/dist/broker/grammars/default/en.json +32 -0
- package/dist/broker/grammars/default/fr.json +32 -0
- package/dist/broker/grammars/default/zh.json +32 -0
- package/dist/broker/index.d.ts +9 -0
- package/dist/broker/index.js +7 -0
- package/dist/broker/index.js.map +1 -0
- package/dist/config.d.ts +101 -0
- package/dist/config.js +61 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/stdio.upstream.d.ts +42 -0
- package/dist/stdio.upstream.js +85 -0
- package/dist/stdio.upstream.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +9 -0
- package/dist/version.js.map +1 -0
- package/dist/ws.tunnel.builder.d.ts +133 -0
- package/dist/ws.tunnel.builder.js +197 -0
- package/dist/ws.tunnel.builder.js.map +1 -0
- package/dist/ws.tunnel.d.ts +310 -0
- package/dist/ws.tunnel.js +971 -0
- package/dist/ws.tunnel.js.map +1 -0
- package/package.json +86 -0
- package/scripts/copy-assets.mjs +34 -0
- package/scripts/gen-cert.mjs +94 -0
- package/src/bin.ts +231 -0
- package/src/broker/adapters/broker.adapter.info.ts +46 -0
- package/src/broker/adapters/broker.adapter.providers.ts +67 -0
- package/src/broker/behaviors/broker.behavior.info.ts +46 -0
- package/src/broker/behaviors/broker.behavior.providers.ts +82 -0
- package/src/broker/broker.context.ts +75 -0
- package/src/broker/broker.grammars.ts +336 -0
- package/src/broker/broker.server.ts +168 -0
- package/src/broker/grammars/claude/en.json +16 -0
- package/src/broker/grammars/claude/fr.json +16 -0
- package/src/broker/grammars/default/en.json +32 -0
- package/src/broker/grammars/default/fr.json +32 -0
- package/src/broker/grammars/default/zh.json +32 -0
- package/src/broker/index.ts +24 -0
- package/src/config.ts +155 -0
- package/src/index.ts +26 -0
- package/src/stdio.upstream.ts +114 -0
- package/src/version.ts +10 -0
- package/src/ws.tunnel.builder.ts +214 -0
- package/src/ws.tunnel.ts +1269 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { WsTunnel, type WsTunnelOptions, type StaticMount } from "./ws.tunnel.js";
|
|
3
|
+
import type { StdioUpstreamConfig } from "./stdio.upstream.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Fluent builder that constructs a configured {@link WsTunnel}.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const tunnel = new WsTunnelBuilder()
|
|
11
|
+
* .withPort(3000)
|
|
12
|
+
* .withHost("localhost")
|
|
13
|
+
* .withStaticMount("/", "/abs/path/to/www")
|
|
14
|
+
* .build();
|
|
15
|
+
*
|
|
16
|
+
* await tunnel.start();
|
|
17
|
+
* console.log("Broker listening on ws://localhost:3000");
|
|
18
|
+
* console.log(" Provider connects to: ws://localhost:3000/provider/<name>");
|
|
19
|
+
* console.log(" Clients connect to: ws://localhost:3000/<name>");
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export class WsTunnelBuilder {
|
|
23
|
+
private _port = 3000;
|
|
24
|
+
private _host: string | undefined;
|
|
25
|
+
private _providerPath = "/provider";
|
|
26
|
+
private _providersPath = "/providers";
|
|
27
|
+
private _clientPath = "/";
|
|
28
|
+
private _ssePath = "/sse";
|
|
29
|
+
private _messagesPath = "/messages";
|
|
30
|
+
private _mcpPath = "/mcp";
|
|
31
|
+
private _samplesIndexPath = "/__samples_index__";
|
|
32
|
+
private _staticMounts: StaticMount[] = [];
|
|
33
|
+
private _stdioUpstreams: StdioUpstreamConfig[] = [];
|
|
34
|
+
private _stdioClient: { providerName: string } | undefined = undefined;
|
|
35
|
+
private _tls: { cert: string; key: string } | undefined = undefined;
|
|
36
|
+
private _brokerLocalGrammarsDir: string | undefined = undefined;
|
|
37
|
+
|
|
38
|
+
/** Sets the TCP port the broker listens on. */
|
|
39
|
+
withPort(port: number): this {
|
|
40
|
+
this._port = port;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Sets the host/interface to bind to.
|
|
46
|
+
* @default "0.0.0.0" (all interfaces)
|
|
47
|
+
*/
|
|
48
|
+
withHost(host: string): this {
|
|
49
|
+
this._host = host;
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Sets the URL path the MCP provider connects to.
|
|
55
|
+
* @default "/provider"
|
|
56
|
+
*/
|
|
57
|
+
withProviderPath(path: string): this {
|
|
58
|
+
this._providerPath = path;
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Sets the URL path for multiplexed provider connections.
|
|
64
|
+
* Multiple providers share a single WebSocket using the envelope protocol.
|
|
65
|
+
* @default "/providers"
|
|
66
|
+
*/
|
|
67
|
+
withProvidersPath(path: string): this {
|
|
68
|
+
this._providersPath = path;
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Sets the URL path MCP clients connect to.
|
|
74
|
+
* @default "/"
|
|
75
|
+
*/
|
|
76
|
+
withClientPath(path: string): this {
|
|
77
|
+
this._clientPath = path;
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Sets the URL path for the SSE stream (legacy Claude transport, GET).
|
|
83
|
+
* @default "/sse"
|
|
84
|
+
*/
|
|
85
|
+
withSsePath(path: string): this {
|
|
86
|
+
this._ssePath = path;
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Sets the URL path for JSON-RPC POST requests (legacy Claude transport).
|
|
92
|
+
* @default "/messages"
|
|
93
|
+
*/
|
|
94
|
+
withMessagesPath(path: string): this {
|
|
95
|
+
this._messagesPath = path;
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Sets the URL path for the Streamable HTTP transport (MCP 2025-03-26).
|
|
101
|
+
* MCP Inspector and other 2025+ clients POST JSON-RPC here.
|
|
102
|
+
* @default "/mcp"
|
|
103
|
+
*/
|
|
104
|
+
withMcpPath(path: string): this {
|
|
105
|
+
this._mcpPath = path;
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Sets the URL path that returns a `{ files: string[] }` listing of the
|
|
111
|
+
* `samples/` subdirectory under the root static mount.
|
|
112
|
+
* @default "/__samples_index__"
|
|
113
|
+
*/
|
|
114
|
+
withSamplesIndexPath(path: string): this {
|
|
115
|
+
this._samplesIndexPath = path;
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Adds a static-file mount served over plain HTTP.
|
|
121
|
+
* Can be called multiple times; longest-prefix match wins at runtime.
|
|
122
|
+
*
|
|
123
|
+
* @param urlPrefix URL prefix that triggers this mount (e.g. `"/"` or `"/bundle"`).
|
|
124
|
+
* @param dir Absolute path to the directory to serve.
|
|
125
|
+
*/
|
|
126
|
+
withStaticMount(urlPrefix: string, dir: string): this {
|
|
127
|
+
this._staticMounts.push({ urlPrefix, dir });
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Registers a stdio upstream provider. The broker will spawn the given
|
|
133
|
+
* command and bridge its stdin/stdout as an MCP transport.
|
|
134
|
+
* Clients reach it using `name` directly (e.g. `/<name>/mcp`).
|
|
135
|
+
*
|
|
136
|
+
* Can be called multiple times to register multiple providers.
|
|
137
|
+
*
|
|
138
|
+
* @param name Provider name (must be unique across all upstream types).
|
|
139
|
+
* @param command Executable to spawn.
|
|
140
|
+
* @param args Arguments passed to the command.
|
|
141
|
+
* @param env Extra environment variables merged with `process.env`.
|
|
142
|
+
*/
|
|
143
|
+
withStdioUpstream(name: string, command: string, args?: string[], env?: NodeJS.ProcessEnv): this {
|
|
144
|
+
this._stdioUpstreams.push({ name, command, args, env });
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Enables the stdio client transport. The broker will read JSON-RPC from
|
|
150
|
+
* `process.stdin` and write responses to `process.stdout`, bridging Claude
|
|
151
|
+
* Desktop (or any stdio MCP client) to the named provider.
|
|
152
|
+
*
|
|
153
|
+
* All console output is automatically redirected to stderr in this mode so
|
|
154
|
+
* stdout stays clean for the JSON-RPC stream.
|
|
155
|
+
*
|
|
156
|
+
* @param providerName The provider the stdio client maps to.
|
|
157
|
+
*/
|
|
158
|
+
withStdioClient(providerName: string): this {
|
|
159
|
+
this._stdioClient = { providerName };
|
|
160
|
+
return this;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Enables HTTPS/WSS mode by supplying PEM-encoded certificate and key strings directly.
|
|
165
|
+
* Call this when you already have the PEM content in memory.
|
|
166
|
+
*/
|
|
167
|
+
withTls(cert: string, key: string): this {
|
|
168
|
+
this._tls = { cert, key };
|
|
169
|
+
return this;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Enables HTTPS/WSS mode by reading the certificate and key from the given file paths.
|
|
174
|
+
* Files are read synchronously at call time.
|
|
175
|
+
*
|
|
176
|
+
* @param certPath Path to the PEM certificate file (e.g. `fullchain.pem`).
|
|
177
|
+
* @param keyPath Path to the PEM private-key file (e.g. `privkey.pem`).
|
|
178
|
+
*/
|
|
179
|
+
withTlsFiles(certPath: string, keyPath: string): this {
|
|
180
|
+
return this.withTls(fs.readFileSync(certPath, "utf8"), fs.readFileSync(keyPath, "utf8"));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Sets the path to a user-supplied grammars directory whose
|
|
185
|
+
* `<userAgent>/<locale>.json` files are merged on top of the packaged
|
|
186
|
+
* grammars used by the embedded broker server (the reserved `_broker`
|
|
187
|
+
* provider slot). Typically pointed at `.mcp-broker/grammars/`.
|
|
188
|
+
*/
|
|
189
|
+
withBrokerLocalGrammarsDir(dir: string): this {
|
|
190
|
+
this._brokerLocalGrammarsDir = dir;
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Constructs and returns a configured {@link WsTunnel}. */
|
|
195
|
+
build(): WsTunnel {
|
|
196
|
+
const options: WsTunnelOptions = {
|
|
197
|
+
port: this._port,
|
|
198
|
+
host: this._host,
|
|
199
|
+
providerPath: this._providerPath,
|
|
200
|
+
providersPath: this._providersPath,
|
|
201
|
+
clientPath: this._clientPath,
|
|
202
|
+
ssePath: this._ssePath,
|
|
203
|
+
messagesPath: this._messagesPath,
|
|
204
|
+
mcpPath: this._mcpPath,
|
|
205
|
+
samplesIndexPath: this._samplesIndexPath,
|
|
206
|
+
staticMounts: this._staticMounts.length > 0 ? [...this._staticMounts] : undefined,
|
|
207
|
+
stdioUpstreams: this._stdioUpstreams.length > 0 ? [...this._stdioUpstreams] : undefined,
|
|
208
|
+
stdioClient: this._stdioClient,
|
|
209
|
+
tls: this._tls,
|
|
210
|
+
brokerLocalGrammarsDir: this._brokerLocalGrammarsDir,
|
|
211
|
+
};
|
|
212
|
+
return new WsTunnel(options);
|
|
213
|
+
}
|
|
214
|
+
}
|