Model or dataset
bartolli/codanna avatar
bartolli/codanna

Codanna: a local code intelligence MCP server for AI coding agents

Local code intelligence MCP server and CLI for AI coding agents

745 stars70 forksRustApache-2.0

At a glance

What is it?
Codanna indexes a repository on disk and serves symbol search, call graphs and impact analysis to MCP clients such as Claude Code, Cursor and Codex. It is a Rust binary with an Apache-2.0 licence, and it is the one-shot CLI mode that makes it usable outside a persistent MCP session.
Who is it for?
Adopt Codanna if your agent spends turns grepping for symbols and you want call graph and impact data in the same response, and if a local index under .codanna/ is acceptable. Do not adopt it if you need a hosted index shared across a team, or if your language is outside the fifteen the README lists.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The grep-and-read loop Codanna is trying to replace

An agent asked to change a function has no cheap way to learn who calls it. The usual workaround is a search for the name, then reading each hit, then repeating for the next hop. Codanna's pitch is that this loop is a data problem, not a reasoning problem: the call graph already exists in the parsed source, so the agent should receive it pre-correlated instead of reconstructing it turn by turn.

The README states the target audience plainly: Claude Code, Cursor, Windsurf, Codex, Gemini and any MCP-compatible client. The unit of value is one response containing a symbol's identity, signature, docstring, callees with call sites, callers, and a recursive impact list. The README's own example against Codanna's source tree shows a similarity score of 0.833 for one match, three callees with file:line coordinates, two callers, and an impact list capped at depth 2. That is the shape of the answer, and it is the reason the project exists: fewer round trips, and coordinates the agent can open directly rather than fuzzy name matches.

How the index, the parsers and the MCP surface fit together

Codanna parses a repository into symbols and edges, stores the result on disk under .codanna/, and exposes queries over it. The repository layout confirms the parsing side is per-language: examples/ contains directories for c, clojure, cpp, csharp, gdscript, go, java, javascript, kotlin, lua, php, python, rust and swift, which matches the README's claim of fifteen languages. The Rust parser is the one the README demonstrates, with paths like src/parsing/cpp/parser.rs appearing in the sample output, so the C++ and Rust front ends are visible in the repository while the others are represented by example directories rather than documented internals.

On top of the graph sit two retrieval paths. Symbol search is structural, keyed on names and symbol_id values that the README says can be reused to disambiguate collisions. Semantic search is embedding-based: the README states the embedding model downloads once on first use and then runs locally, and that remote OpenAI-compatible embeddings are opt-in through remote_url under [semantic_search] in settings.toml or the CODANNA_EMBED_* environment variables. The API key is environment-only, which keeps credentials out of the config file. Document RAG is a separate collection: codanna documents add-collection docs ./docs registers a directory, codanna documents index builds it, and codanna mcp search_documents queries it. Code and prose are indexed as distinct corpora, which is a reasonable split but means a question spanning both needs two calls.

Installing Codanna and running a first semantic query

The README gives four installation routes. The shell script is the shortest for macOS, Linux and WSL, and it pins the protocol and TLS version in the curl invocation:

bash
curl -fsSL --proto '=https' --tlsv1.2 https://install.codanna.sh | sh

Homebrew and Nix are listed as alternatives, and Windows has a PowerShell script. The README points to the installation guide at docs.codanna.sh for Cargo and other options, so a Rust toolchain build is documented there rather than in the README itself.

Once the binary is on PATH, indexing is two commands. The first writes configuration into the project, the second walks a directory:

bash
codanna init
codanna index src

Indexing only src is deliberate: the README's own example uses that path, and the repository ships a .codannaignore file at the top level for exclusions. After the index exists, the headline query is a one-shot call that needs no running daemon:

bash
codanna mcp semantic_search_with_context query:"where do we handle errors" limit:3

The argument syntax is name:value rather than flags, and the README's sample output shows what comes back: numbered results, a similarity score, the docstring and signature, callees with the line they are called at, callers, and an impact section. Adding --json switches to a structured envelope for scripts. If you would rather keep a session alive, codanna serve runs stdio and codanna serve --http or codanna serve --https run network transports, exposing the same tools.

Where Codanna is the wrong tool

The index is local and file-backed. The README says it lives under .codanna/ and that no source code leaves the machine by default. That is the selling point, and it is also the constraint: there is no documented shared or remote index, so a team cannot point several machines at one corpus, and a CI job that wants impact analysis has to build its own index first. For a large monorepo that cost recurs on every clean checkout.

Language coverage is the second boundary. Fifteen languages is broad, but the README only shows parser internals for Rust and C++, and the rest are represented by directories under examples/ with test files such as test_language_filter.py and test_language_filter.ts. Nothing in the README describes what happens when a file fails to parse, so partial coverage is a real possibility you should measure rather than assume.

Semantic search adds a download. The embedding model is fetched on first use, which means the first query is not offline even though later ones are. And the impact analysis shown in the README is capped at a max depth, printed as depth 2 in the example. That cap is a design choice, not a bug, but it means the blast radius you see is the blast radius within the configured depth. For a question like "what breaks if I change this public API", grep plus a compiler is still the more complete answer.

Codanna versus Serena, and versus plain LSP

The search data shows people comparing Codanna with Serena, so the difference is worth stating. Both serve coding agents, but they sit at different layers. Serena is an LSP-backed toolkit: the editor language server already knows the symbol graph, and the agent talks to that. Codanna builds its own index with its own parsers and adds embedding-based semantic search on top. The practical consequence is setup. An LSP approach inherits whatever the language server supports and needs a working server per language; Codanna needs one index build and then answers semantic queries across the languages it parses. The README frames the one-shot CLI as the case where "LSP is too slow", which is an honest description of the trade: Codanna pays an upfront indexing cost to make later queries cheap, and LSP pays nothing upfront but answers per language server.

The other comparison the README invites is against grep itself. The distinction it draws is that Codanna knows parseConfig is a function that calls validateSchema rather than a string match. That matters for callers and callees, less so for locating a literal string or a config key, where grep remains faster and needs no index.

Maintenance, licence and what an upgrade costs

The repository is not archived, and the last push was on 2026-08-29. Three releases landed in the days before that push, v0.14.0 on 2026-08-25, v0.15.0 on 2026-08-28 and v0.16.0 on 2026-08-29, with Cargo.toml carrying version 0.16.0. The project is pre-1.0, and the release cadence in that window was fast, which usually means the CLI surface and the on-disk index format are still moving. The README does not document index migration or rollback, so a version bump that changes the index layout may require a rebuild. Budget for that: codanna index src is cheap on a small repository and not cheap on a large one.

The licence is Apache-2.0, and the repository carries both LICENSE and NOTICE files. Apache-2.0 includes an express patent grant and requires that NOTICE contents be preserved in redistributions, which matters if you vendor the binary or ship it inside a product. The README says the embedding model downloads on first use; that model is a separate artifact with its own licence, and nothing in the repository states which one it is. Check that before shipping anything that bundles the model. This is a description of the licence text, not legal advice.

Editorial conclusion

Adopt Codanna if your agent spends turns grepping for symbols and you want call graph and impact data in the same response, and if a local index under .codanna/ is acceptable. Do not adopt it if you need a hosted index shared across a team, or if your language is outside the fifteen the README lists. Before committing, run codanna init and codanna index src on your own repository and check that the languages you actually use produce symbols, because the README does not document rollback of an index and the docs site is the only place installation options beyond the shell script, Homebrew and Nix are described.

Frequently asked questions

How does Codanna compare with Serena?

Serena works through language servers, so it inherits each language server's symbol graph and needs one running per language. Codanna builds its own index with its own parsers and adds embedding-based semantic search, which the README presents as the option to use when LSP is too slow.

Does Codanna send my source code to a remote service?

No, not by default. The README states the index lives on disk under .codanna/ and that the embedding model downloads once on first use and then runs locally. Remote OpenAI-compatible embeddings are opt-in through remote_url under [semantic_search] in settings.toml or the CODANNA_EMBED_* environment variables, with the API key kept in the environment.

How do I install Codanna?

On macOS, Linux and WSL the README gives a shell script, with Homebrew and Nix as alternatives and a PowerShell script for Windows. The README points to the installation guide at docs.codanna.sh for Cargo and other options.

Can I use Codanna without running an MCP server?

Yes. The README describes two modes over the same toolset: a persistent server started with codanna serve, and a one-shot CLI such as codanna mcp find_symbol name:"my_function". The one-shot form is what the README recommends for slash-commands, bash hooks, scripts and CI.

Which languages does Codanna index?

The README states fifteen languages. The repository's examples/ directory has per-language folders for c, clojure, cpp, csharp, gdscript, go, java, javascript, kotlin, lua, php, python, rust and swift, and the README's sample output shows Rust and C++ parser internals.

Official sources

  1. bartolli/codanna on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bartolli-codanna.svg)](https://hysenlabs.com/projects/bartolli-codanna)