Content
# Easy Code Reader
<div align="center">
<img src="https://raw.githubusercontent.com/FangYuan33/easy-code-reader/master/icon.png" alt="Easy Code Reader Icon" width="200"/>
</div>
<div align="center">
A powerful MCP (Model Context Protocol) server for intelligently reading Java source code. Supports extracting source code from Maven dependencies and local projects, equipped with dual decompiler (CFR/Fernflower) auto-selection mechanism, intelligent SNAPSHOT version handling, and perfect multi-module project support. Empowers AI assistants to deeply understand your Java codebase.
</div>
---
---
## Features
- 📁 **Local Project Code Reading**: Supports reading source code from local project directories, compatible with multi-module Maven/Gradle projects.
- 📋 **Project Listing Functionality**: Lists all projects in the project directory for quick searching and locating, supporting fuzzy matching of project names.
- 🗂️ **Intelligent File Filtering**: Automatically filters out test directories, compiled artifacts, and IDE configurations, displaying only source code and configuration files, supporting fuzzy matching of file names.
- 🎯 **Module Focus Mode**: Supports listing only the files in specific subdirectories of the project, allowing precise targeting of the desired code.
- 🤖 **AI-Friendly Smart Suggestions**: All tools feature an intelligent error suggestion mechanism that actively guides the AI assistant to adjust strategies when queries fail, effectively reducing hallucinations and repeated attempts.
- 📦 **Reading Source Code from Maven Repository**: Automatically searches for and reads JAR source code from the local Maven repository (defaulting to the **MAVEN_HOME** directory or `~/.m2/repository`, configurable).
- 🔍 **Intelligent Source Code Extraction**: Prioritizes extracting source code from sources JAR; if unavailable, it automatically decompiles class files.
- 🛠️ **Dual Decompiler Support**: Supports both CFR and Fernflower decompilers, automatically selecting the best decompiler based on the Java version.
- ⚡ **Intelligent Caching Mechanism**: Decompilation results are cached under `easy-code-reader/` in the same directory as the JAR, avoiding repeated decompilation.
- 🔄 **SNAPSHOT Version Support**: Smartly handles SNAPSHOT versions, automatically searching for the latest timestamped version and managing the cache.
## Best Practices
Easy Code Reader is particularly well-suited for use with large models such as Claude and ChatGPT. Below, we will introduce some best practices using VSCode in conjunction with Copilot as an example:
### 1. Cross-Project Calls: Analyzing Source Code Based on Call Chains
In more complex projects, it is common to split into multiple microservices, and the implementation of certain features may involve calls across multiple projects. Manually sorting out the related logic can be time-consuming, so you can clone the relevant code to your local machine and use Easy Code Reader MCP in conjunction with Code Agent for analysis. Next, we will take the Nacos project as an example. Suppose we want to understand how the service registration feature of Nacos is implemented; we can follow these steps.
First, for example, we create a Nacos Client client that executes service registration in this logic:
```java
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) throws NacosException, InterruptedException {
logger.info("Starting to initialize Nacos client...");
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");
properties.put(PropertyKeyConst.NAMESPACE, "7430d8fe-99ce-4b20-866e-ed021a0652c9");
NamingService namingService = NacosFactory.createNamingService(properties);
System.out.println("=== Registering service instance ===");
try {
// Register a service instance
namingService.registerInstance("test-service0", "127.0.0.1", 8080);
// Add event listener
namingService.subscribe("test-service", event -> {
System.out.println("Service instance changed: " + event);
});
} catch (Exception e) {
System.out.println("Service registration failed (expected, as the server may not be started): " + e.getMessage());
}
TimeUnit.HOURS.sleep(3);
}
}
```
Since we create the Nacos Client to execute service registration directly by calling the `NamingService#registerInstance` method provided by the Nacos SDK, we are not aware of how the underlying implementation works. If we want to understand the implementation details, we need to clone the Nacos source code and use Easy Code Reader to read the relevant source code. Here is an example prompt:
```text
You are a Java expert. Please help me analyze the logic of the namingService.registerInstance method in #file:Main.java. The implementation of this logic is in the local project of nacos, so you need to read a series of related source codes in nacos to understand its core logic. You can use easy-code-reader MCP to read the nacos project code, which includes tools to obtain project information, all file information in the project, and a specific file.
```

As shown in the figure, it will continuously read and analyze the relevant source code based on the call chain, and ultimately we will understand the implementation details of service registration. This will involve using multiple tools provided by MCP Easy Code Reader, such as `list_all_project`, `list_project_files`, and `read_project_code`. The specific calling details are illustrated as follows:

Finally, we obtain the analysis results, saving a lot of time:

### 2. Read the jar package source code and complete the code writing based on the source code
When using third-party or other external dependencies, Copilot or other Code Agents cannot directly read the source code in the jar package. Often, we need to manually copy the source code content into the prompt to complete the task, which is time-consuming and labor-intensive. The Easy Code Reader provides the `read_jar_source` tool to read the source code in the jar package, helping us complete the development implementation. Let's take the following code as an example. Now I want to implement the registration of multiple service instances, but I am not familiar with the implementation of `NamingService`, so I can use `read_jar_source` to achieve this:
```java
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) throws NacosException, InterruptedException {
logger.info("Starting to initialize Nacos client...");
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");
properties.put(PropertyKeyConst.NAMESPACE, "7430d8fe-99ce-4b20-866e-ed021a0652c9");
NamingService namingService = NacosFactory.createNamingService(properties);
System.out.println("=== Registering service instance ===");
try {
// Register a service instance
namingService.registerInstance("test-service0", "127.0.0.1", 8080);
// Add event listener
namingService.subscribe("test-service", event -> {
System.out.println("Service instance changed: " + event);
});
// Register multiple service instances
} catch (Exception e) {
System.out.println("Service registration failed (expected, as the server may not be started): " + e.getMessage());
}
TimeUnit.HOURS.sleep(3);
}
}
```
```text
You are a Java technology expert, proficient in the Nacos framework. Please help me complete the logic for registering multiple service instances in #file:Main.java. Before writing the code, you need to first use the easy-code-reader's read_jar_source tool to read the source information of com.alibaba.nacos.api.naming.NamingService to understand the method for registering multiple service instances.
```
The processing steps are as follows:

This way, we can quickly understand the implementation details of `NamingService`, allowing us to complete the code writing task and save a lot of time.
### 3. Cross-Project Source Code Reading to Complete This Project Implementation
In large projects, the implementation of certain features may span multiple modules or microservices. If part of the logic has already been implemented and subsequent application logic needs to rely on this part, we can use Easy Code Reader to read the source code of the relevant modules, helping us better understand and implement the functionality of the current project. An example prompt is as follows:
```text
You are a Java technology expert. I am now going to implement the business logic of XXX, which requires calling the interface and its implementation of XXX in the local project A. Please use MCP easy-code-reader to help me read the source code in project A and assist me in implementing the business logic of XXX.
```
Of course, in addition to these three application scenarios, Easy Code Reader can also be used to accomplish the following tasks:
- Quick root cause analysis of exceptions: If there is an exception message thrown from an external jar dependency, you can use the `read_jar_source` tool to quickly locate the exception point based on the exception stack log.
- Dependency upgrade impact assessment (old/new version difference verification): Similarly, use the `read_jar_source` tool to complete the implementation differences between old and new versions and assess the impact of the upgrade.
- Business code logic review: If the business logic development is implemented across multiple projects, you can use tools for reading local project code such as `list_all_project`, `list_project_files`, and `read_project_code` to analyze whether the newly added logic meets business requirements.
- Quick onboarding for newcomers across multiple microservices: By using tools to read local project code, you can quickly clarify the relationships between microservice project codes based on the interface call chain, improving onboarding speed.
---
<a id="quick-start-env"></a>
## Environment Requirements
- [uv](https://github.com/astral-sh/uv) - Python package and project management tool
- Python 3.10 or higher
- Java Development Kit (JDK) - Required to run the decompiler, at least Java 8
## Quick Access (Method 1): Using uvx (Recommended)
If you haven't installed uv yet, you can quickly install it using the following command:
```bash
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
```
Alternatively, you can refer to the [uv official website](https://github.com/astral-sh/uv) for installation and configure the installation path of uv to be added to the system PATH, so that you can directly use the `uvx` command. [uv](https://github.com/astral-sh/uv) is an extremely fast Python package and project management tool. Using `uvx`, you can run without pre-installation. Refer to the following MCP client configuration:
- `--maven-repo`: Specify the Maven repository path, replacing `/custom/path/to/maven/repository` with the local Maven repository path. If not configured, it defaults to the **MAVEN_HOME** directory or `~/.m2/repository`.
- `--project-dir`: Specify the local project directory path, replacing `/path/to/projects` with the actual path where all projects are saved.
```json
{
"mcpServers": {
"easy-code-reader": {
"command": "uvx",
"args": [
"easy-code-reader",
"--maven-repo",
"/custom/path/to/maven/repository",
"--project-dir",
"/path/to/projects"
],
"env": {}
}
}
}
```
Once the above configuration is set up, the AI assistant can invoke the tools provided by Easy Code Reader through the MCP protocol to complete the task of reading Java source code with multiple projects and dependencies.
<a id="quick-start-uv"></a>
## Quick Access (Method 2): Install Locally Using uv
If the installation using **Quick Access (Method 1)** fails, you can use the method of direct installation to your local environment by running the following command:
```bash
uv tool install easy-code-reader
```
After a successful installation, execute the following command to get the installation directory:
```bash
which easy-code-reader
```
For example, if the output is: /Users/fangyuan/.local/bin/easy-code-reader, you need to configure the MCP client as follows, **pay attention to the `args` parameter configuration**, **pay attention to the `args` parameter configuration**, **pay attention to the `args` parameter configuration**:
```json
{
"mcpServers": {
"easy-code-reader": {
"command": "/Users/fangyuan/.local/bin/easy-code-reader",
"args": [
"--maven-repo",
"/custom/path/to/maven/repository",
"--project-dir",
"/path/to/projects"
],
"env": {}
}
}
}
```
Generally, this operation will complete the installation. If there are version updates in the future, you can upgrade using the following command:
```bash
uv tool install --upgrade easy-code-reader
```
## Frequently Asked Questions
### Q1: spawn uvx ENOENT spawn uvx ENOENT
The uv command was not found. Please ensure that uv is correctly installed and that its path is added to the system PATH. Refer to [Environment Requirements](#quick-start-env), and try restarting the IDE before starting the MCP Server again.
### Q2: Downloading cpython-3.10.19-macos-aarch64-none (download) (17.7MiB) MCP error -32001: Request timed out
The Python environment download failed. Try downloading manually or retry the download, or refer to [Quick Start (Method 2)](#quick-start-uv).
## Tool Description
Easy Code Reader provides 5 main tools, divided into two major usage scenarios:
### Scenario 1: Reading the Source Code of Maven JAR Package
#### search_artifact
Search for a specified artifact in the local Maven repository and return the complete Maven coordinates.
**Purpose:**
- Quickly find when only the artifact ID is known but the complete Maven coordinates are uncertain
- Infer complete coordinates from classpath (e.g., `xxx.jar!/com/example/...`) or JAR file names
- Explore available dependency versions in the local Maven repository
**Parameters:**
- `artifact_id` (required): Maven artifact ID, for example, `spring-core`
- `version_pattern` (optional): Version number fuzzy matching pattern, such as `1.0.0`, `SNAPSHOT`, `20251110`
- `group_id_hint` (optional): groupId hint to narrow down the search, such as `org.springframework`, `com.alibaba`
**How It Works:**
1. Recursively traverse the Maven repository directory structure (groupId/artifactId/version)
2. Look for directories matching the artifact_id
3. Apply optional filtering conditions (version_pattern, group_id_hint)
4. Return all matching Maven coordinates and their JAR file information
**Performance Optimization Tips:**
- If the repository is large, it is strongly recommended to provide the `group_id_hint` parameter to narrow the search
- All filtering conditions are case-insensitive
**Smart Hint Mechanism:**
Based on the number of search results, the tool will provide different AI-friendly hints:
- **No results found**: Provide detailed troubleshooting suggestions, including checking spelling, downloading dependencies, adjusting filtering conditions, etc.
- **Unique match found**: Directly display the complete coordinates and next steps (call read_jar_source)
- **Few matches found (2-5)**: List all coordinates for selection, with version selection suggestions
- **Many matches found (>5)**: Suggest using filtering parameters to narrow the range, providing specific filtering examples
**Example 1 - Basic Search:**
```json
{
"artifact_id": "spring-core"
}
```
**Example 2 - Using Version Filter:**
```json
{
"artifact_id": "nacos-client",
"version_pattern": "2.0.0"
}
```
**Example 3 - Using groupId Hint:**
```json
{
"artifact_id": "dubbo",
"group_id_hint": "com.alibaba"
}
```
**Return Format:**
```json
{
"artifact_id": "spring-core",
"version_pattern": "none",
"group_id_hint": "none",
"total_matches": 3,
"searched_dirs": 42,
"elapsed_seconds": 0.15,
"matches": [
{
"group_id": "org.springframework",
"artifact_id": "spring-core",
"version": "5.3.21",
"coordinate": "org.springframework:spring-core:5.3.21",
"jar_count": 1,
"jar_files": [
{
"name": "spring-core-5.3.21.jar",
"size_mb": 1.52
}
],
"path": "/Users/xxx/.m2/repository/org/springframework/spring-core/5.3.21"
}
],
"hint": "🎯 Found 3 matching artifacts..."
}
```
**Typical Workflow:**
1. Use `search_artifact` to search for the artifact (only provide artifact_id)
2. Select the correct Maven coordinates from the search results
3. Use the `read_jar_source` tool to read the source code
💡 **Usage Suggestions**:
- When `read_jar_source` reports "JAR file not found," prioritize using this tool to find the correct coordinates
- For large Maven repositories, it is recommended to provide the `group_id_hint` parameter to improve search speed
- Search results will be automatically sorted by version, with the latest version first
#### read_jar_source
Read the source code of Java classes from Maven dependencies (preferably from sources jar, otherwise decompile).
**Parameters:**
- `group_id` (required): Maven group ID, for example `org.springframework`
- `artifact_id` (required): Maven artifact ID, for example `spring-core`
- `version` (required): Maven version, for example `5.3.21`
- `class_name` (required): Fully qualified class name, for example `org.springframework.core.SpringVersion`
- `prefer_sources` (optional, default `true`): Prefer using sources jar instead of decompiling
**How it works:**
1. First, it attempts to extract the source code from `-sources.jar` (if `prefer_sources=true`)
2. If the sources jar does not exist or extraction fails, it automatically falls back to decompiling the main JAR file
3. Smart handling of SNAPSHOT versions is supported
**Smart error messages:**
When the JAR file is not found, the tool provides detailed troubleshooting suggestions:
- Indicates possible reasons (dependency not installed, incorrect Maven coordinates)
- Suggests using the `read_project_code` tool to read the project's `pom.xml` file
- Guides checking the correct Maven coordinates in the `<dependencies>` section
- Prompts to re-invoke the tool after confirming the coordinates
- Explains that it may be necessary to execute Maven build commands to install dependencies
This intelligent hint mechanism is particularly suitable for use with AI assistants, effectively reducing repeated attempts due to incorrect Maven coordinates.
**Example:**
```json
{
"group_id": "org.springframework",
"artifact_id": "spring-core",
"version": "5.3.21",
"class_name": "org.springframework.core.SpringVersion"
}
```
**Return format:**
```json
{
"class_name": "org.springframework.core.SpringVersion",
"artifact": "org.springframework:spring-core:5.3.21",
"source_type": "sources.jar",
"code": "package org.springframework.core;\n\npublic class SpringVersion {\n // ...\n}"
}
```
**Explanation of the source_type field:**
The `source_type` field indicates the source of the source code, helping the AI assistant understand the reliability and freshness of the code:
- `"sources.jar"`: Extracted from Maven's sources JAR file (most reliable, fully consistent with the release version)
- `"decompiled"`: Newly decompiled through a decompiler (may have incomplete decompilation issues)
- `"decompiled_cache"`: Read from previously decompiled cache (avoids repeated decompilation, improves performance)
💡 **Usage suggestions**:
- Code from `sources.jar` is the most accurate and can be directly used as a basis for analysis
- Code from `decompiled` may exhibit decompilation characteristics such as syntax sugar recovery and generic type erasure
- `decompiled_cache` has the same quality as `decompiled`, but is read from cache to enhance efficiency
### Scenario 2: Reading Local Project Source Code
#### list_all_project
List all project folder names under the project directory.
**Purpose:**
- View all available projects
- Help infer the closest project name when an incomplete project name is entered
- Verify if a project exists
- Support fuzzy matching of project names for quick search of specific projects
**Parameters:**
- `project_dir` (optional): The path to the project directory; if not provided, the path configured at startup will be used.
- `project_name_pattern` (optional): Fuzzy matching pattern for project names (case insensitive) used to filter the project list.
- Supports left and right fuzzy matching, for example, `nacos` will match project names containing `nacos`, `Nacos`, `NACOS`.
- ⚠️ **Usage Suggestion**: If the matching pattern is too strict, it may lead to missing the target project.
- 💡 **Best Practice**: If the expected result is not found, it is recommended to omit this parameter and re-query the complete list.
**Intelligent Hint Mechanism:**
- When using `project_name_pattern` but no projects are matched, the returned result will include a hint message.
- It is suggested that the AI assistant omit the `project_name_pattern` parameter and re-query when the expected project is not found.
- Effectively reduces query failures caused by excessive filtering.
**Example 1 - List all projects:**
```json
{}
```
**Example 2 - Use fuzzy matching for project names:**
```json
{
"project_name_pattern": "spring"
}
```
**Return Format:**
```json
{
"project_dir": "/path/to/projects",
"project_name_pattern": "spring",
"total_projects": 2,
"projects": [
"spring-boot",
"spring-cloud-demo"
],
"hint": "Filtered using project name pattern 'spring'. If the expected project is not found, the matching pattern may be too strict. Suggestion: omit the project_name_pattern parameter and re-invoke the list_all_project tool to view the complete project list.",
"total_all_projects": 5
}
```
**Hint Message Explanation:**
- When using `project_name_pattern` but no projects are matched, the `hint` field will indicate that the pattern may be too strict and display the total number of projects `total_all_projects`.
- When using `project_name_pattern` and there are matching results, the `hint` field will remind that if the results do not meet expectations, the parameter can be omitted for re-querying, while also displaying the total number of projects.
- This intelligent hint mechanism helps the AI assistant better adjust the query strategy, avoiding missing the target project due to excessive filtering.
#### list_project_files
List the source code files and configuration file paths in a Java project.
**Purpose:**
- Understand the project structure and file organization
- Locate specific classes or configuration files
- Analyze relationships and dependencies between classes
- Focus on specific modules when there are too many project files
- Support fuzzy matching of file names for quick identification of target files
**Supports two modes:**
1. **Full Project Mode** (without specifying `sub_path`): Lists all files in the entire project
2. **Focused Mode** (specifying `sub_path`): Lists only the files in the specified subdirectory
**Parameters:**
- `project_name` (required): The name of the project, e.g., `nacos`
- `sub_path` (optional): The path of the subdirectory within the project, e.g., `core` or `address/src/main/java`
- `file_name_pattern` (optional): Fuzzy matching pattern for file names (case insensitive), used for further filtering the file list
- Supports left and right fuzzy matching, e.g., `Service` will match file names containing `service`, `Service`, `SERVICE`
- ⚠️ **Usage Suggestion**: If the matching pattern is too strict, it may lead to missing target files
- 💡 **Best Practice**: If the expected results are not found, it is recommended to omit this parameter and re-query the complete list
- `project_dir` (optional): The path of the parent directory where the project is located; if not provided, the path configured at startup will be used
**Automatic Filtering:**
- ✅ Includes: Java source code (.java), configuration files (.xml, .properties, .yaml, .json, etc.), build scripts, documentation
- ❌ Excludes: Test directories (`src/test`), compiled artifacts (`target`, `build`), IDE configurations, version control files
**Intelligent Hint Mechanism:**
- When using `file_name_pattern` but no files are matched, the returned result will include a hint message
- It is suggested that the AI assistant omit the `file_name_pattern` parameter and re-query when the expected files are not found
- Effectively reduces query failures caused by excessive filtering
**Example 1 - List the entire project:**
```json
{
"project_name": "nacos"
}
```
**Example 2 - List only the core module:**
```json
{
"project_name": "nacos",
"sub_path": "core"
}
```
**Example 3 - Use fuzzy matching for file names:**
```json
{
"project_name": "nacos",
"file_name_pattern": "Service"
}
```
**Return Format:**
```json
{
"project_name": "nacos",
"project_dir": "/path/to/projects/nacos",
"search_scope": "core",
"file_name_pattern": "Service",
"total_files": 15,
"files": [
"core/src/main/java/com/alibaba/nacos/core/service/NacosService.java",
"api/src/main/java/com/alibaba/nacos/api/naming/NamingService.java",
"..."
],
"hint": "Filtered using the file name pattern 'Service'. If the expected file is not found, the matching pattern may be too strict. Suggestion: Omit the file_name_pattern parameter and re-invoke the list_project_files tool to view the complete file list."
}
```
**Hint Message Explanation:**
- When using `file_name_pattern` but no files are matched, the `hint` field will indicate that the pattern may be too strict
- When using `file_name_pattern` and there are matching results, the `hint` field will remind that if the results do not meet expectations, the parameter can be omitted for a re-query
- This intelligent hint mechanism helps the AI assistant better adjust the query strategy, avoiding missing target files due to excessive filtering
#### read_project_code
Read the source code or configuration file content of a specified file from the local project directory.
**Purpose:**
- Read the complete source code of a specific class or file
- View the content of configuration files (pom.xml, application.yml, application.properties, etc.)
- Read project documentation (README.md, SQL scripts, etc.)
- Support multi-module Maven/Gradle projects
- Automatically search common source code and configuration file paths
**Parameters:**
- `project_name` (required): The name of the project, e.g., `my-project`
- `file_path` (required): File identifier: can be a fully qualified Java class name or a relative file path
- Java class name format: `com.example.MyClass` (automatically find the corresponding .java file)
- Relative path format: `src/main/java/com/example/MyClass.java`
- Module relative path: `core/src/main/java/com/example/MyClass.java`
- Configuration file path: `src/main/resources/application.yml`, `pom.xml`
- Documentation files: `README.md`, `docs/setup.md`
- `project_dir` (optional): Project directory path; if not provided, the path configured at startup will be used
**Supported File Types:**
- Java source code (.java)
- Configuration files (.xml, .properties, .yaml, .yml, .json, .conf, .config)
- Build scripts (.gradle, .gradle.kts, pom.xml)
- Documentation files (.md, .txt)
- SQL scripts (.sql)
- Shell scripts (.sh, .bat)
**Automatic Search Paths:**
- For Java class names: `src/main/java/{class_path}.java`, `src/{class_path}.java`, `{class_path}.java`
- For configuration files: project root directory, `src/main/resources/`, `src/`, `config/`, and submodules
- Supports submodule paths in multi-module projects
**Recommended Workflow:**
1. Use `list_all_project` to confirm the project exists
2. Use `list_project_files` (recommended with `file_name_pattern` parameter) to view the file list
3. Use this tool to read the content of specific files
**Example 1 - Read Java source code using class name:**
```json
{
"project_name": "my-spring-app",
"file_path": "com.example.service.UserService"
}
```
**Example 2 - Read Java file using relative path:**
```json
{
"project_name": "nacos",
"file_path": "address/src/main/java/com/alibaba/nacos/address/component/AddressServerGeneratorManager.java"
}
```
**Example 3 - Read configuration file:**
```json
{
"project_name": "my-spring-app",
"file_path": "src/main/resources/application.yml"
}
```
**Example 4 - Read a file from the project root directory:**
```json
{
"project_name": "my-spring-app",
"file_path": "pom.xml"
}
```
**Return Format:**
```json
{
"project_name": "my-spring-app",
"class_name": "com.example.service.UserService",
"file_path": "/path/to/projects/my-spring-app/src/main/java/com/example/service/UserService.java",
"code": "package com.example.service;\n\nimport ...\n\npublic class UserService {\n // ...\n}"
}
```
## Technical Details
### Project Structure
```
easy-code-reader/
├── src/easy_code_reader/
│ ├── __init__.py
│ ├── __main__.py # Entry point of the program
│ ├── server.py # MCP server implementation
│ ├── config.py # Configuration management
│ ├── decompiler.py # Decompiler integration
│ └── decompilers/ # Directory for decompiler JAR files
│ ├── fernflower.jar # Fernflower decompiler
│ └── cfr.jar # CFR decompiler
├── tests/ # Test files
├── pyproject.toml # Python project configuration
├── requirements.txt # Python dependencies
└── README.md # This document
```
### Decompiler
Easy Code Reader supports multiple decompilers and automatically selects the most suitable one based on the Java version:
| Java Version | Recommended Decompiler | Description |
|--------------|------------------------|-------------------------------------------------------------------------------------------------------------|
| 8 - 20 | CFR | Automatically uses the **CFR** decompiler (compatible with Java 8+), included in the package: `src/easy_code_reader/decompilers/cfr.jar` |
| 21+ | Fernflower | Automatically uses the **Fernflower** decompiler (the decompiler used by IntelliJ IDEA), included in the package: `src/easy_code_reader/decompilers/fernflower.jar` |
#### Decompilation Cache Mechanism
The decompiled files are cached in the `easy-code-reader/` subdirectory located in the same directory as the JAR package. For example:
If the JAR package is located at:
```
~/.m2/repository/org/springframework/spring-core/5.3.21/spring-core-5.3.21.jar
```
The decompiled source files will be stored in:
```
~/.m2/repository/org/springframework/spring-core/5.3.21/easy-code-reader/spring-core-5.3.21.jar
```
The cache files themselves are also in JAR format, containing all the decompiled `.java` files. This helps avoid redundant decompilation of the same JAR package, improving performance. However, **special handling is required for SNAPSHOT versions:** Since Maven generates timestamped JARs for snapshot versions (e.g., `artifact-1.0.0-20251030.085053-1.jar`), Easy Code Reader will automatically look for the latest timestamped version for decompilation and store it in the cache with the name `artifact-1.0.0-20251030.085053-1.jar`. This provides a basis for version judgment, and when a new version is detected, it will automatically clean up the old SNAPSHOT cache and generate a new cache file.
## License
Apache License 2.0, see the [LICENSE](LICENSE) file for details.
## On the Shoulders of Giants
- [Github: maven-decoder-mcp](https://github.com/salitaba/maven-decoder-mcp)
- [Github: fernflower](https://github.com/JetBrains/fernflower)
- [Github: Model Context Protocol (MCP) Quick Start Guide](https://github.com/liaokongVFX/MCP-Chinese-Getting-Started-Guide)
Connection Info
You Might Also Like
MarkItDown MCP
Converting files and office documents to Markdown.
Time
Obtaining current time information and converting time between different...
Filesystem
Model Context Protocol Servers
Sequential Thinking
Offers a structured approach to dynamic and reflective problem-solving,...
Git
Model Context Protocol Servers
Context 7
Context7 MCP Server -- Up-to-date code documentation for LLMs and AI code editors