@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.
Files changed (151) hide show
  1. package/.mcp-broker.example/CONFIGURATION-EN.md +861 -0
  2. package/.mcp-broker.example/CONFIGURATION-FR.md +871 -0
  3. package/.mcp-broker.example/README.md +8 -3
  4. package/.mcp-broker.example/config.json +86 -0
  5. package/README.md +122 -3
  6. package/dist/bin.d.ts +0 -1
  7. package/dist/bin.js +180 -208
  8. package/dist/bin.js.map +1 -1
  9. package/dist/chunk-FTDKH2C4.js +3670 -0
  10. package/dist/chunk-FTDKH2C4.js.map +1 -0
  11. package/dist/{broker/grammars → grammars}/claude/en.json +1 -1
  12. package/dist/{broker/grammars → grammars}/claude/fr.json +1 -1
  13. package/dist/index.d.ts +1790 -18
  14. package/dist/index.js +2 -14
  15. package/dist/index.js.map +1 -1
  16. package/package.json +14 -8
  17. package/scripts/copy-assets.mjs +16 -10
  18. package/scripts/gen-cert.mjs +5 -5
  19. package/scripts/pack-mcpb.mjs +5 -5
  20. package/scripts/sign-bundle.mjs +6 -6
  21. package/src/auth/auth.config.ts +98 -0
  22. package/src/auth/auth.types.ts +120 -0
  23. package/src/auth/http.auth.ts +128 -0
  24. package/src/auth/index.ts +34 -0
  25. package/src/auth/jwt.validator.ts +63 -0
  26. package/src/auth/provider.auth.ts +114 -0
  27. package/src/auth/resource.metadata.ts +34 -0
  28. package/src/authorization/audit.ts +35 -0
  29. package/src/authorization/capability.classifier.ts +114 -0
  30. package/src/authorization/index.ts +37 -0
  31. package/src/authorization/policy.engine.ts +212 -0
  32. package/src/authorization/policy.types.ts +105 -0
  33. package/src/authorization/resource.path.ts +126 -0
  34. package/src/authorization/runtime.ts +56 -0
  35. package/src/authorization/slot.resource.ts +50 -0
  36. package/src/authorization/subject.mapper.ts +81 -0
  37. package/src/bin.ts +90 -7
  38. package/src/broker/adapters/broker.adapter.info.ts +3 -3
  39. package/src/broker/adapters/broker.adapter.providers.ts +3 -3
  40. package/src/broker/aggregate/aggregate.catalog.ts +49 -21
  41. package/src/broker/aggregate/aggregate.server.ts +149 -19
  42. package/src/broker/aggregate/provider.client.session.ts +22 -22
  43. package/src/broker/behaviors/broker.behavior.info.ts +4 -4
  44. package/src/broker/behaviors/broker.behavior.providers.ts +6 -6
  45. package/src/broker/broker.context.ts +10 -4
  46. package/src/broker/broker.grammars.ts +16 -13
  47. package/src/broker/broker.server.ts +12 -9
  48. package/src/broker/grammars/claude/en.json +1 -1
  49. package/src/broker/grammars/claude/fr.json +1 -1
  50. package/src/broker/index.ts +9 -9
  51. package/src/config.ts +81 -8
  52. package/src/index.ts +121 -20
  53. package/src/{mcpb.loader.ts → mcpb/mcpb.loader.ts} +24 -21
  54. package/src/{mcpb.unzip.ts → mcpb/mcpb.unzip.ts} +2 -2
  55. package/src/remote.transports.ts +11 -8
  56. package/src/remote.upstream.ts +11 -8
  57. package/src/stdio.upstream.ts +9 -6
  58. package/src/upstream.ts +6 -3
  59. package/src/ws/ws.interfaces.ts +357 -0
  60. package/src/{ws.tunnel.builder.ts → ws/ws.tunnel.builder.ts} +112 -9
  61. package/src/{ws.tunnel.ts → ws/ws.tunnel.ts} +646 -457
  62. package/web/README.md +94 -0
  63. package/web/assets/logo.png +0 -0
  64. package/web/broker-self-mcp.html +338 -0
  65. package/web/css/styles.css +580 -0
  66. package/web/demos/DemoPlaceholder.html +258 -0
  67. package/web/demos/broker-explorer/css/app.css +393 -0
  68. package/web/demos/broker-explorer/index.html +94 -0
  69. package/web/demos/broker-explorer/js/app.js +271 -0
  70. package/web/demos/broker-explorer/js/mcp-ws-client.js +132 -0
  71. package/web/demos/oauth-lab/README.md +94 -0
  72. package/web/demos/oauth-lab/config.json +117 -0
  73. package/web/demos/oauth-lab/css/app.css +1097 -0
  74. package/web/demos/oauth-lab/index.html +323 -0
  75. package/web/demos/oauth-lab/js/app.js +654 -0
  76. package/web/demos/oauth-lab/server/auth-server.mjs +426 -0
  77. package/web/demos/oauth-lab/server/factory-provider.mjs +269 -0
  78. package/web/demos/oauth-lab/server/smoke-test.mjs +308 -0
  79. package/web/demos/oauth-lab/server/start.mjs +106 -0
  80. package/web/demos/provider-tunnel/css/app.css +384 -0
  81. package/web/demos/provider-tunnel/index.html +99 -0
  82. package/web/demos/provider-tunnel/js/app.js +226 -0
  83. package/web/demos/provider-tunnel/js/toolbox-server.js +186 -0
  84. package/web/index.html +558 -0
  85. package/web/js/lib/broker-tunnel.js +173 -0
  86. package/dist/broker/adapters/broker.adapter.info.d.ts +0 -16
  87. package/dist/broker/adapters/broker.adapter.info.js +0 -43
  88. package/dist/broker/adapters/broker.adapter.info.js.map +0 -1
  89. package/dist/broker/adapters/broker.adapter.providers.d.ts +0 -18
  90. package/dist/broker/adapters/broker.adapter.providers.js +0 -61
  91. package/dist/broker/adapters/broker.adapter.providers.js.map +0 -1
  92. package/dist/broker/aggregate/aggregate.catalog.d.ts +0 -54
  93. package/dist/broker/aggregate/aggregate.catalog.js +0 -105
  94. package/dist/broker/aggregate/aggregate.catalog.js.map +0 -1
  95. package/dist/broker/aggregate/aggregate.server.d.ts +0 -47
  96. package/dist/broker/aggregate/aggregate.server.js +0 -151
  97. package/dist/broker/aggregate/aggregate.server.js.map +0 -1
  98. package/dist/broker/aggregate/provider.client.session.d.ts +0 -52
  99. package/dist/broker/aggregate/provider.client.session.js +0 -140
  100. package/dist/broker/aggregate/provider.client.session.js.map +0 -1
  101. package/dist/broker/behaviors/broker.behavior.info.d.ts +0 -15
  102. package/dist/broker/behaviors/broker.behavior.info.js +0 -41
  103. package/dist/broker/behaviors/broker.behavior.info.js.map +0 -1
  104. package/dist/broker/behaviors/broker.behavior.providers.d.ts +0 -19
  105. package/dist/broker/behaviors/broker.behavior.providers.js +0 -69
  106. package/dist/broker/behaviors/broker.behavior.providers.js.map +0 -1
  107. package/dist/broker/broker.context.d.ts +0 -59
  108. package/dist/broker/broker.context.js +0 -2
  109. package/dist/broker/broker.context.js.map +0 -1
  110. package/dist/broker/broker.grammars.d.ts +0 -130
  111. package/dist/broker/broker.grammars.js +0 -229
  112. package/dist/broker/broker.grammars.js.map +0 -1
  113. package/dist/broker/broker.server.d.ts +0 -66
  114. package/dist/broker/broker.server.js +0 -73
  115. package/dist/broker/broker.server.js.map +0 -1
  116. package/dist/broker/index.d.ts +0 -9
  117. package/dist/broker/index.js +0 -7
  118. package/dist/broker/index.js.map +0 -1
  119. package/dist/config.d.ts +0 -136
  120. package/dist/config.js +0 -61
  121. package/dist/config.js.map +0 -1
  122. package/dist/mcpb.loader.d.ts +0 -24
  123. package/dist/mcpb.loader.js +0 -161
  124. package/dist/mcpb.loader.js.map +0 -1
  125. package/dist/mcpb.unzip.d.ts +0 -6
  126. package/dist/mcpb.unzip.js +0 -95
  127. package/dist/mcpb.unzip.js.map +0 -1
  128. package/dist/remote.transports.d.ts +0 -16
  129. package/dist/remote.transports.js +0 -297
  130. package/dist/remote.transports.js.map +0 -1
  131. package/dist/remote.upstream.d.ts +0 -36
  132. package/dist/remote.upstream.js +0 -52
  133. package/dist/remote.upstream.js.map +0 -1
  134. package/dist/stdio.upstream.d.ts +0 -45
  135. package/dist/stdio.upstream.js +0 -85
  136. package/dist/stdio.upstream.js.map +0 -1
  137. package/dist/upstream.d.ts +0 -33
  138. package/dist/upstream.js +0 -2
  139. package/dist/upstream.js.map +0 -1
  140. package/dist/version.d.ts +0 -2
  141. package/dist/version.js +0 -9
  142. package/dist/version.js.map +0 -1
  143. package/dist/ws.tunnel.builder.d.ts +0 -139
  144. package/dist/ws.tunnel.builder.js +0 -205
  145. package/dist/ws.tunnel.builder.js.map +0 -1
  146. package/dist/ws.tunnel.d.ts +0 -373
  147. package/dist/ws.tunnel.js +0 -1090
  148. package/dist/ws.tunnel.js.map +0 -1
  149. /package/dist/{broker/grammars → grammars}/default/en.json +0 -0
  150. /package/dist/{broker/grammars → grammars}/default/fr.json +0 -0
  151. /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
+ }