@anyshift/mcp-proxy 0.4.0 → 0.4.2-dev0
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/fileWriter/writer.js +14 -0
- package/dist/index.js +58 -11
- package/dist/types/index.d.ts +4 -0
- package/package.json +1 -1
|
@@ -5,6 +5,18 @@ import { generateQueryAssistSchema, generateJsonlQueryAssistSchema } from './sch
|
|
|
5
5
|
import { parseDynatraceDqlResponse, isDynatraceDqlTool, } from './dynatrace.js';
|
|
6
6
|
// Default minimum character count to trigger file writing
|
|
7
7
|
const DEFAULT_MIN_CHARS = 1000;
|
|
8
|
+
/**
|
|
9
|
+
* Generate the message to include when data is written to file, guiding the LLM on how to use the result.
|
|
10
|
+
* The message conditionally includes the timeseries tool based on configuration.
|
|
11
|
+
*/
|
|
12
|
+
function getFileWrittenMessage(enableTimeseries) {
|
|
13
|
+
const toolsList = enableTimeseries
|
|
14
|
+
? '"execute_jq_query" tool (for JSON/JSONL data extraction and transformation) or "detect_timeseries_anomalies" tool (for time series analysis)'
|
|
15
|
+
: '"execute_jq_query" tool (for JSON/JSONL data extraction and transformation)';
|
|
16
|
+
return `To read this file, use the ${toolsList}.
|
|
17
|
+
|
|
18
|
+
IMPORTANT for supporting facts: This tool_id CANNOT be used as the proxy_tool_id in your output's supporting_facts evidence. You must read the file using one of the tools above and use THAT tool's tool_id as the proxy_tool_id to support facts in your output.`;
|
|
19
|
+
}
|
|
8
20
|
/**
|
|
9
21
|
* Detect whether content is JSON, JSONL, or plain text
|
|
10
22
|
*/
|
|
@@ -251,6 +263,7 @@ async function handleDynatraceDqlResponse(config, tool_id, parsedDql) {
|
|
|
251
263
|
wroteToFile: true,
|
|
252
264
|
filePath: filepath,
|
|
253
265
|
fileSchema,
|
|
266
|
+
message: getFileWrittenMessage(config.enableTimeseries ?? false),
|
|
254
267
|
};
|
|
255
268
|
}
|
|
256
269
|
catch (error) {
|
|
@@ -388,6 +401,7 @@ export async function handleToolResponse(config, toolName, args, responseData) {
|
|
|
388
401
|
wroteToFile: true,
|
|
389
402
|
filePath: filepath,
|
|
390
403
|
fileSchema,
|
|
404
|
+
message: getFileWrittenMessage(config.enableTimeseries ?? false),
|
|
391
405
|
};
|
|
392
406
|
}
|
|
393
407
|
catch (error) {
|
package/dist/index.js
CHANGED
|
@@ -324,7 +324,8 @@ async function main() {
|
|
|
324
324
|
toolAbbreviations: {}, // No service-specific abbreviations (generic proxy)
|
|
325
325
|
schemaMaxDepth: SCHEMA_MAX_DEPTH,
|
|
326
326
|
schemaMaxPaths: SCHEMA_MAX_PATHS,
|
|
327
|
-
schemaMaxKeys: SCHEMA_MAX_KEYS
|
|
327
|
+
schemaMaxKeys: SCHEMA_MAX_KEYS,
|
|
328
|
+
enableTimeseries: ENABLE_TIMESERIES
|
|
328
329
|
};
|
|
329
330
|
const fileWriter = createFileWriter(fileWriterConfig);
|
|
330
331
|
// JQ tool configuration
|
|
@@ -452,26 +453,72 @@ async function main() {
|
|
|
452
453
|
const childReturnedError = !!result.isError;
|
|
453
454
|
// Process result through file writer to get unified response
|
|
454
455
|
if (result.content && Array.isArray(result.content) && result.content.length > 0) {
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
456
|
+
// Extract text content and embedded resources from all content items
|
|
457
|
+
const textContents = [];
|
|
458
|
+
const resources = [];
|
|
459
|
+
for (const item of result.content) {
|
|
460
|
+
if (item.type === 'text' && typeof item.text === 'string') {
|
|
461
|
+
textContents.push(item.text);
|
|
462
|
+
}
|
|
463
|
+
else if (item.type === 'resource' && item.resource) {
|
|
464
|
+
// Handle EmbeddedResource - extract content from resource field
|
|
465
|
+
const resource = item.resource;
|
|
466
|
+
const resourceObj = {};
|
|
467
|
+
if (resource.uri)
|
|
468
|
+
resourceObj.uri = resource.uri;
|
|
469
|
+
if (resource.mimeType)
|
|
470
|
+
resourceObj.mimeType = resource.mimeType;
|
|
471
|
+
// Content can be in 'text' (string) or 'blob' (base64 binary)
|
|
472
|
+
if (resource.text) {
|
|
473
|
+
resourceObj.content = resource.text;
|
|
474
|
+
}
|
|
475
|
+
else if (resource.blob) {
|
|
476
|
+
// For binary content, keep as base64 or decode based on mimeType
|
|
477
|
+
resourceObj.content = typeof resource.blob === 'string'
|
|
478
|
+
? resource.blob
|
|
479
|
+
: Buffer.from(resource.blob).toString('base64');
|
|
480
|
+
}
|
|
481
|
+
resources.push(resourceObj);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
// Build combined content object
|
|
485
|
+
let combinedContent;
|
|
486
|
+
if (resources.length > 0) {
|
|
487
|
+
// Has resources - combine text and resources into single object
|
|
488
|
+
combinedContent = {
|
|
489
|
+
text: textContents.length === 1 ? textContents[0] : textContents,
|
|
490
|
+
resources: resources.length === 1 ? resources[0] : resources
|
|
491
|
+
};
|
|
492
|
+
if (ENABLE_LOGGING) {
|
|
493
|
+
console.debug(`[mcp-proxy] Combined ${textContents.length} text items and ${resources.length} resources`);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
else if (textContents.length > 0) {
|
|
497
|
+
// Text only - use first text content (original behavior)
|
|
498
|
+
combinedContent = textContents[0];
|
|
499
|
+
}
|
|
500
|
+
if (combinedContent !== undefined) {
|
|
501
|
+
const contentStr = typeof combinedContent === 'string'
|
|
502
|
+
? combinedContent
|
|
503
|
+
: JSON.stringify(combinedContent);
|
|
504
|
+
const originalLength = contentStr.length;
|
|
458
505
|
// If child returned error, pass through directly without file writing
|
|
459
506
|
if (childReturnedError) {
|
|
460
507
|
const tool_id = generateToolId(toolName, toolArgs, fileWriterConfig.toolAbbreviations);
|
|
461
508
|
if (ENABLE_LOGGING) {
|
|
462
|
-
console.debug(`[mcp-proxy] Child MCP returned error for ${toolName}: ${
|
|
509
|
+
console.debug(`[mcp-proxy] Child MCP returned error for ${toolName}: ${contentStr.substring(0, 100)}...`);
|
|
463
510
|
}
|
|
464
511
|
return {
|
|
465
512
|
content: [{
|
|
466
513
|
type: 'text',
|
|
467
|
-
text: JSON.stringify(createErrorResponse(tool_id,
|
|
514
|
+
text: JSON.stringify(createErrorResponse(tool_id, contentStr, toolArgs), null, 2)
|
|
468
515
|
}],
|
|
469
516
|
isError: true
|
|
470
517
|
};
|
|
471
518
|
}
|
|
472
519
|
// Get unified response from file writer
|
|
473
520
|
const unifiedResponse = await fileWriter.handleResponse(toolName, toolArgs, {
|
|
474
|
-
content: [{ type: 'text', text:
|
|
521
|
+
content: [{ type: 'text', text: contentStr }]
|
|
475
522
|
});
|
|
476
523
|
if (ENABLE_LOGGING) {
|
|
477
524
|
if (unifiedResponse.wroteToFile) {
|
|
@@ -483,13 +530,13 @@ async function main() {
|
|
|
483
530
|
}
|
|
484
531
|
// If not written to file, apply truncation to outputContent
|
|
485
532
|
if (!unifiedResponse.wroteToFile && unifiedResponse.outputContent) {
|
|
486
|
-
const
|
|
533
|
+
const outputStr = typeof unifiedResponse.outputContent === 'string'
|
|
487
534
|
? unifiedResponse.outputContent
|
|
488
535
|
: JSON.stringify(unifiedResponse.outputContent);
|
|
489
|
-
const truncated = truncateResponseIfNeeded(truncationConfig,
|
|
490
|
-
if (truncated.length <
|
|
536
|
+
const truncated = truncateResponseIfNeeded(truncationConfig, outputStr);
|
|
537
|
+
if (truncated.length < outputStr.length) {
|
|
491
538
|
if (ENABLE_LOGGING) {
|
|
492
|
-
console.debug(`[mcp-proxy] Truncated response: ${
|
|
539
|
+
console.debug(`[mcp-proxy] Truncated response: ${outputStr.length} → ${truncated.length} chars`);
|
|
493
540
|
}
|
|
494
541
|
// Re-parse if it was JSON, otherwise keep as string
|
|
495
542
|
try {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -34,6 +34,8 @@ export interface FileWriterConfig {
|
|
|
34
34
|
schemaMaxPaths?: number;
|
|
35
35
|
/** Maximum keys to analyze per object (default: 50) */
|
|
36
36
|
schemaMaxKeys?: number;
|
|
37
|
+
/** Whether the timeseries anomaly detection tool is enabled (affects file-written message) */
|
|
38
|
+
enableTimeseries?: boolean;
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
39
41
|
* Configuration for the JQ tool
|
|
@@ -74,4 +76,6 @@ export interface UnifiedToolResponse {
|
|
|
74
76
|
isRetryAttempt?: boolean;
|
|
75
77
|
/** The original tool_id this call is retrying */
|
|
76
78
|
originalToolId?: string;
|
|
79
|
+
/** Informational message for the LLM (e.g., guidance on how to use the file) */
|
|
80
|
+
message?: string;
|
|
77
81
|
}
|
package/package.json
CHANGED