-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Summary
Add an MCP (Model Context Protocol) server mode to redisctl, enabling AI systems to manage Redis Cloud and Enterprise through a standardized tool interface.
What is MCP?
Model Context Protocol is an open standard for AI-tool integration introduced by Anthropic and adopted by OpenAI. It allows AI systems to discover and invoke external tools through a JSON-RPC interface.
┌─────────────────┐ JSON-RPC ┌─────────────────┐
│ AI System │ ◄──────────────────────► │ MCP Server │
│ (Claude, etc.) │ - list_tools │ (redisctl) │
│ │ - call_tool │ │
└─────────────────┘ └─────────────────┘
Why MCP vs Shell/CLI?
MCP provides advantages over shelling out to redisctl directly:
| Concern | Shell Out | MCP |
|---|---|---|
| Error handling | Parse stderr strings | Structured error types |
| Parameters | String interpolation | JSON schema validation |
| Discovery | Read --help | Programmatic tool listing |
| Async ops | Poll CLI repeatedly | Native async tracking |
| Output | Parse text/JSON | Typed responses |
Why This Matters
AI agent frameworks that need Redis Cloud/Enterprise access currently have to build and maintain their own API clients. redisctl-mcp eliminates this by exposing our existing, tested handlers as MCP tools.
What consumers get:
- 100% API coverage (50 handlers already implemented)
- Proper async operation handling (our
--waitlogic) - Context-rich error messages
- Credential isolation (keys never exposed to AI systems)
- Zero maintenance burden (we maintain it, they consume it)
Non-Goals
- Not a CLI replacement - The standard CLI remains the primary interface for humans
- Not embedding LLM logic - This exposes tools; reasoning happens in the AI system
- Not doing RAG/knowledge base - No Redis documentation or runbook retrieval
- Not auto-executing commands - AI decides, redisctl executes what it is asked
Prototype Spec
New Crate
crates/
└── redisctl-mcp/
├── Cargo.toml
└── src/
├── lib.rs # Server setup, handler registration
├── cloud_tools.rs # Cloud API tools
├── enterprise_tools.rs # Enterprise API tools
└── config.rs # Credential/profile loading
CLI Command
# Start MCP server (stdio transport, read-only by default)
redisctl mcp serve
# Explicit read-only mode (signals intent)
redisctl mcp serve --read-only
# With specific profile
redisctl mcp serve --profile production
# List available tools (debugging)
redisctl mcp toolsPhase 1 Tools (Read-Only)
Based on common AI agent needs for Redis management:
Redis Cloud (8 tools)
| Tool | Description | Handler |
|---|---|---|
cloud_account_get |
Account information | account.rs |
cloud_subscriptions_list |
List all subscriptions | subscriptions.rs |
cloud_subscription_get |
Subscription details | subscriptions.rs |
cloud_databases_list |
Databases in subscription | databases.rs |
cloud_database_get |
Database configuration | databases.rs |
cloud_tasks_list |
Recent async tasks | tasks.rs |
cloud_task_get |
Task status | tasks.rs |
cloud_logs_list |
Account activity logs | logs.rs |
Redis Enterprise (8 tools)
| Tool | Description | Handler |
|---|---|---|
enterprise_cluster_get |
Cluster information | cluster.rs |
enterprise_nodes_list |
List cluster nodes | nodes.rs |
enterprise_databases_list |
List all databases | bdbs.rs |
enterprise_database_get |
Database configuration | bdbs.rs |
enterprise_database_stats |
Database statistics | stats.rs |
enterprise_shards_list |
Shard placement | shards.rs |
enterprise_alerts_list |
Active alerts | alerts.rs |
enterprise_logs_get |
Cluster event logs | logs.rs |
Example Implementation
use rmcp::{ServerHandler, tool};
use redis_cloud::CloudClient;
pub struct RedisCloudTools {
client: CloudClient,
}
#[tool(
name = "cloud_databases_list",
description = "List all databases in a Redis Cloud subscription",
params(subscription_id = "The subscription ID")
)]
async fn list_databases(&self, subscription_id: u64) -> Result<Value> {
let dbs = self.client.databases().list(subscription_id).await?;
Ok(serde_json::to_value(dbs)?)
}
#[tool(
name = "cloud_database_get",
description = "Get configuration for a specific Redis Cloud database",
params(
subscription_id = "The subscription ID",
database_id = "The database ID"
)
)]
async fn get_database(&self, subscription_id: u64, database_id: u64) -> Result<Value> {
let db = self.client.databases().get(subscription_id, database_id).await?;
Ok(serde_json::to_value(db)?)
}Observability
All tool invocations should be logged for audit purposes:
[2024-01-15T10:23:45Z INFO redisctl_mcp] Tool called: cloud_database_get
[2024-01-15T10:23:45Z DEBUG redisctl_mcp] params: {"subscription_id": 12345, "database_id": 67890}
[2024-01-15T10:23:46Z INFO redisctl_mcp] result: success (235ms)
This provides an audit trail when AI systems are making infrastructure queries.
Integration Examples
Claude Desktop (~/.config/claude/claude_desktop_config.json):
{
"mcpServers": {
"redisctl": {
"command": "redisctl",
"args": ["mcp", "serve", "--profile", "production"]
}
}
}Docker Sidecar:
services:
my-agent:
image: my-ai-agent:latest
depends_on:
- redisctl-mcp
redisctl-mcp:
image: redis/redisctl:latest
command: ["mcp", "serve", "--transport", "sse", "--port", "3000"]
environment:
- REDIS_CLOUD_API_KEY=${REDIS_CLOUD_API_KEY}
- REDIS_CLOUD_SECRET_KEY=${REDIS_CLOUD_SECRET_KEY}Python MCP Client:
from mcp import ClientSession, StdioServerParameters
server = StdioServerParameters(
command="redisctl",
args=["mcp", "serve"],
env={"REDIS_CLOUD_API_KEY": "...", "REDIS_CLOUD_SECRET_KEY": "..."}
)
async with ClientSession(*server) as session:
# List tools
tools = await session.list_tools()
# Call a tool
result = await session.call_tool(
"cloud_database_get",
{"subscription_id": 12345, "database_id": 67890}
)Transport Options
stdio (Phase 1 default)
- Server runs as subprocess, communication via stdin/stdout
- How Claude Desktop and Claude Code work
- Zero network configuration
SSE/HTTP (Phase 4)
- Server runs as HTTP service on configurable port
- Enables remote access (MCP server on bastion host)
- Shared access (team members connecting to same server)
- Required for non-stdio clients
Dependencies
- rmcp - Official Rust MCP SDK
- Existing
redis-cloudandredis-enterprisecrates
Future Phases
| Phase | Scope |
|---|---|
| Phase 1 | 16 read-only tools, stdio transport |
| Phase 2 | Write operations with --write flag, safety confirmations |
| Phase 3 | MCP Resources for context (subscription summaries, cluster overview) |
| Phase 4 | SSE/HTTP transport for network access |
| Phase 5 | MCP Prompts for guided workflows |
References
Acceptance Criteria
-
redisctl-mcpcrate with 16 read-only tools -
redisctl mcp servecommand (stdio transport) -
redisctl mcp serve --read-onlyflag (default, explicit intent) -
redisctl mcp toolscommand to list available tools - Tool invocation logging for audit trail
- Works with Claude Desktop
- Documentation with setup instructions
- Integration tests