clay-server 2.34.0-beta.4 → 2.34.0-beta.5
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/lib/sdk-bridge.js
CHANGED
|
@@ -1227,11 +1227,13 @@ function createSDKBridge(opts) {
|
|
|
1227
1227
|
}
|
|
1228
1228
|
|
|
1229
1229
|
var codexConfig = getCodexConfig(sm);
|
|
1230
|
+
var mergedMcpServers = mergeMcpServers(getMcpServers(), getRemoteMcpServers) || undefined;
|
|
1230
1231
|
var queryOpts = {
|
|
1231
1232
|
cwd: cwd,
|
|
1232
1233
|
model: queryModel,
|
|
1233
1234
|
effort: ls.effort || sm.currentEffort || undefined,
|
|
1234
|
-
toolServers:
|
|
1235
|
+
toolServers: mergedMcpServers,
|
|
1236
|
+
toolServerDescriptors: extractMcpDescriptors(mergedMcpServers) || undefined,
|
|
1235
1237
|
resumeSessionId: session.cliSessionId || undefined,
|
|
1236
1238
|
abortController: linuxUser ? undefined : session.abortController,
|
|
1237
1239
|
canUseTool: function(toolName, input, toolOpts) {
|
|
@@ -1240,6 +1242,9 @@ function createSDKBridge(opts) {
|
|
|
1240
1242
|
onElicitation: function(request, elicitOpts) {
|
|
1241
1243
|
return handleElicitation(session, request, elicitOpts);
|
|
1242
1244
|
},
|
|
1245
|
+
callMcpTool: function(serverName, toolName, args) {
|
|
1246
|
+
return callMcpToolHandler(mergedMcpServers, serverName, toolName, args);
|
|
1247
|
+
},
|
|
1243
1248
|
adapterOptions: {
|
|
1244
1249
|
CLAUDE: claudeOpts,
|
|
1245
1250
|
CODEX: {
|
|
@@ -31,6 +31,7 @@ var abortController = null;
|
|
|
31
31
|
var pendingPermissions = {}; // requestId -> resolve
|
|
32
32
|
var pendingAskUser = {}; // toolUseId -> resolve
|
|
33
33
|
var pendingElicitations = {}; // requestId -> resolve
|
|
34
|
+
var pendingMcpToolCalls = {}; // requestId -> { resolve, reject }
|
|
34
35
|
var conn = null;
|
|
35
36
|
var buffer = "";
|
|
36
37
|
|
|
@@ -81,6 +82,90 @@ function getSDK() {
|
|
|
81
82
|
return sdkModule;
|
|
82
83
|
}
|
|
83
84
|
|
|
85
|
+
function buildZodShape(z, inputSchema) {
|
|
86
|
+
if (!inputSchema || !inputSchema.properties) return {};
|
|
87
|
+
var shape = {};
|
|
88
|
+
var props = inputSchema.properties;
|
|
89
|
+
var required = inputSchema.required || [];
|
|
90
|
+
var keys = Object.keys(props);
|
|
91
|
+
|
|
92
|
+
for (var i = 0; i < keys.length; i++) {
|
|
93
|
+
var key = keys[i];
|
|
94
|
+
var prop = props[key];
|
|
95
|
+
var field;
|
|
96
|
+
|
|
97
|
+
if (prop.type === "number" || prop.type === "integer") {
|
|
98
|
+
field = z.number();
|
|
99
|
+
} else if (prop.type === "boolean") {
|
|
100
|
+
field = z.boolean();
|
|
101
|
+
} else if (prop.type === "array") {
|
|
102
|
+
field = z.array(z.any());
|
|
103
|
+
} else if (prop.type === "object") {
|
|
104
|
+
field = z.record(z.any());
|
|
105
|
+
} else if (prop.enum) {
|
|
106
|
+
field = z.enum(prop.enum);
|
|
107
|
+
} else {
|
|
108
|
+
field = z.string();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (prop.description) field = field.describe(prop.description);
|
|
112
|
+
if (required.indexOf(key) === -1) field = field.optional();
|
|
113
|
+
shape[key] = field;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return shape;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function createWorkerMcpToolHandler(serverName, toolName) {
|
|
120
|
+
return function(args) {
|
|
121
|
+
var requestId = crypto.randomUUID();
|
|
122
|
+
sendToDaemon({
|
|
123
|
+
type: "mcp_tool_call",
|
|
124
|
+
requestId: requestId,
|
|
125
|
+
serverName: serverName,
|
|
126
|
+
toolName: toolName,
|
|
127
|
+
args: args || {},
|
|
128
|
+
});
|
|
129
|
+
return new Promise(function(resolve, reject) {
|
|
130
|
+
pendingMcpToolCalls[requestId] = { resolve: resolve, reject: reject };
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function buildMcpServersFromDescriptors(descriptors, sdk) {
|
|
136
|
+
if (!descriptors || !descriptors.length) return null;
|
|
137
|
+
var z;
|
|
138
|
+
try { z = require("zod").z; } catch (e) {
|
|
139
|
+
try { z = require("zod"); } catch (e2) { return null; }
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
var servers = {};
|
|
143
|
+
for (var i = 0; i < descriptors.length; i++) {
|
|
144
|
+
var descriptor = descriptors[i];
|
|
145
|
+
if (!descriptor || !descriptor.serverName || !descriptor.tools || !descriptor.tools.length) continue;
|
|
146
|
+
var tools = [];
|
|
147
|
+
for (var j = 0; j < descriptor.tools.length; j++) {
|
|
148
|
+
var toolDescriptor = descriptor.tools[j];
|
|
149
|
+
if (!toolDescriptor || !toolDescriptor.name) continue;
|
|
150
|
+
tools.push(sdk.tool(
|
|
151
|
+
toolDescriptor.name,
|
|
152
|
+
toolDescriptor.description || toolDescriptor.name,
|
|
153
|
+
buildZodShape(z, toolDescriptor.inputSchema),
|
|
154
|
+
createWorkerMcpToolHandler(descriptor.serverName, toolDescriptor.name)
|
|
155
|
+
));
|
|
156
|
+
}
|
|
157
|
+
if (tools.length > 0) {
|
|
158
|
+
servers[descriptor.serverName] = sdk.createSdkMcpServer({
|
|
159
|
+
name: descriptor.serverName,
|
|
160
|
+
version: "1.0.0",
|
|
161
|
+
tools: tools,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return Object.keys(servers).length > 0 ? servers : null;
|
|
167
|
+
}
|
|
168
|
+
|
|
84
169
|
// --- IPC helpers ---
|
|
85
170
|
function sendToDaemon(msg) {
|
|
86
171
|
if (!conn || conn.destroyed) return;
|
|
@@ -127,6 +212,9 @@ function handleMessage(msg) {
|
|
|
127
212
|
case "elicitation_response":
|
|
128
213
|
handleElicitationResponse(msg);
|
|
129
214
|
break;
|
|
215
|
+
case "mcp_tool_result":
|
|
216
|
+
handleMcpToolResult(msg);
|
|
217
|
+
break;
|
|
130
218
|
case "warmup":
|
|
131
219
|
handleWarmup(msg);
|
|
132
220
|
break;
|
|
@@ -208,6 +296,17 @@ function handleElicitationResponse(msg) {
|
|
|
208
296
|
}
|
|
209
297
|
}
|
|
210
298
|
|
|
299
|
+
function handleMcpToolResult(msg) {
|
|
300
|
+
var pending = pendingMcpToolCalls[msg.requestId];
|
|
301
|
+
if (!pending) return;
|
|
302
|
+
delete pendingMcpToolCalls[msg.requestId];
|
|
303
|
+
if (msg.error) {
|
|
304
|
+
pending.reject(new Error(msg.error));
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
pending.resolve(msg.result);
|
|
308
|
+
}
|
|
309
|
+
|
|
211
310
|
// --- Query handling ---
|
|
212
311
|
async function handleQueryStart(msg) {
|
|
213
312
|
var t0 = msg._perfT0 || Date.now();
|
|
@@ -238,6 +337,15 @@ async function handleQueryStart(msg) {
|
|
|
238
337
|
options.abortController = abortController;
|
|
239
338
|
options.debug = true;
|
|
240
339
|
options.debugFile = "/tmp/clay-cli-debug-" + process.pid + ".log";
|
|
340
|
+
if (options.mcpServerDescriptors && options.mcpServerDescriptors.length) {
|
|
341
|
+
try {
|
|
342
|
+
var mcpServers = buildMcpServersFromDescriptors(options.mcpServerDescriptors, sdk);
|
|
343
|
+
if (mcpServers) options.mcpServers = mcpServers;
|
|
344
|
+
} catch (e) {
|
|
345
|
+
console.error("[sdk-worker] Failed to build MCP servers:", e.message || e);
|
|
346
|
+
}
|
|
347
|
+
delete options.mcpServerDescriptors;
|
|
348
|
+
}
|
|
241
349
|
// Override CLI subprocess spawn to inject NODE_OPTIONS for IPv4-first DNS.
|
|
242
350
|
// The SDK constructs its own env for the CLI process, so worker env vars
|
|
243
351
|
// like NODE_OPTIONS are not inherited. We intercept the spawn to fix this.
|
|
@@ -648,7 +648,7 @@ function cleanupWorker(worker) {
|
|
|
648
648
|
// in-process QueryHandle. This allows processQueryStream to iterate a worker
|
|
649
649
|
// query identically to an in-process query.
|
|
650
650
|
|
|
651
|
-
function createWorkerQueryHandle(worker, canUseTool, onElicitation) {
|
|
651
|
+
function createWorkerQueryHandle(worker, canUseTool, onElicitation, callMcpTool) {
|
|
652
652
|
// Async iterable state
|
|
653
653
|
var iterQueue = [];
|
|
654
654
|
var iterWaiting = null;
|
|
@@ -741,6 +741,20 @@ function createWorkerQueryHandle(worker, canUseTool, onElicitation) {
|
|
|
741
741
|
}
|
|
742
742
|
break;
|
|
743
743
|
|
|
744
|
+
case "mcp_tool_call":
|
|
745
|
+
if (callMcpTool) {
|
|
746
|
+
callMcpTool(msg.serverName, msg.toolName, msg.args || {}).then(function(result) {
|
|
747
|
+
worker.send({ type: "mcp_tool_result", requestId: msg.requestId, result: result });
|
|
748
|
+
}).catch(function(e) {
|
|
749
|
+
worker.send({
|
|
750
|
+
type: "mcp_tool_result",
|
|
751
|
+
requestId: msg.requestId,
|
|
752
|
+
error: (e && e.message) ? e.message : String(e),
|
|
753
|
+
});
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
break;
|
|
757
|
+
|
|
744
758
|
case "context_usage":
|
|
745
759
|
case "model_changed":
|
|
746
760
|
case "effort_changed":
|
|
@@ -1231,7 +1245,7 @@ function createClaudeAdapter(opts) {
|
|
|
1231
1245
|
}
|
|
1232
1246
|
|
|
1233
1247
|
// Create the worker query handle (sets up message handler on worker)
|
|
1234
|
-
var handle = createWorkerQueryHandle(worker, queryOpts.canUseTool, queryOpts.onElicitation);
|
|
1248
|
+
var handle = createWorkerQueryHandle(worker, queryOpts.canUseTool, queryOpts.onElicitation, queryOpts.callMcpTool);
|
|
1235
1249
|
|
|
1236
1250
|
// Wait for worker to be ready before sending query_start
|
|
1237
1251
|
if (!reusingWorker) {
|
|
@@ -1254,7 +1268,7 @@ function createClaudeAdapter(opts) {
|
|
|
1254
1268
|
if (claudeOpts.allowDangerouslySkipPermissions) queryOptions.allowDangerouslySkipPermissions = true;
|
|
1255
1269
|
if (claudeOpts.settings) queryOptions.settings = claudeOpts.settings;
|
|
1256
1270
|
|
|
1257
|
-
if (queryOpts.
|
|
1271
|
+
if (queryOpts.toolServerDescriptors) queryOptions.mcpServerDescriptors = queryOpts.toolServerDescriptors;
|
|
1258
1272
|
if (queryOpts.model) queryOptions.model = queryOpts.model;
|
|
1259
1273
|
if (queryOpts.effort) queryOptions.effort = queryOpts.effort;
|
|
1260
1274
|
if (queryOpts.resumeSessionId) queryOptions.resume = queryOpts.resumeSessionId;
|