/** * Shared MCP client-config writers. * * Extracted so both `agent-native mcp install` (see `mcp.ts`) and * `agent-native connect` (see `connect.ts`) write the EXACT same on-disk * config file targets and formats for every supported client. * * Supported clients and their config files: * - claude-code / claude-code-cli → `.mcp.json` (project) or * `~/.claude.json` (user). JSON `mcpServers[name] = entry`. * - cowork → `~/.cowork/mcp.json`. Same JSON shape. * - cursor → `.cursor/mcp.json` (project) or * `~/.cursor/mcp.json` (user). JSON `mcpServers[name] = entry`. * - opencode → `opencode.json` (project) or * `~/.config/opencode/opencode.json` (user). JSON `mcp[name] = entry`. * - github-copilot → `.vscode/mcp.json` (project) or the * VS Code user `mcp.json`. JSON `servers[name] = entry`. * - codex → `$CODEX_HOME/config.toml` when set, * otherwise `~/.codex/config.toml`. * `[mcp_servers.]` block. * * Node-only. No new npm deps — hand-rolled JSON merge + minimal TOML block * merge, mirroring `mcp.ts`. */ export type ClientId = "claude-code" | "claude-code-cli" | "codex" | "cowork" | "cursor" | "opencode" | "github-copilot"; export declare const CLIENTS: ClientId[]; /** The HTTP MCP server entry written into a JSON client config. */ export interface HttpMcpEntry { type: "http"; url: string; headers?: Record; } /** Build the HTTP MCP server entry for a deployed agent-native app. */ export declare function buildHttpMcpEntry(mcpUrl: string, token?: string, headers?: Record): HttpMcpEntry; export declare function buildHttpMcpEntryForClient(client: ClientId, mcpUrl: string, token?: string, headers?: Record): Record; export declare function buildLocalMcpEntryForClient(client: ClientId, args: string[], env?: Record, command?: string): Record; /** * Cowork consumes MCP exactly like Claude Code (same JSON server-entry * shape). Resolved lazily so `os.homedir()` reflects the current `$HOME`. */ export declare function coworkConfigPath(): string; export declare function claudeCodeProjectConfig(baseDir: string): string; export declare function claudeCodeUserConfig(): string; export declare function codexConfigPath(): string; export declare function cursorProjectConfig(baseDir: string): string; export declare function cursorUserConfig(): string; export declare function opencodeProjectConfig(baseDir: string): string; export declare function opencodeUserConfig(): string; export declare function githubCopilotProjectConfig(baseDir: string): string; export declare function githubCopilotUserConfig(): string; /** * Resolve the on-disk config path for a client. * * `scope` only affects Claude Code / Claude Code CLI: `"user"` → the global * `~/.claude.json`, anything else → the project-local `.mcp.json` rooted at * `baseDir`. */ export declare function configPathFor(client: ClientId, baseDir: string, scope: string | undefined): string; /** * Write `data` to `file` atomically: write a sibling temp file, then rename it * over the target. `rename(2)` is atomic on the same filesystem, so a crash or * `kill` mid-write can never leave a half-written/truncated file. This matters * most for `~/.claude.json`, which is Claude Code's entire user state (projects, * history, auth) — a torn write there would corrupt the user's whole config, * not just our MCP entry. The temp file lives in the target's directory so the * rename stays within one filesystem. */ export declare function writeFileAtomic(file: string, data: string): void; /** * Idempotently write `mcpServers[name] = entry` into a JSON config file. * Pass `entry === null` to delete the named entry. Re-running with the same * name replaces the existing entry in place — never duplicates. */ export declare function jsonMcpConfigKeyForClient(client: ClientId): string; export declare function writeJsonMcpEntry(file: string, name: string, entry: Record | null): void; export declare function writeJsonMcpEntryForClient(client: ClientId, file: string, name: string, entry: Record | null): void; export declare function hasJsonMcpEntry(file: string, name: string): boolean; export declare function hasJsonMcpEntryForClient(client: ClientId, file: string, name: string): boolean; /** Build a `[mcp_servers.]` block for an HTTP-type MCP server. */ export declare function buildCodexHttpBlock(name: string, mcpUrl: string, token?: string, headers?: Record): string; export declare function buildCodexLocalBlock(name: string, args: string[], env?: Record, command?: string): string; /** * Replace (or append) the entire `[mcp_servers.]` footprint in a TOML * file without disturbing other content. The footprint is the server's own * table AND every sub-table of it (`[mcp_servers..http_headers]`, * `[mcp_servers..env]`, …), each spanning its header line plus every * following line until the next table header or EOF. Removing the whole * footprint — wherever the pieces sit in the file — is what keeps a re-install * from leaving a stale sub-table that collides with the freshly written inline * block (a TOML duplicate-key error). Matches both the canonical quoted header * and the legacy bare header. Pass `block === null` to remove the footprint. * Identical algorithm to `mcp.ts`'s `writeCodexBlock` so the two never diverge. */ export declare function writeCodexBlock(file: string, name: string, block: string | null): void; export declare function codexHasBlock(file: string, name: string): boolean; /** * Idempotently write the HTTP MCP server entry for `serverName` into the * given client's config file and return the file path that was written. * Re-running replaces the same named entry — never duplicates. */ export declare function writeHttpEntryForClient(client: ClientId, serverName: string, mcpUrl: string, token: string | undefined, baseDir: string, scope: string | undefined, headers?: Record): string; /** * Canonicalise a URL for comparison: strip hash, search params, and trailing * slashes. Returns `undefined` for invalid URLs. */ export declare function canonicalUrl(value: string | undefined): string | undefined; export declare function removeJsonSameUrlDuplicates(file: string, mcpUrl: string, keepName: string): string[]; /** * After writing the canonical `keepName` Codex block, remove any OTHER * `[mcp_servers.*]` servers in the same TOML file whose `url =` line normalises * to the same value as `mcpUrl`. A server's entire footprint is removed — its * own table AND any sub-tables (`.http_headers`, `.env`, …), even when they are * not contiguous — so cleanup never leaves an orphaned sub-table behind. * Returns removed entry names in first-seen order. */ export declare function removeCodexSameUrlDuplicates(file: string, mcpUrl: string, keepName: string): string[]; /** * Unified helper: after writing the canonical `serverName` entry for the * given `client`, remove same-URL duplicates from its config file. * Returns the list of removed names (empty if nothing was cleaned up). */ export declare function removeSameUrlDuplicatesForClient(client: ClientId, serverName: string, mcpUrl: string, baseDir: string, scope: string | undefined): string[]; //# sourceMappingURL=mcp-config-writers.d.ts.map