@skillstate/mcp 2.0.0

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/bin/mcp.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ // skillstate MCP stdio server shim (ESM) — @skillstate/mcp bin entry.
3
+ import { launch } from '../dist/index.js';
4
+
5
+ await launch();
@@ -0,0 +1,3 @@
1
+ export * from './mcp-adapter.js';
2
+ export * from './mcp-server.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ // @skillstate/mcp — MCP server + adapter.
2
+ export * from './mcp-adapter.js';
3
+ export * from './mcp-server.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { StatePathRef } from '@skillstate/core';
2
+ /** Options for {@link McpAdapter.generateMcpConfig}. */
3
+ export interface McpConfigOptions {
4
+ /** Path to the procedural-spec JSON. Defaults to `./skill-spec.json`. */
5
+ specPath?: string;
6
+ /** Command that starts the server. Defaults to `node`. */
7
+ command?: string;
8
+ /** Absolute launcher module path. Defaults to the package bin entry. */
9
+ launcherPath?: string;
10
+ /** Extra environment variables to merge into the server env. */
11
+ env?: Record<string, string>;
12
+ }
13
+ /**
14
+ * MCP platform adapter (@non-paper; see module doc).
15
+ */
16
+ export declare class McpAdapter {
17
+ readonly name = "mcp";
18
+ /**
19
+ * Generate a `.mcp.json`-compatible config document registering the
20
+ * `skillstate` server. The config is a plain JSON object:
21
+ *
22
+ * ```json
23
+ * {
24
+ * "mcpServers": {
25
+ * "skillstate": {
26
+ * "command": "node",
27
+ * "args": ["/path/to/bin/mcp.js"],
28
+ * "env": { "SKILLSTATE_STATE_PATH": "...", "SKILLSTATE_SPEC_PATH": "..." }
29
+ * }
30
+ * }
31
+ * }
32
+ * ```
33
+ *
34
+ * `statePath` accepts a raw path (legacy) or a `{ root, name }` ref
35
+ * confined via `resolveStatePath`. Deterministic and secret-free.
36
+ */
37
+ generateMcpConfig(statePath: string | StatePathRef, options?: McpConfigOptions): string;
38
+ /**
39
+ * @non-paper additive helper: generate the config and persist it via
40
+ * `atomicWriteFile` (tmp + fsync + rename). Both the destination and the
41
+ * embedded state path accept raw strings (legacy behavior) or
42
+ * `{ root, name }` refs confined by `resolveStatePath`. Returns the
43
+ * absolute destination path.
44
+ */
45
+ saveMcpConfig(target: string | StatePathRef, statePath: string | StatePathRef, options?: McpConfigOptions): Promise<string>;
46
+ /** Resolve a `string | StatePathRef` via `resolveStatePath`. */
47
+ private resolve;
48
+ }
49
+ //# sourceMappingURL=mcp-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-adapter.d.ts","sourceRoot":"","sources":["../src/mcp-adapter.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAarD,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,QAAQ,CAAC,IAAI,SAAS;IAEtB;;;;;;;;;;;;;;;;;;OAkBG;IACH,iBAAiB,CACf,SAAS,EAAE,MAAM,GAAG,YAAY,EAChC,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAuBR;IAED;;;;;;OAMG;IACG,aAAa,CACjB,MAAM,EAAE,MAAM,GAAG,YAAY,EAC7B,SAAS,EAAE,MAAM,GAAG,YAAY,EAChC,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,MAAM,CAAC,CAMjB;IAMD,gEAAgE;IAChE,OAAO,CAAC,OAAO;CAKhB"}
@@ -0,0 +1,80 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ import { atomicWriteFile, resolveStatePath, } from '@skillstate/core';
3
+ /**
4
+ * Default launcher: the umbrella package's MCP stdio entry (`bin/mcp.js`).
5
+ * When installed, `@skillstate/mcp` lives at the same depth as the
6
+ * package's own `dist/` (or `src/`), so `../../../bin/mcp.js` from the
7
+ * compiled module resolves to the root `bin/mcp.js`. Overridable via
8
+ * {@link McpConfigOptions.launcherPath}.
9
+ */
10
+ const LAUNCHER_PATH = fileURLToPath(new URL('../../../bin/mcp.js', import.meta.url));
11
+ /**
12
+ * MCP platform adapter (@non-paper; see module doc).
13
+ */
14
+ export class McpAdapter {
15
+ name = 'mcp';
16
+ /**
17
+ * Generate a `.mcp.json`-compatible config document registering the
18
+ * `skillstate` server. The config is a plain JSON object:
19
+ *
20
+ * ```json
21
+ * {
22
+ * "mcpServers": {
23
+ * "skillstate": {
24
+ * "command": "node",
25
+ * "args": ["/path/to/bin/mcp.js"],
26
+ * "env": { "SKILLSTATE_STATE_PATH": "...", "SKILLSTATE_SPEC_PATH": "..." }
27
+ * }
28
+ * }
29
+ * }
30
+ * ```
31
+ *
32
+ * `statePath` accepts a raw path (legacy) or a `{ root, name }` ref
33
+ * confined via `resolveStatePath`. Deterministic and secret-free.
34
+ */
35
+ generateMcpConfig(statePath, options) {
36
+ const resolved = this.resolve(statePath);
37
+ const specPath = options?.specPath ?? './skill-spec.json';
38
+ const command = options?.command ?? 'node';
39
+ const launcherPath = options?.launcherPath ?? LAUNCHER_PATH;
40
+ const env = {
41
+ SKILLSTATE_STATE_PATH: resolved,
42
+ SKILLSTATE_SPEC_PATH: specPath,
43
+ ...(options?.env ?? {}),
44
+ };
45
+ const doc = {
46
+ mcpServers: {
47
+ skillstate: {
48
+ command,
49
+ args: [launcherPath],
50
+ env,
51
+ },
52
+ },
53
+ };
54
+ return JSON.stringify(doc, null, 2) + '\n';
55
+ }
56
+ /**
57
+ * @non-paper additive helper: generate the config and persist it via
58
+ * `atomicWriteFile` (tmp + fsync + rename). Both the destination and the
59
+ * embedded state path accept raw strings (legacy behavior) or
60
+ * `{ root, name }` refs confined by `resolveStatePath`. Returns the
61
+ * absolute destination path.
62
+ */
63
+ async saveMcpConfig(target, statePath, options) {
64
+ const dest = this.resolve(target);
65
+ const resolved = this.resolve(statePath);
66
+ const config = this.generateMcpConfig(resolved, options);
67
+ await atomicWriteFile(dest, config);
68
+ return dest;
69
+ }
70
+ /* ------------------------------------------------------------------ */
71
+ /* Internal helpers */
72
+ /* ------------------------------------------------------------------ */
73
+ /** Resolve a `string | StatePathRef` via `resolveStatePath`. */
74
+ resolve(target) {
75
+ return typeof target === 'string'
76
+ ? target
77
+ : resolveStatePath(target.root, target.name);
78
+ }
79
+ }
80
+ //# sourceMappingURL=mcp-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-adapter.js","sourceRoot":"","sources":["../src/mcp-adapter.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAG1B;;;;;;GAMG;AACH,MAAM,aAAa,GAAG,aAAa,CACjC,IAAI,GAAG,CAAC,qBAAqB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAChD,CAAC;AAcF;;GAEG;AACH,MAAM,OAAO,UAAU;IACZ,IAAI,GAAG,KAAK,CAAC;IAEtB;;;;;;;;;;;;;;;;;;OAkBG;IACH,iBAAiB,CACf,SAAgC,EAChC,OAA0B;QAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,mBAAmB,CAAC;QAC1D,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC;QAC3C,MAAM,YAAY,GAAG,OAAO,EAAE,YAAY,IAAI,aAAa,CAAC;QAE5D,MAAM,GAAG,GAA2B;YAClC,qBAAqB,EAAE,QAAQ;YAC/B,oBAAoB,EAAE,QAAQ;YAC9B,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;SACxB,CAAC;QAEF,MAAM,GAAG,GAAG;YACV,UAAU,EAAE;gBACV,UAAU,EAAE;oBACV,OAAO;oBACP,IAAI,EAAE,CAAC,YAAY,CAAC;oBACpB,GAAG;iBACJ;aACF;SACF,CAAC;QAEF,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAC7C,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,aAAa,CACjB,MAA6B,EAC7B,SAAgC,EAChC,OAA0B;QAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzD,MAAM,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wEAAwE;IACxE,yEAAyE;IACzE,wEAAwE;IAExE,gEAAgE;IACxD,OAAO,CAAC,MAA6B;QAC3C,OAAO,OAAO,MAAM,KAAK,QAAQ;YAC/B,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;CACF"}
@@ -0,0 +1,132 @@
1
+ import type { Readable, Writable } from 'node:stream';
2
+ import type { ProceduralSpec } from '@skillstate/core';
3
+ import type { TokenTracker } from '@skillstate/core';
4
+ /** MCP stdio framing modes the server can speak. */
5
+ export type FrameMode = 'jsonl' | 'content-length';
6
+ /** A JSON-RPC request object (id may be a number, string, or null). */
7
+ export interface JsonRpcRequest {
8
+ jsonrpc?: string;
9
+ id?: number | string | null;
10
+ method?: unknown;
11
+ params?: unknown;
12
+ }
13
+ /** The MCP tool-result payload returned on `tools/call`. */
14
+ export interface McpToolResult {
15
+ content: Array<{
16
+ type: 'text';
17
+ text: string;
18
+ }>;
19
+ isError?: boolean;
20
+ }
21
+ /** Options for {@link McpServer}. */
22
+ export interface McpServerOptions {
23
+ /** Procedural spec: drives `spec.get`, schema validation, and reset defaults. */
24
+ spec: ProceduralSpec;
25
+ /** State file root directory (confined by `resolveStatePath`). */
26
+ root: string;
27
+ /** State file name (confined by `resolveStatePath`). */
28
+ name: string;
29
+ /** Optional token tracker for the `state.metrics` tool. */
30
+ tracker?: TokenTracker;
31
+ }
32
+ /** Options for {@link launch} (mirrors `McpServerOptions` + env fallbacks). */
33
+ export interface LaunchArgs {
34
+ spec?: ProceduralSpec;
35
+ specPath?: string;
36
+ statePath?: string;
37
+ root?: string;
38
+ name?: string;
39
+ tracker?: TokenTracker;
40
+ input?: Readable;
41
+ output?: Writable;
42
+ }
43
+ /**
44
+ * The `skillstate` MCP server: a JSON-RPC 2.0 over stdio server exposing
45
+ * the skillstate runtime as MCP tools.
46
+ */
47
+ export declare class McpServer {
48
+ private readonly options;
49
+ /** Protocol version advertised by the server on `initialize`. */
50
+ readonly protocolVersion = "2024-11-05";
51
+ /** Advertised server capabilities (a minimal subset). */
52
+ readonly capabilities: {
53
+ tools: {
54
+ listChanged: boolean;
55
+ };
56
+ };
57
+ /** Advertised server identity. */
58
+ readonly serverInfo: {
59
+ name: string;
60
+ version: string;
61
+ };
62
+ private buffer;
63
+ private running;
64
+ private frameMode;
65
+ constructor(options: McpServerOptions);
66
+ /**
67
+ * Process a single (already-framed) JSON-RPC message line and return the
68
+ * response string, or `null` when the message needs no reply (a
69
+ * notification). This is the stateless unit entry point used by the
70
+ * stdio transport; `feed` drives it for framed/streamed input.
71
+ */
72
+ handleLine(line: string): string | null;
73
+ /**
74
+ * Feed a raw chunk of stdin and return every response produced by the
75
+ * complete messages it contains. Handles BOTH newline-delimited JSON-RPC
76
+ * and `Content-Length`-framed messages; partial frames are buffered until
77
+ * the rest arrives. Responses are framed like the message that triggered
78
+ * them.
79
+ */
80
+ feed(chunk: string): string[];
81
+ /**
82
+ * Attach the server to a stdin/stdout pair (defaults to `process`).
83
+ * Resolves once the server is reading; `stop()` detaches it. The server
84
+ * conserves its own buffered state, so real transports may hand over
85
+ * chunks that split mid-frame.
86
+ */
87
+ start(input?: Readable, output?: Writable): Promise<McpServer>;
88
+ /** Mark the server stopped (idempotent). */
89
+ stop(): void;
90
+ /** Whether the server is currently reading from its input stream. */
91
+ get isRunning(): boolean;
92
+ /** Parse raw text into a message and dispatch; `-32700` on parse error. */
93
+ private processRaw;
94
+ private processMessage;
95
+ private handleRequest;
96
+ private handleToolCall;
97
+ private callTool;
98
+ private stateGet;
99
+ private statePatch;
100
+ private stateMerge;
101
+ private stateReset;
102
+ private specGet;
103
+ private stateMetrics;
104
+ /** Resolve the target state file path (args override the defaults). */
105
+ private resolveStore;
106
+ /** Read + normalize the state, falling back to schema defaults. */
107
+ private loadState;
108
+ /** Crash-safe synchronous write: temp sibling + fsync + rename. */
109
+ private writeState;
110
+ private toolsList;
111
+ private resourcesList;
112
+ /**
113
+ * Parse a `Content-Length`-framed message from the front of the buffer
114
+ * (the caller has already asserted the buffer begins with a valid
115
+ * `Content-Length:` header). Returns the body + consumed length, or
116
+ * `'incomplete'` if the payload has not all arrived.
117
+ */
118
+ private takeContentLengthFrame;
119
+ /** Encode a response in the given framing mode. */
120
+ private encodeResponse;
121
+ private successResponse;
122
+ private errorResponse;
123
+ private textResult;
124
+ }
125
+ /**
126
+ * Launch an MCP server from an argument/env config (reads
127
+ * `SKILLSTATE_SPEC_PATH` and `SKILLSTATE_STATE_PATH` when not passed
128
+ * explicitly). Defaults to the canonical InterCode CTF spec and
129
+ * `.skillstate.json`.
130
+ */
131
+ export declare function launch(args?: LaunchArgs): Promise<McpServer>;
132
+ //# sourceMappingURL=mcp-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,485 @@
1
+ /**
2
+ * @non-paper MCP server — no MCP exists in arXiv 2608.26263v3.
3
+ *
4
+ * A zero-dependency Model Context Protocol server over stdio (JSON-RPC
5
+ * 2.0) that exposes the skillstate runtime as MCP tools. It reuses the
6
+ * paper-exact core directly:
7
+ *
8
+ * - `mergeState` (⊕ null-deletion merge, §3.2) and `createInitialState`;
9
+ * - `validatePatchDeep` (stricter defense-in-depth validation, @non-paper);
10
+ * - `resolveStatePath` (confines `{ root, name }` — traversal throws);
11
+ * - `migrate` (normalizes bare/v0/v1 persisted state);
12
+ * - `redactSecrets` (fail-closed scrubber so secrets never leave the
13
+ * process via a tool result).
14
+ *
15
+ * TRANSPORT: accepts both official MCP stdio newline-delimited JSON-RPC
16
+ * AND `Content-Length`-framed messages (LSP-style). Responses echo the
17
+ * framing of the message that triggered them. State persistence uses a
18
+ * synchronous temp-sibling + fsync + rename so a mid-write crash can never
19
+ * produce a truncated state file.
20
+ */
21
+ import * as fs from 'node:fs';
22
+ import * as path from 'node:path';
23
+ import { resolveStatePath } from '@skillstate/core';
24
+ import { mergeState, createInitialState } from '@skillstate/core';
25
+ import { validatePatchDeep } from '@skillstate/core';
26
+ import { migrate } from '@skillstate/core';
27
+ import { redactSecrets } from '@skillstate/core';
28
+ import { INTERCODE_CTF_SPEC } from '@skillstate/core/schemas';
29
+ /**
30
+ * The `skillstate` MCP server: a JSON-RPC 2.0 over stdio server exposing
31
+ * the skillstate runtime as MCP tools.
32
+ */
33
+ export class McpServer {
34
+ options;
35
+ /** Protocol version advertised by the server on `initialize`. */
36
+ protocolVersion = '2024-11-05';
37
+ /** Advertised server capabilities (a minimal subset). */
38
+ capabilities = { tools: { listChanged: false } };
39
+ /** Advertised server identity. */
40
+ serverInfo = { name: 'skillstate', version: '1.0.0' };
41
+ buffer = '';
42
+ running = false;
43
+ frameMode = 'jsonl';
44
+ constructor(options) {
45
+ this.options = options;
46
+ }
47
+ /**
48
+ * Process a single (already-framed) JSON-RPC message line and return the
49
+ * response string, or `null` when the message needs no reply (a
50
+ * notification). This is the stateless unit entry point used by the
51
+ * stdio transport; `feed` drives it for framed/streamed input.
52
+ */
53
+ handleLine(line) {
54
+ const text = line.trim();
55
+ if (text.length === 0) {
56
+ return null;
57
+ }
58
+ return this.processRaw(text);
59
+ }
60
+ /**
61
+ * Feed a raw chunk of stdin and return every response produced by the
62
+ * complete messages it contains. Handles BOTH newline-delimited JSON-RPC
63
+ * and `Content-Length`-framed messages; partial frames are buffered until
64
+ * the rest arrives. Responses are framed like the message that triggered
65
+ * them.
66
+ */
67
+ feed(chunk) {
68
+ this.buffer += chunk;
69
+ const responses = [];
70
+ while (this.buffer.length > 0) {
71
+ this.buffer = this.buffer.replace(/^(\r?\n)+/, '');
72
+ if (this.buffer.length === 0) {
73
+ break;
74
+ }
75
+ if (/^Content-Length:\s*\d+/i.test(this.buffer)) {
76
+ const framed = this.takeContentLengthFrame();
77
+ if (framed === 'incomplete') {
78
+ break;
79
+ }
80
+ this.frameMode = 'content-length';
81
+ const response = this.processRaw(framed.body);
82
+ if (response !== null) {
83
+ responses.push(this.encodeResponse(response, this.frameMode));
84
+ }
85
+ this.buffer = this.buffer.slice(framed.consumed);
86
+ continue;
87
+ }
88
+ const newline = this.buffer.indexOf('\n');
89
+ if (newline === -1) {
90
+ break;
91
+ }
92
+ const line = this.buffer.slice(0, newline).trim();
93
+ this.buffer = this.buffer.slice(newline + 1);
94
+ if (line.length === 0) {
95
+ continue;
96
+ }
97
+ this.frameMode = 'jsonl';
98
+ const response = this.processRaw(line);
99
+ if (response !== null) {
100
+ responses.push(this.encodeResponse(response, this.frameMode));
101
+ }
102
+ }
103
+ return responses;
104
+ }
105
+ /**
106
+ * Attach the server to a stdin/stdout pair (defaults to `process`).
107
+ * Resolves once the server is reading; `stop()` detaches it. The server
108
+ * conserves its own buffered state, so real transports may hand over
109
+ * chunks that split mid-frame.
110
+ */
111
+ async start(input, output) {
112
+ const source = input ?? process.stdin;
113
+ const sink = output ?? process.stdout;
114
+ this.running = true;
115
+ source.on('data', (chunk) => {
116
+ const text = typeof chunk === 'string' ? chunk : chunk.toString();
117
+ for (const response of this.feed(text)) {
118
+ sink.write(response);
119
+ }
120
+ });
121
+ return this;
122
+ }
123
+ /** Mark the server stopped (idempotent). */
124
+ stop() {
125
+ this.running = false;
126
+ }
127
+ /** Whether the server is currently reading from its input stream. */
128
+ get isRunning() {
129
+ return this.running;
130
+ }
131
+ /* ------------------------------------------------------------------ */
132
+ /* JSON-RPC dispatch */
133
+ /* ------------------------------------------------------------------ */
134
+ /** Parse raw text into a message and dispatch; `-32700` on parse error. */
135
+ processRaw(text) {
136
+ let message;
137
+ try {
138
+ message = JSON.parse(text);
139
+ }
140
+ catch {
141
+ return this.errorResponse(null, -32700, 'Parse error');
142
+ }
143
+ return this.processMessage(message);
144
+ }
145
+ processMessage(message) {
146
+ if (typeof message !== 'object' || message === null || Array.isArray(message)) {
147
+ return this.errorResponse(null, -32600, 'Invalid Request');
148
+ }
149
+ const msg = message;
150
+ const id = 'id' in msg ? msg.id ?? null : null;
151
+ const method = msg.method;
152
+ const hasId = 'id' in msg;
153
+ if (typeof method === 'string' && method.startsWith('notifications/')) {
154
+ if (hasId) {
155
+ return this.errorResponse(id, -32600, 'Invalid Request: notifications must not include an id');
156
+ }
157
+ return null;
158
+ }
159
+ if (typeof method !== 'string' || method.length === 0) {
160
+ return this.errorResponse(id, -32600, 'Invalid Request');
161
+ }
162
+ if (!hasId) {
163
+ return null;
164
+ }
165
+ return this.handleRequest(id, method, msg.params);
166
+ }
167
+ handleRequest(id, method, params) {
168
+ switch (method) {
169
+ case 'initialize':
170
+ return this.successResponse(id, {
171
+ protocolVersion: this.protocolVersion,
172
+ capabilities: this.capabilities,
173
+ serverInfo: this.serverInfo,
174
+ });
175
+ case 'ping':
176
+ return this.successResponse(id, {});
177
+ case 'tools/list':
178
+ return this.successResponse(id, { tools: this.toolsList() });
179
+ case 'tools/call':
180
+ return this.handleToolCall(id, params);
181
+ case 'resources/list':
182
+ return this.successResponse(id, { resources: this.resourcesList() });
183
+ default:
184
+ return this.errorResponse(id, -32601, `Method not found: ${method}`);
185
+ }
186
+ }
187
+ handleToolCall(id, params) {
188
+ if (!isPlainObject(params)) {
189
+ return this.errorResponse(id, -32602, 'Invalid params: expected an object');
190
+ }
191
+ const name = params.name;
192
+ if (typeof name !== 'string' || name.length === 0) {
193
+ return this.errorResponse(id, -32602, 'Invalid params: name required');
194
+ }
195
+ const args = params.arguments;
196
+ const argsObj = isPlainObject(args) ? args : {};
197
+ try {
198
+ const result = this.callTool(name, argsObj);
199
+ return this.successResponse(id, result);
200
+ }
201
+ catch (err) {
202
+ const message = String(err);
203
+ return this.successResponse(id, {
204
+ content: [{ type: 'text', text: message }],
205
+ isError: true,
206
+ });
207
+ }
208
+ }
209
+ /* ------------------------------------------------------------------ */
210
+ /* Tool implementations */
211
+ /* ------------------------------------------------------------------ */
212
+ callTool(name, args) {
213
+ switch (name) {
214
+ case 'state.get':
215
+ return this.stateGet(args);
216
+ case 'state.patch':
217
+ return this.statePatch(args);
218
+ case 'state.merge':
219
+ return this.stateMerge(args);
220
+ case 'state.reset':
221
+ return this.stateReset(args);
222
+ case 'spec.get':
223
+ return this.specGet();
224
+ case 'state.metrics':
225
+ return this.stateMetrics();
226
+ default:
227
+ throw new Error(`Unknown tool: ${name}`);
228
+ }
229
+ }
230
+ stateGet(args) {
231
+ const filePath = this.resolveStore(args);
232
+ const state = this.loadState(filePath);
233
+ return this.textResult(redactSecrets(JSON.stringify(state)));
234
+ }
235
+ statePatch(args) {
236
+ const patch = args.patch;
237
+ if (!isPlainObject(patch)) {
238
+ throw new Error('patch must be an object');
239
+ }
240
+ const filePath = this.resolveStore(args);
241
+ const merged = mergeState(this.loadState(filePath), patch);
242
+ this.writeState(filePath, merged);
243
+ return this.textResult(redactSecrets(JSON.stringify(merged)));
244
+ }
245
+ stateMerge(args) {
246
+ const patch = args.patch;
247
+ if (!isPlainObject(patch)) {
248
+ throw new Error('patch must be an object');
249
+ }
250
+ const validation = validatePatchDeep(this.options.spec.schema, patch);
251
+ if (!validation.valid) {
252
+ throw new Error(validation.error);
253
+ }
254
+ const filePath = this.resolveStore(args);
255
+ const merged = mergeState(this.loadState(filePath), patch);
256
+ this.writeState(filePath, merged);
257
+ return this.textResult(redactSecrets(JSON.stringify(merged)));
258
+ }
259
+ stateReset(args) {
260
+ const filePath = this.resolveStore(args);
261
+ const initial = createInitialState(this.options.spec.schema);
262
+ this.writeState(filePath, initial);
263
+ return this.textResult(redactSecrets(JSON.stringify(initial)));
264
+ }
265
+ specGet() {
266
+ const spec = this.options.spec;
267
+ return this.textResult(redactSecrets(JSON.stringify({
268
+ id: spec.id,
269
+ name: spec.name,
270
+ version: spec.version,
271
+ instructions: spec.instructions,
272
+ schema: spec.schema,
273
+ })));
274
+ }
275
+ stateMetrics() {
276
+ const tracker = this.options.tracker;
277
+ if (!tracker) {
278
+ throw new Error('No token tracker configured');
279
+ }
280
+ const metrics = {
281
+ ...tracker.getMetrics(),
282
+ ...tracker.getBookkeeping(),
283
+ };
284
+ return this.textResult(redactSecrets(JSON.stringify(metrics)));
285
+ }
286
+ /* ------------------------------------------------------------------ */
287
+ /* State helpers */
288
+ /* ------------------------------------------------------------------ */
289
+ /** Resolve the target state file path (args override the defaults). */
290
+ resolveStore(args) {
291
+ const root = typeof args.root === 'string' ? args.root : this.options.root;
292
+ const name = typeof args.name === 'string' ? args.name : this.options.name;
293
+ return resolveStatePath(root, name);
294
+ }
295
+ /** Read + normalize the state, falling back to schema defaults. */
296
+ loadState(filePath) {
297
+ try {
298
+ const raw = fs.readFileSync(filePath, 'utf-8');
299
+ return migrate(JSON.parse(raw)).state;
300
+ }
301
+ catch {
302
+ return createInitialState(this.options.spec.schema);
303
+ }
304
+ }
305
+ /** Crash-safe synchronous write: temp sibling + fsync + rename. */
306
+ writeState(filePath, state) {
307
+ const dir = path.dirname(filePath);
308
+ fs.mkdirSync(dir, { recursive: true });
309
+ const tmp = `${filePath}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`;
310
+ const fd = fs.openSync(tmp, 'w');
311
+ try {
312
+ fs.writeSync(fd, JSON.stringify(state, null, 2));
313
+ fs.fsyncSync(fd);
314
+ }
315
+ finally {
316
+ fs.closeSync(fd);
317
+ }
318
+ fs.renameSync(tmp, filePath);
319
+ }
320
+ /* ------------------------------------------------------------------ */
321
+ /* Tool / resource schemas */
322
+ /* ------------------------------------------------------------------ */
323
+ toolsList() {
324
+ const stringProp = (desc) => ({
325
+ type: 'string',
326
+ description: desc,
327
+ });
328
+ return [
329
+ {
330
+ name: 'state.get',
331
+ description: 'Read the current skill state (secrets redacted).',
332
+ inputSchema: {
333
+ type: 'object',
334
+ properties: { name: stringProp('Optional alternate state file name.') },
335
+ },
336
+ },
337
+ {
338
+ name: 'state.patch',
339
+ description: 'Apply a sparse patch (null deletes a key) to the state and persist it.',
340
+ inputSchema: {
341
+ type: 'object',
342
+ properties: {
343
+ patch: { type: 'object' },
344
+ root: stringProp('Optional state root directory.'),
345
+ name: stringProp('Optional state file name.'),
346
+ },
347
+ required: ['patch'],
348
+ },
349
+ },
350
+ {
351
+ name: 'state.merge',
352
+ description: 'Schema-validated patch: validate then apply the ⊕ merge and persist.',
353
+ inputSchema: {
354
+ type: 'object',
355
+ properties: {
356
+ patch: { type: 'object' },
357
+ root: stringProp('Optional state root directory.'),
358
+ name: stringProp('Optional state file name.'),
359
+ },
360
+ required: ['patch'],
361
+ },
362
+ },
363
+ {
364
+ name: 'state.reset',
365
+ description: 'Reset the state to the schema defaults.',
366
+ inputSchema: {
367
+ type: 'object',
368
+ properties: { name: stringProp('Optional alternate state file name.') },
369
+ },
370
+ },
371
+ {
372
+ name: 'spec.get',
373
+ description: 'Return the procedural spec (id, name, version, schema).',
374
+ inputSchema: { type: 'object' },
375
+ },
376
+ {
377
+ name: 'state.metrics',
378
+ description: 'Return the paper §4.3 metrics readout from the token tracker.',
379
+ inputSchema: { type: 'object' },
380
+ },
381
+ ];
382
+ }
383
+ resourcesList() {
384
+ return [
385
+ {
386
+ uri: 'skillstate://state',
387
+ name: 'Skill State',
388
+ mimeType: 'application/json',
389
+ },
390
+ ];
391
+ }
392
+ /* ------------------------------------------------------------------ */
393
+ /* Frame codec */
394
+ /* ------------------------------------------------------------------ */
395
+ /**
396
+ * Parse a `Content-Length`-framed message from the front of the buffer
397
+ * (the caller has already asserted the buffer begins with a valid
398
+ * `Content-Length:` header). Returns the body + consumed length, or
399
+ * `'incomplete'` if the payload has not all arrived.
400
+ */
401
+ takeContentLengthFrame() {
402
+ const match = this.buffer.match(/^Content-Length:\s*(\d+)/i);
403
+ const crlf = this.buffer.indexOf('\r\n\r\n');
404
+ let headerEnd;
405
+ if (crlf !== -1) {
406
+ headerEnd = crlf + 4;
407
+ }
408
+ else {
409
+ const lf = this.buffer.indexOf('\n\n');
410
+ if (lf === -1) {
411
+ return 'incomplete';
412
+ }
413
+ headerEnd = lf + 2;
414
+ }
415
+ const length = Number(match[1]);
416
+ if (this.buffer.length - headerEnd < length) {
417
+ return 'incomplete';
418
+ }
419
+ return {
420
+ body: this.buffer.slice(headerEnd, headerEnd + length),
421
+ consumed: headerEnd + length,
422
+ };
423
+ }
424
+ /** Encode a response in the given framing mode. */
425
+ encodeResponse(text, mode) {
426
+ if (mode === 'content-length') {
427
+ return `Content-Length: ${Buffer.byteLength(text, 'utf-8')}\r\n\r\n${text}`;
428
+ }
429
+ return `${text}\n`;
430
+ }
431
+ /* ------------------------------------------------------------------ */
432
+ /* JSON-RPC response builders */
433
+ /* ------------------------------------------------------------------ */
434
+ successResponse(id, result) {
435
+ return JSON.stringify({ jsonrpc: '2.0', id, result });
436
+ }
437
+ errorResponse(id, code, message) {
438
+ return JSON.stringify({
439
+ jsonrpc: '2.0',
440
+ id,
441
+ error: { code, message },
442
+ });
443
+ }
444
+ textResult(text) {
445
+ return { content: [{ type: 'text', text }] };
446
+ }
447
+ }
448
+ function isPlainObject(value) {
449
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
450
+ }
451
+ /**
452
+ * Resolve the procedural spec for a launch: explicit `args.spec` wins, then
453
+ * a `SKILLSTATE_SPEC_PATH`/`args.specPath` JSON file, else the canonical
454
+ * InterCode CTF spec. Pure w.r.t. the returned value.
455
+ */
456
+ function resolveSpec(args, env) {
457
+ if (args?.spec) {
458
+ return args.spec;
459
+ }
460
+ const specPath = args?.specPath ?? env['SKILLSTATE_SPEC_PATH'];
461
+ if (typeof specPath === 'string' && specPath.length > 0) {
462
+ return JSON.parse(fs.readFileSync(specPath, 'utf-8'));
463
+ }
464
+ return INTERCODE_CTF_SPEC;
465
+ }
466
+ /**
467
+ * Launch an MCP server from an argument/env config (reads
468
+ * `SKILLSTATE_SPEC_PATH` and `SKILLSTATE_STATE_PATH` when not passed
469
+ * explicitly). Defaults to the canonical InterCode CTF spec and
470
+ * `.skillstate.json`.
471
+ */
472
+ export async function launch(args) {
473
+ const spec = resolveSpec(args, process.env);
474
+ const statePath = args?.statePath ?? process.env['SKILLSTATE_STATE_PATH'];
475
+ const root = args?.root ?? (statePath ? path.dirname(statePath) : '.');
476
+ const name = args?.name ?? (statePath ? path.basename(statePath) : '.skillstate.json');
477
+ const server = new McpServer({
478
+ spec,
479
+ root,
480
+ name,
481
+ tracker: args?.tracker,
482
+ });
483
+ return server.start(args?.input, args?.output);
484
+ }
485
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@skillstate/mcp",
3
+ "version": "2.0.0",
4
+ "description": "Zero-dependency MCP server + adapter for the skillstate runtime.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "skillstate-mcp": "bin/mcp.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "./package.json": "./package.json"
17
+ },
18
+ "files": ["dist", "bin"],
19
+ "sideEffects": false,
20
+ "engines": {
21
+ "node": ">=20"
22
+ },
23
+ "license": "MIT",
24
+ "dependencies": {
25
+ "@skillstate/core": "^2.0.0"
26
+ }
27
+ }