@aiwerk/mcp-bridge 1.1.4 → 1.1.6
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/dist/bin/mcp-bridge.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { readFileSync, existsSync } from "fs";
|
|
3
3
|
import { join, dirname, resolve } from "path";
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
|
-
import {
|
|
5
|
+
import { execFileSync } from "child_process";
|
|
6
6
|
import { loadConfig, initConfigDir } from "../src/config.js";
|
|
7
7
|
import { StandaloneServer } from "../src/standalone-server.js";
|
|
8
8
|
import { PACKAGE_VERSION } from "../src/protocol.js";
|
|
@@ -224,7 +224,7 @@ function cmdInstall(serverName, logger) {
|
|
|
224
224
|
process.exit(1);
|
|
225
225
|
}
|
|
226
226
|
try {
|
|
227
|
-
|
|
227
|
+
execFileSync("bash", [scriptPath, serverName], { stdio: "inherit" });
|
|
228
228
|
}
|
|
229
229
|
catch (err) {
|
|
230
230
|
process.exit(1);
|
package/dist/src/config.js
CHANGED
|
@@ -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
|
|
104
|
+
if (configPath.endsWith("/") || configPath.endsWith("\\") || !extname(configPath)) {
|
|
105
105
|
return configPath;
|
|
106
106
|
}
|
|
107
107
|
return join(configPath, "..");
|
package/dist/src/protocol.js
CHANGED
|
@@ -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
|
-
|
|
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
|
+
process.stderr.write("[mcp-bridge] Tool list pagination exceeded max pages, possible cursor loop\n");
|
|
61
|
+
}
|
|
57
62
|
return allTools;
|
|
58
63
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { McpTransport, McpRequest, McpResponse, McpServerConfig, McpClientConfig, Logger } from "./types.js";
|
|
2
2
|
export type PendingRequest = {
|
|
3
|
-
resolve:
|
|
4
|
-
reject:
|
|
3
|
+
resolve: (value: McpResponse) => void;
|
|
4
|
+
reject: (reason: Error) => void;
|
|
5
5
|
timeout: NodeJS.Timeout;
|
|
6
6
|
};
|
|
7
7
|
/**
|
|
@@ -31,7 +31,8 @@ export class BaseTransport {
|
|
|
31
31
|
* - Responses with id -> resolve/reject matching pending request
|
|
32
32
|
*/
|
|
33
33
|
handleMessage(message) {
|
|
34
|
-
|
|
34
|
+
const hasId = message.id !== undefined && message.id !== null;
|
|
35
|
+
if (!hasId && message.method === "notifications/tools/list_changed") {
|
|
35
36
|
if (this.onReconnected) {
|
|
36
37
|
this.onReconnected().catch((error) => {
|
|
37
38
|
this.logger.error("[mcp-bridge] Failed to refresh tools after list_changed notification:", error);
|
|
@@ -39,11 +40,11 @@ export class BaseTransport {
|
|
|
39
40
|
}
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
42
|
-
if (!
|
|
43
|
+
if (!hasId && message.method) {
|
|
43
44
|
this.logger.debug(`[mcp-bridge] Unhandled ${this.transportName} notification: ${message.method}`);
|
|
44
45
|
return;
|
|
45
46
|
}
|
|
46
|
-
if (
|
|
47
|
+
if (hasId && this.pendingRequests.has(message.id)) {
|
|
47
48
|
const pending = this.pendingRequests.get(message.id);
|
|
48
49
|
clearTimeout(pending.timeout);
|
|
49
50
|
this.pendingRequests.delete(message.id);
|
|
@@ -12,6 +12,9 @@ export class SseTransport extends BaseTransport {
|
|
|
12
12
|
warnIfNonTlsRemoteUrl(this.config.url, this.logger);
|
|
13
13
|
// Validate that all header env vars resolve (fail fast)
|
|
14
14
|
resolveEnvRecord(this.config.headers || {}, "header");
|
|
15
|
+
if (this.sseAbortController) {
|
|
16
|
+
this.sseAbortController.abort();
|
|
17
|
+
}
|
|
15
18
|
this.sseAbortController = new AbortController();
|
|
16
19
|
const connectionTimeout = this.clientConfig.connectionTimeoutMs || 10000;
|
|
17
20
|
const streamReady = new Promise((resolve, reject) => {
|
|
@@ -64,6 +67,9 @@ export class SseTransport extends BaseTransport {
|
|
|
64
67
|
this.processEventLine(line, state);
|
|
65
68
|
}
|
|
66
69
|
}
|
|
70
|
+
// Stream ended normally — server closed connection
|
|
71
|
+
this.logger.warn("[mcp-bridge] SSE stream ended, scheduling reconnect");
|
|
72
|
+
this.scheduleReconnect();
|
|
67
73
|
}
|
|
68
74
|
catch (error) {
|
|
69
75
|
if (error instanceof Error && error.name === 'AbortError')
|
|
@@ -74,12 +80,12 @@ export class SseTransport extends BaseTransport {
|
|
|
74
80
|
}
|
|
75
81
|
processEventLine(line, state) {
|
|
76
82
|
const trimmed = line.trim();
|
|
77
|
-
if (trimmed.startsWith("event:
|
|
78
|
-
state.event = trimmed.substring(
|
|
83
|
+
if (trimmed.startsWith("event:")) {
|
|
84
|
+
state.event = trimmed.substring(6).trim();
|
|
79
85
|
return;
|
|
80
86
|
}
|
|
81
|
-
if (trimmed.startsWith("data:
|
|
82
|
-
state.dataBuffer.push(trimmed.substring(
|
|
87
|
+
if (trimmed.startsWith("data:")) {
|
|
88
|
+
state.dataBuffer.push(trimmed.substring(5).trimStart());
|
|
83
89
|
return;
|
|
84
90
|
}
|
|
85
91
|
if (trimmed === "") {
|