diff --git a/src/agents/mcp-writer.ts b/src/agents/mcp-writer.ts index 505b895..291b35d 100644 --- a/src/agents/mcp-writer.ts +++ b/src/agents/mcp-writer.ts @@ -13,6 +13,11 @@ export interface McpResolvedTarget { export type McpTargetResolver = (agentId: string, spec: McpConfigSpec) => McpResolvedTarget; +export interface McpWriteWarning { + agent: string; + message: string; +} + /** * Convert McpConfig entries (from agents.toml) to universal McpDeclarations. */ @@ -41,13 +46,15 @@ export function projectMcpResolver(projectRoot: string): McpTargetResolver { * Write MCP config files for each agent. * - Dedicated files (shared=false): written fresh each time. * - Shared files (shared=true): read existing, merge dotagents servers under the root key, write back. + * - Agents that don't support MCP: collected as warnings. */ export async function writeMcpConfigs( agentIds: string[], servers: McpDeclaration[], resolveTarget: McpTargetResolver, -): Promise { - if (servers.length === 0) return; +): Promise { + const warnings: McpWriteWarning[] = []; + if (servers.length === 0) return warnings; // Deduplicate by resolved filePath so shared files aren't written twice const seen = new Set(); @@ -56,6 +63,11 @@ export async function writeMcpConfigs( const agent = getAgent(id); if (!agent) continue; + if (!agent.mcp) { + warnings.push({ agent: id, message: `Agent "${agent.displayName}" does not support MCP` }); + continue; + } + const { mcp } = agent; const { filePath, shared } = resolveTarget(id, mcp); if (seen.has(filePath)) continue; @@ -75,6 +87,8 @@ export async function writeMcpConfigs( await freshWrite(filePath, mcp, serialized); } } + + return warnings; } /** @@ -95,6 +109,9 @@ export async function verifyMcpConfigs( const agent = getAgent(id); if (!agent) continue; + // Skip agents that don't support MCP + if (!agent.mcp) continue; + const { mcp } = agent; const { filePath } = resolveTarget(id, mcp); if (seen.has(filePath)) continue; diff --git a/src/agents/types.ts b/src/agents/types.ts index 0b3b908..3acb56a 100644 --- a/src/agents/types.ts +++ b/src/agents/types.ts @@ -91,8 +91,8 @@ export interface AgentDefinition { * Undefined if the agent reads ~/.agents/skills/ natively (no symlink needed). */ userSkillsParentDirs?: string[]; - /** MCP config file specification */ - mcp: McpConfigSpec; + /** MCP config file specification (undefined if agent doesn't support MCP) */ + mcp?: McpConfigSpec; /** Transforms universal MCP declaration to agent-specific format */ serializeServer: McpSerializer; /** Hook config file specification (undefined if agent doesn't support hooks) */ diff --git a/src/cli/commands/install.ts b/src/cli/commands/install.ts index a5b9242..b2f9723 100644 --- a/src/cli/commands/install.ts +++ b/src/cli/commands/install.ts @@ -44,6 +44,7 @@ export interface InstallOptions { export interface InstallResult { installed: string[]; skipped: string[]; + mcpWarnings: { agent: string; message: string }[]; hookWarnings: { agent: string; message: string }[]; } @@ -276,7 +277,7 @@ export async function runInstall(opts: InstallOptions): Promise { // 5. Write MCP config files const mcpResolver = scope.scope === "user" ? userMcpResolver() : projectMcpResolver(scope.root); - await writeMcpConfigs(config.agents, toMcpDeclarations(config.mcp), mcpResolver); + const mcpWarnings = await writeMcpConfigs(config.agents, toMcpDeclarations(config.mcp), mcpResolver); // 6. Write hook config files (skip for user scope) let hookWarnings: { agent: string; message: string }[] = []; @@ -288,7 +289,7 @@ export async function runInstall(opts: InstallOptions): Promise { ); } - return { installed, skipped, hookWarnings }; + return { installed, skipped, mcpWarnings, hookWarnings }; } export default async function install(args: string[], flags?: { user?: boolean }): Promise { @@ -314,7 +315,7 @@ export default async function install(args: string[], flags?: { user?: boolean } chalk.green(`Installed ${result.installed.length} skill(s): ${result.installed.join(", ")}`), ); } - for (const w of result.hookWarnings) { + for (const w of [...result.mcpWarnings, ...result.hookWarnings]) { console.log(chalk.yellow(` warn: ${w.message}`)); } } catch (err) {