@shardworks/claude-code-session-provider 0.1.23
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 +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +159 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +60 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +123 -0
- package/dist/mcp-server.js.map +1 -0
- package/package.json +34 -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,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Session Provider
|
|
3
|
+
*
|
|
4
|
+
* Implements the SessionProvider interface for Claude Code sessions.
|
|
5
|
+
* Handles both interactive (TUI) and autonomous (--print) modes.
|
|
6
|
+
*
|
|
7
|
+
* This is a platform dependency of the CLI, not a guild-registered engine.
|
|
8
|
+
* The CLI imports it at startup and registers it as the session provider.
|
|
9
|
+
* Guilds don't need to know about it — it's a transitive dep of @shardworks/nexus.
|
|
10
|
+
*
|
|
11
|
+
* Key design choice: uses async spawn() instead of spawnSync().
|
|
12
|
+
* This is required for stream-json transcript parsing, timeout enforcement,
|
|
13
|
+
* and future concurrent session support.
|
|
14
|
+
*/
|
|
15
|
+
import type { ResolvedTool } from '@shardworks/nexus-core';
|
|
16
|
+
import type { McpServerConfig } from './mcp-server.ts';
|
|
17
|
+
import type { SessionProvider } from '@shardworks/nexus-core';
|
|
18
|
+
/**
|
|
19
|
+
* Generate the MCP server config for the resolved tool set.
|
|
20
|
+
*
|
|
21
|
+
* For tools with a `package` field in guild.json, the modulePath is the
|
|
22
|
+
* npm package name (resolved via NODE_PATH at runtime). For tools without
|
|
23
|
+
* a package field, the modulePath is an absolute path to the entry point.
|
|
24
|
+
*/
|
|
25
|
+
export declare function generateMcpConfig(home: string, tools: ResolvedTool[]): McpServerConfig;
|
|
26
|
+
/**
|
|
27
|
+
* Claude Code session provider.
|
|
28
|
+
*
|
|
29
|
+
* Launches sessions via the `claude` CLI. Interactive mode inherits stdio;
|
|
30
|
+
* autonomous mode uses --print with optional --output-format stream-json.
|
|
31
|
+
*/
|
|
32
|
+
export declare const claudeCodeProvider: SessionProvider;
|
|
33
|
+
export default claudeCodeProvider;
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,wBAAwB,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAuD,MAAM,wBAAwB,CAAC;AAInH;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,YAAY,EAAE,GACpB,eAAe,CAqBjB;AA8CD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAsDhC,CAAC;AAsCF,eAAe,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Session Provider
|
|
3
|
+
*
|
|
4
|
+
* Implements the SessionProvider interface for Claude Code sessions.
|
|
5
|
+
* Handles both interactive (TUI) and autonomous (--print) modes.
|
|
6
|
+
*
|
|
7
|
+
* This is a platform dependency of the CLI, not a guild-registered engine.
|
|
8
|
+
* The CLI imports it at startup and registers it as the session provider.
|
|
9
|
+
* Guilds don't need to know about it — it's a transitive dep of @shardworks/nexus.
|
|
10
|
+
*
|
|
11
|
+
* Key design choice: uses async spawn() instead of spawnSync().
|
|
12
|
+
* This is required for stream-json transcript parsing, timeout enforcement,
|
|
13
|
+
* and future concurrent session support.
|
|
14
|
+
*/
|
|
15
|
+
import { spawn } from 'node:child_process';
|
|
16
|
+
import fs from 'node:fs';
|
|
17
|
+
import os from 'node:os';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
import { fileURLToPath } from 'node:url';
|
|
20
|
+
// ── MCP Config Generation ──────────────────────────────────────────────
|
|
21
|
+
/**
|
|
22
|
+
* Generate the MCP server config for the resolved tool set.
|
|
23
|
+
*
|
|
24
|
+
* For tools with a `package` field in guild.json, the modulePath is the
|
|
25
|
+
* npm package name (resolved via NODE_PATH at runtime). For tools without
|
|
26
|
+
* a package field, the modulePath is an absolute path to the entry point.
|
|
27
|
+
*/
|
|
28
|
+
export function generateMcpConfig(home, tools) {
|
|
29
|
+
const mcpTools = [];
|
|
30
|
+
for (const t of tools) {
|
|
31
|
+
if (t.package) {
|
|
32
|
+
mcpTools.push({ name: t.name, modulePath: t.package });
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const descriptorPath = path.join(t.path, 'nexus-tool.json');
|
|
36
|
+
if (!fs.existsSync(descriptorPath))
|
|
37
|
+
continue;
|
|
38
|
+
const descriptor = JSON.parse(fs.readFileSync(descriptorPath, 'utf-8'));
|
|
39
|
+
const entry = descriptor.entry;
|
|
40
|
+
mcpTools.push({ name: t.name, modulePath: path.join(t.path, entry) });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Set NODE_PATH so the MCP server process can resolve npm-installed guild
|
|
44
|
+
// tools from the guildhall's node_modules, regardless of where the MCP
|
|
45
|
+
// engine code itself lives on disk.
|
|
46
|
+
const nodePath = path.join(home, 'node_modules');
|
|
47
|
+
return { home, tools: mcpTools, env: { NODE_PATH: nodePath } };
|
|
48
|
+
}
|
|
49
|
+
// ── Claude MCP Config ──────────────────────────────────────────────────
|
|
50
|
+
/**
|
|
51
|
+
* Build the Claude MCP config JSON (mcpServers format) that launches the
|
|
52
|
+
* MCP server as a stdio process serving the anima's tools.
|
|
53
|
+
*/
|
|
54
|
+
function buildClaudeMcpConfig(tmpDir, mcpServerConfigPath, serverConfig) {
|
|
55
|
+
// Resolve the mcp-server entry point within this package
|
|
56
|
+
const mcpServerUrl = import.meta.resolve('./mcp-server.ts');
|
|
57
|
+
const mcpServerPath = fileURLToPath(mcpServerUrl);
|
|
58
|
+
// Write a wrapper script that imports and invokes main().
|
|
59
|
+
const wrapperPath = path.join(tmpDir, 'mcp-entry.mjs');
|
|
60
|
+
fs.writeFileSync(wrapperPath, `import { main } from ${JSON.stringify(mcpServerUrl)};\nawait main();\n`);
|
|
61
|
+
// In dev the resolved path is .ts source; add the transform flag.
|
|
62
|
+
const nodeArgs = [];
|
|
63
|
+
if (mcpServerPath.endsWith('.ts')) {
|
|
64
|
+
nodeArgs.push('--disable-warning=ExperimentalWarning', '--experimental-transform-types');
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
mcpServers: {
|
|
68
|
+
'nexus-guild': {
|
|
69
|
+
command: 'node',
|
|
70
|
+
args: [...nodeArgs, wrapperPath, mcpServerConfigPath],
|
|
71
|
+
env: serverConfig.env ?? {},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// ── Session Provider ───────────────────────────────────────────────────
|
|
77
|
+
/**
|
|
78
|
+
* Claude Code session provider.
|
|
79
|
+
*
|
|
80
|
+
* Launches sessions via the `claude` CLI. Interactive mode inherits stdio;
|
|
81
|
+
* autonomous mode uses --print with optional --output-format stream-json.
|
|
82
|
+
*/
|
|
83
|
+
export const claudeCodeProvider = {
|
|
84
|
+
name: 'claude-code',
|
|
85
|
+
async launch(options) {
|
|
86
|
+
const { home, manifest, prompt, interactive, cwd, name } = options;
|
|
87
|
+
const startTime = Date.now();
|
|
88
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'nsg-session-'));
|
|
89
|
+
try {
|
|
90
|
+
// Generate MCP config from resolved tools
|
|
91
|
+
const mcpConfig = generateMcpConfig(home, manifest.tools);
|
|
92
|
+
const systemPromptPath = path.join(tmpDir, 'system-prompt.md');
|
|
93
|
+
const mcpServerConfigPath = path.join(tmpDir, 'mcp-server-config.json');
|
|
94
|
+
const claudeMcpConfigPath = path.join(tmpDir, 'claude-mcp-config.json');
|
|
95
|
+
fs.writeFileSync(systemPromptPath, manifest.systemPrompt);
|
|
96
|
+
fs.writeFileSync(mcpServerConfigPath, JSON.stringify(mcpConfig, null, 2));
|
|
97
|
+
fs.writeFileSync(claudeMcpConfigPath, JSON.stringify(buildClaudeMcpConfig(tmpDir, mcpServerConfigPath, mcpConfig), null, 2));
|
|
98
|
+
// Base args — shared between interactive and print modes
|
|
99
|
+
const args = [
|
|
100
|
+
'--bare',
|
|
101
|
+
'--setting-sources', 'user',
|
|
102
|
+
'--dangerously-skip-permissions',
|
|
103
|
+
'--system-prompt-file', systemPromptPath,
|
|
104
|
+
'--mcp-config', claudeMcpConfigPath,
|
|
105
|
+
];
|
|
106
|
+
if (name) {
|
|
107
|
+
args.push('--name', name);
|
|
108
|
+
}
|
|
109
|
+
if (interactive) {
|
|
110
|
+
// Interactive: human at keyboard, inherit stdio
|
|
111
|
+
const exitCode = await spawnClaude(args, cwd, 'inherit');
|
|
112
|
+
const durationMs = Date.now() - startTime;
|
|
113
|
+
return { exitCode, durationMs };
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// Autonomous: commission spec / brief as prompt
|
|
117
|
+
args.push('--print', prompt ?? '');
|
|
118
|
+
// TODO Phase 4: add --output-format stream-json and parse transcript + metrics
|
|
119
|
+
const exitCode = await spawnClaude(args, cwd, 'pipe');
|
|
120
|
+
const durationMs = Date.now() - startTime;
|
|
121
|
+
return { exitCode, durationMs };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Spawn the claude CLI process asynchronously.
|
|
131
|
+
*
|
|
132
|
+
* Uses child_process.spawn (not spawnSync) for:
|
|
133
|
+
* - Stream-json transcript parsing (future)
|
|
134
|
+
* - Timeout enforcement (future)
|
|
135
|
+
* - Concurrent session support (future)
|
|
136
|
+
*
|
|
137
|
+
* @param args - CLI arguments for claude
|
|
138
|
+
* @param cwd - Working directory for the process
|
|
139
|
+
* @param stdio - 'inherit' for interactive, 'pipe' for autonomous
|
|
140
|
+
* @returns Exit code (0 = success)
|
|
141
|
+
*/
|
|
142
|
+
function spawnClaude(args, cwd, stdio) {
|
|
143
|
+
return new Promise((resolve, reject) => {
|
|
144
|
+
const proc = spawn('claude', args, {
|
|
145
|
+
cwd,
|
|
146
|
+
stdio: stdio === 'inherit'
|
|
147
|
+
? 'inherit'
|
|
148
|
+
: ['pipe', 'inherit', 'inherit'],
|
|
149
|
+
});
|
|
150
|
+
proc.on('error', (err) => {
|
|
151
|
+
reject(new Error(`Failed to spawn claude: ${err.message}`));
|
|
152
|
+
});
|
|
153
|
+
proc.on('close', (code) => {
|
|
154
|
+
resolve(code ?? 1);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
export default claudeCodeProvider;
|
|
159
|
+
//# 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,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server — serves guild tools as typed MCP tools during anima sessions.
|
|
3
|
+
*
|
|
4
|
+
* Absorbed from the former `engine-mcp-server` package. This is an internal
|
|
5
|
+
* module of claude-code-session-provider — not a separate package.
|
|
6
|
+
*
|
|
7
|
+
* The session provider launches this as a stdio process, configured with
|
|
8
|
+
* the set of tools the anima has access to (based on role gating).
|
|
9
|
+
*
|
|
10
|
+
* One process per session. All the anima's tools. Claude's runtime manages
|
|
11
|
+
* the lifecycle — spawns at session start, kills at session end.
|
|
12
|
+
*
|
|
13
|
+
* ## Usage
|
|
14
|
+
*
|
|
15
|
+
* The server reads a JSON config from a file path passed as argv[2]:
|
|
16
|
+
*
|
|
17
|
+
* node mcp-server <config.json>
|
|
18
|
+
*
|
|
19
|
+
* Config shape:
|
|
20
|
+
* {
|
|
21
|
+
* "home": "/absolute/path/to/guild-root",
|
|
22
|
+
* "tools": [
|
|
23
|
+
* { "name": "install-tool", "modulePath": "@shardworks/nexus-stdlib/tools" },
|
|
24
|
+
* { "name": "my-tool", "modulePath": "/absolute/path/to/handler.ts" }
|
|
25
|
+
* ]
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
29
|
+
/** A single tool to load into the MCP server. */
|
|
30
|
+
export interface ToolSpec {
|
|
31
|
+
/** Tool name — how the anima sees it. */
|
|
32
|
+
name: string;
|
|
33
|
+
/** Module path — package name (for framework tools) or absolute file path (for guild tools). */
|
|
34
|
+
modulePath: string;
|
|
35
|
+
}
|
|
36
|
+
/** Configuration for the MCP server. */
|
|
37
|
+
export interface McpServerConfig {
|
|
38
|
+
/** Absolute path to the guild root. */
|
|
39
|
+
home: string;
|
|
40
|
+
/** Tools to register as MCP tools. */
|
|
41
|
+
tools: ToolSpec[];
|
|
42
|
+
/** Environment variables for the MCP server process. */
|
|
43
|
+
env?: Record<string, string>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Create and configure an MCP server with the given tools.
|
|
47
|
+
*
|
|
48
|
+
* Each tool's Zod param schema is registered directly with the MCP SDK
|
|
49
|
+
* (which handles JSON Schema conversion). The handler is wrapped to inject
|
|
50
|
+
* the framework context and format the result as MCP tool output.
|
|
51
|
+
*/
|
|
52
|
+
export declare function createMcpServer(config: McpServerConfig): Promise<McpServer>;
|
|
53
|
+
/**
|
|
54
|
+
* Entry point when run as a standalone process.
|
|
55
|
+
*
|
|
56
|
+
* Reads config from a JSON file (path passed as first argument),
|
|
57
|
+
* creates the MCP server, and connects via stdio transport.
|
|
58
|
+
*/
|
|
59
|
+
export declare function main(configPath?: string): Promise<void>;
|
|
60
|
+
//# 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;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,iDAAiD;AACjD,MAAM,WAAW,QAAQ;IACvB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,gGAAgG;IAChG,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wCAAwC;AACxC,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AA6BD;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CA0CjF;AAED;;;;;GAKG;AACH,wBAAsB,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe7D"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server — serves guild tools as typed MCP tools during anima sessions.
|
|
3
|
+
*
|
|
4
|
+
* Absorbed from the former `engine-mcp-server` package. This is an internal
|
|
5
|
+
* module of claude-code-session-provider — not a separate package.
|
|
6
|
+
*
|
|
7
|
+
* The session provider launches this as a stdio process, configured with
|
|
8
|
+
* the set of tools the anima has access to (based on role gating).
|
|
9
|
+
*
|
|
10
|
+
* One process per session. All the anima's tools. Claude's runtime manages
|
|
11
|
+
* the lifecycle — spawns at session start, kills at session end.
|
|
12
|
+
*
|
|
13
|
+
* ## Usage
|
|
14
|
+
*
|
|
15
|
+
* The server reads a JSON config from a file path passed as argv[2]:
|
|
16
|
+
*
|
|
17
|
+
* node mcp-server <config.json>
|
|
18
|
+
*
|
|
19
|
+
* Config shape:
|
|
20
|
+
* {
|
|
21
|
+
* "home": "/absolute/path/to/guild-root",
|
|
22
|
+
* "tools": [
|
|
23
|
+
* { "name": "install-tool", "modulePath": "@shardworks/nexus-stdlib/tools" },
|
|
24
|
+
* { "name": "my-tool", "modulePath": "/absolute/path/to/handler.ts" }
|
|
25
|
+
* ]
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
29
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
30
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
31
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return path;
|
|
35
|
+
};
|
|
36
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
37
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
38
|
+
import { VERSION, resolveToolFromExport } from '@shardworks/nexus-core';
|
|
39
|
+
/**
|
|
40
|
+
* Load a tool definition from a module path.
|
|
41
|
+
*
|
|
42
|
+
* Handles both single-tool and array-of-tools exports:
|
|
43
|
+
* - Single: `export default tool({...})` → returned directly
|
|
44
|
+
* - Array: `export default [tool({...}), ...]` → resolved by spec.name
|
|
45
|
+
*/
|
|
46
|
+
async function loadTool(spec) {
|
|
47
|
+
try {
|
|
48
|
+
const mod = await import(__rewriteRelativeImportExtension(spec.modulePath));
|
|
49
|
+
const def = resolveToolFromExport(mod.default, spec.name);
|
|
50
|
+
if (!def) {
|
|
51
|
+
console.error(`[mcp-server] ${spec.name}: could not resolve tool from "${spec.modulePath}". ` +
|
|
52
|
+
`Module must export a tool() definition or an array of tool() definitions with matching names. Skipping.`);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return def;
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
console.error(`[mcp-server] ${spec.name}: failed to load module "${spec.modulePath}":`, err);
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Create and configure an MCP server with the given tools.
|
|
64
|
+
*
|
|
65
|
+
* Each tool's Zod param schema is registered directly with the MCP SDK
|
|
66
|
+
* (which handles JSON Schema conversion). The handler is wrapped to inject
|
|
67
|
+
* the framework context and format the result as MCP tool output.
|
|
68
|
+
*/
|
|
69
|
+
export async function createMcpServer(config) {
|
|
70
|
+
const server = new McpServer({
|
|
71
|
+
name: 'nexus-guild',
|
|
72
|
+
version: VERSION,
|
|
73
|
+
});
|
|
74
|
+
const context = { home: config.home };
|
|
75
|
+
for (const spec of config.tools) {
|
|
76
|
+
const def = await loadTool(spec);
|
|
77
|
+
if (!def)
|
|
78
|
+
continue;
|
|
79
|
+
// Register the tool as an MCP tool.
|
|
80
|
+
// The MCP SDK accepts Zod shapes directly — it handles JSON Schema conversion.
|
|
81
|
+
server.tool(spec.name, def.description, def.params.shape, async (params) => {
|
|
82
|
+
try {
|
|
83
|
+
// Validate params through Zod before passing to handler
|
|
84
|
+
const validated = def.params.parse(params);
|
|
85
|
+
const result = await def.handler(validated, context);
|
|
86
|
+
return {
|
|
87
|
+
content: [{
|
|
88
|
+
type: 'text',
|
|
89
|
+
text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),
|
|
90
|
+
}],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
95
|
+
return {
|
|
96
|
+
content: [{ type: 'text', text: `Error: ${message}` }],
|
|
97
|
+
isError: true,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return server;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Entry point when run as a standalone process.
|
|
106
|
+
*
|
|
107
|
+
* Reads config from a JSON file (path passed as first argument),
|
|
108
|
+
* creates the MCP server, and connects via stdio transport.
|
|
109
|
+
*/
|
|
110
|
+
export async function main(configPath) {
|
|
111
|
+
const resolvedPath = configPath ?? process.argv[2];
|
|
112
|
+
if (!resolvedPath) {
|
|
113
|
+
console.error('Usage: nexus-mcp-server <config.json>');
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
const fs = await import('node:fs');
|
|
117
|
+
const configText = fs.readFileSync(resolvedPath, 'utf-8');
|
|
118
|
+
const config = JSON.parse(configText);
|
|
119
|
+
const server = await createMcpServer(config);
|
|
120
|
+
const transport = new StdioServerTransport();
|
|
121
|
+
await server.connect(transport);
|
|
122
|
+
}
|
|
123
|
+
//# 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,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shardworks/claude-code-session-provider",
|
|
3
|
+
"version": "0.1.23",
|
|
4
|
+
"license": "ISC",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/shardworks/nexus-mk2",
|
|
8
|
+
"directory": "packages/claude-code-session-provider"
|
|
9
|
+
},
|
|
10
|
+
"description": "Claude Code session provider — launches claude sessions with MCP tool serving",
|
|
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/nexus-core": "0.1.23"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "25.5.0"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsc",
|
|
31
|
+
"test": "node --disable-warning=ExperimentalWarning --experimental-transform-types --test 'src/**/*.test.ts'",
|
|
32
|
+
"typecheck": "tsc --noEmit"
|
|
33
|
+
}
|
|
34
|
+
}
|