/**
 * 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 };
