An MCP server providing 56 semantic analysis tools for Java, built directly on Eclipse JDT for compiler-accurate code understanding. JavaLens exists because AI systems need compiler-accurate insights that reading source files cannot provide. When an AI uses grep or Read to find usages of a method, it cannot distinguish: - A method call from a method with the same name in an unrelated class - A fie
Add this skill
npx mdskills install pzalutski-pixel/javalens-mcpComprehensive compiler-accurate Java analysis with 56 semantic tools via Eclipse JDT
1# JavaLens: AI-First Code Analysis for Java23[](https://github.com/pzalutski-pixel/javalens-mcp/releases)4[](LICENSE)5[](https://openjdk.org/projects/jdk/21/)67An MCP server providing 56 semantic analysis tools for Java, built directly on Eclipse JDT for compiler-accurate code understanding.89## Built for AI Agents1011JavaLens exists because **AI systems need compiler-accurate insights that reading source files cannot provide**. When an AI uses `grep` or `Read` to find usages of a method, it cannot distinguish:1213- A method call from a method with the same name in an unrelated class14- A field read from a field write15- An interface implementation from an unrelated class16- A cast to a type from other references to that type1718This leads to incorrect refactorings, missed usages, and incomplete understanding of code behavior.1920## Compiler-Accurate Analysis2122JavaLens provides **compiler-accurate code analysis** through Eclipse JDT—the same engine that powers Eclipse IDE. Unlike text search, JDT understands:2324- Type resolution across inheritance hierarchies25- Method overloading and overriding26- Generic type arguments27- Import resolution and classpath dependencies2829**Example:** Finding all places where `UserService.save()` is called:3031| Approach | Result |32|----------|--------|33| `grep "save("` | Returns 47 matches including `orderService.save()`, `saveButton`, comments |34| `find_references` | Returns exactly 12 calls to `UserService.save()` |3536## AI Training Bias Warning3738> ⚠️ **Important for AI developers and users**3940AI models may exhibit **trained bias toward native tools** (Grep, Read, LSP) over MCP server tools, even when semantic analysis provides better results. This happens because:41421. Training data contains extensive grep/text-search patterns432. Native tools are "always available" in the model's experience443. The model may not recognize when semantic analysis is superior4546**To get the best results:**4748Add guidance to your project instructions or system prompt (e.g., `CLAUDE.md` for Claude Code):4950```markdown51## Code Analysis Preferences5253For Java code analysis, prefer JavaLens MCP tools over text search:54- Use `find_references` instead of grep for finding usages55- Use `find_implementations` instead of text search for implementations56- Use `analyze_type` to understand a class before modifying it57- Use refactoring tools (rename_symbol, extract_method) for safe changes5859Semantic analysis from JDT is more accurate than text-based search,60especially for overloaded methods, inheritance, and generic types.61```6263## What is JavaLens?6465JavaLens is an MCP server that gives AI assistants deep understanding of Java codebases. It provides semantic analysis, navigation, refactoring, and code intelligence tools that go beyond simple text search.6667## Why Not LSP?6869Language Server Protocol was designed for IDE autocomplete and basic navigation—not for AI agent workflows that require deep semantic analysis.7071| Capability | Native LSP | JavaLens |72|------------|------------|----------|73| Find all `@Annotation` usages | ❌ | ✅ |74| Find all `new Type()` instantiations | ❌ | ✅ |75| Find all casts to a type | ❌ | ✅ |76| Distinguish field reads from writes | ❌ | ✅ |77| Detect circular package dependencies | ❌ | ✅ |78| Calculate cyclomatic complexity | ❌ | ✅ |79| Find unused private methods | ❌ | ✅ |80| Detect possible null pointer bugs | ❌ | ✅ |8182JavaLens wraps **Eclipse JDT Core** directly via OSGi, providing:8384- **16 fine-grained reference types**: Find specifically casts, annotations, throws clauses, catch blocks, instanceof checks, method references, type arguments85- **Read vs write access distinction**: Track where fields are mutated vs just read86- **Indexed search**: 10x faster than AST walking for large codebases87- **Full AST access**: Direct manipulation for complex refactorings8889## Installation9091### Prerequisites9293- **Java 21** or later (must be on PATH or set JAVA_HOME)9495### Download9697Download from [Releases](https://github.com/pzalutski-pixel/javalens-mcp/releases):9899| Platform | File |100|----------|------|101| All platforms | `javalens.zip` or `javalens.tar.gz` |102103Extract to a location of your choice (e.g., `/opt/javalens` or `C:\javalens`).104105### Configure MCP Client106107Add to your MCP configuration (e.g., `.mcp.json` for Claude Code):108109```json110{111 "mcpServers": {112 "javalens": {113 "command": "java",114 "args": ["-jar", "/path/to/javalens/javalens.jar", "-data", "/path/to/javalens-workspaces"]115 }116 }117}118```119120The `-data` argument specifies where JavaLens stores its workspace metadata. See [How Workspaces Work](#how-workspaces-work) below.121122### Auto-Load a Project123124Set `JAVA_PROJECT_PATH` to auto-load a project when the server starts:125126```json127{128 "mcpServers": {129 "javalens": {130 "command": "java",131 "args": ["-jar", "/path/to/javalens/javalens.jar", "-data", "/path/to/javalens-workspaces"],132 "env": {133 "JAVA_PROJECT_PATH": "/path/to/your/java/project"134 }135 }136 }137}138```139140> **Note:** Project loading happens asynchronously in the background. The MCP server responds immediately while the project loads. Use `health_check` to monitor loading status—it will show `"project.status": "loading"` until complete, then `"loaded"` when ready.141142## How Workspaces Work143144Unlike in-memory code models, Eclipse JDT requires a **workspace directory** to store:145146- Search indexes for fast symbol lookup147- Compilation state and caches148- Project metadata149150### Workspaces Are Outside Your Source151152JavaLens creates its workspace **outside your source project** to keep your codebase clean:153154```155Your Java Project (unchanged)156├── src/main/java/157├── pom.xml158└── (no Eclipse files added)159160JavaLens Workspace (specified by -data)161└── {session-uuid}/162 ├── .metadata/ <- JDT indexes and state163 └── javalens-project/ <- Links to your source (not copies)164```165166**Why this matters:**1671681. **No pollution**: Your source tree stays clean—no `.project` or `.classpath` files1692. **No conflicts**: Works alongside any build system without interference1703. **Session isolation**: Each MCP session gets its own workspace, enabling concurrent analysis171172### Session Lifecycle1731741. JavaLens starts and creates a unique workspace: `{base}/{uuid}/`1752. `load_project` creates linked folders pointing to your source1763. JDT builds indexes in the workspace (not in your project)1774. When the session ends, the workspace is cleaned up178179## Tools180181### Navigation (10 tools)182183| Tool | Description |184|------|-------------|185| `search_symbols` | Search types, methods, fields by glob pattern |186| `go_to_definition` | Navigate to symbol definition |187| `find_references` | Find all usages of a symbol |188| `find_implementations` | Find interface/class implementations |189| `get_type_hierarchy` | Get inheritance chain |190| `get_document_symbols` | Get all symbols in a file |191| `get_symbol_info` | Get detailed symbol information at position |192| `get_type_at_position` | Get type details at cursor |193| `get_method_at_position` | Get method details at cursor |194| `get_field_at_position` | Get field details at cursor |195196### Fine-Grained Reference Search (8 tools)197198These use JDT's unique reference type constants—not available through LSP:199200| Tool | Description |201|------|-------------|202| `find_annotation_usages` | Find all `@Annotation` usages |203| `find_type_instantiations` | Find all `new Type()` calls |204| `find_casts` | Find all `(Type) expr` casts |205| `find_instanceof_checks` | Find all `x instanceof Type` |206| `find_throws_declarations` | Find all `throws Exception` in signatures |207| `find_catch_blocks` | Find all `catch(Exception e)` blocks |208| `find_method_references` | Find all `Type::method` expressions |209| `find_type_arguments` | Find all `List<Type>` usages |210211### Analysis (12 tools)212213| Tool | Description |214|------|-------------|215| `get_diagnostics` | Get compilation errors and warnings |216| `validate_syntax` | Fast syntax-only validation |217| `get_call_hierarchy_incoming` | Find all callers of a method |218| `get_call_hierarchy_outgoing` | Find all methods called by a method |219| `find_field_writes` | Find where fields are mutated |220| `find_tests` | Discover JUnit/TestNG test methods |221| `find_unused_code` | Find unused private members |222| `find_possible_bugs` | Detect null risks, empty catches, resource leaks |223| `get_hover_info` | Get documentation/signature for symbol |224| `get_javadoc` | Get parsed Javadoc |225| `get_signature_help` | Get method signature at call site |226| `get_enclosing_element` | Get containing method/class at position |227228### Compound Analysis (4 tools)229230Combine multiple queries to reduce round-trips:231232| Tool | Description |233|------|-------------|234| `analyze_file` | Get imports, types, diagnostics in one call |235| `analyze_type` | Get members, hierarchy, usages, diagnostics |236| `analyze_method` | Get signature, callers, callees, overrides |237| `get_type_usage_summary` | Get instantiations, casts, instanceof counts |238239### Refactoring (10 tools)240241All refactoring tools return **text edits** rather than applying changes directly:242243| Tool | Description |244|------|-------------|245| `rename_symbol` | Rename across entire project |246| `organize_imports` | Sort and clean imports |247| `extract_variable` | Extract expression to local variable |248| `extract_method` | Extract code block to new method |249| `extract_constant` | Extract to `static final` field |250| `extract_interface` | Create interface from class methods |251| `inline_variable` | Replace variable with its initializer |252| `inline_method` | Replace call with method body |253| `change_method_signature` | Modify params/return, update all callers |254| `convert_anonymous_to_lambda` | Convert anonymous class to lambda |255256### Quick Fixes (3 tools)257258| Tool | Description |259|------|-------------|260| `suggest_imports` | Find import candidates for unresolved type |261| `get_quick_fixes` | List available fixes for problem at position |262| `apply_quick_fix` | Apply fix by ID (add import, remove import, add throws, try-catch) |263264### Metrics (3 tools)265266| Tool | Description |267|------|-------------|268| `get_complexity_metrics` | Cyclomatic/cognitive complexity, LOC per method |269| `get_dependency_graph` | Package/type dependencies as nodes and edges |270| `find_circular_dependencies` | Detect package cycles using Tarjan's SCC algorithm |271272### Project & Infrastructure (6 tools)273274| Tool | Description |275|------|-------------|276| `health_check` | Server status and capabilities |277| `load_project` | Load Maven/Gradle/plain Java project |278| `get_project_structure` | Get package hierarchy |279| `get_classpath_info` | Get classpath entries |280| `get_type_members` | Get members by type name |281| `get_super_method` | Find overridden method in superclass |282283## Usage284285### Basic Workflow286287```2881. load_project(projectPath="/path/to/java/project")2892. search_symbols(query="*Service", kind="Class")2903. find_references(filePath="...", line=10, column=15)2914. analyze_type(typeName="com.example.UserService")292```293294### Coordinate System295296All line/column parameters are **zero-based**:297- Line 0, Column 0 = first character of file298299### Path Handling300301- Response paths are **relative** by default302- All paths use **forward slashes** for cross-platform consistency303- Input paths can be relative or absolute304305## Important Notes306307### No Live File Watching308309JavaLens analyzes code at load time and does **not** watch for file changes. This is by design—the AI coding agent is responsible for maintaining synchronization:310311| Event | Agent Action |312|-------|--------------|313| After writing/editing files | Call `load_project` to refresh indexes |314| Before complex refactoring | Call `load_project` to ensure fresh state |315| After external changes (git pull, etc.) | Call `load_project` to resync |316317**Why not automatic watching?**3183191. AI agents make discrete edits with clear boundaries—auto-sync adds complexity without benefit3202. The agent controls when analysis should reflect changes3213. Avoids race conditions between file writes and index updates322323**Recommended pattern:**324```3251. Use JavaLens tools to analyze3262. Write changes to files3273. Call load_project to refresh3284. Use JavaLens tools to verify changes329```330331### Refactoring Returns Edits332333Refactoring tools return text edits but don't modify files. This gives visibility into what would change before applying.334335### Session Isolation336337Each MCP session is independent with its own workspace UUID. Multiple sessions can analyze the same project concurrently.338339### Build System Support340341| System | Detection |342|--------|-----------|343| Maven | `pom.xml` |344| Gradle | `build.gradle` / `build.gradle.kts` |345| Plain Java | `src/` directory |346347## Configuration348349| Environment Variable | Description | Default |350|---------------------|-------------|---------|351| `JAVA_PROJECT_PATH` | Auto-load project on startup | (none) |352| `JAVALENS_TIMEOUT_SECONDS` | Operation timeout | 30 |353| `JAVALENS_LOG_LEVEL` | TRACE/DEBUG/INFO/WARN/ERROR | INFO |354355## Building from Source356357```bash358git clone https://github.com/pzalutski-pixel/javalens-mcp.git359cd javalens-mcp360./mvnw clean verify361```362363Distributions are output to `org.javalens.product/target/products/`.364365### Requirements366367- Java 21+368- Maven 3.9+ (wrapper included)369370## Architecture371372```373┌─────────────────────────────────────────────────────────┐374│ MCP Client │375└─────────────────────────────────────────────────────────┘376 │ JSON-RPC over stdio377┌─────────────────────────────────────────────────────────┐378│ org.javalens.mcp │379│ McpProtocolHandler → ToolRegistry → 56 Tools │380└─────────────────────────────────────────────────────────┘381 │382┌─────────────────────────────────────────────────────────┐383│ org.javalens.core │384│ JdtServiceImpl → WorkspaceManager, SearchService │385└─────────────────────────────────────────────────────────┘386 │387┌─────────────────────────────────────────────────────────┐388│ Eclipse JDT Core (via OSGi/Equinox) │389│ IWorkspace, IJavaProject, SearchEngine, ASTParser │390└─────────────────────────────────────────────────────────┘391```392393## License394395MIT License - see [LICENSE](LICENSE) for details.396
Full transparency — inspect the skill content before installing.