import type { ResolvedMcpConfig, McpServerStdioConfig } from "../shared/types.js"; /** * GRS-012c — attach the built-in `jinn` MCP server to a spawned Grok * (`grok-build`) session. Grok has NO per-invocation config flag (its `--cwd` * sets both the working directory AND the config-discovery directory; `grok mcp * add` writes to `~/.grok/config.toml` [user] or `./.grok/config.toml` * [project]). So — unlike Codex, which we drive via per-session `-c` argv * overrides — the only per-session lever for Grok is the PROJECT-scoped * `/.grok/config.toml`, which grok reads from its working directory. Grok * merges project-scoped `[mcp_servers.*]` on top of user config without touching * global `~/.grok` (proven in the GRS-012c probe). * * IMPORTANT — the working directory is SHARED. Every jinn-spawned engine turn runs * with `cwd = JINN_HOME` (sessions/manager.ts + gateway/api.ts), so ALL concurrent * grok sessions read/write the SAME `/.grok/config.toml`. Two design * consequences, both handled here: * 1. We emit ONLY the built-in `jinn` server (see {@link JINN_BUILTIN_SERVER}). * Its spec is process-global (same node bin + entry + the non-secret * `JINN_GATEWAY_URL`), so every concurrent session writes BYTE-IDENTICAL * content — no last-writer-wins corruption. Restricting to `jinn` also means * (a) no arbitrary custom-server name can produce invalid TOML table keys, and * (b) no custom-server `command`/`args` secret is ever written to disk. Other * MCP servers for grok are a deferred, separate slice. * 2. The shared file is REFERENCE-COUNTED ({@link activeConfigs}). The first * attach writes it; concurrent attaches share it; only the LAST session to * settle deletes it. This prevents one session's cleanup from deleting a file * another session's grok is still starting against, while keeping the * zero-residue property: once no grok session is active, the file (and a * `.grok` dir we created) is gone. JINN_HOME is jinn's own home, never the * user's project tree, so the run leaves zero new files in a user repo. * * A jinn-written file carries a first-line {@link JINN_GROK_MCP_MARKER}; we only * ever create/overwrite/delete a file bearing it. A NON-marked pre-existing * `.grok/config.toml` (a user's own) is left untouched and the attach is skipped — * no clobber, no fragile TOML merge. * * SECURITY: only the non-secret env allowlist ({@link GROK_SAFE_ENV_KEYS}) is * written into the config `env`; the bearer token reaches the server via grok's * INHERITED env, never a file (same contract as Codex). */ export declare const JINN_GROK_MCP_MARKER = "# jinn-managed: auto-generated MCP attach config (GRS-012c). Safe to delete."; /** The one server this slice attaches to grok — matches the resolver's built-in * server key (mcp/resolver.ts). */ export declare const JINN_BUILTIN_SERVER = "jinn"; /** * Per-session env to add to the grok CHILD process so the builtin jinn server * (spawned by grok with grok's full env) receives the GRS-017/021c caller * identity + capability. Reads both from the identity-stamped jinn spec * (mcp/identity.ts is the single source; the engine does not invent identity). * Empty when no jinn server is attached or the spec carries no id/capability. */ export declare function grokJinnSessionEnv(resolvedMcp: ResolvedMcpConfig | undefined): Record; export type GrokMcpAttachHandle = { attached: false; } | { attached: true; configPath: string; grokDir: string; released?: boolean; }; /** * Render the `[mcp_servers.jinn]` TOML for a stdio server. `JSON.stringify` emits * a valid TOML basic string for the plain command/path/URL values involved. Only * the built-in `jinn` name is used → a valid bare TOML key. */ export declare function buildGrokMcpToml(name: string, spec: McpServerStdioConfig): string; /** * Write (or share) the `/.grok/config.toml` that attaches the built-in `jinn` * MCP server to a spawned grok session. Reference-counted for the shared * JINN_HOME cwd. Returns a handle for {@link cleanupGrokProjectMcpConfig}. No-ops * (returns `{attached:false}`) when the resolved set has no `jinn` server, or when * a non-jinn-managed config already exists (never clobbers the user's own file). */ export declare function prepareGrokProjectMcpConfig(cwd: string | undefined, resolvedMcp: ResolvedMcpConfig | undefined): GrokMcpAttachHandle; /** * Release one reference to the shared `.grok/config.toml`. Only the LAST active * session deletes the (marker-guarded) file and the `.grok` dir if jinn created it * and it is now empty. Idempotent + best-effort. */ export declare function cleanupGrokProjectMcpConfig(handle: GrokMcpAttachHandle | undefined): void; //# sourceMappingURL=grok-mcp.d.ts.map