@statelyai/mcp 0.1.0 → 0.1.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/LICENSE +10 -0
- package/README.md +409 -39
- package/package.json +7 -7
- package/dist/index.cjs +0 -483
- package/dist/index.d.cts +0 -72
- package/dist/index.d.mts +0 -72
- package/dist/index.mjs +0 -472
package/LICENSE
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Copyright (c) 2025 Stately Software, Inc.
|
|
2
|
+
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
This repository and the Stately Viz software are proprietary to Stately
|
|
6
|
+
Software, Inc. No rights are granted to use, copy, modify, distribute, host, or
|
|
7
|
+
sublicense this software except under a separate written agreement with Stately
|
|
8
|
+
Software, Inc.
|
|
9
|
+
|
|
10
|
+
For licensing inquiries, contact team@stately.ai.
|
package/README.md
CHANGED
|
@@ -1,58 +1,428 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Stately MCP
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use Stately's machine tools from an MCP-compatible agent.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Connect
|
|
6
6
|
|
|
7
|
-
<!--
|
|
7
|
+
<!-- public Stately MCP URL -->
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
import { createStatelyMcpServer } from '@statelyai/mcp';
|
|
9
|
+
Choose your client and add Stately MCP using one of these methods.
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
### Codex
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
codex mcp add stately --url https://stately.ai/mcp
|
|
15
|
+
codex mcp login stately
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Claude Code
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
claude mcp add --transport http stately https://stately.ai/mcp
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Then open Claude Code, run `/mcp`, and complete Stately sign-in.
|
|
25
|
+
|
|
26
|
+
### Cursor
|
|
27
|
+
|
|
28
|
+
Open **Cursor Settings → MCP → Add new global MCP server**, then add:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mcpServers": {
|
|
33
|
+
"stately": {
|
|
34
|
+
"url": "https://stately.ai/mcp"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Save the configuration and complete Stately sign-in when Cursor connects. To
|
|
41
|
+
share the server with a project, put the same configuration in
|
|
42
|
+
`.cursor/mcp.json` at the project root.
|
|
43
|
+
|
|
44
|
+
### VS Code with GitHub Copilot
|
|
45
|
+
|
|
46
|
+
Create `.vscode/mcp.json` in your project:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"servers": {
|
|
51
|
+
"stately": {
|
|
52
|
+
"type": "http",
|
|
53
|
+
"url": "https://stately.ai/mcp"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Open the Command Palette and run **MCP: List Servers**, start `stately`, then
|
|
60
|
+
complete Stately sign-in. For a personal configuration available in every
|
|
61
|
+
workspace, run **MCP: Open User Configuration** instead.
|
|
62
|
+
|
|
63
|
+
### Other MCP clients
|
|
64
|
+
|
|
65
|
+
Add a remote server using the Streamable HTTP transport and this URL:
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
https://stately.ai/mcp
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Complete Stately sign-in when the client connects.
|
|
72
|
+
|
|
73
|
+
## Machine input
|
|
74
|
+
|
|
75
|
+
<!-- shared machine input schemas from src/server.ts -->
|
|
76
|
+
|
|
77
|
+
Most tools accept a machine config object or a source document. Conversion
|
|
78
|
+
supports XState, SCXML, XGraph, and D2. Validation also supports JSON, YAML, and
|
|
79
|
+
Mermaid.
|
|
80
|
+
|
|
81
|
+
## `validate_machine`
|
|
82
|
+
|
|
83
|
+
<!-- validate_machine registration from src/server.ts and validate response contract -->
|
|
84
|
+
|
|
85
|
+
Checks whether a machine can be parsed and reports structural issues such as
|
|
86
|
+
unreachable states. A successful response contains `ok` and an `issues` array.
|
|
87
|
+
|
|
88
|
+
<details>
|
|
89
|
+
<summary>Summary: validate a machine</summary>
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
Use Stately to validate this machine:
|
|
93
|
+
|
|
94
|
+
createMachine({
|
|
95
|
+
id: 'player',
|
|
96
|
+
initial: 'paused',
|
|
97
|
+
states: {
|
|
98
|
+
paused: { on: { PLAY: 'playing' } },
|
|
99
|
+
playing: { on: { PAUSE: 'paused', STOP: 'stopped' } },
|
|
100
|
+
stopped: { type: 'final' }
|
|
101
|
+
}
|
|
20
102
|
});
|
|
21
103
|
```
|
|
22
104
|
|
|
23
|
-
|
|
24
|
-
package owns MCP tool schemas, handlers, annotations, and calls to the Stately
|
|
25
|
-
HTTP API. Use `authMode: 'none'` only when the API is protected elsewhere.
|
|
105
|
+
</details>
|
|
26
106
|
|
|
27
|
-
##
|
|
107
|
+
## `convert_machine`
|
|
28
108
|
|
|
29
|
-
<!--
|
|
109
|
+
<!-- convert_machine registration from src/server.ts and convert response contract -->
|
|
30
110
|
|
|
31
|
-
|
|
32
|
-
|
|
111
|
+
Converts a machine between XState, SCXML, XGraph, and D2. The response contains
|
|
112
|
+
the target `format`, converted `content`, and any `warnings`.
|
|
113
|
+
|
|
114
|
+
<details>
|
|
115
|
+
<summary>Summary: convert XState to SCXML</summary>
|
|
116
|
+
|
|
117
|
+
```text
|
|
118
|
+
Use Stately to convert this machine to SCXML:
|
|
119
|
+
|
|
120
|
+
createMachine({
|
|
121
|
+
id: 'player',
|
|
122
|
+
initial: 'paused',
|
|
123
|
+
states: {
|
|
124
|
+
paused: { on: { PLAY: 'playing' } },
|
|
125
|
+
playing: { on: { STOP: 'stopped' } },
|
|
126
|
+
stopped: { type: 'final' }
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
</details>
|
|
132
|
+
|
|
133
|
+
<details>
|
|
134
|
+
<summary>Summary: convert SCXML to XState</summary>
|
|
135
|
+
|
|
136
|
+
```text
|
|
137
|
+
Use Stately to convert this SCXML machine to XState:
|
|
138
|
+
|
|
139
|
+
<scxml xmlns="http://www.w3.org/2005/07/scxml" name="player" initial="paused">
|
|
140
|
+
<state id="paused">
|
|
141
|
+
<transition event="PLAY" target="playing" />
|
|
142
|
+
</state>
|
|
143
|
+
<state id="playing">
|
|
144
|
+
<transition event="STOP" target="stopped" />
|
|
145
|
+
</state>
|
|
146
|
+
<final id="stopped" />
|
|
147
|
+
</scxml>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
</details>
|
|
151
|
+
|
|
152
|
+
<details>
|
|
153
|
+
<summary>Summary: convert XState to D2</summary>
|
|
154
|
+
|
|
155
|
+
```text
|
|
156
|
+
Use Stately to convert this machine to D2:
|
|
157
|
+
|
|
158
|
+
createMachine({
|
|
159
|
+
id: 'player',
|
|
160
|
+
initial: 'paused',
|
|
161
|
+
states: {
|
|
162
|
+
paused: { on: { PLAY: 'playing' } },
|
|
163
|
+
playing: { on: { STOP: 'stopped' } },
|
|
164
|
+
stopped: { type: 'final' }
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
</details>
|
|
170
|
+
|
|
171
|
+
<details>
|
|
172
|
+
<summary>Summary: convert XState to XGraph</summary>
|
|
173
|
+
|
|
174
|
+
```text
|
|
175
|
+
Use Stately to convert this machine to XGraph:
|
|
176
|
+
|
|
177
|
+
createMachine({
|
|
178
|
+
id: 'player',
|
|
179
|
+
initial: 'paused',
|
|
180
|
+
states: {
|
|
181
|
+
paused: { on: { PLAY: 'playing' } },
|
|
182
|
+
playing: { on: { STOP: 'stopped' } },
|
|
183
|
+
stopped: { type: 'final' }
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
</details>
|
|
189
|
+
|
|
190
|
+
## `diff_machines`
|
|
191
|
+
|
|
192
|
+
<!-- diff_machines registration from src/server.ts and diff response contract -->
|
|
193
|
+
|
|
194
|
+
Compares two machine documents structurally instead of comparing their source
|
|
195
|
+
text. It returns a summary and semantic diff; set `includePatches` to request
|
|
196
|
+
applicable patches.
|
|
197
|
+
|
|
198
|
+
<details>
|
|
199
|
+
<summary>Summary: compare two machine versions</summary>
|
|
200
|
+
|
|
201
|
+
```text
|
|
202
|
+
Use Stately to compare these two versions of a machine and suggest patches:
|
|
203
|
+
|
|
204
|
+
Before:
|
|
205
|
+
createMachine({
|
|
206
|
+
id: 'player',
|
|
207
|
+
initial: 'paused',
|
|
208
|
+
states: {
|
|
209
|
+
paused: { on: { PLAY: 'playing' } },
|
|
210
|
+
playing: {}
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
After:
|
|
215
|
+
createMachine({
|
|
216
|
+
id: 'player',
|
|
217
|
+
initial: 'paused',
|
|
218
|
+
states: {
|
|
219
|
+
paused: { on: { PLAY: 'playing' } },
|
|
220
|
+
playing: { on: { STOP: 'stopped' } },
|
|
221
|
+
stopped: { type: 'final' }
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
</details>
|
|
227
|
+
|
|
228
|
+
## `apply_machine_patches`
|
|
229
|
+
|
|
230
|
+
<!-- apply_machine_patches registration from src/server.ts and apply-patches response contract -->
|
|
231
|
+
|
|
232
|
+
Applies semantic patches to a machine and returns the updated document. Use
|
|
233
|
+
`to` to choose the returned format.
|
|
234
|
+
|
|
235
|
+
<details>
|
|
236
|
+
<summary>Summary: update a machine</summary>
|
|
237
|
+
|
|
238
|
+
```text
|
|
239
|
+
Use Stately to rename the playing state to active and return the updated XState machine:
|
|
240
|
+
|
|
241
|
+
createMachine({
|
|
242
|
+
id: 'player',
|
|
243
|
+
initial: 'paused',
|
|
244
|
+
states: {
|
|
245
|
+
paused: { on: { PLAY: 'playing' } },
|
|
246
|
+
playing: {}
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
</details>
|
|
252
|
+
|
|
253
|
+
## `generate_graph_paths`
|
|
254
|
+
|
|
255
|
+
<!-- generate_graph_paths registration from src/server.ts and graph-paths response contract -->
|
|
256
|
+
|
|
257
|
+
Generates shortest or simple paths through a machine. The response includes
|
|
258
|
+
the event steps for each path plus state and transition coverage. Stately MCP
|
|
259
|
+
returns at most five paths per call.
|
|
260
|
+
|
|
261
|
+
<details>
|
|
262
|
+
<summary>Summary: generate shortest paths</summary>
|
|
263
|
+
|
|
264
|
+
```text
|
|
265
|
+
Use Stately to find up to five shortest paths through this machine:
|
|
266
|
+
|
|
267
|
+
createMachine({
|
|
268
|
+
id: 'player',
|
|
269
|
+
initial: 'paused',
|
|
270
|
+
states: {
|
|
271
|
+
paused: { on: { PLAY: 'playing' } },
|
|
272
|
+
playing: { on: { PAUSE: 'paused', STOP: 'stopped' } },
|
|
273
|
+
stopped: { type: 'final' }
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
</details>
|
|
279
|
+
|
|
280
|
+
## `simulate_machine`
|
|
281
|
+
|
|
282
|
+
<!-- simulate_machine registration from src/server.ts and simulate response contract -->
|
|
283
|
+
|
|
284
|
+
Runs up to 100 events through a machine and returns a step-by-step trace of
|
|
285
|
+
states, context, and executed action names. Guards are stubbed during this
|
|
286
|
+
deterministic simulation.
|
|
287
|
+
|
|
288
|
+
<details>
|
|
289
|
+
<summary>Summary: simulate events</summary>
|
|
290
|
+
|
|
291
|
+
```text
|
|
292
|
+
Use Stately to simulate PLAY followed by STOP on this machine:
|
|
293
|
+
|
|
294
|
+
createMachine({
|
|
295
|
+
id: 'player',
|
|
296
|
+
initial: 'paused',
|
|
297
|
+
states: {
|
|
298
|
+
paused: { on: { PLAY: 'playing' } },
|
|
299
|
+
playing: { on: { STOP: 'stopped' } },
|
|
300
|
+
stopped: { type: 'final' }
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
</details>
|
|
306
|
+
|
|
307
|
+
## `visualize_machine`
|
|
308
|
+
|
|
309
|
+
<!-- visualize_machine registration from src/server.ts and visualize response contract -->
|
|
310
|
+
|
|
311
|
+
Renders a machine as an SVG diagram. The response contains the SVG string,
|
|
312
|
+
its width and height, and any warnings.
|
|
313
|
+
|
|
314
|
+
<details>
|
|
315
|
+
<summary>Summary: visualize a machine</summary>
|
|
316
|
+
|
|
317
|
+
```text
|
|
318
|
+
Use Stately to visualize this machine from left to right:
|
|
319
|
+
|
|
320
|
+
createMachine({
|
|
321
|
+
id: 'player',
|
|
322
|
+
initial: 'paused',
|
|
323
|
+
states: {
|
|
324
|
+
paused: { on: { PLAY: 'playing' } },
|
|
325
|
+
playing: { on: { STOP: 'stopped' } },
|
|
326
|
+
stopped: { type: 'final' }
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
</details>
|
|
332
|
+
|
|
333
|
+
## `analyze_machine`
|
|
334
|
+
|
|
335
|
+
<!-- analyze_machine registration from src/server.ts and analyze response contract -->
|
|
336
|
+
|
|
337
|
+
Combines deterministic checks with AI review. Provide optional intent to assess
|
|
338
|
+
the machine against its expected behavior. The response contains issues and may
|
|
339
|
+
include suggested fixes. Use `validate_machine` when only deterministic checks
|
|
340
|
+
are needed.
|
|
341
|
+
|
|
342
|
+
<details>
|
|
343
|
+
<summary>Summary: analyze intended behavior</summary>
|
|
344
|
+
|
|
345
|
+
```text
|
|
346
|
+
Use Stately to check that STOP reaches a final state and playback cannot restart:
|
|
347
|
+
|
|
348
|
+
createMachine({
|
|
349
|
+
id: 'player',
|
|
350
|
+
initial: 'paused',
|
|
351
|
+
states: {
|
|
352
|
+
paused: { on: { PLAY: 'playing' } },
|
|
353
|
+
playing: { on: { STOP: 'stopped' } },
|
|
354
|
+
stopped: { type: 'final' }
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
</details>
|
|
360
|
+
|
|
361
|
+
## `generate_test_code`
|
|
362
|
+
|
|
363
|
+
<!-- generate_test_code registration and generateTestCode implementation from src/server.ts -->
|
|
364
|
+
|
|
365
|
+
Generates a runnable Vitest file with one test per generated path. Each test
|
|
366
|
+
sends the path's events and asserts its final state. Guards and actions are
|
|
367
|
+
stubbed.
|
|
368
|
+
|
|
369
|
+
<details>
|
|
370
|
+
<summary>Summary: generate Vitest tests</summary>
|
|
371
|
+
|
|
372
|
+
```text
|
|
373
|
+
Use Stately to generate Vitest tests for the shortest paths through this machine:
|
|
374
|
+
|
|
375
|
+
createMachine({
|
|
376
|
+
id: 'player',
|
|
377
|
+
initial: 'paused',
|
|
378
|
+
states: {
|
|
379
|
+
paused: { on: { PLAY: 'playing' } },
|
|
380
|
+
playing: { on: { STOP: 'stopped' } },
|
|
381
|
+
stopped: { type: 'final' }
|
|
382
|
+
}
|
|
383
|
+
});
|
|
33
384
|
```
|
|
34
385
|
|
|
35
|
-
|
|
386
|
+
</details>
|
|
387
|
+
|
|
388
|
+
## `extract_machines_from_code`
|
|
389
|
+
|
|
390
|
+
<!-- extract_machines_from_code registration from src/server.ts -->
|
|
391
|
+
|
|
392
|
+
Parses XState source code and returns the extracted machine as an XGraph
|
|
393
|
+
document.
|
|
394
|
+
|
|
395
|
+
<details>
|
|
396
|
+
<summary>Summary: extract a machine from TypeScript</summary>
|
|
397
|
+
|
|
398
|
+
```text
|
|
399
|
+
Use Stately to extract the machine from this TypeScript:
|
|
400
|
+
|
|
401
|
+
import { createMachine } from 'xstate';
|
|
402
|
+
|
|
403
|
+
export const player = createMachine({
|
|
404
|
+
id: 'player',
|
|
405
|
+
initial: 'paused',
|
|
406
|
+
states: {
|
|
407
|
+
paused: { on: { PLAY: 'playing' } },
|
|
408
|
+
playing: { on: { STOP: 'stopped' } },
|
|
409
|
+
stopped: { type: 'final' }
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
```
|
|
36
413
|
|
|
37
|
-
|
|
38
|
-
- `get_machine`
|
|
414
|
+
</details>
|
|
39
415
|
|
|
40
|
-
|
|
41
|
-
|
|
416
|
+
All Stately MCP tools are registered as read-only, non-destructive, idempotent,
|
|
417
|
+
and closed-world.
|
|
42
418
|
|
|
43
|
-
##
|
|
419
|
+
## Self-hosting
|
|
44
420
|
|
|
45
|
-
<!--
|
|
421
|
+
<!-- self-host MCP endpoint from ../editor/src/app/api/[transport]/route.ts and ../editor/src/lib/auth/oauthProtectedResource.ts -->
|
|
46
422
|
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
- `apply_machine_patches`
|
|
51
|
-
- `generate_graph_paths`
|
|
52
|
-
- `simulate_machine`
|
|
53
|
-
- `visualize_machine`
|
|
54
|
-
- `analyze_machine`
|
|
55
|
-
- `generate_test_code`
|
|
56
|
-
- `extract_machines_from_code`
|
|
423
|
+
Self-host Stately Studio, then replace the hosted URL above with your
|
|
424
|
+
deployment's `/api/mcp` endpoint, for example
|
|
425
|
+
`https://studio.example.com/api/mcp`.
|
|
57
426
|
|
|
58
|
-
|
|
427
|
+
For enterprise self-hosting options, [see pricing and contact
|
|
428
|
+
us](https://stately.ai/pricing).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statelyai/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -19,11 +19,6 @@
|
|
|
19
19
|
"require": "./dist/index.cjs"
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
|
-
"scripts": {
|
|
23
|
-
"build": "tsdown",
|
|
24
|
-
"test": "vitest run",
|
|
25
|
-
"test:watch": "vitest"
|
|
26
|
-
},
|
|
27
22
|
"dependencies": {
|
|
28
23
|
"@modelcontextprotocol/sdk": "1.26.0",
|
|
29
24
|
"zod": "^4.4.1"
|
|
@@ -32,5 +27,10 @@
|
|
|
32
27
|
"@types/node": "25.2.1",
|
|
33
28
|
"tsdown": "0.21.0-beta.2",
|
|
34
29
|
"vitest": "^3.2.4"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsdown",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"test:watch": "vitest"
|
|
35
35
|
}
|
|
36
|
-
}
|
|
36
|
+
}
|