Skip to main content

MCP tools

Explyt Spring ships seven Spring-aware MCP tools for the bundled JetBrains MCP Server. They let agentic AI clients ask the IDE for structured Spring context instead of relying on generic file search, which means fewer exploratory tool calls, lower token usage, and more accurate answers.

Requirements. IntelliJ IDEA 2025.2 or newer with the JetBrains MCP Server plugin. The MCP Server plugin does not exist in earlier platform versions, so this cannot be backported. Works with any AI client that can connect to the IntelliJ IDEA MCP Server, including Explyt AI.

Why this matters

Consider a routine question: which controller handles GET /api/stores/{storeId}/orders?

A generic agent greps for the URL. That fails, because the path is composed from two annotations and exists nowhere in the source as a literal string:

@RequestMapping("/api/stores/{storeId}/orders")  // on the class
@GetMapping("/{orderId}/items") // on the method

With no text match, the agent falls back to guessing controller file names and reading candidates — typically three to eight exploratory calls per question, each one consuming context.

Explyt's tools answer from the IDE's real Spring index in a single call. They cover the questions that actually come up in backend work: which Spring Boot applications exist and what beans they define, which endpoint handles a URL and what its full contract is, which service and repository methods a controller reaches, and how JPA entities map to tables and relationships.

Discovery

explyt_get_spring_boot_applications

Lists the Spring Boot applications in the workspace, with detected Spring Boot versions and starters. This is the orientation call for a multi-module workspace — an agent uses it to pick the right application before calling anything else.

[
{
"fullyQualifiedClassName": "com.example.OrdersApplication",
"springBootVersion": "3.3.4",
"springBootStarters": ["spring-boot-starter-web", "spring-boot-starter-data-jpa"],
"moduleName": "orders-service.main",
"buildTool": "gradle"
}
]

explyt_get_project_beans_by_spring_boot_application

Returns the beans of a chosen application, filtered by bean type, without scanning every source file for stereotype annotations.

Pass the application's fully qualified class name from the previous tool, plus a beanType of CONTROLLER, REPOSITORY, CONFIGURATION, COMPONENT, CONFIGURATION_PROPERTIES, AUTO_CONFIGURATION, ASPECT, or MESSAGE_MAPPING.

[
{ "beanName": "orderRepository", "className": "com.example.repo.OrderRepository", "moduleName": "orders-service.main" },
{ "beanName": "orderItemRepository", "className": "com.example.repo.OrderItemRepository", "moduleName": "orders-service.main" }
]

Endpoints

explyt_find_spring_endpoint

Turns a URL into the exact handler method. This is the most common entry point, because nearly every full-stack task starts from a URL — in a browser, in frontend code, or in a bug report.

Input is an optional HTTP method, a urlPattern, and the project path. Matching is deliberately forgiving: it matches against the composed path, supports substring and fuzzy matching, and ignores path variable names, so {orderId} matches {id} matches any segment.

It matches across every endpoint type the plugin understands: Spring MVC, WebFlux, JAX-RS, HttpExchange, OpenFeign, OpenAPI, message brokers, and event listeners.

[
{
"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"
}
]

explyt_get_spring_http_endpoints

Lists all HTTP endpoints in the project, or for one application, optionally filtered by controller class name or endpoint type such as SPRING_MVC, SPRING_WEBFLUX, or SPRING_JAX_RS. Use it when the agent needs the whole API surface rather than one route.

Results are paginated. Alongside endpoints, the response carries totalCount for how many endpoints matched the filters and truncated, which is true when matches exceeded the result cap — a signal that the list is incomplete and the filters should be narrowed.

explyt_get_spring_endpoint_contract

Returns the full contract for a single endpoint, which is what frontend and integration work actually needs. It includes every parameter — path variables, query parameters, request body, headers — with types and required flags; the response DTO schema expanded recursively up to three levels; the produces and consumes media types; and the first service method the controller calls.

{
"httpMethods": ["POST"],
"fullPath": "/api/stores/{storeId}/orders",
"controllerClass": "com.example.api.OrderController",
"methodName": "create",
"parameters": [
{ "name": "storeId", "source": "PATH", "type": "java.lang.String", "required": true },
{ "name": "body", "source": "BODY", "type": "com.example.api.dto.CreateOrderRequest", "required": true }
],
"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"
}

Call chain

explyt_trace_spring_call_chain

Maps a Controller → Service → Repository chain before an agent edits it. Given a file path and a line, the tool recursively follows method calls and labels each layer using Spring stereotypes:

AnnotationLayer
@Controller / @RestControllerCONTROLLER
@ServiceSERVICE
@RepositoryREPOSITORY
@ComponentCOMPONENT
none — a private method in the same classINTERNAL

The problem this solves is threading a change through a stack. Doing it by hand means alternating find-usages and read-file roughly eight times, and the change still fails to compile — because the test files that mock and verify those methods were missed, and only surface as compiler errors afterwards.

Setting includeTests: true is the key option. It runs usage search on every discovered method and reports the test files and line numbers referencing them, so an agent can update the mocks and verifications up front instead of cycling through edit, compile, fail, fix.

Each node in the returned chain carries layer, className, methodName, filePath, line, parameters, and callsInto with the line of each call. Traversal follows constructor-injected fields to resolve concrete bean types, and stops on circular chains.

Data model

explyt_get_spring_data_entities

Describes the whole domain model in one call. Lists JPA entity classes, detecting both jakarta.persistence and javax.persistence, with an optional packageFilter to restrict the result to a package subtree.

Building a mental model of a twenty-entity data layer otherwise costs thirty or more calls: search for the annotation, then open every file to extract the table name, columns, and relationships.

For each entity it returns the class name, file path and line, the resolved tableName from @Table or JPA default naming, the fields with column name, type, primary key flag and nullability, the JPA relationships with their joinColumn and mappedBy wiring, and the table indexes.

[
{
"name": "OrderItem",
"className": "com.example.domain.OrderItem",
"tableName": "order_items",
"fields": [
{ "name": "id", "type": "java.lang.Long", "column": "id", "primaryKey": true, "nullable": false, "relationship": null },
{ "name": "sku", "type": "java.lang.String", "column": "sku", "primaryKey": false, "nullable": false, "relationship": 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 } ]
}
]

This matters for more than orientation. Column mapping bridges Kotlin or Java field names to SQL column names for query work, the relationship graph drives correct joins, existing indexes and constraints prevent migration conflicts, and the entity shape is the starting point for DTO design.

Using the tools together

For a full-stack change the tools form a pipeline — route, then logic, then data model:

  1. explyt_find_spring_endpoint finds the controller handling a URL.
  2. explyt_trace_spring_call_chain traces it down through service and repository layers, and names the tests to update.
  3. explyt_get_spring_data_entities reveals the entities and tables the repository operates on.

explyt_get_spring_http_endpoints and explyt_get_spring_endpoint_contract layer the API-surface and per-endpoint contract views on top.

Implementation

Example payloads on this page are representative; exact fields may evolve.

Further reading

See also: Explyt AI actions · Native Context Mode