A high-performance Java implementation of the Secure MCP Gateway using Spring Boot framework.
This is a complete implementation of the Secure MCP Gateway in Java using Spring Boot with WebFlux, providing:
- 🚀 Reactive & Non-blocking - Built on Spring WebFlux for high concurrency
- 💾 Efficient Resource Usage - Optimized memory footprint
- 🔗 High Throughput - Handles thousands of concurrent connections
- ✅ Production Ready - Full Spring Boot ecosystem support
- 🔌 MCP Protocol Compliant - Compatible with all MCP clients
- Java 21 (LTS) - Required
- Maven 3.9+ - For building
- Docker - For containerized deployment (optional)
curl -s "https://get.sdkman.io" | bash
sdk install java 21.0.1-tem
sdk use java 21.0.1-tembrew install openjdk@21
export JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Homejava -version
# Should show: openjdk version "21.x.x"server-java/
├── src/
│ ├── main/
│ │ ├── java/com/datacline/mcpgateway/
│ │ │ ├── config/ # Configuration classes
│ │ │ ├── model/ # JPA Entity models
│ │ │ ├── repository/ # Spring Data repositories
│ │ │ ├── service/ # Business logic services
│ │ │ ├── controller/ # REST controllers
│ │ │ └── client/ # HTTP clients
│ │ └── resources/
│ │ ├── application.yaml # Spring Boot configuration
│ │ └── db/migration/ # Flyway migrations
│ └── test/ # Tests
├── pom.xml # Maven dependencies
├── docker-compose.yml # Docker services
├── Dockerfile # Production Docker image
└── README.md # This file
cd server-java
# Start in dev mode
./mvnw spring-boot:run -Dspring-boot.run.profiles=dev
# Or use the Makefile
make devThe application starts on http://localhost:8000 with:
- Live reload with Spring Boot DevTools
- H2 console at http://localhost:8000/h2-console
- Actuator endpoints at http://localhost:8000/actuator
- Auth disabled for easy testing
cd server-java
# Start all services (Gateway + Keycloak + PostgreSQL)
make docker-up
# Or: docker-compose up -d
# View logs
make docker-logs
# Or: docker-compose logs -f mcp-gateway-java
# Stop services
make docker-down
# Or: docker-compose downServices:
- Gateway: http://localhost:8000
- Keycloak: http://localhost:8080 (admin/admin)
- PostgreSQL: localhost:5432
# Build JAR
./mvnw clean package
# Run JAR
java -jar target/mcp-gateway-*.jar
# Or with profile
java -jar target/mcp-gateway-*.jar --spring.profiles.active=prodCopy and customize .env.example:
cp .env.example .envKey variables:
# Server
SERVER_PORT=8000
# Database
SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/mcp_gateway
SPRING_DATASOURCE_USERNAME=mcp_user
SPRING_DATASOURCE_PASSWORD=mcp_password
# Authentication
AUTH_ENABLED=true
KEYCLOAK_URL=http://localhost:8080
KEYCLOAK_REALM=mcp-gateway
# MCP Configuration
MCP_SERVERS_CONFIG=mcp_servers.yaml- dev - Development mode (H2, debug logging)
- test - Testing mode (in-memory H2)
- docker - Docker deployment (PostgreSQL, auth enabled)
- prod - Production mode (optimized settings)
Activate profile:
# Via environment
export SPRING_PROFILES_ACTIVE=dev
# Via command line
./mvnw spring-boot:run -Dspring-boot.run.profiles=dev
# Via application properties
spring.profiles.active=dev# List tools from an MCP server
GET /mcp/list-tools?mcp_server=default
# Invoke a tool
POST /mcp/invoke?mcp_server=default
{
"tool_name": "get_logs",
"parameters": {}
}
# List resources
GET /mcp/list-resources?mcp_server=default
# Read resource
GET /mcp/read-resource?mcp_server=default&uri=file:///path
# List prompts
GET /mcp/list-prompts?mcp_server=default
# Get prompt
GET /mcp/get-prompt?mcp_server=default&name=prompt_name
# List servers
GET /mcp/servers
# Broadcast to multiple servers
POST /mcp/invoke-broadcast
{
"tool_name": "get_logs",
"parameters": {},
"mcp_servers": ["server1", "server2"],
"tags": ["production"]
}# Health check
GET /actuator/health
# Metrics
GET /actuator/metrics
# Prometheus metrics
GET /actuator/prometheus
# Application info
GET /actuator/info# Run all tests
make test
# Or: ./mvnw test
# Run with coverage
make test-coverage
# Or: ./mvnw verify jacoco:report
# Integration tests
make test-integration
# Or: ./mvnw verify# Format code
make fmt
# Run linters
make lint
# Check dependencies
make deps# Access H2 console (dev mode)
make db-console
# Opens: http://localhost:8000/h2-console
# Run migrations
make db-migrate
# Reset database
make db-reset# Build JVM Docker image
make docker
# Or: docker build -t mcp-gateway-java:latest .
# Test the image
docker run -p 8000:8000 \
-e SPRING_PROFILES_ACTIVE=dev \
mcp-gateway-java:latest# Start all services
make docker-up
# View logs
make docker-logs-gateway
# Stop services
make docker-down
# Clean volumes
make docker-cleanThe gateway supports OAuth2/OIDC authentication via Keycloak:
- Start Keycloak:
make docker-up - Access: http://localhost:8080
- Login: admin/admin
- Configure realm:
mcp-gateway
# Via environment
export AUTH_ENABLED=true
export KEYCLOAK_URL=http://localhost:8080
export KEYCLOAK_REALM=mcp-gateway
# Via Spring profile
SPRING_PROFILES_ACTIVE=docker# Get access token
TOKEN=$(curl -X POST \
http://localhost:8080/realms/mcp-gateway/protocol/openid-connect/token \
-d "client_id=mcp-gateway-client" \
-d "grant_type=password" \
-d "username=user" \
-d "password=password" \
| jq -r .access_token)
# Use token
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:8000/mcp/list-tools?mcp_server=defaultEdit mcp_servers.yaml to configure MCP servers:
servers:
my-server:
url: http://localhost:3000/mcp
type: http
timeout: 60
enabled: true
description: "My custom MCP server"
tags: ["production", "critical"]
tools: ["*"] # All tools
auth:
method: bearer
location: header
name: Authorization
format: prefix
prefix: "Bearer "
credential_ref: env://MY_SERVER_TOKENenv://VAR_NAME- Environment variablefile:///path/to/file- File contentvault://path- Vault integration (coming soon)
# Production settings
export JAVA_OPTS="-Xmx512m -Xms256m -XX:+UseG1GC"
# High throughput
export JAVA_OPTS="-Xmx1g -Xms1g -XX:+UseParallelGC"
# Low latency
export JAVA_OPTS="-Xmx512m -Xms512m -XX:+UseZGC"# Connection pool
spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
# WebFlux
spring:
webflux:
max-in-memory-size: 10MB# Check Java version
java -version
# Clean and rebuild
make clean
make build
# Check logs
make docker-logs-gateway# Verify PostgreSQL is running
docker ps | grep postgres
# Check connection
psql -h localhost -U mcp_user -d mcp_gateway
# Reset database
make db-reset# Check Keycloak is running
curl http://localhost:8080
# Verify realm configuration
# Visit: http://localhost:8080/admin
# Disable auth for testing
export AUTH_ENABLED=falsemake help # Show all commands
make dev # Start in dev mode
make dev-debug # Start with debugger
make build # Build application
make test # Run tests
make docker # Build Docker image
make docker-up # Start all services
make docker-down # Stop services
make docker-logs # View logs
make health # Check health
make metrics # Show metrics
make info # Show app infoThe Java implementation is 100% API compatible with the Python version. Simply:
- Update client configuration to point to Java gateway
- Use same MCP server configuration files
- Same authentication mechanism (Keycloak)
- Same API endpoints and responses
See CONTRIBUTING.md for guidelines.
See LICENSE for details.