Files
oh-my-openagent/src/features/claude-code-mcp-loader/loader.test.ts
YeonGyu-Kim e6ffdc4352 feat(claude-code-mcp-loader): auto-disable builtin skills with overlapping MCP servers
Add getSystemMcpServerNames() sync function to detect system-configured MCP
servers from .mcp.json files (user, project, and local scopes). Builtin skills
like playwright are now automatically excluded when their MCP server is already
configured in system config, preventing duplicate MCP server registration.

Also adds comprehensive test suite with 5 BDD-style tests covering empty config,
project/local scopes, disabled servers, and merged configurations.

Changes:
- loader.ts: Add getSystemMcpServerNames() function + readFileSync import
- loader.test.ts: Add 5 tests for getSystemMcpServerNames() edge cases
- index.ts: Filter builtin skills to exclude those with overlapping MCP names

🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
2026-01-02 10:55:54 +09:00

163 lines
4.1 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach } from "bun:test"
import { mkdirSync, writeFileSync, rmSync } from "fs"
import { join } from "path"
import { tmpdir } from "os"
const TEST_DIR = join(tmpdir(), "mcp-loader-test-" + Date.now())
describe("getSystemMcpServerNames", () => {
beforeEach(() => {
mkdirSync(TEST_DIR, { recursive: true })
})
afterEach(() => {
rmSync(TEST_DIR, { recursive: true, force: true })
})
it("returns empty set when no .mcp.json files exist", async () => {
// #given
const originalCwd = process.cwd()
process.chdir(TEST_DIR)
try {
// #when
const { getSystemMcpServerNames } = await import("./loader")
const names = getSystemMcpServerNames()
// #then
expect(names).toBeInstanceOf(Set)
expect(names.size).toBe(0)
} finally {
process.chdir(originalCwd)
}
})
it("returns server names from project .mcp.json", async () => {
// #given
const mcpConfig = {
mcpServers: {
playwright: {
command: "npx",
args: ["@playwright/mcp@latest"],
},
sqlite: {
command: "uvx",
args: ["mcp-server-sqlite"],
},
},
}
writeFileSync(join(TEST_DIR, ".mcp.json"), JSON.stringify(mcpConfig))
const originalCwd = process.cwd()
process.chdir(TEST_DIR)
try {
// #when
const { getSystemMcpServerNames } = await import("./loader")
const names = getSystemMcpServerNames()
// #then
expect(names.has("playwright")).toBe(true)
expect(names.has("sqlite")).toBe(true)
expect(names.size).toBe(2)
} finally {
process.chdir(originalCwd)
}
})
it("returns server names from .claude/.mcp.json", async () => {
// #given
mkdirSync(join(TEST_DIR, ".claude"), { recursive: true })
const mcpConfig = {
mcpServers: {
memory: {
command: "npx",
args: ["-y", "@anthropic-ai/mcp-server-memory"],
},
},
}
writeFileSync(join(TEST_DIR, ".claude", ".mcp.json"), JSON.stringify(mcpConfig))
const originalCwd = process.cwd()
process.chdir(TEST_DIR)
try {
// #when
const { getSystemMcpServerNames } = await import("./loader")
const names = getSystemMcpServerNames()
// #then
expect(names.has("memory")).toBe(true)
} finally {
process.chdir(originalCwd)
}
})
it("excludes disabled MCP servers", async () => {
// #given
const mcpConfig = {
mcpServers: {
playwright: {
command: "npx",
args: ["@playwright/mcp@latest"],
disabled: true,
},
active: {
command: "npx",
args: ["some-mcp"],
},
},
}
writeFileSync(join(TEST_DIR, ".mcp.json"), JSON.stringify(mcpConfig))
const originalCwd = process.cwd()
process.chdir(TEST_DIR)
try {
// #when
const { getSystemMcpServerNames } = await import("./loader")
const names = getSystemMcpServerNames()
// #then
expect(names.has("playwright")).toBe(false)
expect(names.has("active")).toBe(true)
} finally {
process.chdir(originalCwd)
}
})
it("merges server names from multiple .mcp.json files", async () => {
// #given
mkdirSync(join(TEST_DIR, ".claude"), { recursive: true })
const projectMcp = {
mcpServers: {
playwright: { command: "npx", args: ["@playwright/mcp@latest"] },
},
}
const localMcp = {
mcpServers: {
memory: { command: "npx", args: ["-y", "@anthropic-ai/mcp-server-memory"] },
},
}
writeFileSync(join(TEST_DIR, ".mcp.json"), JSON.stringify(projectMcp))
writeFileSync(join(TEST_DIR, ".claude", ".mcp.json"), JSON.stringify(localMcp))
const originalCwd = process.cwd()
process.chdir(TEST_DIR)
try {
// #when
const { getSystemMcpServerNames } = await import("./loader")
const names = getSystemMcpServerNames()
// #then
expect(names.has("playwright")).toBe(true)
expect(names.has("memory")).toBe(true)
} finally {
process.chdir(originalCwd)
}
})
})