For the latest stable version, please use Actuator extensions 4.1.1.4!

Actuator MCP Server

Expose Spring Boot Actuator endpoints to AI assistants (Claude Code, Cursor and other MCP clients) as Model Context Protocol tools — served from inside your application, on the management port.

Installation

<dependency>
    <groupId>org.alexmond</groupId>
    <artifactId>spring-boot-actuator-mcp-starter</artifactId>
    <version>4.0.8.4</version>
</dependency>

Requires a Spring MVC (servlet) application with spring-boot-starter-actuator.

Quick start

management:
  server:
    port: 9090            # recommended: keep MCP off the public port
  endpoints:
    mcp:
      exposure:
        include: health,info,metrics,loggers

Connect a client:

claude mcp add --transport http my-app http://localhost:9090/actuator/mcp

Where it is served

  • Path: <management.endpoints.web.base-path>/mcp — /actuator/mcp by default.

  • With management.server.port set, MCP is served only on the management port.

  • Without a separate management port, it is served on the application port, like every other actuator endpoint.

  • Transport: Streamable HTTP.

What is exposed

Nothing, until you include endpoints:

Property Default Description

management.endpoints.mcp.enabled

true

Turn the actuator MCP server off completely.

management.endpoints.mcp.exposure.include

(empty)

Endpoint IDs to expose, or *.

management.endpoints.mcp.exposure.exclude

(empty)

Endpoint IDs never to expose. Wins over include.

management.endpoints.mcp.max-response-chars

20000

Longer tool results are truncated, with a note telling the assistant how to narrow the call.

management.endpoints.mcp.allowed-origins

(empty)

Browser origins allowed to call the endpoint, e.g. http://localhost:6274; :* matches any port. See Browser origins (DNS rebinding).

Each operation of an included endpoint becomes one tool, named actuator_<endpoint> (endpoint declares one operation) or actuator_<endpoint>_<operation>, for example actuator_metrics_metric. Names depend only on the endpoint type, so changing access settings never renames a tool.

heapdump and logfile are never exposed (binary or file output). Web-only endpoints such as prometheus are not exposed.

Write operations follow actuator access

The starter has no separate read-only switch: it respects actuator’s own access settings.

  • management.endpoint.<id>.access=read-only → only read tools for that endpoint.

  • management.endpoint.<id>.access=none → no tools for that endpoint.

  • management.endpoints.access.max-permitted=read-only → read-only for every endpoint, everywhere.

Actuator’s default access is unrestricted. Including loggers therefore also exposes actuator_loggers_configureLogLevel, which changes log levels. Set access=read-only on endpoints an assistant should only read. shutdown stays unavailable unless you enable it in actuator itself.

Sensitive values

Tools call the endpoints in-process, so actuator’s own masking applies: show-values / show-details settings and every SanitizingFunction bean, including the Actuator Sanitizer when it is on the classpath. Tool calls run without a user principal, so when-authorized settings keep values hidden.

Securing the endpoint

The starter adds no authentication. Protect the MCP path with Spring Security like any actuator endpoint, for example:

@Bean
SecurityFilterChain management(HttpSecurity http) throws Exception {
    return http.securityMatcher("/actuator/**")
            .authorizeHttpRequests(a -> a.anyRequest().hasRole("OPS"))
            .httpBasic(Customizer.withDefaults())
            // every MCP call is a POST: without this, CSRF protection rejects them all with 403
            .csrf(csrf -> csrf.ignoringRequestMatchers("/actuator/mcp"))
            .build();
}

EndpointRequest.toAnyEndpoint() does not match /actuator/mcp, because MCP is not an actuator endpoint id — match the path, as above.

Browser origins (DNS rebinding)

A web page can trick a browser into calling a server on localhost (DNS rebinding). As the MCP specification requires, the endpoint checks the Origin header:

  • No Origin header — CLI clients such as Claude Code — is always accepted.

  • An Origin header must match management.endpoints.mcp.allowed-origins, otherwise the request is rejected with 403. The list is empty by default, so every browser request is refused.

To use a browser-based client such as the MCP Inspector, allow its origin:

management:
  endpoints:
    mcp:
      allowed-origins: http://localhost:6274

Shutdown

Connected MCP clients keep a stream open. The starter closes all MCP sessions before the web server’s graceful shutdown begins, so restarts are not delayed by connected assistants.

Using it with Spring AI’s MCP server

If your application also runs Spring AI’s MCP server for its own tools, both servers work side by side: your tools stay on your server, and the actuator tools are only on /actuator/mcp. (Spring AI collects your tools from beans of type List<SyncToolSpecification>; the actuator tools are never registered as beans, so they cannot leak into your server.)

Custom endpoints

Your own @Endpoint beans are exposed like the built-in ones once included. Each operation parameter becomes a tool argument. Parameters are required unless annotated with JSpecify’s @org.jspecify.annotations.Nullable, which marks them optional in the tool’s input schema.