Lodesman
Compiler-grade code intelligence over MCP. Lodesman puts a real language server behind your coding agent's tools, so "who calls this?" is answered by the compiler rather than by a text search.
A lodesman is the pilot who comes aboard and steers a ship through waters the captain doesn't know. That is the job: an agent dropped into an unfamiliar repository, guided by something with local knowledge.
Status: alpha. The tool surface is still growing and not every tool is finished. If you hit something broken, an issue is genuinely useful — see Status.
Why
An agent's dominant cost is reading files into context, and a tool that returns
coordinates makes that worse, not better — Program.cs — L135 forces the
agent to read the file anyway.
Measured on a real C# repository, answering "what uses RagQueryService":
| approach | cost |
|---|---|
| read the three files involved | 1745 lines, ~17.7k tokens |
| the 3 references, with ±6 lines of code each | ~36 lines, ~370 tokens |
~48× cheaper, and it is a better answer. So Lodesman's tools return code, not locations. A location is a promise of future cost; the code is the answer.
The second reason is correctness. An agent cannot tell a true "no results" from a broken query, so a plausible empty answer is the most dangerous thing a navigation tool can produce. Lodesman gates every answer on the language server actually being ready, and distinguishes "none" from "couldn't tell".
Install
Requires Python 3.11+.
uvx lodesman-mcp # run without installing
pipx install lodesman-mcp # or install it
Wire it into Claude Code
claude mcp add lodesman --scope user -- uvx lodesman-mcp
Or, for any MCP client, in the config directly:
{
"mcpServers": {
"lodesman": {
"command": "uvx",
"args": ["lodesman-mcp"]
}
}
}
With no arguments Lodesman binds to the working directory it is launched in, which is what MCP clients give it. One user-scoped entry therefore works across every project — no per-project configuration.
To point it somewhere explicitly:
lodesman-mcp /path/to/repo --language csharp
First run
The language server itself is downloaded on first use into ~/.solidlsp
(override with SOLIDLSP_HOME). For C# this pulls Roslyn from NuGet and can
take several minutes. Later runs reuse it and start in seconds.
The server process starts immediately; the language server behind it starts lazily on the first tool call and is then kept warm for the life of the process. That is the whole design: a cold Roslyn costs minutes, a warm one answers in milliseconds and tracks your edits incrementally.
Verify your install
python scripts/smoke_test.py /path/to/repo --language csharp
This starts a real language server against a real repository and proves it answers the two questions everything else is built on — what symbols are in this file, and who references this symbol — with cross-file results the compiler agrees with.
Tools
| tool | what it answers |
|---|---|
project_info |
which repository this server bound to, and how |
find_symbol |
find a symbol by name anywhere in the project |
find_definition |
where is this defined |
find_references |
what actually uses this, with the surrounding code |
find_implementations |
concrete implementations of an interface or abstract member |
document_symbols |
outline one file: its types, methods and fields |
get_symbol_body |
the full source of one declaration, by name |
explain_symbol |
resolved type, signature and documentation |
blast_radius |
what breaks if this symbol changes |
rename_symbol |
rename everywhere, using the compiler's understanding |
check |
compiler diagnostics for one file, from the warm server |
blast_radius and check are the two that exist specifically because agents
edit code they haven't read: one tells you the cost of a change before you make
it, the other verifies it afterwards without a full build.
How it binds to a project
One server process serves one repository, chosen at startup: the path you pass, or the working directory if you pass nothing.
The language is detected by counting source files under that root and taking the
majority. Pass --language when that guess is wrong — a repo with a TypeScript
frontend and a C# backend has to be told which one you mean:
lodesman-mcp . --language typescript
Status
Alpha. The tool surface is still growing, and not every tool is finished.
Lodesman inherits SolidLSP's language coverage, and runs wherever its language servers do. Not every language and platform combination has been exercised yet, so if you try one and it breaks, please open an issue — a report with the language, the OS and the stderr output is the most useful thing you can send. Testing help is very welcome.
Known issues are listed here as they are found.
Built on SolidLSP
The language-server client layer is SolidLSP,
MIT, vendored unmodified under src/lodesman/_vendor/. It is bundled rather
than depended on because it is not published to PyPI independently of the Serena
application, which is GPL and is not included here.
Everything Lodesman does lives outside that tree — the project anchoring, the readiness gate, the cross-file indexing wait, symbol ranking, and the decision to return code instead of coordinates were all solved by calling SolidLSP differently, never by editing it. That rule is what keeps re-syncing with upstream cheap.
See NOTICE.md for full attribution.
License
MIT — see LICENSE.
Bundled third-party code, its copyright holders and its license texts are listed in NOTICE.md. Everything bundled is MIT-licensed.
Release files for lodesman-mcp 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lodesman_mcp-0.3.0.tar.gz | 423.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lodesman_mcp-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 964.6 kB
Release files / lodesman_mcp-0.3.0.tar.gz
| Download URL | lodesman_mcp-0.3.0.tar.gz |
|---|---|
| Size | 423.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c6c30143387ec38d41bbb8bd8db53c87d5021694ee61ec92c2506c1669e2387f
|
|
BLAKE2b-256 checksum How to use checksums |
7cf539830cc3d599a9375c43bb78faa7cc5fd732706a9e7d96fe132d312aab18
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / lodesman_mcp-0.3.0-py3-none-any.whl
| Download URL | lodesman_mcp-0.3.0-py3-none-any.whl |
|---|---|
| Size | 541.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f4da96fe7df8206309ca23bbc74fc226c26e0b1566a9c3bd7a4f053f85a9aee4
|
|
BLAKE2b-256 checksum How to use checksums |
c34a826cd855456c9692f2cff0335438b53c22bd132a7df1c26395d4eb6ae37f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|