Symbol-lookup MCP tools backed by vendored cellar#599
Open
oyvindberg wants to merge 1 commit into
Open
Conversation
Adds four MCP tools to bleep-cli that give coding agents API knowledge
straight from the build's resolved classpath:
bleep.symbol.get — full info for an FQN (signature, members,
companion as `object Foo:` block, subtypes,
deprecation tag, docstring)
bleep.symbol.find — discovery: set `scope` (package or class) to
enumerate, set `pattern` to substring-search
the whole classpath, or combine the two.
Results carry source-location annotations:
`(src/.../Foo.scala:42)` for in-project code,
`(in group:artifact:version)` for deps
bleep.symbol.get_source — fetch source code from a published
`-sources.jar` via Coursier, slice to the
symbol's line range. Coordinate is optional;
inferred from the project's resolved artifacts
when omitted.
Powered by `bleep-cellar`, a trimmed fork of VirtusLab/cellar at
liberated/cellar (MPL-2.0), reduced to the tasty-query glue and the
output formatters. Bleep already owns the classpath, JRE info, and
Coursier cache, so we skipped cellar's classpath extraction, build-tool
detection, Coursier wrappers, CLI, HOCON config, and Mill/Nix build
files — ~4,300 LOC gone vs upstream. Dropped fs2; kept cats-effect
(already a bleep dep via the MCP server).
Bridge layer (bleep-cli/src/scala-3/bleep/symbols):
- SymbolsBridge: ResolvedProject/ResolvedJvm → tasty-query Context
with the project's classpath + JRE modules from jrt-fs
- SourceFetcher: on-demand Coursier fetch + zip-slice for sources jars
BleepMcpServer wiring:
- per-project Context cache, invalidated on bleep.yaml change AND on
every successful BSP compile/test cycle (since compile rewrites
classesDir bytes)
- staleness banner when source files are newer than the last compile
- auto-coordinate inference for get_source using
ResolvedProject.resolution
Output choices aimed at agent token-efficiency:
- Scala-source-style rendering (no markdown chrome, no code fences),
modifiers baked into keywords (`sealed trait`, `abstract def`,
`inline def`, `implicit val`); models parse Scala-shaped output more
cheaply than free-form markdown
- `scala.FunctionN[A,..,R]` renders with arrow syntax (`A => R`,
`(A, B) => R`)
- Java signatures: hide `<FromJavaObject>` and `NothingType` bounds;
drop synthetic `x$0`/`x$1` param names; render Object as Object
- Constructors render as `new[Tparams](args)` not `def <init>(): Unit`
- find/pattern groups results by package to elide repeated FQN
prefixes; Scala-2-limited-info note hoisted to a single header
- inherited constructors filtered out; module-class type-alias shims
(`Foo$` traits) filtered out of find/pattern noise
- per-call member limit defaults to 30 to bound output size on large
types like Reactor Flux
- members sorted by category (ctor → abstract → concrete → vals →
types) then alphabetical, for predictable output
bench-bigdeps + `bleep cellar-benchmark`: a Spring-Boot-heavy bleep
project (Spring web/data-jpa/security/webflux, Reactor, Netty,
Hibernate, Jackson, Guava, Apache Commons) plus a benchmark script
exercising 22 representative scenarios across the four tools.
Currently: 22/22 pass quality checks, avg ~110ms per scenario.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four MCP tools that give coding agents JVM API knowledge straight from the build's resolved classpath:
bleep.symbol.get— full info for an FQN: signature, members, companion / Java statics as anobject Foo:block, subtypes, deprecation tag, docstringbleep.symbol.find— discovery:scopeenumerates a package or class,patternsubstring-searches the whole classpath, combine for filtered enumeration. Results carry source-file locations:(src/.../Foo.scala:42)for in-project code,(in group:artifact:version)for depsbleep.symbol.get_source— fetch source from a published-sources.jarvia Coursier, slice to the symbol's line range. Coordinate is optional; inferred from the project's resolved artifacts when omittedPowered by
bleep-cellar, a trimmed fork of VirtusLab/cellar (MPL-2.0) atliberated/cellar, reduced to the tasty-query glue and the output formatters. Bleep already owns the classpath, JRE info, and Coursier cache, so cellar's classpath extraction, build-tool detection, Coursier wrappers, CLI, HOCON config, and Mill/Nix build files were dropped (~4,300 LOC vs upstream). fs2 dropped; cats-effect kept (already a bleep dep via the MCP server).The bridge layer in
bleep-cli/src/scala-3/bleep/symbols/:SymbolsBridge:ResolvedProject/ResolvedJvm→ tasty-queryContextwith project classpath + JRE modulesSourceFetcher: on-demand Coursier-sources.jarfetch + zip sliceBleepMcpServerwiring:bleep.yamlchange AND on every successful BSP compile/test cycle (since compile rewritesclassesDirbytes)get_sourceviaResolvedProject.resolutionOutput choices aimed at agent token-efficiency:
sealed trait,abstract def,inline def,implicit val); models parse Scala-shaped output more cheaply than free-form Markdownscala.FunctionN[A,..,R]renders with arrow syntax<FromJavaObject>andNothingTypebounds; drop syntheticx$0/x$1param namesnew[Tparams](args)notdef <init>(): Unitfind/patterngroups by package to elide repeated FQN prefixes; Scala-2-limited-info note hoisted to a single headerFoo\$traits) hidden from search noiseThe cellar submodule is the bleep-build fork; the trimming commit is on a
mcp-symbolsbranch on that fork (https://github.com/bleep-build/cellar/tree/mcp-symbols). It needs to land onbleep-build/cellarmain(separate small PR) before this can merge.Test plan
bleep test bleep-cellar-tests— 102/102 pass (resolution, lister, formatters, near-match, type printer, etc.)bleep cellar-benchmark— 22/22 scenarios pass quality checks across Spring Boot + Reactor + Netty + Hibernate + Guava + Jackson classpath, avg ~110ms per scenariobleep compileall touched projects:bleep-cellar,bleep-cli,bench-bigdeps,scripts-devbleep fmtbleep.symbol.get/find/get_sourcevia Claude Code against a real bleep build after binary is published🤖 Generated with Claude Code