UNPKG

add-mcp

Version:

Add MCP servers to your favorite coding agents with a single command.

166 lines (159 loc) • 7.08 kB
/** * Optional, capability-gated fields on {@link McpServerConfig}. * * The canonical {@link McpServerConfig} is the single, agent-agnostic schema * that the CLI and library populate. Not every MCP client understands every * optional field, so each agent declares which of these it supports via * `AgentConfig.supportedFields`. Anything an agent does not support is dropped * before its transform runs, guaranteeing that only known fields are ever * written to a client config. */ type OptionalField = "timeout" | "scopes" | "autoApprove" | "bearerTokenEnv"; type AgentType = "antigravity" | "cline" | "cline-cli" | "claude-code" | "claude-desktop" | "codex" | "cursor" | "factory-droid" | "fx" | "gemini-cli" | "goose" | "github-copilot-cli" | "grok-build" | "hermes" | "junie" | "kilo-code" | "kimi-code" | "kiro-cli" | "mastracode" | "mcporter" | "opencode" | "pi" | "vscode" | "windsurf" | "zed"; /** `yaml` is YAML 1.2; `yaml-1.1` is for agents whose parser reads `on`, `off`, and `0123` the YAML 1.1 way. */ type ConfigFormat = "json" | "yaml" | "yaml-1.1" | "toml"; interface AgentConfig { /** Internal name */ name: string; /** Display name for UI */ displayName: string; /** Global config file path */ configPath: string; /** Local (project-level) config file path, if supported */ localConfigPath?: string; /** Paths to check for project-level detection (relative to cwd) */ projectDetectPaths: string[]; /** Key in config file where MCP servers are stored (supports dot notation) */ configKey: string; /** Optional key for project-level config when different from global configKey */ localConfigKey?: string; /** Config file format */ format: ConfigFormat; /** Supported transport types for this agent */ supportedTransports: ("stdio" | "sse" | "http")[]; /** * Optional, capability-gated server fields this agent understands (e.g. * `timeout`, `scopes`). Any optional field not listed here is stripped from * the canonical config before {@link transformConfig} runs, so a client never * receives a field it cannot interpret. Use an empty array for agents that * only support the core fields. */ supportedFields: OptionalField[]; /** Shown when a user tries to use an unsupported transport */ unsupportedTransportMessage?: string; /** Function to detect if agent is installed globally */ detectGlobalInstall: () => Promise<boolean>; /** Optional function to dynamically resolve config path */ resolveConfigPath?: (agent: AgentConfig, options: { local: boolean; cwd: string; }) => string; /** * Transform the canonical, field-gated server config into this agent's * concrete on-disk schema. Required for every agent: transforms must build a * fresh object with only the keys the client understands, which structurally * guarantees no unknown fields leak into a written config. */ transformConfig: (serverName: string, config: McpServerConfig, context?: { local: boolean; configKey?: string; }) => unknown; } type TransportType = "sse" | "http"; interface McpServerConfig { /** For remote servers */ type?: TransportType; url?: string; headers?: Record<string, string>; /** For local stdio servers */ command?: string; args?: string[]; env?: Record<string, string>; /** * Request timeout in milliseconds for remote servers. Capability-gated: * only emitted for agents that list `"timeout"` in `supportedFields`. */ timeout?: number; /** * OAuth scopes to request for remote servers. Capability-gated: only emitted * for agents that list `"scopes"` in `supportedFields`, each mapping it into * their own native shape (e.g. Cursor `auth.scopes`, Gemini `oauth.scopes`). */ oauthScopes?: string[]; /** * Tools to auto-approve (skip the agent's per-call approval prompt). An empty * array means "all tools". This is an install directive rather than a literal * server-config key: capability-gated via `"autoApprove"` in `supportedFields` * and each supporting agent applies it in its own way (e.g. Codex emits * approval modes in its config; Claude Code writes permission allow rules to a * separate settings file). It is never written into a server entry verbatim. */ autoApproveTools?: string[]; bearerTokenEnv?: string; } interface InstallOptions { /** Install to local (project-level) config instead of global */ local?: boolean; /** Current working directory for local installs */ cwd?: string; } interface InstallResult { success: boolean; path: string; error?: string; /** * Optional fields that were requested but dropped because the target agent * does not support them. Empty/undefined when nothing was dropped. */ droppedFields?: OptionalField[]; /** * Additional files written beyond the main config (e.g. a Claude Code * permissions settings file for auto-approval). Surfaced so the CLI can * report them and include them in `--gitignore`. */ extraPaths?: string[]; } declare const agents: Record<AgentType, AgentConfig>; declare function getAgentTypes(): AgentType[]; declare function detectProjectAgents(cwd?: string): AgentType[]; declare function detectGlobalAgents(): Promise<AgentType[]>; interface InstalledServer { serverName: string; config: Record<string, unknown>; identity: string; agentType: AgentType; scope: "local" | "global"; configPath: string; /** Key in the config file where this server was read from */ configKey: string; } interface AgentServers { agentType: AgentType; displayName: string; detected: boolean; scope: "local" | "global"; configPath: string; servers: InstalledServer[]; /** Present when this agent's config could not be read */ error?: string; } /** * Gather installed servers across detected (or explicitly specified) agents. * When `agents` is provided, those agents are included even if not detected * (with detected=false). */ declare function listInstalledServers(options: { global?: boolean; agents?: AgentType[]; cwd?: string; }): Promise<AgentServers[]>; type AgentInput = AgentType | (string & {}); declare function upsertServer(agentType: AgentInput, serverName: string, serverConfig: McpServerConfig, options?: InstallOptions): InstallResult; interface RemoveServerResult { success: boolean; path: string; removed: boolean; error?: string; } declare function removeServer(agentType: AgentInput, serverName: string, options?: InstallOptions): RemoveServerResult; export { type AgentConfig, type AgentInput, type AgentServers, type AgentType, type InstallOptions, type InstallResult, type InstalledServer, type McpServerConfig, type OptionalField, type RemoveServerResult, agents, detectGlobalAgents, detectProjectAgents, getAgentTypes, listInstalledServers, removeServer, upsertServer };