@nataliapc/mcp-openmsx 1.1.15 → 1.2.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 +25 -14
- package/dist/server.js +73 -24
- package/dist/utils.js +10 -2
- package/dist/vectordb.js +60 -0
- package/package.json +8 -3
- package/resources/audio/msx-midi.md +872 -0
- package/resources/audio/psg_registers.md +281 -0
- package/resources/audio/sound_cartridge_scc.md +123 -0
- package/resources/audio/sound_cartridge_scci.md +250 -0
- package/resources/audio/toc.json +8 -4
- package/resources/book--msx2-technical-handbook/toc.json +1 -1
- package/resources/msx-unapi/toc.json +2 -2
- package/resources/programming/basic_wiki/ABS().md +36 -0
- package/resources/programming/basic_wiki/AND.md +71 -0
- package/resources/programming/basic_wiki/ASC().md +38 -0
- package/resources/programming/basic_wiki/ATN().md +36 -0
- package/resources/programming/basic_wiki/AUTO.md +39 -0
- package/resources/programming/basic_wiki/BASE().md +147 -0
- package/resources/programming/basic_wiki/BEEP.md +27 -0
- package/resources/programming/basic_wiki/BIN$().md +36 -0
- package/resources/programming/basic_wiki/BLOAD.md +63 -0
- package/resources/programming/basic_wiki/BSAVE.md +61 -0
- package/resources/programming/basic_wiki/CALL.md +391 -0
- package/resources/programming/basic_wiki/CALL_ADJUST.md +40 -0
- package/resources/programming/basic_wiki/CALL_IMPOSE.md +28 -0
- package/resources/programming/basic_wiki/CALL_OPTIONS.md +26 -0
- package/resources/programming/basic_wiki/CALL_PAUSE.md +119 -0
- package/resources/programming/basic_wiki/CALL_PCMPLAY.md +60 -0
- package/resources/programming/basic_wiki/CALL_PCMREC.md +70 -0
- package/resources/programming/basic_wiki/CDBL().md +36 -0
- package/resources/programming/basic_wiki/CHR$().md +51 -0
- package/resources/programming/basic_wiki/CINT().md +36 -0
- package/resources/programming/basic_wiki/CIRCLE.md +51 -0
- package/resources/programming/basic_wiki/CLEAR.md +39 -0
- package/resources/programming/basic_wiki/CLOAD.md +27 -0
- package/resources/programming/basic_wiki/CLOAD?.md +31 -0
- package/resources/programming/basic_wiki/CLOSE.md +44 -0
- package/resources/programming/basic_wiki/CLS.md +51 -0
- package/resources/programming/basic_wiki/COLOR.md +143 -0
- package/resources/programming/basic_wiki/COLOR=.md +93 -0
- package/resources/programming/basic_wiki/COLOR_SPRITE$().md +83 -0
- package/resources/programming/basic_wiki/COLOR_SPRITE().md +85 -0
- package/resources/programming/basic_wiki/CONT.md +23 -0
- package/resources/programming/basic_wiki/COPY.md +215 -0
- package/resources/programming/basic_wiki/COPY_SCREEN.md +61 -0
- package/resources/programming/basic_wiki/COS().md +37 -0
- package/resources/programming/basic_wiki/CSAVE.md +35 -0
- package/resources/programming/basic_wiki/CSNG().md +36 -0
- package/resources/programming/basic_wiki/CSRLIN.md +33 -0
- package/resources/programming/basic_wiki/DATA.md +47 -0
- package/resources/programming/basic_wiki/DEFDBL.md +40 -0
- package/resources/programming/basic_wiki/DEFINT.md +40 -0
- package/resources/programming/basic_wiki/DEFSNG.md +40 -0
- package/resources/programming/basic_wiki/DEFSTR.md +40 -0
- package/resources/programming/basic_wiki/DEF_FN.md +49 -0
- package/resources/programming/basic_wiki/DEF_USR.md +33 -0
- package/resources/programming/basic_wiki/DELETE.md +49 -0
- package/resources/programming/basic_wiki/DIM.md +59 -0
- package/resources/programming/basic_wiki/DRAW.md +77 -0
- package/resources/programming/basic_wiki/ELSE.md +45 -0
- package/resources/programming/basic_wiki/END.md +32 -0
- package/resources/programming/basic_wiki/EOF().md +36 -0
- package/resources/programming/basic_wiki/EQV.md +76 -0
- package/resources/programming/basic_wiki/ERASE.md +35 -0
- package/resources/programming/basic_wiki/ERL.md +34 -0
- package/resources/programming/basic_wiki/ERR.md +143 -0
- package/resources/programming/basic_wiki/ERROR.md +145 -0
- package/resources/programming/basic_wiki/EXP().md +38 -0
- package/resources/programming/basic_wiki/FIELD.md +48 -0
- package/resources/programming/basic_wiki/FIX().md +44 -0
- package/resources/programming/basic_wiki/FN.md +61 -0
- package/resources/programming/basic_wiki/FOR...NEXT.md +80 -0
- package/resources/programming/basic_wiki/FRE().md +66 -0
- package/resources/programming/basic_wiki/GET_DATE.md +60 -0
- package/resources/programming/basic_wiki/GET_TIME.md +34 -0
- package/resources/programming/basic_wiki/GOSUB.md +41 -0
- package/resources/programming/basic_wiki/GOTO.md +41 -0
- package/resources/programming/basic_wiki/HEX$().md +36 -0
- package/resources/programming/basic_wiki/IF...GOTO...ELSE.md +55 -0
- package/resources/programming/basic_wiki/IF...THEN...ELSE.md +50 -0
- package/resources/programming/basic_wiki/IMP.md +83 -0
- package/resources/programming/basic_wiki/INKEY$.md +65 -0
- package/resources/programming/basic_wiki/INP().md +33 -0
- package/resources/programming/basic_wiki/INPUT$().md +51 -0
- package/resources/programming/basic_wiki/INPUT.md +93 -0
- package/resources/programming/basic_wiki/INSTR().md +44 -0
- package/resources/programming/basic_wiki/INT().md +44 -0
- package/resources/programming/basic_wiki/INTERVAL.md +57 -0
- package/resources/programming/basic_wiki/KEY().md +51 -0
- package/resources/programming/basic_wiki/KEY.md +254 -0
- package/resources/programming/basic_wiki/LEFT$().md +39 -0
- package/resources/programming/basic_wiki/LEN().md +36 -0
- package/resources/programming/basic_wiki/LET.md +68 -0
- package/resources/programming/basic_wiki/LINE.md +74 -0
- package/resources/programming/basic_wiki/LINE_INPUT.md +79 -0
- package/resources/programming/basic_wiki/LIST.md +58 -0
- package/resources/programming/basic_wiki/LLIST.md +43 -0
- package/resources/programming/basic_wiki/LOAD.md +56 -0
- package/resources/programming/basic_wiki/LOCATE.md +67 -0
- package/resources/programming/basic_wiki/LOG().md +36 -0
- package/resources/programming/basic_wiki/LPOS().md +31 -0
- package/resources/programming/basic_wiki/LPRINT.md +46 -0
- package/resources/programming/basic_wiki/MAXFILES.md +39 -0
- package/resources/programming/basic_wiki/MERGE.md +54 -0
- package/resources/programming/basic_wiki/MID$().md +72 -0
- package/resources/programming/basic_wiki/MOD.md +39 -0
- package/resources/programming/basic_wiki/MOTOR.md +46 -0
- package/resources/programming/basic_wiki/NEW.md +27 -0
- package/resources/programming/basic_wiki/NOT.md +61 -0
- package/resources/programming/basic_wiki/OCT$().md +36 -0
- package/resources/programming/basic_wiki/ON...GOSUB.md +45 -0
- package/resources/programming/basic_wiki/ON...GOTO.md +42 -0
- package/resources/programming/basic_wiki/ON_ERROR_GOTO.md +61 -0
- package/resources/programming/basic_wiki/ON_INTERVAL_GOSUB.md +54 -0
- package/resources/programming/basic_wiki/ON_KEY_GOSUB.md +56 -0
- package/resources/programming/basic_wiki/ON_SPRITE_GOSUB.md +41 -0
- package/resources/programming/basic_wiki/ON_STOP_GOSUB.md +56 -0
- package/resources/programming/basic_wiki/ON_STRIG_GOSUB.md +70 -0
- package/resources/programming/basic_wiki/OPEN.md +103 -0
- package/resources/programming/basic_wiki/OR.md +75 -0
- package/resources/programming/basic_wiki/OUT.md +35 -0
- package/resources/programming/basic_wiki/PAD().md +110 -0
- package/resources/programming/basic_wiki/PAINT.md +66 -0
- package/resources/programming/basic_wiki/PDL().md +53 -0
- package/resources/programming/basic_wiki/PEEK().md +44 -0
- package/resources/programming/basic_wiki/PLAY().md +58 -0
- package/resources/programming/basic_wiki/PLAY.md +196 -0
- package/resources/programming/basic_wiki/POINT.md +52 -0
- package/resources/programming/basic_wiki/POKE.md +51 -0
- package/resources/programming/basic_wiki/POS().md +36 -0
- package/resources/programming/basic_wiki/PRESET.md +61 -0
- package/resources/programming/basic_wiki/PRINT.md +179 -0
- package/resources/programming/basic_wiki/PSET.md +82 -0
- package/resources/programming/basic_wiki/PUT_KANJI.md +93 -0
- package/resources/programming/basic_wiki/PUT_SPRITE.md +143 -0
- package/resources/programming/basic_wiki/READ.md +45 -0
- package/resources/programming/basic_wiki/REM.md +42 -0
- package/resources/programming/basic_wiki/RENUM.md +78 -0
- package/resources/programming/basic_wiki/RESTORE.md +52 -0
- package/resources/programming/basic_wiki/RESUME.md +45 -0
- package/resources/programming/basic_wiki/RETURN.md +47 -0
- package/resources/programming/basic_wiki/RIGHT$().md +39 -0
- package/resources/programming/basic_wiki/RND().md +51 -0
- package/resources/programming/basic_wiki/RUN.md +56 -0
- package/resources/programming/basic_wiki/SAVE.md +65 -0
- package/resources/programming/basic_wiki/SCREEN.md +164 -0
- package/resources/programming/basic_wiki/SET_ADJUST.md +66 -0
- package/resources/programming/basic_wiki/SET_BEEP.md +76 -0
- package/resources/programming/basic_wiki/SET_DATE.md +103 -0
- package/resources/programming/basic_wiki/SET_PAGE.md +52 -0
- package/resources/programming/basic_wiki/SET_PASSWORD.md +75 -0
- package/resources/programming/basic_wiki/SET_PROMPT.md +61 -0
- package/resources/programming/basic_wiki/SET_SCREEN.md +100 -0
- package/resources/programming/basic_wiki/SET_SCROLL.md +55 -0
- package/resources/programming/basic_wiki/SET_TIME.md +83 -0
- package/resources/programming/basic_wiki/SET_TITLE.md +87 -0
- package/resources/programming/basic_wiki/SET_VIDEO.md +49 -0
- package/resources/programming/basic_wiki/SGN().md +38 -0
- package/resources/programming/basic_wiki/SIN().md +36 -0
- package/resources/programming/basic_wiki/SOUND.md +188 -0
- package/resources/programming/basic_wiki/SPACE$().md +38 -0
- package/resources/programming/basic_wiki/SPC().md +34 -0
- package/resources/programming/basic_wiki/SPRITE$().md +50 -0
- package/resources/programming/basic_wiki/SPRITE.md +31 -0
- package/resources/programming/basic_wiki/SQR().md +32 -0
- package/resources/programming/basic_wiki/STICK().md +70 -0
- package/resources/programming/basic_wiki/STOP.md +70 -0
- package/resources/programming/basic_wiki/STR$().md +37 -0
- package/resources/programming/basic_wiki/STRIG().md +82 -0
- package/resources/programming/basic_wiki/STRING$().md +42 -0
- package/resources/programming/basic_wiki/SWAP.md +62 -0
- package/resources/programming/basic_wiki/TAB().md +38 -0
- package/resources/programming/basic_wiki/TAN().md +36 -0
- package/resources/programming/basic_wiki/TIME.md +59 -0
- package/resources/programming/basic_wiki/TROFF.md +21 -0
- package/resources/programming/basic_wiki/TRON.md +39 -0
- package/resources/programming/basic_wiki/USR().md +66 -0
- package/resources/programming/basic_wiki/VAL().md +36 -0
- package/resources/programming/basic_wiki/VARPTR().md +50 -0
- package/resources/programming/basic_wiki/VDP().md +103 -0
- package/resources/programming/basic_wiki/VPEEK().md +46 -0
- package/resources/programming/basic_wiki/VPOKE.md +48 -0
- package/resources/programming/basic_wiki/WAIT.md +38 -0
- package/resources/programming/basic_wiki/WIDTH.md +76 -0
- package/resources/programming/basic_wiki/XOR.md +72 -0
- package/resources/programming/basic_wiki/_toc.json +871 -0
- package/resources/sdcc/toc.json +1 -1
- package/vector-db/index.json +1 -0
- /package/resources/msx-unapi/{Ethernet_UNAPI_specification_1.1.md → Ethernet_UNAPI_specification_1_1.md} +0 -0
- /package/resources/msx-unapi/{MSX_UNAPI_specification_1.1.md → MSX_UNAPI_specification_1_1.md} +0 -0
package/README.md
CHANGED
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
[](https://www.npmjs.com/package/@nataliapc/mcp-openmsx?activeTab=versions)
|
|
10
10
|
[]()
|
|
11
11
|
|
|
12
|
-
|
|
13
12
|
A [Model Context Protocol](https://modelcontextprotocol.io/introduction) (MCP) server for automating [openMSX emulator](https://github.com/openMSX/openMSX) instances.
|
|
14
13
|
|
|
15
14
|
This server provides comprehensive tools for MSX software development, testing, and automation through standardized MCP protocols.
|
|
@@ -25,7 +24,8 @@ This project creates a bridge between modern AI-assisted development (e.g. GitHu
|
|
|
25
24
|
- **Video Control**: VDP register manipulation and screen capture.
|
|
26
25
|
- **Memory Operations**: Read/write RAM, VRAM, and I/O port access.
|
|
27
26
|
- **Automation**: Keyboard input simulation and savestate management.
|
|
28
|
-
- **
|
|
27
|
+
- **Vector DB Integration**: Query an embedded vector database with MSX resources for development support.
|
|
28
|
+
- **Hybrid Mode**: This MCP server supports hybrid access mode (_STDIO_ and _HTTP_ transports).
|
|
29
29
|
|
|
30
30
|
## 🏗️ Architecture
|
|
31
31
|
|
|
@@ -74,6 +74,10 @@ The MCP server translates high-level commands from your Copilot AI into `TCL` co
|
|
|
74
74
|
- `screen_dump`: Export screen data as BASIC BSAVE instruction.
|
|
75
75
|
- `msxdocs_resource_get`: Retrieve MCP resources for MCP clients that don't support MCP resources.
|
|
76
76
|
|
|
77
|
+
### Documentation Tools
|
|
78
|
+
- `vector_db_query`: Query the Vector DB resources to obtain information about MSX systems, cartridges, and other development resources.
|
|
79
|
+
- `msxdocs_resource_get`: Retrieve MCP resources for MCP clients that don't support MCP resources.
|
|
80
|
+
|
|
77
81
|
## 📚 Available MCP Resources
|
|
78
82
|
|
|
79
83
|
### What are MCP Resources?
|
|
@@ -118,18 +122,19 @@ The rights to these resources belong to their respective authors and are distrib
|
|
|
118
122
|
|
|
119
123
|
## 🚀 Quick Start
|
|
120
124
|
|
|
121
|
-
You can use this MCP server in this basic way with the [precompiled NPM package](https://www.npmjs.com/package/@nataliapc/mcp-openmsx).
|
|
125
|
+
You can use this MCP server in this basic way with the [precompiled NPM package](https://www.npmjs.com/package/@nataliapc/mcp-openmsx).
|
|
122
126
|
|
|
123
|
-
### 🟢
|
|
127
|
+
### 🟢 Quick installation with VSCode
|
|
124
128
|
|
|
129
|
+
[](vscode:mcp/install?%7B%22name%22%3A%22mcp-openmsx%22%2C%22type%22%3A%22stdio%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40nataliapc%2Fmcp-openmsx%22%5D%7D)
|
|
130
|
+
|
|
131
|
+
Steps to install the MCP server in VSCode:
|
|
125
132
|
* Install [Github Copilot extension](https://code.visualstudio.com/docs/copilot/overview)
|
|
126
|
-
*
|
|
133
|
+
* Use the **Install in VS Code** button above to install the MCP server in your VSCode workspace.
|
|
134
|
+
* Or add to your workspace a file `.vscode/mcp.json` with the json configuration below.
|
|
127
135
|
|
|
128
136
|
### STDIO mode (recommended)
|
|
129
137
|
|
|
130
|
-
[](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22stdio%22%2C%22command%22%3A%20%22npx%22%2C%22args%22%3A%20%5B%22%40nataliapc%2Fmcp-openmsx%22%5D%2C%20%22env%22%3A%20%7B%22OPENMSX_SHARE_DIR%22%3A%20%22%2Fusr%2Fshare%2Fopenmsx%22%7D%7D)
|
|
131
|
-
[](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22stdio%22%2C%22command%22%3A%20%22npx%22%2C%22args%22%3A%20%5B%22%40nataliapc%2Fmcp-openmsx%22%5D%2C%20%22env%22%3A%20%7B%22OPENMSX_SHARE_DIR%22%3A%20%22%2Fusr%2Fshare%2Fopenmsx%22%7D%7D&quality=insiders)
|
|
132
|
-
|
|
133
138
|
```json
|
|
134
139
|
{
|
|
135
140
|
"servers": {
|
|
@@ -137,7 +142,7 @@ You can use this MCP server in this basic way with the [precompiled NPM package]
|
|
|
137
142
|
"command": "npx",
|
|
138
143
|
"args": ["@nataliapc/mcp-openmsx"],
|
|
139
144
|
"env": {
|
|
140
|
-
"OPENMSX_SHARE_DIR": "
|
|
145
|
+
"OPENMSX_SHARE_DIR": "C:\the\location\of\your\openmsx\share\folder"
|
|
141
146
|
}
|
|
142
147
|
}
|
|
143
148
|
}
|
|
@@ -164,7 +169,9 @@ You can use this MCP server in this basic way with the [precompiled NPM package]
|
|
|
164
169
|
|
|
165
170
|
### 🟢 Basic Usage with Claude Desktop
|
|
166
171
|
|
|
167
|
-
|
|
172
|
+
Follow [these instrutions](https://modelcontextprotocol.io/quickstart/user#for-claude-desktop-users) to access Claude's `claude_desktop_config.json` file.
|
|
173
|
+
|
|
174
|
+
Edit it to include the following JSON entry:
|
|
168
175
|
|
|
169
176
|
```json
|
|
170
177
|
{
|
|
@@ -173,13 +180,15 @@ Add to your `claude_desktop_config.json`:
|
|
|
173
180
|
"command": "npx",
|
|
174
181
|
"args": ["@nataliapc/mcp-openmsx"],
|
|
175
182
|
"env": {
|
|
176
|
-
"OPENMSX_SHARE_DIR": "
|
|
183
|
+
"OPENMSX_SHARE_DIR": "C:\the\location\of\your\openmsx\share\folder"
|
|
177
184
|
}
|
|
178
185
|
}
|
|
179
186
|
}
|
|
180
187
|
}
|
|
181
188
|
```
|
|
182
189
|
|
|
190
|
+
**Note:** Environment variables are optional. Customize them as you need.
|
|
191
|
+
|
|
183
192
|
### 🟢 Environment Variables
|
|
184
193
|
|
|
185
194
|
| Variable | Description | Default Value | Example |
|
|
@@ -195,6 +204,8 @@ Add to your `claude_desktop_config.json`:
|
|
|
195
204
|
|
|
196
205
|
## 🧑💻 Advanced Manual Usage
|
|
197
206
|
|
|
207
|
+
This is not needed for using the MCP server, but if you want to install it manually, follow these steps.
|
|
208
|
+
|
|
198
209
|
Currently, the MCP server requires Linux to be compiled. It has not been tested on Windows or macOS, although it will likely work on the latter as well.
|
|
199
210
|
|
|
200
211
|
### Manual installation
|
|
@@ -230,10 +241,11 @@ MCP_TRANSPORT=http mcp-openmsx
|
|
|
230
241
|
mcp-openmsx http
|
|
231
242
|
```
|
|
232
243
|
|
|
233
|
-
|
|
234
244
|
## 💡 Development
|
|
235
245
|
|
|
236
|
-
|
|
246
|
+
This is not needed for using the MCP server, but if you want to contribute or modify the code, follow these steps.
|
|
247
|
+
|
|
248
|
+
### Prerequisites to build
|
|
237
249
|
|
|
238
250
|
- Node.js >= 18.0.0
|
|
239
251
|
- TypeScript
|
|
@@ -254,7 +266,6 @@ npm run build
|
|
|
254
266
|
npm run dev
|
|
255
267
|
```
|
|
256
268
|
|
|
257
|
-
|
|
258
269
|
## 🪪 License
|
|
259
270
|
|
|
260
271
|
GPL2 License - see [LICENSE](LICENSE) file for details.
|
package/dist/server.js
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* through TCL commands via stdio.
|
|
7
7
|
*
|
|
8
8
|
* @package @nataliapc/mcp-openmsx
|
|
9
|
-
* @version 1.1.15
|
|
10
9
|
* @author Natalia Pujol Cremades (@nataliapc)
|
|
11
10
|
* @license GPL2
|
|
12
11
|
*/
|
|
@@ -20,10 +19,14 @@ import express from "express";
|
|
|
20
19
|
import fs from "fs/promises";
|
|
21
20
|
import path from "path";
|
|
22
21
|
import { openMSXInstance } from "./openmsx.js";
|
|
22
|
+
import { VectorDB } from "./vectordb.js";
|
|
23
23
|
import { fetchCleanWebpage, addFileExtension, listResourcesDirectory, encodeTypeText, isErrorResponse, getResponseContent } from "./utils.js";
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
import { createRequire } from 'module';
|
|
25
|
+
// Dynamically obtain PACKAGE_VERSION from package.json at runtime
|
|
26
|
+
const require = createRequire(import.meta.url);
|
|
27
|
+
export const PACKAGE_VERSION = require('../package.json').version;
|
|
26
28
|
const resourcesDir = path.join(path.dirname(new URL(import.meta.url).pathname), "../resources");
|
|
29
|
+
const vectorDbDir = path.join(path.dirname(new URL(import.meta.url).pathname), "../vector-db");
|
|
27
30
|
// Defaults for openMSX paths
|
|
28
31
|
var OPENMSX_EXECUTABLE = 'openmsx';
|
|
29
32
|
var OPENMSX_SHARE_DIR = '/usr/share/openmsx';
|
|
@@ -861,16 +864,61 @@ The parameter scrbasename is the name of the filename (without path) to save the
|
|
|
861
864
|
response !== undefined ? response : `Error: No response for command "${command}".`
|
|
862
865
|
]);
|
|
863
866
|
});
|
|
867
|
+
server.registerTool(
|
|
868
|
+
// Name of the tool (used to call it)
|
|
869
|
+
"vector_db_query", {
|
|
870
|
+
title: "Vector DB query from resources",
|
|
871
|
+
// Description of the tool (what it does)
|
|
872
|
+
description: `Query the Vector DB resources to obtain information about MSX system, cartridges, programming, and other development resources.
|
|
873
|
+
The query is a string used to search within the Vector DB resources; it is case-insensitive and may contain spaces.
|
|
874
|
+
The response is the list of the top 10 result resources that match the query, including their score, title, and resource URI, and are sorted in descending order by proximity score to the query.
|
|
875
|
+
**Important Note**: The Vector DB resources are in english, japanese, or dutch.
|
|
876
|
+
`,
|
|
877
|
+
// Schema for the tool (input validation)
|
|
878
|
+
inputSchema: {
|
|
879
|
+
query: z.string().min(2).max(100).describe("Query string to search in the Vector DB resources, case-insensitive and may contain spaces."),
|
|
880
|
+
},
|
|
881
|
+
// outputSchema: {
|
|
882
|
+
// results: z.array(z.object({
|
|
883
|
+
// score: z.number().describe("Proximity score of the result to the query, higher is better."),
|
|
884
|
+
// title: z.string().describe("Title of the resource."),
|
|
885
|
+
// uri: z.string().describe("URI of the resource, which can be used to access the resource."),
|
|
886
|
+
// document: z.string().describe("Document chunk of the resource, retrieved from the Vector DB."),
|
|
887
|
+
// id: z.string().describe("Unique resource chunk ID, used internally by the Vector DB."),
|
|
888
|
+
// }))
|
|
889
|
+
// },
|
|
890
|
+
},
|
|
891
|
+
// Handler for the tool (function to be executed when the tool is called)
|
|
892
|
+
async ({ query }) => {
|
|
893
|
+
const results = await VectorDB.getInstance().query(query);
|
|
894
|
+
return {
|
|
895
|
+
content: [{
|
|
896
|
+
type: "text",
|
|
897
|
+
text: JSON.stringify(results),
|
|
898
|
+
}],
|
|
899
|
+
results: results,
|
|
900
|
+
isError: false,
|
|
901
|
+
};
|
|
902
|
+
});
|
|
864
903
|
// ============================================================================
|
|
865
904
|
// MSX Documentation resources
|
|
866
905
|
const resdocs = (await listResourcesDirectory(resourcesDir)).sort();
|
|
867
906
|
const regResources = [];
|
|
868
907
|
for (let index = 0; index < resdocs.length; index++) {
|
|
908
|
+
// Read the toc.json file if exists, otherwise skip this section
|
|
869
909
|
const sectionName = resdocs[index];
|
|
870
910
|
const tocFile = path.join(resourcesDir, `${sectionName}/toc.json`);
|
|
871
|
-
|
|
911
|
+
let tocContent = { toc: [] };
|
|
912
|
+
try {
|
|
913
|
+
tocContent = JSON.parse(await fs.readFile(tocFile, 'utf8'));
|
|
914
|
+
}
|
|
915
|
+
catch (error) {
|
|
916
|
+
// The toc.json file does not exist or is invalid, skip this section
|
|
917
|
+
continue;
|
|
918
|
+
}
|
|
919
|
+
// Register each item in the toc.json as a resource
|
|
872
920
|
tocContent.toc.forEach((item, itemIndex) => {
|
|
873
|
-
const itemName = path.parse(item.uri.split('/').pop()).
|
|
921
|
+
const itemName = path.parse(item.uri.split('/').pop()).base || '';
|
|
874
922
|
let resource = {
|
|
875
923
|
uri: item.uri,
|
|
876
924
|
filename: '',
|
|
@@ -926,18 +974,18 @@ The parameter scrbasename is the name of the filename (without path) to save the
|
|
|
926
974
|
;
|
|
927
975
|
// Source: https://www.msx.org/wiki/Category:MSX-BASIC_Instructions
|
|
928
976
|
const basicInstructions = [
|
|
929
|
-
"ABS()", "AND", "ASC()", "ATN()", "AUTO", "BASE()", "BEEP", "BIN$()", "BLOAD", "BSAVE", "CALL", "CALL ADJUST", "CALL
|
|
930
|
-
"CDBL()", "CHR$()", "CINT()", "CIRCLE", "CLEAR", "CLOAD", "CLOAD?", "CLOSE", "CLS", "COLOR", "COLOR=", "COLOR SPRITE()",
|
|
931
|
-
"COPY SCREEN", "COS()", "CSAVE", "CSNG()", "CSRLIN", "DATA", "DEFDBL", "DEF FN", "DEFINT", "DEFSNG", "DEFSTR", "DEF USR",
|
|
932
|
-
"END", "EOF()", "EQV", "ERASE", "ERL", "ERR", "ERROR", "EXP()", "FIX()", "FN", "FOR...NEXT", "FRE()", "GET DATE",
|
|
933
|
-
"IF...GOTO...ELSE", "IF...THEN...ELSE", "IMP", "INKEY$", "INP()", "INPUT", "INPUT$()", "INSTR()", "INT()", "INTERVAL",
|
|
934
|
-
"
|
|
935
|
-
"
|
|
936
|
-
"OR", "OUT", "PAD()", "PAINT", "PDL()", "PEEK()", "PLAY", "PLAY()", "POINT", "POKE", "POS()", "PRESET", "PRINT",
|
|
937
|
-
"REM", "RENUM", "RESTORE", "RESUME", "RETURN", "RIGHT$()", "RND()", "RUN", "SAVE", "SCREEN", "SET ADJUST",
|
|
938
|
-
"SET
|
|
939
|
-
"
|
|
940
|
-
"VPEEK()", "VPOKE", "WAIT", "WIDTH", "XOR"
|
|
977
|
+
"ABS()", "AND", "ASC()", "ATN()", "AUTO", "BASE()", "BEEP", "BIN$()", "BLOAD", "BSAVE", "CALL", "CALL ADJUST", "CALL IMPOSE", "CALL OPTIONS", "CALL PAUSE",
|
|
978
|
+
"CALL PCMPLAY", "CALL PCMREC", "CDBL()", "CHR$()", "CINT()", "CIRCLE", "CLEAR", "CLOAD", "CLOAD?", "CLOSE", "CLS", "COLOR", "COLOR=", "COLOR SPRITE()",
|
|
979
|
+
"COLOR SPRITE$()", "CONT", "COPY", "COPY SCREEN", "COS()", "CSAVE", "CSNG()", "CSRLIN", "DATA", "DEFDBL", "DEF FN", "DEFINT", "DEFSNG", "DEFSTR", "DEF USR",
|
|
980
|
+
"DELETE", "DIM", "DRAW", "ELSE", "END", "EOF()", "EQV", "ERASE", "ERL", "ERR", "ERROR", "EXP()", "FIELD", "FIX()", "FN", "FOR...NEXT", "FRE()", "GET DATE",
|
|
981
|
+
"GET TIME", "GOSUB", "GOTO", "HEX$()", "IF...GOTO...ELSE", "IF...THEN...ELSE", "IMP", "INKEY$", "INP()", "INPUT", "INPUT$()", "INSTR()", "INT()", "INTERVAL",
|
|
982
|
+
"KEY", "KEY()", "LEFT$()", "LEN()", "LET", "LINE", "LINE INPUT", "LIST", "LLIST", "LOAD", "LOCATE", "LOG()", "LPOS()", "LPRINT", "MAXFILES", "MERGE",
|
|
983
|
+
"MID$()", "MOD", "MOTOR", "NEW", "NOT", "OCT$()", "ON...GOSUB", "ON...GOTO", "ON ERROR GOTO", "ON INTERVAL GOSUB", "ON KEY GOSUB", "ON SPRITE GOSUB",
|
|
984
|
+
"ON STOP GOSUB", "ON STRIG GOSUB", "OPEN", "OR", "OUT", "PAD()", "PAINT", "PDL()", "PEEK()", "PLAY", "PLAY()", "POINT", "POKE", "POS()", "PRESET", "PRINT",
|
|
985
|
+
"PSET", "PUT KANJI", "PUT SPRITE", "READ", "REM", "RENUM", "RESTORE", "RESUME", "RETURN", "RIGHT$()", "RND()", "RUN", "SAVE", "SCREEN", "SET ADJUST",
|
|
986
|
+
"SET BEEP", "SET DATE", "SET PAGE", "SET PASSWORD", "SET PROMPT", "SET SCREEN", "SET SCROLL", "SET TIME", "SET TITLE", "SET VIDEO", "SGN()", "SIN()",
|
|
987
|
+
"SOUND", "SPACE$()", "SPC()", "SPRITE", "SPRITE$()", "SQR()", "STICK()", "STOP", "STR$()", "STRIG()", "STRING$()", "SWAP", "TAB()", "TAN()", "TIME", "TROFF",
|
|
988
|
+
"TRON", "USR()", "VAL()", "VARPTR()", "VDP()", "VPEEK()", "VPOKE", "WAIT", "WIDTH", "XOR"
|
|
941
989
|
];
|
|
942
990
|
server.resource("msxdocs_basic_wiki", new ResourceTemplate("msxdocs://basic_wiki/{instruction}", {
|
|
943
991
|
list: undefined,
|
|
@@ -949,19 +997,19 @@ The parameter scrbasename is the name of the filename (without path) to save the
|
|
|
949
997
|
description: "Documentation about all the standard MSX BASIC instructions from www.msx.org",
|
|
950
998
|
mimeType: "text/html",
|
|
951
999
|
}, async (uri, variables) => {
|
|
952
|
-
|
|
953
|
-
.replace(/ /g, '_')
|
|
954
|
-
.replace(/\?/g, '%3F')
|
|
955
|
-
.replace(/=/g, '%3D');
|
|
956
|
-
const url = `https://www.msx.org/wiki/${instruction}`;
|
|
1000
|
+
let instruction = variables.instruction;
|
|
957
1001
|
let resourceContent;
|
|
958
1002
|
let mimeType;
|
|
1003
|
+
// urldecode the instruction to avoid issues with special characters
|
|
1004
|
+
instruction = decodeURIComponent(instruction).replaceAll(' ', '_');
|
|
959
1005
|
try {
|
|
960
|
-
|
|
1006
|
+
let resourceFile;
|
|
1007
|
+
[mimeType, resourceFile] = await addFileExtension(path.join(resourcesDir, 'programming', 'basic_wiki', instruction));
|
|
1008
|
+
resourceContent = await fs.readFile(resourceFile, 'utf8');
|
|
961
1009
|
}
|
|
962
1010
|
catch (error) {
|
|
963
1011
|
// Throw exception (MCP protocol requirement)
|
|
964
|
-
throw error;
|
|
1012
|
+
throw new Error(`Error reading resource programming/basic_wiki/${instruction}: ${error instanceof Error ? error.message : String(error)}`);
|
|
965
1013
|
}
|
|
966
1014
|
return {
|
|
967
1015
|
contents: [{
|
|
@@ -1214,6 +1262,7 @@ async function main() {
|
|
|
1214
1262
|
MACHINES_DIR = `${OPENMSX_SHARE_DIR}machines`;
|
|
1215
1263
|
EXTENSIONS_DIR = `${OPENMSX_SHARE_DIR}extensions`;
|
|
1216
1264
|
}
|
|
1265
|
+
VectorDB.setIndexDirectory(vectorDbDir);
|
|
1217
1266
|
// Detect transport type from environment or command line
|
|
1218
1267
|
const transportType = process.env.MCP_TRANSPORT || process.argv[2] || 'stdio';
|
|
1219
1268
|
if (transportType === 'http') {
|
package/dist/utils.js
CHANGED
|
@@ -54,13 +54,13 @@ export async function addFileExtension(filePath) {
|
|
|
54
54
|
return ['text/plain', filePath];
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
|
-
* List all folders in the resources directory
|
|
57
|
+
* List all folders and subfolders in the resources directory
|
|
58
58
|
* @param resourcesDir - Path to the resources directory
|
|
59
59
|
* @returns Promise<string[]> - List of folder names in the resources directory
|
|
60
60
|
*/
|
|
61
61
|
export async function listResourcesDirectory(resourcesDir) {
|
|
62
62
|
try {
|
|
63
|
-
const directories = await fs.readdir(resourcesDir, { withFileTypes: true });
|
|
63
|
+
const directories = await fs.readdir(resourcesDir, { withFileTypes: true, recursive: true });
|
|
64
64
|
const folderNames = directories
|
|
65
65
|
.filter(dirent => dirent.isDirectory())
|
|
66
66
|
.map(dirent => dirent.name);
|
|
@@ -229,3 +229,11 @@ export function getResponseContent(response, isError = false) {
|
|
|
229
229
|
isError: hasError
|
|
230
230
|
};
|
|
231
231
|
}
|
|
232
|
+
/*
|
|
233
|
+
* Sleep for a specified number of milliseconds
|
|
234
|
+
* @param ms - Number of milliseconds to sleep
|
|
235
|
+
* @returns Promise that resolves after the specified time
|
|
236
|
+
*/
|
|
237
|
+
export function sleep(ms) {
|
|
238
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
239
|
+
}
|
package/dist/vectordb.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vector Database wrapper class
|
|
3
|
+
*
|
|
4
|
+
* @author Natalia Pujol Cremades (@nataliapc)
|
|
5
|
+
* @license GPL2
|
|
6
|
+
*/
|
|
7
|
+
import { LocalIndex } from 'vectra';
|
|
8
|
+
import embeddings from '@themaximalist/embeddings.js';
|
|
9
|
+
export class VectorDB {
|
|
10
|
+
static instance;
|
|
11
|
+
static vectorDbDir = '../vector-db';
|
|
12
|
+
index;
|
|
13
|
+
static getInstance() {
|
|
14
|
+
if (!VectorDB.instance) {
|
|
15
|
+
VectorDB.instance = new VectorDB();
|
|
16
|
+
}
|
|
17
|
+
return VectorDB.instance;
|
|
18
|
+
}
|
|
19
|
+
static setIndexDirectory(dbDir) {
|
|
20
|
+
VectorDB.vectorDbDir = dbDir;
|
|
21
|
+
}
|
|
22
|
+
constructor(dbDir = VectorDB.vectorDbDir) {
|
|
23
|
+
this.index = new LocalIndex(dbDir);
|
|
24
|
+
if (!this.initDatabase()) {
|
|
25
|
+
throw new Error('Failed to initialize VectorDB: Index does not exist');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async initDatabase() {
|
|
29
|
+
return await this.index.isIndexCreated();
|
|
30
|
+
}
|
|
31
|
+
async getVector(text) {
|
|
32
|
+
const response = await embeddings(text);
|
|
33
|
+
if (!response || !Array.isArray(response) || response.length === 0) {
|
|
34
|
+
throw new Error('Failed to generate embedding vector');
|
|
35
|
+
}
|
|
36
|
+
return response;
|
|
37
|
+
}
|
|
38
|
+
async query(text) {
|
|
39
|
+
const vector = await this.getVector(text);
|
|
40
|
+
let results = [];
|
|
41
|
+
try {
|
|
42
|
+
results = await this.index.queryItems(vector, text, 10);
|
|
43
|
+
if (results.length > 0) {
|
|
44
|
+
return results.map(result => {
|
|
45
|
+
return {
|
|
46
|
+
score: result.score.toFixed(4),
|
|
47
|
+
uri: result.item.metadata?.uri || 'unknown',
|
|
48
|
+
title: result.item.metadata?.title || 'unknown',
|
|
49
|
+
document: String(result.item.metadata?.document || ''),
|
|
50
|
+
id: result.item.metadata?.id || 'unknown',
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
throw new Error(`Query failed: ${error}`);
|
|
57
|
+
}
|
|
58
|
+
return results;
|
|
59
|
+
}
|
|
60
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nataliapc/mcp-openmsx",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Model context protocol server for openMSX automation and control",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"type": "module",
|
|
@@ -38,17 +38,21 @@
|
|
|
38
38
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.16.0",
|
|
42
|
+
"@themaximalist/embeddings.js": "^0.1.3",
|
|
42
43
|
"@types/express": "^5.0.2",
|
|
44
|
+
"@xenova/transformers": "^2.17.2",
|
|
45
|
+
"debug": "^4.4.1",
|
|
43
46
|
"express": "^5.1.0",
|
|
44
47
|
"sanitize-html": "^2.17.0",
|
|
45
48
|
"tsx": "^4.7.1",
|
|
49
|
+
"vectra": "^0.11.1",
|
|
46
50
|
"zod": "^3.24.4"
|
|
47
51
|
},
|
|
48
52
|
"devDependencies": {
|
|
49
53
|
"@modelcontextprotocol/inspector": "^0.15.0",
|
|
50
54
|
"@types/mime-types": "^3.0.1",
|
|
51
|
-
"@types/node": "^
|
|
55
|
+
"@types/node": "^24.0.15",
|
|
52
56
|
"@types/sanitize-html": "^2.16.0",
|
|
53
57
|
"shx": "^0.4.0",
|
|
54
58
|
"typescript": "^5.8.3"
|
|
@@ -56,6 +60,7 @@
|
|
|
56
60
|
"files": [
|
|
57
61
|
"dist/**/*",
|
|
58
62
|
"resources/**/*",
|
|
63
|
+
"vector-db/**/*",
|
|
59
64
|
"README.md",
|
|
60
65
|
"LICENSE"
|
|
61
66
|
],
|