Semantic tool discovery for MCP - Solves the "too many tools" problem by making tool discovery query-driven with vector search.
This project was inspired by:
- πΊ MCP Tool Overload Problem - YouTube video explaining the challenge
- π From Reasoning to Retrieval: Solving the MCP Tool Overload Problem - Redis blog post with the vector search solution
When you aggregate 20+ MCP servers (~300+ tools):
- Token explosion: 100,000+ tokens just listing tools
- LLM confusion: Too many choices = poor tool selection
- No filtering: Standard MCP returns ALL tools upfront
DMCP uses a two-process architecture with semantic search:
User: "Create a GitHub issue for this bug"
LLM calls: search_tools(query="create GitHub issue")
β Returns top-30 relevant tools (via semantic vector search)
β Tools become available for use
LLM calls: github_create_issue(...)
β Issue created!
Key insight: The LLM discovers tools by asking, not by loading everything upfront.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β VS Code / GitHub Copilot β
β β
β User: "search for kubernetes tools" β
β ββββββββββββββββββββββββββββββΊ β
β search_tools("kubernetes") β
β β
β ββββββββββββββββββββββββββββββ β
β Returns: 15 k8s tools (get_pods, list_deployments, describe_service...) β
βββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββ
β stdio
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DMCP Server (dmcp-server.ts) β
β β
β β’ Exposes 1 meta-tool: search_tools β
β β’ Hybrid search: text (exact) + vector (semantic) β
β β’ Sends listChanged notifications when tools discovered β
β β’ Forwards tool calls to backend MCP servers β
ββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββ
β β
β Query embeddings β Tool calls
βΌ βΌ
ββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββ
β Redis Stack (VSS) β β Agent Gateway β
β Port: 6380 β β (1MCP/agentgateway) β
β β β β
β ββββββββββββββββββββ β β ββββββββββββββββββββββββ β
β β Vector Index β β β β 20+ MCP Servers β β
β β (HNSW, COSINE) β β β β via SSE endpoints β β
β β 318 tool embeds β β β β Ports 3101-3120 β β
β ββββββββββββββββββββ β β ββββββββββββββββββββββββ β
β β β β
β ββββββββββββββββββββ β β β’ GitHub β
β β Text Index β β β β’ Google Workspace β
β β (Full-text) β β β β’ Jira/Confluence β
β ββββββββββββββββββββ β β β’ Kubernetes β
ββββββββββββββββββββββββββ β β’ Grafana/Datadog β
β² β β’ AWS/Azure β
β Generate embeddings β β’ PostgreSQL β
β β β’ And more... β
ββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββ
β Embedding Service β β²
β Port: 5000 β β
β β β
β β’ E5-small-v2 model β ββββββββββββββββββββββββββββββββ
β β’ 384 dimensions β β
β β’ ONNX Runtime β β Index tools at startup
β β’ ~33s for 318 tools β β
ββββββββββββββββββββββββββ β
β² β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DMCP Indexer (CLI) β
β npm run index β
β β
β 1. Connects to all MCP servers via Agent Gateway β
β 2. Discovers tools from each server β
β 3. Generates embeddings via embedding service β
β 4. Stores in Redis with vector index β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
dmcp/
βββ docker-compose.yml # Infrastructure (Redis VSS + Embedding)
βββ Dockerfile # ONNX-optimized embedding service
βββ app.py # Flask embedding API (E5-small-v2)
βββ requirements.txt # Python dependencies
β
βββ mcp-server/ # DMCP Server (TypeScript)
β βββ src/
β β βββ dmcp-server.ts # Runtime server (stdio)
β β βββ dmcp-indexer.ts # Indexer CLI
β β βββ redis-vss.ts # Redis vector search
β βββ package.json
β
βββ gateway/ # Agent Gateway Configuration
β βββ agentgateway # Binary (download from 1MCP)
β βββ config.yaml # Generated config (gitignored)
β βββ config.yaml.example # Example config structure
β βββ config_parts/ # β οΈ YOUR PRIVATE CONFIGS (gitignored)
β
βββ one-mcp/ # MCP Server Registry
βββ mcp.json # Backend SSE endpoints (gitignored)
βββ mcp.json.example # Example config
βββ start.sh # Start gateway
βββ stop.sh # Stop gateway
- Docker & Docker Compose
- Node.js 18+
- Agent Gateway binary (for running MCP servers)
git clone https://github.com/yourusername/dmcp.git
cd dmcp
# Copy example configs
cp one-mcp/mcp.json.example one-mcp/mcp.json
cp gateway/config.yaml.example gateway/config.yaml
# Edit with your MCP server configurations
# (Add your API keys, tokens, etc.)# Start Redis VSS + Embedding Service
docker-compose up -d
# Verify services are healthy
curl http://localhost:5000/health
# β {"status": "healthy", "model": "intfloat/e5-small-v2", "runtime": "onnx"}
docker exec mcp-redis-vss redis-cli ping
# β PONGcd one-mcp
./start.sh
# Gateway exposes MCP servers on ports 3101-3120cd mcp-server
npm install
# Index all tools in Redis (~33 seconds for 318 tools)
npm run index
# Output:
# βββββββββββββββββββββββββββββββββββββββββββββββββββ
# DMCP Indexer - Tool Discovery
# βββββββββββββββββββββββββββββββββββββββββββββββββββ
# [ββββββββββββββββββββββββββββββ] 100% (318/318)
# β Indexed 318 tools in 33522msAdd to your .vscode/mcp.json:
{
"servers": {
"dmcp": {
"command": "node",
"args": [
"/path/to/dmcp/mcp-server/node_modules/.bin/tsx",
"/path/to/dmcp/mcp-server/src/dmcp-server.ts",
"/path/to/dmcp/one-mcp/mcp.json"
],
"env": {
"REDIS_PORT": "6380",
"DMCP_TOP_K": "30",
"DMCP_MIN_SCORE": "0.25"
}
}
}
}DMCP uses hybrid search combining:
- Text Search (fast, exact) - "jira" β
jira_get,jira_post,jira_search - Vector Search (semantic) - "ticket management" β Jira tools via embeddings
Example queries and what they find:
| Query | Finds | Why |
|---|---|---|
"jira" |
Jira tools | Exact text match |
"ticket management" |
Jira tools | Semantic similarity |
"check pod logs" |
Kubernetes tools | Semantic match |
"search emails" |
Google Workspace | Semantic match |
"query AWS costs" |
AWS Cost Explorer | Semantic match |
| Variable | Default | Description |
|---|---|---|
REDIS_HOST |
localhost | Redis server host |
REDIS_PORT |
6380 | Redis server port |
EMBEDDING_URL |
http://localhost:5000 | Embedding service URL (indexer only) |
EMBEDDING_MODEL |
intfloat/e5-small-v2 | Embedding model name |
DMCP_TOP_K |
30 | Max tools returned per search |
DMCP_MIN_SCORE |
0.25 | Minimum similarity threshold |
npm run index # Index (skip if already cached)
npm run index:force # Force re-index all toolsFor deploying to your own server:
- Copy your private configs to
gateway/config_parts/on your server - Generate gateway config:
cat gateway/config_parts/*.yaml > gateway/config.yaml - Start services:
docker-compose up -d - Start gateway:
cd one-mcp && ./start.sh - Index tools:
cd mcp-server && npm run index
For Apple Silicon (M1/M2/M3), uncomment the platform: linux/arm64 line in docker-compose.yml.
| Metric | Value |
|---|---|
| Tools indexed | 318 |
| Index time | ~33 seconds |
| Search latency | ~50ms |
| Token reduction | 98% (from ~100k to ~2k) |
| Embedding model | E5-small-v2 (33M params, 384 dims) |
Implements MCP Tool Discovery:
- β
listChanged: truecapability - β
notifications/tools/list_changednotifications - β Dynamic tool availability based on search
MIT