├── .gitignore ├── logo.png ├── screenshot.png ├── tsconfig.json ├── tsconfig.base.json ├── smithery.yaml ├── Dockerfile ├── package.json ├── LICENSE ├── index.ts └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | *.lock 4 | package-lock.json 5 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btwiuse/npm-search-mcp-server/HEAD/logo.png -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btwiuse/npm-search-mcp-server/HEAD/screenshot.png -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "./**/*.ts" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "resolveJsonModule": true 11 | }, 12 | "include": ["src/**/*"], 13 | "exclude": ["node_modules"] 14 | } 15 | -------------------------------------------------------------------------------- /smithery.yaml: -------------------------------------------------------------------------------- 1 | # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml 2 | 3 | startCommand: 4 | type: stdio 5 | configSchema: 6 | # JSON Schema defining the configuration options for the MCP. 7 | type: object 8 | required: [] 9 | properties: {} 10 | commandFunction: 11 | # A function that produces the CLI command to start the MCP on stdio. 12 | |- 13 | config => ({command:'node', args:['dist/index.js']}) -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile 2 | # Stage 1: Build the application 3 | FROM node:20 AS builder 4 | 5 | # Set the working directory 6 | WORKDIR /app 7 | 8 | # Copy package.json and package-lock.json 9 | COPY package.json tsconfig.json ./ 10 | 11 | # Install dependencies 12 | RUN npm install 13 | 14 | # Copy the rest of the application 15 | COPY . . 16 | 17 | # Build the application 18 | RUN npm run build 19 | 20 | # Stage 2: Run the application 21 | FROM node:20-alpine 22 | 23 | # Set the working directory 24 | WORKDIR /app 25 | 26 | # Copy the build output and package files from the builder stage 27 | COPY --from=builder /app/dist /app/dist 28 | COPY --from=builder /app/package.json /app/package-lock.json /app/node_modules /app/ 29 | 30 | # Set the entrypoint 31 | ENTRYPOINT ["node", "dist/index.js"] -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm-search-mcp-server", 3 | "version": "0.1.1", 4 | "description": "MCP server for searching npm", 5 | "license": "MIT", 6 | "author": "Anthropic, PBC (https://anthropic.com)", 7 | "homepage": "https://modelcontextprotocol.io", 8 | "repository": "https://github.com/btwiuse/npm-search-mcp-server", 9 | "bugs": "https://github.com/modelcontextprotocol/servers/issues", 10 | "type": "module", 11 | "bin": { 12 | "npm-search-mcp-server": "dist/index.js" 13 | }, 14 | "files": [ 15 | "dist" 16 | ], 17 | "scripts": { 18 | "build": "tsc && shx chmod +x dist/*.js", 19 | "prepare": "npm run build", 20 | "watch": "tsc --watch" 21 | }, 22 | "dependencies": { 23 | "@modelcontextprotocol/sdk": "1.0.1" 24 | }, 25 | "devDependencies": { 26 | "@types/node": "^22.10.5", 27 | "shx": "^0.3.4", 28 | "typescript": "^5.6.2" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Broken Pipe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { Server } from '@modelcontextprotocol/sdk/server/index.js'; 3 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; 4 | import { 5 | CallToolRequestSchema, 6 | ErrorCode, 7 | ListToolsRequestSchema, 8 | McpError, 9 | } from '@modelcontextprotocol/sdk/types.js'; 10 | import { exec } from 'child_process'; 11 | import util from 'util'; 12 | 13 | const execPromise = util.promisify(exec); 14 | 15 | const isValidSearchArgs = (args: any): args is { query: string } => 16 | typeof args === 'object' && args !== null && typeof args.query === 'string'; 17 | 18 | class NpmSearchServer { 19 | private server: Server; 20 | 21 | constructor() { 22 | this.server = new Server( 23 | { 24 | name: 'npm-search-server', 25 | version: '0.1.0', 26 | }, 27 | { 28 | capabilities: { 29 | tools: {}, 30 | }, 31 | } 32 | ); 33 | 34 | this.setupToolHandlers(); 35 | 36 | // Error handling 37 | this.server.onerror = (error) => console.error('[MCP Error]', error); 38 | process.on('SIGINT', async () => { 39 | await this.server.close(); 40 | process.exit(0); 41 | }); 42 | } 43 | 44 | private setupToolHandlers() { 45 | this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ 46 | tools: [ 47 | { 48 | name: 'search_npm_packages', // Unique identifier 49 | description: 'Search for npm packages', // Human-readable description 50 | inputSchema: { 51 | // JSON Schema for parameters 52 | type: 'object', 53 | properties: { 54 | query: { 55 | type: 'string', 56 | description: 'Search query', 57 | }, 58 | }, 59 | required: ['query'], // Array of required property names 60 | }, 61 | }, 62 | ], 63 | })); 64 | 65 | this.server.setRequestHandler(CallToolRequestSchema, async (request) => { 66 | if (request.params.name !== 'search_npm_packages') { 67 | throw new McpError( 68 | ErrorCode.MethodNotFound, 69 | `Unknown tool: ${request.params.name}` 70 | ); 71 | } 72 | 73 | if (!isValidSearchArgs(request.params.arguments)) { 74 | throw new McpError( 75 | ErrorCode.InvalidParams, 76 | 'Invalid search arguments' 77 | ); 78 | } 79 | 80 | const query = request.params.arguments.query; 81 | 82 | try { 83 | const { stdout, stderr } = await execPromise(`npm search ${query}`); 84 | if (stderr) { 85 | throw new McpError( 86 | ErrorCode.InternalError, 87 | `npm search error: ${stderr}` 88 | ); 89 | } 90 | 91 | return { 92 | content: [ 93 | { 94 | type: 'text', 95 | text: stdout, 96 | }, 97 | ], 98 | }; 99 | } catch (error) { 100 | if (error instanceof McpError) { 101 | throw error; 102 | } 103 | if (error instanceof Error) { 104 | throw new McpError( 105 | ErrorCode.InternalError, 106 | `Unexpected error: ${error.message}` 107 | ); 108 | } 109 | throw new McpError( 110 | ErrorCode.InternalError, 111 | 'Unexpected error occurred' 112 | ); 113 | } 114 | }); 115 | } 116 | 117 | async run() { 118 | const transport = new StdioServerTransport(); 119 | await this.server.connect(transport); 120 | console.error('Npm Search MCP server running on stdio'); 121 | } 122 | } 123 | 124 | const server = new NpmSearchServer(); 125 | server.run().catch(console.error); 126 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![MseeP.ai Security Assessment Badge](https://mseep.net/pr/btwiuse-npm-search-mcp-server-badge.png)](https://mseep.ai/app/btwiuse-npm-search-mcp-server) 2 | 3 | # npm-search MCP Server 4 | [![smithery badge](https://smithery.ai/badge/npm-search-mcp-server)](https://smithery.ai/server/npm-search-mcp-server) 5 | 6 | A Model Context Protocol server that allows you to search for npm packages by calling the `npm search` command. 7 | 8 | npm-search-mcp-server MCP server 9 | 10 | ### Available Tools 11 | 12 | - `search_npm_packages` - Search for npm packages. 13 | - Required arguments: 14 | - `query` (string): The search query. 15 | 16 | ![Claude Screenshot](./screenshot.png) 17 | 18 | ## Installation 19 | 20 | ### Installing via Smithery 21 | 22 | To install npm-search for Claude Desktop automatically via [Smithery](https://smithery.ai/server/npm-search-mcp-server): 23 | 24 | ```bash 25 | npx -y @smithery/cli install npm-search-mcp-server --client claude 26 | ``` 27 | 28 | ### Using NPM (recommended) 29 | 30 | Alternatively you can install `npm-search-mcp-server` via npm: 31 | 32 | ```bash 33 | npm install -g npm-search-mcp-server 34 | ``` 35 | 36 | After installation, you can run it as a command using: 37 | 38 | ```bash 39 | npm-search-mcp-server 40 | ``` 41 | 42 | ### Using uv 43 | 44 | When using [`uv`](https://docs.astral.sh/uv/) no specific installation is needed. We will 45 | use [`uvx`](https://docs.astral.sh/uv/guides/tools/) to directly run *npm-search-mcp-server*. 46 | 47 | ## Configuration 48 | 49 | ### Configure for Claude.app 50 | 51 | Add to your Claude settings: 52 | 53 |
54 | Using npm installation 55 | 56 | ```json 57 | "mcpServers": { 58 | "npm-search": { 59 | "command": "npx", 60 | "args": ["-y", "npm-search-mcp-server"] 61 | } 62 | } 63 | ``` 64 |
65 | 66 |
67 | Using uvx 68 | 69 | ```json 70 | "mcpServers": { 71 | "npm-search": { 72 | "command": "uvx", 73 | "args": ["npm-search-mcp-server"] 74 | } 75 | } 76 | ``` 77 |
78 | 79 | ### Configure for Zed 80 | 81 | Add to your Zed settings.json: 82 | 83 |
84 | Using npm installation 85 | 86 | ```json 87 | "context_servers": { 88 | "npm-search-mcp-server": { 89 | "command": "npx", 90 | "args": ["-y", "npm-search-mcp-server"] 91 | } 92 | }, 93 | ``` 94 |
95 | 96 |
97 | Using uvx 98 | 99 | ```json 100 | "context_servers": [ 101 | "npm-search-mcp-server": { 102 | "command": "uvx", 103 | "args": ["npm-search-mcp-server"] 104 | } 105 | ], 106 | ``` 107 |
108 | 109 | ## Example Interactions 110 | 111 | 1. Search for npm packages: 112 | ```json 113 | { 114 | "name": "search_npm_packages", 115 | "arguments": { 116 | "query": "express" 117 | } 118 | } 119 | ``` 120 | Response: 121 | ```json 122 | { 123 | "results": [ 124 | { 125 | "name": "express", 126 | "description": "Fast, unopinionated, minimalist web framework", 127 | "version": "4.17.1", 128 | "author": "TJ Holowaychuk", 129 | "license": "MIT" 130 | }, 131 | ... 132 | ] 133 | } 134 | ``` 135 | 136 | ## Debugging 137 | 138 | You can use the MCP inspector to debug the server. For uvx installations: 139 | 140 | ```bash 141 | npx @modelcontextprotocol/inspector npx -y npm-search-mcp-server 142 | ``` 143 | 144 | Or if you've installed the package in a specific directory or are developing on it: 145 | 146 | ```bash 147 | cd path/to/servers/src/npm-search 148 | npx @modelcontextprotocol/inspector uv run npm-search-mcp-server 149 | ``` 150 | 151 | ## Examples of Questions for Claude 152 | 153 | 1. "Search for express package on npm" 154 | 2. "Find packages related to react" 155 | 3. "Show me npm packages for web development" 156 | 157 | ## Build 158 | 159 | Docker build: 160 | 161 | ```bash 162 | cd src/npm-search 163 | docker build -t mcp/npm-search . 164 | ``` 165 | 166 | ## Contributing 167 | 168 | We encourage contributions to help expand and improve npm-search-mcp-server. Whether you want to add new npm-related tools, enhance existing functionality, or improve documentation, your input is valuable. 169 | 170 | For examples of other MCP servers and implementation patterns, see: 171 | https://github.com/modelcontextprotocol/servers 172 | 173 | Pull requests are welcome! Feel free to contribute new ideas, bug fixes, or enhancements to make npm-search-mcp-server even more powerful and useful. 174 | 175 | ## License 176 | 177 | npm-search-mcp-server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository. 178 | --------------------------------------------------------------------------------