Important: The original code and documentation of this project is still available under the branch: https://github.com/snowdrop/migration-tool/tree/1.x
This project provides tooling to analyze, scan, and validate Java applications targeted for migration — primarily from Spring Boot to Quarkus. It exposes its capabilities as a Quarkus MCP server, enabling AI agents to leverage the tool's analysis and validation features through the Model Context Protocol. While the architecture is designed to support migration from any technology A to B, the current focus is Spring Boot to Quarkus.
- Query: A simplified syntax (parsed using Antlr grammar) to define matching conditions with
AND/ORoperators against Java annotations, POM dependencies, properties, etc. The query language could be extended in a future release to configure validators using YAML specifications. - Validator: A validator verifies whether specific migration conditions are met for a given project (e.g. project setup, persistence layer). Validators are discovered at runtime from the classpath and can be invoked via the CLI or the MCP server.
- Analysis report: The analysis report generated by the rule engine contains issues describing what the tool or user should do, when it should be applied and for which purpose.
- MCP Server: A Quarkus MCP server that exposes the tool's analyze and validate capabilities as MCP tools, allowing AI agents to interact with the migration tool programmatically.
- Provider: A system able to execute the transformation instructions defined as part of a rule where the condition(s) matched. Supported providers: OpenRewrite recipe and manual.
- Rule: A rule defines what the tool should search for within the code source of the scanned project (matching conditions) and optionally includes instructions to be executed by a provider during transformation. Rules are defined in YAML and could be used in a future release to configure validators and define migration plans.
The project has been designed using the following technologies:
- Quarkus MCP server to expose analyze and validate tools to AI agents when running SKILL instructions (module:
mcp)
- Antlr as parser tool to generate the code for the query language used to
matchconditions (module:parser)
- Treesitter4j for fast, accurate source code analysis: java, properties, json, yaml, etc (module:
scanner) - JavaParser for Java source parsing and entity comparison (modules:
scanner,service) - Maven to discover POM dependencies by executing Maven commands (module:
scanner)
- OpenRewrite recipes to execute the transformations as defined in the rule's instructions (module:
openrewrite-recipes)
This project supports a query language able to define using a human-readable syntax what to search part of the different resources: properties, code source, JSON, YAML or dependencies. The language is used by the CLI commands: scan or analyze like the scanners and will translate the query into the technical parameters expected by the scanner called: TreeSitter4j, JavaParser, Maven or OpenRewrite.
The grammar of the query is defined using ANTLR and supports simple clauses or multiple clauses separated with AND / OR operators:
grammar Query;
searchQuery: operation;
operation
: operation AND operation #AndOperation
| operation OR operation #OrOperation
| clause #SimpleClause
;
clause: fileType ('.' symbol)? ('is' | '=') (value | '(' keyValuePair (',' keyValuePair)* ')');
fileType: 'JAVA' | 'java' | 'POM' | 'pom' | 'TEXT' | 'text' | 'PROPERTY' | 'property' | 'YAML' | 'yaml' | 'JSON' | 'json';Examples:
when:
condition: java.annotation is 'org.springframework.boot.autoconfigure.SpringBootApplication'
condition: |
java.annotation is 'org.springframework.stereotype.Controller' OR
java.annotation is 'org.springframework.web.bind.annotation.GetMapping'
condition: |
pom.dependency is (gavs='org.springframework.boot:spring-boot-starter-web') AND
java.annotation is 'org.springframework.stereotype.Controller'- Java 21 installed and Maven 3.9
Install the tool using the jbang tool and the following command:
jbang app install mtool@snowdrop/migration-toolNote
To install a released version, append the version
jbang app install mtool@snowdrop/migration-tool/2.0.0Otherwise, if you plan to contribute to the project, git clone and compile it
mvn clean install -DskipTestsThe Migration Tool CLI (aka mtool) proposes the following commands. For AI agent usage via MCP, see the AI — MCP Server section.
Usage: mtool [-hV] [COMMAND]
Quarkus mtool client able to scan, analyze and migrate a java application
-h, --help Show this help message and exit.
-V, --version Print version information and exit.
Commands:
analyze Analyze a project for migration
validate Validate that a migration is correct and complete
scan Scan an application against a query or a plan
transform Transform a java applicationTo check the installed version:
mtool --versionTo analyze an application to be migrated, it is needed to define, using a YAML file, rules. A rule defines the contract between what to discover in the code source and what a provider should do to transform it.
Key fields:
order: The execution order within the migration planwhen: Matching conditions using the query language(pre)condition: Eligibility check before the main conditions are evaluatedinstructions: Tasks to be executed by the selected provider
Note: The (pre)condition are defined using a human-readable fluent query syntax processed by the Antlr parser. See: query language
- ruleID: springboot-annotations-to-quarkus-00000
category: mandatory
description: Replace the Spring Boot Application Annotation with QuarkusMain
labels:
- source=springboot
- target=quarkus
message: "Replace the Spring Boot Application Annotation with QuarkusMain"
when:
precondition: |
pom.dependency is (gavs='org.springframework.boot:spring-boot-starter-parent:3.5.3')
condition: |
java.annotation is 'org.springframework.boot.autoconfigure.SpringBootApplication'
order: 2
instructions:
manual:
- todo: "Remove the @SpringBootApplication annotation from the main class"
openrewrite:
- name: Migrate Spring Boot to Quarkus
preconditions:
- name: org.openrewrite.java.dependencies.search.ModuleHasDependency
groupIdPattern: org.springframework.boot
artifactIdPattern: spring-boot
version: '[3.5,)'
recipeList:
- dev.snowdrop.mtool.openrewrite.recipe.ReplaceSpringBootApplicationAnnotationWithQuarkusMain
- spring.recipe.dev.snowdrop.mtool.openrewrite.AddQuarkusRun
gav:
- dev.snowdrop.mtool:openrewrite-recipes:2.0.0-SNAPSHOTScan the code source using the rules matching conditions and generate a JSON report augmented with the provider's instructions.
Usage: mtool analyze [-v] [-o=<output>] [-r=<rulesPath>] [-s=<source>]
[--scanner=<scanner>] [-t=<target>] <appPath>
Analyze a project for migration
<appPath> Path to the Java project to analyze
-o, --output=<output> Export the analysing result using the format.
Values: json
-r, --rules=<rulesPath> Path to rules directory (default: from config)
-s, --source=<source> Source technology to consider for analysis
--scanner=<scanner> Scanner tool to be used to analyse the code:
openrewrite (default)
-t, --target=<target> Target technology to consider for analysis
-v, --verbose Enable verbose outputExample:
mtool analyze -r ./cookbook/rules/quarkus-spring ./applications/spring-boot-todo-app
mvn -pl migration-cli quarkus:dev -Dquarkus.args="analyze ../applications/spring-boot-todo-app"By default, the tool generates a JSON report file: analysing-report_yyyy-mm-dd_hh:mm.json. Use -o html for HTML output.
The tool supports different scanners:
- openrewrite recipe (default)
- treesitter
- maven
- file and content search
A scanner can be selected with the --scanner option. The tool will use it as default but will fall back to alternative scanners if the selected one doesn't support the query type.
Execute a query against an application to search for Java annotations, POM dependencies, properties, etc.
mtool scan <appPath> <query>Using queries:
java.annotation is 'org.springframework.boot.autoconfigure.SpringBootApplication'
pom.dependency is (gavs='org.springframework.boot:spring-boot-starter-web')You can also combine queries in a YAML plan file:
mtool scan <appPath> --plan <planPath>/java-app.yml --scanner treesitterExample YAML plan:
name: java-application
queries:
- find all java.class
- find all java.annotation
- find all java.import
- find all properties
- find all pom.dependenciesValidate that a Spring-to-Quarkus migration is correct and complete. Available validators:
- project-setup — checks that the project compiles and has the expected structure
- persistence — compares JPA entities between the original Spring project and the migrated Quarkus project to detect missing entities, field mismatches, ID strategy changes, and relationship differences
Usage: mtool validate [-v] [--skip-compile] [--parser=<parser>]
[--spring-project=<springProjectPath>]
<validatorName> <appPath>
Validate that a migration is correct and complete
<validatorName> Validator to run (e.g. project-setup, persistence)
<appPath> Path to the project to validate
--parser=<parser> Java parser to use: treesitter (default) or javaparser
--skip-compile Skip the mvn compile check
--spring-project=<springProjectPath>
Path to the original Spring project
(required for persistence validator)
-v, --verbose Enable verbose outputExample:
mtool validate persistence ./applications/spring-jpa-crud-quarkus --spring-project ./applications/spring-jpa-crudApply the transformation instructions using as input the JSON analysis report by using the chosen provider.
Usage: mtool transform [-dv] [-p=<provider>] <appPath>
Transform a java application
<appPath> Path to the Java project to transform
-d, --dry-run Execute OpenRewrite in dry-run mode (preview changes without
applying them)
-p, --provider=<provider>
Migration provider to use (openrewrite, manual). Default:
from migration.provider property
-v, --verbose Enable verbose outputNote
The default provider is openrewrite but you can also use manual
To use OpenRewrite, execute the transform command with or without --dry-run mode. In dry-run mode, OpenRewrite generates rewrite.patch file(s) under target/rewrite instead of modifying the code directly.
mtool transform ../applications/spring-boot-todo-app -p openrewrite --dry-runMigrate the Spring Boot Todo Application to Quarkus step by step.
Git clone this project and compile it:
mvn clean package -DskipTests- Analyze the project to generate the migration report:
mtool analyze ../applications/spring-boot-todo-app -r ../cookbook/rules/quarkus-spring --scanner openrewrite- Preview the transformation (dry-run mode):
mtool transform ../applications/spring-boot-todo-app -p openrewrite --dry-run- Apply the transformation:
mtool transform ../applications/spring-boot-todo-app -p openrewriteNote
We recommend creating a git branch within the "spring-boot-todo-app" to revert to the previous state if needed
- Run the migrated Quarkus application:
cd applications/spring-boot-todo-app
mvn package quarkus:dev -DskipTestsNote
Podman or Docker must be installed locally as Quarkus will launch a MySQL TestContainer for the Todo DB.
- Test the REST endpoints:
curl http://127.0.0.1:8080/home
curl -X POST http://localhost:8080/home \
-H "Content-Type: application/json" \
-d '{
"title": "Prepare migration to Quarkus. Step 3",
"description": "Analyser le projet et lister toutes les dependances Spring Data.",
"dueDate": "2025-12-24"
}'The migration tool includes a Quarkus MCP server that exposes its different capabilities (analyze, validate, ...) as MCP tools. AI agents can use these tools to programmatically analyze source code, discover annotations/dependencies, and validate migration correctness.
Before using the MCP server with an AI agent, we recommend locally to use and install the Smallrye ACP client (>= 0.2.1) as you will be able to use your favorite agent and launch the MCP server with just a few parameters:
jbang app install --name acp io.smallrye.ai:acp-java-client:0.2.1:runnerInstall an AI agent from the ACP registry:
acp registry install claude-acpNote: Use the command acp registry list -r to get the full list of ACP agents !
mvn package -pl mcpRun the MCP server in stdio mode and ask the agent to analyze a project:
acp run \
-a claude-acp \
--backup no \
--mcp-server-config '{"type":"stdio","name":"mtools","command":"java","args":["-jar", "./mcp/target/mcp-2.0.0-SNAPSHOT-runner.jar"]}' \
-p "The Project path of the code to analyze using the MCP tool: sourceAnalyze is: ./applications/spring-boot-todo-app"Run the validate tool to check that a migration from Spring to Quarkus is correct:
acp run \
-a claude-acp \
--backup no \
-s ./mcp/skills/validate/SKILLS.md \
--mcp-server-config '{"type":"stdio","name":"mtools","command":"java","args":["-jar", "./mcp/target/mcp-2.0.0-SNAPSHOT-runner.jar"]}' \
-p "Validate the migration of the spring project: ./applications/spring-jpa-crud against the quarkus project: ./applications/spring-jpa-crud-quarkus. Only run the validator: persistence"The MCP server restricts tool access to a set of allowed directories, following the MCP local server security convention. By default, the current working directory (.) is allowed. Override with -Dmtool.allowed-dirs:
--mcp-server-config '{"type":"stdio","name":"mtools","command":"java","args":["-Dmtool.allowed-dirs=./applications,/tmp/projects", "-jar", "./mcp/target/mcp-2.0.0-SNAPSHOT-runner.jar"]}'The analyze or transform commands can be executed using the Quarkus uber jar. Create an .env file to configure the properties:
# .env file content
ANALYZER_RULES_PATH=cookbook/rules
ANALYZER_RULES_REPO_URL=https://github.com/snowdrop/migration-tool/blob/main/cookbook/rules/quarkus-spring/%s.yamlThen source it and execute:
java -jar <MIGRATION_CLI_JAR_PATH> analyze $(pwd)/applications/spring-boot-todo-app -o json
java -jar <MIGRATION_CLI_JAR_PATH> transform $(pwd)/applications/spring-boot-todo-app -p openrewrite --dry-runTo test OpenRewrite recipes separately, use the maven plugin on a Spring Boot project:
cd applications/spring-boot-todo-app
mvn -U org.openrewrite.maven:rewrite-maven-plugin:dryRun \
-Drewrite.recipeArtifactCoordinates=dev.snowdrop.mtool:openrewrite-recipes:2.0.0-SNAPSHOT \
-Drewrite.activeRecipes=spring.recipe.dev.snowdrop.mtool.openrewrite.ReplaceSpringBootApplicationWithQuarkusMainAnnotation