@nataliapc/mcp-openmsx 1.0.0 → 1.0.2
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/README.md +75 -59
- package/dist/openmsx.js +6 -4
- package/dist/server.js +14 -11
- package/dist/utils.js +31 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -62,49 +62,19 @@ The MCP server translates high-level commands from your Copilot AI into `TCL` co
|
|
|
62
62
|
- `screen_shot`: Capture emulator screen: _`as_image`, `to_file`_.
|
|
63
63
|
- `screen_dump`: Export screen data as BASIC BSAVE.
|
|
64
64
|
|
|
65
|
-
## 🚀 Quick Start
|
|
66
|
-
|
|
67
|
-
### Manual installation
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
npm install -g @nataliapc/mcp-openmsx
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### Configuration
|
|
74
|
-
|
|
75
|
-
Set optional environment variables to customize the server:
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
export OPENMSX_EXECUTABLE="openmsx"
|
|
79
|
-
export OPENMSX_SHARE_DIR="/usr/share/openmsx"
|
|
80
|
-
export OPENMSX_SCREENSHOT_DIR="/my_project/screenshots"
|
|
81
|
-
export OPENMSX_SCREENDUMP_DIR="/my_project/screendumps"
|
|
82
|
-
export MCP_HTTP_PORT=3000
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Manuel usage
|
|
86
|
-
|
|
87
|
-
#### As MCP Server (stdio)
|
|
88
65
|
|
|
89
|
-
|
|
90
|
-
mcp-openmsx
|
|
91
|
-
```
|
|
66
|
+
## 🚀 Quick Start
|
|
92
67
|
|
|
93
|
-
|
|
68
|
+
### 🟢 Basic Usage with VSCode
|
|
94
69
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
# or
|
|
98
|
-
mcp-openmsx http
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### Basic Usage with Claude Desktop
|
|
70
|
+
* Install [Github Copilot extension](https://code.visualstudio.com/docs/copilot/overview)
|
|
71
|
+
* Add to your workspace a file `.vscode/mcp.json` with:
|
|
102
72
|
|
|
103
|
-
|
|
73
|
+
### STDIO mode (recommended)
|
|
104
74
|
|
|
105
75
|
```json
|
|
106
76
|
{
|
|
107
|
-
"
|
|
77
|
+
"servers": {
|
|
108
78
|
"mcp-openmsx": {
|
|
109
79
|
"command": "npx",
|
|
110
80
|
"args": ["@nataliapc/mcp-openmsx"],
|
|
@@ -115,44 +85,87 @@ Add to your `claude_desktop_config.json`:
|
|
|
115
85
|
}
|
|
116
86
|
}
|
|
117
87
|
```
|
|
88
|
+
**Note:** Environment variables are optional.
|
|
118
89
|
|
|
119
|
-
###
|
|
120
|
-
|
|
121
|
-
* Install [Github Copilot extension](https://code.visualstudio.com/docs/copilot/overview)
|
|
122
|
-
* Add to your workspace a file `.vscode/mcp.json` with:
|
|
123
|
-
|
|
124
|
-
#### stdio mode
|
|
90
|
+
### Streamed HTTP mode (more advanced)
|
|
125
91
|
|
|
126
92
|
```json
|
|
127
93
|
{
|
|
128
94
|
"servers": {
|
|
129
95
|
"mcp-openmsx": {
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
"
|
|
133
|
-
"OPENMSX_SHARE_DIR": "/usr/share/openmsx"
|
|
134
|
-
}
|
|
96
|
+
"type": "http",
|
|
97
|
+
"url": "http://localhost:3000/mcp",
|
|
98
|
+
"headers": { }
|
|
135
99
|
}
|
|
136
100
|
}
|
|
137
101
|
}
|
|
138
102
|
```
|
|
139
|
-
**Note:** Environment variables are optional.
|
|
140
103
|
|
|
141
|
-
|
|
104
|
+
**Note:** The MCP HTTP Server must be running standalone in the same computer or in another (`make run_http`).
|
|
105
|
+
|
|
106
|
+
### 🟢 Basic Usage with Claude Desktop
|
|
107
|
+
|
|
108
|
+
Add to your `claude_desktop_config.json`:
|
|
142
109
|
|
|
143
110
|
```json
|
|
144
111
|
{
|
|
145
|
-
"
|
|
112
|
+
"mcpServers": {
|
|
146
113
|
"mcp-openmsx": {
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
"
|
|
114
|
+
"command": "npx",
|
|
115
|
+
"args": ["@nataliapc/mcp-openmsx"],
|
|
116
|
+
"env": {
|
|
117
|
+
"OPENMSX_SHARE_DIR": "/usr/share/openmsx"
|
|
118
|
+
}
|
|
150
119
|
}
|
|
151
120
|
}
|
|
152
121
|
}
|
|
153
122
|
```
|
|
154
123
|
|
|
155
|
-
|
|
124
|
+
### 🟢 Environment Variables
|
|
125
|
+
|
|
126
|
+
| Variable | Description | Default Value | Example |
|
|
127
|
+
|----------|-------------|---------------|---------|
|
|
128
|
+
| `OPENMSX_EXECUTABLE` | Path or command to the openMSX executable | `openmsx` | `/usr/local/bin/openmsx` |
|
|
129
|
+
| `OPENMSX_SHARE_DIR` | Directory containing openMSX data files (machines, extensions, etc.) | System dependent | `/home/myuser/.openmsx/share` |
|
|
130
|
+
| `OPENMSX_SCREENSHOT_DIR` | Directory where screenshots will be saved | Current working directory | `/myproject/screenshots` |
|
|
131
|
+
| `OPENMSX_SCREENDUMP_DIR` | Directory where screen dumps will be saved | Current working directory | `/myproject/screendumps` |
|
|
132
|
+
| `MCP_TRANSPORT` | Transport mode (`stdio` or `http`) | `stdio` | `http` |
|
|
133
|
+
| `MCP_HTTP_PORT` | Port number for HTTP transport mode | `3000` | `8080` |
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
## 🧑💻 Advanced Manual Usage
|
|
137
|
+
|
|
138
|
+
### Manual installation
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npm install -g @nataliapc/mcp-openmsx
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Manual set of Environment Variables
|
|
145
|
+
|
|
146
|
+
Set optional environment variables to customize the server:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
export OPENMSX_EXECUTABLE="openmsx"
|
|
150
|
+
export OPENMSX_SHARE_DIR="/usr/share/openmsx"
|
|
151
|
+
export OPENMSX_SCREENSHOT_DIR="/my_project/screenshots"
|
|
152
|
+
export OPENMSX_SCREENDUMP_DIR="/my_project/screendumps"
|
|
153
|
+
export MCP_HTTP_PORT=3000
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### As MCP Server (stdio)
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
mcp-openmsx
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### As HTTP Server
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
MCP_TRANSPORT=http mcp-openmsx
|
|
166
|
+
# or
|
|
167
|
+
mcp-openmsx http
|
|
168
|
+
```
|
|
156
169
|
|
|
157
170
|
|
|
158
171
|
## 💡 Development
|
|
@@ -178,16 +191,19 @@ npm run build
|
|
|
178
191
|
npm run dev
|
|
179
192
|
```
|
|
180
193
|
|
|
181
|
-
|
|
194
|
+
|
|
195
|
+
## 🪪 License
|
|
182
196
|
|
|
183
197
|
GPL2 License - see [LICENSE](LICENSE) file for details.
|
|
184
198
|
|
|
185
|
-
## Contributing
|
|
186
199
|
|
|
187
|
-
|
|
200
|
+
## 🆘 Support
|
|
188
201
|
|
|
189
|
-
|
|
202
|
+
If you need help, or have questions or suggestions, please open an issue on the [GitHub Issues](https://github.com/nataliapc/mcp-openmsx/issues) page or check the project discussions.
|
|
190
203
|
|
|
191
|
-
|
|
204
|
+
|
|
205
|
+
## 🤝 Contributing
|
|
206
|
+
|
|
207
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
192
208
|
|
|
193
209
|
---
|
package/dist/openmsx.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @license GPL2
|
|
6
6
|
*/
|
|
7
7
|
import fs from "fs/promises";
|
|
8
|
-
import { extractDescriptionFromXML } from "./utils.js";
|
|
8
|
+
import { extractDescriptionFromXML, decodeHtmlEntities } from "./utils.js";
|
|
9
9
|
import { spawn } from 'child_process';
|
|
10
10
|
/**
|
|
11
11
|
* OpenMSX class for controlling the openMSX emulator via TCL commands over TCP socket
|
|
@@ -259,14 +259,16 @@ export class OpenMSX {
|
|
|
259
259
|
// Look for reply tags in the output
|
|
260
260
|
const replyMatch = output.match(/<reply result="(ok|nok)"[^>]*>(.*?)<\/reply>/s);
|
|
261
261
|
if (replyMatch) {
|
|
262
|
+
const outputContent = decodeHtmlEntities(replyMatch[2].trim());
|
|
262
263
|
if (replyMatch[1] === 'ok') {
|
|
263
|
-
return
|
|
264
|
+
return outputContent;
|
|
264
265
|
}
|
|
265
266
|
else {
|
|
266
|
-
return `Error: ${
|
|
267
|
+
return `Error: ${outputContent}`;
|
|
267
268
|
}
|
|
268
269
|
}
|
|
269
|
-
|
|
270
|
+
// Return raw output with HTML entities decoded
|
|
271
|
+
return decodeHtmlEntities(output.trim());
|
|
270
272
|
}
|
|
271
273
|
catch (error) {
|
|
272
274
|
return `Error: ${error instanceof Error ? error.message : 'Unknown error'}`;
|
package/dist/server.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* through TCL commands via stdio.
|
|
7
7
|
*
|
|
8
8
|
* @package @nataliapc/mcp-openmsx
|
|
9
|
-
* @version 1.0.
|
|
9
|
+
* @version 1.0.2
|
|
10
10
|
* @author Natalia Pujol Cremades (@nataliapc)
|
|
11
11
|
* @license GPL2
|
|
12
12
|
*/
|
|
@@ -21,7 +21,7 @@ import fs from "fs/promises";
|
|
|
21
21
|
import path from "path";
|
|
22
22
|
import { openMSXInstance } from "./openmsx.js";
|
|
23
23
|
// Version info for CLI
|
|
24
|
-
const PACKAGE_VERSION = "1.0.
|
|
24
|
+
const PACKAGE_VERSION = "1.0.2";
|
|
25
25
|
// Defaults for openMSX paths
|
|
26
26
|
var OPENMSX_EXECUTABLE = 'openmsx';
|
|
27
27
|
var OPENMSX_SHARE_DIR = '/usr/share/openmsx';
|
|
@@ -112,7 +112,7 @@ function registerAllTools(server) {
|
|
|
112
112
|
return {
|
|
113
113
|
content: [{
|
|
114
114
|
type: "text",
|
|
115
|
-
text: result,
|
|
115
|
+
text: result === '' ? 'Ok' : result,
|
|
116
116
|
}],
|
|
117
117
|
};
|
|
118
118
|
});
|
|
@@ -178,7 +178,7 @@ function registerAllTools(server) {
|
|
|
178
178
|
return {
|
|
179
179
|
content: [{
|
|
180
180
|
type: "text",
|
|
181
|
-
text: response ===
|
|
181
|
+
text: response === '' ? 'Ok' : response,
|
|
182
182
|
}],
|
|
183
183
|
};
|
|
184
184
|
});
|
|
@@ -354,7 +354,7 @@ function registerAllTools(server) {
|
|
|
354
354
|
return {
|
|
355
355
|
content: [{
|
|
356
356
|
type: "text",
|
|
357
|
-
text: response,
|
|
357
|
+
text: response === '' ? 'Ok' : response,
|
|
358
358
|
}],
|
|
359
359
|
};
|
|
360
360
|
});
|
|
@@ -412,7 +412,7 @@ function registerAllTools(server) {
|
|
|
412
412
|
return {
|
|
413
413
|
content: [{
|
|
414
414
|
type: "text",
|
|
415
|
-
text: response,
|
|
415
|
+
text: response === '' ? 'Ok' : response,
|
|
416
416
|
}],
|
|
417
417
|
};
|
|
418
418
|
});
|
|
@@ -474,7 +474,7 @@ function registerAllTools(server) {
|
|
|
474
474
|
return {
|
|
475
475
|
content: [{
|
|
476
476
|
type: "text",
|
|
477
|
-
text: response,
|
|
477
|
+
text: response === '' ? 'Ok' : response,
|
|
478
478
|
}],
|
|
479
479
|
};
|
|
480
480
|
});
|
|
@@ -519,7 +519,7 @@ function registerAllTools(server) {
|
|
|
519
519
|
return {
|
|
520
520
|
content: [{
|
|
521
521
|
type: "text",
|
|
522
|
-
text: response,
|
|
522
|
+
text: response === '' ? 'Ok' : response,
|
|
523
523
|
}],
|
|
524
524
|
};
|
|
525
525
|
});
|
|
@@ -648,7 +648,7 @@ function registerAllTools(server) {
|
|
|
648
648
|
return {
|
|
649
649
|
content: [{
|
|
650
650
|
type: "text",
|
|
651
|
-
text: response,
|
|
651
|
+
text: response === '' ? 'Ok' : response,
|
|
652
652
|
}],
|
|
653
653
|
};
|
|
654
654
|
});
|
|
@@ -724,6 +724,9 @@ function registerAllTools(server) {
|
|
|
724
724
|
const response = await openMSXInstance.sendCommand(openmsxCommand);
|
|
725
725
|
return {
|
|
726
726
|
content: [{
|
|
727
|
+
type: "text",
|
|
728
|
+
text: response.startsWith('Error:') ? 'Fail:' : 'Screendump file saved as:',
|
|
729
|
+
}, {
|
|
727
730
|
type: "text",
|
|
728
731
|
text: response,
|
|
729
732
|
}],
|
|
@@ -858,8 +861,8 @@ async function startHttpServer() {
|
|
|
858
861
|
function createServerInstance() {
|
|
859
862
|
// Create a new server instance (you might want to extract server creation logic)
|
|
860
863
|
const newServer = new McpServer({
|
|
861
|
-
name: "mcp-
|
|
862
|
-
version:
|
|
864
|
+
name: "mcp-openmsx",
|
|
865
|
+
version: PACKAGE_VERSION,
|
|
863
866
|
});
|
|
864
867
|
// Re-register all tools (you might want to extract this to a separate function)
|
|
865
868
|
registerAllTools(newServer);
|
package/dist/utils.js
CHANGED
|
@@ -21,3 +21,34 @@ export async function extractDescriptionFromXML(filePath) {
|
|
|
21
21
|
return 'Error reading description';
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Decode HTML entities in a string to plain text
|
|
26
|
+
* @param text - String containing HTML entities
|
|
27
|
+
* @returns string - String with HTML entities decoded
|
|
28
|
+
*/
|
|
29
|
+
export function decodeHtmlEntities(text) {
|
|
30
|
+
const htmlEntities = {
|
|
31
|
+
'<': '<',
|
|
32
|
+
'>': '>',
|
|
33
|
+
'&': '&',
|
|
34
|
+
'"': '"',
|
|
35
|
+
''': "'",
|
|
36
|
+
'/': '/',
|
|
37
|
+
'`': '`',
|
|
38
|
+
'=': '=',
|
|
39
|
+
''': "'",
|
|
40
|
+
'/': '/',
|
|
41
|
+
'`': '`',
|
|
42
|
+
'=': '=',
|
|
43
|
+
''': "'",
|
|
44
|
+
' ': ' ',
|
|
45
|
+
'
': '\n',
|
|
46
|
+
'
': '\n',
|
|
47
|
+
' ': '\n',
|
|
48
|
+
' ': '\r',
|
|
49
|
+
'	': '\t'
|
|
50
|
+
};
|
|
51
|
+
return text.replace(/&[#\w]+;/g, (entity) => {
|
|
52
|
+
return htmlEntities[entity] || entity;
|
|
53
|
+
});
|
|
54
|
+
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nataliapc/mcp-openmsx",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Model context protocol server for openMSX automation and control",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"mcp-openmsx": "
|
|
8
|
+
"mcp-openmsx": "dist/server.js"
|
|
9
9
|
},
|
|
10
10
|
"keywords": [
|
|
11
11
|
"mcp",
|
|
12
|
-
"model-context-protocol",
|
|
12
|
+
"model-context-protocol",
|
|
13
13
|
"openmsx",
|
|
14
14
|
"msx",
|
|
15
15
|
"emulator",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@modelcontextprotocol/sdk": "^1.11.2",
|
|
42
|
-
"@types/express": "^5.0.2",
|
|
42
|
+
"@types/express": "^5.0.2",
|
|
43
43
|
"express": "^5.1.0",
|
|
44
44
|
"tsx": "^4.7.1",
|
|
45
45
|
"zod": "^3.24.4"
|