@vscxml/mcp 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/dist/process-manager.d.ts +3 -24
- package/dist/process-manager.js +4 -131
- package/dist/process-manager.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8,22 +8,27 @@ export { createServer } from './server.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export async function startStdio(config = {}) {
|
|
10
10
|
const processManager = new ProcessManager();
|
|
11
|
-
//
|
|
12
|
-
const genUrl = await processManager.
|
|
11
|
+
// Discover backends (never auto-spawn — user must start them manually)
|
|
12
|
+
const genUrl = await processManager.discoverGenerator(config.generatorUrl);
|
|
13
13
|
if (genUrl) {
|
|
14
14
|
config.generatorUrl = genUrl;
|
|
15
15
|
console.error(`[MCP] Generator: ${genUrl}`);
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
else {
|
|
18
|
+
console.error(`[MCP] Generator not found. Start it manually: vscxml-generator-cli serve --port ${8080} --cors`);
|
|
19
|
+
}
|
|
20
|
+
const simUrl = await processManager.discoverSimulator(config.simulatorUrl);
|
|
18
21
|
if (simUrl) {
|
|
19
22
|
config.simulatorUrl = simUrl;
|
|
20
23
|
console.error(`[MCP] Simulator: ${simUrl}`);
|
|
21
24
|
}
|
|
25
|
+
else {
|
|
26
|
+
console.error(`[MCP] Simulator not found. Start it manually before using simulation tools.`);
|
|
27
|
+
}
|
|
22
28
|
const server = createServer(config);
|
|
23
29
|
const transport = new StdioServerTransport();
|
|
24
|
-
|
|
25
|
-
process.on('
|
|
26
|
-
process.on('SIGTERM', () => { processManager.shutdown(); process.exit(0); });
|
|
30
|
+
process.on('SIGINT', () => process.exit(0));
|
|
31
|
+
process.on('SIGTERM', () => process.exit(0));
|
|
27
32
|
await server.connect(transport);
|
|
28
33
|
}
|
|
29
34
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,SAAoB,EAAE;IACrD,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;IAE5C,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,SAAoB,EAAE;IACrD,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;IAE5C,uEAAuE;IACvE,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAC3E,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC;IAC9C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,mFAAmF,IAAI,SAAS,CAAC,CAAC;IAClH,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAC3E,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC;IAC9C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,6EAA6E,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -1,42 +1,21 @@
|
|
|
1
|
-
import { ChildProcess } from 'child_process';
|
|
2
1
|
/**
|
|
3
|
-
* Discovers
|
|
2
|
+
* Discovers VSCXML backend processes running on known ports.
|
|
4
3
|
*
|
|
5
4
|
* Discovery order for each backend:
|
|
6
5
|
* 1. Environment variable (VSCXML_GENERATOR_URL, etc.)
|
|
7
6
|
* 2. MCP config args (--generator, --simulator)
|
|
8
7
|
* 3. Default ports (probe localhost)
|
|
9
|
-
*
|
|
8
|
+
*
|
|
9
|
+
* If a backend is not found, returns null — the user must start it manually.
|
|
10
10
|
*/
|
|
11
11
|
export declare class ProcessManager {
|
|
12
|
-
private children;
|
|
13
12
|
/** Discover the generator URL */
|
|
14
13
|
discoverGenerator(configUrl?: string): Promise<string | null>;
|
|
15
14
|
/** Discover the simulator URL */
|
|
16
15
|
discoverSimulator(configUrl?: string): Promise<string | null>;
|
|
17
16
|
/** Discover the editor URL */
|
|
18
17
|
discoverEditor(configUrl?: string): Promise<string | null>;
|
|
19
|
-
/** Get known install paths for the generator CLI */
|
|
20
|
-
getGeneratorPaths(): string[];
|
|
21
|
-
/** Get known install paths for the simulator */
|
|
22
|
-
getSimulatorPaths(): string[];
|
|
23
|
-
/** Spawn a generator process */
|
|
24
|
-
spawnGenerator(execPath: string, port?: number): ChildProcess;
|
|
25
|
-
/** Spawn a simulator process */
|
|
26
|
-
spawnSimulator(execPath: string, wsPort?: number, restPort?: number): ChildProcess;
|
|
27
|
-
/** Shut down all spawned child processes */
|
|
28
18
|
shutdown(): void;
|
|
29
|
-
/**
|
|
30
|
-
* Auto-discover and optionally spawn the generator backend.
|
|
31
|
-
* Returns the URL if available, null if not.
|
|
32
|
-
*/
|
|
33
|
-
ensureGenerator(configUrl?: string): Promise<string | null>;
|
|
34
|
-
/**
|
|
35
|
-
* Auto-discover and optionally spawn the simulator backend.
|
|
36
|
-
*/
|
|
37
|
-
ensureSimulator(configUrl?: string): Promise<string | null>;
|
|
38
|
-
private waitForHealth;
|
|
39
|
-
private waitForWs;
|
|
40
19
|
private probeHttp;
|
|
41
20
|
private probeWs;
|
|
42
21
|
}
|
package/dist/process-manager.js
CHANGED
|
@@ -1,28 +1,22 @@
|
|
|
1
|
-
import { spawn } from 'child_process';
|
|
2
|
-
import { existsSync } from 'fs';
|
|
3
|
-
import { join } from 'path';
|
|
4
1
|
import { DEFAULT_PORTS } from './types.js';
|
|
5
2
|
/**
|
|
6
|
-
* Discovers
|
|
3
|
+
* Discovers VSCXML backend processes running on known ports.
|
|
7
4
|
*
|
|
8
5
|
* Discovery order for each backend:
|
|
9
6
|
* 1. Environment variable (VSCXML_GENERATOR_URL, etc.)
|
|
10
7
|
* 2. MCP config args (--generator, --simulator)
|
|
11
8
|
* 3. Default ports (probe localhost)
|
|
12
|
-
*
|
|
9
|
+
*
|
|
10
|
+
* If a backend is not found, returns null — the user must start it manually.
|
|
13
11
|
*/
|
|
14
12
|
export class ProcessManager {
|
|
15
|
-
children = [];
|
|
16
13
|
/** Discover the generator URL */
|
|
17
14
|
async discoverGenerator(configUrl) {
|
|
18
|
-
// 1. Env var
|
|
19
15
|
const envUrl = process.env.VSCXML_GENERATOR_URL;
|
|
20
16
|
if (envUrl)
|
|
21
17
|
return envUrl;
|
|
22
|
-
// 2. Config
|
|
23
18
|
if (configUrl)
|
|
24
19
|
return configUrl;
|
|
25
|
-
// 3. Probe default port
|
|
26
20
|
const defaultUrl = `http://localhost:${DEFAULT_PORTS.generator}`;
|
|
27
21
|
if (await this.probeHttp(defaultUrl))
|
|
28
22
|
return defaultUrl;
|
|
@@ -30,14 +24,11 @@ export class ProcessManager {
|
|
|
30
24
|
}
|
|
31
25
|
/** Discover the simulator URL */
|
|
32
26
|
async discoverSimulator(configUrl) {
|
|
33
|
-
// 1. Env var
|
|
34
27
|
const envUrl = process.env.VSCXML_SIMULATOR_URL;
|
|
35
28
|
if (envUrl)
|
|
36
29
|
return envUrl;
|
|
37
|
-
// 2. Config
|
|
38
30
|
if (configUrl)
|
|
39
31
|
return configUrl;
|
|
40
|
-
// 3. Probe default port
|
|
41
32
|
const defaultUrl = `ws://localhost:${DEFAULT_PORTS.simulatorWs}`;
|
|
42
33
|
if (await this.probeWs(defaultUrl))
|
|
43
34
|
return defaultUrl;
|
|
@@ -55,124 +46,8 @@ export class ProcessManager {
|
|
|
55
46
|
return defaultUrl;
|
|
56
47
|
return null;
|
|
57
48
|
}
|
|
58
|
-
/** Get known install paths for the generator CLI */
|
|
59
|
-
getGeneratorPaths() {
|
|
60
|
-
const platform = process.platform;
|
|
61
|
-
const paths = [];
|
|
62
|
-
if (platform === 'win32') {
|
|
63
|
-
const localAppData = process.env.LOCALAPPDATA || '';
|
|
64
|
-
paths.push(join(localAppData, 'VSCXML-Generator-CLI', 'vscxml-generator-cli.exe'));
|
|
65
|
-
}
|
|
66
|
-
else if (platform === 'darwin') {
|
|
67
|
-
paths.push('/Applications/VSCXML-Generator-CLI.app/Contents/MacOS/VSCXML-Generator-CLI');
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
paths.push('/opt/vscxml-generator-cli/bin/vscxml-generator-cli');
|
|
71
|
-
}
|
|
72
|
-
return paths.filter((p) => existsSync(p));
|
|
73
|
-
}
|
|
74
|
-
/** Get known install paths for the simulator */
|
|
75
|
-
getSimulatorPaths() {
|
|
76
|
-
const platform = process.platform;
|
|
77
|
-
const paths = [];
|
|
78
|
-
if (platform === 'win32') {
|
|
79
|
-
const localAppData = process.env.LOCALAPPDATA || '';
|
|
80
|
-
paths.push(join(localAppData, 'VSCXML-Simulator', 'vscxml-simulator.exe'));
|
|
81
|
-
}
|
|
82
|
-
else if (platform === 'darwin') {
|
|
83
|
-
paths.push('/Applications/VSCXML-Simulator.app/Contents/MacOS/VSCXML-Simulator');
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
paths.push('/opt/vscxml-simulator/bin/vscxml-simulator');
|
|
87
|
-
}
|
|
88
|
-
return paths.filter((p) => existsSync(p));
|
|
89
|
-
}
|
|
90
|
-
/** Spawn a generator process */
|
|
91
|
-
spawnGenerator(execPath, port = DEFAULT_PORTS.generator) {
|
|
92
|
-
const child = spawn(execPath, ['serve', '--port', String(port), '--cors'], {
|
|
93
|
-
stdio: 'ignore',
|
|
94
|
-
detached: false,
|
|
95
|
-
});
|
|
96
|
-
this.children.push(child);
|
|
97
|
-
return child;
|
|
98
|
-
}
|
|
99
|
-
/** Spawn a simulator process */
|
|
100
|
-
spawnSimulator(execPath, wsPort = DEFAULT_PORTS.simulatorWs, restPort = DEFAULT_PORTS.simulatorRest) {
|
|
101
|
-
const child = spawn(execPath, ['serve', '--ws-port', String(wsPort), '--rest-port', String(restPort), '--cors'], { stdio: 'ignore', detached: false });
|
|
102
|
-
this.children.push(child);
|
|
103
|
-
return child;
|
|
104
|
-
}
|
|
105
|
-
/** Shut down all spawned child processes */
|
|
106
49
|
shutdown() {
|
|
107
|
-
|
|
108
|
-
try {
|
|
109
|
-
child.kill();
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
// ignore
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
this.children = [];
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Auto-discover and optionally spawn the generator backend.
|
|
119
|
-
* Returns the URL if available, null if not.
|
|
120
|
-
*/
|
|
121
|
-
async ensureGenerator(configUrl) {
|
|
122
|
-
// Try discovery first
|
|
123
|
-
const url = await this.discoverGenerator(configUrl);
|
|
124
|
-
if (url)
|
|
125
|
-
return url;
|
|
126
|
-
// Try auto-spawn
|
|
127
|
-
const paths = this.getGeneratorPaths();
|
|
128
|
-
if (paths.length === 0)
|
|
129
|
-
return null;
|
|
130
|
-
console.error(`[ProcessManager] Generator not found on default port, spawning ${paths[0]}...`);
|
|
131
|
-
this.spawnGenerator(paths[0]);
|
|
132
|
-
// Wait for it to come up (poll health)
|
|
133
|
-
const targetUrl = `http://localhost:${DEFAULT_PORTS.generator}`;
|
|
134
|
-
if (await this.waitForHealth(targetUrl, 15000)) {
|
|
135
|
-
return targetUrl;
|
|
136
|
-
}
|
|
137
|
-
console.error('[ProcessManager] Generator failed to start');
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Auto-discover and optionally spawn the simulator backend.
|
|
142
|
-
*/
|
|
143
|
-
async ensureSimulator(configUrl) {
|
|
144
|
-
const url = await this.discoverSimulator(configUrl);
|
|
145
|
-
if (url)
|
|
146
|
-
return url;
|
|
147
|
-
const paths = this.getSimulatorPaths();
|
|
148
|
-
if (paths.length === 0)
|
|
149
|
-
return null;
|
|
150
|
-
console.error(`[ProcessManager] Simulator not found on default port, spawning ${paths[0]}...`);
|
|
151
|
-
this.spawnSimulator(paths[0]);
|
|
152
|
-
const targetUrl = `ws://localhost:${DEFAULT_PORTS.simulatorWs}`;
|
|
153
|
-
if (await this.waitForWs(targetUrl, 15000)) {
|
|
154
|
-
return targetUrl;
|
|
155
|
-
}
|
|
156
|
-
console.error('[ProcessManager] Simulator failed to start');
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
async waitForHealth(url, timeoutMs) {
|
|
160
|
-
const deadline = Date.now() + timeoutMs;
|
|
161
|
-
while (Date.now() < deadline) {
|
|
162
|
-
if (await this.probeHttp(url))
|
|
163
|
-
return true;
|
|
164
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
165
|
-
}
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
async waitForWs(url, timeoutMs) {
|
|
169
|
-
const deadline = Date.now() + timeoutMs;
|
|
170
|
-
while (Date.now() < deadline) {
|
|
171
|
-
if (await this.probeWs(url))
|
|
172
|
-
return true;
|
|
173
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
174
|
-
}
|
|
175
|
-
return false;
|
|
50
|
+
// No-op: we no longer spawn child processes
|
|
176
51
|
}
|
|
177
52
|
async probeHttp(url) {
|
|
178
53
|
try {
|
|
@@ -186,8 +61,6 @@ export class ProcessManager {
|
|
|
186
61
|
}
|
|
187
62
|
}
|
|
188
63
|
async probeWs(url) {
|
|
189
|
-
// Use a simple TCP connection probe instead of full WS handshake.
|
|
190
|
-
// More reliable on Windows where WS open/close races can cause false negatives.
|
|
191
64
|
const { createConnection } = await import('net');
|
|
192
65
|
const parsed = new URL(url);
|
|
193
66
|
const port = parseInt(parsed.port) || 48621;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../src/process-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../src/process-manager.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vscxml/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "MCP server for the VSCXML suite — 37 tools for designing, simulating, generating, and visually editing W3C SCXML state machines via LLMs (Claude Code, Claude Desktop, Cursor)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|