# NxtSoft Labs — Documentation (full corpus) > Documentation for NxtSoft Labs open-source developer tools. Featured project — CGraph: A native C++ engine that turns codebases into knowledge graphs for coding agents. This file concatenates every documentation page as Markdown, in navigation order. Each page links back to its canonical HTML source. --- # Overview > What CGraph is, the problem it solves, and how its pieces fit together. [Source](https://open.nxtsoft.io/docs/cgraph/overview) CGraph is a native C++ graph analysis engine for source trees. It scans a project, extracts its structure into a deterministic graph, writes portable exports, and exposes the same graph through a local daemon, a thin client, and an MCP server — so coding agents navigate your code instead of grepping it. ## Why it exists A coding agent that reads code by grepping sees text, not the graph of files, symbols, and references that the text encodes. Every request re-derives that structure from scratch, imperfectly, and the answer is only as good as the search terms. There is no persistent, queryable model of the codebase for the agent to reason over. ## What problem it solves CGraph extracts the structure once and keeps it. Instead of "find every line that mentions `parseConfig`", an agent asks "what calls `parseConfig`, and what breaks if I change its signature" — and gets a precise answer from the graph rather than a page of string matches. ## How it works Extraction, a warm daemon, and an MCP server form a pipeline. _Repository to query — extracted once, then kept warm_ ```text Repository -> Parser -> Resolver -> Graph -> Query ``` - **`cgraph`** — a one-shot CLI that scans a source tree into a deterministic graph and writes portable exports. - **`graphd`** — a daemon that keeps the graph warm and can watch the tree. - **`cgraph-client`** — a thin client for talking to the daemon. - **`cgraph-mcp`** — an MCP server that exposes the graph to coding agents. ## What it does - **Tree-sitter extraction** — C, C++, Java, JavaScript, TypeScript, TSX, Kotlin, Scala, Groovy, Python, and Ruby, plus structured extraction for Apex, Delphi, and MSBuild/XML. - **8 MCP tools** — query, explain, impact, path, context, update, status, and shutdown. - **6 export formats** — JSON, HTML, SVG, Obsidian, Cypher, and a call-flow view. - **Warm daemon** — Keeps the graph resident so queries don't re-scan the tree. ## When to use it Reach for CGraph when an agent (or a developer) needs to reason about how a codebase fits together — call relationships, impact of a change, paths between symbols — rather than just find where a string appears. It complements, rather than replaces, full-text search. ## Where to go next Continue to [Getting Started](/docs/cgraph/getting-started) for the shortest path to a working graph, or [Installation](/docs/cgraph/installation) for the full build. --- # Getting Started > The shortest path from a checkout to a graph an agent can query. [Source](https://open.nxtsoft.io/docs/cgraph/getting-started) This is the fast path. It assumes the [prerequisites](/docs/cgraph/installation) are in place; for the full build and troubleshooting, see Installation. ## Build the tools **clone and build** ```bash git clone https://github.com/taylor009/CGraph.git cd CGraph export VCPKG_ROOT="/path/to/your/vcpkg" cmake --preset default cmake --build --preset default ``` ## Build a graph Point the CLI at any source tree: **extract** ```bash build/default/src/cli/cgraph --root . --out cgraph-out ``` This writes the graph and its exports (JSON, HTML, SVG, Obsidian, Cypher, and a call-flow view) into `cgraph-out`. ## Next Register the graph with a coding agent in the [Quick Start](/docs/cgraph/quick-start), or read [Installation](/docs/cgraph/installation) if the build didn't succeed. --- # Installation > Prerequisites and the full build, from clone to a verified binary. [Source](https://open.nxtsoft.io/docs/cgraph/installation) CGraph builds from source with CMake and vcpkg. There is no prebuilt binary yet; this page covers the full build. ## Prerequisites CGraph is a C++20 project. You need a recent toolchain and vcpkg for its dependencies. - **CMake** 3.25 or newer - **Ninja** - A **C++20 compiler** — recent Clang or GCC, or Apple Clang from the Xcode Command Line Tools - **Git** - **vcpkg**, providing `curl`, `igraph`, `nlohmann-json`, and `utf8proc` Tree-sitter is vendored under `vendor/tree-sitter`, so you do not install it separately. ## Get vcpkg Point `VCPKG_ROOT` at an existing vcpkg, or bootstrap one inside the checkout. #### existing vcpkg ```bash export VCPKG_ROOT="/path/to/your/vcpkg" ``` #### bootstrap locally ```bash git clone https://github.com/microsoft/vcpkg .vcpkg ./.vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT="$PWD/.vcpkg" ``` ## Build **configure, build, test** ```bash git clone https://github.com/taylor009/CGraph.git cd CGraph cmake --preset default cmake --build --preset default ctest --preset default ``` ## Verify Extract a graph of the CGraph repository itself: **smoke test** ```bash build/default/src/cli/cgraph --root . --out cgraph-out ``` The binaries land under `build/default/src/`: the `cgraph` CLI, the `graphd` daemon, the `cgraph-client` thin client, and the `cgraph-mcp` server. ## Next Head to the [Quick Start](/docs/cgraph/quick-start) to run the daemon and register CGraph with a coding agent. --- # Quick Start > Build a graph, run the daemon, and register CGraph with a coding agent. [Source](https://open.nxtsoft.io/docs/cgraph/quick-start) This walks from a built checkout to an agent that can query your graph. If you have not built the tools yet, start with [Installation](/docs/cgraph/installation). ## Build a graph **extract** ```bash build/default/src/cli/cgraph --root . --out cgraph-out ``` `--root` is the source tree to scan; `--out` is where the graph and its exports are written. ```text cgraph [--root PATH] [--out PATH] ``` | Flag | Meaning | | --- | --- | | `--root` | Source tree to scan (defaults to the current directory). | | `--out` | Directory for the graph and exports. | ## Run the daemon Keep the graph warm so queries don't re-scan the tree: **serve** ```bash build/default/src/daemon/graphd --root . ``` The daemon accepts `--idle-timeout SECONDS` and `--no-watch` if you want to bound its lifetime or disable file watching. ## Register with a coding agent Expose the graph over MCP. For Claude Code, point the MCP server at the built binary: **register** ```bash claude mcp add cgraph -- "$PWD/build/default/src/mcp/cgraph-mcp" ``` Use the absolute path to `cgraph-mcp` unless the binary is on your `PATH`. ## What the agent can do Once registered, the agent has eight tools over the graph: - `graph_query`, `graph_explain`, `graph_impact`, `graph_path`, `graph_context` - `graph_update`, `graph_status`, `graph_shutdown` See [MCP Integration](/docs/cgraph/mcp) for what each tool does. --- # Core Concepts > The vocabulary and mental model behind CGraph — from extraction to the graph an agent queries. [Source](https://open.nxtsoft.io/docs/cgraph/core-concepts) CGraph has a small set of concepts that recur throughout the docs. This page is the mental model; later pages go deep on each stage. ## The core idea A codebase is already a graph — files import files, functions call functions, symbols reference symbols. That graph is just implicit in the text. CGraph makes it explicit and queryable: it extracts the structure once into a deterministic graph, then serves that graph to tools and agents so they reason over relationships instead of re-deriving them from string search. ## The pipeline Everything flows through three stages. Extraction reads the source; graph post-processing turns raw extraction into a resolved graph; enrichment layers optional semantic detail on top. _Source to a resolved, queryable graph_ ```text Source tree | detection + extraction (tree-sitter / regex) v Raw graph | resolution + analysis (imports, calls, relations, dedup, communities) v Resolved graph | semantic enrichment (optional, host-driven) v Queryable graph -> exports + daemon + MCP ``` ## Terminology | Term | What it means | | --- | --- | | **Extraction** | Deterministic parse of the source tree into nodes and links — tree-sitter for supported languages, regex/structured for the rest. | | **Resolution** | Post-processing that connects the raw graph: import resolution, raw call resolution, and relation resolution. | | **Semantic deduplication** | A post-processing step that merges duplicate semantic nodes. | | **Community detection** | Graph analysis that groups related nodes into communities. | | **Enrichment** | An optional, host-driven step that adds semantic fragments (chunk planning, validated before they mutate the graph). | | **Gather** | How a query collects a neighborhood — `fixed` packs the whole k-hop neighborhood; `adaptive` keeps the full 2-hop core and expands the third hop only along query-relevant nodes. | | **Context packing** | Fitting the gathered neighborhood into a token budget (a knapsack-style pack) for an agent. | | **Blast radius** | The transitive set of nodes reachable from a change — the basis of impact analysis. | ## Determinism Extraction is **deterministic**: the same source tree produces the same graph. That matters because an agent's answers should not drift run to run, and because a deterministic graph can be diffed — the same property that lets the daemon fold edits in incrementally rather than rebuilding from scratch. ## How it compares | | CGraph | grep | LSP | | --- | --- | --- | --- | | Persistent, queryable model | ✓ | ✕ | ✓ | | Cross-file impact / blast radius | ✓ | ✕ | partial | | Budgeted context for agents | ✓ | ✕ | ✕ | | Language-agnostic graph | ✓ | ✓ | ✕ | CGraph is not a replacement for full-text search or a language server — it answers a different question: how the pieces relate, and what a change touches. ## Where to go next - [Graph Model](/docs/cgraph/graph-model) — what the nodes and links actually are. - [Memory](/docs/cgraph/memory) — how the graph persists and stays warm. --- # Graph Model > What CGraph's nodes and links represent, and how the graph is shaped. [Source](https://open.nxtsoft.io/docs/cgraph/graph-model) CGraph represents a codebase as a directed graph of **nodes** and **links**, serialized as node-link JSON (`graph.json`). This page describes what those nodes and links mean. ## Nodes Nodes are the entities extracted from the source tree — the files, symbols, and declarations that make up a codebase (files, symbols, functions, classes, and the references between them). Semantic enrichment can add further nodes, such as documents that describe parts of the code. The canonical set of node kinds is defined by the extractor in the CGraph `src/engine` code rather than enumerated in the public README. Treat the list above as the categories of things captured, not a closed enum — this page will be pinned to the exact kinds once they are confirmed against the source. ## Links Links are directed edges between nodes. They come from the resolution stage: - **Imports** — from import resolution, connecting a file or module to what it pulls in. - **Calls** — from raw call resolution, connecting a caller to a callee (the basis of the call-flow export). - **Relations** — from relation resolution, plus semantic relations added during enrichment (for example, a `describes` relation from a document to code). _A directed graph of code entities and their relationships_ ```text file --imports--> file fn --calls-----> fn doc --describes-> symbol ``` ## Why a graph Two questions drive the model: *what calls this?* and *what breaks if I change it?* Both are graph traversals — the first walks incoming call edges, the second walks the transitive **blast radius** of a node. Expressing code as a graph makes these first-class queries instead of heuristic text searches. ## Tradeoffs - **Precision vs. recall** — a resolved graph gives precise relationships, but resolution is only as good as extraction; dynamic dispatch and reflection are hard to resolve statically, so some call edges are approximate. - **Structure, not semantics** — the base graph captures how code connects, not what it means. Semantic meaning is layered in optionally via enrichment. ## Exports The same graph is written in several shapes: `graph.json` (the canonical node-link form), `graph.html` and `graph.svg` (visual), `obsidian.md` (a vault), `cypher.txt` (for graph databases), and `call-flow.html` (the call graph). ## Where to go next - [Memory](/docs/cgraph/memory) — how the graph is stored and kept warm. - [Architecture](/docs/cgraph/architecture) — the extraction and resolution pipeline in depth. --- # Memory > How CGraph persists the graph, keeps it warm, and serves context to agents. [Source](https://open.nxtsoft.io/docs/cgraph/memory) "Memory" in CGraph is the persistent, warm graph that agents query — the reason they don't re-derive a codebase's structure on every request. ## Why persistence matters An agent that rebuilds its understanding each turn is slow and inconsistent. CGraph extracts the graph once, persists it, and keeps it resident so that queries are fast and stable across a session — the graph is the agent's durable memory of the codebase. ## Persistent state The canonical graph is written to `cgraph-out/` as `graph.json` (plus the other exports). When the daemon is running, incremental state is re-persisted to `cgraph-out/` in the background and on shutdown, so a restart resumes from the last known graph rather than a cold rescan. Content-hash cache records track semantic enrichment state, so unchanged content isn't re-enriched. ## Warm state and incremental updates The daemon (`graphd`) keeps the graph warm and folds edits in incrementally: - Ordinary source edits are folded into the graph **within a couple of seconds**. - A large batch — a branch switch, say — collapses into a single full rescan rather than thousands of tiny updates. - Without `--watch`, the graph is updated only by explicit `update` operations. While the graph is being built, client queries return `graph_state: "building"` so a caller can distinguish "not ready yet" from "genuinely empty". ## Serving context to agents Memory is only useful if it fits the agent's context window. When an agent asks for context around a node, CGraph **gathers** a neighborhood and **packs** it to a budget: - `gather: "fixed"` packs the whole k-hop neighborhood. - `gather: "adaptive"` keeps the full 2-hop core and expands the third hop only along query-relevant nodes. - Packing is knapsack-style — fit the most relevant nodes into the token budget. The response reports what happened: a `reach` summary (`candidates`, `expanded_past_core`, `gated_at_core`) alongside the `gather` and `packing` mode, so the retrieval is inspectable rather than a black box. Performance figures for adaptive gather (recall lift versus token cost) are documented on the Benchmarks page, with methodology — not asserted here. ## Where to go next - [Graph Model](/docs/cgraph/graph-model) — what is stored. - [Retrieval](/docs/cgraph/retrieval) and [Context Packing](/docs/cgraph/context-packing) — the gather and packing algorithms in depth. --- # Architecture > How CGraph's pieces fit together — from a source tree to a graph an agent queries. [Source](https://open.nxtsoft.io/docs/cgraph/architecture) CGraph is a small set of programs around one shared engine. The engine extracts and resolves the graph; the programs are different front doors onto it. ## The shape of the system _Repository to query, and the four front doors onto the engine_ ```text +-------------------+ Repository -------> | engine | -----> exports (json/html/svg/...) | detect · extract | | resolve · analyze| +---------+---------+ | +------------------+------------------+ | | | cgraph graphd cgraph-mcp (one-shot) (warm daemon) (MCP over stdio) | cgraph-client (thin client) ``` ## The four programs - **`cgraph`** — the one-shot CLI. Scans a tree, builds the graph, writes exports, exits. Good for CI and one-off analysis. - **`graphd`** — the daemon. Keeps the graph warm, watches the tree, and folds in edits incrementally. Good for an interactive session. - **`cgraph-client`** — a thin client that sends operations to a running daemon. - **`cgraph-mcp`** — an MCP server that exposes the graph to coding agents; its tool calls route through the same daemon operation handler as the thin client. ## The engine `src/engine` owns the deterministic core: detection, extraction, graph building, analysis, and daemon operations. Because extraction is deterministic, the same tree always produces the same graph — which is what lets the daemon diff and fold in changes rather than rebuilding. ## Repository layout ```text src/cli/ one-shot CLI: cgraph src/daemon/ daemon: graphd src/client/ thin client: cgraph-client src/mcp/ MCP server: cgraph-mcp src/engine/ detection, extraction, graph building, analysis, daemon ops vendor/ vendored tree-sitter core and grammars ``` ## Reading order The rest of this section follows a request through the system: how the graph is built ([Indexing Pipeline](/docs/cgraph/indexing-pipeline)), how it stays warm ([Daemon Architecture](/docs/cgraph/daemon) and [Incremental Updates](/docs/cgraph/incremental-updates)), and how a query is answered ([Retrieval](/docs/cgraph/retrieval) and [Context Packing](/docs/cgraph/context-packing)). --- # Indexing Pipeline > How CGraph turns a source tree into a resolved, queryable graph. [Source](https://open.nxtsoft.io/docs/cgraph/indexing-pipeline) Indexing is the path from raw files to a resolved graph. It runs on every full build and, in pieces, on every incremental update. ## The stages _Scanning to a resolved graph_ ```text Scan root, .gitignore-aware, skip generated / dependency dirs | Extract tree-sitter (11 languages) or regex/structured extraction | Post-process import resolution -> raw call resolution -> relation resolution | -> semantic deduplication -> community detection -> analysis | Export graph.json (+ html, svg, obsidian, cypher, call-flow) ``` ## Scan CGraph scans the source tree deterministically, honoring the root `.gitignore` and skipping generated and dependency directories by default. Determinism here is the foundation for everything downstream — the same tree yields the same node set every time. ## Extract Each file is parsed into nodes and links. Supported languages (C, C++, Java, JavaScript, TypeScript, TSX, Kotlin, Scala, Groovy, Python, Ruby) use vendored tree-sitter grammars; the rest (Apex, Delphi, MSBuild/XML, MCP config) use regex/structured extraction. ## Post-process Extraction produces a raw graph; post-processing resolves it into a connected one, in order: 1. **Import resolution** — connect files/modules to what they import. 2. **Raw call resolution** — connect callers to callees. 3. **Relation resolution** — resolve remaining relationships. 4. **Semantic deduplication** — merge duplicate semantic nodes. 5. **Community detection** — group related nodes into communities. 6. **Graph analysis** — compute the analytical properties queries rely on. The intermediate data shapes between these stages, and the exact ordering rules within post-processing, are defined in `src/engine` and not enumerated in the public README. This page documents the stages CGraph performs; the internal representations are pending confirmation against the source. ## Export The resolved graph is written to `cgraph-out/` as `graph.json` (canonical node-link) plus the visual and interchange formats. See the [Graph Model](/docs/cgraph/graph-model) for what those nodes and links mean. ## Tradeoffs Static resolution is precise for direct calls and imports but approximate where the language isn't: dynamic dispatch, reflection, and runtime wiring can't always be resolved from source alone. CGraph favors a deterministic, reproducible graph over chasing every dynamic edge. --- # Daemon Architecture > The graphd lifecycle — startup, watching, persistence, and shutdown. [Source](https://open.nxtsoft.io/docs/cgraph/daemon) `graphd` is what makes the graph *warm*. Instead of rebuilding on every query, it holds the graph in memory, watches the tree, and folds in changes as they happen. ## Lifecycle _The daemon's lifecycle_ ```text start ──> build initial graph ──> serve + watch ──┐ ^ │ edits: incremental fold-in └──────────┘ branch switch: full rescan │ idle-timeout / shutdown ──┴──> re-persist to cgraph-out/ ──> exit ``` ## Startup Launch the daemon against a project root: **start the daemon** ```bash graphd --root /path/to/project ``` On first run it builds the initial graph (seconds for a typical tree), then begins serving operations and watching the tree. ## Watching While running, the daemon watches the project and folds source edits into the graph incrementally — usually within a couple of seconds. A large batch, such as a branch switch, collapses into a single full rescan rather than thousands of tiny updates. Pass `--no-watch` to disable watching; updates then happen only via explicit `update` operations. See [Incremental Updates](/docs/cgraph/incremental-updates) for the details. ## Flags ```text graphd --root PATH [--idle-timeout SECONDS] [--no-watch] ``` | Flag | Meaning | | --- | --- | | `--root` | Project tree to index and watch. | | `--idle-timeout` | Shut down after this many idle seconds. | | `--no-watch` | Don't watch the tree; update only on explicit ops. | The default `--idle-timeout` value is not stated in the public README and is left pending rather than guessed. ## Persistence and shutdown Incremental state is re-persisted to `cgraph-out/` in the background and on shutdown, so restarting the daemon resumes from the last graph instead of a cold rebuild. Shut it down explicitly with the client: **shut down** ```bash cgraph-client shutdown ``` --- # Retrieval > How a query travels from a client or agent to an answer from the graph. [Source](https://open.nxtsoft.io/docs/cgraph/retrieval) Retrieval is the read path: a client or agent asks a question, the daemon answers it from the warm graph. Every front door funnels through one operation handler. ## Query execution _One operation handler behind every front door_ ```text cgraph-client ─┐ ├─ JSON op ─> graphd operation handler ─> warm graph ─> JSON result cgraph-mcp ─┘ ``` The thin client sends an operation and a JSON payload to the daemon: **a query** ```bash cgraph-client --root /path/to/project query '{"q":"Parser"}' ``` MCP tool calls route through the **same daemon operation handler** as the thin client, so an agent and a shell get identical semantics. ## The operations - **`query`** — find nodes matching a query. - **`explain`** — explain a node and its role. - **`impact`** — the transitive blast radius of a change. - **`path`** — the shortest path between two symbols. - **`context`** — a packed neighborhood for an agent (see [Context Packing](/docs/cgraph/context-packing)). - **`update`** / **`status`** / **`shutdown`** — maintenance and introspection. ## Responses Responses are JSON. A `status` response, for example, reports daemon process metadata, graph node and edge counts, cache hit rate, and semantic enrichment state — enough to tell whether the graph is ready and how warm the cache is. The client–daemon wire transport (socket type, framing) is not detailed in the public README; the MCP transport is documented on the [MCP Integration](/docs/cgraph/mcp) page. This page describes the operation semantics, which are stated; the transport specifics are pending. --- # Context Packing > How CGraph gathers a neighborhood and fits it into an agent's token budget. [Source](https://open.nxtsoft.io/docs/cgraph/context-packing) An agent's context window is finite. When it asks for context around a node, CGraph has to choose *which* of the surrounding graph to include — enough to be useful, few enough to fit. That is gather-and-pack. ## Gather: fixed vs adaptive _Adaptive gather keeps the core and expands only where the query points_ ```text fixed: [ whole k-hop neighborhood ] (query-independent) adaptive: [ full 2-hop core ] + third hop, only along query-relevant nodes ``` - **`gather: "fixed"`** packs the whole k-hop neighborhood — simple and query-independent. - **`gather: "adaptive"`** keeps the full 2-hop core but expands the third hop only along nodes relevant to the query. It needs a `query`/`q` — without one the relevance gate is a no-op and it behaves like a fixed gather. ## Pack: knapsack The gathered candidates are packed to a token `budget` with a knapsack strategy (`packing: "knapsack"`) — fit the most relevant nodes into the budget rather than truncating arbitrarily. **a budgeted context request** ```bash cgraph-client context '{"q":"Parser","budget":5000}' ``` ## Reach: an inspectable result The response reports how the neighborhood was selected, so retrieval is auditable rather than a black box: | Counter | Meaning | | --- | --- | | `candidates` | Total potential nodes considered. | | `expanded_past_core` | Nodes expanded beyond the 2-hop core. | | `gated_at_core` | Nodes filtered out at the core boundary. | Alongside these, the response carries the `gather` and `packing` mode it used. ## Why adaptive Expanding every third hop is expensive; expanding none loses relevant context. Adaptive gather targets the middle: it spends tokens only where the query points. The measured tradeoff — recall lift versus token cost — is documented on the Benchmarks page with methodology, not asserted here. --- # Incremental Updates > How the daemon keeps the graph current without rebuilding it. [Source](https://open.nxtsoft.io/docs/cgraph/incremental-updates) A warm graph is only useful if it stays current. The daemon folds changes into the existing graph rather than rebuilding from scratch — most of the time. ## Fold-in vs. full rescan _Small changes fold in; large batches rescan_ ```text edit a few files ──> incremental fold-in (~ a couple of seconds) branch switch ──> one full rescan (collapses the batch) ``` - **Ordinary edits** are folded into the graph incrementally, usually within a couple of seconds. - **A large batch** — switching branches, say — collapses into a single full rescan instead of thousands of tiny updates. Rebuilding once is cheaper than folding in a whole tree's worth of changes. ## Explicit updates Without `--watch`, or to force a refresh, ask the daemon to update: **explicit rescan** ```bash cgraph-client update '{"path":"."}' ``` ## Persistence Incremental state is re-persisted to `cgraph-out/` in the background and on shutdown, so the next start resumes from the current graph rather than a cold build. ## Building vs. empty While the graph is under construction, queries return `graph_state: "building"`, so a caller can tell "not ready yet" apart from "genuinely no results". The debounce window and the batch-size threshold that tips a fold-in into a full rescan are not stated in the public README, and are left pending rather than invented. --- # Internals > The engine at the center, and what is and isn't public about it. [Source](https://open.nxtsoft.io/docs/cgraph/internals) Everything in the earlier architecture pages runs on one component: the engine. This page is a short, honest map of it. ## One engine, several front doors `src/engine` owns the deterministic core — detection, extraction, graph building, analysis, and daemon operations. The CLI, daemon, thin client, and MCP server are thin programs around it. Critically, tool calls from the MCP server route through the **same daemon operation handler** used by the thin client, so there is one code path for answering an operation, not several. _Thin front doors, one engine_ ```text cgraph / graphd / cgraph-client / cgraph-mcp | one operation handler | engine detect · extract · build · analyze ``` ## Determinism as an invariant Extraction is deterministic: identical input trees produce identical graphs. This is not a nicety — it's what makes incremental updates and background persistence correct. If the same tree could produce different graphs, a fold-in could not be diffed against the previous state. ## What's public, and what isn't This page deliberately stops where the public README does. The engine's internal module structure, class layout, in-memory data structures, and the exact representation passed between pipeline stages are **not documented publicly**. Rather than reverse-engineer or invent internals, this page marks them pending. When the engine's internals are documented against the source, this page will be filled in with the real module map — not before. ## Where to go next - [Indexing Pipeline](/docs/cgraph/indexing-pipeline) — the stages the engine runs. - [Daemon Architecture](/docs/cgraph/daemon) — how the engine is kept warm. --- # MCP Integration > How CGraph speaks the Model Context Protocol, and the tools it exposes. [Source](https://open.nxtsoft.io/docs/cgraph/mcp) `cgraph-mcp` exposes the graph to coding agents over the Model Context Protocol (MCP). Its tool calls route through the same daemon operation handler as the thin client, so an agent gets exactly the semantics the CLI does. ## The protocol `cgraph-mcp` speaks **newline-delimited JSON-RPC 2.0 over stdio**, protocol version `2024-11-05`. It implements the standard handshake and tool methods: ```text JSON-RPC 2.0 over stdio (protocol 2024-11-05) ``` | Method | Purpose | | --- | --- | | `initialize` | Handshake and capability exchange. | | `notifications/initialized` | Client signals it's ready. | | `tools/list` | Enumerate the available tools. | | `tools/call` | Invoke a tool. | Invalid JSON receives a JSON-RPC parse error response rather than crashing the server. ## The request flow _An agent's tool call, end to end_ ```text agent ── JSON-RPC (stdio) ──> cgraph-mcp ──> daemon operation handler ──> graph ^ | └──────────────────── JSON result ──────────────────────────────────────┘ ``` ## The eight tools - **graph_query** — Find nodes matching a query. - **graph_explain** — Explain a node and its role. - **graph_impact** — The transitive blast radius of a change. - **graph_path** — The shortest path between two symbols. - **graph_context** — A packed, budgeted neighborhood for the agent. - **graph_update** — Fold in changes / trigger a rescan. - **graph_status** — Daemon and graph health. - **graph_shutdown** — Stop the daemon. ## How it finds the project and the daemon `cgraph-mcp` resolves the project **root** in priority order: ```text --root flag > CLAUDE_PROJECT_DIR env var > working directory ``` and discovers the **daemon** in priority order: ```text --daemon > CGRAPH_DAEMON_PATH env var > graphd next to the binary > build-tree layout ``` This is why `cgraph-mcp` works from an agent with minimal configuration: an agent that sets `CLAUDE_PROJECT_DIR` (like Claude Code) and ships `graphd` next to the binary needs no flags at all. ## Where to go next - [AI Agent Integration](/docs/cgraph/ai-agents) — registering CGraph with Claude Code, Codex, and Cursor. --- # AI Agent Integration > Wiring CGraph into Claude Code, Codex, and Cursor over MCP. [Source](https://open.nxtsoft.io/docs/cgraph/ai-agents) Once CGraph is built, registering it with a coding agent is a one-line MCP setup. The agent then has eight graph tools alongside its usual file and shell access. ## Register the MCP server Point your agent's MCP configuration at the built `cgraph-mcp` binary. #### Claude Code ```bash claude mcp add cgraph -- "$PWD/build/default/src/mcp/cgraph-mcp" ``` #### other agents ```text Configure an MCP server that runs the cgraph-mcp binary over stdio. Command: /absolute/path/to/build/default/src/mcp/cgraph-mcp ``` Use the absolute path to `cgraph-mcp` unless it's on your `PATH`. Claude Code sets `CLAUDE_PROJECT_DIR`, which CGraph uses to resolve the project root automatically — so no `--root` is needed there. ## What the agent gains With the server registered, the agent can navigate the codebase as a graph: | Ask | Tool | | --- | --- | | "What is `Parser` and where is it used?" | `graph_query`, `graph_explain` | | "What breaks if I change this signature?" | `graph_impact` | | "How do these two modules connect?" | `graph_path` | | "Give me the relevant context, within budget." | `graph_context` | | "Is the graph up to date?" | `graph_status`, `graph_update` | ## Why this beats grepping An agent without a graph re-derives structure from search on every turn. With CGraph it asks precise questions and gets precise answers from a warm, persistent graph — fewer tokens spent rediscovering the codebase, more spent on the task. See [Context Packing](/docs/cgraph/context-packing) for how `graph_context` fits a neighborhood into the agent's budget. ## Requirements - A built `cgraph-mcp` (see [Installation](/docs/cgraph/installation)). - An agent that supports MCP servers over stdio. - The daemon (`graphd`) reachable — `cgraph-mcp` discovers it next to the binary or via `CGRAPH_DAEMON_PATH`. --- # CLI Reference > The cgraph, graphd, and cgraph-client commands and their flags. [Source](https://open.nxtsoft.io/docs/cgraph/cli) CGraph ships four binaries. This page is the reference for the command-line surface; see [Quick Start](/docs/cgraph/quick-start) for a guided walkthrough. ## cgraph The one-shot CLI: scan a tree, build the graph, write exports, exit. ```text cgraph [--root PATH] [--out PATH] ``` | Flag | Meaning | | --- | --- | | `--root` | Source tree to scan (defaults to the current directory). | | `--out` | Directory for the graph and exports. | ### Enrichment subcommands `cgraph` also drives the host-side semantic enrichment workflow: ```text cgraph enrich-plan [--root PATH] [--out PATH] [--drop DIR] cgraph enrich-ingest [--root PATH] [--out PATH] [--drop DIR] ``` | Flag | Meaning | | --- | --- | | `enrich-plan` | Produce a chunk plan for host-written enrichment fragments. | | `enrich-ingest` | Validate and fold host-written fragments into the graph. | | `--drop` | The semantic drop directory for enrichment fragments. | ## graphd The daemon: keep the graph warm and watch the tree. ```text graphd --root PATH [--idle-timeout SECONDS] [--no-watch] graphd --benchmark-query --graph PATH --query TEXT graphd --version ``` | Flag | Meaning | | --- | --- | | `--root` | Project tree to index and watch. | | `--idle-timeout` | Shut down after this many idle seconds. | | `--no-watch` | Don't watch the tree; update only on explicit ops. | | `--benchmark-query` | Run a one-off benchmark query against a graph. | | `--graph` / `--query` | The graph path and query text for `--benchmark-query`. | | `--version` | Print the version. | ## cgraph-client The thin client: send an operation and a JSON payload to a running daemon. **operations** ```bash cgraph-client --root /path/to/project query '{"q":"Parser"}' cgraph-client context '{"q":"Parser","budget":5000}' cgraph-client update '{"path":"."}' cgraph-client status cgraph-client shutdown ``` The operations mirror the MCP tools: `query`, `explain`, `impact`, `path`, `context`, `update`, `status`, and `shutdown`. ## cgraph-mcp The MCP server, run by an agent over stdio. It takes `--root` and `--daemon` and otherwise resolves both from the environment — see [MCP Integration](/docs/cgraph/mcp). Flags shown here are those stated in the public README. Additional flags and defaults (for example, the `--idle-timeout` default) are not enumerated publicly and are left out rather than guessed. --- # Configuration > The environment variables and resolution rules that configure CGraph. [Source](https://open.nxtsoft.io/docs/cgraph/configuration) CGraph is configured mostly through flags (see the [CLI Reference](/docs/cgraph/cli)) and a small set of environment variables. This page collects the environment and the resolution rules that decide what runs against what. ## Environment variables | Variable | Used by | Meaning | | --- | --- | --- | | `VCPKG_ROOT` | build | Path to vcpkg for the CMake build. | | `CLAUDE_PROJECT_DIR` | `cgraph-mcp` | Project root when no `--root` is given (set by Claude Code). | | `CGRAPH_DAEMON_PATH` | `cgraph-mcp` | Explicit path to the `graphd` binary. | ## Root resolution When `cgraph-mcp` needs the project root, it resolves in priority order: ```text --root flag > CLAUDE_PROJECT_DIR > working directory ``` ## Daemon discovery When `cgraph-mcp` needs the daemon, it resolves in priority order: ```text --daemon > CGRAPH_DAEMON_PATH > graphd next to the binary > build-tree layout ``` This layered resolution is why an agent usually needs no configuration: with the binaries built side by side and `CLAUDE_PROJECT_DIR` set, the defaults resolve correctly. ## Output location The graph and its exports are written to the directory given by `--out` (conventionally `cgraph-out/`), which is also where the daemon re-persists incremental state. CGraph does not have a documented configuration *file* in the public README — behavior is driven by flags, the enrichment drop directory, and the environment variables above. If a config-file format exists in the source, it is intentionally not documented here until it can be verified. This section will be expanded from the real configuration surface, not invented. --- # Examples > End-to-end workflows — from a fresh checkout to an agent reasoning about your code. [Source](https://open.nxtsoft.io/docs/cgraph/examples) These are complete workflows, not isolated commands. Each starts from a built CGraph (see [Installation](/docs/cgraph/installation)) and shows how the pieces fit together in practice. ## Workflow 1 — Index a repository and ask the first questions You've just cloned a service you don't know well and want an agent to help. **1. Build the graph.** **extract** ```bash cgraph --root . --out cgraph-out ``` **2. Start the daemon so queries stay warm.** **serve** ```bash graphd --root . ``` **3. Ask what a symbol is and where it's used.** **query + explain** ```bash cgraph-client query '{"q":"PaymentProcessor"}' cgraph-client explain '{"q":"PaymentProcessor"}' ``` Instead of grepping the string `PaymentProcessor` across the tree, you get the node and its role in the graph. ## Workflow 2 — Check a refactor before you make it You're about to change a function's signature and want to know the blast radius. **impact** ```bash cgraph-client impact '{"q":"parseConfig"}' ``` `impact` returns the transitive set of nodes reachable from `parseConfig` — the things that could break. You review that set *before* editing, not after the tests fail. Pair `impact` with `path` to understand *how* two parts connect: ```bash cgraph-client path '{"from":"HttpServer","to":"Database"}' ``` ## Workflow 3 — Give an agent budgeted context An agent is working on a task and needs the relevant neighborhood around a node, fit into its context window. **adaptive, budgeted context** ```bash cgraph-client context '{"q":"PaymentProcessor","budget":5000}' ``` With a query present, `context` uses adaptive gather — the full 2-hop core plus a query-relevant third hop — and packs it to the 5000-token budget. The response's `reach` counters show what was included and what was gated, so the selection is auditable. See [Context Packing](/docs/cgraph/context-packing) for the mechanics. ## Workflow 4 — Keep the graph current during a session While you work, the daemon folds edits in automatically. After a big change — switching branches, say — it collapses into a single rescan. To force a refresh or check state: **update + status** ```bash cgraph-client update '{"path":"."}' cgraph-client status ``` `status` reports node and edge counts, cache hit rate, and enrichment state — a quick way to confirm the graph is current before relying on it. ## The same, from an agent Every command above has an MCP tool equivalent (`graph_query`, `graph_explain`, `graph_impact`, `graph_path`, `graph_context`, `graph_update`, `graph_status`). Once CGraph is registered (see [AI Agent Integration](/docs/cgraph/ai-agents)), the agent runs these workflows itself — you just describe the goal. --- # Benchmarks > What CGraph measures, how, and the one result published so far. [Source](https://open.nxtsoft.io/docs/cgraph/benchmarks) Benchmarks are only useful when you can see the methodology. This page reports the measurements CGraph publishes, states how they're produced, and is explicit about what is not yet measured — no invented numbers. ## Adaptive gather: recall vs. token cost The question adaptive gather answers is whether targeting the third hop buys back most of the recall of a full 3-hop gather at a fraction of the token cost. _Methodology: Retrieval evaluation measuring grade-2 recall against candidate-token cost. Adaptive gather keeps the full 2-hop core and expands the third hop only along query-relevant nodes; the baseline is a full 3-hop gather. Figures are the values published in the CGraph README; the harness and dataset live in the repository._ | Strategy | Grade-2 recall | Candidate tokens | | --- | --- | --- | | Adaptive third hop | +0.057 | +13% | | Full 3-hop gather | (baseline recall) | +96% | The takeaway: adaptive gather recovers most of the recall of a full third hop for roughly one-seventh of the extra tokens. ## Reproducing a query benchmark `graphd` includes a one-off benchmark mode to time a query against a built graph: **benchmark a query** ```bash graphd --benchmark-query --graph cgraph-out --query "PaymentProcessor" ``` This is the supported path for measuring query behavior on your own graph rather than relying on a headline number. ## What is not yet published Beyond the adaptive-gather result above, CGraph does not publish a full benchmark suite (extraction throughput, query latency distributions, memory footprint, scaling curves) in a form we can cite. Those tables are intentionally left **pending** — this page will grow only with real, reproducible measurements and their methodology, never with placeholder figures. ## Where to go next - [Performance](/docs/cgraph/performance) — tuning guidance grounded in the same mechanics. - [Context Packing](/docs/cgraph/context-packing) — the gather strategy the benchmark evaluates. --- # Performance > How CGraph stays fast, and the levers you have — grounded in mechanics, not invented numbers. [Source](https://open.nxtsoft.io/docs/cgraph/performance) CGraph's performance story is architectural: extract once, keep warm, update incrementally, and spend context tokens only where they matter. This page is the practical guidance that follows from those mechanics. It gives you levers, not benchmark claims — for measured figures see [Benchmarks](/docs/cgraph/benchmarks). ## Keep the graph warm The single biggest lever is running the daemon. A one-shot `cgraph` run rebuilds the graph every time; `graphd` holds it in memory so queries don't re-scan. For any interactive or repeated use, start the daemon. ## Let updates be incremental While watching, the daemon folds ordinary edits into the graph within a couple of seconds rather than rebuilding. Two things follow: - Prefer leaving the daemon watching during a work session. - A large batch — a branch switch — collapses into one full rescan by design; this is cheaper than folding in a whole tree of changes, so expect a brief rebuild after big context switches rather than treating it as a stall. Use `cgraph-client status` to check the cache hit rate and confirm the graph is current before a burst of queries. ## Spend context tokens where they matter For agent context, adaptive gather is the efficient default: it keeps the full 2-hop core and expands the third hop only along query-relevant nodes, then packs to your token `budget`. Provide a `query` (so the relevance gate is active) and a `budget` sized to the agent's window — this is what keeps context cost down without dropping the nodes that matter. ## When to disable watching If you don't want the daemon reacting to filesystem churn — for example in CI, or against a tree that's being rewritten by another process — run with `--no-watch` and drive updates explicitly with `update` operations. You trade automatic freshness for predictable, controlled rebuilds. ## Determinism helps, too Because extraction is deterministic, repeated runs over an unchanged tree produce the same graph, and the daemon can diff and fold changes rather than starting over. You benefit from this automatically; it's the reason incremental updates are possible at all. This page gives qualitative guidance from CGraph's documented mechanics. Specific latency, throughput, and memory figures are not asserted here — they belong on [Benchmarks](/docs/cgraph/benchmarks) with methodology, and are pending real measurement. --- # Design Decisions > The choices that shape CGraph, and the reasoning and tradeoffs behind each. [Source](https://open.nxtsoft.io/docs/cgraph/design-decisions) CGraph makes a handful of load-bearing decisions. This page states each one, why it was made, and what it costs. ## Deterministic extraction **Decision.** Extraction is deterministic — the same source tree always produces the same graph. **Why.** An agent's answers shouldn't drift between runs, and a deterministic graph can be *diffed*. That diffability is what makes incremental updates and background persistence correct: the daemon can fold a change into the previous graph because it knows the previous graph was reproducible. **Tradeoff.** Determinism means resolution is static. Dynamic dispatch, reflection, and runtime wiring can't always be resolved from source, so some edges are approximate. CGraph accepts approximate dynamic edges in exchange for a reproducible, diffable graph. ## One operation handler **Decision.** The MCP server's tool calls route through the *same* daemon operation handler as the thin client. **Why.** An agent and a shell should get identical semantics. Sharing one code path means there's a single place to reason about correctness, and no drift between "what the CLI does" and "what the agent sees". **Tradeoff.** The handler has to be general enough to serve both a human at a terminal and an agent over MCP — but that generality is cheaper than maintaining two parallel implementations. ## A warm daemon **Decision.** Offer a long-lived daemon (`graphd`) alongside the one-shot CLI. **Why.** Rebuilding the graph on every query is wasteful for interactive use. Keeping it warm and folding edits in incrementally turns repeated queries from "rescan each time" into "answer from memory". **Tradeoff.** A daemon is a process to manage — start, watch, idle-timeout, shut down. The one-shot `cgraph` stays available for CI and scripts where a resident process isn't wanted. ## Adaptive gather **Decision.** Default agent context to adaptive gather rather than a fixed k-hop. **Why.** Expanding every third hop is expensive; expanding none loses relevant context. Adaptive gather keeps the full 2-hop core and expands the third hop only along query-relevant nodes — most of the recall for a fraction of the tokens (see [Benchmarks](/docs/cgraph/benchmarks)). **Tradeoff.** Adaptive gather needs a query to gate on; without one the relevance gate is a no-op and it falls back to fixed behavior. ## Host-driven semantic enrichment **Decision.** Semantic enrichment is host-driven: the host writes fragments; CGraph validates them and manages cache state. **Why.** It keeps the deterministic core separate from open-ended semantic work. CGraph owns extraction, validation, and local mutation; the semantic model is supplied rather than guessed, and content-hash cache records keep it from being recomputed needlessly. **Tradeoff.** Enrichment isn't automatic — it's a workflow the host drives. The base graph is useful on its own; enrichment is an opt-in layer. ## Native C++ **Decision.** Build the engine in native C++20. **Why.** Extraction and query latency are the product. A native engine keeps both low and makes the deterministic, incremental design practical at speed. **Tradeoff.** A C++ build with CMake and vcpkg is heavier to set up than a scripting runtime (see [Installation](/docs/cgraph/installation)) — the cost paid once for speed paid back on every query. --- # Contributor Guide > How to build, test, and contribute to CGraph. [Source](https://open.nxtsoft.io/docs/cgraph/contributing) CGraph is open source and built from source. This guide covers the build, the tests, and what a good contribution looks like. ## Build from source CGraph uses CMake and vcpkg. The full prerequisites and commands are on the [Installation](/docs/cgraph/installation) page; the short version: **build and test** ```bash export VCPKG_ROOT="/path/to/your/vcpkg" cmake --preset default cmake --build --preset default ctest --preset default ``` ## Tests The repository carries two test layers: ```text tests/smoke/ CTest smoke coverage (run by ctest --preset default) tests/fuzz/ optional libFuzzer targets ``` Run the smoke suite with `ctest --preset default` before opening a PR; it's the fast gate that a change hasn't broken the core paths. ## What a good contribution looks like **Pick an issue** — 01 Browse open issues; good-first-issue labels mark friendly entry points. **Fork and build** — 02 Clone, configure with CMake + vcpkg, and run the smoke suite to verify your setup. **Open a PR** — 03 Keep extraction deterministic, add smoke coverage for new behavior, and the review will move quickly. The most important invariant to preserve is **determinism**: the same tree must produce the same graph. A change that makes extraction non-deterministic breaks incremental updates and background persistence — add smoke coverage that would catch it. ## Where the code lives See [Architecture](/docs/cgraph/architecture) for the repository layout — `src/cli`, `src/daemon`, `src/client`, `src/mcp`, and the `src/engine` core. --- # Roadmap > Where CGraph is heading — direction, not dated promises. [Source](https://open.nxtsoft.io/docs/cgraph/roadmap) CGraph does not publish a formal, versioned roadmap. This page describes the *direction* visible in the project rather than committed milestones or dates. Anything not yet shipped is labeled as such — it is a direction, not a promise. ## Direction The shape of the project points at a few themes, each already visible in what exists today: - **Deeper semantic enrichment.** Enrichment is host-driven today — CGraph validates fragments and manages cache state. The natural direction is richer enrichment workflows on top of that contract. - **Smarter retrieval.** Adaptive gather (2-hop core + query-relevant third hop, knapsack packing) is a recent, measurable step. Retrieval that spends an agent's tokens ever more precisely is a continuing thread. - **Broader language coverage.** Extraction spans eleven tree-sitter languages plus structured extractors; more languages extend the same model. ## How to follow along The authoritative signal is the repository itself — its issues and commit history. This page will list concrete milestones only once they are tracked as such upstream; until then, treat the above as direction. ## Where to go next - [Design Decisions](/docs/cgraph/design-decisions) — the principles the roadmap builds on. - [Changelog](/docs/cgraph/changelog) — released changes, once versions are cut. --- # FAQ > Common questions about what CGraph is, and isn't. [Source](https://open.nxtsoft.io/docs/cgraph/faq) ## Is CGraph a replacement for grep or ripgrep? No. Full-text search answers "where does this string appear"; CGraph answers "how do these things relate" — what calls a function, what a change touches, the path between two symbols. They're complementary. See [Core Concepts](/docs/cgraph/core-concepts) for the comparison. ## Is it a language server? No. An LSP serves an editor with per-file language intelligence. CGraph builds a persistent, language-agnostic graph of the whole project for querying and for feeding agents budgeted context. Some capabilities overlap; the purpose differs. ## Which languages does it support? Tree-sitter extraction for C, C++, Java, JavaScript, TypeScript, TSX, Kotlin, Scala, Groovy, Python, and Ruby; regex/structured extraction for Apex, Delphi, MSBuild/XML, and MCP config files. ## Do I need to run the daemon? Not for a one-shot graph — `cgraph --root . --out cgraph-out` builds and exits. Run `graphd` when you want the graph kept warm and updated incrementally across many queries or an agent session. ## How does an agent use it? Through MCP. Register `cgraph-mcp` with your agent (see [AI Agent Integration](/docs/cgraph/ai-agents)) and it gains eight graph tools — query, explain, impact, path, context, update, status, shutdown. ## Is the graph deterministic? Yes. The same source tree produces the same graph. That's what makes incremental updates and background persistence correct — see [Design Decisions](/docs/cgraph/design-decisions). ## Does it modify my code? No. CGraph reads the source tree and writes its graph and exports to the output directory (`cgraph-out/`). It does not change your source. ## Where are the graph and exports written? To the `--out` directory (conventionally `cgraph-out/`), as `graph.json` plus HTML, SVG, Obsidian, Cypher, and call-flow exports. --- # Changelog > Released versions of CGraph — as they are cut. [Source](https://open.nxtsoft.io/docs/cgraph/changelog) CGraph does not yet publish tagged releases or a versioned changelog. Until versions are cut, this page has no entries to list — and inventing them would be worse than an honest gap. ## Following changes today Until there are releases, the authoritative record of what changed is the project's git history: **see recent changes** ```bash git -C CGraph log --oneline -20 ``` ## When releases arrive Once CGraph tags releases, this page will list them newest-first — each version with its notable changes — sourced from the real release notes, not reconstructed after the fact. ## Where to go next - [Roadmap](/docs/cgraph/roadmap) — the direction ahead. - [Overview](/docs/cgraph/overview) — where the docs begin.