This is the full developer documentation for CodeXX MCP Server
# CodeXX MCP Server
> C++ code intelligence your agent can query — not a pile of files it has to read.
The **CodeXX MCP Server** connects your AI coding agent to the [CodeXX](https://landing.codexx-dtdk.com) C++ engine over the [Model Context Protocol](https://modelcontextprotocol.io). Instead of pasting files into the model and hoping it infers structure, the agent *asks*: find this symbol, who calls it, what does it reference, what does this type look like in memory, show me exactly these lines.
It speaks the same protocol your agent already knows. You point it at a C++ project, connect it to your client, and the model gains a precise, queryable view of the code.
## What it gives your agent
[Section titled “What it gives your agent”](#what-it-gives-your-agent)
Find symbols, not strings
Resolve a name to the real declaration — function, class, struct, namespace, enum — with its kind, signature, and file:line. Or enumerate every symbol of a kind, or in a file, to map an unfamiliar codebase.
Follow the real relationships
Who calls this function? What does it reference, and from where? The server answers from the engine’s analysis of your actual source, so the agent reasons about the code that exists — not a plausible guess.
Navigate code structure
Walk a function’s control flow, a class inheritance tree, or a file’s include graph — as a compact, paged structure the model can traverse without loading whole files into its context.
Read exactly the right lines
Pull the precise source span for a symbol, with original on-disk coordinates and paging for large bodies — no guessing at offsets, no dumping an entire file to see one function.
See type layout in memory
For builds with debug info, get a type’s byte-by-byte layout — fields, base classes, the vtable pointer, and padding as a named region — so the agent can reason about size, alignment, and waste directly.
Leave notes that stick
The agent can attach short labels and longer descriptions to symbols. They persist across restarts and show up inline on later lookups, so knowledge built up in one session is there for the next.
Warm, incremental, local
The project is indexed once and kept warm; edits are picked up incrementally. Your source is read locally by the engine and is not sent anywhere by the server.
One call to learn the surface
A single `discover` call tells a cold agent the full tool set, where to start, and the recommended workflow — so it can use the server effectively without being pre-taught.
***
## How it fits together
[Section titled “How it fits together”](#how-it-fits-together)
```
flowchart LR
A[AI agent / MCP client] -- MCP --> B[CodeXX MCP Server]
B --> C[CodeXX C++ engine]
C --> D[Your C++ project]
```
Your agent talks to the server over MCP. The server is backed by the CodeXX engine, which has already parsed and analysed your project. The agent gets structured answers — symbols, references, structure, layout — instead of raw text it has to interpret.
The CodeXX MCP Server is in **preview**. See [Installation](/getting-started/installation/) to connect it to your agent, or jump to the [Quick Start](/getting-started/quick-start/).
# For AI Agents
> How an autonomous agent should approach the CodeXX MCP Server — start with discover, and read these docs as llms.txt.
This page is written for the agent as much as the human. The CodeXX MCP Server exists to make a C++ codebase legible to a model, so its own docs are published in a machine-friendly form too.
## Read these docs as `llms.txt`
[Section titled “Read these docs as llms.txt”](#read-these-docs-as-llmstxt)
The entire documentation set is available as a single plain-text bundle, ready to drop into a model’s context:
* **`/llms.txt`** — an indexed summary of the docs.
* **`/llms-full.txt`** — the complete reference in one file.
Point an agent at [`/llms-full.txt`](/llms-full.txt) to teach it the whole product surface in one fetch — no crawling, no HTML.
## Start every session with `discover`
[Section titled “Start every session with discover”](#start-every-session-with-discover)
The server is self-describing. A cold agent’s first call should be **`discover`**, which returns:
* the full tool catalog — every tool’s name, access level, and purpose,
* the recommended **entry point** (`find_symbols`), and
* a suggested **workflow** for using the tools together.
An agent that calls `discover` first can use the server effectively without being pre-taught — the catalog it gets back is always exact for the running version. Pair it with **`health`** to confirm the server is live. See [Discovery & Facts](/tools/discovery/).
## The recommended loop
[Section titled “The recommended loop”](#the-recommended-loop)
The toolset rewards a broad-to-narrow approach, which keeps a model’s context small and its answers grounded in tool results rather than guesses:
1. **Orient** — `discover` (once), then `find_symbols` to locate a symbol or enumerate a kind/file.
2. **Get oriented** — `symbol_dossier` for a one-call overview before pulling detail.
3. **Drill in** — `references`, `read_symbol_source`, `navigate_graph`, or `memory_layout`, as the question demands.
4. **Record** — `relabel_symbol` / `describe_symbol` to leave durable notes that resurface next session.
The [Typical Agent Session](/guides/agent-session/) guide walks this loop end to end with concrete calls.
Design notes that matter to agents
* **Identifiers are strings.** Symbol IDs are decimal strings — thread them through verbatim; never coerce them to numbers. See [Symbols & Identity](/concepts/symbols-and-identity/).
* **Prefer qualified names.** An unqualified name may resolve ambiguously; the server returns candidates rather than guessing.
* **Results are paged and bounded.** Navigation and large source reads come back with a “there’s more” signal — check it before concluding you’ve seen everything. See [Navigating Code](/tools/navigating-code/).
* **Some results are point-in-time.** Navigation handles expire and are invalidated by re-index; memory layout reflects a specific build. Re-query rather than relying on stale results.
# Overview
> What the CodeXX MCP Server is, who it's for, and how the agent, the server, and the CodeXX engine fit together.
The CodeXX MCP Server is a bridge. On one side is your AI agent; on the other is the CodeXX C++ engine, which has parsed and analysed your project. The server lets the agent ask precise questions about the code and get structured answers back.
## The problem it solves
[Section titled “The problem it solves”](#the-problem-it-solves)
Coding agents are good at reasoning but blind to a codebase they can’t see. The usual workaround is to paste files into the context window — which is slow, lossy, and runs out of room on anything large. The model ends up guessing at relationships (“does anything call this?”) that the code already answers definitively.
The CodeXX MCP Server replaces guessing with querying. The engine already knows your symbols, their relationships, and their structure. The server exposes that knowledge as MCP tools, so the agent retrieves facts instead of inferring them from text.
## How the pieces fit
[Section titled “How the pieces fit”](#how-the-pieces-fit)
```
flowchart LR
A[AI agent] -- "MCP (stdio)" --> B[CodeXX MCP Server]
B --> C[CodeXX C++ engine]
C --> D[(Project index)]
D --> E[Your C++ source]
```
* **Your agent** speaks the Model Context Protocol and calls the server’s tools.
* **The server** translates those calls into queries against the engine and shapes the results for a language model — compact, paged, and ready to reason over.
* **The CodeXX engine** is the same C++ analysis engine that powers the rest of the platform. It parses your source, resolves symbols and references, and keeps the index warm.
* **Your project** is read locally by the engine. The server doesn’t ship your source anywhere.
## What the tools cover
[Section titled “What the tools cover”](#what-the-tools-cover)
The toolset is organised around how an agent actually explores code:
* **Discovery & facts** — find symbols, get their details, see references and comments. [Read more](/tools/discovery/)
* **Reading source** — pull the exact lines for a symbol. [Read more](/tools/reading-source/)
* **Navigating code** — walk control flow, inheritance, and include structure. [Read more](/tools/navigating-code/)
* **Memory layout** — byte-level type layout from debug info. [Read more](/tools/memory-layout/)
* **Annotations** — durable labels and notes on symbols. [Read more](/tools/annotations/)
* **Discovery & health** — learn the surface and check liveness. [Read more](/tools/discovery/)
The full list is in the [Tool Catalog](/reference/tool-catalog/).
## What it is — and isn’t
[Section titled “What it is — and isn’t”](#what-it-is--and-isnt)
* It is a **read-and-annotate** interface to a C++ codebase. The agent learns about your code and can leave durable notes on it.
* It does **not** modify your source. The only state it writes is the annotations you ask it to record and an internal index/cache that speeds up later sessions.
* It is **C++-focused** — it surfaces what the CodeXX engine analyses.
Preview
The CodeXX MCP Server is in preview. The capabilities documented here are grounded in the shipping tool set; deployment surface (public distribution, hosted/multi-user modes) is still being rolled out. See [Access & Auth](/trust/auth-posture/).
# Symbols & Identity
> How the server identifies symbols, the id-or-name rule, and why qualified names resolve cleanly.
Almost every tool operates on a **symbol** — a function, class, struct, namespace, enum, and so on. Knowing how symbols are identified makes the difference between a clean answer and an “ambiguous” one.
## Two ways to name a symbol
[Section titled “Two ways to name a symbol”](#two-ways-to-name-a-symbol)
Every symbol-bearing tool accepts either:
* a **symbol ID** — a stable identifier the server assigns to each symbol, or
* a **name** — what you’d write in the source.
You rarely type an ID yourself. The agent gets IDs back from `find_symbols` and threads them into follow-up calls, which is unambiguous and fast. Names are what you use when asking the first question.
A note on IDs
Symbol IDs are passed around as strings, not numbers, so they’re never rounded or truncated in transit. If you see a long numeric string standing in for a symbol, that’s an ID — the agent will have obtained it from a prior lookup.
## Resolving a name
[Section titled “Resolving a name”](#resolving-a-name)
When you give a name, the server looks it up:
* **Unique match** → it’s used directly.
* **Ambiguous** → the server returns the candidates instead of guessing, so the agent can pick the right one.
* **No match** → the server says so, rather than inventing a result.
## Prefer qualified names
[Section titled “Prefer qualified names”](#prefer-qualified-names)
An unqualified name like `push_back` can match many symbols. A **fully qualified name** like `std::vector::push_back` — or `codex::Workspace::open` in your own code — resolves cleanly the first time.
When a lookup comes back ambiguous, the usual fix is to qualify the name. The agent can also narrow with `find_symbols` filters (by kind, or by file) before drilling in. See [Discovery & Facts](/tools/discovery/).
## Enumerating instead of naming
[Section titled “Enumerating instead of naming”](#enumerating-instead-of-naming)
You don’t always start from a name. `find_symbols` can enumerate by **kind** (every `Class`, `Function`, `Struct`, `Namespace`…) and/or by **file** (a path substring), which is how an agent maps an unfamiliar codebase before it knows what to ask for.
# Workspace & Indexing
> How the server indexes your project, what to point it at, and why cold starts are slower than warm ones.
The server answers questions against an **index** of your project that the CodeXX engine builds from your source. Understanding when that index is built — and what it covers — explains the server’s startup behaviour and a few practical tips.
## What gets indexed
[Section titled “What gets indexed”](#what-gets-indexed)
When the server starts, the engine crawls the tree under `CODEXX_MCP_ROOT`, parses the C++ translation units it finds, and resolves them into a symbol database — names, kinds, signatures, comments, references, and relationships. Every query the agent makes is answered from this index.
## Cold start vs. warm start
[Section titled “Cold start vs. warm start”](#cold-start-vs-warm-start)
* **Cold start** — the first time you index a project, the engine parses everything from scratch. On a sizeable codebase this takes **tens of seconds**. The agent should expect the first call after startup to be slower.
* **Warm start** — the engine persists its parse cache inside your project. On the next start it reuses that cache and is ready in a few seconds.
* **Live updates** — once running, the engine notices files you create, modify, or delete and re-parses just the affected files before answering the next query. You don’t restart the server to pick up edits.
Mount read-write to stay warm
The parse cache only helps if the engine can write it. If your project is mounted read-only, every session pays the full cold index. Mount it read-write (the default in the [installation](/getting-started/installation/) commands).
## Point it at a library, not the world
[Section titled “Point it at a library, not the world”](#point-it-at-a-library-not-the-world)
Index time and result focus both scale with how much you point the server at. **Scope `CODEXX_MCP_ROOT` to the library or subtree you’re working in**, not a giant monorepo root:
* The first index stays fast.
* Results stay relevant to the code you care about.
* You avoid stressing the engine on very large trees, which is still being hardened for whole-repository indexing in the preview.
If you need to work across several independent components, run a server instance per component (each with its own `CODEXX_MCP_ROOT`).
## What state lives where
[Section titled “What state lives where”](#what-state-lives-where)
* **The project index / parse cache** is rebuildable. Deleting it just forces a cold start.
* **Your annotations** (labels and descriptions the agent records) are kept separately and durably, so they survive restarts and re-indexing. See [Annotations](/tools/annotations/).
* **Navigation results** are cached briefly while the agent pages through them, then expire. See [Navigating Code](/tools/navigating-code/).
Treat layout and navigation as point-in-time
Memory layout reflects a specific build’s debug info, and navigation results reflect the index at the moment they were produced. After a rebuild or re-index, the agent should re-query rather than rely on earlier results. See [Memory Layout](/tools/memory-layout/) and [Navigating Code](/tools/navigating-code/).
# Installation
> Connect the CodeXX MCP Server to your AI agent. It ships as a container image you run as a local MCP server over stdio.
The CodeXX MCP Server ships as a **container image**. You don’t install a binary — you run the image as a local MCP server and register it with your agent. The image carries the CodeXX engine, so there is nothing to compile on your machine.
The CodeXX MCP Server is in **preview**. The image is distributed through our early-access program — if you don’t yet have access, request it from [](mailto:support@codexx-dtdk.com?subject=CodeXX%20MCP%20Server%20early%20access).
## Prerequisites
[Section titled “Prerequisites”](#prerequisites)
* A container runtime (Docker or compatible) on your machine.
* An MCP-capable agent — Claude Code, Claude Desktop, or any client that can launch a stdio MCP server.
* A C++ project on disk that you want the agent to understand.
## Pull the image
[Section titled “Pull the image”](#pull-the-image)
```sh
docker pull ghcr.io/codexx-dtdk/codexx-mcp-server:stable-0.1.0
```
## Connect it to your agent
[Section titled “Connect it to your agent”](#connect-it-to-your-agent)
The server speaks the Model Context Protocol over **stdio**: your client launches it as a subprocess and talks to it on standard in/out. You mount your project into the container and tell the server where it lives with `CODEXX_MCP_ROOT`.
The quickest path, with Claude Code, from the root of the project you want to analyse:
```sh
claude mcp add codexx -- docker run -i --rm \
-v "$PWD:/workspace" \
-e CODEXX_MCP_ROOT=/workspace \
ghcr.io/codexx-dtdk/codexx-mcp-server:stable-0.1.0
```
This registers a server named `codexx`; its tools appear in your session under the `codex_v1_` prefix (for example `codex_v1_find_symbols`).
Using Gemini CLI or OpenAI Codex?
Every major CLI agent wires up the same `docker run` command — only the registration format differs. See [Configuration → Per-agent setup](/reference/configuration/#per-agent-setup) for the full matrix (Claude Code, Gemini CLI, OpenAI Codex) with config-file snippets and verification commands.
Mount your project read-write
The engine keeps a parse cache inside your project so the **next** session starts warm instead of re-indexing from scratch. Mount the project read-write (as above). A read-only mount works, but you pay the full cold index every time you start the server. See [Workspace & Indexing](/concepts/workspace-and-indexing/).
## Verify the connection
[Section titled “Verify the connection”](#verify-the-connection)
Once registered, ask your agent to call the server’s `health` tool, or have it run `discover`. `health` confirms the server is live and reports the backend; `discover` returns the full catalog of tools and the recommended way to use them. If both respond, you’re connected — head to the [Quick Start](/getting-started/quick-start/).
Point it at the right root
For best results, point `CODEXX_MCP_ROOT` at a single library or subtree rather than a huge repository root. The engine indexes the whole tree under that path on startup; scoping it keeps the first index fast and the results focused. See [Workspace & Indexing](/concepts/workspace-and-indexing/).
# Quick Start
> From a connected server to your agent answering real questions about your C++ code in a few minutes.
This walks through a first session once the server is [connected to your agent](/getting-started/installation/). You don’t call these tools by hand — you ask your agent questions, and it picks the right tools. The flow below is what a good session looks like under the hood.
## 1. Let the agent learn the surface
[Section titled “1. Let the agent learn the surface”](#1-let-the-agent-learn-the-surface)
A cold agent starts with one call:
* **`discover`** returns the full tool catalog, the recommended entry point, and a suggested workflow.
* **`health`** confirms the server is live and reports which backend is answering.
You can simply ask: *“What can the codexx server do?”* — the agent will run `discover` and summarise.
## 2. Find something
[Section titled “2. Find something”](#2-find-something)
Symbol lookups start at **`find_symbols`**. Ask in plain language:
> *“Find the `Workspace` class in this project.”*
The agent resolves the name to a real declaration with its kind, file, and line. If a name is ambiguous, the server reports the candidates so the agent can disambiguate — usually by using the fully qualified name (`codex::Workspace`). See [Symbols & Identity](/concepts/symbols-and-identity/).
You can also map an unfamiliar codebase:
> *“List every class defined under `src/analysis`.”*
## 3. Get the full picture of a symbol
[Section titled “3. Get the full picture of a symbol”](#3-get-the-full-picture-of-a-symbol)
Once a symbol is in hand, **`symbol_dossier`** gives a one-call overview: its facts, a compact memory-layout digest, a summary of where it’s referenced, and flags for whether it has comments or notes attached. It’s the fastest way for the agent to decide where to drill in.
> *“Give me an overview of `Scheduler::enqueue`.”*
## 4. Drill into details
[Section titled “4. Drill into details”](#4-drill-into-details)
From there the agent reaches for the right detail tool:
* **`references`** — every place a symbol is used, and which function each use sits inside.
* **`read_symbol_source`** — the exact source span, so the model reads only the lines that matter.
* **`navigate_graph`** — walk the control flow of a function, a class hierarchy, or an include graph. See [Navigating Code](/tools/navigating-code/).
* **`memory_layout`** — the byte-by-byte layout of a type (debug-info builds). See [Memory Layout](/tools/memory-layout/).
> *“Who calls `enqueue`, and show me its body.”*
## 5. Leave notes for next time
[Section titled “5. Leave notes for next time”](#5-leave-notes-for-next-time)
When the agent works something out, it can record it:
> *“Label `enqueue` as ‘debounced work submission’ and note why the lock is held.”*
Those notes persist and resurface on later lookups — see [Annotations](/tools/annotations/).
The shape of a good session
Start broad (`discover` → `find_symbols`), get oriented (`symbol_dossier`), then drill into just the detail you need (`references`, `read_symbol_source`, `navigate_graph`, `memory_layout`). The [Typical Agent Session](/guides/agent-session/) guide walks an end-to-end example.
# A Typical Agent Session
> An end-to-end walkthrough of how an agent uses the server to answer a real question about a C++ codebase.
This guide follows a single, realistic question end to end, showing which tools the agent reaches for and why. You ask in plain language; the agent orchestrates the tools.
> **You:** *“How does `Scheduler::enqueue` work, who calls it, and is the `Scheduler` type laid out efficiently?“*
## 1. Orient (once per session)
[Section titled “1. Orient (once per session)”](#1-orient-once-per-session)
If it hasn’t already, the agent calls **`discover`** to learn the toolset and the recommended workflow, and optionally **`health`** to confirm the server is live. After this it knows where to start.
## 2. Locate the symbol
[Section titled “2. Locate the symbol”](#2-locate-the-symbol)
The agent calls **`find_symbols`** with `Scheduler::enqueue`. The [qualified name](/concepts/symbols-and-identity/) resolves cleanly to one declaration, and the agent now holds its symbol ID for the follow-up calls.
## 3. Get oriented on the symbol
[Section titled “3. Get oriented on the symbol”](#3-get-oriented-on-the-symbol)
A single **`symbol_dossier`** call returns the facts (signature, file:line), a summary of where `enqueue` is referenced, a layout digest when the symbol is a type, and flags showing it has a doc comment. The agent now knows roughly how heavily it’s used and that documentation exists — enough to plan its drill-down.
What “structured” actually means
These are ordinary tool calls returning JSON the agent reasons over — not prose it has to parse. Illustrative, trimmed:
```json
// find_symbols ⟵ { "name": "codex::Scheduler::enqueue" }
{
"matches": [
{
"symbol_id": "8419302145567788",
"qualified_name": "codex::Scheduler::enqueue",
"kind": "Function",
"file": "libs/codex_workspace/src/scheduler.cpp",
"start_line": 142
}
]
}
```
```json
// symbol_dossier ⟵ { "id": "8419302145567788" }
{
"facts": { "kind": "Function", "signature": "void enqueue(Task)", "file": "…/scheduler.cpp", "start_line": 142 },
"references": { "total": 12, "top_files": [{ "file": "…/scheduler.cpp", "count": 7 }] },
"has_comment": true,
"has_annotation": false
// a layout digest also appears here when the symbol is a record type
}
```
Symbol IDs are strings; the agent threads the one it got from `find_symbols` straight into the next call.
## 4. Read the why, then the how
[Section titled “4. Read the why, then the how”](#4-read-the-why-then-the-how)
* **`get_comment`** pulls the doc comment so the agent leads with the author’s stated intent.
* **`read_symbol_source`** fetches `enqueue`’s exact body — just those lines, not the whole file.
## 5. Answer “who calls it?”
[Section titled “5. Answer “who calls it?””](#5-answer-who-calls-it)
**`references`** lists every use site, each tagged with the function it sits inside. The agent now names the actual callers instead of guessing, and can spot whether `enqueue` is on a hot path.
## 6. Understand the control flow (optional)
[Section titled “6. Understand the control flow (optional)”](#6-understand-the-control-flow-optional)
If the body is branchy, the agent walks the function’s **control flow** with [`navigate_graph`](/tools/navigating-code/) to reason about which paths take the lock, hit early returns, or loop — without re-reading the source repeatedly.
## 7. Check the layout
[Section titled “7. Check the layout”](#7-check-the-layout)
**`memory_layout`** on `Scheduler` returns its byte-region map: fields, any vtable pointer, and padding as named regions. The agent can now say whether the type wastes space and whether reordering fields would help — concretely, not hand-wavily. (Requires a debug-info build; see [Memory Layout](/tools/memory-layout/).)
## 8. Leave a note
[Section titled “8. Leave a note”](#8-leave-a-note)
Having worked it out, the agent records what it learned with **`describe_symbol`** (and maybe a short **`relabel_symbol`**). Next session, that note resurfaces inline the moment anyone looks up `enqueue` again. See [Annotations](/tools/annotations/).
The pattern
**Orient → locate → get oriented → drill into just what’s needed → leave a note.** Broad-to-narrow keeps the model’s context tight and every claim grounded in a tool result rather than a guess.
# Configuration
> Environment variables and profiles that control where the server indexes, where it stores state, and which tools it exposes.
The server is configured through environment variables passed when you launch the container. The two you’ll always set are the project root and (optionally) the deployment profile.
## Environment variables
[Section titled “Environment variables”](#environment-variables)
| Variable | Values | Default | Purpose |
| ----------------------- | ---------------------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `CODEXX_MCP_ROOT` | filesystem path | — | The project root to index. **Required** in normal use. Point it at a library or subtree, not a huge repo root. |
| `CODEXX_MCP_PROFILE` | `full` · `read_only` · `no_layout` | `full` | Which tools the server exposes (see below). |
| `CODEXX_MCP_DB` | path | a dedicated dir under the project | Where durable state — your [annotations](/tools/annotations/) — is stored. Kept separate from the rebuildable parse cache. |
| `CODEXX_MCP_TRANSPORT` | `stdio` · `http` | `stdio` | How clients connect. `stdio` is the default for local/desktop agents; `http` is for self-hosted setups. |
| `CODEXX_MCP_AUTH_TOKEN` | token | unset | If set, every call must present this bearer token. Off by default. See [Access & Auth](/trust/auth-posture/). |
Where state lives
The engine’s parse cache (rebuildable) and your annotations (durable) are stored separately, so clearing the cache to force a fresh index never touches your notes. See [Workspace & Indexing](/concepts/workspace-and-indexing/).
## Profiles
[Section titled “Profiles”](#profiles)
A **profile** scopes which tools the server exposes, so you can match it to a deployment:
* **`full`** *(default)* — every tool, including the annotation write tools and memory layout.
* **`read_only`** — discovery, facts, source reading, navigation, and layout, plus reading annotations — but **no annotation writes**. Use when you want a strictly read-only view of the code.
* **`no_layout`** — everything except [memory layout](/tools/memory-layout/). Use for projects built **without debug info**, where layout queries can’t return data anyway.
An unrecognised profile is rejected at startup rather than silently ignored.
## Transport
[Section titled “Transport”](#transport)
* **stdio** *(default)* — your client launches the server as a subprocess and talks over standard in/out. This is how the [installation](/getting-started/installation/) examples connect it.
* **http** — for running the server as a standalone, self-hosted endpoint. If you expose it beyond your own machine, turn on authentication — see [Access & Auth](/trust/auth-posture/).
## Per-agent setup
[Section titled “Per-agent setup”](#per-agent-setup)
Every major CLI coding agent launches the server the same way — `docker run` with your project mounted and `CODEXX_MCP_ROOT` pointing at the mount — and differs only in how the server is registered and verified. Pull the image first (see [Installation](/getting-started/installation/)), then follow the tab for your agent.
To set any variable from the table above, add another `-e` flag to the `docker run` command. For example, append `-e CODEXX_MCP_PROFILE=read_only` to expose a read-only profile.
Claude Code Gemini CLI OpenAI Codex
Register the server from the root of the project you want to analyse. Everything after `--` is the command Claude Code runs to launch it:
```sh
claude mcp add codexx -- docker run -i --rm \
-v "$PWD:/workspace" \
-e CODEXX_MCP_ROOT=/workspace \
ghcr.io/codexx-dtdk/codexx-mcp-server:stable-0.1.0
```
Verify the connection with `claude mcp list` — look for `codexx` with a `✓ Connected` status — or run `/mcp` inside a session. By default the server is registered to this project only; add `--scope user` to make it available in every project.
To pass a server variable, add another `-e` to the launch command:
```sh
claude mcp add codexx -- docker run -i --rm \
-v "$PWD:/workspace" \
-e CODEXX_MCP_ROOT=/workspace \
-e CODEXX_MCP_PROFILE=read_only \
ghcr.io/codexx-dtdk/codexx-mcp-server:stable-0.1.0
```
Add an entry under `mcpServers` in your Gemini settings — `~/.gemini/settings.json` for all projects, or `.gemini/settings.json` for one project. Use an **absolute** mount path:
```json
{
"mcpServers": {
"codexx": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "/absolute/path/to/your/project:/workspace",
"-e", "CODEXX_MCP_ROOT=/workspace",
"ghcr.io/codexx-dtdk/codexx-mcp-server:stable-0.1.0"
],
"timeout": 60000
}
}
}
```
The raised `timeout` (milliseconds) gives the first **cold index** room to finish before Gemini gives up — see [Workspace & Indexing](/concepts/workspace-and-indexing/). Or register it from the CLI:
```sh
gemini mcp add codexx docker run -i --rm \
-v "$PWD:/workspace" -e CODEXX_MCP_ROOT=/workspace \
ghcr.io/codexx-dtdk/codexx-mcp-server:stable-0.1.0
```
List servers with `gemini mcp list`, and check status and tools with `/mcp` inside a session.
Add a server block to `~/.codex/config.toml` (a project-scoped `.codex/config.toml` also works in a trusted project). Use an **absolute** mount path:
```toml
[mcp_servers.codexx]
command = "docker"
args = [
"run", "-i", "--rm",
"-v", "/absolute/path/to/your/project:/workspace",
"-e", "CODEXX_MCP_ROOT=/workspace",
"ghcr.io/codexx-dtdk/codexx-mcp-server:stable-0.1.0",
]
```
Or register it from the CLI:
```sh
codex mcp add codexx -- docker run -i --rm \
-v "$PWD:/workspace" -e CODEXX_MCP_ROOT=/workspace \
ghcr.io/codexx-dtdk/codexx-mcp-server:stable-0.1.0
```
See active servers with `/mcp` in the Codex TUI, or run `codex mcp --help` for all MCP commands.
Where the container vars go
`CODEXX_MCP_ROOT`, `CODEXX_MCP_PROFILE`, and the rest are read by the **server inside the container**, so they’re passed with `docker run -e …`, not through the agent’s own environment. Each agent only needs to know the command to launch — the `docker run …` line — and which directory to mount.
# Tool Catalog
> Every tool the CodeXX MCP Server exposes, at a glance, grouped by what it's for.
A flat reference of every tool. Tools appear in your client under the `codex_v1_` prefix (for example `codex_v1_find_symbols`); the names below omit it for brevity. The server’s own `discover` tool returns this same catalog at runtime, always current for the version you’re running.
## Server & discovery
[Section titled “Server & discovery”](#server--discovery)
| Tool | What it does |
| ---------- | ------------------------------------------------------------------------------------------------------------- |
| `discover` | Returns the full tool catalog, entry point, and recommended workflow — the one call a cold agent makes first. |
| `health` | Liveness/capability probe: confirms the server is up and reports the backend and storage status. |
## Discovery & facts
[Section titled “Discovery & facts”](#discovery--facts)
| Tool | What it does |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `find_symbols` | Resolve a name (or batch of names) to symbols, or enumerate symbols by kind and/or file. The entry point for symbol queries. |
| `get_symbol` | Display-grade facts for one symbol: kind, signature, file:line, and any label/description. |
| `symbol_dossier` | One-call overview: facts + layout digest + reference digest + comment/note flags. |
| `get_comment` | The verbatim doc/comment text attached to a symbol’s declaration. |
| `references` | Every declaration, definition, and use site of a symbol, each tagged with the function it sits inside. |
## Source
[Section titled “Source”](#source)
| Tool | What it does |
| -------------------- | -------------------------------------------------------------------------------------------------- |
| `read_symbol_source` | The exact source span for a symbol, with original on-disk coordinates and paging for large bodies. |
## Navigating code
[Section titled “Navigating code”](#navigating-code)
| Tool | What it does |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `navigate_graph` | Start walking a structure — control flow, class hierarchy, include graph, or module imports — and get a compact preview plus a summary. |
| `retrieve_graph` | Page through the full structure from a `navigate_graph` result. |
## Memory layout
[Section titled “Memory layout”](#memory-layout)
| Tool | What it does |
| --------------- | --------------------------------------------------------------------------------------------------------------- |
| `memory_layout` | A type’s byte-by-byte layout — fields, bases, vtable pointer, and padding as named regions (debug-info builds). |
## Annotations
[Section titled “Annotations”](#annotations)
| Tool | What it does |
| ------------------- | --------------------------------------------- |
| `relabel_symbol` | Set/replace a symbol’s short label. |
| `describe_symbol` | Set/replace a symbol’s free-form description. |
| `get_annotation` | Read back a symbol’s label and description. |
| `clear_label` | Remove the label, keep the description. |
| `clear_description` | Remove the description, keep the label. |
| `clear_annotation` | Remove both label and description. |
What's available depends on the profile
The annotation write tools and `memory_layout` are gated by the server’s profile — `read_only` hides the annotation writes, `no_layout` hides `memory_layout`. See [Configuration](/reference/configuration/).
## Stability & versioning
[Section titled “Stability & versioning”](#stability--versioning)
The tools are exposed under a **versioned contract**. That’s what the `codex_v1_` prefix means: this is version 1 of the tool surface. The prefix is stable, so an agent that learned the tools via `discover` keeps working as the server is updated within the same contract version.
The CodeXX MCP Server is in **preview**. Tool names and shapes can still change between versions while the surface settles, and a future contract revision would carry a new prefix rather than silently altering `codex_v1_`. For the catalog that exactly matches the version you’re running, have your agent call `discover` — it always reports the live surface. See [Access & Auth](/trust/auth-posture/) for the broader preview-stage caveats.
# Annotations
> Let the agent attach durable labels and descriptions to symbols — knowledge that survives restarts and resurfaces on later lookups.
Everything else the server does is read-only. Annotations are the exception: they let the agent **write knowledge back onto the code** — short labels and longer descriptions attached to symbols — so what it figures out in one session is there in the next.
## Two kinds of note
[Section titled “Two kinds of note”](#two-kinds-of-note)
* **Label** — a short, one-line alias or display name for a symbol (for example, `"debounced work submission"`). Labels come back **inline** on later `find_symbols`, `get_symbol`, and `symbol_dossier` results, so they surface right where the agent is already looking.
* **Description** — free-form prose: the *why* behind a symbol, gotchas, intent. Read it back explicitly when the agent wants the detail.
## The tools
[Section titled “The tools”](#the-tools)
* **`relabel_symbol`** — set (or replace) a symbol’s label.
* **`describe_symbol`** — set (or replace) a symbol’s description.
* **`get_annotation`** — read back both the label and description for a symbol, with the time they were last updated.
* **`clear_label`** — remove the label, keep the description.
* **`clear_description`** — remove the description, keep the label.
* **`clear_annotation`** — remove both in one call.
## Durable by design
[Section titled “Durable by design”](#durable-by-design)
Annotations are stored durably and **survive server restarts and re-indexing** — unlike the rebuildable project index or short-lived navigation handles. They’re tied to the symbol, so they reattach when the project is reloaded.
Building a knowledge layer
Over repeated sessions, annotations turn into a lightweight knowledge layer over your codebase: the agent labels the confusing parts, records the reasoning behind tricky code, and finds those notes waiting next time. Knowledge compounds instead of evaporating when the session ends.
Write access
The annotation tools write state. A server run in a read-only profile exposes the read paths (`get_annotation`, and labels shown inline) but not the write/clear tools — see [Configuration](/reference/configuration/).
# Discovery & Facts
> Learn the server's surface, then find symbols and pull their facts, comments, and references.
These are the tools an agent reaches for first: learn what the server can do, find a symbol, and get the facts about it. Everything else builds on a symbol the agent located here.
## Learn the surface
[Section titled “Learn the surface”](#learn-the-surface)
**`discover`** — one call that tells a cold agent everything it needs to use the server well: the full tool catalog (with each tool’s name, access, and purpose), the recommended entry point, and a suggested workflow. An agent that runs `discover` first can use the rest of the toolset without being pre-taught.
**`health`** — a liveness and capability probe. Confirms the server is up and reports which backend is answering and whether durable storage is available. Useful right after connecting, or to confirm the server is responsive.
## Find symbols
[Section titled “Find symbols”](#find-symbols)
**`find_symbols`** — the entry point for symbol queries. Three ways to use it:
* **By name** — resolve a name (ideally [qualified](/concepts/symbols-and-identity/)) to matching symbols, each with its ID, kind, file, and line.
* **In batch** — resolve several names in one call, with a per-name match count, to map a set of references at once.
* **By filter** — with no name, enumerate every symbol of a given **kind** (`Function`, `Class`, `Struct`, `Namespace`, …) and/or in a given **file** (path substring). This is how an agent surveys an unfamiliar codebase.
Any label the agent has attached to a symbol comes back inline here, so prior knowledge resurfaces during discovery.
## Get the facts on one symbol
[Section titled “Get the facts on one symbol”](#get-the-facts-on-one-symbol)
**`get_symbol`** — display-grade facts for a single symbol (by ID or name): its kind, signature, file:line span, and any label or description attached to it.
**`symbol_dossier`** — a lean, one-call overview that collapses several lookups into one response:
* the symbol’s facts,
* a compact memory-layout digest (size, alignment, padding — not the full byte map),
* a reference digest (total uses, and the files where it’s used most),
* and flags for whether it has a comment or notes attached.
It’s the fastest way for an agent to size up a symbol and decide which detail tool to call next.
## Comments and references
[Section titled “Comments and references”](#comments-and-references)
**`get_comment`** — the raw documentation/comment text attached to a symbol’s declaration, verbatim (comment markers included), with its file and line range. If the symbol has no comment, the server says so.
**`references`** — every place a symbol appears: its declarations and definitions, and every use site, sorted by file and line. Crucially, each use also reports **which function it sits inside** — that’s the “who uses this?” link an agent follows to understand impact and call relationships.
A natural order
`discover` → `find_symbols` → `symbol_dossier` → then `get_comment` / `references` (or a detail tool from another page). Start broad, get oriented, drill in.
# Memory Layout
> Give the agent a type's byte-by-byte layout — fields, bases, the vtable pointer, and padding as a named region.
C++ layout questions — *how big is this type? where’s the padding? does it have a vtable?* — usually mean squinting at a struct and doing arithmetic. The memory-layout tool answers them directly.
## What it returns
[Section titled “What it returns”](#what-it-returns)
**`memory_layout`** — for a given type (by ID or name), the type’s actual in-memory layout:
* its **size** and **alignment** in bytes,
* total **padding**,
* whether it has a **vtable pointer**, and
* an **ordered map of byte regions** that tiles the whole type from start to end — with no gaps and no overlaps.
Each region says what occupies it: a **field** (with its name and type), a **base class** subobject, the **vtable pointer**, or **padding**. Padding is a first-class, named region — not a number you have to infer — so the agent can see wasted space and where it sits, and reason about reordering or packing.
## Requires debug info
[Section titled “Requires debug info”](#requires-debug-info)
This view is built from the **debug information** in a compiled artifact — **DWARF** from a `-g` build on Linux/macOS, or a **PDB** on Windows. It follows that:
* a type with no debug info available returns a clear “no layout” response rather than a guess;
* layouts reflect a **specific build**. After you rebuild, the agent should re-query rather than rely on an earlier answer. Treat layout as point-in-time. See [Workspace & Indexing](/concepts/workspace-and-indexing/).
Quick layout vs. full map
For a fast size/alignment/padding readout without the full byte map, the agent can use the layout digest inside [`symbol_dossier`](/tools/discovery/). Reach for `memory_layout` when it needs the region-by-region breakdown.
Availability by build
If your project is built without debug info, layout queries won’t return data. The server can be run in a profile that omits this tool entirely for projects where layout isn’t available — see [Configuration](/reference/configuration/).
Windows (PDB): current limitations
On Windows the layout is read from the program’s **PDB** via the MSVC DIA SDK, with two caveats today:
* **64-bit only.** Only **x64 (LLP64)** builds are supported — **32-bit (x86)** and **ARM64** PDBs aren’t read yet, so layout queries against those builds return “no layout.” Expect Windows sizes to differ from Linux/macOS for the same source (for example, `long` is 4 bytes on Windows vs. 8 elsewhere).
* **The PDB must sit next to the binary.** The server locates it by convention as `.pdb` beside the compiled artifact. If your build redirects it with the linker’s `/PDB:` flag, or it’s renamed or combined into another file, the server can’t find it and layout is unavailable — keep the PDB beside the binary (the MSVC default).
# Navigating Code
> Let the agent walk control flow, inheritance, includes, and module imports as compact, paged structures — without reading whole files.
Some questions are about *structure*, not text: how does control flow through this function? what derives from this base class? which headers pull in which? Navigating code lets the agent walk these relationships directly, as a compact structure it can traverse — instead of reconstructing them by reading file after file.
## What you can navigate
[Section titled “What you can navigate”](#what-you-can-navigate)
The agent picks one of four structures to walk:
* **Control flow** — the flow of execution through a single function: its branches, loops, and the order blocks run in. The agent reasons about reachability and paths without reading the whole body line by line. (This one needs you to name the function to walk.)
* **Class hierarchy** — inheritance across the project: who derives from whom. Useful for understanding polymorphism and override chains.
* **Include graph** — which files include which, so the agent can see compile-time coupling and spot heavy or circular includes.
* **Module imports** — for C++20 modules, the import relationships between modules.
Each is a simplified, agent-legible view of a relationship the CodeXX engine already computes from your source — presented for what it *enables*, not as raw analysis output.
## How navigation works
[Section titled “How navigation works”](#how-navigation-works)
Navigation is a two-step pattern, designed so even a huge structure stays manageable for a language model.
**`navigate_graph`** starts a traversal. The agent chooses the structure to walk, a starting point, an optional depth limit, and a direction (follow relationships outward, inward, or both). It gets back:
* a **compact preview** — a small, representative sample of the structure,
* a **summary** — total counts of nodes and relationships, and the kinds present,
* and a flag saying whether the preview *is* the whole thing or just the start.
If the structure is small, the preview is all of it. If it’s large, the agent gets a handle to fetch the rest.
**`retrieve_graph`** pages through a large result using that handle — a page at a time, in a stable order — so the model pulls in only as much structure as it needs, when it needs it.
Why two steps
Whole-program structures (a deep class hierarchy, a big include tree) can be far larger than a model’s context. Returning a bounded summary plus paged detail keeps navigation usable at any size — the agent sees the shape first, then drills into the parts that matter.
## Things to know
[Section titled “Things to know”](#things-to-know)
* **Control flow needs a target.** To walk a function’s control flow, the agent names the function. The other structures don’t need one.
* **File vs. symbol structures.** The include and module-import graphs are about files and modules, so their nodes are paths and module names — not symbols. Control flow and class hierarchy are about symbols.
* **Results are point-in-time.** A navigation handle is cached briefly and then expires; it’s also invalidated when the project is re-indexed. If a handle goes stale, the agent simply starts the traversal again. Treat navigation results as a snapshot of the index when they were produced. See [Workspace & Indexing](/concepts/workspace-and-indexing/).
* **Check the “complete” flag.** When the preview is only a sample, the summary says so — the agent should page the rest before concluding it has seen everything.
# Reading Source
> Pull the exact source span for a symbol — with precise on-disk coordinates and paging for large bodies.
When the agent needs to actually read code, it doesn’t dump a whole file — it pulls exactly the lines that belong to a symbol.
## Read a symbol’s source
[Section titled “Read a symbol’s source”](#read-a-symbols-source)
**`read_symbol_source`** — returns the exact source text for a symbol (by ID or name), along with its location: file, start and end line, and byte offsets. The coordinates are **original on-disk coordinates** — the source as written, matching what you’d see opening the file — so anything the agent reports lines up with your editor.
## Built for large bodies
[Section titled “Built for large bodies”](#built-for-large-bodies)
A long function or class shouldn’t blow the model’s context. `read_symbol_source` supports **paging**: the agent can request a slice and get back a clear signal of how much remains, including the total size and whether the result was truncated. Partial reads are never silent — the agent always knows there’s more to fetch.
Read narrowly
Because the agent can locate a symbol precisely with [discovery tools](/tools/discovery/) first, reading source becomes surgical: fetch one function’s body, not the file it lives in. That keeps the model’s context focused and its answers grounded in the right lines.
## What it returns
[Section titled “What it returns”](#what-it-returns)
* the source text for the symbol’s span,
* the file path,
* start/end line and byte offsets (original on-disk coordinates),
* paging signals (how much was returned, how much remains) for large spans.
# Access & Auth
> The server's authentication stance during preview, and how to secure it if you self-host.
The CodeXX MCP Server is in **preview**, and its access model reflects that. This page is the honest summary of where things stand.
## Designed for local, single-project use
[Section titled “Designed for local, single-project use”](#designed-for-local-single-project-use)
The server is built to run on your machine, connected to one project, talking to your agent over a local stdio connection. In that setup the trust boundary is your own machine — the same as any local developer tool — so **authentication is off by default**.
## If you expose it over the network
[Section titled “If you expose it over the network”](#if-you-expose-it-over-the-network)
The server can run as a self-hosted HTTP endpoint instead of local stdio. If you do that, you are responsible for securing it:
* Set `CODEXX_MCP_AUTH_TOKEN` to require a bearer token on **every** call.
* Put it behind your own network controls (private network, reverse proxy, TLS) as appropriate.
Don’t expose an unauthenticated server beyond your own machine.
Preview-stage limitations
Multi-user and hosted deployment are still being rolled out. Today the server is best treated as a **single-user, single-project** tool. Run one instance per project, keep it local unless you’ve secured it, and expect the deployment surface to expand as the product leaves preview.
## State is built to scale later
[Section titled “State is built to scale later”](#state-is-built-to-scale-later)
Even though the preview is single-user, the durable state ([annotations](/tools/annotations/)) is keyed in a way that doesn’t depend on any one session — so the same notes resolve consistently across restarts, and the design leaves room for multi-instance deployments down the line. That’s groundwork, not a feature you should rely on yet.
## Questions?
[Section titled “Questions?”](#questions)
Access to the preview image and early-access onboarding go through [](mailto:support@codexx-dtdk.com?subject=CodeXX%20MCP%20Server%20access).
# Local-First
> Where your code goes when you use the server — and where it doesn't.
The CodeXX MCP Server is designed to run **next to your code**, not to ship it anywhere.
## Your source stays local
[Section titled “Your source stays local”](#your-source-stays-local)
You run the server as a container on your own machine and mount your project into it. The CodeXX engine reads your source **locally** to build its index and answer queries. The server itself does not upload, transmit, or phone home your source code.
## What the server writes
[Section titled “What the server writes”](#what-the-server-writes)
* **The project index / parse cache** — built from your source, kept inside your project so the next session starts warm. Rebuildable; deleting it just forces a cold index.
* **Your annotations** — the labels and descriptions the agent records, stored durably so they survive restarts. See [Annotations](/tools/annotations/).
Both live on your machine. The server does not modify your source files — it only reads them.
## What your agent sees
[Section titled “What your agent sees”](#what-your-agent-sees)
Your AI client, of course, receives the tool results it asks for — symbol facts, source spans you request, layout, and so on — because that’s the point of connecting it. What leaves your machine is governed by **your agent and its model provider**, not by this server. If you’re working under strict data-handling requirements, choose your MCP client and model accordingly.
Network posture
The server’s job is to answer the agent’s queries from a local index. It is not a telemetry or sync service. If you self-host it over HTTP for remote access, secure that endpoint — see [Access & Auth](/trust/auth-posture/).