@luutuankiet/mcp-proxy-shim 1.0.8 → 1.1.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/README.md +260 -24
- package/dist/core.js +165 -18
- package/dist/core.js.map +1 -1
- package/dist/daemon.d.ts +45 -0
- package/dist/daemon.js +608 -0
- package/dist/daemon.js.map +1 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.js +30 -8
- package/dist/index.js.map +1 -1
- package/package.json +5 -12
package/dist/daemon.js
ADDED
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Proxy Shim — Daemon Mode
|
|
4
|
+
*
|
|
5
|
+
* Multi-server MCP gateway: connects to N upstream MCP servers (stdio or HTTP)
|
|
6
|
+
* and exposes all their tools through a single HTTP Streamable endpoint.
|
|
7
|
+
*
|
|
8
|
+
* Pure passthrough — no schema transformation. Designed for cloud agents that
|
|
9
|
+
* can't spawn MCP servers on the fly.
|
|
10
|
+
*
|
|
11
|
+
* Architecture:
|
|
12
|
+
* Cloud Agent ──HTTP──▶ daemon (:3456) ──┬── stdio ──▶ spawned process
|
|
13
|
+
* ├── HTTP ──▶ remote MCP server
|
|
14
|
+
* └── stdio ──▶ another process
|
|
15
|
+
*
|
|
16
|
+
* Configuration via MCP_SERVERS env var (JSON) or MCP_CONFIG file path:
|
|
17
|
+
*
|
|
18
|
+
* {
|
|
19
|
+
* "github": {
|
|
20
|
+
* "type": "stdio",
|
|
21
|
+
* "command": "npx",
|
|
22
|
+
* "args": ["-y", "@modelcontextprotocol/server-github"],
|
|
23
|
+
* "env": { "GITHUB_TOKEN": "ghp_..." }
|
|
24
|
+
* },
|
|
25
|
+
* "my-api": {
|
|
26
|
+
* "type": "streamableHttp",
|
|
27
|
+
* "url": "https://api.example.com/mcp",
|
|
28
|
+
* "headers": { "Authorization": "Bearer xxx", "X-Custom": "value" }
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* Environment variables:
|
|
33
|
+
* MCP_SERVERS JSON string with server configs (inline)
|
|
34
|
+
* MCP_CONFIG Path to JSON config file (alternative to MCP_SERVERS)
|
|
35
|
+
* MCP_PORT Port to listen on (default: 3456)
|
|
36
|
+
* MCP_HOST Host to bind to (default: 0.0.0.0)
|
|
37
|
+
* MCP_APIKEY Require ?apikey=KEY on /mcp requests (optional)
|
|
38
|
+
*
|
|
39
|
+
* Usage:
|
|
40
|
+
* MCP_SERVERS='{"github":{"type":"stdio","command":"npx","args":["-y","@modelcontextprotocol/server-github"]}}' \
|
|
41
|
+
* npx @luutuankiet/mcp-proxy-shim daemon
|
|
42
|
+
*
|
|
43
|
+
* MCP_CONFIG=./mcp-servers.json npx @luutuankiet/mcp-proxy-shim daemon
|
|
44
|
+
*/
|
|
45
|
+
import { readFileSync } from "node:fs";
|
|
46
|
+
import { randomUUID } from "node:crypto";
|
|
47
|
+
import http from "node:http";
|
|
48
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
49
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
50
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
51
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
52
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
53
|
+
import { ListToolsRequestSchema, CallToolRequestSchema, isInitializeRequest, } from "@modelcontextprotocol/sdk/types.js";
|
|
54
|
+
// Proxy support — same pattern as core.ts
|
|
55
|
+
import { createRequire } from "node:module";
|
|
56
|
+
const _require = createRequire(import.meta.url);
|
|
57
|
+
const { ProxyAgent } = _require("undici");
|
|
58
|
+
const PROXY_URL = process.env.https_proxy || process.env.HTTPS_PROXY || "";
|
|
59
|
+
const proxyDispatcher = PROXY_URL ? new ProxyAgent(PROXY_URL) : undefined;
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Config
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
const PORT = parseInt(process.env.MCP_PORT || "3456", 10);
|
|
64
|
+
const HOST = process.env.MCP_HOST || "0.0.0.0";
|
|
65
|
+
const APIKEY = process.env.MCP_APIKEY || null;
|
|
66
|
+
function log(...args) {
|
|
67
|
+
console.error("[mcp-daemon]", ...args);
|
|
68
|
+
}
|
|
69
|
+
function loadConfig() {
|
|
70
|
+
// Try inline JSON first
|
|
71
|
+
if (process.env.MCP_SERVERS) {
|
|
72
|
+
try {
|
|
73
|
+
return JSON.parse(process.env.MCP_SERVERS);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
log("Fatal: MCP_SERVERS is not valid JSON:", err.message);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Try config file
|
|
81
|
+
if (process.env.MCP_CONFIG) {
|
|
82
|
+
try {
|
|
83
|
+
const raw = readFileSync(process.env.MCP_CONFIG, "utf-8");
|
|
84
|
+
const parsed = JSON.parse(raw);
|
|
85
|
+
// Support both { servers: {...} } and flat { name: config } format
|
|
86
|
+
// Also support .mcp.json format: { mcpServers: {...} }
|
|
87
|
+
return parsed.mcpServers || parsed.servers || parsed;
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
log("Fatal: Cannot read MCP_CONFIG:", err.message);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
log("Fatal: No server configuration provided.");
|
|
95
|
+
log("Set MCP_SERVERS (JSON) or MCP_CONFIG (file path).");
|
|
96
|
+
log("");
|
|
97
|
+
log("Example:");
|
|
98
|
+
log(` MCP_SERVERS='{"my-server":{"type":"stdio","command":"npx","args":["-y","some-mcp-server"]}}' \\`);
|
|
99
|
+
log(" npx @luutuankiet/mcp-proxy-shim daemon");
|
|
100
|
+
process.exit(1);
|
|
101
|
+
return {};
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// Upstream connection management
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
const upstreams = new Map();
|
|
107
|
+
/** Namespace a tool name with server prefix to avoid collisions */
|
|
108
|
+
function namespaceTool(serverName, toolName) {
|
|
109
|
+
return `${serverName}__${toolName}`;
|
|
110
|
+
}
|
|
111
|
+
/** Extract server name and original tool name from namespaced name */
|
|
112
|
+
function parseNamespacedTool(namespacedName) {
|
|
113
|
+
for (const [name] of upstreams) {
|
|
114
|
+
const prefix = `${name}__`;
|
|
115
|
+
if (namespacedName.startsWith(prefix)) {
|
|
116
|
+
return { serverName: name, toolName: namespacedName.slice(prefix.length) };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
async function connectStdio(name, config) {
|
|
122
|
+
log(`[${name}] Connecting via stdio: ${config.command} ${(config.args || []).join(" ")}`);
|
|
123
|
+
const client = new Client({ name: `mcp-daemon/${name}`, version: "1.0.0" }, { capabilities: {} });
|
|
124
|
+
const transport = new StdioClientTransport({
|
|
125
|
+
command: config.command,
|
|
126
|
+
args: config.args,
|
|
127
|
+
env: { ...process.env, ...(config.env || {}) },
|
|
128
|
+
cwd: config.cwd,
|
|
129
|
+
});
|
|
130
|
+
await client.connect(transport);
|
|
131
|
+
log(`[${name}] Connected (pid: ${transport.pid ?? "unknown"})`);
|
|
132
|
+
// Fetch tools
|
|
133
|
+
const toolsResult = await client.listTools();
|
|
134
|
+
const tools = (toolsResult.tools || []);
|
|
135
|
+
log(`[${name}] ${tools.length} tools available`);
|
|
136
|
+
return { name, config, client, tools, connected: true };
|
|
137
|
+
}
|
|
138
|
+
async function connectHttp(name, config) {
|
|
139
|
+
const maskedUrl = config.url.replace(/apikey=[^&\s]+/gi, "apikey=***");
|
|
140
|
+
log(`[${name}] Connecting via HTTP: ${maskedUrl}`);
|
|
141
|
+
if (config.headers) {
|
|
142
|
+
const headerNames = Object.keys(config.headers);
|
|
143
|
+
log(`[${name}] Custom headers: ${headerNames.join(", ")}`);
|
|
144
|
+
}
|
|
145
|
+
const client = new Client({ name: `mcp-daemon/${name}`, version: "1.0.0" }, { capabilities: {} });
|
|
146
|
+
const url = new URL(config.url);
|
|
147
|
+
// Build requestInit with custom headers and proxy support
|
|
148
|
+
const requestInit = {};
|
|
149
|
+
if (config.headers && Object.keys(config.headers).length > 0) {
|
|
150
|
+
requestInit.headers = config.headers;
|
|
151
|
+
}
|
|
152
|
+
if (proxyDispatcher) {
|
|
153
|
+
requestInit.dispatcher = proxyDispatcher;
|
|
154
|
+
log(`[${name}] Using HTTPS proxy`);
|
|
155
|
+
}
|
|
156
|
+
const opts = {};
|
|
157
|
+
if (Object.keys(requestInit).length > 0) {
|
|
158
|
+
opts.requestInit = requestInit;
|
|
159
|
+
}
|
|
160
|
+
const transport = new StreamableHTTPClientTransport(url, opts);
|
|
161
|
+
await client.connect(transport);
|
|
162
|
+
log(`[${name}] Connected`);
|
|
163
|
+
// Fetch tools
|
|
164
|
+
const toolsResult = await client.listTools();
|
|
165
|
+
const tools = (toolsResult.tools || []);
|
|
166
|
+
log(`[${name}] ${tools.length} tools available`);
|
|
167
|
+
return { name, config, client, tools, connected: true };
|
|
168
|
+
}
|
|
169
|
+
async function connectServer(name, config) {
|
|
170
|
+
try {
|
|
171
|
+
if (config.type === "stdio") {
|
|
172
|
+
return await connectStdio(name, config);
|
|
173
|
+
}
|
|
174
|
+
else if (config.type === "streamableHttp" || config.type === "http" || config.type === "sse") {
|
|
175
|
+
return await connectHttp(name, config);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
log(`[${name}] Unknown server type: ${config.type}`);
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
log(`[${name}] Connection failed:`, err.message);
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/** Refresh tools from a specific upstream */
|
|
188
|
+
async function refreshTools(server) {
|
|
189
|
+
try {
|
|
190
|
+
const result = await server.client.listTools();
|
|
191
|
+
server.tools = (result.tools || []);
|
|
192
|
+
log(`[${server.name}] Refreshed: ${server.tools.length} tools`);
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
log(`[${server.name}] Tool refresh failed:`, err.message);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
// Aggregated tool list + helper tools
|
|
200
|
+
// ---------------------------------------------------------------------------
|
|
201
|
+
/** Build a usage guide for the current daemon state */
|
|
202
|
+
function buildUsageGuide() {
|
|
203
|
+
const servers = [...upstreams.values()].filter((s) => s.connected);
|
|
204
|
+
const lines = [
|
|
205
|
+
"# MCP Daemon — Usage Guide",
|
|
206
|
+
"",
|
|
207
|
+
"This is an MCP gateway that aggregates tools from multiple upstream servers.",
|
|
208
|
+
"All tools are namespaced: `<server>__<tool>` (double underscore separator).",
|
|
209
|
+
"",
|
|
210
|
+
"## Connected Servers",
|
|
211
|
+
"",
|
|
212
|
+
];
|
|
213
|
+
for (const server of servers) {
|
|
214
|
+
const type = server.config.type;
|
|
215
|
+
lines.push(`### \`${server.name}\` (${type})`);
|
|
216
|
+
lines.push("");
|
|
217
|
+
lines.push(`Tools (${server.tools.length}):`);
|
|
218
|
+
for (const tool of server.tools) {
|
|
219
|
+
const desc = tool.description ? ` — ${tool.description.slice(0, 80)}${tool.description.length > 80 ? "..." : ""}` : "";
|
|
220
|
+
lines.push(`- \`${namespaceTool(server.name, tool.name)}\`${desc}`);
|
|
221
|
+
}
|
|
222
|
+
lines.push("");
|
|
223
|
+
}
|
|
224
|
+
lines.push("## How to Call Tools");
|
|
225
|
+
lines.push("");
|
|
226
|
+
lines.push("1. Find the tool you need from the list above");
|
|
227
|
+
lines.push("2. Call it using the full namespaced name (e.g., `github__get_file_contents`)");
|
|
228
|
+
lines.push("3. Pass arguments as a native JSON object — no special serialization needed");
|
|
229
|
+
lines.push("");
|
|
230
|
+
lines.push("### Example");
|
|
231
|
+
lines.push("");
|
|
232
|
+
// Generate a real example from the first server's first tool
|
|
233
|
+
if (servers.length > 0 && servers[0].tools.length > 0) {
|
|
234
|
+
const example = servers[0].tools[0];
|
|
235
|
+
const exampleName = namespaceTool(servers[0].name, example.name);
|
|
236
|
+
const exampleArgs = example.inputSchema?.properties
|
|
237
|
+
? Object.fromEntries(Object.entries(example.inputSchema.properties)
|
|
238
|
+
.slice(0, 3)
|
|
239
|
+
.map(([k, v]) => [k, v.type === "number" ? 1 : v.type === "boolean" ? true : "..."]))
|
|
240
|
+
: {};
|
|
241
|
+
lines.push("```json");
|
|
242
|
+
lines.push(`{ "name": "${exampleName}", "arguments": ${JSON.stringify(exampleArgs)} }`);
|
|
243
|
+
lines.push("```");
|
|
244
|
+
}
|
|
245
|
+
lines.push("");
|
|
246
|
+
return lines.join("\n");
|
|
247
|
+
}
|
|
248
|
+
/** Shim-local tool schemas injected into the aggregated tool list */
|
|
249
|
+
const DAEMON_HELP_TOOL = {
|
|
250
|
+
name: "daemon_help",
|
|
251
|
+
description: "Get usage guide for this MCP daemon — lists all connected servers, " +
|
|
252
|
+
"their tools (with namespaced names), and how to call them. " +
|
|
253
|
+
"Call this FIRST if you're unsure how to use this gateway.",
|
|
254
|
+
inputSchema: {
|
|
255
|
+
type: "object",
|
|
256
|
+
properties: {
|
|
257
|
+
server: {
|
|
258
|
+
type: "string",
|
|
259
|
+
description: "Optional: filter help to a specific server name",
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
function getAggregatedTools() {
|
|
265
|
+
const allTools = [DAEMON_HELP_TOOL];
|
|
266
|
+
for (const [, server] of upstreams) {
|
|
267
|
+
if (!server.connected)
|
|
268
|
+
continue;
|
|
269
|
+
for (const tool of server.tools) {
|
|
270
|
+
allTools.push({
|
|
271
|
+
...tool,
|
|
272
|
+
name: namespaceTool(server.name, tool.name),
|
|
273
|
+
description: `[${server.name}] ${tool.description || ""}`.trim(),
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return allTools;
|
|
278
|
+
}
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
// Downstream MCP server (exposed to cloud agents)
|
|
281
|
+
// ---------------------------------------------------------------------------
|
|
282
|
+
const downstreamTransports = new Map();
|
|
283
|
+
async function createDownstreamSession() {
|
|
284
|
+
const transport = new StreamableHTTPServerTransport({
|
|
285
|
+
sessionIdGenerator: () => randomUUID(),
|
|
286
|
+
onsessioninitialized: (sessionId) => {
|
|
287
|
+
log(`Session initialized: ${sessionId.slice(0, 12)}...`);
|
|
288
|
+
downstreamTransports.set(sessionId, transport);
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
transport.onclose = () => {
|
|
292
|
+
const sid = transport.sessionId;
|
|
293
|
+
if (sid && downstreamTransports.has(sid)) {
|
|
294
|
+
log(`Session closed: ${sid.slice(0, 12)}...`);
|
|
295
|
+
downstreamTransports.delete(sid);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
// Build server instructions so clients know how to use the daemon
|
|
299
|
+
const connectedServers = [...upstreams.values()].filter((s) => s.connected);
|
|
300
|
+
const serverList = connectedServers.map((s) => `${s.name} (${s.tools.length} tools)`).join(", ");
|
|
301
|
+
const instructions = [
|
|
302
|
+
"MCP Daemon — Multi-server gateway.",
|
|
303
|
+
`Connected servers: ${serverList}.`,
|
|
304
|
+
"All tools are namespaced as <server>__<tool> (double underscore).",
|
|
305
|
+
"Call daemon_help for a full usage guide with all available tools.",
|
|
306
|
+
].join(" ");
|
|
307
|
+
// Create MCP server for this session
|
|
308
|
+
const server = new Server({ name: "mcp-daemon", version: "1.0.0" }, {
|
|
309
|
+
capabilities: { tools: {} },
|
|
310
|
+
instructions,
|
|
311
|
+
});
|
|
312
|
+
// Handle tools/list — aggregate from all upstreams
|
|
313
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
314
|
+
// Refresh tools from all connected upstreams
|
|
315
|
+
await Promise.allSettled([...upstreams.values()]
|
|
316
|
+
.filter((s) => s.connected)
|
|
317
|
+
.map((s) => refreshTools(s)));
|
|
318
|
+
return { tools: getAggregatedTools() };
|
|
319
|
+
});
|
|
320
|
+
// Handle tools/call — route to correct upstream
|
|
321
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
322
|
+
const { name, arguments: args } = request.params;
|
|
323
|
+
// --- Shim-local: daemon_help ---
|
|
324
|
+
if (name === "daemon_help") {
|
|
325
|
+
const filterServer = args?.server || "";
|
|
326
|
+
if (filterServer) {
|
|
327
|
+
const upstream = upstreams.get(filterServer);
|
|
328
|
+
if (!upstream || !upstream.connected) {
|
|
329
|
+
return {
|
|
330
|
+
content: [{ type: "text", text: `Server "${filterServer}" not found. Connected servers: ${[...upstreams.keys()].join(", ")}` }],
|
|
331
|
+
isError: true,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
// Server-specific help
|
|
335
|
+
const lines = [
|
|
336
|
+
`# Server: ${filterServer} (${upstream.config.type})`,
|
|
337
|
+
"",
|
|
338
|
+
`## Tools (${upstream.tools.length})`,
|
|
339
|
+
"",
|
|
340
|
+
];
|
|
341
|
+
for (const tool of upstream.tools) {
|
|
342
|
+
lines.push(`### \`${namespaceTool(filterServer, tool.name)}\``);
|
|
343
|
+
if (tool.description)
|
|
344
|
+
lines.push(tool.description);
|
|
345
|
+
if (tool.inputSchema) {
|
|
346
|
+
lines.push("");
|
|
347
|
+
lines.push("```json");
|
|
348
|
+
lines.push(JSON.stringify(tool.inputSchema, null, 2));
|
|
349
|
+
lines.push("```");
|
|
350
|
+
}
|
|
351
|
+
lines.push("");
|
|
352
|
+
}
|
|
353
|
+
return {
|
|
354
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
return {
|
|
358
|
+
content: [{ type: "text", text: buildUsageGuide() }],
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
const parsed = parseNamespacedTool(name);
|
|
362
|
+
if (!parsed) {
|
|
363
|
+
return {
|
|
364
|
+
content: [{ type: "text", text: JSON.stringify({ error: `Unknown tool: ${name}. Tool names are prefixed with server name (e.g., "myserver__toolname"). Call daemon_help for a full list.` }) }],
|
|
365
|
+
isError: true,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
const server = upstreams.get(parsed.serverName);
|
|
369
|
+
if (!server || !server.connected) {
|
|
370
|
+
return {
|
|
371
|
+
content: [{ type: "text", text: JSON.stringify({ error: `Server "${parsed.serverName}" is not connected` }) }],
|
|
372
|
+
isError: true,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
try {
|
|
376
|
+
const result = await server.client.callTool({
|
|
377
|
+
name: parsed.toolName,
|
|
378
|
+
arguments: args || {},
|
|
379
|
+
});
|
|
380
|
+
// Passthrough the result as-is
|
|
381
|
+
if (result.content && Array.isArray(result.content)) {
|
|
382
|
+
return {
|
|
383
|
+
content: result.content,
|
|
384
|
+
isError: result.isError === true ? true : undefined,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
// Wrap non-standard results
|
|
388
|
+
const text = typeof result === "string" ? result : JSON.stringify(result);
|
|
389
|
+
return { content: [{ type: "text", text }] };
|
|
390
|
+
}
|
|
391
|
+
catch (err) {
|
|
392
|
+
const msg = err.message;
|
|
393
|
+
log(`[${parsed.serverName}] Tool call error (${parsed.toolName}):`, msg);
|
|
394
|
+
return {
|
|
395
|
+
content: [{ type: "text", text: `Error calling ${parsed.serverName}/${parsed.toolName}: ${msg}` }],
|
|
396
|
+
isError: true,
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
await server.connect(transport);
|
|
401
|
+
return transport;
|
|
402
|
+
}
|
|
403
|
+
// ---------------------------------------------------------------------------
|
|
404
|
+
// HTTP Server
|
|
405
|
+
// ---------------------------------------------------------------------------
|
|
406
|
+
function parseBody(req) {
|
|
407
|
+
return new Promise((resolve) => {
|
|
408
|
+
const chunks = [];
|
|
409
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
410
|
+
req.on("end", () => {
|
|
411
|
+
try {
|
|
412
|
+
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
413
|
+
resolve(raw ? JSON.parse(raw) : null);
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
resolve(null);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
req.on("error", () => resolve(null));
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
async function handleMcpRequest(req, res) {
|
|
423
|
+
// CORS
|
|
424
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
425
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
|
426
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Mcp-Session-Id, Last-Event-ID");
|
|
427
|
+
res.setHeader("Access-Control-Expose-Headers", "Mcp-Session-Id");
|
|
428
|
+
if (req.method === "OPTIONS") {
|
|
429
|
+
res.writeHead(204);
|
|
430
|
+
res.end();
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
434
|
+
try {
|
|
435
|
+
if (req.method === "POST") {
|
|
436
|
+
const body = await parseBody(req);
|
|
437
|
+
if (sessionId && downstreamTransports.has(sessionId)) {
|
|
438
|
+
const transport = downstreamTransports.get(sessionId);
|
|
439
|
+
await transport.handleRequest(req, res, body);
|
|
440
|
+
}
|
|
441
|
+
else if (!sessionId && isInitializeRequest(body)) {
|
|
442
|
+
const transport = await createDownstreamSession();
|
|
443
|
+
await transport.handleRequest(req, res, body);
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
447
|
+
res.end(JSON.stringify({
|
|
448
|
+
jsonrpc: "2.0",
|
|
449
|
+
error: { code: -32000, message: "Bad Request: No valid session ID provided" },
|
|
450
|
+
id: null,
|
|
451
|
+
}));
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
else if (req.method === "GET") {
|
|
455
|
+
if (!sessionId || !downstreamTransports.has(sessionId)) {
|
|
456
|
+
res.writeHead(400, { "Content-Type": "text/plain" });
|
|
457
|
+
res.end("Invalid or missing session ID");
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const transport = downstreamTransports.get(sessionId);
|
|
461
|
+
await transport.handleRequest(req, res);
|
|
462
|
+
}
|
|
463
|
+
else if (req.method === "DELETE") {
|
|
464
|
+
if (!sessionId || !downstreamTransports.has(sessionId)) {
|
|
465
|
+
res.writeHead(400, { "Content-Type": "text/plain" });
|
|
466
|
+
res.end("Invalid or missing session ID");
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
const transport = downstreamTransports.get(sessionId);
|
|
470
|
+
await transport.handleRequest(req, res);
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
res.writeHead(405, { "Content-Type": "text/plain" });
|
|
474
|
+
res.end("Method Not Allowed");
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
log("HTTP handler error:", error.message);
|
|
479
|
+
if (!res.headersSent) {
|
|
480
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
481
|
+
res.end(JSON.stringify({
|
|
482
|
+
jsonrpc: "2.0",
|
|
483
|
+
error: { code: -32603, message: "Internal server error" },
|
|
484
|
+
id: null,
|
|
485
|
+
}));
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
// ---------------------------------------------------------------------------
|
|
490
|
+
// Main
|
|
491
|
+
// ---------------------------------------------------------------------------
|
|
492
|
+
async function main() {
|
|
493
|
+
log("Starting MCP Daemon...");
|
|
494
|
+
const configs = loadConfig();
|
|
495
|
+
const serverNames = Object.keys(configs);
|
|
496
|
+
if (serverNames.length === 0) {
|
|
497
|
+
log("Fatal: No servers defined in configuration.");
|
|
498
|
+
process.exit(1);
|
|
499
|
+
}
|
|
500
|
+
log(`Configured servers: ${serverNames.join(", ")}`);
|
|
501
|
+
// Connect to all upstream servers in parallel
|
|
502
|
+
const results = await Promise.allSettled(serverNames.map(async (name) => {
|
|
503
|
+
const server = await connectServer(name, configs[name]);
|
|
504
|
+
if (server) {
|
|
505
|
+
upstreams.set(name, server);
|
|
506
|
+
}
|
|
507
|
+
return server;
|
|
508
|
+
}));
|
|
509
|
+
const connected = [...upstreams.values()].filter((s) => s.connected);
|
|
510
|
+
const totalTools = connected.reduce((sum, s) => sum + s.tools.length, 0);
|
|
511
|
+
if (connected.length === 0) {
|
|
512
|
+
log("Fatal: No upstream servers connected successfully.");
|
|
513
|
+
process.exit(1);
|
|
514
|
+
}
|
|
515
|
+
log(`Connected: ${connected.length}/${serverNames.length} servers, ${totalTools} total tools`);
|
|
516
|
+
// Print tool summary
|
|
517
|
+
for (const server of connected) {
|
|
518
|
+
log(` [${server.name}] ${server.tools.length} tools: ${server.tools.slice(0, 5).map((t) => t.name).join(", ")}${server.tools.length > 5 ? "..." : ""}`);
|
|
519
|
+
}
|
|
520
|
+
// Start HTTP server
|
|
521
|
+
const httpServer = http.createServer((req, res) => {
|
|
522
|
+
const url = new URL(req.url || "/", `http://${req.headers.host || "localhost"}`);
|
|
523
|
+
if (url.pathname === "/mcp" || url.pathname === "/mcp/") {
|
|
524
|
+
// Apikey gate
|
|
525
|
+
if (APIKEY && url.searchParams.get("apikey") !== APIKEY) {
|
|
526
|
+
res.writeHead(401, { "Content-Type": "application/json" });
|
|
527
|
+
res.end(JSON.stringify({
|
|
528
|
+
jsonrpc: "2.0",
|
|
529
|
+
error: { code: -32001, message: "Unauthorized: invalid or missing apikey" },
|
|
530
|
+
id: null,
|
|
531
|
+
}));
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
handleMcpRequest(req, res).catch((err) => {
|
|
535
|
+
log("Unhandled error:", err.message);
|
|
536
|
+
if (!res.headersSent) {
|
|
537
|
+
res.writeHead(500);
|
|
538
|
+
res.end("Internal Server Error");
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
else if (url.pathname === "/health" || url.pathname === "/healthz") {
|
|
543
|
+
const serverStatus = {};
|
|
544
|
+
for (const [name, server] of upstreams) {
|
|
545
|
+
serverStatus[name] = {
|
|
546
|
+
connected: server.connected,
|
|
547
|
+
tools: server.tools.length,
|
|
548
|
+
type: server.config.type,
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
552
|
+
res.end(JSON.stringify({
|
|
553
|
+
status: "ok",
|
|
554
|
+
sessions: downstreamTransports.size,
|
|
555
|
+
uptime: process.uptime(),
|
|
556
|
+
servers: serverStatus,
|
|
557
|
+
totalTools,
|
|
558
|
+
}));
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
562
|
+
res.end("Not Found — MCP endpoint is at /mcp");
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
httpServer.listen(PORT, HOST, () => {
|
|
566
|
+
log(`Daemon listening on http://${HOST}:${PORT}/mcp`);
|
|
567
|
+
log(`Health check: http://${HOST}:${PORT}/health`);
|
|
568
|
+
log(`Auth: ${APIKEY ? "apikey required (?apikey=...)" : "OPEN (no MCP_APIKEY set)"}`);
|
|
569
|
+
log("Waiting for MCP client connections...");
|
|
570
|
+
});
|
|
571
|
+
// Graceful shutdown
|
|
572
|
+
const shutdown = async () => {
|
|
573
|
+
log("Shutting down daemon...");
|
|
574
|
+
// Close downstream sessions
|
|
575
|
+
for (const [sid, transport] of downstreamTransports) {
|
|
576
|
+
try {
|
|
577
|
+
await transport.close();
|
|
578
|
+
}
|
|
579
|
+
catch (err) {
|
|
580
|
+
log(`Error closing session ${sid.slice(0, 12)}:`, err.message);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
downstreamTransports.clear();
|
|
584
|
+
// Disconnect upstream servers
|
|
585
|
+
for (const [name, server] of upstreams) {
|
|
586
|
+
try {
|
|
587
|
+
log(`Disconnecting [${name}]...`);
|
|
588
|
+
await server.client.close();
|
|
589
|
+
}
|
|
590
|
+
catch (err) {
|
|
591
|
+
log(`Error disconnecting [${name}]:`, err.message);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
upstreams.clear();
|
|
595
|
+
httpServer.close(() => {
|
|
596
|
+
log("Daemon stopped");
|
|
597
|
+
process.exit(0);
|
|
598
|
+
});
|
|
599
|
+
setTimeout(() => process.exit(1), 5000).unref();
|
|
600
|
+
};
|
|
601
|
+
process.on("SIGINT", shutdown);
|
|
602
|
+
process.on("SIGTERM", shutdown);
|
|
603
|
+
}
|
|
604
|
+
main().catch((err) => {
|
|
605
|
+
log("Fatal:", err);
|
|
606
|
+
process.exit(1);
|
|
607
|
+
});
|
|
608
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,14 +5,19 @@
|
|
|
5
5
|
* Subcommands:
|
|
6
6
|
* (default) stdio transport — for local MCP clients (Claude Code, Cursor, etc.)
|
|
7
7
|
* serve HTTP Streamable transport — for remote agents over HTTP
|
|
8
|
+
* daemon Multi-server MCP gateway — connects to N upstreams, exposes via HTTP
|
|
8
9
|
*
|
|
9
10
|
* Usage:
|
|
10
|
-
* # Stdio mode (default)
|
|
11
|
+
* # Stdio mode (default) — single upstream via mcpproxy-go
|
|
11
12
|
* MCP_URL="https://proxy.example.com/mcp/?apikey=KEY" npx @luutuankiet/mcp-proxy-shim
|
|
12
13
|
*
|
|
13
|
-
* # HTTP server mode
|
|
14
|
+
* # HTTP server mode — single upstream via mcpproxy-go
|
|
14
15
|
* MCP_URL="https://proxy.example.com/mcp/?apikey=KEY" npx @luutuankiet/mcp-proxy-shim serve
|
|
15
|
-
*
|
|
16
|
+
*
|
|
17
|
+
* # Daemon mode — multi-server gateway (stdio + HTTP upstreams)
|
|
18
|
+
* MCP_SERVERS='{"github":{"type":"stdio","command":"npx","args":["-y","@modelcontextprotocol/server-github"]}}' \
|
|
19
|
+
* npx @luutuankiet/mcp-proxy-shim daemon
|
|
20
|
+
* MCP_CONFIG=./mcp-servers.json npx @luutuankiet/mcp-proxy-shim daemon
|
|
16
21
|
*
|
|
17
22
|
* .mcp.json entry (stdio):
|
|
18
23
|
* { "mcpServers": { "proxy": { "type": "stdio", "command": "npx", "args": ["-y", "@luutuankiet/mcp-proxy-shim"], "env": { "MCP_URL": "..." } } } }
|