> For the complete documentation index, see [llms.txt](https://docs.codna.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.codna.ai/guides/mcp.md).

# MCP Server

Run Codna as a Model Context Protocol server so Cursor, Claude Desktop, or your own agent can triage, fix, secure, recall code, and file reports.

`codna mcp` runs Codna as a [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server over stdio. It exposes five tools that any MCP client can call. Use it when you want Codna inside your editor or chat client (Cursor, Claude Desktop, or your own agent) instead of, or alongside, the `codna` command line.

```bash
codna mcp
```

Run bare, `codna mcp` (equivalent to `codna mcp start`) serves over standard input/output, the transport Cursor and Claude Desktop expect. It stays in the foreground waiting for a client and prints nothing on success; the client spawns it from the config below, so you rarely run it by hand. It also accepts `--repo <repo>` to set a default repo for the tools, and an `install` subcommand (below) that writes a client's config for you.

## Installation

The MCP server is an optional channel, installed with the `mcp` extra:

```bash
pip install "codna[mcp]"
```

This adds the `mcp` package on top of a normal `pip install codna`. It is kept out of the base install because `mcp` pulls a small web stack that CLI and CI use do not need. If you already have Codna, add the extra:

```bash
pip install --upgrade "codna[mcp]"
```

If you run `codna mcp` without the extra, Codna prints `MCP support isn't installed. Add it with: pip install 'codna[mcp]' then re-run codna mcp.` The base `codna` command, triage, fix, review and secure work without it.

## Configuration

The server and the CLI share the same local runtime and the same keys. Because the MCP client spawns `codna mcp` as a child process, set credentials in the `env` block of the client configuration, or store them in the OS keychain with `codna key set`; the server inherits nothing else from your shell.

| Variable                                                      | Purpose                                                                                                                                        | Default |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `GEMINI_API_KEY` / … | Provider key for `codna_fix`. Or store one with `codna key set`.                                                                               | —       |
| `GITHUB_TOKEN` / `CODNA_GITHUB_TOKEN`                         | Write token for `codna_fix` with `open_pr=true`, and for `codna_report_bug`.                                                                   | —       |
| `CODNA_MCP_DEFAULT_REPO`                                      | Default repo for tools when the caller passes `.` (same as `--repo`).                                                                          | `.`     |
| `CODNA_API_KEY`                                               | Your Codna key from the one-time free `codna login` (device authorization, free community license). Required to execute any of the five tools. | —       |

All five tools require the one-time free `codna login` — introspection (`initialize`/`tools/list`) stays credential-free, but every tool call checks the device authorization and otherwise returns a `login_required`-style error. Fully offline thereafter: `codna_triage`, `codna_secure`, and `codna_recall` then need no key at all; `codna_fix` additionally needs a provider key, and `codna_report_bug` needs a GitHub token to auto-file.

## Exposed tools

The server registers five tools. Each one returns a JSON **string** (pretty-printed, two-space indent) and is wrapped so a failure never crashes the server: errors come back as a plain string of the form `codna_<tool> error: <message>`, which the client surfaces as the tool result.

### `codna_triage`

Understands a repository and locates the code relevant to an issue. Read-only and deterministic. 0 model tokens.

| Parameter | Type   | Default | Description                                                                                                                 |
| --------- | ------ | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| `repo`    | string | `.`     | A local path or a git URL. A local directory is read directly; an `http(s)://` or `.git` URL is fetched.                    |
| `issue`   | string | `""`    | Optional description of what to look for. When empty, Codna uses `"Map this repository and locate its most relevant code."` |

Returns a JSON object with these fields (values shown for the shape):

```json
{
  "suspect_files": [
    "src/auth/session.py",
    "src/auth/tokens.py"
  ],
  "reduction_ratio": 312.0,
  "raw_repo_tokens": 1842030,
  "evidence_bundle_tokens": 5904
}
```

| Field                    | Meaning                                                                                  |
| ------------------------ | ---------------------------------------------------------------------------------------- |
| `suspect_files`          | The files Codna identified as most relevant to the issue.                                |
| `reduction_ratio`        | How much smaller the evidence bundle is than the raw repo (e.g. `312.0` = 312x smaller). |
| `raw_repo_tokens`        | Estimated token count of the whole repository.                                           |
| `evidence_bundle_tokens` | Token count of the reduced bundle handed to an agent.                                    |

### `codna_fix`

Finds and fixes a bug. Runs the full Codna agent and a deterministic risk simulation.

| Parameter | Type    | Default                          | Description                                                                                                                                                                              |
| --------- | ------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `repo`    | string  | (required)                       | A local path or a git URL.                                                                                                                                                               |
| `issue`   | string  | (required)                       | What is broken, e.g. the failing test or the observed behavior.                                                                                                                          |
| `ref`     | string  | `""`                             | Optional branch, tag, or commit to check out before analysis.                                                                                                                            |
| `open_pr` | boolean | `false`                          | When `false`, plan only. When `true`, open a pull request; requires a git URL for `repo`, a non-empty `issue`, and `GITHUB_TOKEN` or `CODNA_GITHUB_TOKEN` in the MCP server environment. |
| `model`   | string  | `repository.verified_agentic_v1` | Optional provider-qualified planner model, e.g. `openai/gpt-5`.                                                                                                                          |

Returns a JSON object (values shown for the shape):

```json
{
  "root_cause": "Session token expiry compared against a naive datetime, so tokens never expire under UTC.",
  "impacted_symbols": ["Session.is_expired", "TokenStore.purge"],
  "blast_radius": "low",
  "confidence": 0.91,
  "patch_ref": "…",
  "model": "repository.verified_agentic_v1",
  "cost_usd": 0.021
}
```

| Field              | Meaning                                           |
| ------------------ | ------------------------------------------------- |
| `root_cause`       | Why the bug occurs.                               |
| `impacted_symbols` | Functions and classes the fix touches.            |
| `blast_radius`     | Scope of the change.                              |
| `confidence`       | Planner confidence in the fix, `0.0`–`1.0`.       |
| `patch_ref`        | Reference to the generated patch.                 |
| `model`            | The runtime planner model that produced the plan. |
| `cost_usd`         | Planner cost for the run.                         |

{% hint style="info" %}
By default, `codna_fix` **plans** the fix and returns a `patch_ref`; it does not apply patches to a local checkout. Set `open_pr=true` only when the repo is a git URL and the MCP server environment contains a write-capable GitHub token. To apply a patch directly to a local checkout, use `codna fix --apply` from the command line (see [CLI Reference](/reference/cli.md)).
{% endhint %}

With `open_pr=true`, the tool returns the opened PR URL instead of a local patch reference:

```json
{
  "root_cause": "Checkout total subtracts discounts twice, so carts with coupons underflow.",
  "confidence": 0.78,
  "pull_request_url": "https://github.com/acme/shop/pull/482",
  "status": "opened_pull_request",
  "model": "repository.verified_agentic_v1"
}
```

### `codna_secure`

Proves which scanner findings are reachable. Ingests a SARIF report (CodeQL, Semgrep, Snyk, or Trivy), classifies each finding (`exploitable`, `production-reachable`, `unreachable`, or `unknown`), and reports which are autofix-eligible. Read-only. 0 model tokens.

| Parameter    | Type   | Default    | Description                                                                                                  |
| ------------ | ------ | ---------- | ------------------------------------------------------------------------------------------------------------ |
| `repo`       | string | `.`        | A local path or a git URL.                                                                                   |
| `sarif_path` | string | (required) | Path to the scanner's SARIF output. If empty, the tool returns `codna_secure error: sarif_path is required`. |
| `ref`        | string | `""`       | Optional branch, tag, or commit.                                                                             |

The SARIF report must carry complete provenance. If it does not, the tool returns `codna_secure error: SARIF provenance incomplete: …` listing the missing fields, and does nothing else. On success it returns:

```json
{
  "counts": {
    "production-reachable": 2,
    "unreachable": 5,
    "unknown": 1
  },
  "autofix_eligible": 2,
  "findings": [
    {
      "rule_id": "py/sql-injection",
      "kind": "sql-injection",
      "classification": "production-reachable",
      "eligible": true,
      "reason": "autofix-eligible"
    },
    {
      "rule_id": "py/clear-text-logging",
      "kind": "sensitive-data",
      "classification": "unreachable",
      "eligible": false,
      "reason": "no reachable path from an entry point"
    }
  ]
}
```

| Field              | Meaning                                                                         |
| ------------------ | ------------------------------------------------------------------------------- |
| `counts`           | A map of classification to count across all findings.                           |
| `autofix_eligible` | Total number of findings Codna deems autofix-eligible.                          |
| `findings[]`       | Per-finding `rule_id`, `kind`, `classification`, `eligible` flag, and `reason`. |

{% hint style="info" %}
The MCP `codna_secure` tool classifies and reports only. To remediate eligible findings or open security fix PRs, use `codna secure --fix` / `--open-pr` from the command line. See [Security Autofix](/guides/security-autofix.md).
{% endhint %}

### `codna_recall`

Recalls code from local on-device memory. Read-only and local; it does not call a model or change the repository. Like every tool on this page, it requires the one-time free `codna login` (device authorization, free community license); the same `codna login` installs the on-device memory runtime, and after that recall runs fully offline with no key.

| Parameter  | Type    | Default    | Description                                                                                           |
| ---------- | ------- | ---------- | ----------------------------------------------------------------------------------------------------- |
| `repo`     | string  | `.`        | Local repository path to index and search.                                                            |
| `query`    | string  | (required) | Natural-language or symbol query. If empty, the tool returns `codna_recall error: query is required`. |
| `service`  | string  | `""`       | Optional service/module filter.                                                                       |
| `language` | string  | `""`       | Optional language filter.                                                                             |
| `final_k`  | integer | `8`        | Maximum number of recalled results.                                                                   |

Returns a JSON object with ranked symbols (each with `id`, `score`, `symbol_type`, `path`), an `explain` payload, and the number of candidates searched:

```json
{
  "symbols": [
    {
      "id": "src/checkout/pricing.py::apply_discount",
      "path": "src/checkout/pricing.py",
      "symbol_type": "function",
      "score": 0.93
    }
  ],
  "explain": {
    "query": "checkout discount calculation",
    "final_k": 8
  },
  "candidate_count": 41
}
```

Recall indexes for the MCP server live outside your checkout, under `~/.codna/telys-memory/mcp/` (override with `CODNA_TELYS_MEMORY_ROOT`). See [Code Memory](/concepts/memory.md).

### `codna_report_bug`

Files a bug, feature request, or question to [thyn-ai/feedback](https://github.com/thyn-ai/feedback), the public front door for algenta, codna, telys, and sqai. This is a write: it creates a real GitHub issue, unlike every other tool on this page.

| Parameter             | Type    | Default    | Description                                                                                                 |
| --------------------- | ------- | ---------- | ----------------------------------------------------------------------------------------------------------- |
| `title`               | string  | (required) | A short summary. If empty, the tool returns `codna_report_bug error: title is required`.                    |
| `body`                | string  | `""`       | What happened, or what you want, in as much detail as you have.                                             |
| `product`             | string  | `codna`    | One of `algenta`, `codna`, `telys`, `sqai`, `accounts`, `docs`.                                             |
| `include_diagnostics` | boolean | `false`    | Attach the same redacted output `codna doctor` prints: presence and source of config, never a secret value. |

Filing needs a GitHub token the MCP server's environment can see (`GITHUB_TOKEN`, `GH_TOKEN`, or an already-authenticated `gh` CLI on `PATH`). Without one, or if the network call fails, the tool does not error out: it returns a pre-filled `github.com/.../issues/new` link instead, so nothing is lost.

```json
{
  "submitted": true,
  "url": "https://github.com/thyn-ai/feedback/issues/128",
  "local_path": null
}
```

When it falls back, `submitted` is `false`, `url` is the pre-filled link, and `local_path` points at a saved copy of the report on disk (under `CODNA_RUNTIME_ROOT`).

This is the same submission path the `codna report` CLI command uses (see [CLI Reference](/reference/cli.md#codna-report)), so an agent and a human land in the same place with the same fields.

## Install into a client

Instead of hand-editing the config, let Codna write the client entry for you:

```bash
codna mcp install --client cursor            # writes ~/.cursor/mcp.json
codna mcp install --client cursor --project  # writes ./.cursor/mcp.json (repo-scoped)
codna mcp install --client claude            # writes the Claude Desktop config
```

* `--client cursor|claude` (required) picks the client.
* `--project` writes the project-local Cursor config instead of the user config (Cursor only).
* `--repo <repo>` bakes a default repo into the server entry.

The command merges a `codna` server into `mcpServers` (preserving any existing servers), writes atomically, and prints a JSON summary with the resolved config `path`. It does **not** write credentials. Store your provider key with `codna key set`, or add it to the config's `env` block afterward. To configure a client by hand instead, use the blocks below.

## Editor setup

Both clients use the same `codna` server block; only the config file location differs. Pick your client below.

{% tabs %}
{% tab title="Cursor" icon="laptop-code" %}
Add a `codna` entry to your MCP servers configuration. Use `~/.cursor/mcp.json` for all projects, or `.cursor/mcp.json` inside a project for project-scoped access:

{% code title=".cursor/mcp.json" lineNumbers="true" %}

```json
{
  "mcpServers": {
    "codna": {
      "command": "codna",
      "args": ["mcp"],
      "env": {
        "ANTHROPIC_API_KEY": "$ANTHROPIC_API_KEY"
      }
    }
  }
}
```

{% endcode %}

After saving, reload Cursor's MCP servers (Settings → MCP, or restart). The `codna_triage`, `codna_fix`, `codna_secure`, `codna_recall`, and `codna_report_bug` tools then become available to the agent. Paste the key value in place of `$ANTHROPIC_API_KEY`, or leave the `env` block out when the key is in the OS keychain (`codna key set anthropic`).
{% endtab %}

{% tab title="Claude Desktop" icon="message" %}
Add the same block to your Claude Desktop configuration file, on macOS at `~/Library/Application Support/Claude/claude_desktop_config.json`:

{% code title="claude\_desktop\_config.json" lineNumbers="true" %}

```json
{
  "mcpServers": {
    "codna": {
      "command": "codna",
      "args": ["mcp"],
      "env": {
        "ANTHROPIC_API_KEY": "$ANTHROPIC_API_KEY"
      }
    }
  }
}
```

{% endcode %}

Restart Claude Desktop to load the server. The five Codna tools then appear in the tools (plug) menu in the message composer.
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
`"command": "codna"` requires the `codna` executable to be on the `PATH` of the process that launches the MCP client, which is often **not** your shell's `PATH` (GUI apps on macOS frequently ignore it). If the client cannot find it, set `command` to the absolute path of the binary, the output of `which codna`:

```json
{
  "mcpServers": {
    "codna": {
      "command": "/Users/you/.venvs/codna/bin/codna",
      "args": ["mcp"]
    }
  }
}
```

{% endhint %}

## Example prompts

Once a client is connected, you drive Codna in natural language; the client picks the tool and fills the parameters:

```
Use codna to triage this repo and tell me where the auth code lives.
```

```
codna_triage the github.com/acme/api repo for "checkout returns 500 on empty cart"
```

```
The test tests/test_session.py::test_expiry is failing — use codna to find and fix the bug.
```

```
Run codna_fix on this repository for the issue "JWT refresh tokens never expire" and show me the root cause and confidence.
```

```
I have a CodeQL report at ./results.sarif — use codna to tell me which findings are actually reachable.
```

```
Recall where discounts are applied in this repo.
```

```
File a bug: codna fix hangs on a monorepo. Include diagnostics.
```

## End-to-end: Cursor on a local repo

{% stepper %}
{% step %}

#### Install Codna with the MCP extra

```bash
pip install "codna[mcp]"
codna key set anthropic
```

{% endstep %}

{% step %}

#### Write the Cursor config

```bash
codna mcp install --client cursor --project
```

This writes `.cursor/mcp.json` in the repository with a `codna` server entry (`"command": "codna"`, `"args": ["mcp"]`). If Cursor cannot find `codna` on its `PATH`, set `command` to the output of `which codna`.
{% endstep %}

{% step %}

#### Reload MCP servers in Cursor

The `codna` server shows five tools.
{% endstep %}

{% step %}

#### Drive Codna from the agent panel

In the agent panel, type:

```
Use codna_triage on . and summarize the suspect files.
```

Codna returns the suspect files and the context-reduction ratio, and the agent summarizes them. From there, ask it to `codna_fix` a specific issue. Use `open_pr=true` for a git URL when you want Codna to open a PR, or take the returned `patch_ref` to the CLI to apply it locally.
{% endstep %}
{% endstepper %}

## Verifying the server

You can confirm the server starts by running it directly. It will block waiting for a client; that is success:

```bash
codna mcp
```

Nothing is printed and the process does not exit. Press Ctrl-C to stop. To confirm the client side, check your MCP client's logs for the `codna` server connecting and discovering five tools.

## Troubleshooting

<details>

<summary>Server not detected / tools missing in the client</summary>

The client could not spawn `codna mcp`. Most often `codna` is not on the launching process's `PATH`. Fix by pointing `command` at the absolute path from `which codna` (see the editor-setup warning above), or run `codna mcp install --client cursor|claude`, then reload the client. Verify the binary runs at all:

```bash
codna --version
```

```
codna 0.x.y
```

</details>

<details>

<summary><code>MCP support isn't installed</code> or <code>ModuleNotFoundError: No module named 'mcp'</code></summary>

The `mcp` extra is not installed in the interpreter the client launches. Install it into the **same** interpreter the MCP `command` path points at:

```bash
which codna
python -m pip install --upgrade "codna[mcp]"
```

A mismatched virtualenv is the usual cause of "I installed it but it still fails."

</details>

<details>

<summary><code>codna_fix</code> fails on the model call</summary>

The server did not see a provider key. Store one with `codna key set <provider>`, or add it to the `env` block of the server entry (GUI clients do not inherit your shell environment), then reload the client.

</details>

<details>

<summary><code>codna_secure</code> rejects the SARIF</summary>

Two specific errors come from this tool:

```
codna_secure error: sarif_path is required
```

Pass a `sarif_path`. And:

```
codna_secure error: SARIF provenance incomplete: <missing fields>
```

The report lacks the provenance Codna requires to bind findings to a commit. Re-run your scanner so its SARIF records the full commit and the driver name and version, then retry.

</details>

<details>

<summary><code>repo</code> is neither a directory nor a URL</summary>

If `repo` is not an existing local directory and not an `http(s)://` or `.git` URL, the tool errors with:

```
'<repo>': not a local directory or a git URL.
```

Pass an absolute or relative path to a real checkout, or a git URL.

</details>

## Next steps

* [CLI Reference](/reference/cli.md) — the `codna` command, including `codna fix --apply` / `--open-pr` to act on a plan.
* [Security Autofix](/guides/security-autofix.md) — `codna secure` reachability proofs and remediation PRs.
* [Code Memory](/concepts/memory.md) — how `codna_recall` builds and queries the index.
* [Configuration](/reference/configuration.md) — environment variables and the `codna.yaml` file.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.codna.ai/guides/mcp.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
