ScalaSemantic
ScalaSemantic is an MCP server that gives AI coding agents compiler-resolved Scala facts — exact symbols, types, inheritance, usages, implicits, and call paths — over compiler-emitted SemanticDB. Instead of grepping source text, agents query what the compiler already knows.
Works with Scala 2.13.* and 3.., any sbt/Mill/Gradle project, and any MCP-compatible agent (Claude Code, Codex, Gemini CLI, Cline, Roo Code, Continue…).
Quick setup
Needs only java (no sbt, no Scala CLI). Download the launcher once and run setup. It
idempotently enables SemanticDB, writes the agent steering files, and merges an MCP server entry
into every client config it finds — re-running is always safe:
curl -fsSL https://raw.githubusercontent.com/MercurieVV/ScalaSemantic/master/scripts/scalasemantic-mcp.sh -o scalasemantic-mcp.sh && chmod +x scalasemantic-mcp.sh && ./scalasemantic-mcp.sh setup
iwr https://raw.githubusercontent.com/MercurieVV/ScalaSemantic/master/scripts/scalasemantic-mcp.ps1 -OutFile scalasemantic-mcp.ps1; .\scalasemantic-mcp.ps1 setup
If you already have Scala CLI installed, the equivalent setup is also available as a script:
scala-cli https://raw.githubusercontent.com/MercurieVV/ScalaSemantic/master/scripts/scalasemantic-mcp.scala setup
Guard hook (Claude Code)
For Claude Code, setup also installs .claude/hooks/scala-semantic-guard.sh and registers it as a
PreToolUse hook. It denies grep/cat/Read/Grep aimed at .scala files and points the
agent at the MCP tools instead — steering files only ask, a hook enforces. It fails open when the
semantic answer isn't available (no MCP entry, no compiled *.semanticdb, no jq/python3), and
an explicit # semantic-fallback: <reason> marker on a shell command always passes (and is logged
to .claude/semantic-fallback.log).
Skip it with setup --no-guard (-NoGuard on PowerShell). Rationale and alternatives:
docs/adr/0001-claude-code-guard-hook.md.
Tools
| Tool | Purpose |
|---|---|
find_symbol |
Resolve a name to a SemanticDB symbol |
find_usages |
Exact references to a symbol (paged) |
class_hierarchy |
Parents and known subtypes |
method_signature |
Full signature with type/implicit params |
members |
Declared and inherited members |
resolve_implicits |
Given definitions for a type |
call_path |
Shortest call route between two methods |
type_at_position |
Symbol and type at a source position |
trace_implicit_chain |
Transitive given dependencies |
find_overloads |
All overloads sharing a name and owner |
Full reference: docs/reference/tools.md
SemanticDB vs grep
| Question | Right tool |
|---|---|
| Exact callers of a method | find_usages |
| All subtypes of a trait | class_hierarchy |
Which given satisfies a type |
resolve_implicits |
Call path from method a to c |
call_path |
| Comments, TODOs, config files | grep |
| Code that hasn't compiled yet | grep |
Measured: semantic tools use ~90% fewer tokens than grep for symbol questions. Details: SemanticDB vs grep.
Documentation
- Quickstart — auto-download script, 5 minutes
- Integration — Scala CLI script, launcher, plain jar, logging
- Tool reference — all MCP tools and SemanticDB symbol grammar
- Examples — sample MCP calls and responses
- SemanticDB vs grep — trade-offs and token savings
- FAQ — compile freshness, Metals, install choices
- Development — modules, build, test, cross-version
- Releasing — Sonatype Central release process
Full documentation map: docs/index.md
No comments yet
Be the first to share your take.