(
mcp: {
clients: MCPServerConnection[]
tools: Tool[]
commands: Command[]
resources: Record<string, ServerResource[]>
},
configs: Record<string, ScopedMcpServerConfig>,
)
| 183 | * Returns the stale clients so the caller can disconnect them (clearServerCache). |
| 184 | */ |
| 185 | export function excludeStalePluginClients( |
| 186 | mcp: { |
| 187 | clients: MCPServerConnection[] |
| 188 | tools: Tool[] |
| 189 | commands: Command[] |
| 190 | resources: Record<string, ServerResource[]> |
| 191 | }, |
| 192 | configs: Record<string, ScopedMcpServerConfig>, |
| 193 | ): { |
| 194 | clients: MCPServerConnection[] |
| 195 | tools: Tool[] |
| 196 | commands: Command[] |
| 197 | resources: Record<string, ServerResource[]> |
| 198 | stale: MCPServerConnection[] |
| 199 | } { |
| 200 | const stale = mcp.clients.filter(c => { |
| 201 | const fresh = configs[c.name] |
| 202 | if (!fresh) return c.config.scope === 'dynamic' |
| 203 | return hashMcpConfig(c.config) !== hashMcpConfig(fresh) |
| 204 | }) |
| 205 | if (stale.length === 0) { |
| 206 | return { ...mcp, stale: [] } |
| 207 | } |
| 208 | |
| 209 | let { tools, commands, resources } = mcp |
| 210 | for (const s of stale) { |
| 211 | tools = excludeToolsByServer(tools, s.name) |
| 212 | commands = excludeCommandsByServer(commands, s.name) |
| 213 | resources = excludeResourcesByServer(resources, s.name) |
| 214 | } |
| 215 | const staleNames = new Set(stale.map(c => c.name)) |
| 216 | |
| 217 | return { |
| 218 | clients: mcp.clients.filter(c => !staleNames.has(c.name)), |
| 219 | tools, |
| 220 | commands, |
| 221 | resources, |
| 222 | stale, |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | /** |
| 227 | * Checks if a tool name belongs to a specific MCP server |
no test coverage detected