🔓 unclaimed — this page was auto-generated from GitHub. Are you the creator?
Claim this page →
ScalaSemantic
MCP server for deep semantic analysis of Scala via SemanticDB — exact find-usages, class hierarchies, implicit resolution & call paths for AI coding agents l…
{
"mcpServers": {
"ScalaSemantic": {
"command": "npx",
"args": ["-y", "https://github.com/MercurieVV/ScalaSemantic"]
}
}
}ScalaSemantic
ScalaSemantic helps AI understand your Scala code like the compiler does. Instead of asking an agent to guess from text search (grep), you let it query compiler-emitted SemanticDB for exact symbols, types, implicits, inheritance, usages, and call paths.
For a Scala developer, that means an agent can answer questions like:
- where a method is really used, without false matches from
grep; - which classes extend a trait or override a member;
- which
givencan satisfy a type; - how one method can call another across the project.
It is exposed over MCP, so clients such as Claude Code, Codex, and Gemini CLI can call it as a local tool while you keep using your normal Scala build.
📖 Documentation site: https://mercurievv.github.io/ScalaSemantic/ (mdoc-checked, so its code samples are executed at build time).
Why, vs grep
grep matches characters; ScalaSemantic understands the compiled program.
| You want to know… | grep | ScalaSemantic |
|---|---|---|
Who extends Animal? | every line containing "Animal" | exact subtypes — class_hierarchy |
All usages of method foo | every "foo", unrelated included | exact symbol references — find_usages |
Which givens produce Show[Int]? | — not possible | resolve_implicits |
Call path from a to c? | — not possible | call_path |
Every capability is backed by a test that runs against this repo's own SemanticDB →
AnalyzerSuite.
Full trade-offs, including where grep wins:
docs/explanation/scala-semantic-vs-grep.md.
Quickstart
Your MCP client spawns the server over stdio. Two things are needed (only a JVM — no coursier, no sbt):
- the target project compiled with SemanticDB (
semanticdbEnabled := true); - MCP client config that launches the server with that project's root as its argument.
Pick one setup:
sbt plugin — recommended
Least manual: works on sbt 1 and sbt 2, enables SemanticDB, and generates MCP client config for you; the jar arrives on first spawn.
// project/plugins.sbt — replace x.y.z with the latest release (see the badge / releases page)
addSbtPlugin("io.github.mercurievv" % "sbt-scalasemantic-mcp" % "x.y.z")
// build.sbt
enablePlugins(ScalaSemanticMcpPlugin)
Latest version: · GitHub releases
sbt mcpClientConfig writes/merges the client configuration (or you can specify the client as a CLI argument, e.g., sbt "mcpClientConfig gemini", or sbt "mcpClientConfig all" to generate configs for all supported clients in one go); sbt mcpRun runs the server for testing. The default client is claude (which emits .mcp.json for Claude Code). Other supported clients are: codex (for Codex config.toml), gemini (Gemini CLI), antigravity (Antigravity CLI/IDE), cline, roo (Roo Code), continue (Continue YAML), generic-json, or all.
Running mcpClientConfig also automatically generates a SCALA_SEMANTIC_RULES.md file containing coding rules for the agent, and creates/updates client-specific rules (like CLAUDE.md, AGENTS.md (for Gemini/Antigravity), or .cursorrules) pointing to it.
Any build tool / OS
- Auto-download launcher —
curl -fsSL .../scripts/install.sh | sh(Windows:…ps1), then set your MCP clientcommandto~/.local/bin/scalasemantic-mcp. Fetches + caches the fat jar on first run. - Plain
java -jar— grabscalasemantic-mcp.jarfrom the latest release and run it directly.
Optional launcher flags — append to the MCP client args after the project root (the launcher
forwards them to the server; equivalent env vars in parentheses):
--prefetch— download + cache the jar, then exit without serving.--log(SCALASEMANTIC_LOG) — log a tool call input to file.--log-output(SCALASEMANTIC_LOG_OUTPUT) — log a tool call output to file.
{
"mcpServers": {
"scala-semantic": {
"command": "~/.local/bin/scalasemantic-mcp",
"args": ["/abs/path/to/project", "--log", "--log-output"]
}
}
}
Full setup, generated config, and lifecycle: docs/getting-started/integration.md.
Tools
| Tool | Answers |
|---|---|
find_symbol | resolve a plain/partial name to SemanticDB symbol strings — start here |
find_usages | references to a symbol, def/ref split, paged |
method_signature | full signature incl. implicit/using parameter lists |
class_hierarchy | parents, linearization, index-wide known subtypes |
find_overloads | all overloads sharing a name and owner |
members | declared vs inherited members (override-aware) |
type_at_position | symbol + type at a 0-based position |
resolve_implicits | given definitions that produce a type |
trace_implicit_chain | a given's transitive implicit dependencies |
call_path | shortest call path between two methods |
Every tool takes a SemanticDB symbol string; call find_symbol first to get one from a plain name.
On initialize the server also sends instructions telling the agent to prefer these tools over
grep for Scala code questions. Results are lean by default (locations as uri:line:col,
signatures one line, empty fields omitted); pass "detailed": true to expand, and find_usages is
paged.
Supported Scala versions
There are two analysis paths, with different version coverage:
- Disk SemanticDB (primary path) — the server reads the
*.semanticdbfiles your build emits, so it is largely compiler-version-agnostic: it works against any project that compiles cleanly with SemanticDB enabled. Cross-version behavior is enforced by tests — the analyzer is exercised against golden SemanticDB from Scala 2.13.* and 3.*.* (see docs/project/development.md). - Presentation-compiler (live) path — used for position-local tools on an edited / uncompiled / broken in-memory buffer, before a clean compile exists on disk. This embeds Scala 3's own presentation compiler, which is version-locked to Scala 3.8.4 (the only PC build wired in today). In principle the Scala 3 compiler can parse older 3.* source, but no per-version PC switching ships yet, and Scala 2.13 is not supported on this path (Scala 3's compiler is not a Scala 2 compiler).
So: disk-based analysis covers 2.13.* + 3.*.*; the live broken-buffer path is Scala 3.8.4
only. The server itself runs on any JVM (java 11+); the target project's Scala version is independent.
Docs
- Documentation site — the rendered, mdoc-checked microsite
- Quickstart — shortest sbt setup path
- Integration — register with a client, sbt plugin, other build tools
- Tool reference — MCP tools, symbol grammar, request shape
- Examples — sample MCP queries and responses
- ScalaSemantic vs grep — trade-offs and measured context cost
- Development — module layout, build & test, cross-version testing
- Design decisions — implementation notes and future extension points
- Releasing — Sonatype Central release process
License
// compatibility
| Platforms | cli, api |
|---|---|
| Operating systems | — |
| AI compatibility | claude |
| License | MIT |
| Pricing | open-source |
| Language | Scala |
// faq
What is ScalaSemantic?
MCP server for deep semantic analysis of Scala via SemanticDB — exact find-usages, class hierarchies, implicit resolution & call paths for AI coding agents like Claude Code. Beyond grep and standard LSP.. It is open-source on GitHub.
Is ScalaSemantic free to use?
ScalaSemantic is open-source under the MIT license, so it is free to use.
What category does ScalaSemantic belong to?
ScalaSemantic is listed under mcp-servers in the Claudeers registry of Claude-compatible tools.
// embed badge
[](https://claudeers.com/scalasemantic)
// retro hit counter
[](https://claudeers.com/scalasemantic)
// reviews
// guestbook
// related in MCP Servers
f.k.a. Awesome ChatGPT Prompts. Share, discover, and collect prompts from the community. Free and open source — self-host for your organization with complete…
A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Gemini CLI & Hermes Agent. Only official website: ccswitch.io
An open-source AI agent that brings the power of Gemini directly into your terminal.