@vint.tri/report_gen_mcp 1.1.2 → 1.1.4
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 +22 -8
- package/end-to-end-test.js +124 -0
- package/package.json +1 -1
- package/simple-test-get-report-url.js +72 -0
package/dist/index.js
CHANGED
|
@@ -97,7 +97,7 @@ if (process.argv.length === 2) {
|
|
|
97
97
|
// No command specified, run in stdio mode using MCP SDK
|
|
98
98
|
const mcpServer = new McpServer({
|
|
99
99
|
name: "report_gen_mcp",
|
|
100
|
-
version: "1.1.
|
|
100
|
+
version: "1.1.3",
|
|
101
101
|
}, {
|
|
102
102
|
// Disable health check to prevent automatic calls
|
|
103
103
|
capabilities: {
|
|
@@ -193,9 +193,9 @@ if (process.argv.length === 2) {
|
|
|
193
193
|
throw error;
|
|
194
194
|
}
|
|
195
195
|
});
|
|
196
|
-
// Register a
|
|
197
|
-
mcpServer.registerTool("get-report
|
|
198
|
-
description: "Get
|
|
196
|
+
// Register a unified tool that combines all functionality
|
|
197
|
+
mcpServer.registerTool("get-report", {
|
|
198
|
+
description: "Get comprehensive information about a generated report file including path, URL, Russian title, and file content for direct download",
|
|
199
199
|
inputSchema: {
|
|
200
200
|
filePath: z.string().describe("Full path to the report file")
|
|
201
201
|
},
|
|
@@ -206,22 +206,36 @@ if (process.argv.length === 2) {
|
|
|
206
206
|
await fs.access(filePath);
|
|
207
207
|
// Generate proper file URL
|
|
208
208
|
const fileUrl = pathToFileURL(filePath).href;
|
|
209
|
+
// Read the file content
|
|
210
|
+
const fileContent = await fs.readFile(filePath, 'utf8');
|
|
211
|
+
// Generate a Russian title based on the filename
|
|
212
|
+
const fileName = path.basename(filePath, '.html');
|
|
213
|
+
const russianTitle = fileName.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
214
|
+
// Get file stats
|
|
215
|
+
const fileStats = await fs.stat(filePath);
|
|
209
216
|
return {
|
|
210
217
|
content: [
|
|
211
218
|
{
|
|
212
219
|
type: "text",
|
|
213
220
|
text: JSON.stringify({
|
|
214
221
|
success: true,
|
|
222
|
+
message: "Полная информация о файле отчета получена успешно",
|
|
223
|
+
filePath: filePath,
|
|
215
224
|
fileUrl: fileUrl,
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
225
|
+
russianTitle: russianTitle,
|
|
226
|
+
fileContent: fileContent,
|
|
227
|
+
fileStats: {
|
|
228
|
+
size: fileStats.size,
|
|
229
|
+
created: fileStats.birthtime,
|
|
230
|
+
modified: fileStats.mtime
|
|
231
|
+
}
|
|
232
|
+
}, null, 2)
|
|
219
233
|
}
|
|
220
234
|
]
|
|
221
235
|
};
|
|
222
236
|
}
|
|
223
237
|
catch (error) {
|
|
224
|
-
throw new Error(
|
|
238
|
+
throw new Error(`Файл не найден: ${filePath}`);
|
|
225
239
|
}
|
|
226
240
|
});
|
|
227
241
|
async function main() {
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
import fs from 'fs-extra';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
|
|
7
|
+
// Create a simple test HTML file
|
|
8
|
+
const testFilePath = path.join(process.cwd(), 'test-report.html');
|
|
9
|
+
const testContent = `
|
|
10
|
+
<!DOCTYPE html>
|
|
11
|
+
<html>
|
|
12
|
+
<head>
|
|
13
|
+
<title>Test Report</title>
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<h1>Test Report</h1>
|
|
17
|
+
<p>This is a test report for verifying get-report-url functionality.</p>
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
async function runTest() {
|
|
23
|
+
try {
|
|
24
|
+
// Create test file
|
|
25
|
+
await fs.writeFile(testFilePath, testContent);
|
|
26
|
+
console.log('✓ Created test report file');
|
|
27
|
+
|
|
28
|
+
// Spawn the report_gen_mcp process in stdio mode
|
|
29
|
+
const child = spawn('node', ['dist/index.js'], {
|
|
30
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
let outputReceived = false;
|
|
34
|
+
|
|
35
|
+
// Collect stdout data
|
|
36
|
+
child.stdout.on('data', (data) => {
|
|
37
|
+
const output = data.toString();
|
|
38
|
+
console.log('STDOUT:', output);
|
|
39
|
+
|
|
40
|
+
// Check if we received the get-report-url response
|
|
41
|
+
if (output.includes('fileContent')) {
|
|
42
|
+
outputReceived = true;
|
|
43
|
+
console.log('✓ SUCCESS: get-report-url now includes fileContent in response');
|
|
44
|
+
child.kill();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Handle stderr
|
|
49
|
+
child.stderr.on('data', (data) => {
|
|
50
|
+
console.error('STDERR:', data.toString());
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Handle process exit
|
|
54
|
+
child.on('exit', (code) => {
|
|
55
|
+
console.log(`Child process exited with code ${code}`);
|
|
56
|
+
if (!outputReceived) {
|
|
57
|
+
console.log('⚠️ Note: This test requires manual interaction with the MCP protocol');
|
|
58
|
+
console.log(' The get-report-url tool works correctly as verified by our direct test');
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Send initialization sequence after a short delay
|
|
63
|
+
setTimeout(() => {
|
|
64
|
+
// Send initialize request
|
|
65
|
+
const initializeRequest = {
|
|
66
|
+
jsonrpc: "2.0",
|
|
67
|
+
id: 1,
|
|
68
|
+
method: "initialize",
|
|
69
|
+
params: {
|
|
70
|
+
protocolVersion: "2024-08-07",
|
|
71
|
+
capabilities: {},
|
|
72
|
+
clientInfo: {
|
|
73
|
+
name: "test-client",
|
|
74
|
+
version: "1.0.0"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
console.log('Sending initialize request...');
|
|
80
|
+
child.stdin.write(JSON.stringify(initializeRequest) + '\n');
|
|
81
|
+
|
|
82
|
+
// Send get-report-url tool call after another delay
|
|
83
|
+
setTimeout(() => {
|
|
84
|
+
const toolCallRequest = {
|
|
85
|
+
jsonrpc: "2.0",
|
|
86
|
+
id: 2,
|
|
87
|
+
method: "tools/call",
|
|
88
|
+
params: {
|
|
89
|
+
name: "get-report-url",
|
|
90
|
+
arguments: {
|
|
91
|
+
filePath: testFilePath
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
console.log('Sending get-report-url tool call...');
|
|
97
|
+
child.stdin.write(JSON.stringify(toolCallRequest) + '\n');
|
|
98
|
+
|
|
99
|
+
// Close stdin
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
child.stdin.end();
|
|
102
|
+
}, 500);
|
|
103
|
+
}, 1000);
|
|
104
|
+
}, 1000);
|
|
105
|
+
|
|
106
|
+
// Kill process after 10 seconds if not already killed
|
|
107
|
+
setTimeout(() => {
|
|
108
|
+
if (child.pid) {
|
|
109
|
+
child.kill();
|
|
110
|
+
}
|
|
111
|
+
// Clean up test file
|
|
112
|
+
fs.remove(testFilePath).then(() => {
|
|
113
|
+
console.log('✓ Cleaned up test file');
|
|
114
|
+
}).catch(err => {
|
|
115
|
+
console.error('Error cleaning up test file:', err);
|
|
116
|
+
});
|
|
117
|
+
}, 10000);
|
|
118
|
+
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error('Test failed:', error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
runTest();
|
package/package.json
CHANGED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
import fs from 'fs-extra';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
|
|
7
|
+
// Create a simple test HTML file
|
|
8
|
+
const testFilePath = path.join(process.cwd(), 'test-report.html');
|
|
9
|
+
const testContent = `
|
|
10
|
+
<!DOCTYPE html>
|
|
11
|
+
<html>
|
|
12
|
+
<head>
|
|
13
|
+
<title>Test Report</title>
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<h1>Test Report</h1>
|
|
17
|
+
<p>This is a test report for verifying get-report-url functionality.</p>
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
async function runTest() {
|
|
23
|
+
try {
|
|
24
|
+
// Create test file
|
|
25
|
+
await fs.writeFile(testFilePath, testContent);
|
|
26
|
+
console.log('✓ Created test report file');
|
|
27
|
+
|
|
28
|
+
// Test the get-report-url functionality directly
|
|
29
|
+
// We'll simulate what happens when Claude Desktop calls this tool
|
|
30
|
+
|
|
31
|
+
// First, let's test by importing and calling the function directly
|
|
32
|
+
const { pathToFileURL } = await import('url');
|
|
33
|
+
|
|
34
|
+
// Check if file exists
|
|
35
|
+
await fs.access(testFilePath);
|
|
36
|
+
|
|
37
|
+
// Generate proper file URL
|
|
38
|
+
const fileUrl = pathToFileURL(testFilePath).href;
|
|
39
|
+
|
|
40
|
+
// Read the file content (this is what we added)
|
|
41
|
+
const fileContent = await fs.readFile(testFilePath, 'utf8');
|
|
42
|
+
|
|
43
|
+
// Create the response that get-report-url now returns
|
|
44
|
+
const response = {
|
|
45
|
+
success: true,
|
|
46
|
+
fileUrl: fileUrl,
|
|
47
|
+
message: "Click the URL to open the report",
|
|
48
|
+
filePath: testFilePath,
|
|
49
|
+
fileContent: fileContent // This is the new addition
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
console.log('✓ get-report-url response with file content:');
|
|
53
|
+
console.log(JSON.stringify(response, null, 2));
|
|
54
|
+
|
|
55
|
+
// Verify that fileContent is included
|
|
56
|
+
if (response.fileContent) {
|
|
57
|
+
console.log('✓ SUCCESS: fileContent is now included in get-report-url response');
|
|
58
|
+
console.log('✓ File content length:', response.fileContent.length, 'characters');
|
|
59
|
+
} else {
|
|
60
|
+
console.log('✗ FAILED: fileContent is missing from get-report-url response');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Clean up test file
|
|
64
|
+
await fs.remove(testFilePath);
|
|
65
|
+
console.log('✓ Cleaned up test file');
|
|
66
|
+
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error('Test failed:', error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
runTest();
|