{"record":{"id":"153f4bea7b056507","repo":"JuliusBrussee/caveman","slug":"could-not-install-caveman-cloud-mcp-for-agent","errorCode":null,"errorMessage":"could not install caveman-cloud MCP for ${agent}","messagePattern":"could not install caveman-cloud MCP for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":2371,"sourceCode":"    exact_shape: keys.length === 2 && keys[0] === \"args\" && keys[1] === \"command\",\n  };\n}\n\nfunction agentNativeCloudMcpMatches(agent: \"claude\" | \"codex\", mcp: { command: string; args: string[] }): boolean {\n  if (agent === \"codex\") return codexMcpRegistrationMatches(\"caveman-cloud\", mcp);\n  const actual = claudeMcpRegistration(\"caveman-cloud\");\n  return actual.present && actual.exact_shape && actual.command === mcp.command && JSON.stringify(actual.args) === JSON.stringify(mcp.args);\n}\n\nfunction installAgentNativeCloudMcp(agent: \"claude\" | \"codex\", mcp: { command: string; args: string[] }): void {\n  if (agentNativeCloudMcpMatches(agent, mcp)) {\n    writeMcpServerMarker(agent, \"caveman-cloud\", mcp, \"caveman_context\");\n    return;\n  }\n  const installed = agent === \"claude\"\n    ? installMcpJson(join(homedir(), \".claude.json\"), [\"mcpServers\", \"caveman-cloud\"], { command: mcp.command, args: mcp.args })\n    : installMcpForAgent(findAgent(agent)!, mcp, \"caveman-cloud\");\n  if (!installed) throw new Error(`could not install caveman-cloud MCP for ${agent}`);\n  writeMcpServerMarker(agent, \"caveman-cloud\", mcp, \"caveman_context\");\n}\n\nfunction uninstallAgentNativeCloudMcp(agent: \"claude\" | \"codex\"): void {\n  const removed = agent === \"claude\"\n    ? removeMcpJson(join(homedir(), \".claude.json\"), [\"mcpServers\", \"caveman-cloud\"])\n    : uninstallMcpForAgent(findAgent(agent)!, \"caveman-cloud\");\n  if (!removed) throw new Error(`could not remove caveman-cloud MCP for ${agent}`);\n  try { unlinkSync(mcpServerMarkerPath(agent, \"caveman-cloud\")); } catch (error) {\n    if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n  }\n}\n\nfunction agentNativeSkillFiles(agent: \"claude\" | \"codex\"): Array<{ name: string; file: string; body: string }> {\n  const names = AGENT_SKILL_SUITES[\"agent-native\"] ?? [];\n  const root = agent === \"claude\" ? join(homedir(), \".claude\", \"skills\") : join(homedir(), \".codex\", \"skills\");\n  return names.map((name) => ({ name, file: join(root, name, \"SKILL.md\"), body: SKILLS[name]! }));\n}","sourceCodeStart":2353,"sourceCodeEnd":2389,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/cli/src/index.ts#L2353-L2389","documentation":"installAgentNativeCloudMcp() registers the caveman-cloud MCP server for claude (via installMcpJson into ~/.claude.json mcpServers) or codex (via installMcpForAgent). When the underlying installer returns falsy — it could not write the registration — this error aborts the bundle install. The writeMcpServerMarker call after it is what makes the registration Caveman-journaled, so failing install must never continue.","triggerScenarios":"`caveman setup` / agent-native install where ~/.claude.json is unreadable/unwritable, malformed JSON so the installer cannot merge mcpServers, ~/.codex/config.toml cannot be edited, or findAgent(agent) cannot resolve a writable config path for the agent.","commonSituations":"Permissions problems on ~/.claude.json; another tool holding/reformatting the file; a corrupted config from a different tool; codex installed under a non-default CODEX_HOME.","solutions":["Check that ~/.claude.json (or ~/.codex/config.toml) is valid JSON/TOML and writable by the current user","Fix file permissions (chmod/chown) on the agent config","Back up and remove a corrupted config so the agent and caveman can regenerate it, then re-run setup","Ensure CODEX_HOME points at the config you expect when running setup"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { readFileSync, accessSync, constants } from \"node:fs\";\nfunction claudeConfigWritable(p = join(homedir(), \".claude.json\")): boolean {\n  try {\n    if (existsSync(p)) { JSON.parse(readFileSync(p, \"utf8\")); accessSync(p, constants.W_OK); }\n    return true;\n  } catch { return false; }\n}","typeGuard":"function isMcpInstallError(e: unknown): boolean {\n  return e instanceof Error && e.message.startsWith(\"could not install caveman-cloud MCP for \");\n}","tryCatchPattern":"try {\n  runCavemanSetup();\n} catch (e) {\n  if (isMcpInstallError(e)) {\n    // validate ~/.claude.json / ~/.codex/config.toml, fix permissions, re-run\n  } else throw e;\n}","preventionTips":["Validate agent config files are parseable and writable before setup","Close the agent app during caveman setup to avoid config write races","Back up ~/.claude.json before major setup runs"],"tags":["mcp","install","config","agent-native"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}