⚠️ Beta Software: This project is under active development. Expect bugs and breaking changes.
For the official Redis MCP server, please visit redis-mcp This project is intended to be used as library to develop custom MCP tools for Redis ( e.g. in-house Redis modules, custom Lua scripts or Redis Functions ) The existing tools are provided as examples and can be used as a reference for developing your own tools.
A Java implementation of Model Context Protocol (MCP) tools for Redis operations, providing both Lettuce and Jedis client support with automatic tool discovery and schema generation.
The Redis MCP Java library follows a layered architecture that separates concerns between connection management,validation, MCP tool handling, and MCP protocol integration.
redis-mcp-java/
├── core/ # Core MCP Redis functionality
│ └── src/main/java/io/redis/mcp/java/core/
│ ├── handlers/ # Redis command implementations
│ │ ├── lettuce/ # Lettuce-based handlers
│ │ └── jedis/ # Jedis-based handlers
│ ├── net/ # Connection management
│ ├── tooling/ # Tool discovery and MCP integration
│ └── validation/ # Input validation and error handling
└── spring/ # Spring Boot integration (optional)
Each Redis command is implemented as a separate handler class that extends either LettuceHandler
or JedisHandler
:
public class GetHandler extends LettuceHandler {
public record GetRequest(
@Nonnull @Description("The Redis key to retrieve") String key
) {
}
@Override
public McpSchema.Tool toolSchema() {
return new McpSchema.Tool(
"redis_get",
"Retrieve a value from Redis by key",
recordToJSONSchema(GetRequest.class)
);
}
// Implementation methods...
}
The HandlerScanner
uses reflection to automatically discover and instantiate all handler classes:
- Scans specified packages for
LettuceHandler
andJedisHandler
subclasses - Instantiates handlers with Redis connection providers
- Validates tool name uniqueness across all handlers
- Builds tool registry for MCP server registration
The Redis
interface abstracts connection management with support for:
- Lazy Connection Pooling: Connections created on-demand
- Round-Robin Distribution: Load balancing across pooled connections
- Dual Client Support: Both Lettuce (async/reactive) and Jedis (sync) clients
- Connection Caching: Efficient connection reuse
Automatic MCP JSON Schema generation from Java records:
@Description
annotations provide field documentation@Nonnull
annotations mark required fields
Type-safe user input validation
- Result<T, E>: Represents success or failure without exceptions
- Validation Combinators: Compose multiple validations
- Type Safety: Compile-time validation of parameter types
- Error Accumulation: Collect multiple validation errors
Adding new Redis tools involves creating handler classes that integrate automatically with the MCP framework.
Decide whether to use Lettuce or Jedis :
public class MyHandler extends LettuceHandler {
// Implementation
}
public class MyHandler extends JedisHandler {
// Implementation
}
Create a Java record with validation annotations:
public record MyRequest(
@Nonnull
@Description("The Redis key to operate on")
String key,
@Description("Optional timeout in seconds")
Long timeout,
@Description("Operation mode")
String mode
) {
}
Define the MCP tool specification:
@Override
public McpSchema.Tool toolSchema() {
return new McpSchema.Tool(
"redis_my_command", // Tool name (must be unique)
"Description of what this tool does", // Tool description
recordToJSONSchema(MyRequest.class) // Auto-generated schema
);
}
Use the validation framework to safely parse arguments:
private static Result<MyRequest, McpSchema.CallToolResult> validateRequest(
Map<String, Object> arguments
) {
return Result.combine(
V.String(arguments, "key"), // Required string
V.OptionalLong(arguments, "timeout"), // Optional long
V.OptionalString(arguments, "mode") // Optional string
).with(MyRequest::new);
}
@Override
public McpSchema.CallToolResult handleSync(
McpSyncServerExchange exchange,
Map<String, Object> arguments
) {
var result = validateRequest(arguments);
if (result.isErr()) {
return result.unwrapErr();
}
var request = result.unwrap();
var jedis = getConnection();
var request = result.unwrap();
var value = jedis.myCommand(request.key);
return McpSchema.CallToolResult.builder()
.addTextContent("Result: " + value)
.isError(false)
.build();
}
@Override
public CompletableFuture<McpSchema.CallToolResult> handleAsync(
McpAsyncServerExchange exchange,
Map<String, Object> arguments
) {
var result = validateRequest(arguments);
if (result.isErr()) {
return CompletableFuture.completedFuture(result.unwrapErr());
}
var request = result.unwrap();
return getConnectionAsync()
.thenCompose(conn -> conn.async().myCommand(request.key))
.thenApply(value -> McpSchema.CallToolResult.builder()
.addTextContent("Result: " + value)
.isError(false)
.build());
});
}
If you are contributing a handler to this project, place your handler in the appropriate package:
- Lettuce handlers:
io.redis.mcp.java.core.handlers.lettuce
- Jedis handlers:
io.redis.mcp.java.core.handlers.jedis
Handlers in these packages will be automatically discovered and registered when users call:
RedisToolsRepository.getSyncToolSpecifications(String redisUrl, int maxConnections)
If you are developing your own handler in a custom package, pass the package name to the RedisToolsRepository
for
manual instantiation:
RedisToolsRepository.getSyncToolSpecifications(String redisUrl, int maxConnections, List<String> packages)
// Create tool specifications
var toolSpecs = RedisToolsRepository.getSyncToolSpecifications(
"redis://localhost:6379",
10 // max connections
);
// Register with the Java MCP server
mcpServer.
registerTools(toolSpecs);
var customPackages = List.of(
"com.mycompany.redis.handlers",
"io.redis.mcp.java.core.handlers.lettuce"
);
var toolSpecs = RedisToolsRepository.getSyncToolSpecifications(
"redis://localhost:6379",
10,
customPackages
);
The project includes a ready-to-run Spring Boot application that provides a complete MCP server with Redis tool integration.
Future Development: We are planning to develop Spring-specific annotations, annotation processors, and auto-configuration starters to streamline the integration of redis-mcp-java with Spring MCP in a future release. This will provide declarative configuration and automatic setup. For now, manual MCP server configuration is required, but the current approach is straightforward and provides full control over the setup.
Configure Redis connection settings in spring/src/main/resources/application.properties
:
# Redis MCP Configuration
redis.mcp.url=redis://localhost:6379
redis.mcp.pool.size=4
# Run the Spring Boot application
./gradlew :spring:bootRun
# Or build and run the JAR
./gradlew :spring:bootJar
java -jar spring/build/libs/spring-*.jar
You can override configuration via environment variables or command-line arguments:
# Via environment variables
export REDIS_MCP_URL=redis://production-redis:6379
export REDIS_MCP_POOL_SIZE=10
./gradlew :spring:bootRun
# Via command line arguments
./gradlew :spring:bootRun --args="--redis.mcp.url=redis://staging:6379 --redis.mcp.pool.size=8"
# Or with JAR
java -jar spring/build/libs/spring-*.jar --redis.mcp.url=redis://custom:6379
Once running, the MCP server provides:
- Server-Sent Events Endpoint:
http://localhost:8080/mcp/message
- Available Tools: Automatically discovered Redis handlers (GET, SET, JSON.GET, JSON.SET)