@cyanmycelium/mcp-broker 0.4.0 → 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/CONFIGURATION-EN.md +861 -0
- package/.mcp-broker.example/CONFIGURATION-FR.md +871 -0
- package/.mcp-broker.example/README.md +8 -3
- package/.mcp-broker.example/config.json +86 -0
- package/README.md +122 -3
- package/dist/bin.d.ts +0 -1
- package/dist/bin.js +180 -208
- 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 -18
- package/dist/index.js +2 -14
- package/dist/index.js.map +1 -1
- package/package.json +14 -8
- 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 +98 -0
- package/src/auth/auth.types.ts +120 -0
- package/src/auth/http.auth.ts +128 -0
- package/src/auth/index.ts +34 -0
- package/src/auth/jwt.validator.ts +63 -0
- package/src/auth/provider.auth.ts +114 -0
- package/src/auth/resource.metadata.ts +34 -0
- package/src/authorization/audit.ts +35 -0
- package/src/authorization/capability.classifier.ts +114 -0
- package/src/authorization/index.ts +37 -0
- package/src/authorization/policy.engine.ts +212 -0
- package/src/authorization/policy.types.ts +105 -0
- package/src/authorization/resource.path.ts +126 -0
- package/src/authorization/runtime.ts +56 -0
- package/src/authorization/slot.resource.ts +50 -0
- package/src/authorization/subject.mapper.ts +81 -0
- package/src/bin.ts +90 -7
- package/src/broker/adapters/broker.adapter.info.ts +3 -3
- package/src/broker/adapters/broker.adapter.providers.ts +3 -3
- package/src/broker/aggregate/aggregate.catalog.ts +49 -21
- package/src/broker/aggregate/aggregate.server.ts +149 -19
- package/src/broker/aggregate/provider.client.session.ts +22 -22
- package/src/broker/behaviors/broker.behavior.info.ts +4 -4
- package/src/broker/behaviors/broker.behavior.providers.ts +6 -6
- package/src/broker/broker.context.ts +10 -4
- package/src/broker/broker.grammars.ts +16 -13
- package/src/broker/broker.server.ts +12 -9
- 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 +81 -8
- package/src/index.ts +121 -20
- package/src/{mcpb.loader.ts → mcpb/mcpb.loader.ts} +24 -21
- package/src/{mcpb.unzip.ts → mcpb/mcpb.unzip.ts} +2 -2
- package/src/remote.transports.ts +11 -8
- package/src/remote.upstream.ts +11 -8
- package/src/stdio.upstream.ts +9 -6
- package/src/upstream.ts +6 -3
- package/src/ws/ws.interfaces.ts +357 -0
- package/src/{ws.tunnel.builder.ts → ws/ws.tunnel.builder.ts} +112 -9
- package/src/{ws.tunnel.ts → ws/ws.tunnel.ts} +646 -457
- package/web/README.md +94 -0
- package/web/assets/logo.png +0 -0
- package/web/broker-self-mcp.html +338 -0
- package/web/css/styles.css +580 -0
- package/web/demos/DemoPlaceholder.html +258 -0
- package/web/demos/broker-explorer/css/app.css +393 -0
- package/web/demos/broker-explorer/index.html +94 -0
- package/web/demos/broker-explorer/js/app.js +271 -0
- package/web/demos/broker-explorer/js/mcp-ws-client.js +132 -0
- package/web/demos/oauth-lab/README.md +94 -0
- package/web/demos/oauth-lab/config.json +117 -0
- package/web/demos/oauth-lab/css/app.css +1097 -0
- package/web/demos/oauth-lab/index.html +323 -0
- package/web/demos/oauth-lab/js/app.js +654 -0
- package/web/demos/oauth-lab/server/auth-server.mjs +426 -0
- package/web/demos/oauth-lab/server/factory-provider.mjs +269 -0
- package/web/demos/oauth-lab/server/smoke-test.mjs +308 -0
- package/web/demos/oauth-lab/server/start.mjs +106 -0
- package/web/demos/provider-tunnel/css/app.css +384 -0
- package/web/demos/provider-tunnel/index.html +99 -0
- package/web/demos/provider-tunnel/js/app.js +226 -0
- package/web/demos/provider-tunnel/js/toolbox-server.js +186 -0
- package/web/index.html +558 -0
- package/web/js/lib/broker-tunnel.js +173 -0
- 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 -54
- package/dist/broker/aggregate/aggregate.catalog.js +0 -105
- package/dist/broker/aggregate/aggregate.catalog.js.map +0 -1
- package/dist/broker/aggregate/aggregate.server.d.ts +0 -47
- package/dist/broker/aggregate/aggregate.server.js +0 -151
- 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 -59
- 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 -130
- 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 -66
- 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 -136
- package/dist/config.js +0 -61
- package/dist/config.js.map +0 -1
- package/dist/mcpb.loader.d.ts +0 -24
- 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 -16
- package/dist/remote.transports.js +0 -297
- package/dist/remote.transports.js.map +0 -1
- package/dist/remote.upstream.d.ts +0 -36
- package/dist/remote.upstream.js +0 -52
- package/dist/remote.upstream.js.map +0 -1
- package/dist/stdio.upstream.d.ts +0 -45
- package/dist/stdio.upstream.js +0 -85
- package/dist/stdio.upstream.js.map +0 -1
- package/dist/upstream.d.ts +0 -33
- 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 -139
- package/dist/ws.tunnel.builder.js +0 -205
- package/dist/ws.tunnel.builder.js.map +0 -1
- package/dist/ws.tunnel.d.ts +0 -373
- package/dist/ws.tunnel.js +0 -1090
- 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
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* toolbox-server.js: the demo MCP server.
|
|
3
|
+
*
|
|
4
|
+
* A generic "toolbox" MCP server built with the official
|
|
5
|
+
* `@modelcontextprotocol/sdk`. It is plain MCP: nothing here knows about the
|
|
6
|
+
* broker. `app.js` wires it to a `BrokerTunnelTransport` to tunnel it through.
|
|
7
|
+
*
|
|
8
|
+
* Tool and resource definitions are exported as data (`TOOLS`, `RESOURCES`)
|
|
9
|
+
* so the UI can render a catalog from the same source the server advertises.
|
|
10
|
+
*
|
|
11
|
+
* Pinned to an exact SDK version: the CDN-served build of newer releases
|
|
12
|
+
* trips a zod resolution bug. Bump deliberately after testing.
|
|
13
|
+
*/
|
|
14
|
+
import { Server } from "https://esm.sh/@modelcontextprotocol/sdk@1.12.3/server/index.js";
|
|
15
|
+
import {
|
|
16
|
+
ListToolsRequestSchema,
|
|
17
|
+
CallToolRequestSchema,
|
|
18
|
+
ListResourcesRequestSchema,
|
|
19
|
+
ReadResourceRequestSchema,
|
|
20
|
+
} from "https://esm.sh/@modelcontextprotocol/sdk@1.12.3/types.js";
|
|
21
|
+
|
|
22
|
+
/** Tool catalog, advertised by `tools/list` and rendered by the UI. */
|
|
23
|
+
export const TOOLS = [
|
|
24
|
+
{
|
|
25
|
+
name: "echo",
|
|
26
|
+
description: "Returns the text it was given, unchanged.",
|
|
27
|
+
inputSchema: {
|
|
28
|
+
type: "object",
|
|
29
|
+
properties: { text: { type: "string", description: "Text to echo back." } },
|
|
30
|
+
required: ["text"],
|
|
31
|
+
additionalProperties: false,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "add",
|
|
36
|
+
description: "Adds two numbers and returns the sum.",
|
|
37
|
+
inputSchema: {
|
|
38
|
+
type: "object",
|
|
39
|
+
properties: {
|
|
40
|
+
a: { type: "number", description: "First addend." },
|
|
41
|
+
b: { type: "number", description: "Second addend." },
|
|
42
|
+
},
|
|
43
|
+
required: ["a", "b"],
|
|
44
|
+
additionalProperties: false,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "random",
|
|
49
|
+
description: "Returns a random number in the half-open interval [min, max).",
|
|
50
|
+
inputSchema: {
|
|
51
|
+
type: "object",
|
|
52
|
+
properties: {
|
|
53
|
+
min: { type: "number", description: "Lower bound (default 0)." },
|
|
54
|
+
max: { type: "number", description: "Upper bound (default 1)." },
|
|
55
|
+
},
|
|
56
|
+
additionalProperties: false,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "note_set",
|
|
61
|
+
description: "Stores a string value under a key in the in-memory note store.",
|
|
62
|
+
inputSchema: {
|
|
63
|
+
type: "object",
|
|
64
|
+
properties: {
|
|
65
|
+
key: { type: "string", description: "Note key." },
|
|
66
|
+
value: { type: "string", description: "Note value." },
|
|
67
|
+
},
|
|
68
|
+
required: ["key", "value"],
|
|
69
|
+
additionalProperties: false,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "note_get",
|
|
74
|
+
description: "Reads back the value previously stored under a key.",
|
|
75
|
+
inputSchema: {
|
|
76
|
+
type: "object",
|
|
77
|
+
properties: { key: { type: "string", description: "Note key to read." } },
|
|
78
|
+
required: ["key"],
|
|
79
|
+
additionalProperties: false,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: "note_list",
|
|
84
|
+
description: "Lists every key currently in the note store.",
|
|
85
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
/** Resource catalog, advertised by `resources/list` and rendered by the UI. */
|
|
90
|
+
export const RESOURCES = [
|
|
91
|
+
{
|
|
92
|
+
uri: "demo://clock",
|
|
93
|
+
name: "Server clock",
|
|
94
|
+
mimeType: "text/plain",
|
|
95
|
+
description: "The provider's current wall-clock time, ISO-8601.",
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
uri: "demo://notes",
|
|
99
|
+
name: "Note store",
|
|
100
|
+
mimeType: "application/json",
|
|
101
|
+
description: "Every stored note as a JSON object of key/value pairs.",
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
|
|
105
|
+
const ok = (text) => ({ content: [{ type: "text", text }] });
|
|
106
|
+
const fail = (text) => ({ content: [{ type: "text", text }], isError: true });
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Builds the demo toolbox MCP server. Each call gets its own note store.
|
|
110
|
+
*
|
|
111
|
+
* @param {object} opts
|
|
112
|
+
* @param {string} opts.name Server / slot name.
|
|
113
|
+
* @param {(msg: string, level?: string) => void} [opts.onActivity]
|
|
114
|
+
* Called on each tool call, resource read, and on the initialize
|
|
115
|
+
* handshake, lets the UI log tunnel traffic without this module
|
|
116
|
+
* depending on the DOM.
|
|
117
|
+
* @returns {import("https://esm.sh/@modelcontextprotocol/sdk@1.12.3/server/index.js").Server}
|
|
118
|
+
*/
|
|
119
|
+
export function createToolboxServer({ name, onActivity = () => {} }) {
|
|
120
|
+
/** In-memory note store, shared by the note_* tools and demo://notes. */
|
|
121
|
+
const notes = new Map();
|
|
122
|
+
|
|
123
|
+
const server = new Server({ name, version: "0.1.0" }, { capabilities: { tools: {}, resources: {} } });
|
|
124
|
+
|
|
125
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
126
|
+
|
|
127
|
+
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
128
|
+
const { name: tool, arguments: args = {} } = req.params;
|
|
129
|
+
onActivity(`tools/call → ${tool}(${JSON.stringify(args)})`, "info");
|
|
130
|
+
|
|
131
|
+
switch (tool) {
|
|
132
|
+
case "echo":
|
|
133
|
+
return ok(String(args.text ?? ""));
|
|
134
|
+
case "add": {
|
|
135
|
+
const a = Number(args.a);
|
|
136
|
+
const b = Number(args.b);
|
|
137
|
+
if (!Number.isFinite(a) || !Number.isFinite(b)) {
|
|
138
|
+
return fail("add: 'a' and 'b' must both be numbers.");
|
|
139
|
+
}
|
|
140
|
+
return ok(String(a + b));
|
|
141
|
+
}
|
|
142
|
+
case "random": {
|
|
143
|
+
const min = Number.isFinite(Number(args.min)) ? Number(args.min) : 0;
|
|
144
|
+
const max = Number.isFinite(Number(args.max)) ? Number(args.max) : 1;
|
|
145
|
+
return ok(String(min + Math.random() * (max - min)));
|
|
146
|
+
}
|
|
147
|
+
case "note_set": {
|
|
148
|
+
const key = String(args.key ?? "");
|
|
149
|
+
if (!key) return fail("note_set: 'key' is required.");
|
|
150
|
+
notes.set(key, String(args.value ?? ""));
|
|
151
|
+
return ok(`Stored note "${key}".`);
|
|
152
|
+
}
|
|
153
|
+
case "note_get": {
|
|
154
|
+
const key = String(args.key ?? "");
|
|
155
|
+
if (!notes.has(key)) return fail(`note_get: no note named "${key}".`);
|
|
156
|
+
return ok(notes.get(key));
|
|
157
|
+
}
|
|
158
|
+
case "note_list":
|
|
159
|
+
return ok(JSON.stringify([...notes.keys()]));
|
|
160
|
+
default:
|
|
161
|
+
return fail(`Unknown tool: ${tool}`);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => ({ resources: RESOURCES }));
|
|
166
|
+
|
|
167
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (req) => {
|
|
168
|
+
const { uri } = req.params;
|
|
169
|
+
onActivity(`resources/read → ${uri}`, "info");
|
|
170
|
+
if (uri === "demo://clock") {
|
|
171
|
+
return { contents: [{ uri, mimeType: "text/plain", text: new Date().toISOString() }] };
|
|
172
|
+
}
|
|
173
|
+
if (uri === "demo://notes") {
|
|
174
|
+
return {
|
|
175
|
+
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(Object.fromEntries(notes)) }],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Fires when an MCP client finishes the initialize handshake through the
|
|
182
|
+
// tunnel, proof the broker relayed a real client end to end.
|
|
183
|
+
server.oninitialized = () => onActivity("An MCP client completed the initialize handshake.", "ok");
|
|
184
|
+
|
|
185
|
+
return server;
|
|
186
|
+
}
|