-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathclaw_mcp_server.ts
More file actions
89 lines (72 loc) · 2.55 KB
/
Copy pathclaw_mcp_server.ts
File metadata and controls
89 lines (72 loc) · 2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env node
// MCP stdio reserves stdout for JSON-RPC frames. Some shared DEXBot2 modules
// (notably modules/paths.ts) log relocation notices during require-time
// initialization, so the heavy claw modules are loaded lazily below — AFTER the
// console shim has been installed. Static imports here are limited to the
// lightweight transport helpers (mcp_utils) which never write to stdout.
import { createJsonRpcToolsHandler, jsonRpcError, runMcpServer, createMessageParser } from '../modules/mcp_utils.js';
import { pathToFileURL } from 'node:url';
console.log = () => {};
console.warn = () => {};
// NOTE: this is a custom newline-delimited JSON transport (not the official
// MCP Content-Length framing); protocolVersion is echoed from the client and
// is informational only. See claw_runtime_matrix.ts.
function parseArgs(argv: any) {
const options: Record<string, any> = {};
for (let i = 0; i < argv.length; i += 1) {
const arg = argv[i];
const next = argv[i + 1];
if (arg === '--profile-root' && next) {
options.profileRoot = next;
i += 1;
continue;
}
if (arg === '--account' && next) {
options.accountName = next;
i += 1;
continue;
}
if (arg === '--runtime' && next) {
options.runtimeName = next;
i += 1;
continue;
}
}
return options;
}
async function listMcpTools() {
const { getClawToolCatalog } = await import('../modules/claw_catalog.js');
return getClawToolCatalog().map((tool: any) => ({
name: tool.toolName,
description: tool.description,
inputSchema: tool.inputSchema || {
type: 'object',
properties: {},
additionalProperties: true
}
}));
}
async function callTool(params: any, defaults: any) {
const { getClawToolByName } = await import('../modules/claw_catalog.js');
const tool = getClawToolByName(params?.name);
if (!tool) {
throw jsonRpcError(-32602, `Unknown tool: ${params?.name || '(missing)'}`);
}
const { runClawCommand } = await import('../modules/claw_bridge.js');
return runClawCommand(tool.command, {
...defaults,
...(params?.arguments || {})
});
}
const handleRequest = createJsonRpcToolsHandler({
serverName: 'bitshares-claw',
listTools: listMcpTools,
callTool
});
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
runMcpServer(parseArgs, handleRequest).catch((err: unknown) => {
process.stderr.write(`${err instanceof Error && err.stack ? err.stack : String(err)}\n`);
process.exit(1);
});
}
export { createMessageParser, handleRequest }