Mcp Code Search — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Mcp Code Search (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
An MCP (Model Context Protocol) server for semantic code search using vector embeddings. Index your code folders and perform semantic searches to find code by meaning, not just keywords.
Required:
Optional (for LSP enrichment):
# TypeScript/JavaScript LSP (improves search quality for TS/JS/TSX/JSX)
npm install -g typescript-language-server typescript
# C# LSP (improves search quality for .cs files)
dotnet tool install --global csharp-ls# Clone the repository
git clone https://github.com/amolchanov/mcp-code-search.git
cd mcp-code-search
# Install dependencies
npm install
# Download tree-sitter WASM files
npm run download-wasm
# Build the project
npm run buildThe server can run in two modes:
Used when integrating with Claude CLI, Copilot, or other MCP clients:
# Run directly (waits for JSON-RPC input on stdin)
node dist/index.js
# Or with auto-indexing of specific folders
node dist/index.js --index /path/to/project1 --index /path/to/project2In stdio mode, the server communicates via stdin/stdout using the MCP protocol. This is what Claude CLI uses when you add it as an MCP server.
Used for the web-based admin interface:
# Start with default port 3100
node dist/index.js --sse
# Or specify a custom port
node dist/index.js --sse --port 8080
# With system tray icon (Windows/macOS)
node dist/index.js --sse --tray
# With auto-indexing
node dist/index.js --sse --index /path/to/projectThen open: http://localhost:3100/admin
For production use, run the server with PM2 for automatic restart if it crashes:
# Install PM2 globally (one-time)
npm install -g pm2
# Start the server with PM2
npm run pm2:start
# View logs
npm run pm2:logs
# Check status
npm run pm2:status
# Stop the server
npm run pm2:stop
# Restart the server
npm run pm2:restartPM2 will automatically restart the server if it crashes (up to 10 times). Logs are saved to logs/output.log and logs/error.log.
| Option | Description |
|---|---|
--sse | Run in SSE mode with HTTP server and Admin UI |
--port <number> | HTTP port for SSE mode (default: 3100) |
--tray | Show system tray icon (SSE mode only) |
--index <path> | Auto-index a folder on startup (can be repeated) |
When multiple MCP clients (e.g., multiple Copilot CLI windows) connect simultaneously, the server uses a client-server architecture to prevent database corruption:
┌─────────────────────────────────────────────────┐
│ SSE Server (Daemon) │
│ • Handles ALL indexing and database writes │
│ • HTTP API at localhost:3100 │
│ • Admin UI for monitoring │
└─────────────────────────────────────────────────┘
↑ HTTP
┌───────────┼───────────┐
┌────┴────┐ ┌────┴────┐ ┌───┴─────┐
│ stdio │ │ stdio │ │ stdio │
│ client │ │ client │ │ client │
└─────────┘ └─────────┘ └─────────┘
↑ ↑ ↑
Copilot 1 Copilot 2 Copilot 3How it works:
Key benefits:
If you don't have Docker installed:
Windows/macOS:
docker --versionLinux:
# Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER # Add your user to docker group
# Log out and back in for group changes to take effectQdrant is the vector database that stores code embeddings. Choose one option:
#### Option A: Docker (Recommended)
Start Qdrant container:
# Run in foreground (stops when terminal closes)
docker run -p 6333:6333 qdrant/qdrant
# OR run in background (keeps running)
docker run -d -p 6333:6333 -v qdrant_storage:/qdrant/storage --name qdrant qdrant/qdrant
# Check if running
docker ps | grep qdrant
# Stop the container
docker stop qdrant
# Restart the container
docker start qdrant
# View logs
docker logs qdrantVerify Qdrant is running:
curl http://localhost:6333/collections
# Should return: {"result":{"collections":[]}, ...}#### Option B: Local Installation
Follow the Qdrant installation guide for native installation.
Ollama provides free local embeddings without API costs. Alternatively, you can use OpenAI, Gemini, Mistral, or Bedrock.
#### Option A: Native Installation (Recommended)
Download and Install:
Pull the embedding model:
# Recommended model for code (8192 token context)
ollama pull nomic-embed-text
# Verify model is downloaded
ollama list
# Test the model
ollama run nomic-embed-text#### Option B: Docker
# Run Ollama in Docker
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
# Pull the embedding model
docker exec ollama ollama pull nomic-embed-text
# Verify
docker exec ollama ollama listStart/Stop Ollama:
# Native installation - Ollama runs as a service automatically
# Check status
curl http://localhost:11434/api/tags
# Docker
docker start ollama
docker stop ollamaBefore starting the MCP server, check:
# Check Qdrant
curl http://localhost:6333/collections
# Check Ollama (if using)
curl http://localhost:11434/api/tagsRecommended: Use the Claude CLI command:
# Add to current project (creates .mcp.json in project root)
claude mcp add code-search -s project -- node /path/to/code-search-mcp/dist/index.js
# Or add globally for all projects (user-level config)
claude mcp add code-search -s user -- node /path/to/code-search-mcp/dist/index.jsWindows example:
claude mcp add code-search -s project -- node C:/repos/code-search-mcp/dist/index.jsVerify the server is connected:
claude mcp list
# Should show: code-search: node ... - ✓ ConnectedAlternative: Manual JSON configuration
Add to .mcp.json in your project root:
{
"mcpServers": {
"code-search": {
"type": "stdio",
"command": "node",
"args": ["/path/to/code-search-mcp/dist/index.js"],
"env": {}
}
}
}Option A: Use the MCP tool (recommended)
Once connected, ask Claude to run:
Use the get_instructions tool to get the code-search instructions, then add them to my CLAUDE.md file.Or via CLI:
# The get_instructions tool returns markdown content for CLAUDE.md
# Format options: "claude" (default), "copilot", "generic"Option B: Copy manually
# Copy to global instructions
cp examples/CLAUDE.md ~/.claude/CLAUDE.md
# Or append to existing instructions
cat examples/CLAUDE.md >> ~/.claude/CLAUDE.mdSee examples/CLAUDE.md for the full instructions template.
Key points:
mcp__code-search__search over built-in Grep and Glob for finding codeGrep only for exact string/regex matchesYou can configure the server globally (for all repos) or per-repository:
#### Option A: Global Configuration (All Repositories)
Add this to your global Copilot CLI MCP settings file:
Location: ~/.copilot/mcp-config.json (create if it doesn't exist)
Windows: C:\Users\<username>\.copilot\mcp-config.json
{
"mcpServers": {
"code-search": {
"type": "local",
"command": "node",
"args": ["/path/to/code-search-mcp/dist/index.js"],
"tools": ["*"]
}
}
}Windows example:
{
"mcpServers": {
"code-search": {
"type": "local",
"command": "node",
"args": ["c:/repos/mcp-code-search/dist/index.js"],
"tools": ["*"]
}
}
}#### Option B: Repository-Specific Configuration
Add .copilot/mcp-config.json to your repository root:
# In your project repository
mkdir -p .copilot
touch .copilot/mcp-config.jsonAdd the same configuration:
{
"mcpServers": {
"code-search": {
"type": "local",
"command": "node",
"args": ["/path/to/code-search-mcp/dist/index.js"],
"tools": ["*"]
}
}
}Note:
.copilot/mcp-config.json to version control (add to .gitignore)code-search entry to the existing mcpServers objectCopy the example instructions to your Copilot instructions file:
See examples/COPILOT.md for the full instructions template.
Key points:
The Admin UI is available when running in SSE mode (see Running the Server):
node dist/index.js --sse
# Then open: http://localhost:3100/adminFolders Tab:
Queries Tab:
Ingestion Tab:
Services Tab:
Settings Tab:
Use the configure tool to set up the server after connecting.
{
"qdrantUrl": "http://localhost:6333",
"embedderProvider": "ollama",
"ollamaBaseUrl": "http://localhost:11434",
"modelId": "nomic-embed-text:latest"
}{
"embedderProvider": "openai",
"openAiApiKey": "sk-...",
"modelId": "text-embedding-3-small"
}Supported: gemini, mistral, bedrock, openrouter, openai-compatible
You can configure different embedding models for different folders via the Admin UI. This is useful when:
Supported models and their context sizes:
| Model | Provider | Context (tokens) |
|---|---|---|
nomic-embed-text | Ollama | 8192 |
mxbai-embed-large | Ollama | 512 |
text-embedding-3-small | OpenAI | 8191 |
text-embedding-3-large | OpenAI | 8191 |
text-embedding-ada-002 | OpenAI | 8191 |
mistral-embed | Mistral | 8192 |
voyage-code-2 | Voyage | 16000 |
voyage-code-3 | Voyage | 32000 |
gemma2 | Ollama | 8192 |
snowflake-arctic-embed | Ollama | 8192 |
Note: For code indexing, models with larger context (8192+ tokens) are recommended to avoid truncation of large functions/classes.
| Tool | Description |
|---|---|
add_folder | Add a folder to be indexed |
remove_folder | Remove a folder from indexing |
list_folders | List all indexed folders |
clear_index | Clear/rebuild index |
reindex_folder | Reindex a folder (clears and rebuilds) |
pause_indexing | Pause indexing for a folder |
resume_indexing | Resume paused indexing |
reenrich_folder | Re-enrich folder with LSP (for folders indexed without LSP) |
| Tool | Description |
|---|---|
search | Perform semantic code search |
Search Parameters:
query (required): Natural language search queryfolderPath: Filter to specific folderfileTypes: Filter by extensions (e.g., [".ts", ".js"])minScore: Minimum similarity (0-1)maxResults: Max results to return| Tool | Description |
|---|---|
get_status | Get indexing status |
get_errors | Get error reports |
configure | Update server configuration |
get_instructions | Get AI assistant instructions (for CLAUDE.md, etc.) |
# From Claude CLI, you can use these tools directly:
# "search for authentication middleware"
# "add folder /path/to/project"
# "pause indexing for project-name"
# "reindex the api folder"JavaScript, TypeScript, TSX, JSX, Python, Rust, Go, C, C++, C#, Java, Ruby, PHP, Swift, Kotlin, Scala, Elixir, Erlang, Haskell, OCaml, Lua, Perl, R, Julia, Dart, Vue, Svelte, HTML, CSS, SCSS, SQL, GraphQL, Markdown, JSON, YAML, TOML, XML, Bash, PowerShell, Dockerfile, Terraform, Solidity, Zig, Nim, and more.
The server respects .gitignore files in indexed folders. You can also create a .cs-mcp-ignore file with additional patterns to exclude.
Always ignored directories:
node_modules, .git, dist, build, .next, .cache, coverage, .venv, vendor, target, etc.All server data is stored in a platform-appropriate application data folder:
| Platform | Location |
|---|---|
| Windows | %LOCALAPPDATA%\code-search |
| macOS | ~/Library/Application Support/code-search |
| Linux | ~/.local/share/code-search (or $XDG_DATA_HOME/code-search) |
Folder contents:
code-search/
├── config.json # Server configuration
├── folders.json # Indexed folder registry
├── embedding-cache.db # SQLite embedding cache
├── lsp-cache.db # LSP enrichment cache
├── queries/ # Query logs (daily JSONL files)
│ └── queries-YYYY-MM-DD.jsonl
└── cache/ # Per-folder file hash cache
└── {folder-id}.jsonNotes:
The server caches computed embeddings in SQLite to avoid redundant API calls. When re-indexing or updating files:
The cache auto-warms from existing Qdrant data on startup.
Enable Language Server Protocol integration to enrich code chunks with type information before embedding:
{
"lspEnabled": true,
"lspTimeout": 5000,
"lspMaxConcurrentRequests": 5,
"lspUseOmniSharp": false
}Benefits:
Prerequisites:
npm install -g typescript-language-server typescriptdotnet tool install --global csharp-ls (or set lspUseOmniSharp: true for OmniSharp)Code chunks automatically include parent context from the AST:
This helps queries like "authentication method in UserService" match more accurately.
The server automatically detects git worktrees and optimizes indexing:
How it works:
Benefits:
Important: Keep your base repository checked out to the main/master branch for best results. The index reflects whatever is on disk, not a specific git branch.
Orphaned folder cleanup: If you delete a worktree from disk, the server marks it as "orphaned" on next startup. Use the Cleanup button in the admin UI to remove orphaned indexes.
When upgrading to a version with new enrichment features (LSP, hierarchical context), you need to reindex existing folders to take advantage of the improvements:
http://localhost:3100/adminThis clears the existing index and re-indexes all files with the new enrichment features.
See FUTURE-IMPROVEMENTS.md for planned enhancements including:
Symptom: claude mcp list shows code-search: ... - ✗ Failed to connect
Solutions:
node /path/to/code-search-mcp/dist/index.jsShould output: [CodeSearch] Server running on stdio
curl http://localhost:6333/collectionsIf not running, start it: docker run -p 6333:6333 qdrant/qdrant
curl http://localhost:11434/api/tagsIf not running, start Ollama and ensure the model is pulled: ollama pull nomic-embed-text
.mcp.json from the project root, NOT .claude/mcp.jsonclaude mcp add command to ensure correct placementclaude mcp list to verify registration--sse flag), Claude CLI cannot connect npm run buildnode dist/index.jsmxbai-embed-large: 512 tokens (small, may truncate code)nomic-embed-text: 8192 tokens (recommended for code)get_errors for specific file failures # TypeScript/JavaScript
typescript-language-server --version
# C#
csharp-ls --version { "lspEnabled": true }get_status or Admin UI "args": ["C:/repos/code-search/dist/index.js"]Not backslashes: "C:\\repos\\..." (can cause escaping issues)
# Find what's using port 3100
netstat -ano | findstr :3100 # Windows
lsof -i :3100 # macOS/Linux
# Use a different port
node dist/index.js --sse --port 3101 docker ps | grep qdrant docker restart $(docker ps -q --filter ancestor=qdrant/qdrant)
# Or start fresh:
docker run -d -p 6333:6333 -v qdrant_storage:/qdrant/storage qdrant/qdrant node --max-old-space-size=4096 dist/index.jsMIT License - see LICENSE file.
See THIRD-PARTY-LICENSES.md for dependency licenses.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.