JVM Source Lens
Resuelve el classpath real de tu proyecto Gradle y devuelve código fuente Java, firmas de métodos y estructura de clases para cualquier clase de dependencia, usando la versión que tu compilación realmente utiliza, no archivos aleatorios de ~/.gradle/caches.
Documentación
jvmsrc — Dale a tu agente de codificación un IDE de Java
Un servidor MCP y CLI que le da a tu agente de codificación lo único que le falta en proyectos JVM: el classpath real.
El Problema
Usas un IDE para escribir Java. Tu agente de codificación no tiene uno.
Cuando tu agente se encuentra con un tipo de librería desconocido — por ejemplo, una superclase de una librería interna propietaria — gasta más de 25 turnos recorriendo ~/.gradle/caches, abriendo JARs manualmente con jar tf, eligiendo uno a ciegas, e intentando responder una pregunta que tu IDE respondería con una sola pulsación: ¿tiene esta superclase un método utilitario público llamado X?
La Solución
jvmsrc consulta tu herramienta de compilación (Gradle) para obtener el classpath resuelto de este proyecto, y luego entrega a tu agente código fuente real, firmas reales y estructura real — para la versión exacta que tu compilación realmente usa.
- Como servidor MCP – Conéctalo a Claude Code, Cursor, Windsurf, o cualquier otro host MCP y equipa a tu agente con seis herramientas de classpath diseñadas específicamente.
- Como CLI
jvmsrc– El mismo motor, scripteable, compatible con pipes, y útil por sí solo cuando solo quieres leer una clase.
Claude Code resolviendo firmas de HandlerInterceptor mediante jvmsrc — 3 llamadas, respuesta correcta, sin recorrer caché.
Lo que ahorra, a diario
En proyectos JVM con librerías privadas y sin Javadocs públicos, jvmsrc es un multiplicador de fuerza:
- ~50K tokens ahorrados por investigación de "qué hay en esta clase externa" — aproximadamente 70% de reducción en costos.
- Más de 15 bucles de pánico del agente evitados al día — sin triturar cachés de Gradle, abrir JARs equivocados, o rendirse.
- Desbloquea la delegación de tareas complejas que tocan SDKs internos que antes tenías que hacer tú mismo.
La Diferencia en Acción
Sin jvmsrc (El molino ciego de 25 turnos)
Usuario: Sobrescribe el hook de auditoría de
AbstractTradingService— ¿hay un método utilitario público en él que deberíamos reutilizar?Agente:
- Busca en el espacio de trabajo AbstractTradingService.java ➔
0 hits- Ejecuta:
find ~/.gradle -name "trading-core*"- Encuentra 4 versiones:
2.1.0,2.3.0,2.4.1,3.0.0-SNAPSHOT- Adivina: Elige
trading-core-2.4.1.jar(¡el proyecto realmente usa3.0.0-SNAPSHOT!)- Ejecuta:
jar tfyjavap -pen el JAR equivocado- [22 turnos después] "No veo un método utilitario, tendrás que implementarlo tú mismo."
Realidad:
3.0.0-SNAPSHOTañadiómaskSensitiveFields()como helper protegido exactamente para este caso. El agente no alucinó — simplemente estaba ciego.
Con jvmsrc (La resolución instantánea de 3 turnos)
Usuario: Sobrescribe el hook de auditoría de
AbstractTradingService— ¿hay un método utilitario público en él que deberíamos reutilizar?Agente:
search_classes("AbstractTradingService")➔ Encuentra el FQN y la librería resuelta exacta.get_class_structure(scope: "overview")➔ DescubremaskSensitiveFields()en3.0.0-SNAPSHOT.get_method_signature("maskSensitiveFields")➔ Obtiene la firma precisa y los genéricos.Resultado: Escribe la sobrescritura correctamente al primer intento. Sin recorrer caché, sin adivinar, sin versión equivocada.
Cómo Funciona
- Consulta a la Herramienta de Compilación:
jvmsrcconsulta tu herramienta de compilación activa (por ejemplo, Gradle) para obtener la configuración exacta del classpath resuelto. - Caché Inteligente: Almacena en caché el classpath resuelto, rastreando cambios en los archivos de compilación para mantenerse actualizado.
- Herramientas de IA de Precisión: En lugar de volcar código completo, expone herramientas precisas y de alta granularidad (firmas, estructura, búsqueda) para mantener las ventanas de contexto pequeñas y el uso de tokens ultrabajo.
Instalación y Inicio Rápido
1. Instalar CLI
npm install -g jvmsrc
O úsalo directamente con npx:
npx jvmsrc mcp
[!IMPORTANTE]
Requiere Node ≥ 20 y Java enPATH(para el descompilador CFR +javap).
2. Añadir el servidor MCP
Pega esto en la configuración de tu asistente de IA (Cursor, Claude Code, Windsurf, etc.), y luego reinicia el host:
{
"mcpServers": {
"jvmsrc": {
"command": "jvmsrc",
"args": ["mcp"]
}
}
}
Opcional: jvmsrc config (o jvmsrc config --project /path/to/gradle-project) imprime un bloque listo para pegar más sugerencias de entorno. La mayoría de los usuarios pueden omitirlo y copiar el fragmento de arriba.
Referencia del Servidor MCP
El servidor MCP se ejecuta sobre stdio mediante jvmsrc mcp. La configuración predeterminada no necesita variables de entorno:
{
"mcpServers": {
"jvmsrc": {
"command": "jvmsrc",
"args": ["mcp"]
}
}
}
Credenciales de repositorio privado (opcional)
Solo se necesitan cuando tu compilación de Gradle requiere variables de entorno de credenciales para un repositorio privado estilo Maven/Artifactory/Nexus. Los hosts MCP a menudo no heredan tu shell interactivo, por lo que esas variables deben establecerse en el proceso MCP de jvmsrc (luego reinicia el servidor).
REPO_USER / REPO_PASS a continuación son solo nombres de ejemplo — no son requeridos por jvmsrc. Usa los nombres de variables que documenten los scripts de Gradle de tu proyecto:
{
"mcpServers": {
"jvmsrc": {
"command": "jvmsrc",
"args": ["mcp"],
"env": {
"REPO_USER": "your-username",
"REPO_PASS": "your-password"
}
}
}
}
Omite el bloque env por completo cuando el proyecto no los necesite.
Herramientas que recibe tu agente
| Herramienta | Qué hace |
|---|---|
search_classes | Encuentra una clase por nombre simple o glob; devuelve listas compactas de FQN + nombre de librería |
get_class_structure | Recupera la vista general de la clase (propósito + nombres de métodos) o firmas declaradas |
get_method_signature | Obtiene las sobrecargas reales de un método, con nombres de parámetros y genéricos |
find_in_class_source | Realiza búsquedas regex o de subcadenas dentro de una clase resuelta |
get_class_source | Recupera cuerpos de métodos o rangos de líneas (usado como último recurso) |
search_in_artifact | Busca texto en todas las clases de un JAR de dependencia resuelto |
resolve_dependencies | Analiza el grafo de dependencias real que usa este proyecto |
[!CONSEJO]
Cada respuesta de fuente incluyesourceAvailable:truepara fuentes reales (Javadoc, nombres de parámetros, genéricos),falsepara descompilación CFR (estructura confiable, los nombres pueden ser sintéticos).
[!NOTA]
Multimódulo: omitemodulePathy jvmsrc elige automáticamente el módulo propietario único; si falla, lista losmodulePathcandidatos. Métodos:search_classescoincide con nombres de métodos declarados cuando el índice tiene enriquecimiento de fuente; para texto de cuerpo en un JAR conocido usasearch_in_artifact.get_class_sourcemethodNamestambién recorre superclases para nombres no coincidentes.
Cómo se Compara
| Herramienta | Enfoque | Brecha |
|---|---|---|
Indexadores de Caché / grep de ~/.gradle | Escanean cachés globales | Sin versión resuelta por proyecto |
Analizadores Estáticos (por ejemplo, parser de build.gradle) | Analizan solo declaraciones | Pierde dependencias transitivas, BOMs, versiones dinámicas |
mcp-javadoc / CFR solo por ruta | El usuario proporciona rutas JAR manuales | Sin resolución automática de compilación/classpath |
| Gradle MCP (Tooling API) | Enfocado en tareas/compilación | No optimizado para búsqueda de fuente FQN precisa de classpath |
jvmsrc | Consulta la herramienta de compilación real y almacena en caché | Fuentes y firmas correctas por versión para agentes |
Público Objetivo
Principalmente proyectos Java + Spring Boot en Gradle. Otros lenguajes JVM (Kotlin, Scala) y Android funcionan hoy con el mejor esfuerzo posible y están en la hoja de ruta como objetivos de primera clase — consulta ROADMAP.md.
Si usas Maven o Bazel, está planificado pero aún no disponible. Marca el repositorio con una estrella o abre un issue y lo priorizaré en consecuencia.
Referencia Detallada
Requisitos y Compatibilidad
Entorno de ejecución: Node.js ≥ 20, Java en PATH.
Tipos de proyecto: Proyectos JVM (Java, Kotlin, Scala, Groovy). jvmsrc llama a la herramienta de compilación, no a tu editor.
| Sistema de compilación | Estado |
|---|---|
| Gradle | Compatible — incluye multimódulo |
| Maven, Bazel | Planificado (SPEC.md) |
Apunta -p / projectRoot a la raíz de Gradle (settings.gradle(.kts) o build.gradle(.kts) raíz). Usa ./gradlew cuando esté presente, si no gradle en PATH. Los árboles solo-Maven reciben un error explícito de no compatibilidad.
Limitaciones Conocidas
Software temprano; la ruta compatible es limitada:
| Área | Hoy |
|---|---|
| Herramienta de compilación | Solo Gradle |
| Integración | Script init de Groovy (--init-script) — no un plugin del Portal de Gradle |
| Classpaths | JVM estándar + configuraciones jvm* de Kotlin MPP cuando Gradle las expone |
| Salida | Texto .java con forma de Java (JAR de fuentes, src entre proyectos, o CFR) |
Compilaciones compuestas, diseños solo-Android y configuraciones exóticas no están completamente validadas. Consulta ROADMAP.md.
Seguridad y Privacidad
- Sin telemetría.
- Solo local — los cachés y diagnósticos permanecen en disco; nunca escribe bajo la raíz de tu proyecto.
- Subprocesos solo mediante argv (sin interpolación de shell) — consulta SECURITY.md.
JVMSRC_ALLOWED_ROOTSopcional para restringir qué proyectos puede resolver jvmsrc.
Referencia de Comandos CLI
jvmsrc com.example.MyClass -p /path/to/gradle-project # shorthand for get
jvmsrc get com.example.MyClass -p /path/to/project -q > MyClass.java
jvmsrc resolve -p /path/to/project --force-refresh
jvmsrc config jdk-roots add /path/to/jdks # one-time JDK roots setup
jvmsrc doctor java -p /path/to/project # check JDK requirement + selection
jvmsrc diagnostics last # latest failure message
jvmsrc mcp # run as MCP server
Banderas útiles: -p / --project, --module (:core:api), --configuration, --include-test, --force-refresh, --verbose (solo stderr de Gradle), --method, --start-line / --end-line.
Fixture de repositorio para pruebas:
test/fixtures/gradle-smoke —
jvmsrc get com.smoke.Core -p test/fixtures/gradle-smoke --module :core.
Solución de Problemas
- Fallos de resolución: Ejecuta
jvmsrc diagnostics last(ojvmsrc diagnostics last 5) - Raíces de instalación de JDK personalizadas: Añade una vez con
jvmsrc config jdk-roots add /path/to/jdks - Depuración de discrepancia de JDK: Ejecuta
jvmsrc doctor java -p /path/to/project - Después de actualizar jvmsrc: Reinicia tu host MCP
- Classpath desactualizado: Ejecuta
jvmsrc resolve --force-refresh
Variables de Entorno
| Variable | Propósito |
|---|---|
JVMSRC_JAVA_HOME | Forzar el home de JDK para procesos hijos de Gradle/CFR |
JVMSRC_CONFIG_DIR | Directorio de configuración global de jvmsrc (absoluto) |
JVMSRC_CACHE_ROOT | Raíz de caché (absoluta) |
JVMSRC_LOG_DIR | Registros de diagnóstico (absolutos) |
JVMSRC_ALLOWED_ROOTS | Prefijos projectRoot permitidos |
JVMSRC_MAX_SOURCE_OUTPUT_CHARS | Tamaño máximo del cuerpo de fuente (predeterminado 524288) |
JVMSRC_GRADLE_TIMEOUT_MS | Tiempo de espera de Gradle |
JVMSRC_CFR_PATH | JAR de CFR personalizado |
Los valores predeterminados siguen las convenciones de env-paths por sistema operativo. Diseño completo: SPEC.md §6.
Cuando JVMSRC_JAVA_HOME no está establecido, jvmsrc descubre automáticamente JDKs locales desde rutas comunes como ~/.jdks (IntelliJ), ~/.gradle/jdks, SDKMan, jenv, asdf, y directorios de instalación del sistema específicos del SO, además de tus raíces JDK configuradas globalmente desde jvmsrc config jdk-roots ....
Reseñas de Agentes de IA
Finalmente, un MCP que no me hace descompilar JARs
"Esta herramienta es una revelación para cualquiera cansado de que los LLMs alucinen APIs de Spring inexistentes. Realmente lee bytecode, proporcionando definiciones de clase precisas y búsquedas de fuente sin la habitual adivinanza 'basada en vibraciones'. La funcionalidad
search_classeses increíblemente precisa, y la implementación cuidadosa del respaldojavapy los controles de alcance granulares (overview/declared/effective) hace que navegar JARs complejos sea sin dolor. Es rápido, honesto cuando no puede encontrar una clase, y maneja la gestión de caché perfectamente. Imprescindible para cualquier desarrollador que luche con el infierno de dependencias — es como tener un ingeniero senior que realmente disfruta leyendo documentación." — Claude (Revisor de IA)
Documentación del Proyecto
| Documento | Contenido |
|---|---|
| SPEC.md | Esquemas, contratos, detalles de CLI/MCP |
| CONTRIBUTING.md | Compilación, pruebas, notas de PR |
| RELEASING.md | Ramas, semver, publicaciones npm |
| CHANGELOG.md | Historial de versiones |
| ROADMAP.md | Estado y trabajo planificado |
| SECURITY.md | Reporte de vulnerabilidades |
Compilación desde el Código Fuente
git clone https://github.com/Sintexer/jvm-source-lens.git
cd jvm-source-lens
bun install && bun run setup:cfr && bun run build
node dist/cli.js --version
Flujo de trabajo completo para contribuidores: CONTRIBUTING.md.
Construí jvmsrc porque seguía encontrándome con el mismo obstáculo: agentes que son excelentes escribiendo Java pero ciegos al classpath real. Si te ahorra los mismos 25 turnos de idas y vueltas que me ahorró a mí, eso es exactamente por lo que esto existe. ¿Encontraste un error, tienes una idea o solo quieres decir que te ayudó? Abre un issue o un PR — leo todo.
Licencia
MIT — ver LICENSE.