@vint.tri/report_gen_mcp 1.0.30 โ 1.0.31
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 +25 -7
- package/final-verification-test.js +116 -141
- package/package.json +1 -1
- package/src/index.ts +22 -7
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ const commander_1 = require("commander");
|
|
|
9
9
|
const reportGenerator_1 = require("./utils/reportGenerator");
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
11
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
12
13
|
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
13
14
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
14
15
|
const zod_1 = require("zod");
|
|
@@ -88,7 +89,7 @@ if (process.argv.length === 2) {
|
|
|
88
89
|
// No command specified, run in stdio mode using MCP SDK
|
|
89
90
|
const mcpServer = new mcp_js_1.McpServer({
|
|
90
91
|
name: "report_gen_mcp",
|
|
91
|
-
version: "1.0.
|
|
92
|
+
version: "1.0.31",
|
|
92
93
|
}, {
|
|
93
94
|
// Disable health check to prevent automatic calls
|
|
94
95
|
capabilities: {
|
|
@@ -117,7 +118,7 @@ if (process.argv.length === 2) {
|
|
|
117
118
|
}),
|
|
118
119
|
})).describe("Chart configurations mapped by ID"),
|
|
119
120
|
outputFile: zod_1.z.string().optional().describe("Output HTML file path"),
|
|
120
|
-
tempDirectory: zod_1.z.string().describe("Temporary directory for file storage (
|
|
121
|
+
tempDirectory: zod_1.z.string().optional().describe("Temporary directory for file storage (optional, will use REPORTS_DIR environment variable if set)"),
|
|
121
122
|
},
|
|
122
123
|
}, async (params) => {
|
|
123
124
|
// Handle case where arguments might be sent as a JSON string by Claude desktop
|
|
@@ -133,12 +134,29 @@ if (process.argv.length === 2) {
|
|
|
133
134
|
else if (params.arguments && typeof params.arguments === 'object') {
|
|
134
135
|
processedParams = params.arguments;
|
|
135
136
|
}
|
|
136
|
-
// Check if tempDirectory parameter is provided
|
|
137
|
-
if (!processedParams.tempDirectory) {
|
|
138
|
-
throw new Error('tempDirectory parameter is required. Please provide the directory where reports should be generated.');
|
|
139
|
-
}
|
|
140
137
|
const { document, charts, outputFile = 'report.html', tempDirectory } = processedParams;
|
|
141
|
-
|
|
138
|
+
// Determine the output directory:
|
|
139
|
+
// 1. Use REPORTS_DIR environment variable if set
|
|
140
|
+
// 2. Fall back to tempDirectory parameter if provided
|
|
141
|
+
// 3. Default to system temp directory if neither is available
|
|
142
|
+
let outputDir;
|
|
143
|
+
if (process.env.REPORTS_DIR) {
|
|
144
|
+
outputDir = process.env.REPORTS_DIR;
|
|
145
|
+
// Ensure the reports directory exists
|
|
146
|
+
try {
|
|
147
|
+
fs_extra_1.default.ensureDirSync(outputDir);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
throw new Error(`Cannot create or access the reports directory: ${outputDir}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else if (tempDirectory) {
|
|
154
|
+
outputDir = tempDirectory;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
outputDir = os_1.default.tmpdir();
|
|
158
|
+
}
|
|
159
|
+
const outputPath = path_1.default.resolve(outputDir, outputFile);
|
|
142
160
|
try {
|
|
143
161
|
const result = await (0, reportGenerator_1.generateReport)(document, charts, outputPath);
|
|
144
162
|
// Properly encode the file path for URL
|
|
@@ -1,164 +1,139 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// Final verification test for report_gen_mcp v1.0.23
|
|
4
|
-
// This test verifies that the tempDirectory parameter is properly handled
|
|
5
|
-
|
|
6
3
|
const { spawn } = require('child_process');
|
|
7
4
|
const fs = require('fs');
|
|
8
5
|
const path = require('path');
|
|
9
6
|
|
|
10
|
-
console.log('
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
console.log('=== Final Verification Test ===\n');
|
|
8
|
+
|
|
9
|
+
// Test 1: CLI mode with REPORTS_DIR
|
|
10
|
+
console.log('Test 1: CLI mode with REPORTS_DIR environment variable...');
|
|
11
|
+
const testReportsDir = path.join(__dirname, 'test-reports');
|
|
12
|
+
if (!fs.existsSync(testReportsDir)) {
|
|
13
|
+
fs.mkdirSync(testReportsDir);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const cliTest = spawn('node', [
|
|
17
|
+
'dist/index.js',
|
|
18
|
+
'generate',
|
|
19
|
+
'--document', '# CLI Test Report\n\nThis is a test report with a [[chart:cli]] chart.',
|
|
20
|
+
'--charts', JSON.stringify({
|
|
21
|
+
cli: {
|
|
22
|
+
type: "bar",
|
|
23
|
+
config: {
|
|
24
|
+
labels: ["X", "Y", "Z"],
|
|
25
|
+
datasets: [{
|
|
26
|
+
label: "CLI Data",
|
|
27
|
+
data: [10, 20, 30],
|
|
28
|
+
backgroundColor: ["red", "green", "blue"]
|
|
29
|
+
}]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}),
|
|
33
|
+
'--output', 'cli-test-report.html'
|
|
34
|
+
], {
|
|
35
|
+
env: {
|
|
36
|
+
...process.env,
|
|
37
|
+
REPORTS_DIR: testReportsDir
|
|
38
|
+
}
|
|
17
39
|
});
|
|
18
40
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
testWithTempDir.stdout.on('data', (data) => {
|
|
22
|
-
test1Output += data.toString();
|
|
41
|
+
cliTest.stdout.on('data', (data) => {
|
|
42
|
+
console.log('CLI stdout:', data.toString());
|
|
23
43
|
});
|
|
24
44
|
|
|
25
|
-
|
|
26
|
-
|
|
45
|
+
cliTest.stderr.on('data', (data) => {
|
|
46
|
+
console.log('CLI stderr:', data.toString());
|
|
27
47
|
});
|
|
28
48
|
|
|
29
|
-
|
|
30
|
-
console.log(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
},
|
|
57
|
-
outputFile: "test-report.html",
|
|
58
|
-
tempDirectory: "/tmp"
|
|
49
|
+
cliTest.on('close', (code) => {
|
|
50
|
+
console.log('CLI test exited with code:', code);
|
|
51
|
+
|
|
52
|
+
const expectedReportPath = path.join(testReportsDir, 'cli-test-report.html');
|
|
53
|
+
if (fs.existsSync(expectedReportPath)) {
|
|
54
|
+
console.log('โ
CLI Test PASSED: Report generated in correct directory\n');
|
|
55
|
+
} else {
|
|
56
|
+
console.log('โ CLI Test FAILED: Report not found in expected directory\n');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Clean up
|
|
60
|
+
if (fs.existsSync(testReportsDir)) {
|
|
61
|
+
fs.rmSync(testReportsDir, { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Test 2: CLI mode without REPORTS_DIR (should fail)
|
|
65
|
+
console.log('Test 2: CLI mode without REPORTS_DIR environment variable (should fail)...');
|
|
66
|
+
const cliErrorTest = spawn('node', [
|
|
67
|
+
'dist/index.js',
|
|
68
|
+
'generate',
|
|
69
|
+
'--document', '# Error Test Report',
|
|
70
|
+
'--charts', JSON.stringify({}),
|
|
71
|
+
'--output', 'error-test-report.html'
|
|
72
|
+
], {
|
|
73
|
+
env: {
|
|
74
|
+
...process.env,
|
|
75
|
+
REPORTS_DIR: ''
|
|
59
76
|
}
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
console.log('\n๐ Sending test request with tempDirectory...');
|
|
63
|
-
console.log(JSON.stringify(testRequest, null, 2));
|
|
64
|
-
|
|
65
|
-
const testProcess = spawn('npx', ['@vint.tri/report_gen_mcp@1.0.23'], {
|
|
66
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
67
77
|
});
|
|
68
78
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
testProcess.stdout.on('data', (data) => {
|
|
72
|
-
testOutput += data.toString();
|
|
79
|
+
cliErrorTest.stdout.on('data', (data) => {
|
|
80
|
+
console.log('CLI Error stdout:', data.toString());
|
|
73
81
|
});
|
|
74
82
|
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
cliErrorTest.stderr.on('data', (data) => {
|
|
84
|
+
console.log('CLI Error stderr:', data.toString());
|
|
77
85
|
});
|
|
78
86
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
urlProcess.stdin.write(JSON.stringify(urlRequest));
|
|
121
|
-
urlProcess.stdin.end();
|
|
122
|
-
|
|
123
|
-
urlProcess.on('close', (code) => {
|
|
124
|
-
console.log(`\nโ
URL test completed with code ${code}`);
|
|
125
|
-
console.log('Full output:');
|
|
126
|
-
console.log(urlOutput);
|
|
127
|
-
|
|
128
|
-
try {
|
|
129
|
-
const urlLines = urlOutput.split('\n').filter(line => line.trim());
|
|
130
|
-
const urlLastLine = urlLines[urlLines.length - 1];
|
|
131
|
-
const urlResponse = JSON.parse(urlLastLine);
|
|
132
|
-
|
|
133
|
-
if (urlResponse.success) {
|
|
134
|
-
console.log('๐ SUCCESS: get-report-url works correctly!');
|
|
135
|
-
console.log(`๐ File URL: ${urlResponse.fileUrl}`);
|
|
136
|
-
console.log('\n๐ ALL TESTS PASSED! The fix is working correctly.');
|
|
137
|
-
console.log('๐ Summary:');
|
|
138
|
-
console.log(' - tempDirectory parameter is properly handled');
|
|
139
|
-
console.log(' - Reports are generated successfully');
|
|
140
|
-
console.log(' - File URLs are returned correctly');
|
|
141
|
-
console.log(' - Version 1.0.23 is working as expected');
|
|
142
|
-
} else {
|
|
143
|
-
console.log('โ FAILED: get-report-url did not succeed');
|
|
144
|
-
}
|
|
145
|
-
} catch (e) {
|
|
146
|
-
console.log('โ ERROR: Could not parse URL response');
|
|
147
|
-
console.error(e);
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
} else {
|
|
151
|
-
console.log('โ FAILED: Report generation was not successful');
|
|
152
|
-
console.log(response.message || 'Unknown error');
|
|
153
|
-
}
|
|
154
|
-
} catch (e) {
|
|
155
|
-
console.log('โ ๏ธ WARNING: Could not parse response, but checking for success indicators...');
|
|
156
|
-
if (testOutput.includes('success') && testOutput.includes('filePath')) {
|
|
157
|
-
console.log('๐ SUCCESS: Found success indicators in output!');
|
|
87
|
+
cliErrorTest.on('close', (code) => {
|
|
88
|
+
console.log('CLI error test exited with code:', code);
|
|
89
|
+
|
|
90
|
+
if (code !== 0) {
|
|
91
|
+
console.log('โ
CLI Error Test PASSED: Correctly failed without REPORTS_DIR\n');
|
|
92
|
+
} else {
|
|
93
|
+
console.log('โ CLI Error Test FAILED: Should have failed without REPORTS_DIR\n');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Test 3: Stdio mode (should work without REPORTS_DIR)
|
|
97
|
+
console.log('Test 3: Stdio mode (should work without REPORTS_DIR)...');
|
|
98
|
+
const stdioTest = spawn('node', ['dist/index.js'], {
|
|
99
|
+
env: process.env
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Send a simple MCP request
|
|
103
|
+
const mcpRequest = {
|
|
104
|
+
"jsonrpc": "2.0",
|
|
105
|
+
"id": 1,
|
|
106
|
+
"method": "tools/list",
|
|
107
|
+
"params": {}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
stdioTest.stdin.write(JSON.stringify(mcpRequest) + '\n');
|
|
111
|
+
|
|
112
|
+
let stdioOutput = '';
|
|
113
|
+
stdioTest.stdout.on('data', (data) => {
|
|
114
|
+
stdioOutput += data.toString();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
stdioTest.stderr.on('data', (data) => {
|
|
118
|
+
console.log('Stdio stderr:', data.toString());
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
stdioTest.on('close', (code) => {
|
|
122
|
+
console.log('Stdio test exited with code:', code);
|
|
123
|
+
console.log('Stdio output:', stdioOutput);
|
|
124
|
+
|
|
125
|
+
if (stdioOutput.includes('"tools"') || stdioOutput.includes('MCP server is running')) {
|
|
126
|
+
console.log('โ
Stdio Test PASSED: Stdio mode is working\n');
|
|
158
127
|
} else {
|
|
159
|
-
console.log('โ FAILED:
|
|
160
|
-
console.error(e);
|
|
128
|
+
console.log('โ Stdio Test FAILED: Stdio mode not working correctly\n');
|
|
161
129
|
}
|
|
162
|
-
|
|
130
|
+
|
|
131
|
+
console.log('=== All Tests Completed ===');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Give it a moment then close stdin
|
|
135
|
+
setTimeout(() => {
|
|
136
|
+
stdioTest.stdin.end();
|
|
137
|
+
}, 1000);
|
|
163
138
|
});
|
|
164
139
|
});
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -94,7 +94,7 @@ if (process.argv.length === 2) {
|
|
|
94
94
|
// No command specified, run in stdio mode using MCP SDK
|
|
95
95
|
const mcpServer = new McpServer({
|
|
96
96
|
name: "report_gen_mcp",
|
|
97
|
-
version: "1.0.
|
|
97
|
+
version: "1.0.31",
|
|
98
98
|
}, {
|
|
99
99
|
// Disable health check to prevent automatic calls
|
|
100
100
|
capabilities: {
|
|
@@ -124,7 +124,7 @@ if (process.argv.length === 2) {
|
|
|
124
124
|
}),
|
|
125
125
|
})).describe("Chart configurations mapped by ID"),
|
|
126
126
|
outputFile: z.string().optional().describe("Output HTML file path"),
|
|
127
|
-
tempDirectory: z.string().describe("Temporary directory for file storage (
|
|
127
|
+
tempDirectory: z.string().optional().describe("Temporary directory for file storage (optional, will use REPORTS_DIR environment variable if set)"),
|
|
128
128
|
},
|
|
129
129
|
}, async (params: any) => {
|
|
130
130
|
// Handle case where arguments might be sent as a JSON string by Claude desktop
|
|
@@ -139,13 +139,28 @@ if (process.argv.length === 2) {
|
|
|
139
139
|
processedParams = params.arguments;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
const { document, charts, outputFile = 'report.html', tempDirectory } = processedParams;
|
|
143
|
+
|
|
144
|
+
// Determine the output directory:
|
|
145
|
+
// 1. Use REPORTS_DIR environment variable if set
|
|
146
|
+
// 2. Fall back to tempDirectory parameter if provided
|
|
147
|
+
// 3. Default to system temp directory if neither is available
|
|
148
|
+
let outputDir: string;
|
|
149
|
+
if (process.env.REPORTS_DIR) {
|
|
150
|
+
outputDir = process.env.REPORTS_DIR;
|
|
151
|
+
// Ensure the reports directory exists
|
|
152
|
+
try {
|
|
153
|
+
fs.ensureDirSync(outputDir);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
throw new Error(`Cannot create or access the reports directory: ${outputDir}`);
|
|
156
|
+
}
|
|
157
|
+
} else if (tempDirectory) {
|
|
158
|
+
outputDir = tempDirectory;
|
|
159
|
+
} else {
|
|
160
|
+
outputDir = os.tmpdir();
|
|
145
161
|
}
|
|
146
162
|
|
|
147
|
-
const
|
|
148
|
-
const outputPath = path.resolve(tempDirectory, outputFile);
|
|
163
|
+
const outputPath = path.resolve(outputDir, outputFile);
|
|
149
164
|
|
|
150
165
|
try {
|
|
151
166
|
const result = await generateReport(document, charts, outputPath);
|