use redis_enterprise::debuginfo::{DebugInfoHandler, DebugInfoRequest};
use redis_enterprise::logs::{LogsHandler, LogsQuery};
use tower_mcp::{CallToolResult, ResultExt};
use crate::tools::macros::{enterprise_tool, mcp_module};
mcp_module! {
list_alerts => "list_alerts",
acknowledge_enterprise_alert => "acknowledge_enterprise_alert",
list_logs => "list_logs",
get_all_nodes_stats => "get_all_nodes_stats",
get_all_databases_stats => "get_all_databases_stats",
get_shard_stats => "get_shard_stats",
get_all_shards_stats => "get_all_shards_stats",
list_shards => "list_shards",
get_shard => "get_shard",
list_shards_by_database => "list_shards_by_database",
list_shards_by_node => "list_shards_by_node",
list_debug_info_tasks => "list_debug_info_tasks",
get_debug_info_status => "get_debug_info_status",
create_debug_info => "create_debug_info",
list_modules => "list_modules",
get_module => "get_module",
}
enterprise_tool!(read_only, list_alerts, "list_alerts",
"List all active alerts.",
{} => |client, _input| {
let handler = redis_enterprise::alerts::AlertHandler::new(client);
let alerts = handler.list().await.tool_context("Failed to list alerts")?;
CallToolResult::from_list("alerts", &alerts)
}
);
enterprise_tool!(write, acknowledge_enterprise_alert, "acknowledge_enterprise_alert",
"Acknowledge (clear) a specific alert by ID.",
{
pub alert_uid: String,
} => |client, input| {
let handler = redis_enterprise::alerts::AlertHandler::new(client);
handler
.clear(&input.alert_uid)
.await
.tool_context("Failed to acknowledge alert")?;
CallToolResult::from_serialize(&serde_json::json!({
"message": "Alert acknowledged successfully",
"alert_uid": input.alert_uid
}))
}
);
enterprise_tool!(read_only, list_logs, "list_logs",
"List cluster event logs. Supports filtering by time range and pagination.",
{
#[serde(default)]
pub start_time: Option<String>,
#[serde(default)]
pub end_time: Option<String>,
#[serde(default)]
pub order: Option<String>,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub offset: Option<u32>,
} => |client, input| {
let query = if input.start_time.is_some()
|| input.end_time.is_some()
|| input.order.is_some()
|| input.limit.is_some()
|| input.offset.is_some()
{
Some(LogsQuery {
stime: input.start_time,
etime: input.end_time,
order: input.order,
limit: input.limit,
offset: input.offset,
})
} else {
None
};
let handler = LogsHandler::new(client);
let logs = handler
.list(query)
.await
.tool_context("Failed to list logs")?;
CallToolResult::from_list("logs", &logs)
}
);
enterprise_tool!(read_only, get_all_nodes_stats, "get_all_nodes_stats",
"Get current statistics for all nodes including CPU, memory, and network metrics.",
{} => |client, _input| {
let handler = redis_enterprise::stats::StatsHandler::new(client);
let stats = handler
.nodes_last()
.await
.tool_context("Failed to get all nodes stats")?;
CallToolResult::from_serialize(&stats)
}
);
enterprise_tool!(read_only, get_all_databases_stats, "get_all_databases_stats",
"Get current statistics for all databases including latency, throughput, and memory usage.",
{} => |client, _input| {
let handler = redis_enterprise::stats::StatsHandler::new(client);
let stats = handler
.databases_last()
.await
.tool_context("Failed to get all databases stats")?;
CallToolResult::from_serialize(&stats)
}
);
enterprise_tool!(read_only, get_shard_stats, "get_shard_stats",
"Get current statistics for a specific shard.",
{
pub uid: u32,
} => |client, input| {
let handler = redis_enterprise::stats::StatsHandler::new(client);
let stats = handler
.shard(input.uid, None)
.await
.tool_context("Failed to get shard stats")?;
CallToolResult::from_serialize(&stats)
}
);
enterprise_tool!(read_only, get_all_shards_stats, "get_all_shards_stats",
"Get current statistics for all shards.",
{} => |client, _input| {
let handler = redis_enterprise::stats::StatsHandler::new(client);
let stats = handler
.shards(None)
.await
.tool_context("Failed to get all shards stats")?;
CallToolResult::from_serialize(&stats)
}
);
enterprise_tool!(read_only, list_shards, "list_shards",
"List all shards. Optionally filter by database UID.",
{
#[serde(default)]
pub database_uid: Option<u32>,
} => |client, input| {
let handler = redis_enterprise::shards::ShardHandler::new(client);
let shards = if let Some(db_uid) = input.database_uid {
handler
.list_by_database(db_uid)
.await
.tool_context("Failed to list shards")?
} else {
handler.list().await.tool_context("Failed to list shards")?
};
CallToolResult::from_list("shards", &shards)
}
);
enterprise_tool!(read_only, get_shard, "get_shard",
"Get shard details including role (master/replica), status, and assigned node.",
{
pub uid: String,
} => |client, input| {
let handler = redis_enterprise::shards::ShardHandler::new(client);
let shard = handler
.get(&input.uid)
.await
.tool_context("Failed to get shard")?;
CallToolResult::from_serialize(&shard)
}
);
enterprise_tool!(read_only, list_shards_by_database, "list_shards_by_database",
"List all shards for a specific database.",
{
pub bdb_uid: u32,
} => |client, input| {
let handler = redis_enterprise::shards::ShardHandler::new(client);
let shards = handler
.list_by_database(input.bdb_uid)
.await
.tool_context("Failed to list shards by database")?;
CallToolResult::from_list("shards", &shards)
}
);
enterprise_tool!(read_only, list_shards_by_node, "list_shards_by_node",
"List all shards on a specific node.",
{
pub node_uid: u32,
} => |client, input| {
let handler = redis_enterprise::shards::ShardHandler::new(client);
let shards = handler
.list_by_node(input.node_uid)
.await
.tool_context("Failed to list shards by node")?;
CallToolResult::from_list("shards", &shards)
}
);
enterprise_tool!(read_only, list_debug_info_tasks, "list_debug_info_tasks",
"List all debug info collection tasks and their statuses.",
{} => |client, _input| {
let handler = DebugInfoHandler::new(client);
let tasks = handler
.list()
.await
.tool_context("Failed to list debug info tasks")?;
CallToolResult::from_list("tasks", &tasks)
}
);
enterprise_tool!(read_only, get_debug_info_status, "get_debug_info_status",
"Get the status of a debug info collection task by ID.",
{
pub task_id: String,
} => |client, input| {
let handler = DebugInfoHandler::new(client);
let status = handler
.status(&input.task_id)
.await
.tool_context("Failed to get debug info status")?;
CallToolResult::from_serialize(&status)
}
);
enterprise_tool!(write, create_debug_info, "create_debug_info",
"Start a debug info collection task. Optionally scope to specific nodes or databases.",
{
#[serde(default)]
pub node_uids: Option<Vec<u32>>,
#[serde(default)]
pub bdb_uids: Option<Vec<u32>>,
} => |client, input| {
let request = DebugInfoRequest {
node_uids: input.node_uids,
bdb_uids: input.bdb_uids,
include_logs: None,
include_metrics: None,
include_configs: None,
time_range: None,
};
let handler = DebugInfoHandler::new(client);
let status = handler
.create(request)
.await
.tool_context("Failed to create debug info collection")?;
CallToolResult::from_serialize(&status)
}
);
enterprise_tool!(read_only, list_modules, "list_modules",
"List all installed Redis modules.",
{} => |client, _input| {
let handler = redis_enterprise::modules::ModuleHandler::new(client);
let modules = handler
.list()
.await
.tool_context("Failed to list modules")?;
CallToolResult::from_list("modules", &modules)
}
);
enterprise_tool!(read_only, get_module, "get_module",
"Get details of a specific Redis module by UID.",
{
pub uid: String,
} => |client, input| {
let handler = redis_enterprise::modules::ModuleHandler::new(client);
let module = handler
.get(&input.uid)
.await
.tool_context("Failed to get module")?;
CallToolResult::from_serialize(&module)
}
);