Skip to main content

ScalaSemantic MCP vs. Grep Response Metrics

This document evaluates the effectiveness and token efficiency of the scala-semantic-mcp tools against traditional grep/ripgrep analogs.

The data is collected by analyzing the JSON-RPC queries and responses recorded in scala-semantic-mcp.log across 337 tool calls.

1. Metrics Comparison Table​

Below is the comparison of the character sizes returned by the semantic server vs. standard text matching (grep) output formatted as filename:line:content\n (the typical output parsed by IDEs/LLMs).

Tool NameParams PreviewMCP Size (chars)Grep Size (chars)Saving Ratio
find_symbol{"query":"rangeContains","exact":true,"limit":20}4266,55293.5%
find_symbol{"query":"McpTools","exact":true,"limit":10}1393,74296.3%
find_symbol{"query":"linearize"}2802,72889.7%
find_symbol{"name":"mcpServer"}5,5226,1159.7%
find_symbol{"name":"Main"}5,522911-506.1%
document_outline{"uri":"analysis/src/main/scala/com/github/...7,74727,48171.8%
document_outline{"uri":"analysis/src/test/scala/com/github/...9809,93090.1%
document_outline{"uri":"mcp/src/main/scala/com/github/mercur...7,83321,54763.6%
members{"symbol":"com/github/mercurievv/scalasem...11273484.7%
class_hierarchy{"symbol":"com/github/mercurievv/scalasem...14536560.3%
method_signature{"symbol":"com/github/mercurievv/scalasem...34449730.8%
method_signature{"symbol":"com/github/mercurievv/scalasem...481394-22.1%
annotated_source{"uri":"analysis/src/test/scala/com/github/...18,81014,793-27.2%
annotated_source{"uri":"mcp/src/test/scala/com/github/mercur...28,54919,882-43.6%
annotated_source{"uri":"sbt-plugin/src/test/scala/com/github/...13,50815,12610.7%
annotated_source{"uri":"project/ScalaSemanticConfigMerger.s...21,05116,659-26.4%
Total337 calls3,503,6214,036,47913.2%

2. Key Insights and Analysis​

  • High Savings for Search & Metadata (up to 96%): For querying tools like find_symbol, document_outline, class_hierarchy, and members, scala-semantic-mcp is extremely token-efficient. Instead of returning hundreds of noisy matching lines from various files, it parses the query semantically and returns a precise JSON payload.

  • Enriched Data for Code Reading (-10% to -50% ratio): annotated_source calls are generally larger in size than standard plain file reads. This is expected because the tool enriches the plain source code with compiler-inferred type annotations, implicit parameters, and implicit conversions. While this uses slightly more tokens, it provides the LLM with critical semantic context that plain-text search completely misses.

  • Overall Savings: Across the entire 337-call session, the semantic tools saved 13.2% of total character output (saving over 530,000 characters of context tokens) while delivering compiler-level accuracy.


3. Grep Analogs Used​

The comparison script models how a developer would construct text searches to accomplish the same goals:

  1. find_symbol: Substring text search for the query term across all source files.
  2. find_usages: Regex word-boundary search (\b<name>\b) of the symbol's simple name across the codebase.
  3. document_outline: Grep for type/class/member declarations (\b(class|trait|object|def|val|var|type)\s) in the target file.
  4. annotated_source: Plain-text read of the entire file.
  5. method_signature: Search for the method definition (\b(def|val|var)\s+<name>\b) across all files.
  6. class_hierarchy: Combined search for type declaration (class/trait/object <name>) and subclass extension references (extends/with <name>).
  7. members: Find the file defining the class, then list all internal declarations (class, def, val, etc.) inside that file.
  8. structure: Search for all package and type declarations (class, trait, object, package) across the project.

4. Re-Running the Comparison​

You can run the script using scala-cli to re-analyze the logs:

scala-cli run scripts/compare_grep.sc