Skip to content

Commit d6a06c6

Browse files
authored
Merge branch 'main' into fix/gitlab-get-file-contents
2 parents f221e95 + fdcc967 commit d6a06c6

File tree

16 files changed

+757
-192
lines changed

16 files changed

+757
-192
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 347 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/brave-search/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ An MCP server implementation that integrates the Brave Search API, providing bot
3131
### Getting an API Key
3232
1. Sign up for a [Brave Search API account](https://brave.com/search/api/)
3333
2. Choose a plan (Free tier available with 2,000 queries/month)
34-
3. Generate your API key [from the developer dashboard](https://api.search.brave.com/app/keys)
34+
3. Generate your API key [from the developer dashboard](https://api-dashboard.search.brave.com/app/keys)
3535

3636
### Usage with Claude Desktop
3737
Add this to your `claude_desktop_config.json`:

src/everything/everything.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,22 +108,24 @@ export const createServer = () => {
108108
resources: { subscribe: true },
109109
tools: {},
110110
logging: {},
111+
completions: {},
111112
},
112113
}
113114
);
114115

115116
let subscriptions: Set<string> = new Set();
116117
let subsUpdateInterval: NodeJS.Timeout | undefined;
117-
// Set up update interval for subscribed resources
118+
let stdErrUpdateInterval: NodeJS.Timeout | undefined;
118119

120+
// Set up update interval for subscribed resources
119121
subsUpdateInterval = setInterval(() => {
120122
for (const uri of subscriptions) {
121123
server.notification({
122124
method: "notifications/resources/updated",
123125
params: { uri },
124126
});
125127
}
126-
}, 5000);
128+
}, 10000);
127129

128130
let logLevel: LoggingLevel = "debug";
129131
let logsUpdateInterval: NodeJS.Timeout | undefined;
@@ -152,7 +154,21 @@ export const createServer = () => {
152154
};
153155
if (!isMessageIgnored(message.params.level as LoggingLevel))
154156
server.notification(message);
155-
}, 15000);
157+
}, 20000);
158+
159+
160+
// Set up update interval for stderr messages
161+
stdErrUpdateInterval = setInterval(() => {
162+
const shortTimestamp = new Date().toLocaleTimeString([], {
163+
hour: '2-digit',
164+
minute: '2-digit',
165+
second: '2-digit'
166+
});
167+
server.notification({
168+
method: "notifications/stderr",
169+
params: { content: `${shortTimestamp}: A stderr message` },
170+
});
171+
}, 30000);
156172

157173
// Helper method to request sampling from client
158174
const requestSampling = async (
@@ -676,6 +692,7 @@ export const createServer = () => {
676692
const cleanup = async () => {
677693
if (subsUpdateInterval) clearInterval(subsUpdateInterval);
678694
if (logsUpdateInterval) clearInterval(logsUpdateInterval);
695+
if (stdErrUpdateInterval) clearInterval(stdErrUpdateInterval);
679696
};
680697

681698
return { server, cleanup };

src/everything/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"start:sse": "node dist/sse.js"
2222
},
2323
"dependencies": {
24-
"@modelcontextprotocol/sdk": "1.0.1",
24+
"@modelcontextprotocol/sdk": "^1.9.0",
2525
"express": "^4.21.1",
2626
"zod": "^3.23.8",
2727
"zod-to-json-schema": "^3.23.5"
@@ -31,4 +31,4 @@
3131
"shx": "^0.3.4",
3232
"typescript": "^5.6.2"
3333
}
34-
}
34+
}

src/redis/README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,18 @@ A Model Context Protocol server that provides access to Redis databases. This se
1414
### Connection Errors
1515

1616
**ECONNREFUSED**
17-
- **Cause**: Redis server is not running or unreachable
17+
- **Cause**: Redis/Memurai server is not running or unreachable
1818
- **Solution**:
19-
- Verify Redis is running: `redis-cli ping` should return "PONG"
20-
- Check Redis service status: `systemctl status redis` (Linux) or `brew services list` (macOS)
19+
- Verify server is running:
20+
- Redis: `redis-cli ping` should return "PONG"
21+
- Memurai (Windows): `memurai-cli ping` should return "PONG"
22+
- Check service status:
23+
- Linux: `systemctl status redis`
24+
- macOS: `brew services list`
25+
- Windows: Check Memurai in Services (services.msc)
2126
- Ensure correct port (default 6379) is not blocked by firewall
2227
- Verify Redis URL format: `redis://hostname:port`
28+
- If `redis://localhost:6379` fails with ECONNREFUSED, try using the explicit IP: `redis://127.0.0.1:6379`
2329

2430
### Server Behavior
2531

@@ -57,7 +63,7 @@ To use this server with the Claude Desktop app, add the following configuration
5763
### Docker
5864

5965
* when running docker on macos, use host.docker.internal if the server is running on the host network (eg localhost)
60-
* Redis URL can be specified as an argument, defaults to "redis://localhost:6379"
66+
* Redis URL can be specified as an argument, defaults to "redis://localhost:6379" (use "redis://127.0.0.1:6379" if localhost fails)
6167

6268
```json
6369
{

src/redis/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
{
22
"name": "@modelcontextprotocol/server-redis",
3-
"version": "0.1.0",
3+
"version": "0.1.1",
44
"description": "MCP server for using Redis",
55
"license": "MIT",
66
"author": "Anthropic, PBC (https://anthropic.com)",
77
"homepage": "https://modelcontextprotocol.io",
88
"bugs": "https://github.com/modelcontextprotocol/servers/issues",
99
"type": "module",
1010
"bin": {
11-
"redis": "./build/index.js"
11+
"mcp-server-redis": "dist/index.js"
1212
},
1313
"files": [
14-
"build"
14+
"dist"
1515
],
1616
"scripts": {
17-
"build": "tsc && shx chmod +x build/*.js",
17+
"build": "tsc && shx chmod +x dist/*.js",
1818
"prepare": "npm run build",
1919
"watch": "tsc --watch"
2020
},

src/redis/src/index.ts

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#!/usr/bin/env node
2+
13
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
24
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
35
import {
@@ -19,11 +21,14 @@ const redisClient = createClient({
1921
socket: {
2022
reconnectStrategy: (retries) => {
2123
if (retries >= MAX_RETRIES) {
22-
console.error(`Maximum retries (${MAX_RETRIES}) reached. Giving up.`);
24+
console.error(`[Redis Error] Maximum retries (${MAX_RETRIES}) reached. Giving up.`);
25+
console.error(`[Redis Error] Connection: ${REDIS_URL}`);
2326
return new Error('Max retries reached');
2427
}
2528
const delay = Math.min(Math.pow(2, retries) * MIN_RETRY_DELAY, MAX_RETRY_DELAY);
26-
console.error(`Reconnection attempt ${retries + 1}/${MAX_RETRIES} in ${delay}ms`);
29+
console.error(`[Redis Retry] Attempt ${retries + 1}/${MAX_RETRIES} failed`);
30+
console.error(`[Redis Retry] Next attempt in ${delay}ms`);
31+
console.error(`[Redis Retry] Connection: ${REDIS_URL}`);
2732
return delay;
2833
}
2934
}
@@ -233,26 +238,27 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
233238
}
234239
});
235240

236-
// Start the server
237-
async function main() {
238-
try {
239-
// Set up Redis event handlers
240-
redisClient.on('error', (err: Error) => {
241-
console.error('Redis Client Error:', err);
242-
});
241+
// Set up Redis event handlers
242+
redisClient.on('error', (err: Error) => {
243+
console.error(`[Redis Error] ${err.name}: ${err.message}`);
244+
console.error(`[Redis Error] Connection: ${REDIS_URL}`);
245+
console.error(`[Redis Error] Stack: ${err.stack}`);
246+
});
243247

244-
redisClient.on('connect', () => {
245-
console.error(`Connected to Redis at ${REDIS_URL}`);
246-
});
248+
redisClient.on('connect', () => {
249+
console.error(`[Redis Connected] Successfully connected to ${REDIS_URL}`);
250+
});
247251

248-
redisClient.on('reconnecting', () => {
249-
console.error('Attempting to reconnect to Redis...');
250-
});
252+
redisClient.on('reconnecting', () => {
253+
console.error('[Redis Reconnecting] Connection lost, attempting to reconnect...');
254+
});
251255

252-
redisClient.on('end', () => {
253-
console.error('Redis connection closed');
254-
});
256+
redisClient.on('end', () => {
257+
console.error('[Redis Disconnected] Connection closed');
258+
});
255259

260+
async function runServer() {
261+
try {
256262
// Connect to Redis
257263
await redisClient.connect();
258264

@@ -261,26 +267,25 @@ async function main() {
261267
await server.connect(transport);
262268
console.error("Redis MCP Server running on stdio");
263269
} catch (error) {
264-
console.error("Error during startup:", error);
265-
await cleanup();
270+
const err = error as Error;
271+
console.error("[Redis Fatal] Server initialization failed");
272+
console.error(`[Redis Fatal] Error: ${err.name}: ${err.message}`);
273+
console.error(`[Redis Fatal] Connection: ${REDIS_URL}`);
274+
console.error(`[Redis Fatal] Stack: ${err.stack}`);
275+
await redisClient.quit().catch(() => {});
276+
process.exit(1);
266277
}
267278
}
268279

269-
// Cleanup function
270-
async function cleanup() {
271-
try {
272-
await redisClient.quit();
273-
} catch (error) {
274-
console.error("Error during cleanup:", error);
275-
}
276-
process.exit(1);
277-
}
278-
279280
// Handle process termination
280-
process.on('SIGINT', cleanup);
281-
process.on('SIGTERM', cleanup);
281+
process.on('SIGINT', async () => {
282+
await redisClient.quit().catch(() => {});
283+
process.exit(0);
284+
});
282285

283-
main().catch((error) => {
284-
console.error("Fatal error in main():", error);
285-
cleanup();
286+
process.on('SIGTERM', async () => {
287+
await redisClient.quit().catch(() => {});
288+
process.exit(0);
286289
});
290+
291+
runServer();

src/redis/tsconfig.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"target": "ES2022",
44
"module": "Node16",
55
"moduleResolution": "Node16",
6-
"outDir": "./build",
6+
"outDir": "./dist",
77
"rootDir": "./src",
88
"strict": true,
99
"esModuleInterop": true,
@@ -13,4 +13,3 @@
1313
"include": ["src/**/*"],
1414
"exclude": ["node_modules"]
1515
}
16-

src/slack/README.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ MCP Server for the Slack API, enabling Claude to interact with Slack workspaces.
55
## Tools
66

77
1. `slack_list_channels`
8-
- List public channels in the workspace
8+
- List public or pre-defined channels in the workspace
99
- Optional inputs:
1010
- `limit` (number, default: 100, max: 200): Maximum number of channels to return
1111
- `cursor` (string): Pagination cursor for next page
@@ -78,6 +78,7 @@ MCP Server for the Slack API, enabling Claude to interact with Slack workspaces.
7878
- `chat:write` - Send messages as the app
7979
- `reactions:write` - Add emoji reactions to messages
8080
- `users:read` - View users and their basic information
81+
- `users.profile:read` - View detailed profiles about users
8182

8283
4. Install App to Workspace:
8384
- Click "Install to Workspace" and authorize the app
@@ -102,7 +103,8 @@ Add the following to your `claude_desktop_config.json`:
102103
],
103104
"env": {
104105
"SLACK_BOT_TOKEN": "xoxb-your-bot-token",
105-
"SLACK_TEAM_ID": "T01234567"
106+
"SLACK_TEAM_ID": "T01234567",
107+
"SLACK_CHANNEL_IDS": "C01234567, C76543210"
106108
}
107109
}
108110
}
@@ -124,17 +126,26 @@ Add the following to your `claude_desktop_config.json`:
124126
"SLACK_BOT_TOKEN",
125127
"-e",
126128
"SLACK_TEAM_ID",
129+
"-e",
130+
"SLACK_CHANNEL_IDS",
127131
"mcp/slack"
128132
],
129133
"env": {
130134
"SLACK_BOT_TOKEN": "xoxb-your-bot-token",
131-
"SLACK_TEAM_ID": "T01234567"
135+
"SLACK_TEAM_ID": "T01234567",
136+
"SLACK_CHANNEL_IDS": "C01234567, C76543210"
132137
}
133138
}
134139
}
135140
}
136141
```
137142

143+
### Environment Variables
144+
145+
1. `SLACK_BOT_TOKEN`: Required. The Bot User OAuth Token starting with `xoxb-`.
146+
2. `SLACK_TEAM_ID`: Required. Your Slack workspace ID starting with `T`.
147+
3. `SLACK_CHANNEL_IDS`: Optional. Comma-separated list of channel IDs to limit channel access (e.g., "C01234567, C76543210"). If not set, all public channels will be listed.
148+
138149
### Troubleshooting
139150

140151
If you encounter permission errors, verify that:

0 commit comments

Comments
 (0)