From deffdb94acd99043817d6e36f9f770bab31dcf91 Mon Sep 17 00:00:00 2001 From: Enrico Ballardini Date: Tue, 3 Dec 2024 22:52:29 +0100 Subject: [PATCH 01/11] directory_tree base implementation --- src/filesystem/index.ts | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/filesystem/index.ts b/src/filesystem/index.ts index b4c4e92d..062b6e16 100644 --- a/src/filesystem/index.ts +++ b/src/filesystem/index.ts @@ -114,6 +114,10 @@ const ListDirectoryArgsSchema = z.object({ path: z.string(), }); +const DirectoryTreeArgsSchema = z.object({ + path: z.string(), +}); + const MoveFileArgsSchema = z.object({ source: z.string(), destination: z.string(), @@ -251,6 +255,16 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { "finding specific files within a directory. Only works within allowed directories.", inputSchema: zodToJsonSchema(ListDirectoryArgsSchema) as ToolInput, }, + { + name: "directory_tree", + description: + "Get a recursive tree view of files and directories starting from a specified path. " + + "Results are formatted in a hierarchical ASCII tree structure with proper indentation " + + "using pipes and dashes (│ ├ └ ─). Files and directories are distinguished " + + "with [F] and [D] prefixes. This tool provides a comprehensive visualization of nested " + + "directory structures. Only works within allowed directories.", + inputSchema: zodToJsonSchema(DirectoryTreeArgsSchema) as ToolInput, + }, { name: "move_file", description: @@ -373,6 +387,40 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { }; } + case "directory_tree": { + const parsed = ListDirectoryArgsSchema.safeParse(args); + if (!parsed.success) { + throw new Error(`Invalid arguments for directory_tree: ${parsed.error}`); + } + + async function buildTree(currentPath: string, prefix = ""): Promise { + const validPath = await validatePath(currentPath); + const entries = await fs.readdir(validPath, {withFileTypes: true}); + let result = ""; + + for (let i = 0; i < entries.length; i++) { + const entry = entries[i]; + const isLast = i === entries.length - 1; + const connector = isLast ? "└── " : "├── "; + const newPrefix = prefix + (isLast ? " " : "│ "); + + result += `${prefix}${connector}${entry.isDirectory() ? "[D]" : "[F]"} ${entry.name}\n`; + + if (entry.isDirectory()) { + const subPath = path.join(currentPath, entry.name); + result += await buildTree(subPath, newPrefix); + } + } + + return result; + } + + const treeOutput = await buildTree(parsed.data.path); + return { + content: [{type: "text", text: treeOutput}], + }; + } + case "move_file": { const parsed = MoveFileArgsSchema.safeParse(args); if (!parsed.success) { From 4fb85e5aa71760cfcc080b31591d67524a82fcfa Mon Sep 17 00:00:00 2001 From: idoubi Date: Thu, 5 Dec 2024 23:41:31 +0800 Subject: [PATCH 02/11] add mcp-server-chatsum --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 78f569f1..12c0b1bd 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ A growing set of community-developed and maintained servers demonstrates various - **[Any Chat Completions](https://github.com/pyroprompts/any-chat-completions-mcp)** - Interact with any OpenAI SDK Compatible Chat Completions API like OpenAI, Perplexity, Groq, xAI and many more. - **[Windows CLI](https://github.com/SimonB97/win-cli-mcp-server)** - MCP server for secure command-line interactions on Windows systems, enabling controlled access to PowerShell, CMD, and Git Bash shells. - **[OpenRPC](https://github.com/shanejonas/openrpc-mpc-server)** - Interact with and discover JSON-RPC APIs via [OpenRPC](https://open-rpc.org). +- **[ChatSum](https://github.com/mcpservers/mcp-server-chatsum)** - Query and Summarize wechat messages with LLM. ## 📚 Resources From 188cd7653c5360f7ffcdf2da29acb050d4858363 Mon Sep 17 00:00:00 2001 From: lamemind Date: Mon, 9 Dec 2024 21:06:10 +0100 Subject: [PATCH 03/11] directory_tree outputs JSON --- src/filesystem/index.ts | 86 ++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/src/filesystem/index.ts b/src/filesystem/index.ts index 912ae5fc..04d25755 100644 --- a/src/filesystem/index.ts +++ b/src/filesystem/index.ts @@ -34,7 +34,7 @@ function expandHome(filepath: string): string { } // Store allowed directories in normalized form -const allowedDirectories = args.map(dir => +const allowedDirectories = args.map(dir => normalizePath(path.resolve(expandHome(dir))) ); @@ -58,7 +58,7 @@ async function validatePath(requestedPath: string): Promise { const absolute = path.isAbsolute(expandedPath) ? path.resolve(expandedPath) : path.resolve(process.cwd(), expandedPath); - + const normalizedRequested = normalizePath(absolute); // Check if path is within allowed directories @@ -195,7 +195,7 @@ async function searchFiles( for (const entry of entries) { const fullPath = path.join(currentPath, entry.name); - + try { // Validate each path before processing await validatePath(fullPath); @@ -227,7 +227,7 @@ function createUnifiedDiff(originalContent: string, newContent: string, filepath // Ensure consistent line endings for diff const normalizedOriginal = normalizeLineEndings(originalContent); const normalizedNew = normalizeLineEndings(newContent); - + return createTwoFilesPatch( filepath, filepath, @@ -245,33 +245,33 @@ async function applyFileEdits( ): Promise { // Read file content and normalize line endings const content = normalizeLineEndings(await fs.readFile(filePath, 'utf-8')); - + // Apply edits sequentially let modifiedContent = content; for (const edit of edits) { const normalizedOld = normalizeLineEndings(edit.oldText); const normalizedNew = normalizeLineEndings(edit.newText); - + // If exact match exists, use it if (modifiedContent.includes(normalizedOld)) { modifiedContent = modifiedContent.replace(normalizedOld, normalizedNew); continue; } - + // Otherwise, try line-by-line matching with flexibility for whitespace const oldLines = normalizedOld.split('\n'); const contentLines = modifiedContent.split('\n'); let matchFound = false; - + for (let i = 0; i <= contentLines.length - oldLines.length; i++) { const potentialMatch = contentLines.slice(i, i + oldLines.length); - + // Compare lines with normalized whitespace const isMatch = oldLines.every((oldLine, j) => { const contentLine = potentialMatch[j]; return oldLine.trim() === contentLine.trim(); }); - + if (isMatch) { // Preserve original indentation of first line const originalIndent = contentLines[i].match(/^\s*/)?.[0] || ''; @@ -286,33 +286,33 @@ async function applyFileEdits( } return line; }); - + contentLines.splice(i, oldLines.length, ...newLines); modifiedContent = contentLines.join('\n'); matchFound = true; break; } } - + if (!matchFound) { throw new Error(`Could not find exact match for edit:\n${edit.oldText}`); } } - + // Create unified diff const diff = createUnifiedDiff(content, modifiedContent, filePath); - + // Format diff with appropriate number of backticks let numBackticks = 3; while (diff.includes('`'.repeat(numBackticks))) { numBackticks++; } const formattedDiff = `${'`'.repeat(numBackticks)}diff\n${diff}${'`'.repeat(numBackticks)}\n\n`; - + if (!dryRun) { await fs.writeFile(filePath, modifiedContent, 'utf-8'); } - + return formattedDiff; } @@ -376,11 +376,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { { name: "directory_tree", description: - "Get a recursive tree view of files and directories starting from a specified path. " + - "Results are formatted in a hierarchical ASCII tree structure with proper indentation " + - "using pipes and dashes (│ ├ └ ─). Files and directories are distinguished " + - "with [F] and [D] prefixes. This tool provides a comprehensive visualization of nested " + - "directory structures. Only works within allowed directories.", + "Get a recursive tree view of files and directories as a JSON structure. " + + "Each entry includes 'name', 'type' (file/directory), and 'children' for directories. " + + "Files have no children array, while directories always have a children array (which may be empty). " + + "The output is formatted with 2-space indentation for readability. Only works within allowed directories.", inputSchema: zodToJsonSchema(DirectoryTreeArgsSchema) as ToolInput, }, { @@ -413,7 +412,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { }, { name: "list_allowed_directories", - description: + description: "Returns the list of directories that this server is allowed to access. " + "Use this to understand which directories are available before trying to access files.", inputSchema: { @@ -518,36 +517,45 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { } case "directory_tree": { - const parsed = ListDirectoryArgsSchema.safeParse(args); + const parsed = DirectoryTreeArgsSchema.safeParse(args); if (!parsed.success) { throw new Error(`Invalid arguments for directory_tree: ${parsed.error}`); } - async function buildTree(currentPath: string, prefix = ""): Promise { + interface TreeEntry { + name: string; + type: 'file' | 'directory'; + children?: TreeEntry[]; + } + + async function buildTree(currentPath: string): Promise { const validPath = await validatePath(currentPath); const entries = await fs.readdir(validPath, {withFileTypes: true}); - let result = ""; + const result: TreeEntry[] = []; - for (let i = 0; i < entries.length; i++) { - const entry = entries[i]; - const isLast = i === entries.length - 1; - const connector = isLast ? "└── " : "├── "; - const newPrefix = prefix + (isLast ? " " : "│ "); - - result += `${prefix}${connector}${entry.isDirectory() ? "[D]" : "[F]"} ${entry.name}\n`; + for (const entry of entries) { + const entryData: TreeEntry = { + name: entry.name, + type: entry.isDirectory() ? 'directory' : 'file' + }; if (entry.isDirectory()) { const subPath = path.join(currentPath, entry.name); - result += await buildTree(subPath, newPrefix); + entryData.children = await buildTree(subPath); } + + result.push(entryData); } return result; } - const treeOutput = await buildTree(parsed.data.path); + const treeData = await buildTree(parsed.data.path); return { - content: [{type: "text", text: treeOutput}], + content: [{ + type: "text", + text: JSON.stringify(treeData, null, 2) + }], }; } @@ -592,9 +600,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { case "list_allowed_directories": { return { - content: [{ - type: "text", - text: `Allowed directories:\n${allowedDirectories.join('\n')}` + content: [{ + type: "text", + text: `Allowed directories:\n${allowedDirectories.join('\n')}` }], }; } @@ -622,4 +630,4 @@ async function runServer() { runServer().catch((error) => { console.error("Fatal error running server:", error); process.exit(1); -}); \ No newline at end of file +}); From a56d68495532f025938b59ae1235a4a4adcfd6f2 Mon Sep 17 00:00:00 2001 From: amxv <156369134+amxv@users.noreply.github.com> Date: Tue, 10 Dec 2024 02:18:09 +0530 Subject: [PATCH 04/11] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3dc4777a..59400c74 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ Additional resources on MCP. - **[mcp-get](https://mcp-get.com)** - Command line tool for installing and managing MCP servers by **[Michael Latman](https://github.com/michaellatman)** - **[mcp-cli](https://github.com/wong2/mcp-cli)** - A CLI inspector for the Model Context Protocol by **[wong2](https://github.com/wong2)** - **[r/mcp](https://www.reddit.com/r/mcp)** – A Reddit community dedicated to MCP by **[Frank Fiegel](https://github.com/punkpeye)** +- **[mcp-manager](https://github.com/zueai/mcp-manager)** - Simple Web UI to install and manage MCP servers for Claude Desktop by **[Zue](https://github.com/zueai)** ## 🚀 Getting Started From 6ad2de11a5d43002daccc7f658341cb9da436158 Mon Sep 17 00:00:00 2001 From: idoubi Date: Tue, 10 Dec 2024 10:50:35 +0800 Subject: [PATCH 05/11] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa03df7d..9ab28768 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ A growing set of community-developed and maintained servers demonstrates various - **[Kubernetes](https://github.com/Flux159/mcp-server-kubernetes)** - Connect to Kubernetes cluster and manage pods, deployments, and services. - **[OpenAPI](https://github.com/snaggle-ai/openapi-mcp-server)** - Interact with [OpenAPI](https://www.openapis.org/) APIs. - **[Pandoc](https://github.com/vivekVells/mcp-pandoc)** - MCP server for seamless document format conversion using Pandoc, supporting Markdown, HTML, and plain text, with other formats like PDF, csv and docx in development. -- **[ChatSum](https://github.com/mcpso/mcp-server-chatsum)** - Query and Summarize chat messages with LLM. +- **[ChatSum](https://github.com/mcpso/mcp-server-chatsum)** - Query and Summarize chat messages with LLM. by **[mcpso](https://mcp.so)** ## 📚 Resources From 4b9fca738384255754d77bb1571a504accb5c9dc Mon Sep 17 00:00:00 2001 From: East Agile Date: Tue, 10 Dec 2024 14:28:36 +0700 Subject: [PATCH 06/11] Add mcp-server-rememberizer to community servers in README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3dc4777a..836d148a 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,8 @@ A growing set of community-developed and maintained servers demonstrates various - **[Docker](https://github.com/ckreiling/mcp-server-docker)** - Integrate with Docker to manage containers, images, volumes, and networks. - **[Kubernetes](https://github.com/Flux159/mcp-server-kubernetes)** - Connect to Kubernetes cluster and manage pods, deployments, and services. - **[OpenAPI](https://github.com/snaggle-ai/openapi-mcp-server)** - Interact with [OpenAPI](https://www.openapis.org/) APIs. -- **[Pandoc](https://github.com/vivekVells/mcp-pandoc)** - MCP server for seamless document format conversion using Pandoc, supporting Markdown, HTML, and plain text, with other formats like PDF, csv and docx in development. +- **[Pandoc](https://github.com/vivekVells/mcp-pandoc)** - MCP server for seamless document format conversion using Pandoc, supporting Markdown, HTML, and plain text, with other formats like PDF, csv and docx in development. +- **[Rememberizer AI](https://github.com/skydeckai/mcp-server-rememberizer)** - MCP server for interacting with Rememberizer data source and enhanced knowledge retrieval. ## 📚 Resources From c65601cfc5762084e0f45b27593e2717bf0fe52c Mon Sep 17 00:00:00 2001 From: East Agile Date: Tue, 10 Dec 2024 17:15:11 +0700 Subject: [PATCH 07/11] refine Rememberizer server description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 836d148a..79cd5c5f 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ A growing set of community-developed and maintained servers demonstrates various - **[Kubernetes](https://github.com/Flux159/mcp-server-kubernetes)** - Connect to Kubernetes cluster and manage pods, deployments, and services. - **[OpenAPI](https://github.com/snaggle-ai/openapi-mcp-server)** - Interact with [OpenAPI](https://www.openapis.org/) APIs. - **[Pandoc](https://github.com/vivekVells/mcp-pandoc)** - MCP server for seamless document format conversion using Pandoc, supporting Markdown, HTML, and plain text, with other formats like PDF, csv and docx in development. -- **[Rememberizer AI](https://github.com/skydeckai/mcp-server-rememberizer)** - MCP server for interacting with Rememberizer data source and enhanced knowledge retrieval. +- **[Rememberizer AI](https://github.com/skydeckai/mcp-server-rememberizer)** - An MCP server designed for interacting with the Rememberizer data source, facilitating enhanced knowledge retrieval. ## 📚 Resources From 8cc8c6e7a788f179d57caebd0a2a2efc8f2ecd2b Mon Sep 17 00:00:00 2001 From: Raduan77 Date: Wed, 11 Dec 2024 09:14:25 +0100 Subject: [PATCH 08/11] Allow body to be nullable in GithubIssueSchema --- src/github/schemas.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/github/schemas.ts b/src/github/schemas.ts index cefdc1d1..0a322328 100644 --- a/src/github/schemas.ts +++ b/src/github/schemas.ts @@ -274,7 +274,7 @@ export const GitHubIssueSchema = z.object({ created_at: z.string(), updated_at: z.string(), closed_at: z.string().nullable(), - body: z.string(), + body: z.string().nullable(), }); // Pull Request related schemas From fe91dc76eb7ce6a2d63f952d068c266c9d806615 Mon Sep 17 00:00:00 2001 From: Ruud Huijts Date: Wed, 11 Dec 2024 10:01:42 +0100 Subject: [PATCH 09/11] added NS Dutch Railways mcp server to community server list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f511bb2c..0106b8ba 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ A growing set of community-developed and maintained servers demonstrates various > **Note:** Community servers are **untested** and should be used at **your own risk**. They are not affiliated with or endorsed by Anthropic. - **[MCP Installer](https://github.com/anaisbetts/mcp-installer)** - This server is a server that installs other MCP servers for you. +- **[NS Travel Information](https://github.com/r-huijts/ns-mcp-server)** - Access Dutch Railways (NS) real-time train travel information and disruptions through the official NS API. - **[Spotify](https://github.com/varunneal/spotify-mcp)** - This MCP allows an LLM to play and use Spotify. - **[Inoyu](https://github.com/sergehuber/inoyu-mcp-unomi-server)** - Interact with an Apache Unomi CDP customer data platform to retrieve and update customer profiles - **[Snowflake](https://github.com/datawiz168/mcp-snowflake-service)** - This MCP server enables LLMs to interact with Snowflake databases, allowing for secure and controlled data operations. From db0bafbe8d43256a758eaa5f60475a50da3ba4e0 Mon Sep 17 00:00:00 2001 From: TerminalMan <84923604+SecretiveShell@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:57:11 +0000 Subject: [PATCH 10/11] Fix AWS KB Retrieval link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f289c3dd..5060eb26 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Each MCP server is implemented with either the [Typescript MCP SDK](https://gith These servers aim to demonstrate MCP features and the Typescript and Python SDK. -- **[AWS KB Retrieval](src/aws-kb-retrieval)** - Retrieval from AWS Knowledge Base using Bedrock Agent Runtime +- **[AWS KB Retrieval](src/aws-kb-retrieval-server)** - Retrieval from AWS Knowledge Base using Bedrock Agent Runtime - **[Brave Search](src/brave-search)** - Web and local search using Brave's Search API - **[EverArt](src/everart)** - AI image generation using various models - **[Fetch](src/fetch)** - Web content fetching and conversion for efficient LLM usage From c1012d7b70909fdfb35c48347ba795c4c8a7316b Mon Sep 17 00:00:00 2001 From: David Soria Parra <167242713+dsp-ant@users.noreply.github.com> Date: Thu, 12 Dec 2024 22:46:04 +0000 Subject: [PATCH 11/11] Update README.md fix indent --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b4a7a8c2..7bd08e8e 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ Additional resources on MCP. - **[mcp-get](https://mcp-get.com)** - Command line tool for installing and managing MCP servers by **[Michael Latman](https://github.com/michaellatman)** - **[mcp-cli](https://github.com/wong2/mcp-cli)** - A CLI inspector for the Model Context Protocol by **[wong2](https://github.com/wong2)** - **[r/mcp](https://www.reddit.com/r/mcp)** – A Reddit community dedicated to MCP by **[Frank Fiegel](https://github.com/punkpeye)** -- **[mcp-manager](https://github.com/zueai/mcp-manager)** - Simple Web UI to install and manage MCP servers for Claude Desktop by **[Zue](https://github.com/zueai)** +- **[mcp-manager](https://github.com/zueai/mcp-manager)** - Simple Web UI to install and manage MCP servers for Claude Desktop by **[Zue](https://github.com/zueai)** ## 🚀 Getting Started