search_codeLABSCO SUMMARY
Two vectors per symbol, because one query style is never enough.
Dense embeddings find "where do we publish order events"; BM25 over camelCase and snake_case subwords finds PlaceOrderRequest. Running both and fusing them is why neither question fails. Indexing skips files whose git blob SHA is unchanged, and deletes symbols for files that vanished — but that same change detection means a newly added index field needs a forced reindex, which re-embeds everything. One GITHUB_TOKEN reads every repository you index, which the README flags directly.
What it is
An MCP server that indexes code and git history from GitHub repositories you list. It parses symbols with Tree-sitter, stores two vectors per symbol — a dense semantic one and a BM25 sparse one keyed on code identifier tokens — and fuses the results with Reciprocal Rank Fusion so both query styles land.
What you get
- Hybrid search by query, filterable by language, service and symbol type —
search_code - A symbol looked up by name, exact or by case-insensitive token match —
find_symbol; and code referencing it, with the definition excluded —find_usages - The full source of a file, or one symbol inside it, fetched straight from GitHub —
get_code_context - Git history indexed and searched in natural language, with full commit detail including changed files and diffs —
index_history,search_commits,get_commit - Indexing triggered for one service or all, incremental by default —
reindex; pluslist_indexed_servicesandindex_stats - Two prompts that walk a client through a write-up —
service_overviewfor one service,system_design_overviewfor the whole system, with Mermaid diagrams - Framework-aware parsing across Go, Java, Python, TypeScript/JavaScript, Rust, C#, C, C++, Ruby, PHP, Kotlin, Scala, Swift, Dart, Bash, SQL and more — Spring stereotypes and HTTP routes, FastAPI/Pydantic, ASP.NET, Rails, Laravel/Symfony, React/SwiftUI/Flutter widgets
Requirements
Python 3.12+, Docker and a GitHub token — a fine-grained PAT with Contents: read on the target repositories is enough, though the README recommends an org-wide GitHub App if repositories self-register. uv sync, copy .env.example to .env and set GITHUB_TOKEN. Repositories go in config.yaml with an optional github_ref, root and exclude, or are registered on the fly through POST /reindex. Start with make docker-up-jina for local keyless Jina embeddings, or set EMBEDDINGS_PROVIDER to voyage, openai or ollama and use make docker-up. Connect with claude mcp add --transport http semcode http://localhost:8090/mcp, or over stdio. Package semcode 1.1.0, MIT licensed.
Setup effort
Run a container — build the image from the repository, then point your client at it
USE CASES
Finding a behaviour when you do not know the class name
Describe what the code does and let the dense side of the search find it, filtered by service or language.
Tracing who uses a symbol across services
Look the symbol up, then find the references with its own definition excluded from the results.
Working out why the code looks the way it does
Search commit history in natural language and open the commit with its changed files and diffs.
Writing an architecture overview of a service
Run the service overview prompt, which walks through HTTP entry points, domain types and framework conventions.
Keeping the index current on merge
Trigger an incremental reindex from CI — unchanged files are skipped by blob SHA.
10 tools
Listed in project docs. Your client may show a different list.
find_symbolfind_usagesget_code_contextreindexindex_historysearch_commitsget_commitlist_indexed_servicesindex_statsBEFORE YOU INSTALL
What to know first
Tools you get
10 tools named in the project's documentation.
Requires
- Python 3.12+
- Docker
- GITHUB_TOKEN in your environment
Optional
- JINA_API_KEY in your environment
- VOYAGE_API_KEY in your environment
- OPENAI_API_KEY in your environment
Where it runs
All 5 documented setups run the server on your machine.
INSTALLATION
Connect your client
Server setup
git clone https://github.com/GoodbyePlanet/semcode
cd semcode
uv sync
cp .env.example .env
make docker-up-jinaMCP Clients
Claude Code — HTTP
claude mcp add --transport http semcode http://localhost:8090/mcpClaude Code — stdio
claude mcp add semcode --transport stdio --env MCP_TRANSPORT=stdio -- uv run --directory <YOUR_PATH_TO_SEMCODE> python -m server.mainClaude Code — SSE
claude mcp add --transport sse semcode http://localhost:8090/sseCursor — HTTP
{
"mcpServers": {
"semcode": {
"url": "http://localhost:8090/mcp"
}
}
}Any MCP client — stdio
{
"mcpServers": {
"semcode": {
"command": "uv",
"args": [
"run",
"--directory",
"<YOUR_PATH_TO_SEMCODE>",
"python",
"-m",
"server.main"
],
"env": {
"MCP_TRANSPORT": "stdio"
}
}
}
}The configuration on this page does not set GITHUB_TOKEN, JINA_API_KEY, VOYAGE_API_KEY and OPENAI_API_KEY; the project's instructions put them in a .env file. To supply them without depending on where the server looks for that file, use the block's "env" section.