Spring Ops MCP
MCP server for Spring Boot Actuator β let AI assistants monitor, debug, and interact with your running Spring Boot applications
Ask AI about Spring Ops MCP
Powered by Claude Β· Grounded in docs
I know everything about Spring Ops MCP. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Spring Ops MCP
Connect AI coding assistants to your Spring Boot applications.
Spring Ops MCP exposes Spring Boot Actuator endpoints as MCP (Model Context Protocol) tools, allowing Claude Code, Cursor, Windsurf, and other AI assistants to monitor, debug, and interact with your running applications through natural language.
"Check the health of my user-service"
"Why is my app slow? Check the metrics and thread dump"
"Enable debug logging for com.myapp.auth"
"What REST endpoints does order-service expose?"
"Compare memory usage across all my services"
Why Spring Ops MCP?
Because debugging Spring Boot apps shouldn't require 10 browser tabs and a PhD in Actuator endpoints.
Before: The Old Way π©
1. Something's wrong β open browser β localhost:8081/actuator/health
2. Copy JSON, try to read it
3. Open /actuator/metrics β "what was that metric name again?"
4. Google the metric name
5. /actuator/metrics/http.server.requests?tag=uri:/api/users&tag=method:GET
6. Need debug logs β edit application.properties β restart app
7. Reproduce the issue β finally find the problem after 30 minutes
After: The Spring Ops MCP Way π
You: "My /api/users endpoint is slow, investigate"
Claude: Found the issue:
- Response time: 2.3s (should be <200ms)
- Root cause: Connection pool exhausted (10/10 connections)
- Fix: spring.datasource.hikari.maximum-pool-size=20
30 minutes β 30 seconds.
Real-World Impact
| Task | Before | After |
|---|---|---|
| Morning health check across 5 services | 10 min | 10 sec |
| Debug production performance issue | 30 min | 2 min |
| Onboard new team member to codebase | 2 days | 30 min |
| Change log level for debugging | 5 min + restart | 5 sec, no restart |
| Find why auto-config isn't working | 15 min | 30 sec |
π See all use cases with examples β
Table of Contents
- Features
- Quick Start
- Configuration
- Available MCP Tools
- Usage Examples
- Target App Requirements
- Building from Source
- Architecture
- Roadmap
- Contributing
- License
Features
| Category | Capabilities |
|---|---|
| π₯ Health & Status | Application health with all indicators (database, redis, disk, custom), build info, git commit |
| π Metrics | JVM memory, CPU, HTTP request stats, connection pools, Micrometer metrics with tag filtering |
| βοΈ Configuration | Environment properties, active profiles, Spring beans, REST endpoint mappings |
| π Logging | View log levels, change log levels at runtime (no restart needed!) |
| π Diagnostics | Thread dumps, auto-configuration report, scheduled tasks, HTTP exchange traces |
| ποΈ Caches | List caches, clear specific or all caches |
Quick Start
Option A: Embedded Mode (Recommended)
Add the MCP server directly to your Spring Boot application. The MCP endpoint runs alongside your app.
1. Add the dependency
Maven:
<dependency>
<groupId>io.github.sigachev</groupId>
<artifactId>spring-ops-mcp-starter</artifactId>
<version>0.1.0</version>
</dependency>
Gradle:
implementation 'io.github.sigachev:spring-ops-mcp-starter:0.1.0'
2. Configure your application
Add to application.properties:
# Your app's port
server.port=8081
# Expose Actuator endpoints
management.endpoints.web.exposure.include=health,info,metrics,env,loggers,beans,mappings,threaddump,scheduledtasks,conditions,caches
management.endpoint.health.show-details=always
# MCP server configuration
spring.ai.mcp.server.name=my-app
spring.ai.mcp.server.transport=sse
spring.ai.mcp.server.sse-path=/mcp/sse
# Auto-register this app for self-monitoring
spring.ops.mcp.register-self=true
spring.ops.mcp.self-name=my-app
spring.ops.mcp.self-port=${server.port}
Or application.yml:
server:
port: 8081
management:
endpoints:
web:
exposure:
include: health,info,metrics,env,loggers,beans,mappings,threaddump,scheduledtasks,conditions,caches
endpoint:
health:
show-details: always
spring:
ai:
mcp:
server:
name: my-app
transport: sse
sse-path: /mcp/sse
ops:
mcp:
register-self: true
self-name: my-app
self-port: 8081
3. Start your application
./mvnw spring-boot:run
Your app now has an MCP endpoint at http://localhost:8081/mcp/sse
4. Connect Claude Code
claude mcp add my-app --transport http http://localhost:8081/mcp/sse
5. Start chatting!
You: Check the health of my-app
Claude: β my-app is UP
Components:
- db: UP (PostgreSQL 15.3)
- redis: UP
- diskSpace: UP (128 GB free)
Option B: Standalone Mode
Run Spring Ops MCP as a separate service that connects to multiple Spring Boot applications.
1. Run the standalone server
Docker (recommended):
docker run -p 8090:8090 sigachev/spring-ops-mcp
Or download and run the JAR:
curl -LO https://github.com/sigachev/spring-ops-mcp/releases/latest/download/spring-ops-mcp-server.jar
java -jar spring-ops-mcp-server.jar
Or build from source:
git clone https://github.com/sigachev/spring-ops-mcp.git
cd spring-ops-mcp
./mvnw clean package -pl spring-ops-mcp-server -am -DskipTests
java -jar spring-ops-mcp-server/target/spring-ops-mcp-server-0.1.0-SNAPSHOT.jar
2. Connect Claude Code
claude mcp add spring-ops --transport http http://localhost:8090/mcp/sse
3. Register your applications
You: Register user-service at http://localhost:8081
Claude: β Registered 'user-service' - connection verified!
You: Register order-service at http://localhost:8082
Claude: β Registered 'order-service' - connection verified!
You: List my apps
Claude: Registered applications:
1. user-service β http://localhost:8081/actuator
2. order-service β http://localhost:8082/actuator
4. Pre-configure apps (optional)
Instead of registering apps via chat, configure them in application.yml:
spring:
ops:
mcp:
apps:
user-service:
url: http://localhost:8081
order-service:
url: http://localhost:8082
payment-service:
url: http://localhost:8083
actuator-path: /management # custom actuator path
Configuration
Configuration Properties
| Property | Default | Description |
|---|---|---|
spring.ops.mcp.enabled | true | Enable/disable Spring Ops MCP |
spring.ops.mcp.register-self | true | Auto-register this app for self-monitoring |
spring.ops.mcp.self-name | self | Name for self-registration |
spring.ops.mcp.self-port | 8080 | Port for self-registration |
spring.ops.mcp.apps.<name>.url | - | Base URL of target application |
spring.ops.mcp.apps.<name>.actuator-path | /actuator | Actuator base path |
Full Configuration Example
server:
port: 8090
spring:
application:
name: spring-ops-mcp-server
ai:
mcp:
server:
name: spring-ops-mcp
version: 0.1.0
transport: sse
sse-path: /mcp/sse
ops:
mcp:
enabled: true
register-self: false # Standalone mode
apps:
# Development services
user-service:
url: http://localhost:8081
order-service:
url: http://localhost:8082
payment-service:
url: http://localhost:8083
# Production services (with auth - coming soon)
# prod-api:
# url: https://api.mycompany.com
# actuator-path: /management
# auth-type: basic
# username: actuator
# password: ${ACTUATOR_PASSWORD}
logging:
level:
io.github.sigachev.springopsmcp: DEBUG
Available MCP Tools
App Management
| Tool | Description |
|---|---|
listApps | List all registered Spring Boot applications |
registerApp(name, url, actuatorPath?) | Register a new application for monitoring |
removeApp(name) | Remove an application from monitoring |
Health & Status
| Tool | Description |
|---|---|
getHealth(appName) | Get health status with all indicators (db, redis, disk, custom) |
getInfo(appName) | Get build info, git commit, and custom info |
Metrics
| Tool | Description |
|---|---|
listMetrics(appName) | List all available metric names |
getMetric(appName, metricName, tags?) | Get specific metric with optional tag filtering |
Common metrics:
jvm.memory.used,jvm.memory.maxβ JVM heapjvm.gc.pauseβ Garbage collectionhttp.server.requestsβ HTTP request stats (filter byuri,method,status)hikaricp.connections.activeβ Database connection poolsystem.cpu.usage,process.cpu.usageβ CPUtomcat.threads.current,tomcat.threads.busyβ Thread pool
Configuration
| Tool | Description |
|---|---|
getEnv(appName, pattern?) | Get environment properties (optionally filtered) |
getBeans(appName) | List all Spring beans |
getMappings(appName) | Get all REST endpoint mappings |
Logging
| Tool | Description |
|---|---|
getLoggers(appName, loggerName?) | Get log levels for all or specific logger |
setLogLevel(appName, loggerName, level) | Change log level at runtime |
Valid log levels: TRACE, DEBUG, INFO, WARN, ERROR, OFF
Diagnostics
| Tool | Description |
|---|---|
getThreadDump(appName) | Get thread dump for deadlock analysis |
getScheduledTasks(appName) | List @Scheduled tasks |
getConditions(appName) | Get auto-configuration conditions report |
getHttpExchanges(appName) | Get recent HTTP request traces |
Caches
| Tool | Description |
|---|---|
getCaches(appName) | List all caches |
clearCache(appName, cacheName) | Clear specific cache (or "all" for all caches) |
Usage Examples
π Morning Health Check
You: Good morning! How are my services doing?
Claude: Good morning! All 3 services are healthy:
βββββββββββββββββββ¬βββββββββ¬ββββββββββββββββββββββββββ
β Service β Status β Memory β
βββββββββββββββββββΌβββββββββΌββββββββββββββββββββββββββ€
β user-service β β UP β 245 MB / 512 MB (48%) β
β order-service β β UP β 312 MB / 512 MB (61%) β
β payment-service β β UP β 198 MB / 512 MB (39%) β
βββββββββββββββββββ΄βββββββββ΄ββββββββββββββββββββββββββ
No issues detected. All database and Redis connections healthy.
π Performance Investigation
You: The checkout endpoint is slow, investigate
Claude: I'll analyze the checkout endpoint performance.
[Calling getMetric("order-service", "http.server.requests", "uri:/api/checkout")]
[Calling getMetric("order-service", "hikaricp.connections.active")]
[Calling getThreadDump("order-service")]
Found the issue:
π /api/checkout performance:
- Average response time: 4.2s (should be <500ms)
- 95th percentile: 6.8s
- Requests/min: 847
π Root cause: Database connection pool exhausted
- HikariCP: 10/10 connections active (100% utilized)
- 6 threads blocked waiting for connections
- Slow query in OrderRepository.findByUserIdWithItems()
π‘ Recommendations:
1. Increase pool size:
spring.datasource.hikari.maximum-pool-size=20
2. Add database index:
CREATE INDEX idx_orders_user_id ON orders(user_id);
3. Optimize the query β consider pagination or lazy loading for order items
π Runtime Debugging
You: Enable debug logging for the auth package, I need to trace a login issue
Claude: Done! Set com.myapp.auth to DEBUG in user-service.
You: [reproduce the issue]
You: What do the logs show?
Claude: Based on the debug output, the issue is in TokenValidator:
- JWT signature validation is passing
- But the token's "aud" claim doesn't match your configured audience
- Expected: "https://api.myapp.com"
- Actual: "https://api.myapp.com/" (trailing slash)
You: OK, I see the issue. Set logging back to INFO.
Claude: Done! Set com.myapp.auth back to INFO.
πΊοΈ API Discovery
You: I'm new to the team. What endpoints does order-service have?
Claude: order-service exposes 12 REST endpoints:
π¦ Orders
POST /api/orders Create new order
GET /api/orders List orders (paginated)
GET /api/orders/{id} Get order by ID
PUT /api/orders/{id} Update order
DELETE /api/orders/{id} Cancel order
π³ Payments
POST /api/orders/{id}/pay Process payment
GET /api/orders/{id}/payment Payment status
π€ User Orders
GET /api/users/{userId}/orders User's order history
π Analytics
GET /api/orders/stats Order statistics
GET /api/orders/export Export orders (CSV)
π§ Internal
POST /internal/orders/sync Sync with warehouse
GET /internal/health Deep health check
βοΈ Environment Comparison
You: Compare the config between local and staging for user-service
Claude: Configuration differences between local and staging:
| Property | Local | Staging |
|---------------------------------|-----------------|----------------------|
| spring.datasource.url | localhost:5432 | staging-db.aws:5432 |
| spring.redis.host | localhost | staging-redis.aws |
| spring.kafka.bootstrap-servers | localhost:9092 | staging-kafka.aws |
| logging.level.root | DEBUG | INFO |
| server.tomcat.max-threads | 200 | 400 |
| app.feature.new-checkout | true | false |
β οΈ Note: The new-checkout feature flag is enabled locally but disabled in staging.
π§Ή Cache Management
You: The product catalog seems stale, clear the product caches
Claude: Found 3 product-related caches in catalog-service:
- products (1,247 entries)
- product-categories (89 entries)
- product-prices (1,247 entries)
Cleared all 3 caches. The next requests will fetch fresh data from the database.
Target App Requirements
Your monitored Spring Boot applications need:
1. Actuator Dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2. Exposed Endpoints
# Minimum for basic monitoring
management.endpoints.web.exposure.include=health,info,metrics
# Full feature set
management.endpoints.web.exposure.include=health,info,metrics,env,loggers,beans,mappings,threaddump,scheduledtasks,conditions,httpexchanges,caches
# Show health details
management.endpoint.health.show-details=always
3. (Optional) HTTP Exchanges
To enable getHttpExchanges, add:
@Bean
public HttpExchangeRepository httpExchangeRepository() {
return new InMemoryHttpExchangeRepository();
}
Building from Source
# Clone
git clone https://github.com/sigachev/spring-ops-mcp.git
cd spring-ops-mcp
# Build all modules
./mvnw clean install
# Build server JAR only
./mvnw clean package -pl spring-ops-mcp-server -am -DskipTests
# Run standalone server
java -jar spring-ops-mcp-server/target/spring-ops-mcp-server-0.1.0-SNAPSHOT.jar
# Docker build
docker build -t spring-ops-mcp .
Architecture
spring-ops-mcp/
βββ spring-ops-mcp-core/ # Core MCP tools & Actuator client
β βββ ActuatorMcpTools.java # 18 @Tool-annotated methods
β βββ ActuatorClient.java # HTTP client for Actuator endpoints
β βββ AppRegistry.java # Registered apps storage
β βββ RegisteredApp.java # App model
β
βββ spring-ops-mcp-starter/ # Spring Boot Starter (embedded mode)
β βββ SpringOpsMcpAutoConfiguration.java
β βββ SpringOpsMcpProperties.java
β
βββ spring-ops-mcp-server/ # Standalone server application
βββ SpringOpsMcpServerApplication.java
How It Works
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Developer Machine β
β β
β βββββββββββββββ ββββββββββββββββββββββββ β
β β Claude Code ββββββββββΊβ spring-ops-mcp β β
β β Cursor β MCP β (Embedded or β β
β β Windsurf β Protocolβ Standalone) β β
β βββββββββββββββ ββββββββββββ¬ββββββββββββ β
β β β
β HTTP calls to /actuator/* β
β β β
β βββββββββββββββββββββββββββββΌββββββββββββββββββββββββ β
β βΌ βΌ βΌ β
β βββββββββββββββ βββββββββββββββ ββββββββββββββββ
β βuser-service β βorder-serviceβ βpayment-svc ββ
β β :8081 β β :8082 β β :8083 ββ
β β /actuator/* β β /actuator/* β β /actuator/* ββ
β βββββββββββββββ βββββββββββββββ ββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Roadmap
- Authentication support β Basic auth, Bearer token, mTLS for secured Actuator endpoints
- Prometheus metrics β Query Prometheus for historical data
- Log streaming β Stream application logs via MCP
- Kubernetes integration β Pod discovery, kubectl operations
- Flyway/Liquibase β Migration status and management
- Spring Cloud Config β Configuration management across environments
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the Apache License 2.0 β see the LICENSE file for details.
Related Projects
- Spring AI β AI integration for Spring
- MCP Java SDK β Official MCP SDK for Java
- Model Context Protocol β The MCP specification
- Spring Boot Actuator β Production-ready features
Support
- π Report a bug
- π‘ Request a feature
- π¬ Discussions
Author
Mikhail Sigachev
- GitHub: @sigachev
- Project: spring-ops-mcp
Built with β€οΈ for the Spring Boot community.
