# Directory Structure ``` ├── .github │ └── workflows │ └── npm-publish.yml ├── .gitignore ├── .npmignore ├── build │ ├── index.d.ts │ └── index.js ├── build.sh ├── Dockerfile ├── docs │ └── images │ └── screenshot.png ├── LICENSE ├── package-lock.json ├── package.json ├── README.md ├── smithery.yaml ├── src │ └── index.ts └── tsconfig.json ``` # Files -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- ``` # Development files .git .github .vscode src/ test/ tests/ *.test.js *.spec.js tsconfig.json .eslintrc .prettierrc .editorconfig .gitignore .travis.yml .circleci/ jest.config.js # Build scripts build.sh scripts/ # Documentation files that aren't needed in the package docs/ test-instructions.md # Node.js node_modules/ npm-debug.log yarn-debug.log yarn-error.log # macOS .DS_Store ``` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- ``` # Dependency directories node_modules/ # Build artifacts dist/ # dotenv environment variables file .env .env.local .env.development.local .env.test.local .env.production.local # OS-specific files .DS_Store .DS_Store? ._* .Spotlight-V100 .Trashes ehthumbs.db Thumbs.db # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* # Yarn integrity file .yarn-integrity # Optional npm cache directory .npm # Editor directories and files .idea .vscode *.swp *.swo ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- ```markdown # MCP Easy Copy [](https://modelcontextprotocol.io) [](https://claude.ai/download) [](https://www.npmjs.com/package/@fishes/mcp-easy-copy) [](https://nodejs.org) [](https://smithery.ai/server/@fisheepx/mcp-easy-copy) [](LICENSE) A Model Context Protocol server that makes it easy to discover and copy available MCP services in Claude Desktop. <img src="docs/images/screenshot.png" alt="MCP Easy Copy in action" width="400"/> ## Purpose This MCP server is designed to be your first stop when working with Claude Desktop. It solves the problem of having to remember MCP service names or looking them up in configuration files by: 1. Automatically reading the Claude Desktop configuration file 2. Extracting the names of all configured MCP services 3. Presenting them in an easy-to-copy format at the top of the tools list Although Claude can now automatically select the appropriate MCP services in most scenarios, there are still situations where users need to explicitly specify an MCP service name. These situations include: - When you have many MCP services configured, making the tools list long and difficult to navigate - When specific MCP services offer multiple callable actions, further increasing the list length - When you need to direct Claude to use a specific service rather than relying on its automatic selection - When troubleshooting or comparing results between different MCP services This tool bridges that gap, making all available services easily accessible without having to search through configuration files. ## Features - **Appears at the top of tools list**: Uses special name formatting to always appear first - **Dynamic updates**: Always shows the latest available services - **Copy-friendly format**: Numbered list for easy reference - **Zero external dependencies**: Just needs Node.js ## Installation ### Option 1: Install via npm (Recommended) ```bash npm install -g @fishes/mcp-easy-copy ``` Then add to your Claude Desktop configuration: ```json { "mcpServers": { "mcp-easy-copy": { "command": "npx", "args": [ "-y", "@fishes/mcp-easy-copy" ] } } } ``` ### Option 2: Installing via Smithery To install Easy Copy for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@fisheepx/mcp-easy-copy): ```bash npx -y @smithery/cli install @fisheepx/mcp-easy-copy --client claude ``` ### Option 3: Manual Installation 1. Clone the repository: ```bash git clone https://github.com/f-is-h/mcp-easy-copy.git cd mcp-easy-copy ``` 2. Install dependencies and build: ```bash npm install npm run build ``` 3. Configure Claude Desktop: **For macOS:** Edit `~/Library/Application Support/Claude/claude_desktop_config.json` **For Windows:** Edit `%APPDATA%\Claude\claude_desktop_config.json` Add the following configuration: ```json { "mcpServers": { "mcp-easy-copy": { "command": "node", "args": [ "/ABSOLUTE/PATH/TO/mcp_easy_copy/build/index.js" ] } } } ``` 4. Restart Claude Desktop ## Using the Tool Once installed, you can use the service in two ways: 1. **Via the tools menu:** Click the hammer icon in Claude Desktop and select the service at the top of the list (it will show all available services in its description) 2. **Via a prompt:** Ask Claude something like: ``` Please list all MCP services that are available to you ``` or ``` Please use _________mcp-easy-copy_________ to show me all available MCP services ``` ## Development MCP Easy Copy is built with TypeScript and uses the Model Context Protocol SDK. ```bash # Install dependencies npm install # Build the project npm run build # Test with the MCP Inspector npm run inspector ``` ## Troubleshooting If the tool doesn't work as expected: 1. **Check logs**: Look at the log files - macOS: `~/Library/Logs/Claude/mcp-server-mcp-easy-copy.log` - Windows: `%APPDATA%\Claude\logs\mcp-server-mcp-easy-copy.log` 2. **Verify configuration**: Make sure your `claude_desktop_config.json` is valid JSON 3. **Check Node.js**: Ensure Node.js is properly installed (`node --version`) 4. **Restart Claude**: Always restart Claude Desktop after making configuration changes 5. **Use the Inspector**: Run `npm run inspector` to debug with the MCP Inspector ## Other Badges ### Glama <a href="https://glama.ai/mcp/servers/@fisheepx/mcp-easy-copy"> <img width="380" height="200" src="https://glama.ai/mcp/servers/@f-is-h/mcp-easy-copy/badge" alt="Easy Copy MCP server" /> </a> ### MseeP.ai [](https://mseep.ai/app/f-is-h-mcp-easy-copy) ## License [MIT License](LICENSE) ## Future Vision While we have no specific knowledge of Anthropic's roadmap, we imagine that future versions of Claude's client could potentially implement features like autocomplete when using the '@' symbol. Such a feature might display a dropdown list of available MCP services, making it much easier for users to explicitly instruct Claude to utilize specific services. Even if such improvements eventually make this project obsolete, we'd be delighted to see Claude's interface evolve in ways that improve user experience. After all, the goal of this tool is to make MCP services more accessible, and having that functionality built directly into Claude would be the ultimate success. ``` -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- ```bash #!/bin/bash # Change to the directory where the script is located cd "$(dirname "$0")" # Build the project npm run build # Show success message echo "Build completed successfully!" echo "To use this MCP service, configure it in Claude Desktop." ``` -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- ```json { "compilerOptions": { "target": "ES2020", "module": "NodeNext", "moduleResolution": "NodeNext", "esModuleInterop": true, "outDir": "./build", "strict": true, "declaration": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules", "**/*.test.ts"] } ``` -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- ```dockerfile # Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile FROM node:lts-alpine WORKDIR /app # Copy package files and install dependencies COPY package*.json ./ RUN npm install --ignore-scripts # Copy the rest of the source code and build COPY . . RUN npm run build # Expose any required ports (if applicable) # EXPOSE 3000 CMD ["npm", "start"] ``` -------------------------------------------------------------------------------- /smithery.yaml: -------------------------------------------------------------------------------- ```yaml # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml startCommand: type: stdio configSchema: # JSON Schema defining the configuration options for the MCP. type: object properties: {} commandFunction: # A JS function that produces the CLI command based on the given config to start the MCP on stdio. |- (config) => ({ command: 'node', args: ['build/index.js'] }) exampleConfig: {} ``` -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- ```yaml name: Node.js Package on: release: types: [created] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: 16 - run: npm ci - run: npm test - run: npm run build publish-npm: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: 16 registry-url: https://registry.npmjs.org/ - run: npm ci - run: npm run build - run: npm publish --access public env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- ```json { "name": "@fishes/mcp-easy-copy", "version": "1.0.1", "description": "A MCP server that lists all available MCP services for easy copying and usage", "main": "build/index.js", "type": "module", "bin": { "mcp-easy-copy": "build/index.js" }, "scripts": { "build": "tsc", "start": "node build/index.js", "inspector": "npx @modelcontextprotocol/inspector node build/index.js", "prepublishOnly": "npm run build" }, "repository": { "type": "git", "url": "git+https://github.com/fisheepx/mcp-easy-copy.git" }, "keywords": [ "mcp", "claude", "service-list", "tools", "utility" ], "author": "fisheep", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.7.0" }, "devDependencies": { "@types/node": "^20.8.0", "typescript": "^5.2.2" }, "engines": { "node": ">=14.0.0" } } ``` -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- ```typescript #!/usr/bin/env node /** * MCP Easy Copy Server * * This MCP server lists all configured MCP services in the Claude Desktop application. * It makes it easy for users to copy service names for use in their prompts. */ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import fs from "fs/promises"; import path from "path"; import os from "os"; // Create an MCP server that will appear at the top of the tools list const server = new McpServer({ name: "mcp-easy-copy", // Use hyphens consistently for npm naming convention version: "1.0.0" }); // Configure logging to stderr (doesn't interfere with the MCP protocol) const logDebug = (message: string) => { // Uncomment for debugging // console.error(`[DEBUG] ${message}`); }; /** * Configuration file paths for different operating systems * - macOS: ~/Library/Application Support/Claude/claude_desktop_config.json * - Linux: ~/.config/Claude/claude_desktop_config.json * - Windows: %APPDATA%/Claude/claude_desktop_config.json */ const possibleConfigPaths = [ path.join(os.homedir(), "Library/Application Support/Claude/claude_desktop_config.json"), path.join(os.homedir(), ".config/Claude/claude_desktop_config.json"), path.join(os.homedir(), "AppData/Roaming/Claude/claude_desktop_config.json") ]; /** * Finds the Claude Desktop configuration file * @returns The path to the config file if found, null otherwise */ async function findConfigFile(): Promise<string | null> { for (const configPath of possibleConfigPaths) { try { await fs.access(configPath); logDebug(`Found config file at: ${configPath}`); return configPath; } catch (error) { logDebug(`Config file not found at: ${configPath}`); } } return null; } /** * Retrieves all MCP service names from the Claude Desktop configuration file * @returns Array of MCP service names */ async function getMcpServices(): Promise<string[]> { try { // Find the config file const configPath = await findConfigFile(); if (!configPath) { return []; } // Read and parse the config file const configContent = await fs.readFile(configPath, 'utf-8'); const config = JSON.parse(configContent); // Extract and return MCP service names return config.mcpServers ? Object.keys(config.mcpServers) : []; } catch (error) { logDebug(`Error getting MCP services: ${error}`); return []; } } /** * Resource that returns the list of configured MCP services * This resource is exposed through URI: mcp-services://list */ server.resource( "mcp-services-list", "mcp-services://list", async (uri) => { try { // Find the config file const configPath = await findConfigFile(); if (!configPath) { return { contents: [{ uri: uri.href, text: "Error: Claude Desktop configuration file not found." }] }; } // Read and parse the config file const configContent = await fs.readFile(configPath, 'utf-8'); const config = JSON.parse(configContent); // Extract MCP service names const services = config.mcpServers ? Object.keys(config.mcpServers) : []; // Format the output in a user-friendly way const formattedList = services.length > 0 ? "📋 AVAILABLE MCP SERVICES:\n" + services.map((name) => `- ${name}`).join("\n") + "\n\nCopy a service name to use in prompts like:\n" + "• Can you use [service name] to...\n" + "• Please call [service name] to..." : "No MCP services configured."; return { contents: [{ uri: uri.href, text: formattedList }] }; } catch (error) { console.error("Error reading MCP config:", error); return { contents: [{ uri: uri.href, text: `Error reading MCP configuration: ${error instanceof Error ? error.message : String(error)}` }] }; } } ); /** * Initializes and starts the MCP server */ async function main() { try { // Get initial MCP services to include in the tool description let toolDescription = "List all MCP services available in this Claude instance"; const services = await getMcpServices(); if (services.length > 0) { // Format service names with separators for better visibility in the UI // (newlines don't work well in Claude's tool descriptions) const servicesList = services.map(name => `${name}`).join(" │ "); toolDescription = `│ ${servicesList} │`; } // Register the tool with underscores to appear at the top of tool listings server.tool( "_________available_mcp_services_for_easy_copy_________", toolDescription, {}, // No parameters needed async () => { // Always fetch the latest services when the tool is called const currentServices = await getMcpServices(); if (currentServices.length === 0) { return { content: [{ type: "text", text: "No MCP services configured." }] }; } // Format the output with numbered list and usage instructions const formattedList = "📋 AVAILABLE MCP SERVICES:\n" + currentServices.map((name, index) => `${index + 1}. ${name}`).join("\n") + "\n\nCopy a service name to use in prompts like:\n" + "• Can you use [service name] to...\n" + "• Please call [service name] to..."; return { content: [{ type: "text", text: formattedList }] }; } ); // Connect the server using stdio transport (standard for MCP) const transport = new StdioServerTransport(); await server.connect(transport); console.error("MCP Easy Copy server running..."); } catch (error) { console.error("Failed to start server:", error); process.exit(1); } } // Start the server main(); ```