@skillstate/mcp 2.0.1 → 2.0.3

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.
Files changed (2) hide show
  1. package/README.md +149 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,149 @@
1
+ <div align="center">
2
+
3
+ # @skillstate/mcp
4
+
5
+ **Zero-dependency Model Context Protocol server + adapter for the @skillstate/core runtime.**
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@skillstate/mcp)](https://www.npmjs.com/package/@skillstate/mcp)
8
+ [![node](https://img.shields.io/node/v/@skillstate/mcp)](https://www.npmjs.com/package/@skillstate/mcp)
9
+ [![Tests](https://img.shields.io/badge/tests-755%20passing-brightgreen)](https://github.com/vitkuz573/skillstate)
10
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](https://github.com/vitkuz573/skillstate/blob/main/LICENSE)
11
+
12
+ </div>
13
+
14
+ ---
15
+
16
+ `@skillstate/mcp` exposes the skillstate runtime ([`@skillstate/core`](../core))
17
+ as a **Model Context Protocol** server over stdio (JSON-RPC 2.0). It reuses the
18
+ paper-exact core directly — `mergeState`, `createInitialState`,
19
+ `validatePatchDeep`, `migrate`, `redactSecrets` — so any MCP client can read,
20
+ patch, merge, and reset the execution state as tools.
21
+
22
+ > **@non-paper** — the server is additive; no MCP exists in arXiv 2608.26263v3.
23
+ > Unlike the prompting adapters, MCP is runtime **access**, not prompting, so
24
+ > the O(1) question does not apply.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm i @skillstate/core @skillstate/mcp
30
+ ```
31
+
32
+ Requires Node.js >= 20. TypeScript types are bundled. Ships a `skillstate-mcp`
33
+ bin that launches the server directly.
34
+
35
+ ## Quick start
36
+
37
+ ```ts
38
+ import { McpAdapter, McpServer, launch } from '@skillstate/mcp';
39
+ import { INTERCODE_CTF_SPEC } from '@skillstate/core/schemas';
40
+
41
+ const adapter = new McpAdapter();
42
+
43
+ // .mcp.json config registering the skillstate stdio server:
44
+ const config = adapter.generateMcpConfig('/path/to/.skillstate.json');
45
+ // -> { "mcpServers": { "skillstate": { "command", "args", "env" } } }
46
+
47
+ // Or run an in-process server and drive it line-by-line:
48
+ const server = new McpServer({
49
+ spec: INTERCODE_CTF_SPEC,
50
+ root: '.',
51
+ name: '.skillstate.json',
52
+ });
53
+ const response = server.handleLine(
54
+ JSON.stringify({
55
+ jsonrpc: '2.0', id: 1, method: 'tools/call',
56
+ params: { name: 'state.get', arguments: {} },
57
+ }),
58
+ );
59
+
60
+ // Or launch a stdio server from env / args (SKILLSTATE_SPEC_PATH, SKILLSTATE_STATE_PATH):
61
+ await launch({ statePath: './.skillstate.json', spec: INTERCODE_CTF_SPEC });
62
+ ```
63
+
64
+ Command-line:
65
+
66
+ ```bash
67
+ skillstate-mcp # reads SKILLSTATE_SPEC_PATH / SKILLSTATE_STATE_PATH
68
+ ```
69
+
70
+ ## Register in opencode.jsonc
71
+
72
+ For an OpenCode host, add the stdio server to the `mcp` block of
73
+ `~/.config/opencode/opencode.jsonc` (or the project `opencode.jsonc`). The
74
+ `environment` block feeds `SKILLSTATE_STATE_PATH`, which `launch()` reads:
75
+
76
+ ```jsonc
77
+ {
78
+ "mcp": {
79
+ "skillstate": {
80
+ "type": "local",
81
+ "command": ["node", "/abs/path/to/skillstate/packages/mcp/bin/mcp.js"],
82
+ "enabled": true,
83
+ "environment": {
84
+ "SKILLSTATE_STATE_PATH": "/abs/path/to/.skillstate.json"
85
+ }
86
+ }
87
+ }
88
+ }
89
+ ```
90
+
91
+ If you installed from npm instead of a checkout, replace the command with
92
+ `["npx", "-y", "skillstate-mcp"]` (the packaged bin). Create the state file
93
+ first (see the `@skillstate/opencode` README for a sample). Verify with:
94
+
95
+ ```bash
96
+ opencode debug config # mcp.skillstate appears in the resolved config
97
+ echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"t","version":"0"}}}
98
+ {"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
99
+ | SKILLSTATE_STATE_PATH=/abs/path/to/.skillstate.json node packages/mcp/bin/mcp.js
100
+ # -> serverInfo {"name":"skillstate","version":"1.0.0"} + 6 tools
101
+ ```
102
+
103
+ ## API / Exports
104
+
105
+ Root path `@skillstate/mcp` exports `McpAdapter`, `McpServer`, and `launch`
106
+ (plus the types `McpServerOptions`, `LaunchArgs`, `FrameMode`, `JsonRpcRequest`,
107
+ `McpToolResult`, and `McpConfigOptions`).
108
+
109
+ - `new McpAdapter()` — `name = 'mcp'`.
110
+ - `generateMcpConfig(statePath, options?): string` — a deterministic,
111
+ secret-free `.mcp.json` document (`McpConfigOptions.specPath`, `.command`,
112
+ `.launcherPath`, `.env`).
113
+ - `saveMcpConfig(target, statePath, options?): Promise<string>` — atomic write.
114
+ - `new McpServer(options: McpServerOptions)` — `{ spec, root, name, tracker? }`.
115
+ - `handleLine(line): string | null` — process one already-framed JSON-RPC
116
+ message.
117
+ - `feed(chunk): string[]` — consume streamed stdin, handling both
118
+ newline-delimited JSON-RPC and `Content-Length`-framed messages.
119
+ - `start(input?, output?): Promise<McpServer>` / `stop()` / `get isRunning()`.
120
+ - `launch(args?): Promise<McpServer>` — resolves spec/state from args or
121
+ env and starts a stdio server.
122
+
123
+ **Tools:** `state.get`, `state.patch`, `state.merge` (schema-validated),
124
+ `state.reset`, `spec.get`, `state.metrics`. **Resource:** `skillstate://state`.
125
+ State is redacted on every read, and the server conserves its own buffering so
126
+ transports may split frames mid-message.
127
+
128
+ ## Notes
129
+
130
+ - **Zero dependencies.** `@skillstate/mcp` declares only
131
+ [`@skillstate/core`](../core); it uses Node's `fs`/`path`/`stream` for the
132
+ stdio transport and crash-safe state writes (temp sibling + fsync + rename).
133
+ - Both newline-delimited JSON-RPC and `Content-Length`-framed (LSP-style)
134
+ messages are accepted; responses echo the framing that triggered them.
135
+ - `state.merge` runs `validatePatchDeep` (defense-in-depth) before the ⊕ merge;
136
+ `state.patch` applies the raw ⊕ merge. `redactSecrets` fails closed so
137
+ secrets never leave the process through a tool result.
138
+
139
+ ## Related
140
+
141
+ - Paper: [arXiv:2608.26263](https://arxiv.org/abs/2608.26263).
142
+ - Core runtime: [`@skillstate/core`](../core).
143
+ - [`state.md`](../../state.md) — design notes.
144
+ - Prompting adapters: `@skillstate/claude`, `@skillstate/opencode`,
145
+ `@skillstate/codex`.
146
+
147
+ ## License
148
+
149
+ [MIT](LICENSE) © 2026 Vitaly Kuzyaev
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillstate/mcp",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Zero-dependency MCP server + adapter for the skillstate runtime.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",