Quill
Local MCP server that indexes compiled Java and Kotlin projects with their DI wiring and git history
Entity-level diff, impact, call-graph and blame queries over a local Git repo for coding agents
By Ataraxy Labs Inc. Rust Local · stdio, Streamable HTTP Developer toolsGit and code hosting
73 popularity score ★ 3.4k ↓ 5.8k/wk
Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.
claude mcp add --transport http sem http://127.0.0.1:8765/mcp --header 'Authorization: Bearer <SEM_MCP_HTTP_TOKEN>'{
"mcpServers": {
"sem": {
"url": "http://127.0.0.1:8765/mcp",
"headers": {
"Authorization": "Bearer <SEM_MCP_HTTP_TOKEN>"
}
}
}
}{
"servers": {
"sem": {
"type": "http",
"url": "http://127.0.0.1:8765/mcp",
"headers": {
"Authorization": "Bearer <SEM_MCP_HTTP_TOKEN>"
}
}
}
}[mcp_servers.sem]
url = "http://127.0.0.1:8765/mcp"
http_headers = { "Authorization" = "Bearer <SEM_MCP_HTTP_TOKEN>" }gemini mcp add --scope user --transport http --header 'Authorization: Bearer <SEM_MCP_HTTP_TOKEN>' sem http://127.0.0.1:8765/mcpOpens the app, which asks before it adds the server.
claude mcp add sem -- npx -y @ataraxy-labs/sem mcp{
"mcpServers": {
"sem": {
"command": "npx",
"args": [
"-y",
"@ataraxy-labs/sem",
"mcp"
]
}
}
}{
"mcpServers": {
"sem": {
"command": "npx",
"args": [
"-y",
"@ataraxy-labs/sem",
"mcp"
]
}
}
}{
"servers": {
"sem": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@ataraxy-labs/sem",
"mcp"
]
}
}
}[mcp_servers.sem]
command = "npx"
args = ["-y", "@ataraxy-labs/sem", "mcp"]gemini mcp add --scope user sem npx -- -y @ataraxy-labs/sem mcp| Set together: http | |
|---|---|
SEM_REPO |
Optional: Absolute path to the repository root when the client does not start sem inside it; required for the HTTP preview. |
SEM_MCP_HTTP_TOKEN secret |
Optional: Bearer token of at least 32 printable characters; the HTTP preview will not start without it. |
SEM_MCP_NO_SHARED |
Optional: Set to any value to run a standalone process instead of joining the shared per-checkout process. |
SEM_NO_INDEX |
Optional: Set to skip the on-disk query index and compute answers directly. |
SEM_TELEMETRY |
Optional: Telemetry mode: off, local (count on this machine only) or on (upload). |
SEM_NO_TELEMETRY |
Optional: Set to 1 to force telemetry off; DO_NOT_TRACK=1 and SEM_NO_NETWORK=1 do the same. |
sem is a Rust command-line tool from Ataraxy Labs. It parses source code with tree-sitter and treats each function, method and class as a named unit, so a change shows up as "this function was modified" rather than "these lines changed". The README counts 32 supported languages. Running `sem mcp` starts the same binary as an MCP server over stdio.
The server lists eight tools. They find where an entity is defined, plus its callers, references, or source with surrounding context. They also search text, list what depends on an entity and which tests reach it, run the project's checkers or one given build or test command and return pass, fail or could not decide, build a review summary for a commit range, diff entities between two refs, draw entity, module or data-flow graphs, and trace an entity's history or blame a file. Older tool names (`sem_entities`, `sem_context`, `sem_callers`, `sem_log`, `sem_blame`) still answer when called but are hidden from the tool list. When started with `sem mcp --review`, it also lists four tools that attach the agent to a code review on Ataraxy Labs' cloud service.
Since 0.28.0 there is also a Streamable HTTP preview, started with `sem mcp --http 127.0.0.1:<PORT>`. It serves only `sem_find` and `sem_grep` for one repository named by `SEM_REPO`, binds to loopback addresses only, and refuses to start unless `SEM_MCP_HTTP_TOKEN` holds a token of at least 32 printable characters (crates/sem-mcp/src/http.rs at v0.28.1). Clients send that token as a bearer header; requests are capped at 1 MiB.
Over stdio the server finds its repository from an absolute file path passed to a tool, then from `SEM_REPO`, then from the working directory (crates/sem-mcp/src/server.rs at v0.28.1) (not in the README). On macOS and Linux, clients in the same checkout share one background process, which takes at most 64 clients (crates/sem-mcp/src/shared.rs) and exits after ten idle minutes.
| Runtime | Node.js |
|---|---|
| Runs on | macOS, Windows, Linux |
| Also |
|
Besides the npm wrapper, sem installs by script, Homebrew (sem-cli), winget, Scoop or cargo (sem-cli); building with cargo needs Rust 1.89 or later. Bun users must run `bun pm trust @ataraxy-labs/sem` so the postinstall step can fetch the binary. Start the client inside the repository or set SEM_REPO. The HTTP preview is started by hand: set SEM_REPO and SEM_MCP_HTTP_TOKEN, run `sem mcp --http 127.0.0.1:8765`, and point the client at http://127.0.0.1:8765/mcp with an `Authorization: Bearer <token>` header. Review mode needs an Ataraxy Labs cloud account (`sem cloud login`).
It cannot work across repositories over one connection: absolute paths into another repository are refused, so each repository needs its own MCP connection. On Windows there is no shared process; each client runs its own standalone stdio server. The shared process shares read caches only and gives no write isolation between agents. GNU Parallel also ships a /usr/bin/sem, and the two names clash on PATH; the README suggests an alias or putting cargo's bin directory first. The review tools appear only in `sem mcp --review` sessions.
Suits developers whose coding agents work in local Git repositories and need precise answers: who calls a function, what a change touches, which tests to run. sem answers these from a parsed dependency graph instead of text search, and the default tools run on your machine with no account. Clients that cannot launch stdio servers can use the HTTP preview, but only for find and grep and only on loopback or through an SSH tunnel. Developers who want search across many repositories in one connection, or a hosted endpoint, need something else; Windows users get no shared process.
8 only read, 4 change things. A ? marks an optional parameter.
sem_findquery?: stringqueries?: arraymode?: stringin?: stringfile?: stringlimit?: integertoken_budget?: integerhops?: integerheaders?: booleantext?: stringintent?: stringfiles?: arraylines?: stringfresh?: booleanformat?: stringsem_greppattern?: stringpatterns?: arraycase_insensitive?: booleanin?: stringbodies?: booleantoken_budget?: integerformat?: stringsem_impactfile_path: stringentity_name: stringmode?: stringno_default_excludes?: booleansem_check changesbase?: stringcheckers?: arraypromises?: booleanrun?: stringat_base?: booleansem_certifyrange: stringarch?: booleanformat?: stringsem_diffbase_ref?: stringtarget_ref?: stringfile_path?: stringsem_graphlayer?: stringoperation?: arraysem_historyentity_name?: stringfile_path?: stringblame?: booleanlimit?: integerjoin_review changesdiff_id: stringwait_for_branch changesdiff_id: stringwait_seconds?: integerreply_to_branch changesdiff_id: stringcomment_id: stringcontent: stringpartial?: booleanlist_open_branchesdiff_id: string