From bd88937d7ea4113549fea7754f0c1ca001aafe18 Mon Sep 17 00:00:00 2001 From: LiuVaayne <10231735+vaayne@users.noreply.github.com> Date: Sun, 18 May 2025 23:05:44 +0800 Subject: [PATCH] feat: add buildFunctionCallToolName utility for generating tool names (#6136) --- src/main/services/MCPService.ts | 3 ++- src/main/utils/mcp.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 src/main/utils/mcp.ts diff --git a/src/main/services/MCPService.ts b/src/main/services/MCPService.ts index 237e709deb..92db1c98a2 100644 --- a/src/main/services/MCPService.ts +++ b/src/main/services/MCPService.ts @@ -4,6 +4,7 @@ import path from 'node:path' import { createInMemoryMCPServer } from '@main/mcpServers/factory' import { makeSureDirExists } from '@main/utils' +import { buildFunctionCallToolName } from '@main/utils/mcp' import { getBinaryName, getBinaryPath } from '@main/utils/process' import { Client } from '@modelcontextprotocol/sdk/client/index.js' import { SSEClientTransport, SSEClientTransportOptions } from '@modelcontextprotocol/sdk/client/sse.js' @@ -372,7 +373,7 @@ class McpService { tools.map((tool: any) => { const serverTool: MCPTool = { ...tool, - id: `f${nanoid()}`, + id: buildFunctionCallToolName(server.name, tool.name), serverId: server.id, serverName: server.name } diff --git a/src/main/utils/mcp.ts b/src/main/utils/mcp.ts new file mode 100644 index 0000000000..ded81d71fe --- /dev/null +++ b/src/main/utils/mcp.ts @@ -0,0 +1,31 @@ +export function buildFunctionCallToolName(serverName: string, toolName: string) { + // Combine server name and tool name + let name = toolName + if (!toolName.includes(serverName.slice(0, 7))) { + name = `${serverName.slice(0, 7) || ''}_${toolName || ''}` + } + + // Replace invalid characters with underscores or dashes + // Keep a-z, A-Z, 0-9, underscores and dashes + name = name.replace(/[^a-zA-Z0-9_-]/g, '_') + + // Ensure name starts with a letter or underscore (for valid JavaScript identifier) + if (!/^[a-zA-Z]/.test(name)) { + name = `tool_${name}` + } + + // Remove consecutive underscores/dashes (optional improvement) + name = name.replace(/[_-]{2,}/g, '_') + + // Truncate to 63 characters maximum + if (name.length > 63) { + name = name.slice(0, 63) + } + + // Handle edge case: ensure we still have a valid name if truncation left invalid chars at edges + if (name.endsWith('_') || name.endsWith('-')) { + name = name.slice(0, -1) + } + + return name +}