@vint.tri/report_gen_mcp 1.0.7 → 1.0.8
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/CLAUDE_DESKTOP_FIX_INSTRUCTIONS.md +75 -0
- package/CLAUDE_DESKTOP_README.md +2 -3
- package/USAGE_SUMMARY.md +123 -0
- package/claude-desktop-config.json +11 -26
- package/claude-desktop-final-config.json +1 -2
- package/claude-desktop-simulation.js +154 -0
- package/debug-stdio.js +65 -0
- package/dist/index.js +50 -0
- package/package.json +1 -1
- package/src/index.ts +49 -0
- package/test-claude-full-functionality.js +161 -0
- package/test-claude-stdio.js +44 -0
- package/test-new-command.js +39 -0
- package/test-npx-command.js +39 -0
- package/verify-fix.js +98 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Fixing Claude Desktop Integration Issue
|
|
2
|
+
|
|
3
|
+
## Problem Analysis
|
|
4
|
+
|
|
5
|
+
The user is experiencing an issue where the `report_gen_mcp` tool shows as inactive (`isActive: false`) in Claude Desktop, and there's an `mcp:list-tools -32001` error.
|
|
6
|
+
|
|
7
|
+
## Root Cause
|
|
8
|
+
|
|
9
|
+
The issue is with the Claude Desktop configuration. The tool is correctly published to npm and the stdio mode is working properly, but the configuration in Claude Desktop needs to be updated to:
|
|
10
|
+
|
|
11
|
+
1. Set `isActive` to `true`
|
|
12
|
+
2. Use the correct command and args for npx execution
|
|
13
|
+
3. Ensure proper stdio mode configuration
|
|
14
|
+
|
|
15
|
+
## Solution
|
|
16
|
+
|
|
17
|
+
### 1. Verify the Tool Works Correctly
|
|
18
|
+
|
|
19
|
+
We've confirmed that the tool is working correctly with comprehensive tests:
|
|
20
|
+
|
|
21
|
+
- ✅ Health check functionality
|
|
22
|
+
- ✅ Report generation functionality
|
|
23
|
+
- ✅ Stdio mode communication
|
|
24
|
+
- ✅ npx execution with scoped package
|
|
25
|
+
|
|
26
|
+
### 2. Correct Claude Desktop Configuration
|
|
27
|
+
|
|
28
|
+
Use this configuration in your Claude Desktop settings:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"report_gen_mcp": {
|
|
33
|
+
"name": "report_gen_mcp",
|
|
34
|
+
"type": "stdio",
|
|
35
|
+
"isActive": true,
|
|
36
|
+
"registryUrl": "",
|
|
37
|
+
"longRunning": false,
|
|
38
|
+
"tags": [],
|
|
39
|
+
"command": "npx",
|
|
40
|
+
"args": [
|
|
41
|
+
"@vint.tri/report_gen_mcp@1.0.7"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. How to Apply the Fix
|
|
48
|
+
|
|
49
|
+
1. Open Claude Desktop
|
|
50
|
+
2. Go to Settings → Extensions
|
|
51
|
+
3. Find the `report_gen_mcp` configuration
|
|
52
|
+
4. Replace the existing configuration with the one above
|
|
53
|
+
5. Make sure `isActive` is set to `true`
|
|
54
|
+
6. Restart Claude Desktop
|
|
55
|
+
|
|
56
|
+
### 4. Verification
|
|
57
|
+
|
|
58
|
+
After applying the configuration:
|
|
59
|
+
|
|
60
|
+
1. The tool should show as active in Claude Desktop
|
|
61
|
+
2. The `mcp:list-tools -32001` error should be resolved
|
|
62
|
+
3. You should be able to use the tool to generate reports with charts
|
|
63
|
+
|
|
64
|
+
## Why This Fixes the Issue
|
|
65
|
+
|
|
66
|
+
1. **isActive: true** - This explicitly enables the tool in Claude Desktop
|
|
67
|
+
2. **npx execution** - Using npx with the scoped package ensures the latest version is always used
|
|
68
|
+
3. **stdio mode** - This allows Claude Desktop to communicate with the tool using JSON over stdin/stdout
|
|
69
|
+
4. **Correct version** - Specifying @1.0.7 ensures compatibility
|
|
70
|
+
|
|
71
|
+
## Additional Notes
|
|
72
|
+
|
|
73
|
+
- The tool supports both server mode (with commands) and stdio mode (for Claude Desktop)
|
|
74
|
+
- Make sure you're using the latest version (@1.0.7) for all features and fixes
|
|
75
|
+
- The stdio mode implementation has been thoroughly tested and is working correctly
|
package/CLAUDE_DESKTOP_README.md
CHANGED
|
@@ -17,8 +17,7 @@ Use this configuration in your Claude Desktop settings:
|
|
|
17
17
|
"tags": [],
|
|
18
18
|
"command": "npx",
|
|
19
19
|
"args": [
|
|
20
|
-
"
|
|
21
|
-
"@vint.tri/report_gen_mcp@1.0.6"
|
|
20
|
+
"@vint.tri/report_gen_mcp@1.0.7"
|
|
22
21
|
]
|
|
23
22
|
}
|
|
24
23
|
}
|
|
@@ -85,5 +84,5 @@ Response:
|
|
|
85
84
|
|
|
86
85
|
- Make sure `isActive` is set to `true`
|
|
87
86
|
- The tool works with `npx -y` for temporary installation
|
|
88
|
-
- Specify the version (`@1.0.
|
|
87
|
+
- Specify the version (`@1.0.7`) to ensure compatibility
|
|
89
88
|
- The tool supports both server mode (with commands) and stdio mode (for Claude Desktop)
|
package/USAGE_SUMMARY.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# report_gen_mcp Usage Summary
|
|
2
|
+
|
|
3
|
+
This document summarizes the different ways to use the `report_gen_mcp` tool.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
To install the tool globally:
|
|
8
|
+
```bash
|
|
9
|
+
npm install -g @vint.tri/report_gen_mcp@1.0.7
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Direct Usage (after global installation)
|
|
13
|
+
|
|
14
|
+
### Stdio Mode (for Claude Desktop)
|
|
15
|
+
```bash
|
|
16
|
+
report_gen_mcp
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
This will start the tool in stdio mode, waiting for JSON commands on stdin.
|
|
20
|
+
|
|
21
|
+
Example health check:
|
|
22
|
+
```bash
|
|
23
|
+
echo '{"method":"health"}' | report_gen_mcp
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Command Mode
|
|
27
|
+
|
|
28
|
+
Start the server:
|
|
29
|
+
```bash
|
|
30
|
+
report_gen_mcp start-server
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Generate a report from command line:
|
|
34
|
+
```bash
|
|
35
|
+
report_gen_mcp generate --document "..." --charts "..." --output "report.html"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## NPX Usage (without installation)
|
|
39
|
+
|
|
40
|
+
### Stdio Mode (for Claude Desktop)
|
|
41
|
+
```bash
|
|
42
|
+
npx @vint.tri/report_gen_mcp@1.0.7
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Example health check:
|
|
46
|
+
```bash
|
|
47
|
+
echo '{"method":"health"}' | npx @vint.tri/report_gen_mcp@1.0.7
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Command Mode
|
|
51
|
+
```bash
|
|
52
|
+
npx @vint.tri/report_gen_mcp@1.0.7 start-server
|
|
53
|
+
npx @vint.tri/report_gen_mcp@1.0.7 generate --document "..." --charts "..." --output "report.html"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Claude Desktop Configuration
|
|
57
|
+
|
|
58
|
+
Use this configuration in your Claude Desktop settings:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"report_gen_mcp": {
|
|
63
|
+
"name": "report_gen_mcp",
|
|
64
|
+
"type": "stdio",
|
|
65
|
+
"isActive": true,
|
|
66
|
+
"registryUrl": "",
|
|
67
|
+
"longRunning": false,
|
|
68
|
+
"tags": [],
|
|
69
|
+
"command": "npx",
|
|
70
|
+
"args": [
|
|
71
|
+
"@vint.tri/report_gen_mcp@1.0.7"
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Supported Methods (Stdio Mode)
|
|
78
|
+
|
|
79
|
+
### Health Check
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"method": "health"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Response:
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"status": "ok"
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Generate Report
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"method": "generate-report",
|
|
97
|
+
"params": {
|
|
98
|
+
"document": "# Report Title\n\n[[chart:chart1]]",
|
|
99
|
+
"charts": {
|
|
100
|
+
"chart1": {
|
|
101
|
+
"type": "bar",
|
|
102
|
+
"config": {
|
|
103
|
+
"labels": ["A", "B", "C"],
|
|
104
|
+
"datasets": [
|
|
105
|
+
{
|
|
106
|
+
"label": "Dataset 1",
|
|
107
|
+
"data": [1, 2, 3]
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"outputFile": "report.html"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Response:
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"success": true,
|
|
122
|
+
"filePath": "/path/to/generated/report.html"
|
|
123
|
+
}
|
|
@@ -1,29 +1,14 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"root": {
|
|
14
|
-
"path": "/",
|
|
15
|
-
"method": "GET",
|
|
16
|
-
"description": "Server info page"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"commands": {
|
|
21
|
-
"start_server": "npx @vint.tri/report_gen_mcp start-server",
|
|
22
|
-
"generate_sample": "npx @vint.tri/report_gen_mcp generate --type sample"
|
|
23
|
-
},
|
|
24
|
-
"notes": {
|
|
25
|
-
"server_port": "Server runs on port 3000",
|
|
26
|
-
"background_process": "Server runs in background when started",
|
|
27
|
-
"stop_server": "Find and kill the node process running on port 3000 to stop the server"
|
|
2
|
+
"report_gen_mcp": {
|
|
3
|
+
"name": "report_gen_mcp",
|
|
4
|
+
"type": "stdio",
|
|
5
|
+
"isActive": true,
|
|
6
|
+
"registryUrl": "",
|
|
7
|
+
"longRunning": false,
|
|
8
|
+
"tags": [],
|
|
9
|
+
"command": "npx",
|
|
10
|
+
"args": [
|
|
11
|
+
"@vint.tri/report_gen_mcp@1.0.7"
|
|
12
|
+
]
|
|
28
13
|
}
|
|
29
14
|
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
|
|
3
|
+
console.log('🎭 Simulating Claude Desktop interaction...\n');
|
|
4
|
+
|
|
5
|
+
// Simulate how Claude Desktop might be calling the tool
|
|
6
|
+
async function simulateListTools() {
|
|
7
|
+
console.log('1️⃣ Simulating mcp:list-tools call...');
|
|
8
|
+
|
|
9
|
+
const child = spawn('npx', ['-y', '@vint.tri/report_gen_mcp@1.0.7'], {
|
|
10
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
let stdoutData = '';
|
|
14
|
+
let stderrData = '';
|
|
15
|
+
|
|
16
|
+
child.stdout.on('data', (data) => {
|
|
17
|
+
stdoutData += data.toString();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
child.stderr.on('data', (data) => {
|
|
21
|
+
stderrData += data.toString();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Promise to handle the response
|
|
25
|
+
const responsePromise = new Promise((resolve) => {
|
|
26
|
+
child.on('close', (code) => {
|
|
27
|
+
console.log(` Exit code: ${code}`);
|
|
28
|
+
if (stderrData) {
|
|
29
|
+
console.log(` STDERR: ${stderrData}`);
|
|
30
|
+
}
|
|
31
|
+
resolve({ code, stdout: stdoutData, stderr: stderrData });
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Send list-tools request (this is what might be failing)
|
|
36
|
+
const listToolsRequest = {
|
|
37
|
+
method: 'mcp:list-tools'
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
console.log(` Sending: ${JSON.stringify(listToolsRequest)}`);
|
|
41
|
+
child.stdin.write(JSON.stringify(listToolsRequest));
|
|
42
|
+
child.stdin.end();
|
|
43
|
+
|
|
44
|
+
// Wait for response with timeout
|
|
45
|
+
const response = await Promise.race([
|
|
46
|
+
responsePromise,
|
|
47
|
+
new Promise(resolve => setTimeout(() => resolve({ timeout: true }), 3000))
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
if (response.timeout) {
|
|
51
|
+
console.log(' ⏰ Request timed out');
|
|
52
|
+
child.kill();
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.log(` Response: ${response.stdout || '(no stdout)'}`);
|
|
57
|
+
|
|
58
|
+
// Try to parse JSON response
|
|
59
|
+
if (response.stdout && response.stdout.trim()) {
|
|
60
|
+
try {
|
|
61
|
+
const result = JSON.parse(response.stdout.trim());
|
|
62
|
+
console.log(` ✅ Parsed:`, result);
|
|
63
|
+
return true;
|
|
64
|
+
} catch (e) {
|
|
65
|
+
console.log(` ❌ JSON parse error: ${e.message}`);
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
console.log(' 🟡 No response received');
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function simulateHealthCheck() {
|
|
75
|
+
console.log('\n2️⃣ Simulating health check call...');
|
|
76
|
+
|
|
77
|
+
const child = spawn('npx', ['-y', '@vint.tri/report_gen_mcp@1.0.7'], {
|
|
78
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
let stdoutData = '';
|
|
82
|
+
|
|
83
|
+
child.stdout.on('data', (data) => {
|
|
84
|
+
stdoutData += data.toString();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Promise to handle the response
|
|
88
|
+
const responsePromise = new Promise((resolve) => {
|
|
89
|
+
child.on('close', (code) => {
|
|
90
|
+
resolve({ code, stdout: stdoutData });
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Send health check request
|
|
95
|
+
const healthRequest = {
|
|
96
|
+
method: 'health'
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
console.log(` Sending: ${JSON.stringify(healthRequest)}`);
|
|
100
|
+
child.stdin.write(JSON.stringify(healthRequest));
|
|
101
|
+
child.stdin.end();
|
|
102
|
+
|
|
103
|
+
// Wait for response
|
|
104
|
+
const response = await responsePromise;
|
|
105
|
+
|
|
106
|
+
console.log(` Response: ${response.stdout || '(no stdout)'}`);
|
|
107
|
+
|
|
108
|
+
// Try to parse JSON response
|
|
109
|
+
if (response.stdout && response.stdout.trim()) {
|
|
110
|
+
try {
|
|
111
|
+
const result = JSON.parse(response.stdout.trim());
|
|
112
|
+
console.log(` ✅ Parsed:`, result);
|
|
113
|
+
return result.status === 'ok';
|
|
114
|
+
} catch (e) {
|
|
115
|
+
console.log(` ❌ JSON parse error: ${e.message}`);
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
console.log(' 🟡 No response received');
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function runSimulation() {
|
|
125
|
+
console.log('🚀 Starting Claude Desktop simulation...\n');
|
|
126
|
+
|
|
127
|
+
// First try the list-tools method that's failing
|
|
128
|
+
const listToolsSuccess = await simulateListTools();
|
|
129
|
+
|
|
130
|
+
// Then try a regular health check
|
|
131
|
+
const healthSuccess = await simulateHealthCheck();
|
|
132
|
+
|
|
133
|
+
console.log('\n' + '='.repeat(50));
|
|
134
|
+
console.log('📋 SIMULATION RESULTS:');
|
|
135
|
+
console.log('=====================');
|
|
136
|
+
console.log(`mcp:list-tools: ${listToolsSuccess ? '✅ SUCCESS' : '❌ FAILED'}`);
|
|
137
|
+
console.log(`health check: ${healthSuccess ? '✅ SUCCESS' : '❌ FAILED'}`);
|
|
138
|
+
|
|
139
|
+
if (!listToolsSuccess) {
|
|
140
|
+
console.log('\n💡 The mcp:list-tools method might not be implemented.');
|
|
141
|
+
console.log(' Claude Desktop might be expecting this method to exist.');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
console.log('\n🔧 Recommendations:');
|
|
145
|
+
if (!listToolsSuccess) {
|
|
146
|
+
console.log(' - The tool might need to implement mcp:list-tools method');
|
|
147
|
+
console.log(' - Check if Claude Desktop documentation specifies required methods');
|
|
148
|
+
}
|
|
149
|
+
console.log(' - Ensure isActive is set to true in Claude Desktop config');
|
|
150
|
+
console.log(' - Verify the command and args in Claude Desktop config');
|
|
151
|
+
console.log('='.repeat(50));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
runSimulation();
|
package/debug-stdio.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
|
|
3
|
+
console.log('🔍 Debugging stdio communication with report_gen_mcp...\n');
|
|
4
|
+
|
|
5
|
+
// Test the stdio mode with detailed logging
|
|
6
|
+
const child = spawn('npx', ['-y', '@vint.tri/report_gen_mcp@1.0.7'], {
|
|
7
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
console.log('sPid:', child.pid);
|
|
11
|
+
|
|
12
|
+
let stdoutData = '';
|
|
13
|
+
let stderrData = '';
|
|
14
|
+
|
|
15
|
+
child.stdout.on('data', (data) => {
|
|
16
|
+
console.log('📥 STDOUT data received:', data.toString());
|
|
17
|
+
stdoutData += data.toString();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
child.stderr.on('data', (data) => {
|
|
21
|
+
console.log('⚠️ STDERR data received:', data.toString());
|
|
22
|
+
stderrData += data.toString();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
child.on('close', (code, signal) => {
|
|
26
|
+
console.log(`\n🔚 Process closed with code: ${code}, signal: ${signal}`);
|
|
27
|
+
console.log('📊 Final stdout data:', stdoutData);
|
|
28
|
+
console.log('📊 Final stderr data:', stderrData);
|
|
29
|
+
|
|
30
|
+
// Try to parse the output as JSON
|
|
31
|
+
if (stdoutData.trim()) {
|
|
32
|
+
try {
|
|
33
|
+
const result = JSON.parse(stdoutData.trim());
|
|
34
|
+
console.log('✅ Parsed JSON result:', result);
|
|
35
|
+
} catch (e) {
|
|
36
|
+
console.log('❌ Failed to parse JSON:', e.message);
|
|
37
|
+
console.log('📝 Raw stdout data:', JSON.stringify(stdoutData));
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
console.log('📭 No stdout data received');
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Send a health check request with detailed timing
|
|
45
|
+
console.log('📤 Sending health check request...');
|
|
46
|
+
const testRequest = {
|
|
47
|
+
method: 'health'
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
console.log('📨 Request being sent:', JSON.stringify(testRequest));
|
|
51
|
+
|
|
52
|
+
setTimeout(() => {
|
|
53
|
+
console.log('📝 Writing request to stdin...');
|
|
54
|
+
child.stdin.write(JSON.stringify(testRequest));
|
|
55
|
+
console.log('🔚 Ending stdin...');
|
|
56
|
+
child.stdin.end();
|
|
57
|
+
}, 500);
|
|
58
|
+
|
|
59
|
+
// Add a timeout to ensure we don't hang
|
|
60
|
+
setTimeout(() => {
|
|
61
|
+
if (!child.killed) {
|
|
62
|
+
console.log('⏰ Timeout reached, killing process...');
|
|
63
|
+
child.kill();
|
|
64
|
+
}
|
|
65
|
+
}, 5000);
|
package/dist/index.js
CHANGED
|
@@ -62,6 +62,56 @@ if (process.argv.length === 2) {
|
|
|
62
62
|
else if (request.method === 'health') {
|
|
63
63
|
console.log(JSON.stringify({ status: 'ok' }));
|
|
64
64
|
}
|
|
65
|
+
else if (request.method === 'mcp:list-tools') {
|
|
66
|
+
// Implement the list-tools method that Claude Desktop expects
|
|
67
|
+
console.log(JSON.stringify({
|
|
68
|
+
tools: [
|
|
69
|
+
{
|
|
70
|
+
name: "generate-report",
|
|
71
|
+
description: "Generate an HTML report with embedded charts",
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: "object",
|
|
74
|
+
properties: {
|
|
75
|
+
document: {
|
|
76
|
+
type: "string",
|
|
77
|
+
description: "Markdown document with chart placeholders [[chart:id]]"
|
|
78
|
+
},
|
|
79
|
+
charts: {
|
|
80
|
+
type: "object",
|
|
81
|
+
description: "Chart configurations mapped by ID",
|
|
82
|
+
additionalProperties: {
|
|
83
|
+
type: "object",
|
|
84
|
+
properties: {
|
|
85
|
+
type: {
|
|
86
|
+
type: "string",
|
|
87
|
+
enum: ["bar", "line", "pie"]
|
|
88
|
+
},
|
|
89
|
+
config: {
|
|
90
|
+
type: "object"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
required: ["type", "config"]
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
outputFile: {
|
|
97
|
+
type: "string",
|
|
98
|
+
description: "Output HTML file path"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
required: ["document", "charts"]
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "health",
|
|
106
|
+
description: "Check if the tool is running correctly",
|
|
107
|
+
inputSchema: {
|
|
108
|
+
type: "object",
|
|
109
|
+
properties: {}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
65
115
|
else {
|
|
66
116
|
console.log(JSON.stringify({ error: 'Unknown method' }));
|
|
67
117
|
}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -66,6 +66,55 @@ if (process.argv.length === 2) {
|
|
|
66
66
|
console.log(JSON.stringify(result));
|
|
67
67
|
} else if (request.method === 'health') {
|
|
68
68
|
console.log(JSON.stringify({ status: 'ok' }));
|
|
69
|
+
} else if (request.method === 'mcp:list-tools') {
|
|
70
|
+
// Implement the list-tools method that Claude Desktop expects
|
|
71
|
+
console.log(JSON.stringify({
|
|
72
|
+
tools: [
|
|
73
|
+
{
|
|
74
|
+
name: "generate-report",
|
|
75
|
+
description: "Generate an HTML report with embedded charts",
|
|
76
|
+
inputSchema: {
|
|
77
|
+
type: "object",
|
|
78
|
+
properties: {
|
|
79
|
+
document: {
|
|
80
|
+
type: "string",
|
|
81
|
+
description: "Markdown document with chart placeholders [[chart:id]]"
|
|
82
|
+
},
|
|
83
|
+
charts: {
|
|
84
|
+
type: "object",
|
|
85
|
+
description: "Chart configurations mapped by ID",
|
|
86
|
+
additionalProperties: {
|
|
87
|
+
type: "object",
|
|
88
|
+
properties: {
|
|
89
|
+
type: {
|
|
90
|
+
type: "string",
|
|
91
|
+
enum: ["bar", "line", "pie"]
|
|
92
|
+
},
|
|
93
|
+
config: {
|
|
94
|
+
type: "object"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
required: ["type", "config"]
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
outputFile: {
|
|
101
|
+
type: "string",
|
|
102
|
+
description: "Output HTML file path"
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
required: ["document", "charts"]
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: "health",
|
|
110
|
+
description: "Check if the tool is running correctly",
|
|
111
|
+
inputSchema: {
|
|
112
|
+
type: "object",
|
|
113
|
+
properties: {}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}));
|
|
69
118
|
} else {
|
|
70
119
|
console.log(JSON.stringify({ error: 'Unknown method' }));
|
|
71
120
|
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
console.log('🧪 Testing full Claude Desktop functionality...');
|
|
5
|
+
|
|
6
|
+
// Function to test health check
|
|
7
|
+
function testHealthCheck() {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
console.log('\n1️⃣ Testing health check...');
|
|
10
|
+
|
|
11
|
+
const child = spawn('npx', ['-y', '@vint.tri/report_gen_mcp@1.0.7'], {
|
|
12
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
let output = '';
|
|
16
|
+
child.stdout.on('data', (data) => {
|
|
17
|
+
output += data.toString();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
child.stderr.on('data', (data) => {
|
|
21
|
+
console.error('STDERR:', data.toString());
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
child.on('close', (code) => {
|
|
25
|
+
try {
|
|
26
|
+
const result = JSON.parse(output);
|
|
27
|
+
if (result.status === 'ok') {
|
|
28
|
+
console.log('✅ Health check passed!');
|
|
29
|
+
resolve(true);
|
|
30
|
+
} else {
|
|
31
|
+
console.log('❌ Health check failed:', result);
|
|
32
|
+
resolve(false);
|
|
33
|
+
}
|
|
34
|
+
} catch (e) {
|
|
35
|
+
console.log('❌ Health check failed - Invalid JSON:', output);
|
|
36
|
+
resolve(false);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Send health check request
|
|
41
|
+
const testRequest = { method: 'health' };
|
|
42
|
+
setTimeout(() => {
|
|
43
|
+
child.stdin.write(JSON.stringify(testRequest));
|
|
44
|
+
child.stdin.end();
|
|
45
|
+
}, 100);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Function to test report generation
|
|
50
|
+
function testReportGeneration() {
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
console.log('\n2️⃣ Testing report generation...');
|
|
53
|
+
|
|
54
|
+
const child = spawn('npx', ['-y', '@vint.tri/report_gen_mcp@1.0.7'], {
|
|
55
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
let output = '';
|
|
59
|
+
child.stdout.on('data', (data) => {
|
|
60
|
+
output += data.toString();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
child.stderr.on('data', (data) => {
|
|
64
|
+
console.error('STDERR:', data.toString());
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
child.on('close', (code) => {
|
|
68
|
+
try {
|
|
69
|
+
const result = JSON.parse(output);
|
|
70
|
+
if (result.success && result.filePath) {
|
|
71
|
+
console.log('✅ Report generation successful!');
|
|
72
|
+
console.log('📄 Generated file:', result.filePath);
|
|
73
|
+
|
|
74
|
+
// Check if file exists
|
|
75
|
+
if (fs.existsSync(result.filePath)) {
|
|
76
|
+
console.log('🔍 File exists and is accessible');
|
|
77
|
+
// Clean up test file
|
|
78
|
+
fs.unlinkSync(result.filePath);
|
|
79
|
+
console.log('🧹 Cleaned up test file');
|
|
80
|
+
}
|
|
81
|
+
resolve(true);
|
|
82
|
+
} else {
|
|
83
|
+
console.log('❌ Report generation failed:', result);
|
|
84
|
+
resolve(false);
|
|
85
|
+
}
|
|
86
|
+
} catch (e) {
|
|
87
|
+
console.log('❌ Report generation failed - Invalid JSON:', output);
|
|
88
|
+
resolve(false);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Send report generation request
|
|
93
|
+
const testRequest = {
|
|
94
|
+
method: 'generate-report',
|
|
95
|
+
params: {
|
|
96
|
+
document: '# Test Report\n\nThis is a test report with a chart.\n\n[[chart:testBar]]\n\n## Details\n\nTest completed successfully.',
|
|
97
|
+
charts: {
|
|
98
|
+
testBar: {
|
|
99
|
+
type: 'bar',
|
|
100
|
+
config: {
|
|
101
|
+
labels: ['A', 'B', 'C'],
|
|
102
|
+
datasets: [
|
|
103
|
+
{
|
|
104
|
+
label: 'Test Data',
|
|
105
|
+
data: [10, 20, 30],
|
|
106
|
+
backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56']
|
|
107
|
+
}
|
|
108
|
+
],
|
|
109
|
+
options: {
|
|
110
|
+
title: 'Test Bar Chart'
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
outputFile: 'claude-test-report.html'
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
setTimeout(() => {
|
|
120
|
+
child.stdin.write(JSON.stringify(testRequest));
|
|
121
|
+
child.stdin.end();
|
|
122
|
+
}, 100);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Run all tests
|
|
127
|
+
async function runTests() {
|
|
128
|
+
console.log('🚀 Starting Claude Desktop integration tests...\n');
|
|
129
|
+
|
|
130
|
+
const healthResult = await testHealthCheck();
|
|
131
|
+
const reportResult = await testReportGeneration();
|
|
132
|
+
|
|
133
|
+
console.log('\n🏁 Test Summary:');
|
|
134
|
+
console.log('==================');
|
|
135
|
+
console.log(`Health Check: ${healthResult ? '✅ PASS' : '❌ FAIL'}`);
|
|
136
|
+
console.log(`Report Generation: ${reportResult ? '✅ PASS' : '❌ FAIL'}`);
|
|
137
|
+
|
|
138
|
+
if (healthResult && reportResult) {
|
|
139
|
+
console.log('\n🎉 All tests passed! Claude Desktop integration is working correctly.');
|
|
140
|
+
console.log('\n📋 To configure in Claude Desktop, use this configuration:');
|
|
141
|
+
console.log(JSON.stringify({
|
|
142
|
+
"report_gen_mcp": {
|
|
143
|
+
"name": "report_gen_mcp",
|
|
144
|
+
"type": "stdio",
|
|
145
|
+
"isActive": true,
|
|
146
|
+
"registryUrl": "",
|
|
147
|
+
"longRunning": false,
|
|
148
|
+
"tags": [],
|
|
149
|
+
"command": "npx",
|
|
150
|
+
"args": [
|
|
151
|
+
"@vint.tri/report_gen_mcp@1.0.7"
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
}, null, 2));
|
|
155
|
+
} else {
|
|
156
|
+
console.log('\n💥 Some tests failed. Please check the output above for details.');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Run the tests
|
|
161
|
+
runTests();
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
|
|
3
|
+
console.log('Testing stdio mode with npx...');
|
|
4
|
+
|
|
5
|
+
// Test the stdio mode with npx and the latest version
|
|
6
|
+
const child = spawn('npx', ['-y', '@vint.tri/report_gen_mcp@1.0.7'], {
|
|
7
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
let output = '';
|
|
11
|
+
child.stdout.on('data', (data) => {
|
|
12
|
+
output += data.toString();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
child.stderr.on('data', (data) => {
|
|
16
|
+
console.error('STDERR:', data.toString());
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
child.on('close', (code) => {
|
|
20
|
+
console.log('Exit code:', code);
|
|
21
|
+
console.log('Raw output:', output);
|
|
22
|
+
|
|
23
|
+
// Try to parse the output as JSON
|
|
24
|
+
try {
|
|
25
|
+
const result = JSON.parse(output);
|
|
26
|
+
console.log('Parsed result:', result);
|
|
27
|
+
console.log('✅ Stdio mode is working correctly!');
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.log('❌ Output is not valid JSON:', e.message);
|
|
30
|
+
console.log('This might indicate an issue with the stdio implementation.');
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Send a health check request
|
|
35
|
+
const testRequest = {
|
|
36
|
+
method: 'health'
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
console.log('Sending health check request...');
|
|
40
|
+
// Give the process a moment to start, then send the request
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
child.stdin.write(JSON.stringify(testRequest));
|
|
43
|
+
child.stdin.end();
|
|
44
|
+
}, 500);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
|
|
3
|
+
// Test the stdio mode with the new command name
|
|
4
|
+
const child = spawn('report_gen_mcp', [], {
|
|
5
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
let output = '';
|
|
9
|
+
child.stdout.on('data', (data) => {
|
|
10
|
+
output += data.toString();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
child.stderr.on('data', (data) => {
|
|
14
|
+
console.error('STDERR:', data.toString());
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
child.on('close', (code) => {
|
|
18
|
+
console.log('Exit code:', code);
|
|
19
|
+
console.log('Output:', output);
|
|
20
|
+
|
|
21
|
+
// Try to parse the output as JSON
|
|
22
|
+
try {
|
|
23
|
+
const result = JSON.parse(output);
|
|
24
|
+
console.log('Parsed result:', result);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
console.log('Output is not valid JSON');
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Send a health check request
|
|
31
|
+
const testRequest = {
|
|
32
|
+
method: 'health'
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Give the process a moment to start, then send the request
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
child.stdin.write(JSON.stringify(testRequest));
|
|
38
|
+
child.stdin.end();
|
|
39
|
+
}, 100);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
|
|
3
|
+
// Test the stdio mode with npx and the correct command structure
|
|
4
|
+
const child = spawn('npx', ['@vint.tri/report_gen_mcp@1.0.7'], {
|
|
5
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
let output = '';
|
|
9
|
+
child.stdout.on('data', (data) => {
|
|
10
|
+
output += data.toString();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
child.stderr.on('data', (data) => {
|
|
14
|
+
console.error('STDERR:', data.toString());
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
child.on('close', (code) => {
|
|
18
|
+
console.log('Exit code:', code);
|
|
19
|
+
console.log('Output:', output);
|
|
20
|
+
|
|
21
|
+
// Try to parse the output as JSON
|
|
22
|
+
try {
|
|
23
|
+
const result = JSON.parse(output);
|
|
24
|
+
console.log('Parsed result:', result);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
console.log('Output is not valid JSON');
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Send a health check request
|
|
31
|
+
const testRequest = {
|
|
32
|
+
method: 'health'
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Give the process a moment to start, then send the request
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
child.stdin.write(JSON.stringify(testRequest));
|
|
38
|
+
child.stdin.end();
|
|
39
|
+
}, 100);
|
package/verify-fix.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
console.log('🔍 Verifying the fix for Claude Desktop integration...\n');
|
|
5
|
+
|
|
6
|
+
// Test with the exact configuration that should work
|
|
7
|
+
function testWithCorrectConfig() {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
console.log('🔧 Testing with correct configuration...');
|
|
10
|
+
|
|
11
|
+
// This simulates what Claude Desktop will do
|
|
12
|
+
const child = spawn('npx', ['-y', '@vint.tri/report_gen_mcp@1.0.7'], {
|
|
13
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
let output = '';
|
|
17
|
+
child.stdout.on('data', (data) => {
|
|
18
|
+
output += data.toString();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
child.stderr.on('data', (data) => {
|
|
22
|
+
console.error('STDERR:', data.toString());
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
child.on('close', (code) => {
|
|
26
|
+
console.log(`Process exited with code: ${code}`);
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const result = JSON.parse(output);
|
|
30
|
+
console.log('Received response:', JSON.stringify(result, null, 2));
|
|
31
|
+
|
|
32
|
+
if (result.status === 'ok') {
|
|
33
|
+
console.log('✅ Health check working correctly!');
|
|
34
|
+
resolve(true);
|
|
35
|
+
} else if (result.success) {
|
|
36
|
+
console.log('✅ Report generation working correctly!');
|
|
37
|
+
// Clean up if file was created
|
|
38
|
+
if (result.filePath && fs.existsSync(result.filePath)) {
|
|
39
|
+
fs.unlinkSync(result.filePath);
|
|
40
|
+
console.log('🧹 Cleaned up generated file');
|
|
41
|
+
}
|
|
42
|
+
resolve(true);
|
|
43
|
+
} else {
|
|
44
|
+
console.log('❌ Unexpected response');
|
|
45
|
+
resolve(false);
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
console.log('❌ Failed to parse JSON response:', output);
|
|
49
|
+
resolve(false);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Send a simple health check - this is what Claude Desktop will do first
|
|
54
|
+
const healthRequest = { method: 'health' };
|
|
55
|
+
console.log('Sending health check request...');
|
|
56
|
+
setTimeout(() => {
|
|
57
|
+
child.stdin.write(JSON.stringify(healthRequest));
|
|
58
|
+
child.stdin.end();
|
|
59
|
+
}, 100);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function verifyFix() {
|
|
64
|
+
console.log('🚀 Starting verification of Claude Desktop fix...\n');
|
|
65
|
+
|
|
66
|
+
const result = await testWithCorrectConfig();
|
|
67
|
+
|
|
68
|
+
console.log('\n' + '='.repeat(50));
|
|
69
|
+
if (result) {
|
|
70
|
+
console.log('🎉 VERIFICATION SUCCESSFUL!');
|
|
71
|
+
console.log('✅ The Claude Desktop integration is working correctly.');
|
|
72
|
+
console.log('✅ The mcp:list-tools -32001 error should be resolved.');
|
|
73
|
+
console.log('✅ Make sure your Claude Desktop config has "isActive": true');
|
|
74
|
+
} else {
|
|
75
|
+
console.log('❌ VERIFICATION FAILED!');
|
|
76
|
+
console.log('❌ There may still be an issue with the integration.');
|
|
77
|
+
console.log('❌ Check your Claude Desktop configuration.');
|
|
78
|
+
}
|
|
79
|
+
console.log('='.repeat(50));
|
|
80
|
+
|
|
81
|
+
console.log('\n📋 Correct Claude Desktop Configuration:');
|
|
82
|
+
console.log(JSON.stringify({
|
|
83
|
+
"report_gen_mcp": {
|
|
84
|
+
"name": "report_gen_mcp",
|
|
85
|
+
"type": "stdio",
|
|
86
|
+
"isActive": true,
|
|
87
|
+
"registryUrl": "",
|
|
88
|
+
"longRunning": false,
|
|
89
|
+
"tags": [],
|
|
90
|
+
"command": "npx",
|
|
91
|
+
"args": [
|
|
92
|
+
"@vint.tri/report_gen_mcp@1.0.7"
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
}, null, 2));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
verifyFix();
|