@aiwerk/mcp-bridge 1.1.3 → 1.1.5

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.
@@ -67,6 +67,10 @@ function parseArgs(argv) {
67
67
  break;
68
68
  case "--config":
69
69
  i++;
70
+ if (!argv[i]) {
71
+ process.stderr.write("Error: --config requires a path\n");
72
+ process.exit(1);
73
+ }
70
74
  args.configPath = resolve(argv[i]);
71
75
  break;
72
76
  case "--verbose":
@@ -1,5 +1,5 @@
1
1
  import { readFileSync, existsSync, mkdirSync, writeFileSync, chmodSync } from "fs";
2
- import { join } from "path";
2
+ import { join, extname } from "path";
3
3
  import { homedir } from "os";
4
4
  import { resolveEnvVars } from "./transport-base.js";
5
5
  import { randomBytes } from "crypto";
@@ -101,7 +101,7 @@ export function getConfigDir(configPath) {
101
101
  if (!configPath)
102
102
  return DEFAULT_CONFIG_DIR;
103
103
  // If path ends with separator or has no extension, treat as directory
104
- if (configPath.endsWith("/") || configPath.endsWith("\\") || !configPath.includes(".")) {
104
+ if (configPath.endsWith("/") || configPath.endsWith("\\") || !extname(configPath)) {
105
105
  return configPath;
106
106
  }
107
107
  return join(configPath, "..");
@@ -36,7 +36,9 @@ export async function initializeProtocol(transport, version) {
36
36
  export async function fetchToolsList(transport) {
37
37
  const allTools = [];
38
38
  let cursor;
39
- while (true) {
39
+ const MAX_PAGES = 100;
40
+ let page = 0;
41
+ while (page++ < MAX_PAGES) {
40
42
  const request = {
41
43
  jsonrpc: "2.0",
42
44
  method: "tools/list",
@@ -54,5 +56,8 @@ export async function fetchToolsList(transport) {
54
56
  }
55
57
  cursor = nextCursor;
56
58
  }
59
+ if (page >= MAX_PAGES) {
60
+ console.warn("[mcp-bridge] Tool list pagination exceeded max pages, possible cursor loop");
61
+ }
57
62
  return allTools;
58
63
  }
@@ -85,23 +85,23 @@ export async function convertJsonSchemaToTypeBox(schema, depth = 0) {
85
85
  return Type.String(stringOptions);
86
86
  }
87
87
  case "number": {
88
+ if (schema.enum)
89
+ return Type.Union(schema.enum.map((v) => Type.Literal(v)));
88
90
  const numberOptions = {};
89
91
  if (schema.minimum !== undefined)
90
92
  numberOptions.minimum = schema.minimum;
91
93
  if (schema.maximum !== undefined)
92
94
  numberOptions.maximum = schema.maximum;
93
- if (schema.enum)
94
- return Type.Union(schema.enum.map((v) => Type.Literal(v)));
95
95
  return Type.Number(numberOptions);
96
96
  }
97
97
  case "integer": {
98
+ if (schema.enum)
99
+ return Type.Union(schema.enum.map((v) => Type.Literal(v)));
98
100
  const intOptions = {};
99
101
  if (schema.minimum !== undefined)
100
102
  intOptions.minimum = schema.minimum;
101
103
  if (schema.maximum !== undefined)
102
104
  intOptions.maximum = schema.maximum;
103
- if (schema.enum)
104
- return Type.Union(schema.enum.map((v) => Type.Literal(v)));
105
105
  return Type.Integer(intOptions);
106
106
  }
107
107
  case "boolean":
@@ -64,6 +64,9 @@ export class SseTransport extends BaseTransport {
64
64
  this.processEventLine(line, state);
65
65
  }
66
66
  }
67
+ // Stream ended normally — server closed connection
68
+ this.logger.warn("[mcp-bridge] SSE stream ended, scheduling reconnect");
69
+ this.scheduleReconnect();
67
70
  }
68
71
  catch (error) {
69
72
  if (error instanceof Error && error.name === 'AbortError')
@@ -74,12 +77,12 @@ export class SseTransport extends BaseTransport {
74
77
  }
75
78
  processEventLine(line, state) {
76
79
  const trimmed = line.trim();
77
- if (trimmed.startsWith("event: ")) {
78
- state.event = trimmed.substring(7).trim();
80
+ if (trimmed.startsWith("event:")) {
81
+ state.event = trimmed.substring(6).trim();
79
82
  return;
80
83
  }
81
- if (trimmed.startsWith("data: ")) {
82
- state.dataBuffer.push(trimmed.substring(6));
84
+ if (trimmed.startsWith("data:")) {
85
+ state.dataBuffer.push(trimmed.substring(5).trimStart());
83
86
  return;
84
87
  }
85
88
  if (trimmed === "") {
@@ -87,8 +90,9 @@ export class SseTransport extends BaseTransport {
87
90
  return;
88
91
  const data = state.dataBuffer.join("\n");
89
92
  state.dataBuffer.length = 0;
93
+ const eventType = state.event;
90
94
  state.event = "";
91
- if (state.event === "endpoint") {
95
+ if (eventType === "endpoint") {
92
96
  if (data.startsWith("/")) {
93
97
  const base = new URL(this.config.url);
94
98
  this.endpointUrl = `${base.origin}${data}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiwerk/mcp-bridge",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "Standalone MCP server that multiplexes multiple MCP servers into one interface",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",