@corbat-tech/coco 2.25.10 → 2.25.12
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/dist/cli/index.js +392 -289
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +85 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -2568,7 +2568,11 @@ function getDefaultModel(provider) {
|
|
|
2568
2568
|
function normalizeConfiguredModel(model) {
|
|
2569
2569
|
if (typeof model !== "string") return void 0;
|
|
2570
2570
|
const trimmed = model.trim();
|
|
2571
|
-
|
|
2571
|
+
if (trimmed.length === 0) return void 0;
|
|
2572
|
+
if (["default", "none", "null", "undefined"].includes(trimmed.toLowerCase())) {
|
|
2573
|
+
return void 0;
|
|
2574
|
+
}
|
|
2575
|
+
return trimmed;
|
|
2572
2576
|
}
|
|
2573
2577
|
function getDefaultProvider() {
|
|
2574
2578
|
const envProvider = process.env["COCO_PROVIDER"]?.toLowerCase();
|
|
@@ -4498,7 +4502,9 @@ var init_openai = __esm({
|
|
|
4498
4502
|
input,
|
|
4499
4503
|
instructions: instructions ?? void 0,
|
|
4500
4504
|
max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
|
|
4501
|
-
...supportsTemp && {
|
|
4505
|
+
...supportsTemp && {
|
|
4506
|
+
temperature: options?.temperature ?? this.config.temperature ?? 0
|
|
4507
|
+
},
|
|
4502
4508
|
store: false
|
|
4503
4509
|
});
|
|
4504
4510
|
return {
|
|
@@ -4533,7 +4539,9 @@ var init_openai = __esm({
|
|
|
4533
4539
|
instructions: instructions ?? void 0,
|
|
4534
4540
|
tools,
|
|
4535
4541
|
max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
|
|
4536
|
-
...supportsTemp && {
|
|
4542
|
+
...supportsTemp && {
|
|
4543
|
+
temperature: options?.temperature ?? this.config.temperature ?? 0
|
|
4544
|
+
},
|
|
4537
4545
|
store: false
|
|
4538
4546
|
});
|
|
4539
4547
|
let content = "";
|
|
@@ -10261,6 +10269,7 @@ Rules:
|
|
|
10261
10269
|
- If you need real-time data, CALL web_search. NEVER say "I don't have access to real-time data."
|
|
10262
10270
|
- If an MCP tool exists for a service (tool names like \`mcp_<service>_...\`), prefer that MCP tool over generic \`web_fetch\` or \`http_fetch\`.
|
|
10263
10271
|
- Use \`mcp_list_servers\` to inspect configured or connected MCP services. Do NOT use \`bash_exec\` to run \`coco mcp ...\` unless the user explicitly asked for that CLI command.
|
|
10272
|
+
- If the user asks you to use an MCP service and it is configured but disconnected, call \`mcp_connect_server\` first. This built-in flow may open a browser for OAuth. Do NOT ask the user for raw tokens when MCP OAuth is supported.
|
|
10264
10273
|
- Before answering "I can't do that", check your full tool catalog below \u2014 you likely have a tool for it.
|
|
10265
10274
|
- NEVER claim you cannot run a command because you lack credentials, access, or connectivity. bash_exec runs in the user's own shell environment and inherits their full PATH, kubeconfig, gcloud auth, AWS profiles, SSH keys, and every other tool installed on their machine. kubectl, gcloud, aws, docker, and any other CLI available to the user are available to you. ALWAYS attempt the command with bash_exec; report failure only if it actually returns a non-zero exit code.
|
|
10266
10275
|
|
|
@@ -21252,7 +21261,9 @@ function createProtectedMetadataCandidates(resourceUrl, headerUrl) {
|
|
|
21252
21261
|
candidates.push(`${origin}/.well-known/oauth-protected-resource`);
|
|
21253
21262
|
if (pathPart && pathPart !== "/") {
|
|
21254
21263
|
candidates.push(`${origin}/.well-known/oauth-protected-resource${pathPart}`);
|
|
21255
|
-
candidates.push(
|
|
21264
|
+
candidates.push(
|
|
21265
|
+
`${origin}/.well-known/oauth-protected-resource/${pathPart.replace(/^\//, "")}`
|
|
21266
|
+
);
|
|
21256
21267
|
}
|
|
21257
21268
|
return Array.from(new Set(candidates));
|
|
21258
21269
|
}
|
|
@@ -21651,14 +21662,6 @@ var init_http = __esm({
|
|
|
21651
21662
|
if (this.shouldAttemptOAuth()) {
|
|
21652
21663
|
this.oauthToken = await getStoredMcpOAuthToken(this.config.url);
|
|
21653
21664
|
}
|
|
21654
|
-
const response = await this.sendRequestWithOAuthRetry(
|
|
21655
|
-
"GET",
|
|
21656
|
-
void 0,
|
|
21657
|
-
this.abortController.signal
|
|
21658
|
-
);
|
|
21659
|
-
if (!response.ok && response.status !== 404) {
|
|
21660
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
21661
|
-
}
|
|
21662
21665
|
this.connected = true;
|
|
21663
21666
|
} catch (error) {
|
|
21664
21667
|
if (error instanceof MCPError) {
|
|
@@ -22367,6 +22370,263 @@ var init_full_power_risk_mode = __esm({
|
|
|
22367
22370
|
}
|
|
22368
22371
|
});
|
|
22369
22372
|
|
|
22373
|
+
// src/mcp/tools.ts
|
|
22374
|
+
var tools_exports = {};
|
|
22375
|
+
__export(tools_exports, {
|
|
22376
|
+
createToolsFromMCPServer: () => createToolsFromMCPServer,
|
|
22377
|
+
extractOriginalToolName: () => extractOriginalToolName,
|
|
22378
|
+
getMCPToolInfo: () => getMCPToolInfo,
|
|
22379
|
+
jsonSchemaToZod: () => jsonSchemaToZod,
|
|
22380
|
+
registerMCPTools: () => registerMCPTools,
|
|
22381
|
+
wrapMCPTool: () => wrapMCPTool,
|
|
22382
|
+
wrapMCPTools: () => wrapMCPTools
|
|
22383
|
+
});
|
|
22384
|
+
function buildMcpToolDescription(serverName, tool) {
|
|
22385
|
+
const base = tool.description || `Tool '${tool.name}' exposed by MCP server '${serverName}'`;
|
|
22386
|
+
const lowerServer = serverName.toLowerCase();
|
|
22387
|
+
if (lowerServer.includes("atlassian") || lowerServer.includes("jira") || lowerServer.includes("confluence")) {
|
|
22388
|
+
return `${base}. Use this MCP tool for Atlassian/Jira/Confluence data. Prefer it over direct web_fetch or http_fetch for Atlassian content.`;
|
|
22389
|
+
}
|
|
22390
|
+
return `${base}. Exposed by MCP server '${serverName}'. Prefer this MCP tool over generic web/http fetch when accessing data from that connected service.`;
|
|
22391
|
+
}
|
|
22392
|
+
function jsonSchemaToZod(schema) {
|
|
22393
|
+
if (schema.enum && Array.isArray(schema.enum)) {
|
|
22394
|
+
const values = schema.enum;
|
|
22395
|
+
if (values.length > 0 && values.every((v) => typeof v === "string")) {
|
|
22396
|
+
return z.enum(values);
|
|
22397
|
+
}
|
|
22398
|
+
const literals = values.map((v) => z.literal(v));
|
|
22399
|
+
if (literals.length < 2) {
|
|
22400
|
+
return literals[0] ?? z.any();
|
|
22401
|
+
}
|
|
22402
|
+
return z.union(literals);
|
|
22403
|
+
}
|
|
22404
|
+
if (schema.const !== void 0) {
|
|
22405
|
+
return z.literal(schema.const);
|
|
22406
|
+
}
|
|
22407
|
+
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
22408
|
+
const schemas = schema.oneOf.map(jsonSchemaToZod);
|
|
22409
|
+
if (schemas.length >= 2) {
|
|
22410
|
+
return z.union(schemas);
|
|
22411
|
+
}
|
|
22412
|
+
return schemas[0] ?? z.unknown();
|
|
22413
|
+
}
|
|
22414
|
+
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
|
22415
|
+
const schemas = schema.anyOf.map(jsonSchemaToZod);
|
|
22416
|
+
if (schemas.length >= 2) {
|
|
22417
|
+
return z.union(schemas);
|
|
22418
|
+
}
|
|
22419
|
+
return schemas[0] ?? z.unknown();
|
|
22420
|
+
}
|
|
22421
|
+
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
22422
|
+
const schemas = schema.allOf.map(jsonSchemaToZod);
|
|
22423
|
+
return schemas.reduce((acc, s) => z.intersection(acc, s));
|
|
22424
|
+
}
|
|
22425
|
+
const type = schema.type;
|
|
22426
|
+
const makeNullable = (s) => {
|
|
22427
|
+
if (schema.nullable === true) return s.nullable();
|
|
22428
|
+
return s;
|
|
22429
|
+
};
|
|
22430
|
+
switch (type) {
|
|
22431
|
+
case "string": {
|
|
22432
|
+
let s = z.string();
|
|
22433
|
+
if (schema.format) {
|
|
22434
|
+
switch (schema.format) {
|
|
22435
|
+
case "uri":
|
|
22436
|
+
case "url":
|
|
22437
|
+
s = z.string().url();
|
|
22438
|
+
break;
|
|
22439
|
+
case "email":
|
|
22440
|
+
s = z.string().email();
|
|
22441
|
+
break;
|
|
22442
|
+
case "date-time":
|
|
22443
|
+
case "datetime":
|
|
22444
|
+
s = z.string().datetime();
|
|
22445
|
+
break;
|
|
22446
|
+
}
|
|
22447
|
+
}
|
|
22448
|
+
if (typeof schema.minLength === "number") s = s.min(schema.minLength);
|
|
22449
|
+
if (typeof schema.maxLength === "number") s = s.max(schema.maxLength);
|
|
22450
|
+
return makeNullable(s);
|
|
22451
|
+
}
|
|
22452
|
+
case "number": {
|
|
22453
|
+
let n = z.number();
|
|
22454
|
+
if (typeof schema.minimum === "number") n = n.min(schema.minimum);
|
|
22455
|
+
if (typeof schema.maximum === "number") n = n.max(schema.maximum);
|
|
22456
|
+
if (typeof schema.exclusiveMinimum === "number") n = n.gt(schema.exclusiveMinimum);
|
|
22457
|
+
if (typeof schema.exclusiveMaximum === "number") n = n.lt(schema.exclusiveMaximum);
|
|
22458
|
+
return makeNullable(n);
|
|
22459
|
+
}
|
|
22460
|
+
case "integer": {
|
|
22461
|
+
let n = z.number().int();
|
|
22462
|
+
if (typeof schema.minimum === "number") n = n.min(schema.minimum);
|
|
22463
|
+
if (typeof schema.maximum === "number") n = n.max(schema.maximum);
|
|
22464
|
+
return makeNullable(n);
|
|
22465
|
+
}
|
|
22466
|
+
case "boolean":
|
|
22467
|
+
return makeNullable(z.boolean());
|
|
22468
|
+
case "null":
|
|
22469
|
+
return z.null();
|
|
22470
|
+
case "array":
|
|
22471
|
+
if (schema.items) {
|
|
22472
|
+
const itemSchema = jsonSchemaToZod(schema.items);
|
|
22473
|
+
let arr = z.array(itemSchema);
|
|
22474
|
+
if (typeof schema.minItems === "number") arr = arr.min(schema.minItems);
|
|
22475
|
+
if (typeof schema.maxItems === "number") arr = arr.max(schema.maxItems);
|
|
22476
|
+
return makeNullable(arr);
|
|
22477
|
+
}
|
|
22478
|
+
return makeNullable(z.array(z.unknown()));
|
|
22479
|
+
case "object": {
|
|
22480
|
+
const properties = schema.properties;
|
|
22481
|
+
const required = schema.required;
|
|
22482
|
+
if (!properties) {
|
|
22483
|
+
return makeNullable(z.record(z.string(), z.unknown()));
|
|
22484
|
+
}
|
|
22485
|
+
const shape = {};
|
|
22486
|
+
for (const [key, propSchema] of Object.entries(properties)) {
|
|
22487
|
+
let fieldSchema = jsonSchemaToZod(propSchema);
|
|
22488
|
+
if (!required?.includes(key)) {
|
|
22489
|
+
fieldSchema = fieldSchema.optional();
|
|
22490
|
+
}
|
|
22491
|
+
if (propSchema.description && typeof propSchema.description === "string") {
|
|
22492
|
+
fieldSchema = fieldSchema.describe(propSchema.description);
|
|
22493
|
+
}
|
|
22494
|
+
shape[key] = fieldSchema;
|
|
22495
|
+
}
|
|
22496
|
+
return makeNullable(z.object(shape));
|
|
22497
|
+
}
|
|
22498
|
+
default:
|
|
22499
|
+
if (Array.isArray(schema.type)) {
|
|
22500
|
+
const types = schema.type;
|
|
22501
|
+
if (types.includes("null")) {
|
|
22502
|
+
const nonNullType = types.find((t) => t !== "null");
|
|
22503
|
+
if (nonNullType) {
|
|
22504
|
+
return jsonSchemaToZod({ ...schema, type: nonNullType }).nullable();
|
|
22505
|
+
}
|
|
22506
|
+
}
|
|
22507
|
+
}
|
|
22508
|
+
return z.unknown();
|
|
22509
|
+
}
|
|
22510
|
+
}
|
|
22511
|
+
function createToolParametersSchema(tool) {
|
|
22512
|
+
const schema = tool.inputSchema;
|
|
22513
|
+
if (!schema || schema.type !== "object") {
|
|
22514
|
+
return z.object({});
|
|
22515
|
+
}
|
|
22516
|
+
return jsonSchemaToZod(schema);
|
|
22517
|
+
}
|
|
22518
|
+
function formatToolResult(result) {
|
|
22519
|
+
if (result.isError) {
|
|
22520
|
+
throw new Error(result.content.map((c) => c.text || "").join("\n"));
|
|
22521
|
+
}
|
|
22522
|
+
return result.content.map((item) => {
|
|
22523
|
+
switch (item.type) {
|
|
22524
|
+
case "text":
|
|
22525
|
+
return item.text || "";
|
|
22526
|
+
case "image":
|
|
22527
|
+
return `[Image: ${item.mimeType || "unknown"}]`;
|
|
22528
|
+
case "resource":
|
|
22529
|
+
return `[Resource: ${item.resource?.uri || "unknown"}]`;
|
|
22530
|
+
default:
|
|
22531
|
+
return "";
|
|
22532
|
+
}
|
|
22533
|
+
}).filter(Boolean).join("\n");
|
|
22534
|
+
}
|
|
22535
|
+
function createToolName(serverName, toolName, prefix) {
|
|
22536
|
+
return `${prefix}_${serverName}_${toolName}`.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
22537
|
+
}
|
|
22538
|
+
function wrapMCPTool(tool, serverName, client, options = {}) {
|
|
22539
|
+
const opts = { ...DEFAULT_OPTIONS2, ...options };
|
|
22540
|
+
const wrappedName = createToolName(serverName, tool.name, opts.namePrefix);
|
|
22541
|
+
const parametersSchema = createToolParametersSchema(tool);
|
|
22542
|
+
const cocoTool = {
|
|
22543
|
+
name: wrappedName,
|
|
22544
|
+
description: buildMcpToolDescription(serverName, tool),
|
|
22545
|
+
category: opts.category,
|
|
22546
|
+
parameters: parametersSchema,
|
|
22547
|
+
execute: async (params) => {
|
|
22548
|
+
const timeout = opts.requestTimeout;
|
|
22549
|
+
try {
|
|
22550
|
+
const result = await Promise.race([
|
|
22551
|
+
client.callTool({
|
|
22552
|
+
name: tool.name,
|
|
22553
|
+
arguments: params
|
|
22554
|
+
}),
|
|
22555
|
+
new Promise((_, reject) => {
|
|
22556
|
+
setTimeout(() => {
|
|
22557
|
+
reject(new MCPTimeoutError(`Tool '${tool.name}' timed out after ${timeout}ms`));
|
|
22558
|
+
}, timeout);
|
|
22559
|
+
})
|
|
22560
|
+
]);
|
|
22561
|
+
return formatToolResult(result);
|
|
22562
|
+
} catch (error) {
|
|
22563
|
+
if (error instanceof MCPError) {
|
|
22564
|
+
throw error;
|
|
22565
|
+
}
|
|
22566
|
+
throw new MCPError(
|
|
22567
|
+
-32603,
|
|
22568
|
+
`Tool execution failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
22569
|
+
);
|
|
22570
|
+
}
|
|
22571
|
+
}
|
|
22572
|
+
};
|
|
22573
|
+
const wrapped = {
|
|
22574
|
+
originalTool: tool,
|
|
22575
|
+
serverName,
|
|
22576
|
+
wrappedName
|
|
22577
|
+
};
|
|
22578
|
+
return { tool: cocoTool, wrapped };
|
|
22579
|
+
}
|
|
22580
|
+
function wrapMCPTools(tools, serverName, client, options = {}) {
|
|
22581
|
+
const cocoTools = [];
|
|
22582
|
+
const wrappedTools = [];
|
|
22583
|
+
for (const tool of tools) {
|
|
22584
|
+
const { tool: cocoTool, wrapped } = wrapMCPTool(tool, serverName, client, options);
|
|
22585
|
+
cocoTools.push(cocoTool);
|
|
22586
|
+
wrappedTools.push(wrapped);
|
|
22587
|
+
}
|
|
22588
|
+
return { tools: cocoTools, wrapped: wrappedTools };
|
|
22589
|
+
}
|
|
22590
|
+
async function createToolsFromMCPServer(serverName, client, options = {}) {
|
|
22591
|
+
if (!client.isConnected()) {
|
|
22592
|
+
await client.initialize({
|
|
22593
|
+
protocolVersion: "2024-11-05",
|
|
22594
|
+
capabilities: {},
|
|
22595
|
+
clientInfo: { name: "coco-mcp-client", version: "0.2.0" }
|
|
22596
|
+
});
|
|
22597
|
+
}
|
|
22598
|
+
const { tools } = await client.listTools();
|
|
22599
|
+
return wrapMCPTools(tools, serverName, client, options);
|
|
22600
|
+
}
|
|
22601
|
+
async function registerMCPTools(registry, serverName, client, options = {}) {
|
|
22602
|
+
const { tools, wrapped } = await createToolsFromMCPServer(serverName, client, options);
|
|
22603
|
+
for (const tool of tools) {
|
|
22604
|
+
registry.register(tool);
|
|
22605
|
+
}
|
|
22606
|
+
return wrapped;
|
|
22607
|
+
}
|
|
22608
|
+
function getMCPToolInfo(wrappedName, wrappedTools) {
|
|
22609
|
+
return wrappedTools.find((t) => t.wrappedName === wrappedName);
|
|
22610
|
+
}
|
|
22611
|
+
function extractOriginalToolName(wrappedName, serverName, prefix = "mcp") {
|
|
22612
|
+
const prefix_pattern = `${prefix}_${serverName}_`;
|
|
22613
|
+
if (wrappedName.startsWith(prefix_pattern)) {
|
|
22614
|
+
return wrappedName.slice(prefix_pattern.length);
|
|
22615
|
+
}
|
|
22616
|
+
return null;
|
|
22617
|
+
}
|
|
22618
|
+
var DEFAULT_OPTIONS2;
|
|
22619
|
+
var init_tools = __esm({
|
|
22620
|
+
"src/mcp/tools.ts"() {
|
|
22621
|
+
init_errors2();
|
|
22622
|
+
DEFAULT_OPTIONS2 = {
|
|
22623
|
+
namePrefix: "mcp",
|
|
22624
|
+
category: "deploy",
|
|
22625
|
+
requestTimeout: 6e4
|
|
22626
|
+
};
|
|
22627
|
+
}
|
|
22628
|
+
});
|
|
22629
|
+
|
|
22370
22630
|
// src/cli/repl/allow-path-prompt.ts
|
|
22371
22631
|
var allow_path_prompt_exports = {};
|
|
22372
22632
|
__export(allow_path_prompt_exports, {
|
|
@@ -22815,263 +23075,6 @@ var init_stack_detector = __esm({
|
|
|
22815
23075
|
}
|
|
22816
23076
|
});
|
|
22817
23077
|
|
|
22818
|
-
// src/mcp/tools.ts
|
|
22819
|
-
var tools_exports = {};
|
|
22820
|
-
__export(tools_exports, {
|
|
22821
|
-
createToolsFromMCPServer: () => createToolsFromMCPServer,
|
|
22822
|
-
extractOriginalToolName: () => extractOriginalToolName,
|
|
22823
|
-
getMCPToolInfo: () => getMCPToolInfo,
|
|
22824
|
-
jsonSchemaToZod: () => jsonSchemaToZod,
|
|
22825
|
-
registerMCPTools: () => registerMCPTools,
|
|
22826
|
-
wrapMCPTool: () => wrapMCPTool,
|
|
22827
|
-
wrapMCPTools: () => wrapMCPTools
|
|
22828
|
-
});
|
|
22829
|
-
function buildMcpToolDescription(serverName, tool) {
|
|
22830
|
-
const base = tool.description || `Tool '${tool.name}' exposed by MCP server '${serverName}'`;
|
|
22831
|
-
const lowerServer = serverName.toLowerCase();
|
|
22832
|
-
if (lowerServer.includes("atlassian") || lowerServer.includes("jira") || lowerServer.includes("confluence")) {
|
|
22833
|
-
return `${base}. Use this MCP tool for Atlassian/Jira/Confluence data. Prefer it over direct web_fetch or http_fetch for Atlassian content.`;
|
|
22834
|
-
}
|
|
22835
|
-
return `${base}. Exposed by MCP server '${serverName}'. Prefer this MCP tool over generic web/http fetch when accessing data from that connected service.`;
|
|
22836
|
-
}
|
|
22837
|
-
function jsonSchemaToZod(schema) {
|
|
22838
|
-
if (schema.enum && Array.isArray(schema.enum)) {
|
|
22839
|
-
const values = schema.enum;
|
|
22840
|
-
if (values.length > 0 && values.every((v) => typeof v === "string")) {
|
|
22841
|
-
return z.enum(values);
|
|
22842
|
-
}
|
|
22843
|
-
const literals = values.map((v) => z.literal(v));
|
|
22844
|
-
if (literals.length < 2) {
|
|
22845
|
-
return literals[0] ?? z.any();
|
|
22846
|
-
}
|
|
22847
|
-
return z.union(literals);
|
|
22848
|
-
}
|
|
22849
|
-
if (schema.const !== void 0) {
|
|
22850
|
-
return z.literal(schema.const);
|
|
22851
|
-
}
|
|
22852
|
-
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
22853
|
-
const schemas = schema.oneOf.map(jsonSchemaToZod);
|
|
22854
|
-
if (schemas.length >= 2) {
|
|
22855
|
-
return z.union(schemas);
|
|
22856
|
-
}
|
|
22857
|
-
return schemas[0] ?? z.unknown();
|
|
22858
|
-
}
|
|
22859
|
-
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
|
22860
|
-
const schemas = schema.anyOf.map(jsonSchemaToZod);
|
|
22861
|
-
if (schemas.length >= 2) {
|
|
22862
|
-
return z.union(schemas);
|
|
22863
|
-
}
|
|
22864
|
-
return schemas[0] ?? z.unknown();
|
|
22865
|
-
}
|
|
22866
|
-
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
22867
|
-
const schemas = schema.allOf.map(jsonSchemaToZod);
|
|
22868
|
-
return schemas.reduce((acc, s) => z.intersection(acc, s));
|
|
22869
|
-
}
|
|
22870
|
-
const type = schema.type;
|
|
22871
|
-
const makeNullable = (s) => {
|
|
22872
|
-
if (schema.nullable === true) return s.nullable();
|
|
22873
|
-
return s;
|
|
22874
|
-
};
|
|
22875
|
-
switch (type) {
|
|
22876
|
-
case "string": {
|
|
22877
|
-
let s = z.string();
|
|
22878
|
-
if (schema.format) {
|
|
22879
|
-
switch (schema.format) {
|
|
22880
|
-
case "uri":
|
|
22881
|
-
case "url":
|
|
22882
|
-
s = z.string().url();
|
|
22883
|
-
break;
|
|
22884
|
-
case "email":
|
|
22885
|
-
s = z.string().email();
|
|
22886
|
-
break;
|
|
22887
|
-
case "date-time":
|
|
22888
|
-
case "datetime":
|
|
22889
|
-
s = z.string().datetime();
|
|
22890
|
-
break;
|
|
22891
|
-
}
|
|
22892
|
-
}
|
|
22893
|
-
if (typeof schema.minLength === "number") s = s.min(schema.minLength);
|
|
22894
|
-
if (typeof schema.maxLength === "number") s = s.max(schema.maxLength);
|
|
22895
|
-
return makeNullable(s);
|
|
22896
|
-
}
|
|
22897
|
-
case "number": {
|
|
22898
|
-
let n = z.number();
|
|
22899
|
-
if (typeof schema.minimum === "number") n = n.min(schema.minimum);
|
|
22900
|
-
if (typeof schema.maximum === "number") n = n.max(schema.maximum);
|
|
22901
|
-
if (typeof schema.exclusiveMinimum === "number") n = n.gt(schema.exclusiveMinimum);
|
|
22902
|
-
if (typeof schema.exclusiveMaximum === "number") n = n.lt(schema.exclusiveMaximum);
|
|
22903
|
-
return makeNullable(n);
|
|
22904
|
-
}
|
|
22905
|
-
case "integer": {
|
|
22906
|
-
let n = z.number().int();
|
|
22907
|
-
if (typeof schema.minimum === "number") n = n.min(schema.minimum);
|
|
22908
|
-
if (typeof schema.maximum === "number") n = n.max(schema.maximum);
|
|
22909
|
-
return makeNullable(n);
|
|
22910
|
-
}
|
|
22911
|
-
case "boolean":
|
|
22912
|
-
return makeNullable(z.boolean());
|
|
22913
|
-
case "null":
|
|
22914
|
-
return z.null();
|
|
22915
|
-
case "array":
|
|
22916
|
-
if (schema.items) {
|
|
22917
|
-
const itemSchema = jsonSchemaToZod(schema.items);
|
|
22918
|
-
let arr = z.array(itemSchema);
|
|
22919
|
-
if (typeof schema.minItems === "number") arr = arr.min(schema.minItems);
|
|
22920
|
-
if (typeof schema.maxItems === "number") arr = arr.max(schema.maxItems);
|
|
22921
|
-
return makeNullable(arr);
|
|
22922
|
-
}
|
|
22923
|
-
return makeNullable(z.array(z.unknown()));
|
|
22924
|
-
case "object": {
|
|
22925
|
-
const properties = schema.properties;
|
|
22926
|
-
const required = schema.required;
|
|
22927
|
-
if (!properties) {
|
|
22928
|
-
return makeNullable(z.record(z.string(), z.unknown()));
|
|
22929
|
-
}
|
|
22930
|
-
const shape = {};
|
|
22931
|
-
for (const [key, propSchema] of Object.entries(properties)) {
|
|
22932
|
-
let fieldSchema = jsonSchemaToZod(propSchema);
|
|
22933
|
-
if (!required?.includes(key)) {
|
|
22934
|
-
fieldSchema = fieldSchema.optional();
|
|
22935
|
-
}
|
|
22936
|
-
if (propSchema.description && typeof propSchema.description === "string") {
|
|
22937
|
-
fieldSchema = fieldSchema.describe(propSchema.description);
|
|
22938
|
-
}
|
|
22939
|
-
shape[key] = fieldSchema;
|
|
22940
|
-
}
|
|
22941
|
-
return makeNullable(z.object(shape));
|
|
22942
|
-
}
|
|
22943
|
-
default:
|
|
22944
|
-
if (Array.isArray(schema.type)) {
|
|
22945
|
-
const types = schema.type;
|
|
22946
|
-
if (types.includes("null")) {
|
|
22947
|
-
const nonNullType = types.find((t) => t !== "null");
|
|
22948
|
-
if (nonNullType) {
|
|
22949
|
-
return jsonSchemaToZod({ ...schema, type: nonNullType }).nullable();
|
|
22950
|
-
}
|
|
22951
|
-
}
|
|
22952
|
-
}
|
|
22953
|
-
return z.unknown();
|
|
22954
|
-
}
|
|
22955
|
-
}
|
|
22956
|
-
function createToolParametersSchema(tool) {
|
|
22957
|
-
const schema = tool.inputSchema;
|
|
22958
|
-
if (!schema || schema.type !== "object") {
|
|
22959
|
-
return z.object({});
|
|
22960
|
-
}
|
|
22961
|
-
return jsonSchemaToZod(schema);
|
|
22962
|
-
}
|
|
22963
|
-
function formatToolResult(result) {
|
|
22964
|
-
if (result.isError) {
|
|
22965
|
-
throw new Error(result.content.map((c) => c.text || "").join("\n"));
|
|
22966
|
-
}
|
|
22967
|
-
return result.content.map((item) => {
|
|
22968
|
-
switch (item.type) {
|
|
22969
|
-
case "text":
|
|
22970
|
-
return item.text || "";
|
|
22971
|
-
case "image":
|
|
22972
|
-
return `[Image: ${item.mimeType || "unknown"}]`;
|
|
22973
|
-
case "resource":
|
|
22974
|
-
return `[Resource: ${item.resource?.uri || "unknown"}]`;
|
|
22975
|
-
default:
|
|
22976
|
-
return "";
|
|
22977
|
-
}
|
|
22978
|
-
}).filter(Boolean).join("\n");
|
|
22979
|
-
}
|
|
22980
|
-
function createToolName(serverName, toolName, prefix) {
|
|
22981
|
-
return `${prefix}_${serverName}_${toolName}`.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
22982
|
-
}
|
|
22983
|
-
function wrapMCPTool(tool, serverName, client, options = {}) {
|
|
22984
|
-
const opts = { ...DEFAULT_OPTIONS2, ...options };
|
|
22985
|
-
const wrappedName = createToolName(serverName, tool.name, opts.namePrefix);
|
|
22986
|
-
const parametersSchema = createToolParametersSchema(tool);
|
|
22987
|
-
const cocoTool = {
|
|
22988
|
-
name: wrappedName,
|
|
22989
|
-
description: buildMcpToolDescription(serverName, tool),
|
|
22990
|
-
category: opts.category,
|
|
22991
|
-
parameters: parametersSchema,
|
|
22992
|
-
execute: async (params) => {
|
|
22993
|
-
const timeout = opts.requestTimeout;
|
|
22994
|
-
try {
|
|
22995
|
-
const result = await Promise.race([
|
|
22996
|
-
client.callTool({
|
|
22997
|
-
name: tool.name,
|
|
22998
|
-
arguments: params
|
|
22999
|
-
}),
|
|
23000
|
-
new Promise((_, reject) => {
|
|
23001
|
-
setTimeout(() => {
|
|
23002
|
-
reject(new MCPTimeoutError(`Tool '${tool.name}' timed out after ${timeout}ms`));
|
|
23003
|
-
}, timeout);
|
|
23004
|
-
})
|
|
23005
|
-
]);
|
|
23006
|
-
return formatToolResult(result);
|
|
23007
|
-
} catch (error) {
|
|
23008
|
-
if (error instanceof MCPError) {
|
|
23009
|
-
throw error;
|
|
23010
|
-
}
|
|
23011
|
-
throw new MCPError(
|
|
23012
|
-
-32603,
|
|
23013
|
-
`Tool execution failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
23014
|
-
);
|
|
23015
|
-
}
|
|
23016
|
-
}
|
|
23017
|
-
};
|
|
23018
|
-
const wrapped = {
|
|
23019
|
-
originalTool: tool,
|
|
23020
|
-
serverName,
|
|
23021
|
-
wrappedName
|
|
23022
|
-
};
|
|
23023
|
-
return { tool: cocoTool, wrapped };
|
|
23024
|
-
}
|
|
23025
|
-
function wrapMCPTools(tools, serverName, client, options = {}) {
|
|
23026
|
-
const cocoTools = [];
|
|
23027
|
-
const wrappedTools = [];
|
|
23028
|
-
for (const tool of tools) {
|
|
23029
|
-
const { tool: cocoTool, wrapped } = wrapMCPTool(tool, serverName, client, options);
|
|
23030
|
-
cocoTools.push(cocoTool);
|
|
23031
|
-
wrappedTools.push(wrapped);
|
|
23032
|
-
}
|
|
23033
|
-
return { tools: cocoTools, wrapped: wrappedTools };
|
|
23034
|
-
}
|
|
23035
|
-
async function createToolsFromMCPServer(serverName, client, options = {}) {
|
|
23036
|
-
if (!client.isConnected()) {
|
|
23037
|
-
await client.initialize({
|
|
23038
|
-
protocolVersion: "2024-11-05",
|
|
23039
|
-
capabilities: {},
|
|
23040
|
-
clientInfo: { name: "coco-mcp-client", version: "0.2.0" }
|
|
23041
|
-
});
|
|
23042
|
-
}
|
|
23043
|
-
const { tools } = await client.listTools();
|
|
23044
|
-
return wrapMCPTools(tools, serverName, client, options);
|
|
23045
|
-
}
|
|
23046
|
-
async function registerMCPTools(registry, serverName, client, options = {}) {
|
|
23047
|
-
const { tools, wrapped } = await createToolsFromMCPServer(serverName, client, options);
|
|
23048
|
-
for (const tool of tools) {
|
|
23049
|
-
registry.register(tool);
|
|
23050
|
-
}
|
|
23051
|
-
return wrapped;
|
|
23052
|
-
}
|
|
23053
|
-
function getMCPToolInfo(wrappedName, wrappedTools) {
|
|
23054
|
-
return wrappedTools.find((t) => t.wrappedName === wrappedName);
|
|
23055
|
-
}
|
|
23056
|
-
function extractOriginalToolName(wrappedName, serverName, prefix = "mcp") {
|
|
23057
|
-
const prefix_pattern = `${prefix}_${serverName}_`;
|
|
23058
|
-
if (wrappedName.startsWith(prefix_pattern)) {
|
|
23059
|
-
return wrappedName.slice(prefix_pattern.length);
|
|
23060
|
-
}
|
|
23061
|
-
return null;
|
|
23062
|
-
}
|
|
23063
|
-
var DEFAULT_OPTIONS2;
|
|
23064
|
-
var init_tools = __esm({
|
|
23065
|
-
"src/mcp/tools.ts"() {
|
|
23066
|
-
init_errors2();
|
|
23067
|
-
DEFAULT_OPTIONS2 = {
|
|
23068
|
-
namePrefix: "mcp",
|
|
23069
|
-
category: "deploy",
|
|
23070
|
-
requestTimeout: 6e4
|
|
23071
|
-
};
|
|
23072
|
-
}
|
|
23073
|
-
});
|
|
23074
|
-
|
|
23075
23078
|
// src/cli/repl/hooks/types.ts
|
|
23076
23079
|
function isHookEvent(value) {
|
|
23077
23080
|
return typeof value === "string" && HOOK_EVENTS.includes(value);
|
|
@@ -38297,6 +38300,9 @@ var RECOMMENDED_DENY = [
|
|
|
38297
38300
|
"bash:eval",
|
|
38298
38301
|
"bash:source"
|
|
38299
38302
|
];
|
|
38303
|
+
function getProjectPreferenceKey(projectPath) {
|
|
38304
|
+
return path39__default.resolve(projectPath);
|
|
38305
|
+
}
|
|
38300
38306
|
async function loadPermissionPreferences() {
|
|
38301
38307
|
try {
|
|
38302
38308
|
const content = await fs35__default.readFile(CONFIG_PATHS.config, "utf-8");
|
|
@@ -38304,7 +38310,8 @@ async function loadPermissionPreferences() {
|
|
|
38304
38310
|
return {
|
|
38305
38311
|
recommendedAllowlistApplied: config.recommendedAllowlistApplied,
|
|
38306
38312
|
recommendedAllowlistDismissed: config.recommendedAllowlistDismissed,
|
|
38307
|
-
recommendedAllowlistPrompted: config.recommendedAllowlistPrompted
|
|
38313
|
+
recommendedAllowlistPrompted: config.recommendedAllowlistPrompted,
|
|
38314
|
+
recommendedAllowlistPromptedProjects: config.recommendedAllowlistPromptedProjects
|
|
38308
38315
|
};
|
|
38309
38316
|
} catch {
|
|
38310
38317
|
return {};
|
|
@@ -38324,7 +38331,26 @@ async function savePermissionPreference(key, value) {
|
|
|
38324
38331
|
} catch {
|
|
38325
38332
|
}
|
|
38326
38333
|
}
|
|
38327
|
-
async function
|
|
38334
|
+
async function markPermissionSuggestionShownForProject(projectPath) {
|
|
38335
|
+
try {
|
|
38336
|
+
let config = {};
|
|
38337
|
+
try {
|
|
38338
|
+
const content = await fs35__default.readFile(CONFIG_PATHS.config, "utf-8");
|
|
38339
|
+
config = JSON.parse(content);
|
|
38340
|
+
} catch {
|
|
38341
|
+
}
|
|
38342
|
+
const promptedProjects = {
|
|
38343
|
+
...config.recommendedAllowlistPromptedProjects,
|
|
38344
|
+
[getProjectPreferenceKey(projectPath)]: true
|
|
38345
|
+
};
|
|
38346
|
+
config.recommendedAllowlistPromptedProjects = promptedProjects;
|
|
38347
|
+
config.recommendedAllowlistPrompted = true;
|
|
38348
|
+
await fs35__default.mkdir(path39__default.dirname(CONFIG_PATHS.config), { recursive: true });
|
|
38349
|
+
await fs35__default.writeFile(CONFIG_PATHS.config, JSON.stringify(config, null, 2), "utf-8");
|
|
38350
|
+
} catch {
|
|
38351
|
+
}
|
|
38352
|
+
}
|
|
38353
|
+
async function shouldShowPermissionSuggestion(projectPath = process.cwd()) {
|
|
38328
38354
|
const prefs = await loadPermissionPreferences();
|
|
38329
38355
|
if (prefs.recommendedAllowlistDismissed) {
|
|
38330
38356
|
return false;
|
|
@@ -38332,6 +38358,10 @@ async function shouldShowPermissionSuggestion() {
|
|
|
38332
38358
|
if (prefs.recommendedAllowlistApplied) {
|
|
38333
38359
|
return false;
|
|
38334
38360
|
}
|
|
38361
|
+
const projectKey = getProjectPreferenceKey(projectPath);
|
|
38362
|
+
if (prefs.recommendedAllowlistPromptedProjects?.[projectKey]) {
|
|
38363
|
+
return false;
|
|
38364
|
+
}
|
|
38335
38365
|
return true;
|
|
38336
38366
|
}
|
|
38337
38367
|
async function applyRecommendedPermissions() {
|
|
@@ -38340,7 +38370,8 @@ async function applyRecommendedPermissions() {
|
|
|
38340
38370
|
}
|
|
38341
38371
|
await savePermissionPreference("recommendedAllowlistApplied", true);
|
|
38342
38372
|
}
|
|
38343
|
-
async function showPermissionSuggestion() {
|
|
38373
|
+
async function showPermissionSuggestion(projectPath = process.cwd()) {
|
|
38374
|
+
await markPermissionSuggestionShownForProject(projectPath);
|
|
38344
38375
|
console.log();
|
|
38345
38376
|
console.log(chalk.magenta.bold(" \u{1F4CB} Recommended Permissions"));
|
|
38346
38377
|
console.log();
|
|
@@ -47396,6 +47427,27 @@ init_registry4();
|
|
|
47396
47427
|
init_registry();
|
|
47397
47428
|
init_config_loader();
|
|
47398
47429
|
init_lifecycle();
|
|
47430
|
+
init_tools();
|
|
47431
|
+
async function loadConfiguredServers(projectPath) {
|
|
47432
|
+
const registry = new MCPRegistryImpl();
|
|
47433
|
+
await registry.load();
|
|
47434
|
+
const resolvedProjectPath = projectPath || process.cwd();
|
|
47435
|
+
return mergeMCPConfigs(
|
|
47436
|
+
registry.listServers(),
|
|
47437
|
+
await loadMCPServersFromCOCOConfig(),
|
|
47438
|
+
await loadProjectMCPFile(resolvedProjectPath)
|
|
47439
|
+
);
|
|
47440
|
+
}
|
|
47441
|
+
function findConfiguredServer(servers, requestedServer) {
|
|
47442
|
+
const normalized = requestedServer.trim().toLowerCase();
|
|
47443
|
+
return servers.find((server) => {
|
|
47444
|
+
const name = server.name.toLowerCase();
|
|
47445
|
+
if (name === normalized) return true;
|
|
47446
|
+
if (name.includes(normalized) || normalized.includes(name)) return true;
|
|
47447
|
+
if (name.includes("atlassian") && /^(atlassian|jira|confluence)$/.test(normalized)) return true;
|
|
47448
|
+
return false;
|
|
47449
|
+
});
|
|
47450
|
+
}
|
|
47399
47451
|
var mcpListServersTool = defineTool({
|
|
47400
47452
|
name: "mcp_list_servers",
|
|
47401
47453
|
description: `Inspect Coco's MCP configuration and current runtime connections.
|
|
@@ -47409,14 +47461,9 @@ when you need to know which MCP servers are configured, connected, healthy, or w
|
|
|
47409
47461
|
projectPath: z.string().optional().describe("Project path whose .mcp.json should be merged. Defaults to process.cwd()")
|
|
47410
47462
|
}),
|
|
47411
47463
|
async execute({ includeDisabled, includeTools, projectPath }) {
|
|
47412
|
-
const
|
|
47413
|
-
|
|
47414
|
-
|
|
47415
|
-
const configuredServers = mergeMCPConfigs(
|
|
47416
|
-
registry.listServers(),
|
|
47417
|
-
await loadMCPServersFromCOCOConfig(),
|
|
47418
|
-
await loadProjectMCPFile(resolvedProjectPath)
|
|
47419
|
-
).filter((server) => includeDisabled || server.enabled !== false);
|
|
47464
|
+
const configuredServers = (await loadConfiguredServers(projectPath)).filter(
|
|
47465
|
+
(server) => includeDisabled || server.enabled !== false
|
|
47466
|
+
);
|
|
47420
47467
|
const manager = getMCPServerManager();
|
|
47421
47468
|
const servers = [];
|
|
47422
47469
|
for (const server of configuredServers) {
|
|
@@ -47447,7 +47494,59 @@ when you need to know which MCP servers are configured, connected, healthy, or w
|
|
|
47447
47494
|
};
|
|
47448
47495
|
}
|
|
47449
47496
|
});
|
|
47450
|
-
var
|
|
47497
|
+
var mcpConnectServerTool = defineTool({
|
|
47498
|
+
name: "mcp_connect_server",
|
|
47499
|
+
description: `Connect or reconnect a configured MCP server in the current Coco session.
|
|
47500
|
+
|
|
47501
|
+
Use this when mcp_list_servers shows a service as configured but disconnected, or when
|
|
47502
|
+
the user explicitly asks you to use a specific MCP service. This tool can trigger the
|
|
47503
|
+
built-in MCP OAuth browser login flow. Do not ask the user for raw tokens when this exists.`,
|
|
47504
|
+
category: "config",
|
|
47505
|
+
parameters: z.object({
|
|
47506
|
+
server: z.string().describe("Configured MCP server name, or a common alias like 'jira' or 'atlassian'"),
|
|
47507
|
+
includeTools: z.boolean().optional().default(true).describe("Include discovered MCP tool names after connecting"),
|
|
47508
|
+
projectPath: z.string().optional().describe("Project path whose .mcp.json should be merged. Defaults to process.cwd()")
|
|
47509
|
+
}),
|
|
47510
|
+
async execute({ server, includeTools, projectPath }) {
|
|
47511
|
+
const configuredServers = await loadConfiguredServers(projectPath);
|
|
47512
|
+
const target = findConfiguredServer(
|
|
47513
|
+
configuredServers.filter((configuredServer) => configuredServer.enabled !== false),
|
|
47514
|
+
server
|
|
47515
|
+
);
|
|
47516
|
+
if (!target) {
|
|
47517
|
+
throw new Error(`MCP server '${server}' is not configured`);
|
|
47518
|
+
}
|
|
47519
|
+
const manager = getMCPServerManager();
|
|
47520
|
+
const existingConnection = manager.getConnection(target.name);
|
|
47521
|
+
if (existingConnection && existingConnection.healthy === false) {
|
|
47522
|
+
await manager.stopServer(target.name);
|
|
47523
|
+
}
|
|
47524
|
+
const connection = await manager.startServer(target);
|
|
47525
|
+
const toolRegistry = getAgentToolRegistry();
|
|
47526
|
+
if (toolRegistry) {
|
|
47527
|
+
await registerMCPTools(toolRegistry, connection.name, connection.client);
|
|
47528
|
+
}
|
|
47529
|
+
let tools;
|
|
47530
|
+
if (includeTools) {
|
|
47531
|
+
try {
|
|
47532
|
+
const listed = await connection.client.listTools();
|
|
47533
|
+
tools = listed.tools.map((tool) => tool.name);
|
|
47534
|
+
} catch {
|
|
47535
|
+
tools = [];
|
|
47536
|
+
}
|
|
47537
|
+
}
|
|
47538
|
+
return {
|
|
47539
|
+
requestedServer: server,
|
|
47540
|
+
connected: true,
|
|
47541
|
+
healthy: true,
|
|
47542
|
+
toolCount: connection.toolCount,
|
|
47543
|
+
...includeTools ? { tools: tools ?? [] } : {},
|
|
47544
|
+
authTriggered: target.transport === "http",
|
|
47545
|
+
message: `MCP server '${target.name}' is connected for this session.`
|
|
47546
|
+
};
|
|
47547
|
+
}
|
|
47548
|
+
});
|
|
47549
|
+
var mcpTools = [mcpListServersTool, mcpConnectServerTool];
|
|
47451
47550
|
|
|
47452
47551
|
// src/tools/index.ts
|
|
47453
47552
|
init_registry4();
|
|
@@ -53064,8 +53163,8 @@ async function startRepl(options = {}) {
|
|
|
53064
53163
|
]);
|
|
53065
53164
|
session.projectContext = projectContext;
|
|
53066
53165
|
await initializeSessionMemory(session);
|
|
53067
|
-
if (await shouldShowPermissionSuggestion()) {
|
|
53068
|
-
await showPermissionSuggestion();
|
|
53166
|
+
if (await shouldShowPermissionSuggestion(projectPath)) {
|
|
53167
|
+
await showPermissionSuggestion(projectPath);
|
|
53069
53168
|
const updatedTrust = await loadTrustedTools(projectPath);
|
|
53070
53169
|
for (const tool of updatedTrust) {
|
|
53071
53170
|
session.trustedTools.add(tool);
|
|
@@ -53169,7 +53268,11 @@ async function startRepl(options = {}) {
|
|
|
53169
53268
|
);
|
|
53170
53269
|
}
|
|
53171
53270
|
async function ensureRequestedMcpConnections(message) {
|
|
53172
|
-
if (
|
|
53271
|
+
if (configuredMcpServers.length === 0) return;
|
|
53272
|
+
if (!mcpManager) {
|
|
53273
|
+
const { getMCPServerManager: getMCPServerManager2 } = await Promise.resolve().then(() => (init_lifecycle(), lifecycle_exports));
|
|
53274
|
+
mcpManager = getMCPServerManager2();
|
|
53275
|
+
}
|
|
53173
53276
|
const normalizedMessage = message.toLowerCase();
|
|
53174
53277
|
const explicitlyRequestsMcp = /\bmcp\b/.test(normalizedMessage) || /\b(use|using|usa|usar|utiliza|utilizar)\b.{0,24}\bmcp\b/.test(normalizedMessage);
|
|
53175
53278
|
const matchingServers = configuredMcpServers.filter((server) => {
|
|
@@ -53184,13 +53287,13 @@ async function startRepl(options = {}) {
|
|
|
53184
53287
|
});
|
|
53185
53288
|
for (const server of matchingServers) {
|
|
53186
53289
|
try {
|
|
53290
|
+
const existingConnection = mcpManager.getConnection(server.name);
|
|
53291
|
+
if (existingConnection?.healthy === false) {
|
|
53292
|
+
await mcpManager.stopServer(server.name);
|
|
53293
|
+
}
|
|
53187
53294
|
const connection = await mcpManager.startServer(server);
|
|
53188
53295
|
if (!registeredMcpServers.has(connection.name)) {
|
|
53189
|
-
await (await Promise.resolve().then(() => (init_tools(), tools_exports))).registerMCPTools(
|
|
53190
|
-
toolRegistry,
|
|
53191
|
-
connection.name,
|
|
53192
|
-
connection.client
|
|
53193
|
-
);
|
|
53296
|
+
await (await Promise.resolve().then(() => (init_tools(), tools_exports))).registerMCPTools(toolRegistry, connection.name, connection.client);
|
|
53194
53297
|
registeredMcpServers.add(connection.name);
|
|
53195
53298
|
}
|
|
53196
53299
|
} catch (error) {
|