@shardworks/claude-code-apparatus 0.1.101
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 +15 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +384 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +61 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +135 -0
- package/dist/mcp-server.js.map +1 -0
- package/package.json +36 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sean Boots
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Session Provider
|
|
3
|
+
*
|
|
4
|
+
* Apparatus plugin that implements AnimatorSessionProvider for the
|
|
5
|
+
* Claude Code CLI. The Animator discovers this via guild config:
|
|
6
|
+
*
|
|
7
|
+
* guild.json["animator"]["sessionProvider"] = "claude-code"
|
|
8
|
+
*
|
|
9
|
+
* Launches sessions via the `claude` CLI in autonomous mode (--print)
|
|
10
|
+
* with --output-format stream-json for structured telemetry.
|
|
11
|
+
*
|
|
12
|
+
* Key design choice: uses async spawn() instead of spawnSync().
|
|
13
|
+
* This is required for stream-json transcript parsing, timeout enforcement,
|
|
14
|
+
* and future concurrent session support.
|
|
15
|
+
*/
|
|
16
|
+
import type { Plugin } from '@shardworks/nexus-core';
|
|
17
|
+
import type { SessionChunk } from '@shardworks/animator-apparatus';
|
|
18
|
+
/**
|
|
19
|
+
* Create the Claude Code session provider apparatus.
|
|
20
|
+
*
|
|
21
|
+
* The apparatus has no startup logic — it just provides the
|
|
22
|
+
* AnimatorSessionProvider implementation. The Animator looks it up
|
|
23
|
+
* via guild().apparatus('claude-code').
|
|
24
|
+
*/
|
|
25
|
+
export declare function createClaudeCodeProvider(): Plugin;
|
|
26
|
+
declare const _default: Plugin;
|
|
27
|
+
export default _default;
|
|
28
|
+
export { createMcpServer, startMcpHttpServer } from './mcp-server.ts';
|
|
29
|
+
export type { McpHttpHandle } from './mcp-server.ts';
|
|
30
|
+
/** Parsed result from stream-json output. @internal */
|
|
31
|
+
export interface StreamJsonResult {
|
|
32
|
+
exitCode: number;
|
|
33
|
+
transcript: Record<string, unknown>[];
|
|
34
|
+
costUsd?: number;
|
|
35
|
+
tokenUsage?: {
|
|
36
|
+
inputTokens: number;
|
|
37
|
+
outputTokens: number;
|
|
38
|
+
cacheReadTokens?: number;
|
|
39
|
+
cacheWriteTokens?: number;
|
|
40
|
+
};
|
|
41
|
+
providerSessionId?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Parse a single NDJSON message from stream-json output.
|
|
45
|
+
*
|
|
46
|
+
* Returns parsed chunks for streaming and accumulates data into the
|
|
47
|
+
* provided accumulators (transcript, metrics).
|
|
48
|
+
*
|
|
49
|
+
* @internal Exported for testing only.
|
|
50
|
+
*/
|
|
51
|
+
export declare function parseStreamJsonMessage(msg: Record<string, unknown>, acc: {
|
|
52
|
+
transcript: Record<string, unknown>[];
|
|
53
|
+
costUsd?: number;
|
|
54
|
+
tokenUsage?: StreamJsonResult['tokenUsage'];
|
|
55
|
+
providerSessionId?: string;
|
|
56
|
+
}): SessionChunk[];
|
|
57
|
+
/**
|
|
58
|
+
* Process NDJSON buffer, calling handler for each complete line.
|
|
59
|
+
* Returns the remaining incomplete buffer.
|
|
60
|
+
*
|
|
61
|
+
* @internal Exported for testing only.
|
|
62
|
+
*/
|
|
63
|
+
export declare function processNdjsonBuffer(buffer: string, handler: (msg: Record<string, unknown>) => void): string;
|
|
64
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAIV,YAAY,EACb,MAAM,gCAAgC,CAAC;AAwLxC;;;;;;GAMG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAWjD;;AAED,wBAA0C;AAO1C,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACtE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIrD,uDAAuD;AACvD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,GAAG,EAAE;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC5C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GACA,YAAY,EAAE,CAiDhB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAC9C,MAAM,CAgBR"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Session Provider
|
|
3
|
+
*
|
|
4
|
+
* Apparatus plugin that implements AnimatorSessionProvider for the
|
|
5
|
+
* Claude Code CLI. The Animator discovers this via guild config:
|
|
6
|
+
*
|
|
7
|
+
* guild.json["animator"]["sessionProvider"] = "claude-code"
|
|
8
|
+
*
|
|
9
|
+
* Launches sessions via the `claude` CLI in autonomous mode (--print)
|
|
10
|
+
* with --output-format stream-json for structured telemetry.
|
|
11
|
+
*
|
|
12
|
+
* Key design choice: uses async spawn() instead of spawnSync().
|
|
13
|
+
* This is required for stream-json transcript parsing, timeout enforcement,
|
|
14
|
+
* and future concurrent session support.
|
|
15
|
+
*/
|
|
16
|
+
import { spawn } from 'node:child_process';
|
|
17
|
+
import fs from 'node:fs';
|
|
18
|
+
import os from 'node:os';
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
import { startMcpHttpServer } from "./mcp-server.js";
|
|
21
|
+
/**
|
|
22
|
+
* Prepare session files and build base CLI args.
|
|
23
|
+
*
|
|
24
|
+
* Writes system prompt to a temp directory. Builds the base args array
|
|
25
|
+
* including --resume support. When tools are provided, starts an
|
|
26
|
+
* in-process MCP HTTP server and writes --mcp-config.
|
|
27
|
+
*
|
|
28
|
+
* Caller is responsible for cleaning up tmpDir and calling mcpHandle.close().
|
|
29
|
+
*/
|
|
30
|
+
async function prepareSession(config) {
|
|
31
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'nsg-session-'));
|
|
32
|
+
const args = [
|
|
33
|
+
'--setting-sources', 'user',
|
|
34
|
+
'--dangerously-skip-permissions',
|
|
35
|
+
'--model', config.model,
|
|
36
|
+
];
|
|
37
|
+
if (config.systemPrompt) {
|
|
38
|
+
const systemPromptPath = path.join(tmpDir, 'system-prompt.md');
|
|
39
|
+
fs.writeFileSync(systemPromptPath, config.systemPrompt);
|
|
40
|
+
args.push('--system-prompt-file', systemPromptPath);
|
|
41
|
+
}
|
|
42
|
+
// Resume an existing conversation
|
|
43
|
+
if (config.conversationId) {
|
|
44
|
+
args.push('--resume', config.conversationId);
|
|
45
|
+
}
|
|
46
|
+
// Tool-equipped session: start MCP HTTP server, write --mcp-config
|
|
47
|
+
let mcpHandle;
|
|
48
|
+
if (config.tools && config.tools.length > 0) {
|
|
49
|
+
const tools = config.tools.map((rt) => rt.definition);
|
|
50
|
+
mcpHandle = await startMcpHttpServer(tools);
|
|
51
|
+
const mcpConfig = {
|
|
52
|
+
mcpServers: {
|
|
53
|
+
'nexus-guild': {
|
|
54
|
+
type: 'sse',
|
|
55
|
+
url: mcpHandle.url,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
const mcpConfigPath = path.join(tmpDir, 'mcp-config.json');
|
|
60
|
+
fs.writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig));
|
|
61
|
+
args.push('--mcp-config', mcpConfigPath, '--strict-mcp-config');
|
|
62
|
+
}
|
|
63
|
+
return { tmpDir, args, mcpHandle };
|
|
64
|
+
}
|
|
65
|
+
// ── Result builder ──────────────────────────────────────────────────
|
|
66
|
+
function buildResult(raw) {
|
|
67
|
+
const status = raw.exitCode === 0 ? 'completed' : 'failed';
|
|
68
|
+
return {
|
|
69
|
+
status,
|
|
70
|
+
exitCode: raw.exitCode,
|
|
71
|
+
error: status === 'failed' ? `claude exited with code ${raw.exitCode}` : undefined,
|
|
72
|
+
costUsd: raw.costUsd,
|
|
73
|
+
tokenUsage: raw.tokenUsage,
|
|
74
|
+
providerSessionId: raw.providerSessionId,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// ── Provider implementation ──────────────────────────────────────────
|
|
78
|
+
const provider = {
|
|
79
|
+
name: 'claude-code',
|
|
80
|
+
launch(config) {
|
|
81
|
+
// prepareSession is async (MCP server start), so we wrap the launch
|
|
82
|
+
// in a promise. The chunks iterable bridges the async gap — it waits
|
|
83
|
+
// for prep to complete before yielding.
|
|
84
|
+
let chunkResolve = null;
|
|
85
|
+
let innerChunks = null;
|
|
86
|
+
let innerIterator = null;
|
|
87
|
+
let prepDone = false;
|
|
88
|
+
let prepError = null;
|
|
89
|
+
let done = false;
|
|
90
|
+
const result = prepareSession(config).then(async ({ tmpDir, args, mcpHandle }) => {
|
|
91
|
+
// Autonomous mode: initial prompt via --print, stream-json for telemetry
|
|
92
|
+
args.push('--print', config.initialPrompt ?? '', '--output-format', 'stream-json', '--verbose');
|
|
93
|
+
const cleanup = async () => {
|
|
94
|
+
await mcpHandle?.close().catch(() => { });
|
|
95
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
96
|
+
};
|
|
97
|
+
try {
|
|
98
|
+
if (config.streaming) {
|
|
99
|
+
const spawned = spawnClaudeStreamingJson(args, config.cwd);
|
|
100
|
+
innerChunks = spawned.chunks;
|
|
101
|
+
prepDone = true;
|
|
102
|
+
if (chunkResolve) {
|
|
103
|
+
chunkResolve();
|
|
104
|
+
chunkResolve = null;
|
|
105
|
+
}
|
|
106
|
+
const raw = await spawned.result;
|
|
107
|
+
await cleanup();
|
|
108
|
+
return buildResult(raw);
|
|
109
|
+
}
|
|
110
|
+
// Non-streaming
|
|
111
|
+
prepDone = true;
|
|
112
|
+
done = true;
|
|
113
|
+
if (chunkResolve) {
|
|
114
|
+
chunkResolve();
|
|
115
|
+
chunkResolve = null;
|
|
116
|
+
}
|
|
117
|
+
const raw = await spawnClaudeStreamJson(args, config.cwd);
|
|
118
|
+
await cleanup();
|
|
119
|
+
return buildResult(raw);
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
await cleanup();
|
|
123
|
+
throw err;
|
|
124
|
+
}
|
|
125
|
+
}).catch((err) => {
|
|
126
|
+
// If prep itself failed, unblock the chunk iterator
|
|
127
|
+
prepError = err instanceof Error ? err : new Error(String(err));
|
|
128
|
+
prepDone = true;
|
|
129
|
+
done = true;
|
|
130
|
+
if (chunkResolve) {
|
|
131
|
+
chunkResolve();
|
|
132
|
+
chunkResolve = null;
|
|
133
|
+
}
|
|
134
|
+
throw err;
|
|
135
|
+
});
|
|
136
|
+
// Chunks iterable that bridges the async prep gap. In non-streaming
|
|
137
|
+
// mode or on error, it completes immediately with no items.
|
|
138
|
+
const chunks = {
|
|
139
|
+
[Symbol.asyncIterator]() {
|
|
140
|
+
return {
|
|
141
|
+
async next() {
|
|
142
|
+
// Wait for prep to complete
|
|
143
|
+
while (!prepDone) {
|
|
144
|
+
await new Promise((resolve) => { chunkResolve = resolve; });
|
|
145
|
+
}
|
|
146
|
+
if (prepError || done) {
|
|
147
|
+
return { value: undefined, done: true };
|
|
148
|
+
}
|
|
149
|
+
// Delegate to inner streaming iterator
|
|
150
|
+
if (innerChunks && !innerIterator) {
|
|
151
|
+
innerIterator = innerChunks[Symbol.asyncIterator]();
|
|
152
|
+
}
|
|
153
|
+
if (innerIterator) {
|
|
154
|
+
return innerIterator.next();
|
|
155
|
+
}
|
|
156
|
+
return { value: undefined, done: true };
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
return { chunks, result };
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
// ── Apparatus export ─────────────────────────────────────────────────
|
|
165
|
+
/**
|
|
166
|
+
* Create the Claude Code session provider apparatus.
|
|
167
|
+
*
|
|
168
|
+
* The apparatus has no startup logic — it just provides the
|
|
169
|
+
* AnimatorSessionProvider implementation. The Animator looks it up
|
|
170
|
+
* via guild().apparatus('claude-code').
|
|
171
|
+
*/
|
|
172
|
+
export function createClaudeCodeProvider() {
|
|
173
|
+
return {
|
|
174
|
+
apparatus: {
|
|
175
|
+
requires: [],
|
|
176
|
+
provides: provider,
|
|
177
|
+
start() {
|
|
178
|
+
// No startup work — the provider is stateless.
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
export default createClaudeCodeProvider();
|
|
184
|
+
// ── MCP server re-exports ───────────────────────────────────────────
|
|
185
|
+
// The MCP server module is used by the session provider to attach tools
|
|
186
|
+
// to sessions via --mcp-config, and can be imported directly for
|
|
187
|
+
// testing or custom integrations.
|
|
188
|
+
export { createMcpServer, startMcpHttpServer } from "./mcp-server.js";
|
|
189
|
+
/**
|
|
190
|
+
* Parse a single NDJSON message from stream-json output.
|
|
191
|
+
*
|
|
192
|
+
* Returns parsed chunks for streaming and accumulates data into the
|
|
193
|
+
* provided accumulators (transcript, metrics).
|
|
194
|
+
*
|
|
195
|
+
* @internal Exported for testing only.
|
|
196
|
+
*/
|
|
197
|
+
export function parseStreamJsonMessage(msg, acc) {
|
|
198
|
+
const chunks = [];
|
|
199
|
+
if (msg.type === 'assistant') {
|
|
200
|
+
acc.transcript.push(msg);
|
|
201
|
+
const message = msg.message;
|
|
202
|
+
if (message) {
|
|
203
|
+
const content = message.content;
|
|
204
|
+
if (content) {
|
|
205
|
+
for (const block of content) {
|
|
206
|
+
if (block.type === 'text' && typeof block.text === 'string') {
|
|
207
|
+
process.stderr.write(block.text);
|
|
208
|
+
chunks.push({ type: 'text', text: block.text });
|
|
209
|
+
}
|
|
210
|
+
else if (block.type === 'tool_use' && typeof block.name === 'string') {
|
|
211
|
+
chunks.push({ type: 'tool_use', tool: block.name });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else if (msg.type === 'user') {
|
|
218
|
+
acc.transcript.push(msg);
|
|
219
|
+
const content = msg.content;
|
|
220
|
+
if (content) {
|
|
221
|
+
for (const block of content) {
|
|
222
|
+
if (block.type === 'tool_result' && typeof block.tool_use_id === 'string') {
|
|
223
|
+
chunks.push({ type: 'tool_result', tool: String(block.tool_use_id) });
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else if (msg.type === 'result') {
|
|
229
|
+
acc.costUsd = typeof msg.total_cost_usd === 'number' ? msg.total_cost_usd : undefined;
|
|
230
|
+
acc.providerSessionId = typeof msg.session_id === 'string' ? msg.session_id : undefined;
|
|
231
|
+
const usage = msg.usage;
|
|
232
|
+
if (usage) {
|
|
233
|
+
acc.tokenUsage = {
|
|
234
|
+
inputTokens: (typeof usage.input_tokens === 'number' ? usage.input_tokens : 0),
|
|
235
|
+
outputTokens: (typeof usage.output_tokens === 'number' ? usage.output_tokens : 0),
|
|
236
|
+
cacheReadTokens: typeof usage.cache_read_input_tokens === 'number'
|
|
237
|
+
? usage.cache_read_input_tokens : undefined,
|
|
238
|
+
cacheWriteTokens: typeof usage.cache_creation_input_tokens === 'number'
|
|
239
|
+
? usage.cache_creation_input_tokens : undefined,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return chunks;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Process NDJSON buffer, calling handler for each complete line.
|
|
247
|
+
* Returns the remaining incomplete buffer.
|
|
248
|
+
*
|
|
249
|
+
* @internal Exported for testing only.
|
|
250
|
+
*/
|
|
251
|
+
export function processNdjsonBuffer(buffer, handler) {
|
|
252
|
+
let newlineIdx;
|
|
253
|
+
while ((newlineIdx = buffer.indexOf('\n')) !== -1) {
|
|
254
|
+
const line = buffer.slice(0, newlineIdx).trim();
|
|
255
|
+
buffer = buffer.slice(newlineIdx + 1);
|
|
256
|
+
if (!line)
|
|
257
|
+
continue;
|
|
258
|
+
try {
|
|
259
|
+
const msg = JSON.parse(line);
|
|
260
|
+
handler(msg);
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
// Non-JSON line — ignore
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return buffer;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Spawn Claude in autonomous mode with --output-format stream-json.
|
|
270
|
+
*
|
|
271
|
+
* Captures stdout (NDJSON lines), parses each line to extract:
|
|
272
|
+
* - assistant messages → transcript
|
|
273
|
+
* - result message → cost, token usage, session ID
|
|
274
|
+
*
|
|
275
|
+
* Forwards assistant text content to stderr so it's visible during execution.
|
|
276
|
+
*/
|
|
277
|
+
function spawnClaudeStreamJson(args, cwd) {
|
|
278
|
+
return new Promise((resolve, reject) => {
|
|
279
|
+
const proc = spawn('claude', args, {
|
|
280
|
+
cwd,
|
|
281
|
+
stdio: ['pipe', 'pipe', 'inherit'],
|
|
282
|
+
});
|
|
283
|
+
const acc = { transcript: [] };
|
|
284
|
+
let buffer = '';
|
|
285
|
+
proc.stdout.on('data', (chunk) => {
|
|
286
|
+
buffer += chunk.toString();
|
|
287
|
+
buffer = processNdjsonBuffer(buffer, (msg) => {
|
|
288
|
+
parseStreamJsonMessage(msg, acc);
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
proc.on('error', (err) => {
|
|
292
|
+
reject(new Error(`Failed to spawn claude: ${err.message}`));
|
|
293
|
+
});
|
|
294
|
+
proc.on('close', (code) => {
|
|
295
|
+
if (acc.transcript.length > 0) {
|
|
296
|
+
process.stderr.write('\n');
|
|
297
|
+
}
|
|
298
|
+
resolve({
|
|
299
|
+
exitCode: code ?? 1,
|
|
300
|
+
transcript: acc.transcript,
|
|
301
|
+
costUsd: acc.costUsd,
|
|
302
|
+
tokenUsage: acc.tokenUsage,
|
|
303
|
+
providerSessionId: acc.providerSessionId,
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Spawn Claude with streaming — yields SessionChunks as they arrive
|
|
310
|
+
* while also accumulating the full result.
|
|
311
|
+
*
|
|
312
|
+
* Returns an async iterable of chunks for real-time consumption and
|
|
313
|
+
* a promise for the final StreamJsonResult.
|
|
314
|
+
*/
|
|
315
|
+
function spawnClaudeStreamingJson(args, cwd) {
|
|
316
|
+
const chunkQueue = [];
|
|
317
|
+
let chunkResolve = null;
|
|
318
|
+
let done = false;
|
|
319
|
+
const acc = { transcript: [] };
|
|
320
|
+
const proc = spawn('claude', args, {
|
|
321
|
+
cwd,
|
|
322
|
+
stdio: ['pipe', 'pipe', 'inherit'],
|
|
323
|
+
});
|
|
324
|
+
let buffer = '';
|
|
325
|
+
proc.stdout.on('data', (chunk) => {
|
|
326
|
+
buffer += chunk.toString();
|
|
327
|
+
buffer = processNdjsonBuffer(buffer, (msg) => {
|
|
328
|
+
const newChunks = parseStreamJsonMessage(msg, acc);
|
|
329
|
+
if (newChunks.length > 0) {
|
|
330
|
+
chunkQueue.push(...newChunks);
|
|
331
|
+
if (chunkResolve) {
|
|
332
|
+
chunkResolve();
|
|
333
|
+
chunkResolve = null;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
const result = new Promise((resolve, reject) => {
|
|
339
|
+
proc.on('error', (err) => {
|
|
340
|
+
done = true;
|
|
341
|
+
if (chunkResolve) {
|
|
342
|
+
chunkResolve();
|
|
343
|
+
chunkResolve = null;
|
|
344
|
+
}
|
|
345
|
+
reject(new Error(`Failed to spawn claude: ${err.message}`));
|
|
346
|
+
});
|
|
347
|
+
proc.on('close', (code) => {
|
|
348
|
+
if (acc.transcript.length > 0) {
|
|
349
|
+
process.stderr.write('\n');
|
|
350
|
+
}
|
|
351
|
+
done = true;
|
|
352
|
+
if (chunkResolve) {
|
|
353
|
+
chunkResolve();
|
|
354
|
+
chunkResolve = null;
|
|
355
|
+
}
|
|
356
|
+
resolve({
|
|
357
|
+
exitCode: code ?? 1,
|
|
358
|
+
transcript: acc.transcript,
|
|
359
|
+
costUsd: acc.costUsd,
|
|
360
|
+
tokenUsage: acc.tokenUsage,
|
|
361
|
+
providerSessionId: acc.providerSessionId,
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
const chunks = {
|
|
366
|
+
[Symbol.asyncIterator]() {
|
|
367
|
+
return {
|
|
368
|
+
async next() {
|
|
369
|
+
while (true) {
|
|
370
|
+
if (chunkQueue.length > 0) {
|
|
371
|
+
return { value: chunkQueue.shift(), done: false };
|
|
372
|
+
}
|
|
373
|
+
if (done) {
|
|
374
|
+
return { value: undefined, done: true };
|
|
375
|
+
}
|
|
376
|
+
await new Promise((resolve) => { chunkResolve = resolve; });
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
};
|
|
380
|
+
},
|
|
381
|
+
};
|
|
382
|
+
return { chunks, result };
|
|
383
|
+
}
|
|
384
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool Server — serves guild tools as typed MCP tools during anima sessions.
|
|
3
|
+
*
|
|
4
|
+
* Two entry points:
|
|
5
|
+
*
|
|
6
|
+
* 1. **`createMcpServer(tools)`** — library function. Takes an array of
|
|
7
|
+
* ToolDefinitions (already resolved by the Instrumentarium) and returns
|
|
8
|
+
* a configured McpServer.
|
|
9
|
+
*
|
|
10
|
+
* 2. **`startMcpHttpServer(tools)`** — starts an in-process HTTP server
|
|
11
|
+
* serving the MCP tool set via Streamable HTTP on an ephemeral localhost
|
|
12
|
+
* port. Returns a handle with the URL (for --mcp-config) and a close()
|
|
13
|
+
* function for cleanup.
|
|
14
|
+
*
|
|
15
|
+
* The MCP server is one-per-session. The claude-code provider owns the
|
|
16
|
+
* lifecycle — starts before the Claude process, stops after it exits.
|
|
17
|
+
*
|
|
18
|
+
* See: docs/architecture/apparatus/claude-code.md
|
|
19
|
+
*/
|
|
20
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
21
|
+
import type { ToolDefinition } from '@shardworks/tools-apparatus';
|
|
22
|
+
/**
|
|
23
|
+
* Handle returned by startMcpHttpServer().
|
|
24
|
+
*
|
|
25
|
+
* Provides the URL for --mcp-config and a close() function for cleanup.
|
|
26
|
+
*/
|
|
27
|
+
export interface McpHttpHandle {
|
|
28
|
+
/** URL for --mcp-config (e.g. "http://127.0.0.1:PORT/mcp"). */
|
|
29
|
+
url: string;
|
|
30
|
+
/** Shut down the HTTP server and MCP transport. */
|
|
31
|
+
close(): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create and configure an MCP server with the given tools.
|
|
35
|
+
*
|
|
36
|
+
* Each tool's Zod param schema is registered directly with the MCP SDK
|
|
37
|
+
* (which handles JSON Schema conversion). The handler is wrapped to
|
|
38
|
+
* validate params via Zod and format the result as MCP tool output.
|
|
39
|
+
*
|
|
40
|
+
* Tools with `callableBy` set that does not include `'anima'` are
|
|
41
|
+
* filtered out. Tools without `callableBy` are included (available
|
|
42
|
+
* to all callers by default).
|
|
43
|
+
*/
|
|
44
|
+
export declare function createMcpServer(tools: ToolDefinition[]): Promise<McpServer>;
|
|
45
|
+
/**
|
|
46
|
+
* Start an in-process HTTP server serving the MCP tool set via SSE.
|
|
47
|
+
*
|
|
48
|
+
* Uses the MCP SDK's SSE transport: the client GETs /sse to establish
|
|
49
|
+
* the event stream, then POSTs messages to /message. Claude Code's
|
|
50
|
+
* --mcp-config expects `type: "sse"` for HTTP-based MCP servers.
|
|
51
|
+
*
|
|
52
|
+
* The server binds to 127.0.0.1 only — not network-accessible.
|
|
53
|
+
*
|
|
54
|
+
* Returns a handle with the URL (for --mcp-config) and a close() function.
|
|
55
|
+
* The caller is responsible for calling close() after the session exits.
|
|
56
|
+
*
|
|
57
|
+
* Each session gets its own server instance. Concurrent sessions get
|
|
58
|
+
* independent servers on different ports.
|
|
59
|
+
*/
|
|
60
|
+
export declare function startMcpHttpServer(tools: ToolDefinition[]): Promise<McpHttpHandle>;
|
|
61
|
+
//# 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":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAIlE;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAwCjF;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAoDxF"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool Server — serves guild tools as typed MCP tools during anima sessions.
|
|
3
|
+
*
|
|
4
|
+
* Two entry points:
|
|
5
|
+
*
|
|
6
|
+
* 1. **`createMcpServer(tools)`** — library function. Takes an array of
|
|
7
|
+
* ToolDefinitions (already resolved by the Instrumentarium) and returns
|
|
8
|
+
* a configured McpServer.
|
|
9
|
+
*
|
|
10
|
+
* 2. **`startMcpHttpServer(tools)`** — starts an in-process HTTP server
|
|
11
|
+
* serving the MCP tool set via Streamable HTTP on an ephemeral localhost
|
|
12
|
+
* port. Returns a handle with the URL (for --mcp-config) and a close()
|
|
13
|
+
* function for cleanup.
|
|
14
|
+
*
|
|
15
|
+
* The MCP server is one-per-session. The claude-code provider owns the
|
|
16
|
+
* lifecycle — starts before the Claude process, stops after it exits.
|
|
17
|
+
*
|
|
18
|
+
* See: docs/architecture/apparatus/claude-code.md
|
|
19
|
+
*/
|
|
20
|
+
import http from 'node:http';
|
|
21
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
22
|
+
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
23
|
+
import { VERSION } from '@shardworks/nexus-core';
|
|
24
|
+
// ── Library API ─────────────────────────────────────────────────────────
|
|
25
|
+
/**
|
|
26
|
+
* Create and configure an MCP server with the given tools.
|
|
27
|
+
*
|
|
28
|
+
* Each tool's Zod param schema is registered directly with the MCP SDK
|
|
29
|
+
* (which handles JSON Schema conversion). The handler is wrapped to
|
|
30
|
+
* validate params via Zod and format the result as MCP tool output.
|
|
31
|
+
*
|
|
32
|
+
* Tools with `callableBy` set that does not include `'anima'` are
|
|
33
|
+
* filtered out. Tools without `callableBy` are included (available
|
|
34
|
+
* to all callers by default).
|
|
35
|
+
*/
|
|
36
|
+
export async function createMcpServer(tools) {
|
|
37
|
+
const server = new McpServer({
|
|
38
|
+
name: 'nexus-guild',
|
|
39
|
+
version: VERSION,
|
|
40
|
+
});
|
|
41
|
+
for (const def of tools) {
|
|
42
|
+
// Filter by callableBy — only serve tools callable by animas.
|
|
43
|
+
// Tools with no callableBy default to all callers (available everywhere).
|
|
44
|
+
if (def.callableBy && !def.callableBy.includes('anima')) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
server.tool(def.name, def.description, def.params.shape, async (params) => {
|
|
48
|
+
try {
|
|
49
|
+
const validated = def.params.parse(params);
|
|
50
|
+
const result = await def.handler(validated);
|
|
51
|
+
return {
|
|
52
|
+
content: [{
|
|
53
|
+
type: 'text',
|
|
54
|
+
text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),
|
|
55
|
+
}],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
60
|
+
return {
|
|
61
|
+
content: [{ type: 'text', text: `Error: ${message}` }],
|
|
62
|
+
isError: true,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return server;
|
|
68
|
+
}
|
|
69
|
+
// ── HTTP Server ─────────────────────────────────────────────────────────
|
|
70
|
+
/**
|
|
71
|
+
* Start an in-process HTTP server serving the MCP tool set via SSE.
|
|
72
|
+
*
|
|
73
|
+
* Uses the MCP SDK's SSE transport: the client GETs /sse to establish
|
|
74
|
+
* the event stream, then POSTs messages to /message. Claude Code's
|
|
75
|
+
* --mcp-config expects `type: "sse"` for HTTP-based MCP servers.
|
|
76
|
+
*
|
|
77
|
+
* The server binds to 127.0.0.1 only — not network-accessible.
|
|
78
|
+
*
|
|
79
|
+
* Returns a handle with the URL (for --mcp-config) and a close() function.
|
|
80
|
+
* The caller is responsible for calling close() after the session exits.
|
|
81
|
+
*
|
|
82
|
+
* Each session gets its own server instance. Concurrent sessions get
|
|
83
|
+
* independent servers on different ports.
|
|
84
|
+
*/
|
|
85
|
+
export async function startMcpHttpServer(tools) {
|
|
86
|
+
const mcpServer = await createMcpServer(tools);
|
|
87
|
+
// SSE transport: the client GETs /sse, the transport tells it to POST
|
|
88
|
+
// messages to /message. One transport per connection (single-session).
|
|
89
|
+
let transport = null;
|
|
90
|
+
const httpServer = http.createServer(async (req, res) => {
|
|
91
|
+
try {
|
|
92
|
+
if (req.method === 'GET' && req.url === '/sse') {
|
|
93
|
+
// New SSE connection — create transport bound to this response.
|
|
94
|
+
transport = new SSEServerTransport('/message', res);
|
|
95
|
+
await mcpServer.connect(transport);
|
|
96
|
+
}
|
|
97
|
+
else if (req.method === 'POST' && req.url?.startsWith('/message')) {
|
|
98
|
+
if (!transport) {
|
|
99
|
+
res.writeHead(400).end('No active SSE connection');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
await transport.handlePostMessage(req, res);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
res.writeHead(404).end('Not found');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
if (!res.headersSent) {
|
|
110
|
+
res.writeHead(500).end('Internal Server Error');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
// Listen on ephemeral port, localhost only.
|
|
115
|
+
await new Promise((resolve) => {
|
|
116
|
+
httpServer.listen(0, '127.0.0.1', resolve);
|
|
117
|
+
});
|
|
118
|
+
const addr = httpServer.address();
|
|
119
|
+
if (!addr || typeof addr === 'string') {
|
|
120
|
+
throw new Error('Failed to get server address');
|
|
121
|
+
}
|
|
122
|
+
const url = `http://127.0.0.1:${addr.port}/sse`;
|
|
123
|
+
return {
|
|
124
|
+
url,
|
|
125
|
+
async close() {
|
|
126
|
+
if (transport) {
|
|
127
|
+
await transport.close();
|
|
128
|
+
}
|
|
129
|
+
await new Promise((resolve, reject) => {
|
|
130
|
+
httpServer.close((err) => (err ? reject(err) : resolve()));
|
|
131
|
+
});
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//# 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,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shardworks/claude-code-apparatus",
|
|
3
|
+
"version": "0.1.101",
|
|
4
|
+
"license": "ISC",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/shardworks/nexus",
|
|
8
|
+
"directory": "packages/plugins/claude-code"
|
|
9
|
+
},
|
|
10
|
+
"description": "Claude Code session provider apparatus — launches claude sessions via the Animator",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@modelcontextprotocol/sdk": "1.27.1",
|
|
20
|
+
"zod": "4.3.6",
|
|
21
|
+
"@shardworks/animator-apparatus": "0.1.101",
|
|
22
|
+
"@shardworks/nexus-core": "0.1.101",
|
|
23
|
+
"@shardworks/tools-apparatus": "0.1.101"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "25.5.0"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc",
|
|
33
|
+
"test": "node --disable-warning=ExperimentalWarning --experimental-transform-types --test 'src/**/*.test.ts'",
|
|
34
|
+
"typecheck": "tsc --noEmit"
|
|
35
|
+
}
|
|
36
|
+
}
|