Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### New Features

- CodeGraph's installer now supports **octo** (octo-agent). Running `codegraph install` can auto-detect and wire the CodeGraph MCP server into octo's MCP config at `~/.octo/mcp.json` (global) or `./.octo/mcp.json` (project-local), using the same `mcpServers.codegraph` shape as Claude Code / Cursor / Gemini. `codegraph uninstall` removes the entry cleanly.

## [1.3.1] - 2026-07-09

Expand All @@ -19,8 +22,6 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- Fixed a race that could leave a freshly-attached MCP session permanently silent: when a client's first messages arrived glued together during the daemon's connection handshake (roughly one attach in five on a busy machine), the daemon could drop them and stop reading that connection entirely — every tool call from that session then hung with no reply. The handshake now hands the connection over losslessly, and the fix is validated by hammering the previously-flaky attach test 25× under load.
- The first tool call after the shared daemon starts no longer waits behind the query workers' cold start (which can take many seconds on a busy machine) — it's served directly until the first worker is warm, so a fresh session answers immediately.

## [1.3.0] - 2026-07-07

### New Features

- CodeGraph now indexes **Nix** (`.nix`) — flakes, NixOS and home-manager modules, overlays, and package sets join the graph: `let` and attrset bindings, functions (simple, destructured `{ pkgs, ... }`, and curried), and `inherit` bindings all become searchable symbols, with call edges between bindings. File-level wiring follows the ways Nix actually connects files: `import ./relative/path.nix` (with `import ./dir` reaching the directory's `default.nix`), NixOS module `imports = [ ./hardware.nix ../common ]` lists, flake-style `modules = [ ./configuration.nix ]` lists, and the nixpkgs `callPackage ./pkgs/foo { }` idiom — so "what does this configuration actually pull in" and "what uses this module" are answerable on real setups. Dynamic references (`import <nixpkgs>`, variable paths, flake-input module references) are deliberately left unlinked rather than guessed. Thanks @TyceHerrman. (#324, #332, #648)
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Project Overview

CodeGraph is a local-first code intelligence library + CLI + MCP server. It parses any supported codebase with tree-sitter, stores symbols/edges/files in SQLite (FTS5), and exposes a knowledge graph to AI agents (Claude Code, Cursor, Codex CLI, opencode) over MCP. Per-project data lives in `.codegraph/`. Extraction is deterministic — derived from AST, not LLM-summarized.
CodeGraph is a local-first code intelligence library + CLI + MCP server. It parses any supported codebase with tree-sitter, stores symbols/edges/files in SQLite (FTS5), and exposes a knowledge graph to AI agents (Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, octo) over MCP. Per-project data lives in `.codegraph/`. Extraction is deterministic — derived from AST, not LLM-summarized.

Distributed as `@colbymchenry/codegraph` on npm; same binary serves as installer, indexer, and MCP server.

Expand Down Expand Up @@ -75,7 +75,7 @@ Defined in `src/types.ts`. Both extractors and resolvers must use these exact st

- `targets/registry.ts` lists every supported agent.
- `targets/types.ts` defines the `AgentTarget` interface — adding a 5th agent (Continue, Zed, Windsurf…) is **one new file in `targets/` + one entry in `registry.ts`**. Each target owns its config-file location and MCP-server JSON/TOML/JSONC writing. (Targets no longer write an instructions file — see below.)
- Current targets: `claude.ts`, `cursor.ts`, `codex.ts`, `opencode.ts`.
- Current targets: `claude.ts`, `cursor.ts`, `codex.ts`, `opencode.ts`, `hermes.ts`, `gemini.ts`, `antigravity.ts`, `kiro.ts`, `octo.ts`.
- `targets/toml.ts` is a hand-rolled TOML serializer scoped to `[mcp_servers.codegraph]` (used by Codex). Sibling tables and `[[array_of_tables]]` are preserved verbatim. No new dependency.
- opencode reads `opencode.jsonc` by default; the installer prefers existing `.jsonc`, falls back to `.json`, and creates `.jsonc` for greenfield installs. Edits are surgical via `jsonc-parser` so user comments and formatting survive install/re-install/uninstall round-trips.
- `instructions-template.ts` no longer holds an instructions body — it exports only the `<!-- CODEGRAPH_START -->`/`<!-- CODEGRAPH_END -->` markers. The installer **stopped writing** a `## CodeGraph` block into each agent's instructions file (`CLAUDE.md` / `~/.codex/AGENTS.md` / `~/.config/opencode/AGENTS.md` / `~/.gemini/GEMINI.md` / `.cursor/rules/codegraph.mdc` / Kiro steering doc) because it duplicated the MCP `initialize` instructions verbatim (issue #529). Each target's `install` (self-heal on upgrade) and `uninstall` use the markers to **strip** a block a previous install left behind. `server-instructions.ts` is the single source of truth for agent-facing guidance.
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Already installed? Run `codegraph upgrade`

Follow [@getcodegraph](https://x.com/getcodegraph) on X for updates.

### Supercharge Claude Code, Cursor, Codex, OpenCode, Hermes Agent, Gemini, Antigravity, and Kiro with Semantic Code Intelligence
### Supercharge Claude Code, Cursor, Codex, OpenCode, Hermes Agent, Gemini, Antigravity, Kiro, and octo with Semantic Code Intelligence

**Surgical context · fewer tool calls · faster answers · 100% local**

Expand Down Expand Up @@ -99,7 +99,7 @@ In a **new terminal**, run the installer to connect CodeGraph to the agents you
codegraph install
```

<sub>Detects and auto-configures Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, and Kiro — wiring the CodeGraph MCP server into each. **This is the step that connects CodeGraph to your agent;** installing the CLI in step 1 does not do it on its own. It only wires up your agent — it does **not** index any code; building each project's graph is the separate `codegraph init` in step 3. (Shortcut: `npx @colbymchenry/codegraph` downloads and runs this in one go.)</sub>
<sub>Detects and auto-configures Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, and octo — wiring the CodeGraph MCP server into each. **This is the step that connects CodeGraph to your agent;** installing the CLI in step 1 does not do it on its own. It only wires up your agent — it does **not** index any code; building each project's graph is the separate `codegraph init` in step 3. (Shortcut: `npx @colbymchenry/codegraph` downloads and runs this in one go.)</sub>

### 3. Initialize each project

Expand Down Expand Up @@ -768,6 +768,7 @@ is written):
- **Gemini CLI**
- **Antigravity IDE**
- **Kiro**
- **octo**

## Supported Languages

Expand Down Expand Up @@ -876,7 +877,7 @@ MIT

<div align="center">

**Made for AI coding agents — Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, and Kiro**
**Made for AI coding agents — Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, and octo**

[Report Bug](https://github.com/colbymchenry/codegraph/issues) · [Request Feature](https://github.com/colbymchenry/codegraph/issues)

Expand Down
6 changes: 3 additions & 3 deletions site/src/content/docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ npx @colbymchenry/codegraph

The installer will:

- Ask which agent(s) to configure — auto-detecting installed ones from **Claude Code**, **Cursor**, **Codex CLI**, **opencode**, **Hermes Agent**, **Gemini CLI**, **Antigravity IDE**, and **Kiro**.
- Ask which agent(s) to configure — auto-detecting installed ones from **Claude Code**, **Cursor**, **Codex CLI**, **opencode**, **Hermes Agent**, **Gemini CLI**, **Antigravity IDE**, **Kiro**, and **octo**.
- Prompt to install `codegraph` on your `PATH` (so agents can launch the MCP server).
- Ask whether configs apply to all your projects or just this one.
- Write each chosen agent's MCP server config, plus a small marker-fenced CodeGraph section in the agent's instructions file (`CLAUDE.md` / `AGENTS.md` / `GEMINI.md`). Cursor and Kiro get the MCP config only. Removed cleanly by `codegraph uninstall`.
- Write each chosen agent's MCP server config, plus a small marker-fenced CodeGraph section in the agent's instructions file (`CLAUDE.md` / `AGENTS.md` / `GEMINI.md` / `octorules.md`). Cursor and Kiro get the MCP config only. Removed cleanly by `codegraph uninstall`.
- Set up auto-allow permissions when Claude Code is one of the targets.

The installer **wires up your agents only — it does not index your code.** After it finishes, build each project's graph yourself with `codegraph init` (step 3 below).
Expand All @@ -38,7 +38,7 @@ codegraph install --print-config codex # print snippet, no file wr

## 2. Restart your agent

Restart your agent (Claude Code / Cursor / Codex CLI / opencode / Hermes Agent / Gemini CLI / Antigravity IDE / Kiro) for the MCP server to load.
Restart your agent (Claude Code / Cursor / Codex CLI / opencode / Hermes Agent / Gemini CLI / Antigravity IDE / Kiro / octo) for the MCP server to load.

## 3. Initialize projects

Expand Down
2 changes: 1 addition & 1 deletion site/src/content/docs/getting-started/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: What CodeGraph is, and why it makes AI coding agents faster and mor

CodeGraph is a **local-first code-intelligence tool**. It parses your codebase with [tree-sitter](https://tree-sitter.github.io/), stores every symbol, edge, and file in a local SQLite database, and exposes the result as a queryable **knowledge graph** — over the [Model Context Protocol (MCP)](/codegraph/reference/mcp-server/), a CLI, and a TypeScript library.

It exists to make AI coding agents — Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, and Kiro — **answer structural questions without scanning files**. Instead of fanning out across `grep`, `glob`, and `Read` to reconstruct how code fits together, an agent queries a pre-built index and gets the answer in a handful of calls.
It exists to make AI coding agents — Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, and octo — **answer structural questions without scanning files**. Instead of fanning out across `grep`, `glob`, and `Read` to reconstruct how code fits together, an agent queries a pre-built index and gets the answer in a handful of calls.

## Why it matters

Expand Down
2 changes: 1 addition & 1 deletion site/src/content/docs/getting-started/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Already have Node? `npm i -g @colbymchenry/codegraph` works on any version. Code
codegraph install
```

Auto-detects and configures Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, and Kiro — wiring the CodeGraph MCP server into each. This step connects your agents only; it does **not** index any code. (Shortcut: `npx @colbymchenry/codegraph` downloads and runs the installer in one go.)
Auto-detects and configures Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, and octo — wiring the CodeGraph MCP server into each. This step connects your agents only; it does **not** index any code. (Shortcut: `npx @colbymchenry/codegraph` downloads and runs the installer in one go.)

## 3. Initialize each project

Expand Down
2 changes: 1 addition & 1 deletion site/src/content/docs/guides/indexing.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ codegraph sync # incremental — only changed files

## Stay fresh automatically

**You don't need to run `codegraph sync` by hand during an agent session.** When your agent (Claude Code, Cursor, Codex, opencode, Hermes, Gemini, Antigravity, Kiro) launches `codegraph serve --mcp`, three layers cooperate to keep the index in step with your code — and to never give the agent a quiet wrong answer in the small window between an edit and the next sync.
**You don't need to run `codegraph sync` by hand during an agent session.** When your agent (Claude Code, Cursor, Codex, opencode, Hermes, Gemini, Antigravity, Kiro, octo) launches `codegraph serve --mcp`, three layers cooperate to keep the index in step with your code — and to never give the agent a quiet wrong answer in the small window between an edit and the next sync.

### 1. File watcher with debounced auto-sync (always on)

Expand Down
1 change: 1 addition & 0 deletions site/src/content/docs/reference/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The interactive installer auto-detects and configures each supported agent — w
- **Gemini CLI**
- **Antigravity IDE**
- **Kiro**
- **octo**

Run `npx @colbymchenry/codegraph` and pick your agent(s); see [Installation](/codegraph/getting-started/installation/) for the non-interactive flags.

Expand Down
2 changes: 1 addition & 1 deletion site/src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const install = 'npx @colbymchenry/codegraph';
<h2>MCP server</h2>
<p>
Expose the graph to Claude Code, Cursor, Codex, opencode, Hermes,
Gemini, Antigravity, and Kiro over MCP — agents answer in a handful of calls.
Gemini, Antigravity, Kiro, and octo over MCP — agents answer in a handful of calls.
</p>
</article>
<article class="feature">
Expand Down
4 changes: 2 additions & 2 deletions src/bin/codegraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2181,7 +2181,7 @@ program
*/
program
.command('install')
.description('Install codegraph MCP server into one or more agents (Claude Code, Cursor, Codex CLI, opencode, Hermes Agent)')
.description('Install codegraph MCP server into one or more agents (Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, octo)')
.option('-t, --target <ids>', 'Target agent(s): comma-separated ids, or "auto"|"all"|"none". Default: prompt')
.option('-l, --location <where>', 'Install location: "global" or "local". Default: prompt')
.option('-y, --yes', 'Non-interactive: defaults to --location=global --target=auto, auto-allow on')
Expand Down Expand Up @@ -2248,7 +2248,7 @@ program
*/
program
.command('uninstall')
.description('Remove codegraph from your agents (Claude Code, Cursor, Codex CLI, opencode, Hermes Agent)')
.description('Remove codegraph from your agents (Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, octo)')
.option('-t, --target <ids>', 'Target agent(s): comma-separated ids, or "all". Default: all')
.option('-l, --location <where>', 'Uninstall location: "global" or "local". Default: prompt')
.option('-y, --yes', 'Non-interactive: defaults to --location=global --target=all')
Expand Down
6 changes: 3 additions & 3 deletions src/installer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* Multi-target: writes MCP server config + instructions for the
* agents the user picks (Claude Code, Cursor, Codex CLI, opencode,
* Hermes Agent, Gemini CLI, Antigravity IDE).
* Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, octo).
* Defaults to the Claude-only behavior for backwards compatibility
* when no targets are explicitly chosen and nothing else is detected.
*
Expand Down Expand Up @@ -388,8 +388,8 @@ export async function runUninstaller(opts: RunUninstallerOptions): Promise<void>
const sel = await clack.select({
message: 'Remove CodeGraph from all your projects, or just this one?',
options: [
{ value: 'global' as const, label: 'All projects (global)', hint: '~/.claude, ~/.cursor, ~/.codex, ~/.config/opencode, ~/.hermes, ~/.gemini, ~/.kiro' },
{ value: 'local' as const, label: 'Just this project (local)', hint: './.claude, ./.cursor, ./opencode.jsonc, ./.gemini, ./.kiro' },
{ value: 'global' as const, label: 'All projects (global)', hint: '~/.claude, ~/.cursor, ~/.codex, ~/.config/opencode, ~/.hermes, ~/.gemini, ~/.kiro, ~/.octo' },
{ value: 'local' as const, label: 'Just this project (local)', hint: './.claude, ./.cursor, ./opencode.jsonc, ./.gemini, ./.kiro, ./.octo' },
],
initialValue: 'global' as const,
});
Expand Down
143 changes: 143 additions & 0 deletions src/installer/targets/octo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/**
* octo (octo-agent) target.
*
* - MCP server entry to `~/.octo/mcp.json` (global) or
* `./.octo/mcp.json` (local) under the standard `mcpServers.codegraph`
* key. The shape is the same one Claude Code / Cursor / Gemini use,
* so users can copy-paste configs between octo and other agents.
*
* - Project instructions are upserted into `~/.octo/octorules.md`
* (global) or `./.octo/octorules.md` (local) using the same
* marker-fenced CodeGraph section that Claude / Codex / Gemini use,
* because octo loads these rules into every session's system prompt.
*
* - No permissions concept — octo gates tool invocations through its
* own permission-mode system, not an external allowlist. `autoAllow`
* is silently ignored.
*
* Docs: https://octo-agent.dev/docs/guides/connect-mcp-servers
*/

import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import {
CODEGRAPH_INSTRUCTIONS_BLOCK,
CODEGRAPH_SECTION_END,
CODEGRAPH_SECTION_START,
} from '../instructions-template';
import {
AgentTarget,
DetectionResult,
InstallOptions,
Location,
WriteResult,
} from './types';
import {
getMcpServerConfig,
jsonDeepEqual,
readJsonFile,
removeMarkedSection,
upsertInstructionsEntry,
writeJsonFile,
} from './shared';

function configDir(loc: Location): string {
return loc === 'global'
? path.join(os.homedir(), '.octo')
: path.join(process.cwd(), '.octo');
}

function mcpJsonPath(loc: Location): string {
return path.join(configDir(loc), 'mcp.json');
}

function octorulesPath(loc: Location): string {
return path.join(configDir(loc), 'octorules.md');
}

class OctoTarget implements AgentTarget {
readonly id = 'octo' as const;
readonly displayName = 'octo';
readonly docsUrl = 'https://octo-agent.dev/docs/guides/connect-mcp-servers';

supportsLocation(_loc: Location): boolean {
return true;
}

detect(loc: Location): DetectionResult {
const file = mcpJsonPath(loc);
const config = readJsonFile(file);
const alreadyConfigured = !!config.mcpServers?.codegraph;
const installed = loc === 'global'
? fs.existsSync(configDir('global')) || fs.existsSync(file)
: fs.existsSync(file) || fs.existsSync(configDir('local'));
return { installed, alreadyConfigured, configPath: file };
}

install(loc: Location, _opts: InstallOptions): WriteResult {
const files: WriteResult['files'] = [];
files.push(writeMcpEntry(loc));
files.push(upsertInstructionsEntry(octorulesPath(loc)));
return { files };
}

uninstall(loc: Location): WriteResult {
const files: WriteResult['files'] = [];

const file = mcpJsonPath(loc);
const config = readJsonFile(file);
if (config.mcpServers?.codegraph) {
delete config.mcpServers.codegraph;
if (Object.keys(config.mcpServers).length === 0) {
delete config.mcpServers;
}
writeJsonFile(file, config);
files.push({ path: file, action: 'removed' });
} else {
files.push({ path: file, action: 'not-found' });
}

const rulesFile = octorulesPath(loc);
const instructionsAction = removeMarkedSection(
rulesFile,
CODEGRAPH_SECTION_START,
CODEGRAPH_SECTION_END,
);
files.push({ path: rulesFile, action: instructionsAction });

return { files };
}

printConfig(loc: Location): string {
const target = mcpJsonPath(loc);
const snippet = JSON.stringify({ mcpServers: { codegraph: getMcpServerConfig() } }, null, 2);
return `# Add to ${target}\n\n${snippet}\n\n# Add to ${octorulesPath(loc)}\n\n${CODEGRAPH_INSTRUCTIONS_BLOCK}\n`;
}

describePaths(loc: Location): string[] {
return [mcpJsonPath(loc), octorulesPath(loc)];
}
}

function writeMcpEntry(loc: Location): WriteResult['files'][number] {
const file = mcpJsonPath(loc);
const dir = path.dirname(file);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });

const existing = readJsonFile(file);
const before = existing.mcpServers?.codegraph;
const after = getMcpServerConfig();

if (jsonDeepEqual(before, after)) {
return { path: file, action: 'unchanged' };
}
const action: 'created' | 'updated' =
before ? 'updated' : (fs.existsSync(file) ? 'updated' : 'created');
if (!existing.mcpServers) existing.mcpServers = {};
existing.mcpServers.codegraph = after;
writeJsonFile(file, existing);
return { path: file, action };
}

export const octoTarget: AgentTarget = new OctoTarget();
Loading