@aiwerk/mcp-bridge 1.0.0 → 1.0.1

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 (63) hide show
  1. package/dist/bin/mcp-bridge.d.ts +2 -0
  2. package/dist/bin/mcp-bridge.js +320 -0
  3. package/dist/src/config.d.ts +19 -0
  4. package/dist/src/config.js +145 -0
  5. package/{src/index.ts → dist/src/index.d.ts} +1 -30
  6. package/dist/src/index.js +21 -0
  7. package/dist/src/mcp-router.d.ts +65 -0
  8. package/dist/src/mcp-router.js +271 -0
  9. package/dist/src/protocol.d.ts +4 -0
  10. package/dist/src/protocol.js +58 -0
  11. package/dist/src/schema-convert.d.ts +11 -0
  12. package/dist/src/schema-convert.js +150 -0
  13. package/dist/src/standalone-server.d.ts +30 -0
  14. package/dist/src/standalone-server.js +312 -0
  15. package/dist/src/tool-naming.d.ts +3 -0
  16. package/dist/src/tool-naming.js +38 -0
  17. package/dist/src/transport-base.d.ts +76 -0
  18. package/dist/src/transport-base.js +163 -0
  19. package/dist/src/transport-sse.d.ts +16 -0
  20. package/dist/src/transport-sse.js +207 -0
  21. package/dist/src/transport-stdio.d.ts +20 -0
  22. package/dist/src/transport-stdio.js +281 -0
  23. package/dist/src/transport-streamable-http.d.ts +11 -0
  24. package/dist/src/transport-streamable-http.js +164 -0
  25. package/dist/src/types.d.ts +72 -0
  26. package/dist/src/types.js +4 -0
  27. package/dist/src/update-checker.d.ts +25 -0
  28. package/dist/src/update-checker.js +132 -0
  29. package/package.json +19 -4
  30. package/scripts/install-server.ps1 +25 -58
  31. package/scripts/install-server.sh +37 -90
  32. package/servers/apify/README.md +6 -6
  33. package/servers/github/README.md +6 -6
  34. package/servers/google-maps/README.md +6 -6
  35. package/servers/hetzner/README.md +6 -6
  36. package/servers/hostinger/README.md +6 -6
  37. package/servers/linear/README.md +6 -6
  38. package/servers/miro/README.md +6 -6
  39. package/servers/notion/README.md +6 -6
  40. package/servers/stripe/README.md +6 -6
  41. package/servers/tavily/README.md +6 -6
  42. package/servers/todoist/README.md +6 -6
  43. package/servers/wise/README.md +6 -6
  44. package/bin/mcp-bridge.js +0 -9
  45. package/bin/mcp-bridge.ts +0 -335
  46. package/src/config.ts +0 -168
  47. package/src/mcp-router.ts +0 -366
  48. package/src/protocol.ts +0 -69
  49. package/src/schema-convert.ts +0 -178
  50. package/src/standalone-server.ts +0 -385
  51. package/src/tool-naming.ts +0 -51
  52. package/src/transport-base.ts +0 -199
  53. package/src/transport-sse.ts +0 -230
  54. package/src/transport-stdio.ts +0 -312
  55. package/src/transport-streamable-http.ts +0 -188
  56. package/src/types.ts +0 -88
  57. package/src/update-checker.ts +0 -155
  58. package/tests/collision.test.ts +0 -60
  59. package/tests/env-resolve.test.ts +0 -68
  60. package/tests/mcp-router.test.ts +0 -301
  61. package/tests/schema-convert.test.ts +0 -70
  62. package/tests/transport-base.test.ts +0 -214
  63. package/tsconfig.json +0 -15
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,320 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, existsSync } from "fs";
3
+ import { join, dirname, resolve } from "path";
4
+ import { fileURLToPath } from "url";
5
+ import { execSync } from "child_process";
6
+ import { loadConfig, initConfigDir } from "../src/config.js";
7
+ import { StandaloneServer } from "../src/standalone-server.js";
8
+ import { PACKAGE_VERSION } from "../src/protocol.js";
9
+ import { checkForUpdate, runUpdate } from "../src/update-checker.js";
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+ // After tsc, this file lives at dist/bin/mcp-bridge.js.
13
+ // Package root is two levels up: dist/bin/ -> dist/ -> package root.
14
+ const PACKAGE_ROOT = join(__dirname, "..", "..");
15
+ function createLogger(level) {
16
+ const levels = { error: 0, warn: 1, info: 2, debug: 3 };
17
+ const threshold = levels[level];
18
+ const ts = () => new Date().toISOString().replace("T", " ").replace("Z", "");
19
+ return {
20
+ error: (...args) => {
21
+ if (threshold >= 0)
22
+ process.stderr.write(`[${ts()}] [ERROR] ${args.map(String).join(" ")}\n`);
23
+ },
24
+ warn: (...args) => {
25
+ if (threshold >= 1)
26
+ process.stderr.write(`[${ts()}] [WARN] ${args.map(String).join(" ")}\n`);
27
+ },
28
+ info: (...args) => {
29
+ if (threshold >= 2)
30
+ process.stderr.write(`[${ts()}] [INFO] ${args.map(String).join(" ")}\n`);
31
+ },
32
+ debug: (...args) => {
33
+ if (threshold >= 3)
34
+ process.stderr.write(`[${ts()}] [DEBUG] ${args.map(String).join(" ")}\n`);
35
+ },
36
+ };
37
+ }
38
+ function parseArgs(argv) {
39
+ const args = {
40
+ command: "serve",
41
+ sse: false,
42
+ http: false,
43
+ port: 3000,
44
+ verbose: false,
45
+ debug: false,
46
+ positional: [],
47
+ checkOnly: false,
48
+ offline: false,
49
+ };
50
+ let i = 0;
51
+ while (i < argv.length) {
52
+ const arg = argv[i];
53
+ switch (arg) {
54
+ case "--sse":
55
+ args.sse = true;
56
+ break;
57
+ case "--http":
58
+ args.http = true;
59
+ break;
60
+ case "--port":
61
+ i++;
62
+ args.port = parseInt(argv[i], 10);
63
+ if (isNaN(args.port)) {
64
+ process.stderr.write("Error: --port requires a number\n");
65
+ process.exit(1);
66
+ }
67
+ break;
68
+ case "--config":
69
+ i++;
70
+ args.configPath = resolve(argv[i]);
71
+ break;
72
+ case "--verbose":
73
+ args.verbose = true;
74
+ break;
75
+ case "--debug":
76
+ args.debug = true;
77
+ break;
78
+ case "--version":
79
+ args.command = "version";
80
+ break;
81
+ case "--help":
82
+ case "-h":
83
+ args.command = "help";
84
+ break;
85
+ case "--check":
86
+ args.checkOnly = true;
87
+ break;
88
+ case "--offline":
89
+ args.offline = true;
90
+ break;
91
+ case "init":
92
+ args.command = "init";
93
+ break;
94
+ case "install":
95
+ args.command = "install";
96
+ break;
97
+ case "catalog":
98
+ args.command = "catalog";
99
+ break;
100
+ case "servers":
101
+ args.command = "servers";
102
+ break;
103
+ case "search":
104
+ args.command = "search";
105
+ break;
106
+ case "update":
107
+ args.command = "update";
108
+ break;
109
+ default:
110
+ if (!arg.startsWith("-")) {
111
+ args.positional.push(arg);
112
+ }
113
+ break;
114
+ }
115
+ i++;
116
+ }
117
+ return args;
118
+ }
119
+ // -- Commands -------------------------------------------------------------
120
+ function printVersion() {
121
+ process.stdout.write(`mcp-bridge ${PACKAGE_VERSION}\n`);
122
+ }
123
+ function printHelp() {
124
+ process.stdout.write(`
125
+ mcp-bridge v${PACKAGE_VERSION} — MCP server multiplexer
126
+
127
+ Usage:
128
+ mcp-bridge Start in stdio mode (default)
129
+ mcp-bridge --sse --port 3000 Start as SSE server
130
+ mcp-bridge --http --port 3000 Start as streamable-http server
131
+ mcp-bridge init Create ~/.mcp-bridge/ with config template
132
+ mcp-bridge install <server> Install a server from the catalog
133
+ mcp-bridge catalog [--offline] List available servers
134
+ mcp-bridge servers List configured servers
135
+ mcp-bridge search <query> Search catalog by keyword
136
+ mcp-bridge update [--check] Check for / install updates
137
+
138
+ Options:
139
+ --config PATH Custom config file (default: ~/.mcp-bridge/config.json)
140
+ --verbose Info-level logs to stderr
141
+ --debug Full protocol-level logs to stderr
142
+ --version Print version
143
+ --help Show this help
144
+
145
+ All logs go to stderr. Stdout is reserved for the MCP protocol (stdio mode).
146
+ `);
147
+ }
148
+ function cmdInit(logger) {
149
+ initConfigDir(logger);
150
+ }
151
+ function cmdCatalog(logger, offline) {
152
+ const catalogPath = join(PACKAGE_ROOT, "servers", "index.json");
153
+ if (!existsSync(catalogPath)) {
154
+ logger.error("Server catalog not found");
155
+ process.exit(1);
156
+ }
157
+ const catalog = JSON.parse(readFileSync(catalogPath, "utf-8"));
158
+ const servers = catalog.servers || {};
159
+ process.stdout.write("\nAvailable servers:\n\n");
160
+ process.stdout.write(" Server Transport Description\n");
161
+ process.stdout.write(" " + "─".repeat(60) + "\n");
162
+ for (const [name, info] of Object.entries(servers)) {
163
+ const padded = name.padEnd(16);
164
+ const transport = (info.transport || "stdio").padEnd(13);
165
+ process.stdout.write(` ${padded}${transport}${info.description || ""}\n`);
166
+ }
167
+ process.stdout.write("\n");
168
+ }
169
+ function cmdServers(logger, configPath) {
170
+ try {
171
+ const config = loadConfig({ configPath, logger });
172
+ const servers = config.servers || {};
173
+ const entries = Object.entries(servers);
174
+ if (entries.length === 0) {
175
+ process.stdout.write("No servers configured.\n");
176
+ return;
177
+ }
178
+ process.stdout.write("\nConfigured servers:\n\n");
179
+ process.stdout.write(" Server Transport Description\n");
180
+ process.stdout.write(" " + "─".repeat(60) + "\n");
181
+ for (const [name, serverConfig] of entries) {
182
+ const padded = name.padEnd(16);
183
+ const transport = serverConfig.transport.padEnd(13);
184
+ process.stdout.write(` ${padded}${transport}${serverConfig.description || ""}\n`);
185
+ }
186
+ process.stdout.write("\n");
187
+ }
188
+ catch (err) {
189
+ logger.error(err instanceof Error ? err.message : String(err));
190
+ process.exit(1);
191
+ }
192
+ }
193
+ function cmdSearch(query, logger) {
194
+ const catalogPath = join(PACKAGE_ROOT, "servers", "index.json");
195
+ if (!existsSync(catalogPath)) {
196
+ logger.error("Server catalog not found");
197
+ process.exit(1);
198
+ }
199
+ const catalog = JSON.parse(readFileSync(catalogPath, "utf-8"));
200
+ const servers = catalog.servers || {};
201
+ const lowerQuery = query.toLowerCase();
202
+ const matches = Object.entries(servers).filter(([name, info]) => {
203
+ return name.toLowerCase().includes(lowerQuery) ||
204
+ (info.description || "").toLowerCase().includes(lowerQuery);
205
+ });
206
+ if (matches.length === 0) {
207
+ process.stdout.write(`No servers matching "${query}"\n`);
208
+ return;
209
+ }
210
+ process.stdout.write(`\nSearch results for "${query}":\n\n`);
211
+ for (const [i, [name, info]] of matches.entries()) {
212
+ process.stdout.write(` ${i + 1} ${name.padEnd(16)}${info.description || ""}\n`);
213
+ }
214
+ process.stdout.write("\n");
215
+ }
216
+ function cmdInstall(serverName, logger) {
217
+ const scriptPath = join(PACKAGE_ROOT, "scripts", "install-server.sh");
218
+ if (!existsSync(scriptPath)) {
219
+ logger.error("Install script not found");
220
+ process.exit(1);
221
+ }
222
+ try {
223
+ execSync(`bash "${scriptPath}" "${serverName}"`, { stdio: "inherit" });
224
+ }
225
+ catch (err) {
226
+ process.exit(1);
227
+ }
228
+ }
229
+ async function cmdUpdate(logger, checkOnly) {
230
+ if (checkOnly) {
231
+ const info = await checkForUpdate(logger);
232
+ if (info.updateAvailable) {
233
+ process.stdout.write(`Update available: ${info.currentVersion} → ${info.latestVersion}\n`);
234
+ process.stdout.write(`Run 'mcp-bridge update' to install.\n`);
235
+ }
236
+ else {
237
+ process.stdout.write(`mcp-bridge ${info.currentVersion} is up to date.\n`);
238
+ }
239
+ return;
240
+ }
241
+ const result = await runUpdate(logger);
242
+ process.stdout.write(result + "\n");
243
+ }
244
+ async function cmdServe(args, logger) {
245
+ let config;
246
+ try {
247
+ config = loadConfig({ configPath: args.configPath, logger });
248
+ }
249
+ catch (err) {
250
+ logger.error(err instanceof Error ? err.message : String(err));
251
+ process.exit(1);
252
+ }
253
+ // HTTP modes: require auth
254
+ if ((args.sse || args.http) && !config.http?.auth?.token) {
255
+ logger.error("HTTP auth not configured. Set http.auth in config or use stdio mode.");
256
+ process.exit(1);
257
+ }
258
+ const server = new StandaloneServer(config, logger);
259
+ // Graceful shutdown
260
+ const shutdown = async () => {
261
+ await server.shutdown();
262
+ process.exit(0);
263
+ };
264
+ process.on("SIGTERM", shutdown);
265
+ process.on("SIGINT", shutdown);
266
+ if (args.sse || args.http) {
267
+ // SSE/HTTP mode: not yet implemented in standalone, show message
268
+ logger.error("SSE and HTTP server modes are not yet implemented. Use stdio mode (default).");
269
+ process.exit(1);
270
+ }
271
+ // Default: stdio mode
272
+ await server.startStdio();
273
+ }
274
+ // -- Main -----------------------------------------------------------------
275
+ async function main() {
276
+ const args = parseArgs(process.argv.slice(2));
277
+ const logLevel = args.debug ? "debug" : args.verbose ? "info" : "warn";
278
+ const logger = createLogger(logLevel);
279
+ switch (args.command) {
280
+ case "version":
281
+ printVersion();
282
+ break;
283
+ case "help":
284
+ printHelp();
285
+ break;
286
+ case "init":
287
+ cmdInit(logger);
288
+ break;
289
+ case "catalog":
290
+ cmdCatalog(logger, args.offline);
291
+ break;
292
+ case "servers":
293
+ cmdServers(logger, args.configPath);
294
+ break;
295
+ case "search":
296
+ if (args.positional.length === 0) {
297
+ process.stderr.write("Usage: mcp-bridge search <query>\n");
298
+ process.exit(1);
299
+ }
300
+ cmdSearch(args.positional[0], logger);
301
+ break;
302
+ case "install":
303
+ if (args.positional.length === 0) {
304
+ process.stderr.write("Usage: mcp-bridge install <server>\n");
305
+ process.exit(1);
306
+ }
307
+ cmdInstall(args.positional[0], logger);
308
+ break;
309
+ case "update":
310
+ await cmdUpdate(logger, args.checkOnly);
311
+ break;
312
+ case "serve":
313
+ await cmdServe(args, logger);
314
+ break;
315
+ }
316
+ }
317
+ main().catch(err => {
318
+ process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}\n`);
319
+ process.exit(1);
320
+ });
@@ -0,0 +1,19 @@
1
+ import { BridgeConfig, Logger } from "./types.js";
2
+ /** Parse a simple KEY=VALUE .env file (no npm dependency). */
3
+ export declare function parseEnvFile(content: string): Record<string, string>;
4
+ export interface LoadConfigOptions {
5
+ configPath?: string;
6
+ logger?: Logger;
7
+ }
8
+ /**
9
+ * Load and validate bridge config.
10
+ * 1. Read ~/.mcp-bridge/config.json (or custom path)
11
+ * 2. Parse ~/.mcp-bridge/.env
12
+ * 3. Resolve ${ENV_VAR} in config values
13
+ * 4. Validate required fields
14
+ */
15
+ export declare function loadConfig(options?: LoadConfigOptions): BridgeConfig;
16
+ /** Get the default config directory path. */
17
+ export declare function getConfigDir(configPath?: string): string;
18
+ /** Initialize the config directory with template files. */
19
+ export declare function initConfigDir(logger: Logger): void;
@@ -0,0 +1,145 @@
1
+ import { readFileSync, existsSync, mkdirSync, writeFileSync, chmodSync } from "fs";
2
+ import { join } from "path";
3
+ import { homedir } from "os";
4
+ import { resolveEnvVars } from "./transport-base.js";
5
+ import { randomBytes } from "crypto";
6
+ const DEFAULT_CONFIG_DIR = join(homedir(), ".mcp-bridge");
7
+ const DEFAULT_CONFIG_FILE = "config.json";
8
+ const DEFAULT_ENV_FILE = ".env";
9
+ /** Parse a simple KEY=VALUE .env file (no npm dependency). */
10
+ export function parseEnvFile(content) {
11
+ const env = {};
12
+ for (const line of content.split("\n")) {
13
+ const trimmed = line.trim();
14
+ if (!trimmed || trimmed.startsWith("#"))
15
+ continue;
16
+ const eqIdx = trimmed.indexOf("=");
17
+ if (eqIdx === -1)
18
+ continue;
19
+ const key = trimmed.substring(0, eqIdx).trim();
20
+ let value = trimmed.substring(eqIdx + 1).trim();
21
+ // Strip surrounding quotes
22
+ if ((value.startsWith('"') && value.endsWith('"')) ||
23
+ (value.startsWith("'") && value.endsWith("'"))) {
24
+ value = value.slice(1, -1);
25
+ }
26
+ if (key)
27
+ env[key] = value;
28
+ }
29
+ return env;
30
+ }
31
+ /** Recursively resolve ${VAR} placeholders in a JSON-compatible value. */
32
+ function resolveConfigValue(value, extraEnv) {
33
+ if (typeof value === "string") {
34
+ return resolveEnvVars(value, "config value", extraEnv);
35
+ }
36
+ if (Array.isArray(value)) {
37
+ return value.map(item => resolveConfigValue(item, extraEnv));
38
+ }
39
+ if (value !== null && typeof value === "object") {
40
+ const resolved = {};
41
+ for (const [k, v] of Object.entries(value)) {
42
+ resolved[k] = resolveConfigValue(v, extraEnv);
43
+ }
44
+ return resolved;
45
+ }
46
+ return value;
47
+ }
48
+ /**
49
+ * Load and validate bridge config.
50
+ * 1. Read ~/.mcp-bridge/config.json (or custom path)
51
+ * 2. Parse ~/.mcp-bridge/.env
52
+ * 3. Resolve ${ENV_VAR} in config values
53
+ * 4. Validate required fields
54
+ */
55
+ export function loadConfig(options = {}) {
56
+ const configDir = options.configPath
57
+ ? join(options.configPath, "..") // If a file path is given, derive directory
58
+ : DEFAULT_CONFIG_DIR;
59
+ const configPath = options.configPath || join(DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILE);
60
+ const envPath = join(options.configPath ? join(options.configPath, "..") : DEFAULT_CONFIG_DIR, DEFAULT_ENV_FILE);
61
+ if (!existsSync(configPath)) {
62
+ throw new Error(`Config file not found: ${configPath}\nRun 'mcp-bridge init' to set up.`);
63
+ }
64
+ // Load .env file
65
+ let dotEnv = {};
66
+ if (existsSync(envPath)) {
67
+ try {
68
+ dotEnv = parseEnvFile(readFileSync(envPath, "utf-8"));
69
+ }
70
+ catch (err) {
71
+ options.logger?.warn(`[mcp-bridge] Failed to parse .env file: ${err instanceof Error ? err.message : err}`);
72
+ }
73
+ }
74
+ // Merge .env into process.env (don't overwrite existing)
75
+ for (const [key, value] of Object.entries(dotEnv)) {
76
+ if (process.env[key] === undefined) {
77
+ process.env[key] = value;
78
+ }
79
+ }
80
+ // Read and parse config
81
+ const rawConfig = JSON.parse(readFileSync(configPath, "utf-8"));
82
+ // Resolve ${VAR} placeholders using .env + process.env
83
+ const mergedEnv = { ...dotEnv };
84
+ for (const [k, v] of Object.entries(process.env)) {
85
+ if (mergedEnv[k] === undefined)
86
+ mergedEnv[k] = v;
87
+ }
88
+ let config;
89
+ try {
90
+ config = resolveConfigValue(rawConfig, mergedEnv);
91
+ }
92
+ catch (err) {
93
+ throw new Error(`Config resolution failed: ${err instanceof Error ? err.message : err}`);
94
+ }
95
+ // Validate required fields
96
+ if (!config.servers || typeof config.servers !== "object") {
97
+ throw new Error("Config must have a 'servers' object");
98
+ }
99
+ return config;
100
+ }
101
+ /** Get the default config directory path. */
102
+ export function getConfigDir(configPath) {
103
+ return configPath ? join(configPath, "..") : DEFAULT_CONFIG_DIR;
104
+ }
105
+ /** Initialize the config directory with template files. */
106
+ export function initConfigDir(logger) {
107
+ const dir = DEFAULT_CONFIG_DIR;
108
+ mkdirSync(dir, { recursive: true });
109
+ // Set directory permissions (Linux/macOS)
110
+ try {
111
+ chmodSync(dir, 0o700);
112
+ }
113
+ catch { /* Windows doesn't support chmod */ }
114
+ const configPath = join(dir, DEFAULT_CONFIG_FILE);
115
+ if (!existsSync(configPath)) {
116
+ const template = {
117
+ mode: "router",
118
+ servers: {},
119
+ toolPrefix: true,
120
+ connectionTimeoutMs: 5000,
121
+ requestTimeoutMs: 60000,
122
+ routerIdleTimeoutMs: 600000,
123
+ routerMaxConcurrent: 5,
124
+ http: {
125
+ auth: {
126
+ type: "bearer",
127
+ token: "${MCP_BRIDGE_TOKEN}"
128
+ }
129
+ }
130
+ };
131
+ writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
132
+ logger.info(`Created config: ${configPath}`);
133
+ }
134
+ const envPath = join(dir, DEFAULT_ENV_FILE);
135
+ if (!existsSync(envPath)) {
136
+ const token = randomBytes(32).toString("hex");
137
+ writeFileSync(envPath, `# MCP Bridge environment variables\nMCP_BRIDGE_TOKEN=${token}\n`);
138
+ try {
139
+ chmodSync(envPath, 0o600);
140
+ }
141
+ catch { /* Windows */ }
142
+ logger.info(`Created .env: ${envPath} (with generated token)`);
143
+ }
144
+ logger.info(`Config directory ready: ${dir}`);
145
+ }
@@ -1,44 +1,15 @@
1
- // Core exports for @aiwerk/mcp-bridge
2
-
3
- // Transport classes
4
1
  export { BaseTransport, resolveEnvVars, resolveEnvRecord, resolveArgs, warnIfNonTlsRemoteUrl } from "./transport-base.js";
5
2
  export { StdioTransport } from "./transport-stdio.js";
6
3
  export { SseTransport } from "./transport-sse.js";
7
4
  export { StreamableHttpTransport } from "./transport-streamable-http.js";
8
-
9
- // Router
10
5
  export { McpRouter } from "./mcp-router.js";
11
6
  export type { RouterToolHint, RouterServerStatus, RouterDispatchResponse, RouterTransportRefs } from "./mcp-router.js";
12
-
13
- // Schema conversion
14
7
  export { convertJsonSchemaToTypeBox, createToolParameters, setTypeBoxLoader, setSchemaLogger } from "./schema-convert.js";
15
-
16
- // Protocol helpers
17
8
  export { initializeProtocol, fetchToolsList, PACKAGE_VERSION } from "./protocol.js";
18
-
19
- // Config
20
9
  export { loadConfig, parseEnvFile, initConfigDir, getConfigDir } from "./config.js";
21
-
22
- // Types
23
- export type {
24
- Logger,
25
- McpServerConfig,
26
- McpClientConfig,
27
- McpTool,
28
- McpRequest,
29
- McpResponse,
30
- McpTransport,
31
- McpServerConnection,
32
- BridgeConfig,
33
- } from "./types.js";
10
+ export type { Logger, McpServerConfig, McpClientConfig, McpTool, McpRequest, McpResponse, McpTransport, McpServerConnection, BridgeConfig, } from "./types.js";
34
11
  export { nextRequestId } from "./types.js";
35
-
36
- // Tool naming
37
12
  export { pickRegisteredToolName } from "./tool-naming.js";
38
-
39
- // Standalone server
40
13
  export { StandaloneServer } from "./standalone-server.js";
41
-
42
- // Update checker
43
14
  export { checkForUpdate, getUpdateNotice, runUpdate, resetNoticeFlag } from "./update-checker.js";
44
15
  export type { UpdateInfo } from "./update-checker.js";
@@ -0,0 +1,21 @@
1
+ // Core exports for @aiwerk/mcp-bridge
2
+ // Transport classes
3
+ export { BaseTransport, resolveEnvVars, resolveEnvRecord, resolveArgs, warnIfNonTlsRemoteUrl } from "./transport-base.js";
4
+ export { StdioTransport } from "./transport-stdio.js";
5
+ export { SseTransport } from "./transport-sse.js";
6
+ export { StreamableHttpTransport } from "./transport-streamable-http.js";
7
+ // Router
8
+ export { McpRouter } from "./mcp-router.js";
9
+ // Schema conversion
10
+ export { convertJsonSchemaToTypeBox, createToolParameters, setTypeBoxLoader, setSchemaLogger } from "./schema-convert.js";
11
+ // Protocol helpers
12
+ export { initializeProtocol, fetchToolsList, PACKAGE_VERSION } from "./protocol.js";
13
+ // Config
14
+ export { loadConfig, parseEnvFile, initConfigDir, getConfigDir } from "./config.js";
15
+ export { nextRequestId } from "./types.js";
16
+ // Tool naming
17
+ export { pickRegisteredToolName } from "./tool-naming.js";
18
+ // Standalone server
19
+ export { StandaloneServer } from "./standalone-server.js";
20
+ // Update checker
21
+ export { checkForUpdate, getUpdateNotice, runUpdate, resetNoticeFlag } from "./update-checker.js";
@@ -0,0 +1,65 @@
1
+ import { McpClientConfig, McpServerConfig, McpTransport } from "./types.js";
2
+ type RouterErrorCode = "unknown_server" | "unknown_tool" | "connection_failed" | "mcp_error" | "invalid_params";
3
+ export interface RouterToolHint {
4
+ name: string;
5
+ description: string;
6
+ requiredParams: string[];
7
+ }
8
+ export interface RouterServerStatus {
9
+ name: string;
10
+ transport: string;
11
+ status: "connected" | "idle" | "disconnected";
12
+ tools: number;
13
+ lastUsed?: string;
14
+ }
15
+ export type RouterDispatchResponse = {
16
+ server: string;
17
+ action: "list";
18
+ tools: RouterToolHint[];
19
+ } | {
20
+ server: string;
21
+ action: "refresh";
22
+ refreshed: true;
23
+ tools: RouterToolHint[];
24
+ } | {
25
+ server: string;
26
+ action: "call";
27
+ tool: string;
28
+ result: any;
29
+ } | {
30
+ action: "status";
31
+ servers: RouterServerStatus[];
32
+ } | {
33
+ error: RouterErrorCode;
34
+ message: string;
35
+ available?: string[];
36
+ code?: number;
37
+ };
38
+ export interface RouterTransportRefs {
39
+ sse: new (config: McpServerConfig, clientConfig: McpClientConfig, logger: any, onReconnected?: () => Promise<void>) => McpTransport;
40
+ stdio: new (config: McpServerConfig, clientConfig: McpClientConfig, logger: any, onReconnected?: () => Promise<void>) => McpTransport;
41
+ streamableHttp: new (config: McpServerConfig, clientConfig: McpClientConfig, logger: any, onReconnected?: () => Promise<void>) => McpTransport;
42
+ }
43
+ export declare class McpRouter {
44
+ private readonly servers;
45
+ private readonly clientConfig;
46
+ private readonly logger;
47
+ private readonly transportRefs;
48
+ private readonly idleTimeoutMs;
49
+ private readonly maxConcurrent;
50
+ private readonly states;
51
+ constructor(servers: Record<string, McpServerConfig>, clientConfig: McpClientConfig, logger: any, transportRefs?: Partial<RouterTransportRefs>);
52
+ static generateDescription(servers: Record<string, McpServerConfig>): string;
53
+ dispatch(server?: string, action?: string, tool?: string, params?: any): Promise<RouterDispatchResponse>;
54
+ getToolList(server: string): Promise<RouterToolHint[]>;
55
+ private getStatus;
56
+ disconnectAll(): Promise<void>;
57
+ private ensureConnected;
58
+ private enforceMaxConcurrent;
59
+ private disconnectServer;
60
+ private markUsed;
61
+ private createTransport;
62
+ private extractRequiredParams;
63
+ private error;
64
+ }
65
+ export {};