/** * `npx zpl-engine-mcp setup` — interactive device-flow auth. * * Why this exists: * The MCP runs over stdio JSON-RPC inside Claude Desktop / Cursor / Windsurf. * It cannot show UI, cannot open a browser, and cannot prompt for input — any * stdout write corrupts the JSON-RPC stream. So the user was previously * forced to: sign up on the website, find the dashboard, create an API key, * copy-paste it into a JSON config file by hand. 10+ minutes, high drop-off. * * `setup` is a separate CLI entry point invoked *outside* the MCP loop. * It drives the RFC 8628-style device flow against * zeropointlogic.io/api/auth/cli/*, stores the resulting user key in * ~/.zpl/config.toml (which the MCP picks up automatically at next launch), * and auto-patches every supported client's MCP config (Claude Desktop, * Cursor, Windsurf) so the user doesn't have to touch JSON at all. Clients * that aren't installed are skipped silently; the snippet is printed once * as a fallback for non-standard setups (Claude Code, VS Code, Zed). * Install-to-working in ~15 seconds. * * Safety: * - Never logs the API key. * - Chmod 600 on the config file (no-op on Windows, which is fine; NTFS ACLs * default to per-user home anyway). * - Preserves existing mcpServers entries across all patched configs. * - On malformed config JSON, refuses to write and prints instructions * instead of destroying the file. * - Each client patch is isolated — one failing doesn't abort the others. * - Bounded polling (10 min max) and always uses `interval_s` from the * backend so a misbehaving server can't DoS itself. */ /** * Read existing ~/.zpl/config.toml and return key + email. * Returns null if file missing, unreadable, or no api_key inside. * Exported for unit tests (so we can verify behaviour against fixture configs). */ export declare function readExistingConfig(): Promise<{ apiKey: string; userEmail: string; path: string; } | null>; /** * Patch a standard MCP config file (Claude Desktop / Cursor / Windsurf all * share the same `{ mcpServers: {...} }` shape). Returns: * - "updated" if we wrote a merged file, * - "created" if the parent dir existed but the file didn't (we wrote fresh), * - "manual" if the parent dir doesn't exist (client not installed) * — caller decides whether to print a snippet. * - "malformed" if JSON didn't parse — we refuse to write, caller explains. * * Design note: one function for all three clients is intentional. They all * accept the same shape (`{mcpServers: {"zpl-engine-mcp": {command, args, env}}}`), * and keeping the merge logic in one place means malformed/missing handling * can't drift between clients over time. */ type PatchResult = "updated" | "created" | "manual" | "malformed"; export declare function patchMcpConfigFile(path: string, apiKey: string): Promise<{ result: PatchResult; path: string; }>; export interface SetupOptions { /** Skip the "already logged in" prompt and force a fresh device-flow login. */ force?: boolean; } /** * `npx zpl-engine-mcp setup` — interactive device-flow auth. * * v3.7.2: detects existing config and offers three choices instead of * silently re-authenticating. Stops the "every run forces a new browser * login" UX papercut. `--force` skips the prompt for power users who * want to rotate keys. */ export declare function runSetup(opts?: SetupOptions): Promise; /** * `npx zpl-engine-mcp repair` — wipe local config + remove MCP entries * from Claude Desktop / Cursor / Windsurf configs. * * Use when: * - Setup left the install in a confused state (duplicate entries, stale key) * - User wants a clean uninstall before reinstalling * - Switching to a different account and `--force` re-setup isn't enough * * Always asks for confirmation in interactive mode. Pass `--yes` to skip * (useful for automation / one-line bash docs). */ export interface RepairOptions { /** Skip the confirmation prompt. */ yes?: boolean; } export declare function runRepair(opts?: RepairOptions): Promise; /** * `npx zpl-engine-mcp whoami` — print which account this install is logged * into, without re-running the full setup. Useful for sanity-checking * after an update or when troubleshooting. */ export declare function runWhoami(): Promise; export {};