Skip to main content
Glama
ETHAN0430

java-class-analyzer-mcp

by ETHAN0430
README.md
# Java Class Analyzer MCP Server

一个基于Model Context Protocol (MCP)的Java类分析服务,可以扫描Maven项目依赖、反编译Java类文件、获取class方法列表等详细信息,并提供给LLM进行代码分析。

## 致谢

本项目源自 [handsomestWei/java-class-analyzer-mcp-server](https://github.com/handsomestWei/java-class-analyzer-mcp-server),感谢原作者的开源贡献。

- **本项目仓库**:[ETHAN0430/java-class-analyzer-mcp](https://github.com/ETHAN0430/java-class-analyzer-mcp)

🚀 核心突破与改进
- **修复 Cursor/stdio 兼容性**:修复原版只支持字节跳动Trae,而在 Cursor 下 完全不可用的致命问题。
- **全版本 JDK 深度适配**:补齐了原版缺失的 JDK 类扫描能力,完美支持 Java 8 (`rt.jar`) 及 Java 9+ 模块化系统 (`jrt://`)。
- **CFR 反编译引擎工程化**:内置 CFR 0.152 核心,解决了原版 npm 安装后找不到反编译工具、环境变量不生效等分发难题。
- **工业级 Maven 执行器**:重写了依赖扫描逻辑,支持 Windows 环境下含空格路径、`.cmd` 脚本,并加入超时与健壮的错误处理机制。
- **智能项目隔离缓存**:重构了缓存架构,按项目根目录和包名进行强隔离,彻底解决临时文件污染工程根目录的问题。
- **企业级分发优化**:适配公网 npm/npx 分发,并针对 AI Agent 优化了 Tool Definitions,使其能更精准地自动按需触发。

## 适用场景
Cursor等AI工具直接生成调用二方(内部调用)、三方包(外部调用)接口的代码,但因AI无法读取未在当前工程中打开的依赖源码,导致生成的代码错误频出,甚至出现幻觉式编码。

为解决此问题,一般会直接拷贝源码内容喂给LLM;或者先将源码文件放到当前工程内,再在对话中引用。

而使用本地反编译MCP方案最有效,能精准解析jar包中的类与方法,显著提升代码生成的准确性和可用性。

## 功能特性

- 🚀 **使用方便**:mcp服务基于TypeScript实现,使用npm打包,方便分发和安装,弱环境依赖。
- 🔍 **依赖扫描**: 自动扫描Maven项目的所有依赖JAR包
- 📦 **类索引**: 建立类全名到JAR包路径的映射索引
- 🔄 **反编译**: 使用CFR工具(已内置有)实时反编译.class文件为Java源码
- 📊 **类分析**: 分析Java类的结构、方法、字段、继承关系等
- 💾 **智能缓存**: 按包名结构缓存反编译结果,支持缓存控制
- 🚀 **自动索引**: 执行分析前自动检查并创建索引
- ⚙️ **灵活配置**: 支持外部指定CFR工具路径
- 🤖 **LLM集成**: 通过MCP协议为LLM提供Java代码分析能力

## 使用示例
### 在IDE中注册mcp服务
![工具列表](./doc/mcp-tools.png)

### 在智能体对话中使用mcp
![示例](./doc/mcp-use-case.png)

## 使用说明

### mcp服务安装

**推荐方式**:直接在 MCP 客户端配置文件中添加以下配置:

```json
{
  "mcpServers": {
    "java-class-analyzer": {
      "command": "npx",
      "args": [
        "-y",
        "@jianxiancyf/java-class-analyzer-mcp-server@latest",
        "start",
        "--stdio"
      ],
      "env": {
        "npm_config_registry": "https://registry.npmjs.org/",
        "NODE_ENV": "production"
      }
    }
  }
}
```

**可选方式**:
- 全局安装:
  ```bash
  npm install -g @jianxiancyf/java-class-analyzer-mcp-server
  ```
- 本地安装:
  ```bash
  npm install @jianxiancyf/java-class-analyzer-mcp-server
  ```


### 可选环境变量

在配置的 `env` 中可以添加以下可选环境变量:

- `MAVEN_REPO`: Maven 本地仓库路径(默认:`~/.m2/repository`)
- `JAVA_HOME`: Java 安装路径(默认:使用 PATH 中的 java)
- `CFR_PATH`: CFR 反编译工具路径(默认:使用内置版本)

示例(添加可选环境变量):
```json
{
  "mcpServers": {
    "java-class-analyzer": {
      "command": "npx",
      "args": [
        "-y",
        "@jianxiancyf/java-class-analyzer-mcp-server@latest",
        "start"
      ],
      "env": {
        "npm_config_registry": "https://registry.npmjs.org/",
        "NODE_ENV": "production",
        "MAVEN_REPO": "D:/maven/repository",
        "JAVA_HOME": "C:/Program Files/Java/jdk-11"
      }
    }
  }
}
```

### 可选:SSE 传输方式

如果需要使用 SSE 方式(需要手动启动服务器):

1. 手动启动服务器:
```bash
java-class-analyzer-mcp start --sse --port 6666
```

2. 在客户端配置中使用 URL:
```json
{
  "mcpServers": {
    "java-class-analyzer": {
      "url": "http://localhost:6666/sse",
      "env": {
        "npm_config_registry": "https://registry.npmjs.org/",
        "NODE_ENV": "production"
      }
    }
  }
}
```

### 让Cursor Agent自动使用MCP工具

为了让Cursor Agent在识别到三方依赖时自动使用MCP工具(无需手动指定),请按以下步骤配置:

1. **确保MCP服务器已正确配置**(参考上面的配置说明)

2. **创建 `.cursorrules` 文件**(项目根目录):
   项目已包含 `.cursorrules` 文件,其中定义了自动使用MCP工具的规则。Cursor Agent会根据这些规则自动识别需要使用MCP的场景。

3. **工具描述已优化**:
   MCP工具的描述已优化,明确说明了何时应该自动使用这些工具,AI会更容易识别触发场景。

4. **自动触发场景**:
   - 代码中出现 `import` 三方包时
   - 生成调用三方库API的代码时
   - 需要了解三方类的结构、方法签名时
   - 错误排查涉及三方依赖时

### 可用的工具

#### 1. scan_dependencies
扫描Maven项目的所有依赖,建立类名到JAR包的映射索引。当需要分析三方依赖类时,应先执行此工具建立索引。

**参数:**
- `projectPath` (string): Maven项目根目录路径
- `forceRefresh` (boolean, 可选): 是否强制刷新索引,默认false

**示例:**
```json
{
  "name": "scan_dependencies",
  "arguments": {
    "projectPath": "/path/to/your/maven/project",
    "forceRefresh": false
  }
}
```

#### 2. decompile_class
反编译指定的Java类文件,返回Java源码。**当代码中使用了三方依赖类(如import语句、类引用),或需要查看三方类的实现细节、方法签名时,Cursor Agent应自动使用此工具**,获取准确的类信息,避免生成错误的代码。

**参数:**
- `className` (string): 要反编译的Java类全名,如:com.example.QueryBizOrderDO
- `projectPath` (string): Maven项目根目录路径
- `useCache` (boolean, 可选): 是否使用缓存,默认true。避免每次都重复生成。
- `cfrPath` (string, 可选): CFR反编译工具的jar包路径。已内置有,可以额外指定版本。

**示例:**
```json
{
  "name": "decompile_class",
  "arguments": {
    "className": "com.example.QueryBizOrderDO",
    "projectPath": "/path/to/your/maven/project",
    "useCache": true,
    "cfrPath": "/path/to/cfr-0.152.jar"
  }
}
```

#### 3. analyze_class
分析Java类的结构、方法、字段等信息。**当需要了解三方依赖类的API(方法名、参数类型、返回类型、字段定义)时,Cursor Agent应自动使用此工具**。特别适用于生成调用三方库代码的场景,确保方法签名和参数类型完全正确。

**参数:**
- `className` (string): 要分析的Java类全名
- `projectPath` (string): Maven项目根目录路径

**示例:**
```json
{
  "name": "analyze_class",
  "arguments": {
    "className": "com.example.QueryBizOrderDO",
    "projectPath": "/path/to/your/maven/project",
  }
}
```

### 缓存文件
在当前工程,会生成以下缓存目录和文件。
- `.mcp-class-index.json`: 类索引缓存文件
- `.mcp-decompile-cache/`: 反编译结果缓存目录(按包名结构)
- `.mcp-class-temp/`: 临时文件目录(按包名结构)

## 工作流程

1. **自动索引**: 首次调用`analyze_class`或`decompile_class`时,自动检查并创建索引
2. **智能缓存**: 反编译结果按包名结构缓存,支持缓存控制
3. **分析类**: 使用`analyze_class`或`decompile_class`获取类的详细信息
4. **LLM分析**: 将反编译的源码提供给LLM进行代码分析

## 技术架构

### 核心组件

- **DependencyScanner**: 负责扫描Maven依赖和建立类索引
- **DecompilerService**: 负责反编译.class文件
- **JavaClassAnalyzer**: 负责分析Java类结构
- **MCP Server**: 提供标准化的MCP接口

### 依赖扫描流程

1. 执行`mvn dependency:tree`获取依赖树
2. 解析每个JAR包,提取所有.class文件
3. 建立"类全名 -> JAR包路径"的映射索引
4. 缓存索引到`.mcp-class-index.json`文件

### 反编译流程

1. 根据类名查找对应的JAR包路径
2. 检查缓存,如果存在且启用缓存则直接返回
3. 从JAR包中提取.class文件到`.mcp-class-temp`目录(按包名结构)
4. 使用CFR工具反编译.class文件
5. 保存反编译结果到缓存`.mcp-decompile-cache`目录(按包名结构)
6. 返回Java源码

## 故障排除

### 常见问题

1. **Maven命令失败**
   - 确保Maven已安装并在PATH中
   - 检查项目是否有有效的pom.xml文件

2. **CFR反编译失败**
   - 确保CFR jar包已下载(支持任意版本号)
   - 检查Java环境是否正确配置
   - 可通过`cfrPath`参数指定CFR路径

3. **类未找到**
   - 程序会自动检查并创建索引
   - 检查类名是否正确
   - 确保项目依赖已正确解析

## 测试说明

### 构建项目

```bash
npm install
npm run build
```

### 测试工具使用

项目提供了独立的测试工具,可以直接测试MCP服务的各个功能,无需通过MCP客户端。

```bash
# 测试所有工具
node test-tools.js

# 测试特定工具
node test-tools.js --tool decompile_class --class com.alibaba.excel.EasyExcelFactory --project /path/to/project

# 不使用缓存
node test-tools.js --tool decompile_class --no-cache

# 指定CFR路径
node test-tools.js --tool decompile_class --cfr-path /path/to/cfr.jar
```

### 测试工具参数

- `-t, --tool <工具名>`: 指定要测试的工具 (scan|decompile|analyze|all)
- `-p, --project <路径>`: 项目路径
- `-c, --class <类名>`: 要分析的类名
- `--no-refresh`: 不强制刷新依赖索引
- `--no-cache`: 不使用反编译缓存
- `--cfr-path <路径>`: 指定CFR反编译工具的jar包路径
- `-h, --help`: 显示帮助信息

### 日志级别控制

通过 `NODE_ENV` 环境变量控制日志输出:

- `development`: 输出详细调试信息
- `production`: 只输出关键信息

## 更新日志

### v1.0.3 (feature/sse分支)

#### 🚀 新增功能

- **JDK类支持**:完整支持Java标准库类的扫描和反编译
  - 支持Java 8及之前的`rt.jar`扫描
  - 支持Java 9+模块化JDK(`jrt://`文件系统)的类扫描
  - 自动检测JDK版本并使用相应的扫描策略
  - 使用Java命令访问`jrt://`文件系统,支持所有JDK模块类

- **内置CFR工具**:内置CFR 0.152版本jar包(`lib/cfr-0.152.jar`)
  - 无需单独下载CFR工具即可使用
  - 优先检查`CFR_PATH`环境变量
  - 改进CFR查找路径,支持npm包安装后的路径结构
  - 仍支持通过`CFR_PATH`环境变量指定自定义CFR路径

#### 🔧 核心改进

- **Maven命令执行优化**:
  - 使用`spawn`替代`exec`,正确处理包含空格的路径
  - Windows平台特殊处理:支持`.cmd`文件和包含空格的路径
  - 改进错误处理和超时机制(60秒超时)
  - 更好的跨平台兼容性

- **JAR包解析增强**:
  - 处理JAR包中的绝对路径条目(跳过以`/`开头的无效条目)
  - 支持`.jmod`文件格式(Java模块文件,处理`classes/`目录结构)
  - 改进错误处理:单个条目处理失败不中断整个流程
  - 处理`absolute path`错误,避免因无效条目导致解析失败
  - 跳过内部类(包含`$`符号的类文件)

- **缓存路径优化**:
  - 使用项目路径作为缓存根目录,而不是`process.cwd()`
  - 统一管理临时文件目录(`.mcp-class-temp`)
  - 临时Java文件统一放在项目缓存目录下,避免污染根目录
  - 改进缓存路径结构,按包名组织

- **工具描述优化**:优化MCP工具的描述文本,使AI更容易自动识别和使用
  - `scan_dependencies`: 明确说明在缺类/引入三方或JDK类时自动调用
  - `decompile_class`: 明确说明在需查看依赖或JDK类实现时自动调用
  - `analyze_class`: 明确说明在需生成调用代码或确认签名时自动调用

- **错误处理改进**:
  - 更详细的错误信息和警告提示
  - 索引文件验证:检查索引文件是否存在且有效
  - 工具调用异常处理:提供友好的错误提示和建议
  - stdio模式下完全静默,避免干扰MCP协议通信

- **版本管理**:从package.json动态读取版本号,确保版本一致性

#### 🐛 Bug修复

- **修复Maven命令执行问题**:
  - 修复Windows平台路径包含空格时命令执行失败的问题
  - 修复`.cmd`文件无法执行的问题
  - 修复超时处理不生效的问题

- **修复JAR包解析问题**:
  - 修复JAR包包含绝对路径条目导致解析失败的问题
  - 修复`.jmod`文件无法解析的问题
  - 修复单个条目处理失败导致整个JAR解析失败的问题
  - 修复内部类被错误包含的问题

- **修复JDK类扫描问题**:
  - 修复Java 9+模块化JDK无法扫描的问题
  - 修复JDK类无法反编译的问题
  - 修复`jrt://`文件系统访问问题

- **修复CFR工具查找问题**:
  - 修复npm包安装后CFR工具找不到的问题
  - 修复CFR_PATH环境变量不生效的问题
  - 改进CFR查找路径优先级

- **修复缓存路径问题**:
  - 修复缓存文件保存到错误位置的问题
  - 修复临时文件污染根目录的问题

- **修复其他问题**:
  - 修复索引文件为空时的处理问题
  - 修复类查找超时无提示的问题
  - 修复错误信息不够详细的问题

#### 📦 依赖更新

- `archiver`: `^6.0.1` → `^7.0.1`
- `jest`: `^29.7.0` → `^30.2.0`
- `@types/jest`: `^29.5.8` → `^30.0.0`
- 新增`overrides`配置:强制使用`glob ^10.0.0`

#### 📝 文档更新

- 添加"让Cursor Agent自动使用MCP工具"章节
- 完善工具使用说明,强调自动触发场景
- 添加致谢章节
- 更新配置示例,说明默认使用SSE模式

#### 📁 文件变更

- 新增:`.cursorignore` - Cursor忽略文件配置
- 新增:`lib/cfr-0.152.jar` - 内置CFR工具
- 删除:`mcp-server-config.json` - 配置文件模板(改为通过CLI命令生成)
- 修改:`src/index.ts` - 改进错误处理、工具描述优化
- 修改:`src/cli.ts` - 版本号动态读取、改进配置生成
- 修改:`src/scanner/DependencyScanner.ts` - JDK类支持、Maven命令优化、JAR解析增强
- 修改:`src/decompiler/DecompilerService.ts` - JDK模块类反编译、CFR查找优化、缓存路径优化
- 修改:`package.json` - 更新版本号和依赖
- 修改:`.gitignore` - 更新忽略规则