mirror of
https://github.com/modelcontextprotocol/servers.git
synced 2026-04-24 23:05:21 +02:00
Merge pull request #1166 from modelcontextprotocol/force-bump-redis-and-memory
Add missing capabilities and improve connection handling for server-redis
This commit is contained in:
@@ -2,6 +2,31 @@
|
|||||||
|
|
||||||
A Model Context Protocol server that provides access to Redis databases. This server enables LLMs to interact with Redis key-value stores through a set of standardized tools.
|
A Model Context Protocol server that provides access to Redis databases. This server enables LLMs to interact with Redis key-value stores through a set of standardized tools.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
1. Redis server must be installed and running
|
||||||
|
- [Download Redis](https://redis.io/download)
|
||||||
|
- For Windows users: Use [Windows Subsystem for Linux (WSL)](https://redis.io/docs/getting-started/installation/install-redis-on-windows/) or [Memurai](https://www.memurai.com/) (Redis-compatible Windows server)
|
||||||
|
- Default port: 6379
|
||||||
|
|
||||||
|
## Common Issues & Solutions
|
||||||
|
|
||||||
|
### Connection Errors
|
||||||
|
|
||||||
|
**ECONNREFUSED**
|
||||||
|
- **Cause**: Redis server is not running or unreachable
|
||||||
|
- **Solution**:
|
||||||
|
- Verify Redis is running: `redis-cli ping` should return "PONG"
|
||||||
|
- Check Redis service status: `systemctl status redis` (Linux) or `brew services list` (macOS)
|
||||||
|
- Ensure correct port (default 6379) is not blocked by firewall
|
||||||
|
- Verify Redis URL format: `redis://hostname:port`
|
||||||
|
|
||||||
|
### Server Behavior
|
||||||
|
|
||||||
|
- The server implements exponential backoff with a maximum of 5 retries
|
||||||
|
- Initial retry delay: 1 second, maximum delay: 30 seconds
|
||||||
|
- Server will exit after max retries to prevent infinite reconnection loops
|
||||||
|
|
||||||
## Components
|
## Components
|
||||||
|
|
||||||
### Tools
|
### Tools
|
||||||
|
|||||||
@@ -7,10 +7,26 @@ import {
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { createClient } from 'redis';
|
import { createClient } from 'redis';
|
||||||
|
|
||||||
// Get Redis URL from command line args or use default
|
// Configuration
|
||||||
const REDIS_URL = process.argv[2] || "redis://localhost:6379";
|
const REDIS_URL = process.argv[2] || "redis://localhost:6379";
|
||||||
|
const MAX_RETRIES = 5;
|
||||||
|
const MIN_RETRY_DELAY = 1000; // 1 second
|
||||||
|
const MAX_RETRY_DELAY = 30000; // 30 seconds
|
||||||
|
|
||||||
|
// Create Redis client with retry strategy
|
||||||
const redisClient = createClient({
|
const redisClient = createClient({
|
||||||
url: REDIS_URL
|
url: REDIS_URL,
|
||||||
|
socket: {
|
||||||
|
reconnectStrategy: (retries) => {
|
||||||
|
if (retries >= MAX_RETRIES) {
|
||||||
|
console.error(`Maximum retries (${MAX_RETRIES}) reached. Giving up.`);
|
||||||
|
return new Error('Max retries reached');
|
||||||
|
}
|
||||||
|
const delay = Math.min(Math.pow(2, retries) * MIN_RETRY_DELAY, MAX_RETRY_DELAY);
|
||||||
|
console.error(`Reconnection attempt ${retries + 1}/${MAX_RETRIES} in ${delay}ms`);
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Define Zod schemas for validation
|
// Define Zod schemas for validation
|
||||||
@@ -36,7 +52,12 @@ const ListArgumentsSchema = z.object({
|
|||||||
const server = new Server(
|
const server = new Server(
|
||||||
{
|
{
|
||||||
name: "redis",
|
name: "redis",
|
||||||
version: "1.0.0"
|
version: "0.0.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
capabilities: {
|
||||||
|
tools: {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -215,22 +236,51 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
// Start the server
|
// Start the server
|
||||||
async function main() {
|
async function main() {
|
||||||
try {
|
try {
|
||||||
// Connect to Redis
|
// Set up Redis event handlers
|
||||||
redisClient.on('error', (err: Error) => console.error('Redis Client Error', err));
|
redisClient.on('error', (err: Error) => {
|
||||||
await redisClient.connect();
|
console.error('Redis Client Error:', err);
|
||||||
console.error(`Connected to Redis successfully at ${REDIS_URL}`);
|
});
|
||||||
|
|
||||||
|
redisClient.on('connect', () => {
|
||||||
|
console.error(`Connected to Redis at ${REDIS_URL}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
redisClient.on('reconnecting', () => {
|
||||||
|
console.error('Attempting to reconnect to Redis...');
|
||||||
|
});
|
||||||
|
|
||||||
|
redisClient.on('end', () => {
|
||||||
|
console.error('Redis connection closed');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Connect to Redis
|
||||||
|
await redisClient.connect();
|
||||||
|
|
||||||
|
// Set up MCP server
|
||||||
const transport = new StdioServerTransport();
|
const transport = new StdioServerTransport();
|
||||||
await server.connect(transport);
|
await server.connect(transport);
|
||||||
console.error("Redis MCP Server running on stdio");
|
console.error("Redis MCP Server running on stdio");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error during startup:", error);
|
console.error("Error during startup:", error);
|
||||||
await redisClient.quit();
|
await cleanup();
|
||||||
process.exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cleanup function
|
||||||
|
async function cleanup() {
|
||||||
|
try {
|
||||||
|
await redisClient.quit();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error during cleanup:", error);
|
||||||
|
}
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle process termination
|
||||||
|
process.on('SIGINT', cleanup);
|
||||||
|
process.on('SIGTERM', cleanup);
|
||||||
|
|
||||||
main().catch((error) => {
|
main().catch((error) => {
|
||||||
console.error("Fatal error in main():", error);
|
console.error("Fatal error in main():", error);
|
||||||
redisClient.quit().finally(() => process.exit(1));
|
cleanup();
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user