@darkiceinteractive/mcp-conductor 1.0.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.
- package/LICENSE +21 -0
- package/README.md +558 -0
- package/dist/bin/cli.d.ts +8 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +940 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/bridge/http-server.d.ts +161 -0
- package/dist/bridge/http-server.d.ts.map +1 -0
- package/dist/bridge/http-server.js +367 -0
- package/dist/bridge/http-server.js.map +1 -0
- package/dist/bridge/index.d.ts +5 -0
- package/dist/bridge/index.d.ts.map +1 -0
- package/dist/bridge/index.js +5 -0
- package/dist/bridge/index.js.map +1 -0
- package/dist/config/defaults.d.ts +29 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +60 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +7 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +49 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +272 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +93 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +5 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/hub/index.d.ts +5 -0
- package/dist/hub/index.d.ts.map +1 -0
- package/dist/hub/index.js +5 -0
- package/dist/hub/index.js.map +1 -0
- package/dist/hub/mcp-hub.d.ts +176 -0
- package/dist/hub/mcp-hub.d.ts.map +1 -0
- package/dist/hub/mcp-hub.js +550 -0
- package/dist/hub/mcp-hub.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/index.d.ts +5 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +5 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/metrics-collector.d.ts +211 -0
- package/dist/metrics/metrics-collector.d.ts.map +1 -0
- package/dist/metrics/metrics-collector.js +437 -0
- package/dist/metrics/metrics-collector.js.map +1 -0
- package/dist/modes/index.d.ts +5 -0
- package/dist/modes/index.d.ts.map +1 -0
- package/dist/modes/index.js +5 -0
- package/dist/modes/index.js.map +1 -0
- package/dist/modes/mode-handler.d.ts +132 -0
- package/dist/modes/mode-handler.d.ts.map +1 -0
- package/dist/modes/mode-handler.js +252 -0
- package/dist/modes/mode-handler.js.map +1 -0
- package/dist/runtime/executor.d.ts +57 -0
- package/dist/runtime/executor.d.ts.map +1 -0
- package/dist/runtime/executor.js +700 -0
- package/dist/runtime/executor.js.map +1 -0
- package/dist/runtime/index.d.ts +5 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +5 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/server/index.d.ts +5 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +5 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/mcp-server.d.ts +62 -0
- package/dist/server/mcp-server.d.ts.map +1 -0
- package/dist/server/mcp-server.js +1272 -0
- package/dist/server/mcp-server.js.map +1 -0
- package/dist/skills/index.d.ts +5 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +5 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/skills-engine.d.ts +157 -0
- package/dist/skills/skills-engine.d.ts.map +1 -0
- package/dist/skills/skills-engine.js +405 -0
- package/dist/skills/skills-engine.js.map +1 -0
- package/dist/streaming/execution-stream.d.ts +158 -0
- package/dist/streaming/execution-stream.d.ts.map +1 -0
- package/dist/streaming/execution-stream.js +320 -0
- package/dist/streaming/execution-stream.js.map +1 -0
- package/dist/streaming/index.d.ts +5 -0
- package/dist/streaming/index.d.ts.map +1 -0
- package/dist/streaming/index.js +5 -0
- package/dist/streaming/index.js.map +1 -0
- package/dist/utils/errors.d.ts +36 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +68 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/helpers.d.ts +44 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +95 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +48 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/permissions.d.ts +97 -0
- package/dist/utils/permissions.d.ts.map +1 -0
- package/dist/utils/permissions.js +165 -0
- package/dist/utils/permissions.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts +87 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -0
- package/dist/utils/rate-limiter.js +187 -0
- package/dist/utils/rate-limiter.js.map +1 -0
- package/dist/watcher/config-watcher.d.ts +67 -0
- package/dist/watcher/config-watcher.d.ts.map +1 -0
- package/dist/watcher/config-watcher.js +150 -0
- package/dist/watcher/config-watcher.js.map +1 -0
- package/dist/watcher/index.d.ts +5 -0
- package/dist/watcher/index.d.ts.map +1 -0
- package/dist/watcher/index.js +5 -0
- package/dist/watcher/index.js.map +1 -0
- package/package.json +86 -0
- package/templates/CLAUDE.md +137 -0
- package/templates/skill-mcp-conductor.md +64 -0
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Hub - Connects to and manages real MCP servers
|
|
3
|
+
*
|
|
4
|
+
* This component:
|
|
5
|
+
* - Reads Claude config files to discover MCP servers
|
|
6
|
+
* - Spawns and connects to each server via stdio transport
|
|
7
|
+
* - Maintains connection pool with health monitoring
|
|
8
|
+
* - Caches tool schemas for efficient discovery
|
|
9
|
+
* - Supports hot-reload of server configurations
|
|
10
|
+
*/
|
|
11
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
12
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
13
|
+
import { EventEmitter } from 'node:events';
|
|
14
|
+
import { logger, RateLimiter } from '../utils/index.js';
|
|
15
|
+
import { loadClaudeConfig, findClaudeConfig, loadConductorConfig, findConductorConfig, } from '../config/loader.js';
|
|
16
|
+
const DEFAULT_HUB_CONFIG = {
|
|
17
|
+
claudeConfigPath: '',
|
|
18
|
+
conductorConfigPath: '',
|
|
19
|
+
servers: { allowList: [], denyList: [] },
|
|
20
|
+
connectionTimeoutMs: 30000,
|
|
21
|
+
autoReconnect: true,
|
|
22
|
+
reconnectDelayMs: 5000,
|
|
23
|
+
maxReconnectAttempts: 3,
|
|
24
|
+
};
|
|
25
|
+
export class MCPHub extends EventEmitter {
|
|
26
|
+
config;
|
|
27
|
+
connections = new Map();
|
|
28
|
+
toolCache = new Map();
|
|
29
|
+
reconnectAttempts = new Map();
|
|
30
|
+
isShuttingDown = false;
|
|
31
|
+
constructor(config = {}) {
|
|
32
|
+
super();
|
|
33
|
+
this.config = { ...DEFAULT_HUB_CONFIG, ...config };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Initialise the hub and connect to all configured servers
|
|
37
|
+
*/
|
|
38
|
+
async initialise() {
|
|
39
|
+
logger.info('Initialising MCP Hub');
|
|
40
|
+
// Build a merged server map based on conductor config and/or Claude config
|
|
41
|
+
const serverMap = await this.discoverServers();
|
|
42
|
+
if (Object.keys(serverMap).length === 0) {
|
|
43
|
+
logger.warn('No MCP servers found in any configuration');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const serverNames = Object.keys(serverMap);
|
|
47
|
+
const filteredServers = this.filterServers(serverNames);
|
|
48
|
+
logger.info(`Found ${serverNames.length} servers, connecting to ${filteredServers.length}`, {
|
|
49
|
+
total: serverNames.length,
|
|
50
|
+
filtered: filteredServers.length,
|
|
51
|
+
servers: filteredServers,
|
|
52
|
+
});
|
|
53
|
+
// Connect to all servers concurrently
|
|
54
|
+
const connectionPromises = filteredServers.map((name) => {
|
|
55
|
+
const serverConfig = serverMap[name];
|
|
56
|
+
if (!serverConfig)
|
|
57
|
+
return Promise.resolve(false);
|
|
58
|
+
return this.connectServer(name, serverConfig);
|
|
59
|
+
});
|
|
60
|
+
await Promise.allSettled(connectionPromises);
|
|
61
|
+
const connected = Array.from(this.connections.values()).filter((c) => c.status === 'connected').length;
|
|
62
|
+
logger.info(`MCP Hub initialised`, {
|
|
63
|
+
connected,
|
|
64
|
+
total: filteredServers.length,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Discover servers from conductor config and/or Claude config
|
|
69
|
+
* Returns a merged map of server configurations
|
|
70
|
+
*/
|
|
71
|
+
async discoverServers() {
|
|
72
|
+
const serverMap = {};
|
|
73
|
+
// 1. Check for conductor config first (exclusive mode)
|
|
74
|
+
const conductorConfig = loadConductorConfig(this.config.conductorConfigPath || undefined);
|
|
75
|
+
if (conductorConfig && Object.keys(conductorConfig.servers || {}).length > 0) {
|
|
76
|
+
// Add servers from conductor config
|
|
77
|
+
for (const [name, config] of Object.entries(conductorConfig.servers)) {
|
|
78
|
+
serverMap[name] = config;
|
|
79
|
+
}
|
|
80
|
+
logger.info('Using conductor config', {
|
|
81
|
+
exclusive: conductorConfig.exclusive,
|
|
82
|
+
serverCount: Object.keys(conductorConfig.servers).length,
|
|
83
|
+
});
|
|
84
|
+
// If exclusive mode, return only conductor servers
|
|
85
|
+
if (conductorConfig.exclusive) {
|
|
86
|
+
logger.debug('Exclusive mode enabled - using only conductor config servers');
|
|
87
|
+
return serverMap;
|
|
88
|
+
}
|
|
89
|
+
// If not exclusive, continue to add Claude config servers
|
|
90
|
+
logger.debug('Non-exclusive mode - will merge with Claude config');
|
|
91
|
+
}
|
|
92
|
+
// 2. Load Claude config (if no conductor config or non-exclusive mode)
|
|
93
|
+
const claudeConfig = loadClaudeConfig(this.config.claudeConfigPath || undefined);
|
|
94
|
+
if (claudeConfig?.mcpServers) {
|
|
95
|
+
for (const [name, config] of Object.entries(claudeConfig.mcpServers)) {
|
|
96
|
+
// Don't override servers already defined in conductor config
|
|
97
|
+
if (!serverMap[name]) {
|
|
98
|
+
serverMap[name] = config;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
logger.debug('Added servers from Claude config', {
|
|
102
|
+
claudeServerCount: Object.keys(claudeConfig.mcpServers).length,
|
|
103
|
+
totalServerCount: Object.keys(serverMap).length,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return serverMap;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Filter servers based on allow/deny lists
|
|
110
|
+
*/
|
|
111
|
+
filterServers(serverNames) {
|
|
112
|
+
const { allowList, denyList } = this.config.servers;
|
|
113
|
+
return serverNames.filter((name) => {
|
|
114
|
+
// Skip self-reference to avoid circular connection
|
|
115
|
+
if (name === 'mcp-conductor' || name === 'mcp-executor') {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
// Check allow list - '*' means allow all, otherwise server must be in list
|
|
119
|
+
const allowsAll = allowList.includes('*');
|
|
120
|
+
if (!allowsAll && allowList.length > 0 && !allowList.includes(name)) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
// If server is in deny list, exclude it
|
|
124
|
+
if (denyList.includes(name)) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
return true;
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Connect to a single MCP server
|
|
132
|
+
*/
|
|
133
|
+
async connectServer(name, serverConfig) {
|
|
134
|
+
if (this.isShuttingDown) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
logger.debug(`Connecting to server: ${name}`, {
|
|
139
|
+
command: serverConfig.command,
|
|
140
|
+
args: serverConfig.args,
|
|
141
|
+
});
|
|
142
|
+
const client = new Client({
|
|
143
|
+
name: `mcp-executor-${name}`,
|
|
144
|
+
version: '1.0.0',
|
|
145
|
+
});
|
|
146
|
+
// Build env with defined values only
|
|
147
|
+
let transportEnv;
|
|
148
|
+
if (serverConfig.env) {
|
|
149
|
+
transportEnv = {};
|
|
150
|
+
// Copy process.env, filtering out undefined values
|
|
151
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
152
|
+
if (value !== undefined) {
|
|
153
|
+
transportEnv[key] = value;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Override with server-specific env
|
|
157
|
+
Object.assign(transportEnv, serverConfig.env);
|
|
158
|
+
}
|
|
159
|
+
const transport = new StdioClientTransport({
|
|
160
|
+
command: serverConfig.command,
|
|
161
|
+
args: serverConfig.args || [],
|
|
162
|
+
env: transportEnv,
|
|
163
|
+
});
|
|
164
|
+
// Create rate limiter if configured
|
|
165
|
+
let rateLimiter;
|
|
166
|
+
if (serverConfig.rateLimit) {
|
|
167
|
+
rateLimiter = new RateLimiter(serverConfig.rateLimit, name);
|
|
168
|
+
logger.info(`Rate limiter configured for ${name}`, {
|
|
169
|
+
requestsPerSecond: serverConfig.rateLimit.requestsPerSecond,
|
|
170
|
+
burstSize: serverConfig.rateLimit.burstSize,
|
|
171
|
+
mode: serverConfig.rateLimit.onLimitExceeded || 'queue',
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const connection = {
|
|
175
|
+
name,
|
|
176
|
+
client,
|
|
177
|
+
transport,
|
|
178
|
+
status: 'connecting',
|
|
179
|
+
tools: [],
|
|
180
|
+
command: serverConfig.command,
|
|
181
|
+
args: serverConfig.args || [],
|
|
182
|
+
env: serverConfig.env,
|
|
183
|
+
rateLimiter,
|
|
184
|
+
rateLimitConfig: serverConfig.rateLimit,
|
|
185
|
+
};
|
|
186
|
+
this.connections.set(name, connection);
|
|
187
|
+
// Set up error handling
|
|
188
|
+
transport.onerror = (error) => {
|
|
189
|
+
logger.error(`Transport error for ${name}`, { error: String(error) });
|
|
190
|
+
connection.status = 'error';
|
|
191
|
+
connection.lastError = String(error);
|
|
192
|
+
this.emit('serverError', name, error instanceof Error ? error : new Error(String(error)));
|
|
193
|
+
this.handleDisconnection(name);
|
|
194
|
+
};
|
|
195
|
+
transport.onclose = () => {
|
|
196
|
+
if (connection.status === 'connected') {
|
|
197
|
+
logger.warn(`Server ${name} disconnected`);
|
|
198
|
+
connection.status = 'disconnected';
|
|
199
|
+
this.emit('serverDisconnected', name);
|
|
200
|
+
this.handleDisconnection(name);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
// Connect with timeout
|
|
204
|
+
await Promise.race([
|
|
205
|
+
client.connect(transport),
|
|
206
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Connection timeout')), this.config.connectionTimeoutMs)),
|
|
207
|
+
]);
|
|
208
|
+
connection.status = 'connected';
|
|
209
|
+
connection.connectedAt = new Date();
|
|
210
|
+
this.reconnectAttempts.delete(name);
|
|
211
|
+
// Cache tools
|
|
212
|
+
await this.cacheServerTools(name, client);
|
|
213
|
+
logger.info(`Connected to server: ${name}`, {
|
|
214
|
+
toolCount: connection.tools.length,
|
|
215
|
+
});
|
|
216
|
+
this.emit('serverConnected', name);
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
221
|
+
logger.error(`Failed to connect to server: ${name}`, { error: errorMessage });
|
|
222
|
+
const connection = this.connections.get(name);
|
|
223
|
+
if (connection) {
|
|
224
|
+
connection.status = 'error';
|
|
225
|
+
connection.lastError = errorMessage;
|
|
226
|
+
}
|
|
227
|
+
this.emit('serverError', name, error instanceof Error ? error : new Error(errorMessage));
|
|
228
|
+
this.handleDisconnection(name);
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Handle server disconnection with optional reconnection
|
|
234
|
+
*/
|
|
235
|
+
async handleDisconnection(name) {
|
|
236
|
+
if (this.isShuttingDown || !this.config.autoReconnect) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const connection = this.connections.get(name);
|
|
240
|
+
if (!connection) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const attempts = (this.reconnectAttempts.get(name) || 0) + 1;
|
|
244
|
+
this.reconnectAttempts.set(name, attempts);
|
|
245
|
+
if (attempts > this.config.maxReconnectAttempts) {
|
|
246
|
+
logger.warn(`Max reconnect attempts reached for ${name}`, { attempts });
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
logger.info(`Scheduling reconnect for ${name}`, {
|
|
250
|
+
attempt: attempts,
|
|
251
|
+
maxAttempts: this.config.maxReconnectAttempts,
|
|
252
|
+
delayMs: this.config.reconnectDelayMs,
|
|
253
|
+
});
|
|
254
|
+
setTimeout(async () => {
|
|
255
|
+
if (this.isShuttingDown)
|
|
256
|
+
return;
|
|
257
|
+
logger.info(`Attempting reconnect for ${name}`, { attempt: attempts });
|
|
258
|
+
await this.connectServer(name, {
|
|
259
|
+
command: connection.command,
|
|
260
|
+
args: connection.args,
|
|
261
|
+
env: connection.env,
|
|
262
|
+
});
|
|
263
|
+
}, this.config.reconnectDelayMs);
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Cache tools from a connected server
|
|
267
|
+
*/
|
|
268
|
+
async cacheServerTools(name, client) {
|
|
269
|
+
try {
|
|
270
|
+
const response = await client.listTools();
|
|
271
|
+
const tools = response.tools || [];
|
|
272
|
+
const connection = this.connections.get(name);
|
|
273
|
+
if (connection) {
|
|
274
|
+
connection.tools = tools;
|
|
275
|
+
}
|
|
276
|
+
this.toolCache.set(name, tools);
|
|
277
|
+
this.emit('toolsCached', name, tools.length);
|
|
278
|
+
logger.debug(`Cached ${tools.length} tools for ${name}`, {
|
|
279
|
+
tools: tools.map((t) => t.name),
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
logger.warn(`Failed to cache tools for ${name}`, { error: String(error) });
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Disconnect from a specific server
|
|
288
|
+
*/
|
|
289
|
+
async disconnectServer(name) {
|
|
290
|
+
const connection = this.connections.get(name);
|
|
291
|
+
if (!connection) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
// Clean up rate limiter
|
|
295
|
+
if (connection.rateLimiter) {
|
|
296
|
+
connection.rateLimiter.destroy();
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
await connection.client.close();
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
logger.debug(`Error closing connection to ${name}`, { error: String(error) });
|
|
303
|
+
}
|
|
304
|
+
connection.status = 'disconnected';
|
|
305
|
+
this.toolCache.delete(name);
|
|
306
|
+
this.connections.delete(name);
|
|
307
|
+
logger.info(`Disconnected from server: ${name}`);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Reload server configurations
|
|
311
|
+
*/
|
|
312
|
+
async reload() {
|
|
313
|
+
logger.info('Reloading MCP Hub configuration');
|
|
314
|
+
const serverMap = await this.discoverServers();
|
|
315
|
+
const currentServerNames = Array.from(this.connections.keys());
|
|
316
|
+
if (Object.keys(serverMap).length === 0 && currentServerNames.length === 0) {
|
|
317
|
+
logger.warn('No MCP servers found during reload');
|
|
318
|
+
return { added: [], removed: [] };
|
|
319
|
+
}
|
|
320
|
+
const newServerNames = this.filterServers(Object.keys(serverMap));
|
|
321
|
+
// Find added and removed servers
|
|
322
|
+
const added = newServerNames.filter((name) => !currentServerNames.includes(name));
|
|
323
|
+
const removed = currentServerNames.filter((name) => !newServerNames.includes(name));
|
|
324
|
+
// Disconnect removed servers
|
|
325
|
+
for (const name of removed) {
|
|
326
|
+
await this.disconnectServer(name);
|
|
327
|
+
}
|
|
328
|
+
// Connect new servers
|
|
329
|
+
for (const name of added) {
|
|
330
|
+
const serverConfig = serverMap[name];
|
|
331
|
+
if (serverConfig) {
|
|
332
|
+
await this.connectServer(name, serverConfig);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// Reconnect servers that may have changed config
|
|
336
|
+
const existing = newServerNames.filter((name) => currentServerNames.includes(name));
|
|
337
|
+
for (const name of existing) {
|
|
338
|
+
const connection = this.connections.get(name);
|
|
339
|
+
const newConfig = serverMap[name];
|
|
340
|
+
// Check if config changed (command, args, env vars, OR rate limit)
|
|
341
|
+
if (connection && newConfig) {
|
|
342
|
+
const commandChanged = connection.command !== newConfig.command;
|
|
343
|
+
const argsChanged = JSON.stringify(connection.args) !== JSON.stringify(newConfig.args || []);
|
|
344
|
+
const envChanged = JSON.stringify(connection.env || {}) !== JSON.stringify(newConfig.env || {});
|
|
345
|
+
const rateLimitChanged = JSON.stringify(connection.rateLimitConfig || null) !== JSON.stringify(newConfig.rateLimit || null);
|
|
346
|
+
if (commandChanged || argsChanged || envChanged || rateLimitChanged) {
|
|
347
|
+
logger.info(`Server config changed, reconnecting: ${name}`, {
|
|
348
|
+
commandChanged,
|
|
349
|
+
argsChanged,
|
|
350
|
+
envChanged,
|
|
351
|
+
rateLimitChanged,
|
|
352
|
+
});
|
|
353
|
+
await this.disconnectServer(name);
|
|
354
|
+
await this.connectServer(name, newConfig);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (added.length > 0 || removed.length > 0) {
|
|
359
|
+
this.emit('serversChanged', added, removed);
|
|
360
|
+
}
|
|
361
|
+
logger.info('MCP Hub reload complete', { added, removed });
|
|
362
|
+
return { added, removed };
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Shutdown all connections
|
|
366
|
+
*/
|
|
367
|
+
async shutdown() {
|
|
368
|
+
logger.info('Shutting down MCP Hub');
|
|
369
|
+
this.isShuttingDown = true;
|
|
370
|
+
const disconnectPromises = Array.from(this.connections.keys()).map((name) => this.disconnectServer(name));
|
|
371
|
+
await Promise.allSettled(disconnectPromises);
|
|
372
|
+
this.connections.clear();
|
|
373
|
+
this.toolCache.clear();
|
|
374
|
+
logger.info('MCP Hub shutdown complete');
|
|
375
|
+
}
|
|
376
|
+
// ============================================
|
|
377
|
+
// Public API for tool discovery and execution
|
|
378
|
+
// ============================================
|
|
379
|
+
/**
|
|
380
|
+
* List all connected servers
|
|
381
|
+
*/
|
|
382
|
+
listServers() {
|
|
383
|
+
return Array.from(this.connections.values()).map((conn) => ({
|
|
384
|
+
name: conn.name,
|
|
385
|
+
status: conn.status,
|
|
386
|
+
toolCount: conn.tools.length,
|
|
387
|
+
connectedAt: conn.connectedAt,
|
|
388
|
+
lastError: conn.lastError,
|
|
389
|
+
}));
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Get tools for a specific server
|
|
393
|
+
*/
|
|
394
|
+
getServerTools(serverName) {
|
|
395
|
+
return this.toolCache.get(serverName) || [];
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Get all tools from all servers
|
|
399
|
+
*/
|
|
400
|
+
getAllTools() {
|
|
401
|
+
const allTools = [];
|
|
402
|
+
for (const [server, tools] of this.toolCache) {
|
|
403
|
+
for (const tool of tools) {
|
|
404
|
+
allTools.push({ server, tool });
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return allTools;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Search for tools across all servers
|
|
411
|
+
*/
|
|
412
|
+
searchTools(query) {
|
|
413
|
+
const results = [];
|
|
414
|
+
const lowerQuery = query.toLowerCase();
|
|
415
|
+
for (const [server, tools] of this.toolCache) {
|
|
416
|
+
for (const tool of tools) {
|
|
417
|
+
const nameMatch = tool.name.toLowerCase().includes(lowerQuery);
|
|
418
|
+
const descMatch = tool.description?.toLowerCase().includes(lowerQuery);
|
|
419
|
+
if (nameMatch || descMatch) {
|
|
420
|
+
results.push({
|
|
421
|
+
server,
|
|
422
|
+
tool: tool.name,
|
|
423
|
+
description: tool.description || '',
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return results;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Call a tool on a specific server
|
|
432
|
+
*/
|
|
433
|
+
async callTool(serverName, toolName, params) {
|
|
434
|
+
const connection = this.connections.get(serverName);
|
|
435
|
+
if (!connection) {
|
|
436
|
+
throw new Error(`Server not found: ${serverName}`);
|
|
437
|
+
}
|
|
438
|
+
if (connection.status !== 'connected') {
|
|
439
|
+
throw new Error(`Server not connected: ${serverName} (status: ${connection.status})`);
|
|
440
|
+
}
|
|
441
|
+
// Acquire rate limit token if rate limiter is configured
|
|
442
|
+
if (connection.rateLimiter) {
|
|
443
|
+
try {
|
|
444
|
+
await connection.rateLimiter.acquire();
|
|
445
|
+
}
|
|
446
|
+
catch (error) {
|
|
447
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
448
|
+
logger.warn(`Rate limit for ${serverName}.${toolName}`, { error: errorMessage });
|
|
449
|
+
throw error;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
try {
|
|
453
|
+
const result = await connection.client.callTool({
|
|
454
|
+
name: toolName,
|
|
455
|
+
arguments: params,
|
|
456
|
+
});
|
|
457
|
+
// Extract content from result
|
|
458
|
+
if (result.content && Array.isArray(result.content)) {
|
|
459
|
+
// If there's structured content, prefer it
|
|
460
|
+
if (result.structuredContent) {
|
|
461
|
+
return result.structuredContent;
|
|
462
|
+
}
|
|
463
|
+
// Otherwise, try to parse text content as JSON
|
|
464
|
+
const textContent = result.content.find((c) => c.type === 'text');
|
|
465
|
+
if (textContent && 'text' in textContent) {
|
|
466
|
+
try {
|
|
467
|
+
return JSON.parse(textContent.text);
|
|
468
|
+
}
|
|
469
|
+
catch {
|
|
470
|
+
return textContent.text;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return result.content;
|
|
474
|
+
}
|
|
475
|
+
return result;
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
479
|
+
logger.error(`Tool call failed: ${serverName}.${toolName}`, { error: errorMessage, params });
|
|
480
|
+
throw new Error(`Tool call failed: ${serverName}.${toolName} - ${errorMessage}`);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Check if a server is connected
|
|
485
|
+
*/
|
|
486
|
+
isServerConnected(serverName) {
|
|
487
|
+
const connection = this.connections.get(serverName);
|
|
488
|
+
return connection?.status === 'connected';
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Get server count by status
|
|
492
|
+
*/
|
|
493
|
+
getStats() {
|
|
494
|
+
const connections = Array.from(this.connections.values());
|
|
495
|
+
return {
|
|
496
|
+
total: connections.length,
|
|
497
|
+
connected: connections.filter((c) => c.status === 'connected').length,
|
|
498
|
+
error: connections.filter((c) => c.status === 'error').length,
|
|
499
|
+
disconnected: connections.filter((c) => c.status === 'disconnected').length,
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Get the Claude config file path being used
|
|
504
|
+
*/
|
|
505
|
+
getConfigPath() {
|
|
506
|
+
return this.config.claudeConfigPath || findClaudeConfig();
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Get the conductor config file path being used
|
|
510
|
+
*/
|
|
511
|
+
getConductorConfigPath() {
|
|
512
|
+
return this.config.conductorConfigPath || findConductorConfig();
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Check if running in exclusive mode (conductor config only)
|
|
516
|
+
*/
|
|
517
|
+
isExclusiveMode() {
|
|
518
|
+
const conductorConfig = loadConductorConfig(this.config.conductorConfigPath || undefined);
|
|
519
|
+
return (conductorConfig !== null &&
|
|
520
|
+
conductorConfig.exclusive === true &&
|
|
521
|
+
Object.keys(conductorConfig.servers || {}).length > 0);
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Get configuration info for status display
|
|
525
|
+
*/
|
|
526
|
+
getConfigInfo() {
|
|
527
|
+
const conductorConfig = loadConductorConfig(this.config.conductorConfigPath || undefined);
|
|
528
|
+
const claudeConfig = loadClaudeConfig(this.config.claudeConfigPath || undefined);
|
|
529
|
+
const conductorServerCount = Object.keys(conductorConfig?.servers || {}).length;
|
|
530
|
+
const claudeServerCount = Object.keys(claudeConfig?.mcpServers || {}).length;
|
|
531
|
+
let mode;
|
|
532
|
+
if (conductorConfig && conductorConfig.exclusive && conductorServerCount > 0) {
|
|
533
|
+
mode = 'exclusive';
|
|
534
|
+
}
|
|
535
|
+
else if (conductorServerCount > 0) {
|
|
536
|
+
mode = 'shared';
|
|
537
|
+
}
|
|
538
|
+
else {
|
|
539
|
+
mode = 'claude-only';
|
|
540
|
+
}
|
|
541
|
+
return {
|
|
542
|
+
mode,
|
|
543
|
+
conductorConfigPath: this.getConductorConfigPath(),
|
|
544
|
+
claudeConfigPath: this.getConfigPath(),
|
|
545
|
+
conductorServerCount,
|
|
546
|
+
claudeServerCount,
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
//# sourceMappingURL=mcp-hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-hub.js","sourceRoot":"","sources":["../../src/hub/mcp-hub.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Executor - Main Entry Point
|
|
3
|
+
*
|
|
4
|
+
* An MCP server that acts as a code execution proxy for all other MCP servers.
|
|
5
|
+
* Instead of Claude making direct tool calls, Claude writes code that runs in
|
|
6
|
+
* a sandboxed Deno environment with access to all MCP servers as APIs.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Executor - Main Entry Point
|
|
3
|
+
*
|
|
4
|
+
* An MCP server that acts as a code execution proxy for all other MCP servers.
|
|
5
|
+
* Instead of Claude making direct tool calls, Claude writes code that runs in
|
|
6
|
+
* a sandboxed Deno environment with access to all MCP servers as APIs.
|
|
7
|
+
*/
|
|
8
|
+
import { MCPExecutorServer } from './server/index.js';
|
|
9
|
+
import { loadConfig } from './config/index.js';
|
|
10
|
+
import { logger } from './utils/index.js';
|
|
11
|
+
/**
|
|
12
|
+
* Main entry point
|
|
13
|
+
*/
|
|
14
|
+
async function main() {
|
|
15
|
+
// Load configuration
|
|
16
|
+
const config = loadConfig();
|
|
17
|
+
logger.info('Starting MCP Executor', {
|
|
18
|
+
mode: config.execution.mode,
|
|
19
|
+
bridgePort: config.bridge.port,
|
|
20
|
+
timeout: config.execution.defaultTimeoutMs,
|
|
21
|
+
});
|
|
22
|
+
// Create and start server
|
|
23
|
+
const server = new MCPExecutorServer(config);
|
|
24
|
+
// Handle shutdown gracefully
|
|
25
|
+
const shutdown = async () => {
|
|
26
|
+
logger.info('Shutting down...');
|
|
27
|
+
await server.stop();
|
|
28
|
+
process.exit(0);
|
|
29
|
+
};
|
|
30
|
+
process.on('SIGINT', shutdown);
|
|
31
|
+
process.on('SIGTERM', shutdown);
|
|
32
|
+
try {
|
|
33
|
+
await server.start();
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
logger.error('Failed to start server', { error: String(error) });
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Run
|
|
41
|
+
main().catch((error) => {
|
|
42
|
+
console.error('Fatal error:', error);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,qBAAqB;IACrB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE;QACnC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI;QAC3B,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI;QAC9B,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,gBAAgB;KAC3C,CAAC,CAAC;IAEH,0BAA0B;IAC1B,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE7C,6BAA6B;IAC7B,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAChC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM;AACN,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrics module exports
|
|
3
|
+
*/
|
|
4
|
+
export { MetricsCollector, getMetricsCollector, shutdownMetricsCollector, type TokenEstimationConfig, type ExecutionMetrics, type SessionMetrics, type WindowedMetrics, } from './metrics-collector.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,GAKzB,MAAM,wBAAwB,CAAC"}
|