@yawlabs/mcp-connect 0.2.0 → 0.2.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.
- package/dist/index.js +42 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -118,9 +118,10 @@ async function shutdownAnalytics() {
|
|
|
118
118
|
clearInterval(flushTimer);
|
|
119
119
|
flushTimer = null;
|
|
120
120
|
}
|
|
121
|
-
|
|
121
|
+
for (let i = 0; i < 3 && buffer.length > 0; i++) {
|
|
122
122
|
await flush();
|
|
123
123
|
}
|
|
124
|
+
buffer.length = 0;
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
// src/meta-tools.ts
|
|
@@ -433,11 +434,21 @@ async function connectToUpstream(config, onDisconnect) {
|
|
|
433
434
|
}
|
|
434
435
|
transport = new StreamableHTTPClientTransport(new URL(config.url));
|
|
435
436
|
}
|
|
436
|
-
|
|
437
|
-
const timeoutPromise = new Promise(
|
|
438
|
-
|
|
439
|
-
);
|
|
440
|
-
|
|
437
|
+
let timer;
|
|
438
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
439
|
+
timer = setTimeout(() => reject(new Error("Connection timeout after " + CONNECT_TIMEOUT + "ms")), CONNECT_TIMEOUT);
|
|
440
|
+
});
|
|
441
|
+
try {
|
|
442
|
+
await Promise.race([client.connect(transport), timeoutPromise]);
|
|
443
|
+
clearTimeout(timer);
|
|
444
|
+
} catch (err) {
|
|
445
|
+
clearTimeout(timer);
|
|
446
|
+
try {
|
|
447
|
+
await client.close();
|
|
448
|
+
} catch {
|
|
449
|
+
}
|
|
450
|
+
throw err;
|
|
451
|
+
}
|
|
441
452
|
log("info", "Connected to upstream", { name: config.name, namespace: config.namespace, type: config.type });
|
|
442
453
|
const connection = {};
|
|
443
454
|
client.onclose = () => {
|
|
@@ -647,6 +658,7 @@ var ConnectServer = class _ConnectServer {
|
|
|
647
658
|
const newConn = await connectToUpstream(serverConfig, (ns) => this.handleUpstreamDisconnect(ns));
|
|
648
659
|
this.connections.set(route.namespace, newConn);
|
|
649
660
|
this.rebuildRoutes();
|
|
661
|
+
await this.notifyAllListsChanged();
|
|
650
662
|
log("info", "Auto-reconnected to upstream", { namespace: route.namespace });
|
|
651
663
|
} catch (err) {
|
|
652
664
|
log("error", "Auto-reconnect failed", { namespace: route.namespace, error: err.message });
|
|
@@ -858,6 +870,7 @@ var ConnectServer = class _ConnectServer {
|
|
|
858
870
|
log("info", "Server removed or disabled in config, deactivating", { namespace });
|
|
859
871
|
await disconnectFromUpstream(connection);
|
|
860
872
|
this.connections.delete(namespace);
|
|
873
|
+
this.idleCallCounts.delete(namespace);
|
|
861
874
|
changed = true;
|
|
862
875
|
continue;
|
|
863
876
|
}
|
|
@@ -866,6 +879,7 @@ var ConnectServer = class _ConnectServer {
|
|
|
866
879
|
log("info", "Server config changed, deactivating stale connection", { namespace });
|
|
867
880
|
await disconnectFromUpstream(connection);
|
|
868
881
|
this.connections.delete(namespace);
|
|
882
|
+
this.idleCallCounts.delete(namespace);
|
|
869
883
|
changed = true;
|
|
870
884
|
}
|
|
871
885
|
}
|
|
@@ -890,11 +904,30 @@ var ConnectServer = class _ConnectServer {
|
|
|
890
904
|
if (!filepath) {
|
|
891
905
|
return { content: [{ type: "text", text: "filepath is required." }], isError: true };
|
|
892
906
|
}
|
|
907
|
+
const ALLOWED_FILENAMES = ["claude_desktop_config.json", "mcp.json", "settings.json", "mcp_config.json"];
|
|
908
|
+
const basename = filepath.split(/[/\\]/).pop() || "";
|
|
909
|
+
if (!ALLOWED_FILENAMES.includes(basename)) {
|
|
910
|
+
return {
|
|
911
|
+
content: [
|
|
912
|
+
{
|
|
913
|
+
type: "text",
|
|
914
|
+
text: "Only MCP config files are allowed: " + ALLOWED_FILENAMES.join(", ") + ". Got: " + basename
|
|
915
|
+
}
|
|
916
|
+
],
|
|
917
|
+
isError: true
|
|
918
|
+
};
|
|
919
|
+
}
|
|
893
920
|
try {
|
|
894
|
-
const resolved = filepath.startsWith("
|
|
921
|
+
const resolved = filepath.startsWith("~/") ? resolve(homedir(), filepath.slice(2)) : resolve(filepath);
|
|
895
922
|
const raw = await readFile(resolved, "utf-8");
|
|
896
923
|
const parsed = JSON.parse(raw);
|
|
897
|
-
|
|
924
|
+
if (!parsed.mcpServers || typeof parsed.mcpServers !== "object") {
|
|
925
|
+
return {
|
|
926
|
+
content: [{ type: "text", text: "No mcpServers object found in " + resolved }],
|
|
927
|
+
isError: true
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
const mcpServers = parsed.mcpServers;
|
|
898
931
|
if (typeof mcpServers !== "object" || Array.isArray(mcpServers)) {
|
|
899
932
|
return { content: [{ type: "text", text: "No mcpServers object found in " + resolved }], isError: true };
|
|
900
933
|
}
|
|
@@ -911,7 +944,6 @@ var ConnectServer = class _ConnectServer {
|
|
|
911
944
|
};
|
|
912
945
|
if (value.command) entry.command = value.command;
|
|
913
946
|
if (value.args) entry.args = value.args;
|
|
914
|
-
if (value.env) entry.env = value.env;
|
|
915
947
|
if (value.url) entry.url = value.url;
|
|
916
948
|
servers.push(entry);
|
|
917
949
|
}
|
|
@@ -941,7 +973,7 @@ var ConnectServer = class _ConnectServer {
|
|
|
941
973
|
content: [
|
|
942
974
|
{
|
|
943
975
|
type: "text",
|
|
944
|
-
text: "Imported " + (body.imported || 0) + " servers" + (body.skipped ? ", " + body.skipped + " skipped (already exist)" : "") + " from " + resolved + ". Use mcp_connect_discover to see
|
|
976
|
+
text: "Imported " + (body.imported || 0) + " servers" + (body.skipped ? ", " + body.skipped + " skipped (already exist)" : "") + " from " + resolved + ". Note: environment variables (API keys, tokens) were NOT imported for security \u2014 set them at mcp.hosting. Use mcp_connect_discover to see imported servers."
|
|
945
977
|
}
|
|
946
978
|
]
|
|
947
979
|
};
|
package/package.json
CHANGED