-
Notifications
You must be signed in to change notification settings - Fork 15
MCP Tools
Explyt Spring ships Spring-aware MCP tools for the bundled JetBrains MCP Server in IntelliJ IDEA 2025.2+. They let agentic AI clients ask the IDE for structured Spring context instead of relying only on generic file search — which means fewer broad tool calls, lower token usage, and more accurate Spring-specific answers.
Requires IntelliJ IDEA 2025.2+ with the bundled JetBrains MCP Server. Works with AI clients that can connect to the IntelliJ IDEA MCP Server, including Explyt AI.
Looking for AI-augmented editor actions (entity↔DTO, schema→entity, etc.) instead? See Explyt AI Actions.
A generic agent answers "which controller handles GET /api/stores/{storeId}/orders?" by grepping for the URL — which fails when the path is split across annotations:
@RequestMapping("/api/stores/{storeId}/orders") // on the class
@GetMapping("/{orderId}/items") // on the methodNo text search matches the composed path, so the agent falls back to guessing file names and reading candidates — typically 3–8 exploratory calls per question. Explyt's MCP tools answer the same questions in one call, using the IDE's real Spring index:
- Which Spring Boot apps are in this workspace, and which beans do they define?
- Which endpoint handles this URL, and what is its full request/response contract?
- Which service/repository methods does a controller call — and which tests reference them?
- How do JPA entities map to tables, columns, and relationships?
The example I/O below is representative (a neutral
ordersdomain) — exact fields may evolve. Tool behavior is implemented inSpringMcpProvider.kt.
Lists Spring Boot applications in the current workspace, including detected Spring Boot versions and starters. Use it when an agent first enters a multi-module workspace and needs the right application context before calling the other tools.
Example output
[
{
"fullyQualifiedClassName": "com.example.OrdersApplication",
"springBootVersion": "3.3.4",
"springBootStarters": ["spring-boot-starter-web", "spring-boot-starter-data-jpa"],
"moduleName": "orders-service.main",
"buildTool": "gradle"
}
]Returns the beans for a selected Spring Boot application, filtered by a bean type — CONTROLLER, REPOSITORY, CONFIGURATION, COMPONENT, CONFIGURATION_PROPERTIES, AUTO_CONFIGURATION, ASPECT, or MESSAGE_MAPPING — without searching every source file for stereotypes. Pass the application's fully-qualified class name (from explyt_get_spring_boot_applications) and the beanType.
Example output (beanType = REPOSITORY)
[
{ "beanName": "orderRepository", "className": "com.example.repo.OrderRepository", "moduleName": "orders-service.main" },
{ "beanName": "orderItemRepository", "className": "com.example.repo.OrderItemRepository", "moduleName": "orders-service.main" }
]Turn a URL into the exact handler method. This is the most common entry point for backend work: almost every full-stack task starts from a URL (a browser, frontend code, a bug report).
Problem it solves. A plain search for orders/{orderId}/items returns 0 results when the path is composed from a class-level @RequestMapping plus a method-level @GetMapping. The agent then burns several calls guessing controller file names and reading them.
Input: an optional HTTP method, a urlPattern, and the project path. Matching is forgiving — it matches against the composed path, supports substring/fuzzy matching, and ignores path-variable names ({orderId} matches {id} matches any segment).
Matches across all endpoint types: Spring MVC, WebFlux, JAX-RS, HttpExchange, OpenFeign, OpenAPI, message brokers (Kafka/RabbitMQ listeners), and event listeners.
Example output (a bare array of matches)
[
{
"httpMethods": ["GET"],
"fullPath": "/api/stores/{storeId}/orders/{orderId}/items",
"controllerClass": "com.example.api.OrderItemsController",
"methodName": "items",
"filePath": "src/main/kotlin/.../OrderItemsController.kt",
"line": 23,
"parameters": [
{ "name": "storeId", "source": "PATH", "type": "java.lang.String", "required": true },
{ "name": "orderId", "source": "PATH", "type": "java.lang.String", "required": true },
{ "name": "page", "source": "QUERY", "type": "java.lang.String", "required": false }
],
"returnType": "com.example.api.dto.OrderItemsResponse",
"endpointType": "Spring MVC"
}
]Cost: ~3–5 exploratory calls today → 1 call.
Lists all HTTP endpoints in the project (or for a given application), optionally filtered by controller class name or endpoint type (SPRING_MVC, SPRING_WEBFLUX, SPRING_JAX_RS, …). Best for "give me the whole API surface."
Returns endpoints (a per-endpoint summary: HTTP methods, full path, controller, method name, return type, file location, endpoint type), totalCount (how many matched the filters), and truncated (true when matches exceed the result cap, so the list is incomplete — narrow it with the filters).
Example output
{
"totalCount": 2,
"truncated": false,
"endpoints": [
{
"httpMethods": ["GET"],
"fullPath": "/api/stores/{storeId}/orders/{orderId}/items",
"controllerClass": "com.example.api.OrderItemsController",
"methodName": "items",
"filePath": "src/main/kotlin/.../OrderItemsController.kt",
"line": 23,
"parameters": [
{ "name": "storeId", "source": "PATH", "type": "java.lang.String", "required": true }
],
"returnType": "com.example.api.dto.OrderItemsResponse",
"endpointType": "Spring MVC"
},
{
"httpMethods": ["POST"],
"fullPath": "/api/stores/{storeId}/orders",
"controllerClass": "com.example.api.OrderController",
"methodName": "create",
"filePath": "src/main/kotlin/.../OrderController.kt",
"line": 41,
"parameters": [
{ "name": "storeId", "source": "PATH", "type": "java.lang.String", "required": true },
{ "name": "body", "source": "BODY", "type": "com.example.api.dto.CreateOrderRequest", "required": true }
],
"returnType": "com.example.api.dto.OrderResponse",
"endpointType": "Spring MVC"
}
]
}Returns the full API contract for one endpoint — ideal for backend/frontend integration work. Includes every parameter (path variables, query params, request body, headers) with types and required flags, the response DTO schema recursively expanded up to 3 levels (each DtoSchemaJson has a className and fields; nested DTOs hang off each field's nested), the produces/consumes media types, and the first service method called from the controller (serviceCall).
Example output (abridged)
{
"httpMethods": ["POST"],
"fullPath": "/api/stores/{storeId}/orders",
"controllerClass": "com.example.api.OrderController",
"methodName": "create",
"filePath": "src/main/kotlin/.../OrderController.kt",
"line": 41,
"parameters": [
{ "name": "storeId", "source": "PATH", "type": "java.lang.String", "required": true },
{ "name": "body", "source": "BODY", "type": "com.example.api.dto.CreateOrderRequest", "required": true }
],
"returnType": "com.example.api.dto.OrderResponse",
"responseSchema": {
"className": "com.example.api.dto.OrderResponse",
"fields": [
{ "name": "id", "type": "java.lang.Long", "nullable": false, "nested": null },
{ "name": "items", "type": "java.util.List<com.example.api.dto.OrderItemResponse>", "nullable": false,
"nested": { "className": "com.example.api.dto.OrderItemResponse",
"fields": [ { "name": "sku", "type": "java.lang.String", "nullable": false, "nested": null } ] } }
]
},
"produces": ["application/json"],
"consumes": ["application/json"],
"serviceCall": { "target": "com.example.service.OrderService.createOrder", "line": 88 },
"endpointType": "Spring MVC"
}Map a Controller → Service → Repository call chain before you edit it. Given a file path and line, the tool recursively follows method calls via UAST and labels each layer using Spring stereotypes:
| Annotation | Layer |
|---|---|
@Controller / @RestController
|
CONTROLLER |
@Service |
SERVICE |
@Repository |
REPOSITORY |
@Component |
COMPONENT |
| (none — private method in the same class) | INTERNAL |
Problem it solves. Threading a new parameter through a stack means tracing each layer by hand (find_usages → read_file, repeated ~8 times) — and the change still fails to compile because test files that mock/verify those methods were missed and only surface in compiler errors.
includeTests: true is the key option: it runs usage search on each discovered method and reports the test files + line numbers that reference them, so the agent updates every mock { on { … } } / verify(repo).…(…) up front and avoids the "edit → compile → fail → fix → repeat" cycle.
Example output (abridged)
{
"chain": [
{ "layer": "CONTROLLER", "className": "com.example.api.OrderItemsController", "methodName": "items",
"filePath": "src/main/kotlin/.../OrderItemsController.kt", "line": 23,
"parameters": ["storeId", "orderId", "page"],
"callsInto": [{ "target": "com.example.service.OrderItemsService.listItems", "line": 31 }] },
{ "layer": "SERVICE", "className": "com.example.service.OrderItemsService", "methodName": "listItems",
"filePath": "src/main/kotlin/.../OrderItemsService.kt", "line": 18,
"parameters": ["storeId", "orderId", "page"],
"callsInto": [{ "target": "com.example.repo.OrderItemsRepository.fetchItems", "line": 44 }] },
{ "layer": "REPOSITORY", "className": "com.example.repo.OrderItemsRepository", "methodName": "fetchItems",
"filePath": "src/main/kotlin/.../OrderItemsRepository.kt", "line": 12,
"parameters": ["storeId", "orderId", "page"],
"callsInto": [{ "target": "this.buildItemsQuery", "line": 60 }] }
],
"testReferences": [
{ "filePath": "src/test/kotlin/.../OrderItemsServiceTest.kt",
"referencedMethods": [{ "method": "listItems", "lines": [55, 128] }] }
]
}Each chain node carries layer, className, methodName, filePath, line, parameters, and callsInto (each call target with its line). The traversal follows constructor-injected fields to resolve concrete bean types and stops on circular chains.
Understand the whole domain model in one call. Lists all JPA @Entity classes (detects both jakarta.persistence and javax.persistence), with an optional packageFilter to restrict to a package subtree.
Problem it solves. Building a mental model of a 20-entity data layer otherwise costs 30+ calls: search_for_text("@Entity") returns raw lines, then each file is read to extract the table name, columns, and relationships.
Per entity it returns: class name, file path and line, resolved tableName (from @Table/@Entity(name=…) or JPA default naming), fields (with column, type, primaryKey from @Id/@EmbeddedId, and nullable), JPA relationships (ONE_TO_ONE, ONE_TO_MANY, MANY_TO_ONE, MANY_TO_MANY) with joinColumn/mappedBy wiring, and table indexes (from @Table(indexes=[...]) / @Index).
Example output (a bare array of entities, abridged)
[
{
"name": "OrderItem",
"className": "com.example.domain.OrderItem",
"filePath": "src/main/kotlin/.../OrderItem.kt",
"line": 12,
"tableName": "order_items",
"fields": [
{ "name": "id", "type": "java.lang.Long", "column": "id", "primaryKey": true, "nullable": false, "relationship": null, "joinColumn": null, "mappedBy": null },
{ "name": "sku", "type": "java.lang.String", "column": "sku", "primaryKey": false, "nullable": false, "relationship": null, "joinColumn": null, "mappedBy": null },
{ "name": "order", "type": "com.example.domain.Order", "column": null, "primaryKey": false, "nullable": true, "relationship": "MANY_TO_ONE", "joinColumn": "order_id", "mappedBy": null }
],
"indexes": [ { "name": "idx_order_id", "columns": ["order_id"], "unique": false } ]
}
]Why it's valuable: column-name mapping bridges Kotlin field names ↔ SQL columns for repository/query work; the relationship graph drives correct JOINs; existing indexes/constraints prevent migration conflicts; and the entity shape is the starting point for DTO design.
For a full-stack change they form a pipeline — route → logic → data model:
-
explyt_find_spring_endpoint— find the controller that handles a URL. -
explyt_trace_spring_call_chain— trace Controller → Service → Repository (and the tests to update). -
explyt_get_spring_data_entities— reveal the entities/tables the repository operates on.
explyt_get_spring_http_endpoints and explyt_get_spring_endpoint_contract add the API-surface and per-endpoint contract views on top.
See also: Features · Native Context Mode · Explyt AI Actions
Home · Features · Installation · Usage · Marketplace · Issues · Telegram (EN)
Explyt Spring Plugin — free for commercial and non-commercial use under the Apache License 2.0.
Getting started
Features
- All features
- Native Context Mode
- Spring Debugger
- HTTP Client
- Spring Web & OpenAPI REST client
.http/.restfiles (RFC 7230)- Code Generations
- MCP Tools
- Explyt AI Actions
Gallery
Links