Skip to content

Commit dae9883

Browse files
authored
Merge branch 'main' into bugfix/github-issue-label-null-description
2 parents 6209bed + 97e3554 commit dae9883

File tree

9 files changed

+1153
-130
lines changed

9 files changed

+1153
-130
lines changed

README.md

Lines changed: 173 additions & 6 deletions
Large diffs are not rendered by default.

package-lock.json

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

src/everything/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,20 @@ Resource features:
9696
- `style` (string): Output style preference
9797
- Returns: Multi-turn conversation with images
9898

99+
### Logging
100+
101+
The server sends random-leveled log messages every 15 seconds, e.g.:
102+
103+
```json
104+
{
105+
"method": "notifications/message",
106+
"params": {
107+
"level": "info",
108+
"data": "Info-level message"
109+
}
110+
}
111+
```
112+
99113
## Usage with Claude Desktop
100114

101115
Add to your `claude_desktop_config.json`:

src/everything/everything.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
ListResourcesRequestSchema,
1010
ListResourceTemplatesRequestSchema,
1111
ListToolsRequestSchema,
12+
LoggingLevel,
1213
ReadResourceRequestSchema,
1314
Resource,
1415
SetLevelRequestSchema,
@@ -99,10 +100,10 @@ export const createServer = () => {
99100
);
100101

101102
let subscriptions: Set<string> = new Set();
102-
let updateInterval: NodeJS.Timeout | undefined;
103-
103+
let subsUpdateInterval: NodeJS.Timeout | undefined;
104104
// Set up update interval for subscribed resources
105-
updateInterval = setInterval(() => {
105+
106+
subsUpdateInterval = setInterval(() => {
106107
for (const uri of subscriptions) {
107108
server.notification({
108109
method: "notifications/resources/updated",
@@ -111,6 +112,34 @@ export const createServer = () => {
111112
}
112113
}, 5000);
113114

115+
let logLevel: LoggingLevel = "debug";
116+
let logsUpdateInterval: NodeJS.Timeout | undefined;
117+
const messages = [
118+
{level: "debug", data: "Debug-level message"},
119+
{level: "info", data: "Info-level message"},
120+
{level: "notice", data: "Notice-level message"},
121+
{level: "warning", data: "Warning-level message"},
122+
{level: "error", data: "Error-level message"},
123+
{level: "critical", data: "Critical-level message"},
124+
{level: "alert", data: "Alert level-message"},
125+
{level: "emergency", data: "Emergency-level message"}
126+
]
127+
128+
const isMessageIgnored = (level:LoggingLevel):boolean => {
129+
const currentLevel = messages.findIndex((msg) => logLevel === msg.level);
130+
const messageLevel = messages.findIndex((msg) => level === msg.level);
131+
return messageLevel < currentLevel;
132+
}
133+
134+
// Set up update interval for random log messages
135+
logsUpdateInterval = setInterval(() => {
136+
let message = {
137+
method: "notifications/message",
138+
params: messages[Math.floor(Math.random() * messages.length)],
139+
}
140+
if (!isMessageIgnored(message.params.level as LoggingLevel)) server.notification(message);
141+
}, 15000);
142+
114143
// Helper method to request sampling from client
115144
const requestSampling = async (
116145
context: string,
@@ -451,7 +480,7 @@ export const createServer = () => {
451480

452481
if (name === ToolName.ANNOTATED_MESSAGE) {
453482
const { messageType, includeImage } = AnnotatedMessageSchema.parse(args);
454-
483+
455484
const content = [];
456485

457486
// Main message with different priorities/audiences based on type
@@ -511,7 +540,7 @@ export const createServer = () => {
511540
if (!resourceId) return { completion: { values: [] } };
512541

513542
// Filter resource IDs that start with the input value
514-
const values = EXAMPLE_COMPLETIONS.resourceId.filter(id =>
543+
const values = EXAMPLE_COMPLETIONS.resourceId.filter(id =>
515544
id.startsWith(argument.value)
516545
);
517546
return { completion: { values, hasMore: false, total: values.length } };
@@ -522,7 +551,7 @@ export const createServer = () => {
522551
const completions = EXAMPLE_COMPLETIONS[argument.name as keyof typeof EXAMPLE_COMPLETIONS];
523552
if (!completions) return { completion: { values: [] } };
524553

525-
const values = completions.filter(value =>
554+
const values = completions.filter(value =>
526555
value.startsWith(argument.value)
527556
);
528557
return { completion: { values, hasMore: false, total: values.length } };
@@ -533,24 +562,24 @@ export const createServer = () => {
533562

534563
server.setRequestHandler(SetLevelRequestSchema, async (request) => {
535564
const { level } = request.params;
565+
logLevel = level;
536566

537567
// Demonstrate different log levels
538568
await server.notification({
539569
method: "notifications/message",
540570
params: {
541571
level: "debug",
542572
logger: "test-server",
543-
data: `Logging level set to: ${level}`,
573+
data: `Logging level set to: ${logLevel}`,
544574
},
545575
});
546576

547577
return {};
548578
});
549579

550580
const cleanup = async () => {
551-
if (updateInterval) {
552-
clearInterval(updateInterval);
553-
}
581+
if (subsUpdateInterval) clearInterval(subsUpdateInterval);
582+
if (logsUpdateInterval) clearInterval(logsUpdateInterval);
554583
};
555584

556585
return { server, cleanup };

src/filesystem/README.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,16 @@ Node.js server implementing Model Context Protocol (MCP) for filesystem operatio
4141
- Features:
4242
- Line-based and multi-line content matching
4343
- Whitespace normalization with indentation preservation
44-
- Fuzzy matching with confidence scoring
4544
- Multiple simultaneous edits with correct positioning
4645
- Indentation style detection and preservation
4746
- Git-style diff output with context
4847
- Preview changes with dry run mode
49-
- Failed match debugging with confidence scores
5048
- Inputs:
5149
- `path` (string): File to edit
5250
- `edits` (array): List of edit operations
5351
- `oldText` (string): Text to search for (can be substring)
5452
- `newText` (string): Text to replace with
5553
- `dryRun` (boolean): Preview changes without applying (default: false)
56-
- `options` (object): Optional formatting settings
57-
- `preserveIndentation` (boolean): Keep existing indentation (default: true)
58-
- `normalizeWhitespace` (boolean): Normalize spaces while preserving structure (default: true)
59-
- `partialMatch` (boolean): Enable fuzzy matching (default: true)
6054
- Returns detailed diff and match information for dry runs, otherwise applies changes
6155
- Best Practice: Always use dryRun first to preview changes before applying them
6256

src/filesystem/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const allowedDirectories = args.map(dir =>
4242
// Validate that all directories exist and are accessible
4343
await Promise.all(args.map(async (dir) => {
4444
try {
45-
const stats = await fs.stat(dir);
45+
const stats = await fs.stat(expandHome(dir));
4646
if (!stats.isDirectory()) {
4747
console.error(`Error: ${dir} is not a directory`);
4848
process.exit(1);

src/git/uv.lock

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

src/github/index.ts

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,51 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
149149
name: "get_issue",
150150
description: "Get details of a specific issue in a GitHub repository.",
151151
inputSchema: zodToJsonSchema(issues.GetIssueSchema)
152+
},
153+
{
154+
name: "get_pull_request",
155+
description: "Get details of a specific pull request",
156+
inputSchema: zodToJsonSchema(pulls.GetPullRequestSchema)
157+
},
158+
{
159+
name: "list_pull_requests",
160+
description: "List and filter repository pull requests",
161+
inputSchema: zodToJsonSchema(pulls.ListPullRequestsSchema)
162+
},
163+
{
164+
name: "create_pull_request_review",
165+
description: "Create a review on a pull request",
166+
inputSchema: zodToJsonSchema(pulls.CreatePullRequestReviewSchema)
167+
},
168+
{
169+
name: "merge_pull_request",
170+
description: "Merge a pull request",
171+
inputSchema: zodToJsonSchema(pulls.MergePullRequestSchema)
172+
},
173+
{
174+
name: "get_pull_request_files",
175+
description: "Get the list of files changed in a pull request",
176+
inputSchema: zodToJsonSchema(pulls.GetPullRequestFilesSchema)
177+
},
178+
{
179+
name: "get_pull_request_status",
180+
description: "Get the combined status of all status checks for a pull request",
181+
inputSchema: zodToJsonSchema(pulls.GetPullRequestStatusSchema)
182+
},
183+
{
184+
name: "update_pull_request_branch",
185+
description: "Update a pull request branch with the latest changes from the base branch",
186+
inputSchema: zodToJsonSchema(pulls.UpdatePullRequestBranchSchema)
187+
},
188+
{
189+
name: "get_pull_request_comments",
190+
description: "Get the review comments on a pull request",
191+
inputSchema: zodToJsonSchema(pulls.GetPullRequestCommentsSchema)
192+
},
193+
{
194+
name: "get_pull_request_reviews",
195+
description: "Get the reviews on a pull request",
196+
inputSchema: zodToJsonSchema(pulls.GetPullRequestReviewsSchema)
152197
}
153198
],
154199
};
@@ -335,6 +380,82 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
335380
};
336381
}
337382

383+
case "get_pull_request": {
384+
const args = pulls.GetPullRequestSchema.parse(request.params.arguments);
385+
const pullRequest = await pulls.getPullRequest(args.owner, args.repo, args.pull_number);
386+
return {
387+
content: [{ type: "text", text: JSON.stringify(pullRequest, null, 2) }],
388+
};
389+
}
390+
391+
case "list_pull_requests": {
392+
const args = pulls.ListPullRequestsSchema.parse(request.params.arguments);
393+
const { owner, repo, ...options } = args;
394+
const pullRequests = await pulls.listPullRequests(owner, repo, options);
395+
return {
396+
content: [{ type: "text", text: JSON.stringify(pullRequests, null, 2) }],
397+
};
398+
}
399+
400+
case "create_pull_request_review": {
401+
const args = pulls.CreatePullRequestReviewSchema.parse(request.params.arguments);
402+
const { owner, repo, pull_number, ...options } = args;
403+
const review = await pulls.createPullRequestReview(owner, repo, pull_number, options);
404+
return {
405+
content: [{ type: "text", text: JSON.stringify(review, null, 2) }],
406+
};
407+
}
408+
409+
case "merge_pull_request": {
410+
const args = pulls.MergePullRequestSchema.parse(request.params.arguments);
411+
const { owner, repo, pull_number, ...options } = args;
412+
const result = await pulls.mergePullRequest(owner, repo, pull_number, options);
413+
return {
414+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
415+
};
416+
}
417+
418+
case "get_pull_request_files": {
419+
const args = pulls.GetPullRequestFilesSchema.parse(request.params.arguments);
420+
const files = await pulls.getPullRequestFiles(args.owner, args.repo, args.pull_number);
421+
return {
422+
content: [{ type: "text", text: JSON.stringify(files, null, 2) }],
423+
};
424+
}
425+
426+
case "get_pull_request_status": {
427+
const args = pulls.GetPullRequestStatusSchema.parse(request.params.arguments);
428+
const status = await pulls.getPullRequestStatus(args.owner, args.repo, args.pull_number);
429+
return {
430+
content: [{ type: "text", text: JSON.stringify(status, null, 2) }],
431+
};
432+
}
433+
434+
case "update_pull_request_branch": {
435+
const args = pulls.UpdatePullRequestBranchSchema.parse(request.params.arguments);
436+
const { owner, repo, pull_number, expected_head_sha } = args;
437+
await pulls.updatePullRequestBranch(owner, repo, pull_number, expected_head_sha);
438+
return {
439+
content: [{ type: "text", text: JSON.stringify({ success: true }, null, 2) }],
440+
};
441+
}
442+
443+
case "get_pull_request_comments": {
444+
const args = pulls.GetPullRequestCommentsSchema.parse(request.params.arguments);
445+
const comments = await pulls.getPullRequestComments(args.owner, args.repo, args.pull_number);
446+
return {
447+
content: [{ type: "text", text: JSON.stringify(comments, null, 2) }],
448+
};
449+
}
450+
451+
case "get_pull_request_reviews": {
452+
const args = pulls.GetPullRequestReviewsSchema.parse(request.params.arguments);
453+
const reviews = await pulls.getPullRequestReviews(args.owner, args.repo, args.pull_number);
454+
return {
455+
content: [{ type: "text", text: JSON.stringify(reviews, null, 2) }],
456+
};
457+
}
458+
338459
default:
339460
throw new Error(`Unknown tool: ${request.params.name}`);
340461
}

src/redis/package.json

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
11
{
2-
"name": "redis",
3-
"version": "1.0.0",
4-
"main": "index.js",
2+
"name": "@modelcontextprotocol/server-redis",
3+
"version": "0.1.0",
4+
"description": "MCP server for using Redis",
5+
"license": "MIT",
6+
"author": "Anthropic, PBC (https://anthropic.com)",
7+
"homepage": "https://modelcontextprotocol.io",
8+
"bugs": "https://github.com/modelcontextprotocol/servers/issues",
59
"type": "module",
610
"bin": {
711
"redis": "./build/index.js"
812
},
9-
"scripts": {
10-
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\""
11-
},
1213
"files": [
1314
"build"
1415
],
15-
"keywords": [],
16-
"author": "",
17-
"license": "ISC",
18-
"description": "",
19-
"devDependencies": {
20-
"@types/node": "^22.10.2",
21-
"typescript": "^5.7.2"
16+
"scripts": {
17+
"build": "tsc && shx chmod +x build/*.js",
18+
"prepare": "npm run build",
19+
"watch": "tsc --watch"
2220
},
2321
"dependencies": {
24-
"@modelcontextprotocol/sdk": "^0.4.0",
22+
"@modelcontextprotocol/sdk": "^1.7.0",
23+
"@types/node": "^22.10.2",
2524
"@types/redis": "^4.0.10",
2625
"redis": "^4.7.0"
26+
},
27+
"devDependencies": {
28+
"shx": "^0.3.4",
29+
"typescript": "^5.7.2"
2730
}
2831
}

0 commit comments

Comments
 (0)