A remote implementation of a Model Context Protocol (MCP) server in Java using HTTP/SSE transport. This is a proof-of-concept showing how to adapt a local stdio-based MCP server to work over the network.
- Communication via stdin/stdout pipes
- Claude Desktop spawns the Java process directly
- Single client per server instance
- No network layer or authentication
- Process lifecycle managed by client
- Communication via HTTP POST and Server-Sent Events (SSE)
- Server runs independently as a web service
- Multiple concurrent clients supported
- Network-based with potential for authentication/authorization
- Server has independent lifecycle
HTTP/SSE Model:
- Client → Server: HTTP POST requests to
/message
endpoint - Server → Client: Server-Sent Events via
/sse
endpoint - Protocol: Same JSON-RPC 2.0 MCP messages, different transport
MCPHttpServer.java - HTTP server using Javalin framework
- Manages SSE connections from clients
- Routes HTTP POST messages to request processor
- Handles multiple concurrent client sessions
- Provides health check and info endpoints
MCPRequestProcessor.java - Transport-agnostic MCP logic
- Processes JSON-RPC 2.0 requests
- Routes to tool implementations
- Same logic as stdio version, but decoupled from I/O
Tool implementations - Unchanged from local version
- CalculateTool, ReverseTextTool, WordCountTool
- Same interface and behavior
./gradlew build
This creates build/libs/mcp-server-remote-1.0.0.jar
# Default port 8080
./gradlew run
# Or with custom port
java -jar build/libs/mcp-server-remote-1.0.0.jar 8081
Check health:
curl http://localhost:8080/health
Get server info:
curl http://localhost:8080/
Test a tool call:
curl -X POST http://localhost:8080/message \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "calculate",
"arguments": {
"operation": "add",
"a": 5,
"b": 3
}
}
}'
Initialize session:
curl -X POST http://localhost:8080/message \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "test-client",
"version": "1.0.0"
}
}
}'
List tools:
curl -X POST http://localhost:8080/message \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}'
To use this remote server with Claude Desktop, you would need an MCP client that supports HTTP/SSE transport. The official MCP SDKs support this pattern.
Example configuration (conceptual - requires MCP client with SSE support):
{
"mcpServers": {
"mcp-server-remote-java": {
"url": "http://localhost:8080/sse",
"transport": "sse"
}
}
}
Note: The current Claude Desktop primarily supports stdio transport. This remote server is designed for:
- Custom MCP clients
- Web applications
- Microservice architectures
- Multi-tenant scenarios
Server information and available endpoints
Health check endpoint
{
"status": "ok",
"server": "mcp-server-remote-java",
"version": "1.0.0",
"activeConnections": 0
}
Establish Server-Sent Events connection for receiving server messages. Returns:
connected
event with client ID- Periodic heartbeats to keep connection alive
Send JSON-RPC 2.0 MCP messages. Accepts standard MCP methods:
initialize
- Handshaketools/list
- List available toolstools/call
- Execute a toolprompts/list
- List prompts (empty)resources/list
- List resources (empty)
Same process as local server:
- Create a class implementing
Tool
interface - Implement
getName()
,getDefinition()
, andexecute()
- Register in
MCPRequestProcessor.registerTools()
- Rebuild and restart server
When deploying this server in production:
- Add authentication (API keys, OAuth, JWT)
- Enable HTTPS/TLS
- Implement rate limiting
- Validate all inputs
- Add CORS restrictions for specific origins
- Add session management for stateful tools
- Consider load balancing for horizontal scaling
- Implement connection pooling
- Add request timeouts
- Add metrics collection (Prometheus, etc.)
- Enhanced logging with correlation IDs
- Health check endpoints
- Performance monitoring
- Externalize configuration (port, timeouts, etc.)
- Environment-specific settings
- Feature flags for tools
Aspect | Local (stdio) | Remote (HTTP/SSE) |
---|---|---|
Transport | stdin/stdout | HTTP POST + SSE |
Lifecycle | Managed by client | Independent service |
Clients | Single | Multiple concurrent |
Discovery | Config file path | Network URL |
Security | Process isolation | Network security needed |
Deployment | User's machine | Server infrastructure |
Logging | Can use stdout after handshake | HTTP logs + application logs |
State | Per-process | Shared or per-session |
Scaling | One per client | Horizontal scaling possible |
- Java 17 - Language runtime
- Javalin 5.6 - Lightweight web framework
- Jackson - JSON processing
- SLF4J + Logback - Logging
- Gradle - Build tool
my-mcp-server-java-server/
├── src/main/java/com/example/mcp/remote/
│ ├── MCPHttpServer.java # HTTP/SSE server
│ ├── MCPRequestProcessor.java # MCP protocol handler
│ ├── Tool.java # Tool interface
│ ├── ToolRegistry.java # Tool registry
│ ├── TextContent.java # Tool response wrapper
│ ├── CalculateTool.java # Example tool
│ ├── ReverseTextTool.java # Example tool
│ └── WordCountTool.java # Example tool
├── src/main/resources/
│ └── logback.xml # Logging configuration
├── build.gradle # Build configuration
├── settings.gradle # Project settings
└── README.md # This file
This is a demonstration/educational project showing MCP protocol implementation patterns.