90 lines
2.3 KiB
TypeScript
90 lines
2.3 KiB
TypeScript
import { existsSync } from "fs"
|
|
import { homedir } from "os"
|
|
import { join } from "path"
|
|
import type {
|
|
ClaudeCodeMcpConfig,
|
|
LoadedMcpServer,
|
|
McpLoadResult,
|
|
McpScope,
|
|
} from "./types"
|
|
import { transformMcpServer } from "./transformer"
|
|
import { log } from "../../shared/logger"
|
|
|
|
interface McpConfigPath {
|
|
path: string
|
|
scope: McpScope
|
|
}
|
|
|
|
function getMcpConfigPaths(): McpConfigPath[] {
|
|
const home = homedir()
|
|
const cwd = process.cwd()
|
|
|
|
return [
|
|
{ path: join(home, ".claude", ".mcp.json"), scope: "user" },
|
|
{ path: join(cwd, ".mcp.json"), scope: "project" },
|
|
{ path: join(cwd, ".claude", ".mcp.json"), scope: "local" },
|
|
]
|
|
}
|
|
|
|
async function loadMcpConfigFile(
|
|
filePath: string
|
|
): Promise<ClaudeCodeMcpConfig | null> {
|
|
if (!existsSync(filePath)) {
|
|
return null
|
|
}
|
|
|
|
try {
|
|
const content = await Bun.file(filePath).text()
|
|
return JSON.parse(content) as ClaudeCodeMcpConfig
|
|
} catch (error) {
|
|
log(`Failed to load MCP config from ${filePath}`, error)
|
|
return null
|
|
}
|
|
}
|
|
|
|
export async function loadMcpConfigs(): Promise<McpLoadResult> {
|
|
const servers: McpLoadResult["servers"] = {}
|
|
const loadedServers: LoadedMcpServer[] = []
|
|
const paths = getMcpConfigPaths()
|
|
|
|
for (const { path, scope } of paths) {
|
|
const config = await loadMcpConfigFile(path)
|
|
if (!config?.mcpServers) continue
|
|
|
|
for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
|
|
if (serverConfig.disabled) {
|
|
log(`Skipping disabled MCP server "${name}"`, { path })
|
|
continue
|
|
}
|
|
|
|
try {
|
|
const transformed = transformMcpServer(name, serverConfig)
|
|
servers[name] = transformed
|
|
|
|
const existingIndex = loadedServers.findIndex((s) => s.name === name)
|
|
if (existingIndex !== -1) {
|
|
loadedServers.splice(existingIndex, 1)
|
|
}
|
|
|
|
loadedServers.push({ name, scope, config: transformed })
|
|
|
|
log(`Loaded MCP server "${name}" from ${scope}`, { path })
|
|
} catch (error) {
|
|
log(`Failed to transform MCP server "${name}"`, error)
|
|
}
|
|
}
|
|
}
|
|
|
|
return { servers, loadedServers }
|
|
}
|
|
|
|
export function formatLoadedServersForToast(
|
|
loadedServers: LoadedMcpServer[]
|
|
): string {
|
|
if (loadedServers.length === 0) return ""
|
|
|
|
return loadedServers
|
|
.map((server) => `${server.name} (${server.scope})`)
|
|
.join(", ")
|
|
}
|