Merge pull request #1426 from olaservo/fix-redis-server-binary

Standardize build and binary references for server-redis
This commit is contained in:
Ola Hungerford 2025-04-18 07:07:50 -07:00 • committed by GitHub
commit fc99b57e63
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 57 additions and 47 deletions

4
package-lock.json generated
View file

@ -5795,7 +5795,7 @@
}, },
"src/redis": { "src/redis": {
"name": "@modelcontextprotocol/server-redis", "name": "@modelcontextprotocol/server-redis",
"version": "0.1.0", "version": "0.1.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.7.0", "@modelcontextprotocol/sdk": "^1.7.0",
@ -5804,7 +5804,7 @@
"redis": "^4.7.0" "redis": "^4.7.0"
}, },
"bin": { "bin": {
"redis": "build/index.js" "mcp-server-redis": "dist/index.js"
}, },
"devDependencies": { "devDependencies": {
"shx": "^0.3.4", "shx": "^0.3.4",

View file

@ -14,12 +14,18 @@ A Model Context Protocol server that provides access to Redis databases. This se
### Connection Errors ### Connection Errors
**ECONNREFUSED** **ECONNREFUSED**
- **Cause**: Redis server is not running or unreachable - **Cause**: Redis/Memurai server is not running or unreachable
- **Solution**: - **Solution**:
- Verify Redis is running: `redis-cli ping` should return "PONG" - Verify server is running:
- Check Redis service status: `systemctl status redis` (Linux) or `brew services list` (macOS) - Redis: `redis-cli ping` should return "PONG"
- Memurai (Windows): `memurai-cli ping` should return "PONG"
- Check service status:
- Linux: `systemctl status redis`
- macOS: `brew services list`
- Windows: Check Memurai in Services (services.msc)
- Ensure correct port (default 6379) is not blocked by firewall - Ensure correct port (default 6379) is not blocked by firewall
- Verify Redis URL format: `redis://hostname:port` - Verify Redis URL format: `redis://hostname:port`
- If `redis://localhost:6379` fails with ECONNREFUSED, try using the explicit IP: `redis://127.0.0.1:6379`
### Server Behavior ### Server Behavior
@ -57,7 +63,7 @@ To use this server with the Claude Desktop app, add the following configuration
### Docker ### Docker
* when running docker on macos, use host.docker.internal if the server is running on the host network (eg localhost) * when running docker on macos, use host.docker.internal if the server is running on the host network (eg localhost)
* Redis URL can be specified as an argument, defaults to "redis://localhost:6379" * Redis URL can be specified as an argument, defaults to "redis://localhost:6379" (use "redis://127.0.0.1:6379" if localhost fails)
```json ```json
{ {

View file

@ -1,6 +1,6 @@
{ {
"name": "@modelcontextprotocol/server-redis", "name": "@modelcontextprotocol/server-redis",
"version": "0.1.0", "version": "0.1.1",
"description": "MCP server for using Redis", "description": "MCP server for using Redis",
"license": "MIT", "license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)", "author": "Anthropic, PBC (https://anthropic.com)",
@ -8,13 +8,13 @@
"bugs": "https://github.com/modelcontextprotocol/servers/issues", "bugs": "https://github.com/modelcontextprotocol/servers/issues",
"type": "module", "type": "module",
"bin": { "bin": {
"redis": "./build/index.js" "mcp-server-redis": "dist/index.js"
}, },
"files": [ "files": [
"build" "dist"
], ],
"scripts": { "scripts": {
"build": "tsc && shx chmod +x build/*.js", "build": "tsc && shx chmod +x dist/*.js",
"prepare": "npm run build", "prepare": "npm run build",
"watch": "tsc --watch" "watch": "tsc --watch"
}, },

View file

@ -1,3 +1,5 @@
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { import {
@ -19,11 +21,14 @@ const redisClient = createClient({
socket: { socket: {
reconnectStrategy: (retries) => { reconnectStrategy: (retries) => {
if (retries >= MAX_RETRIES) { if (retries >= MAX_RETRIES) {
console.error(`Maximum retries (${MAX_RETRIES}) reached. Giving up.`); console.error(`[Redis Error] Maximum retries (${MAX_RETRIES}) reached. Giving up.`);
console.error(`[Redis Error] Connection: ${REDIS_URL}`);
return new Error('Max retries reached'); return new Error('Max retries reached');
} }
const delay = Math.min(Math.pow(2, retries) * MIN_RETRY_DELAY, MAX_RETRY_DELAY); 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`); console.error(`[Redis Retry] Attempt ${retries + 1}/${MAX_RETRIES} failed`);
console.error(`[Redis Retry] Next attempt in ${delay}ms`);
console.error(`[Redis Retry] Connection: ${REDIS_URL}`);
return delay; return delay;
} }
} }
@ -233,26 +238,27 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
} }
}); });
// Start the server // Set up Redis event handlers
async function main() { redisClient.on('error', (err: Error) => {
console.error(`[Redis Error] ${err.name}: ${err.message}`);
console.error(`[Redis Error] Connection: ${REDIS_URL}`);
console.error(`[Redis Error] Stack: ${err.stack}`);
});
redisClient.on('connect', () => {
console.error(`[Redis Connected] Successfully connected to ${REDIS_URL}`);
});
redisClient.on('reconnecting', () => {
console.error('[Redis Reconnecting] Connection lost, attempting to reconnect...');
});
redisClient.on('end', () => {
console.error('[Redis Disconnected] Connection closed');
});
async function runServer() {
try { try {
// Set up Redis event handlers
redisClient.on('error', (err: Error) => {
console.error('Redis Client Error:', err);
});
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 // Connect to Redis
await redisClient.connect(); await redisClient.connect();
@ -261,26 +267,25 @@ async function main() {
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); const err = error as Error;
await cleanup(); console.error("[Redis Fatal] Server initialization failed");
console.error(`[Redis Fatal] Error: ${err.name}: ${err.message}`);
console.error(`[Redis Fatal] Connection: ${REDIS_URL}`);
console.error(`[Redis Fatal] Stack: ${err.stack}`);
await redisClient.quit().catch(() => {});
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 // Handle process termination
process.on('SIGINT', cleanup); process.on('SIGINT', async () => {
process.on('SIGTERM', cleanup); await redisClient.quit().catch(() => {});
process.exit(0);
main().catch((error) => {
console.error("Fatal error in main():", error);
cleanup();
}); });
process.on('SIGTERM', async () => {
await redisClient.quit().catch(() => {});
process.exit(0);
});
runServer();

View file

@ -3,7 +3,7 @@
"target": "ES2022", "target": "ES2022",
"module": "Node16", "module": "Node16",
"moduleResolution": "Node16", "moduleResolution": "Node16",
"outDir": "./build", "outDir": "./dist",
"rootDir": "./src", "rootDir": "./src",
"strict": true, "strict": true,
"esModuleInterop": true, "esModuleInterop": true,
@ -13,4 +13,3 @@
"include": ["src/**/*"], "include": ["src/**/*"],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }