@anyshift/mcp-proxy 0.2.3-dev → 0.2.3
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 +33 -25
- package/dist/utils/pathValidation.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -125,7 +125,7 @@ const ENABLE_LOGGING = process.env.MCP_PROXY_ENABLE_LOGGING === 'true';
|
|
|
125
125
|
// Validate configuration
|
|
126
126
|
// CHILD_COMMAND is now optional - if not provided, proxy runs in standalone mode (JQ only)
|
|
127
127
|
if (!CHILD_COMMAND) {
|
|
128
|
-
console.
|
|
128
|
+
console.debug('[mcp-proxy] No child command specified - running in standalone mode (JQ only)');
|
|
129
129
|
if (!ENABLE_JQ) {
|
|
130
130
|
console.error('ERROR: Standalone mode requires JQ to be enabled (MCP_PROXY_ENABLE_JQ must not be false)');
|
|
131
131
|
process.exit(1);
|
|
@@ -168,41 +168,45 @@ for (const [key, value] of Object.entries(process.env)) {
|
|
|
168
168
|
// CONFIGURATION SUMMARY
|
|
169
169
|
// ============================================================================
|
|
170
170
|
if (ENABLE_LOGGING) {
|
|
171
|
-
console.
|
|
172
|
-
console.
|
|
171
|
+
console.debug('[mcp-proxy] Configuration:');
|
|
172
|
+
console.debug(` Mode: ${CHILD_COMMAND ? 'wrapper' : 'standalone (JQ only)'}`);
|
|
173
173
|
if (CHILD_COMMAND) {
|
|
174
|
-
console.
|
|
175
|
-
console.
|
|
174
|
+
console.debug(` Child command: ${CHILD_COMMAND}`);
|
|
175
|
+
console.debug(` Child args: [${CHILD_ARGS.join(', ')}]`);
|
|
176
176
|
}
|
|
177
|
-
console.
|
|
178
|
-
console.
|
|
179
|
-
console.
|
|
177
|
+
console.debug(` Max tokens: ${MAX_TOKENS}`);
|
|
178
|
+
console.debug(` Chars per token: ${CHARS_PER_TOKEN}`);
|
|
179
|
+
console.debug(` Write to file: ${WRITE_TO_FILE}`);
|
|
180
180
|
if (WRITE_TO_FILE) {
|
|
181
|
-
console.
|
|
182
|
-
console.
|
|
181
|
+
console.debug(` Output path: ${OUTPUT_PATH}`);
|
|
182
|
+
console.debug(` Min chars for write: ${MIN_CHARS_FOR_WRITE}`);
|
|
183
183
|
}
|
|
184
|
-
console.
|
|
184
|
+
console.debug(` JQ tool enabled: ${ENABLE_JQ}`);
|
|
185
185
|
if (CHILD_COMMAND) {
|
|
186
|
-
console.
|
|
186
|
+
console.debug(` Pass-through env vars: ${Object.keys(childEnv).length}`);
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
// ============================================================================
|
|
190
190
|
// MAIN PROXY LOGIC
|
|
191
191
|
// ============================================================================
|
|
192
192
|
async function main() {
|
|
193
|
-
console.
|
|
193
|
+
console.debug('[mcp-proxy] Starting generic MCP proxy...');
|
|
194
194
|
// ------------------------------------------------------------------------
|
|
195
195
|
// 1. SPAWN CHILD MCP SERVER (if configured)
|
|
196
196
|
// ------------------------------------------------------------------------
|
|
197
197
|
let childClient = null;
|
|
198
198
|
let childToolsResponse = { tools: [] };
|
|
199
199
|
if (CHILD_COMMAND) {
|
|
200
|
-
console.
|
|
200
|
+
console.debug(`[mcp-proxy] Spawning child MCP: ${CHILD_COMMAND}`);
|
|
201
201
|
const childTransport = new StdioClientTransport({
|
|
202
202
|
command: CHILD_COMMAND,
|
|
203
203
|
args: CHILD_ARGS,
|
|
204
204
|
env: childEnv // All values are defined strings (filtered in extraction loop)
|
|
205
205
|
});
|
|
206
|
+
// Log errors instead of crashing silently
|
|
207
|
+
childTransport.onerror = (error) => {
|
|
208
|
+
console.error('[mcp-proxy] Child error:', error.message);
|
|
209
|
+
};
|
|
206
210
|
childClient = new Client({
|
|
207
211
|
name: 'mcp-proxy-client',
|
|
208
212
|
version: '1.0.0'
|
|
@@ -210,15 +214,17 @@ async function main() {
|
|
|
210
214
|
capabilities: {}
|
|
211
215
|
});
|
|
212
216
|
await childClient.connect(childTransport);
|
|
213
|
-
console.
|
|
217
|
+
console.debug('[mcp-proxy] Connected to child MCP');
|
|
218
|
+
// Give child 50ms to stabilize before making requests
|
|
219
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
214
220
|
// ------------------------------------------------------------------------
|
|
215
221
|
// 2. DISCOVER TOOLS FROM CHILD MCP
|
|
216
222
|
// ------------------------------------------------------------------------
|
|
217
223
|
childToolsResponse = await childClient.listTools();
|
|
218
|
-
console.
|
|
224
|
+
console.debug(`[mcp-proxy] Discovered ${childToolsResponse.tools.length} tools from child MCP`);
|
|
219
225
|
}
|
|
220
226
|
else {
|
|
221
|
-
console.
|
|
227
|
+
console.debug('[mcp-proxy] Standalone mode - no child MCP');
|
|
222
228
|
}
|
|
223
229
|
// ------------------------------------------------------------------------
|
|
224
230
|
// 3. CREATE PROXY SERVER
|
|
@@ -267,7 +273,7 @@ async function main() {
|
|
|
267
273
|
...childToolsResponse.tools,
|
|
268
274
|
...(jqTool ? [jqTool.toolDefinition] : [])
|
|
269
275
|
];
|
|
270
|
-
console.
|
|
276
|
+
console.debug(`[mcp-proxy] Exposing ${allTools.length} tools total (${childToolsResponse.tools.length} from child${jqTool ? ' + 1 JQ' : ''})`);
|
|
271
277
|
// ------------------------------------------------------------------------
|
|
272
278
|
// 6. HANDLE TOOL LIST REQUESTS
|
|
273
279
|
// ------------------------------------------------------------------------
|
|
@@ -281,14 +287,14 @@ async function main() {
|
|
|
281
287
|
const toolName = request.params.name;
|
|
282
288
|
const toolArgs = request.params.arguments || {};
|
|
283
289
|
if (ENABLE_LOGGING) {
|
|
284
|
-
console.
|
|
290
|
+
console.debug(`[mcp-proxy] Tool call: ${toolName}`);
|
|
285
291
|
}
|
|
286
292
|
try {
|
|
287
293
|
let result;
|
|
288
294
|
// Handle JQ tool locally (if enabled)
|
|
289
295
|
if (toolName === 'execute_jq_query' && jqTool) {
|
|
290
296
|
if (ENABLE_LOGGING) {
|
|
291
|
-
console.
|
|
297
|
+
console.debug('[mcp-proxy] Executing JQ tool locally');
|
|
292
298
|
}
|
|
293
299
|
result = await jqTool.handler({
|
|
294
300
|
params: { arguments: toolArgs }
|
|
@@ -306,7 +312,7 @@ async function main() {
|
|
|
306
312
|
};
|
|
307
313
|
}
|
|
308
314
|
if (ENABLE_LOGGING) {
|
|
309
|
-
console.
|
|
315
|
+
console.debug(`[mcp-proxy] Forwarding to child MCP: ${toolName}`);
|
|
310
316
|
}
|
|
311
317
|
result = await childClient.callTool({
|
|
312
318
|
name: toolName,
|
|
@@ -336,7 +342,7 @@ async function main() {
|
|
|
336
342
|
item.text = resultText;
|
|
337
343
|
fileWasWritten = true;
|
|
338
344
|
if (ENABLE_LOGGING) {
|
|
339
|
-
console.
|
|
345
|
+
console.debug(`[mcp-proxy] File writing applied for ${toolName} (${originalLength} chars written to file)`);
|
|
340
346
|
}
|
|
341
347
|
}
|
|
342
348
|
}
|
|
@@ -346,7 +352,7 @@ async function main() {
|
|
|
346
352
|
if (!fileWasWritten) {
|
|
347
353
|
item.text = truncateResponseIfNeeded(truncationConfig, item.text);
|
|
348
354
|
if (item.text.length < originalLength && ENABLE_LOGGING) {
|
|
349
|
-
console.
|
|
355
|
+
console.debug(`[mcp-proxy] Truncated response: ${originalLength} → ${item.text.length} chars`);
|
|
350
356
|
}
|
|
351
357
|
}
|
|
352
358
|
}
|
|
@@ -370,8 +376,10 @@ async function main() {
|
|
|
370
376
|
// ------------------------------------------------------------------------
|
|
371
377
|
const transport = new StdioServerTransport();
|
|
372
378
|
await server.connect(transport);
|
|
373
|
-
console.
|
|
374
|
-
console.
|
|
379
|
+
console.debug('[mcp-proxy] Proxy server ready on stdio');
|
|
380
|
+
console.debug('[mcp-proxy] Waiting for MCP protocol messages...');
|
|
381
|
+
// Prevent EPIPE from crashing the process
|
|
382
|
+
process.on('SIGPIPE', () => { });
|
|
375
383
|
}
|
|
376
384
|
// ============================================================================
|
|
377
385
|
// START THE PROXY
|
|
@@ -32,7 +32,7 @@ export const validatePathWithinAllowedDirs = (filePath, allowedPaths) => {
|
|
|
32
32
|
const allowedPathReal = realpathSync(path.resolve(allowedPath));
|
|
33
33
|
// Check if the real path is within this allowed directory
|
|
34
34
|
if (realPath.startsWith(allowedPathReal + path.sep) || realPath === allowedPathReal) {
|
|
35
|
-
console.
|
|
35
|
+
console.debug(`[validatePathWithinAllowedDirs] Path allowed (within ${allowedPathReal}): ${realPath}`);
|
|
36
36
|
return realPath;
|
|
37
37
|
}
|
|
38
38
|
}
|
package/package.json
CHANGED