(cwd: string)
| 243 | |
| 244 | /** Discover MCP servers declared by Claude Code plugins (plugin.json mcpServers + .mcp.json). */ |
| 245 | export async function loadClaudeCodePluginMcpServers(cwd: string): Promise<Record<string, MCPServerConfig>> { |
| 246 | if (disabled()) return {}; |
| 247 | const out: Record<string, MCPServerConfig> = {}; |
| 248 | let plugins: Array<{ name: string; path: string }> = []; |
| 249 | try { plugins = await relevantPluginPaths(cwd); } catch { return {}; } |
| 250 | for (const p of plugins) { |
| 251 | const manifest = await readJsonIfExists(path.join(p.path, '.claude-plugin', 'plugin.json')); |
| 252 | const dotMcp = await readJsonIfExists(path.join(p.path, '.mcp.json')); |
| 253 | const servers = { ...(manifest?.mcpServers ?? {}), ...(dotMcp?.mcpServers ?? {}) }; |
| 254 | for (const [name, raw] of Object.entries(servers)) { |
| 255 | if (!raw || typeof raw !== 'object') continue; |
| 256 | // Namespace by plugin to avoid collisions, mirroring Claude Code conventions. |
| 257 | out[`${p.name}:${name}`] = substitutePluginRoot(raw as MCPServerConfig, p.path); |
| 258 | } |
| 259 | } |
| 260 | return out; |
| 261 | } |
| 262 | |
| 263 | const SUPPORTED_HOOK_EVENTS: HookEvent[] = ['PreToolUse', 'PostToolUse', 'SessionStart', 'SessionEnd', 'PreCompact']; |
| 264 |
no test coverage detected