Merge pull request #1426 from olaservo/fix-redis-server-binary
Standardize build and binary references for server-redis
This commit is contained in:
commit
fc99b57e63
5 changed files with 57 additions and 47 deletions
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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"]
|
||||||
}
|
}
|
||||||
|
|
||||||
Loading…
Reference in a new issue