Skip to content

pyrault/dmcp

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

DMCP - Dynamic Model Context Protocol

Semantic tool discovery for MCP - Solves the "too many tools" problem by making tool discovery query-driven with vector search.

🎬 Inspiration & Credits

This project was inspired by:

🎯 The Problem

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

✨ The Solution

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.

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           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                                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ Project Structure

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

πŸš€ Quick Start

Prerequisites

1. Clone and Setup

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.)

2. Start Infrastructure

# 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
# β†’ PONG

3. Start Agent Gateway

cd one-mcp
./start.sh
# Gateway exposes MCP servers on ports 3101-3120

4. Index Tools

cd 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 33522ms

5. Configure VS Code

Add 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"
      }
    }
  }
}

πŸ” How Search Works

DMCP uses hybrid search combining:

  1. Text Search (fast, exact) - "jira" β†’ jira_get, jira_post, jira_search
  2. 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

βš™οΈ Configuration

Environment Variables

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

Indexer CLI

npm run index                # Index (skip if already cached)
npm run index:force          # Force re-index all tools

πŸ–₯️ Server Deployment

For deploying to your own server:

  1. Copy your private configs to gateway/config_parts/ on your server
  2. Generate gateway config: cat gateway/config_parts/*.yaml > gateway/config.yaml
  3. Start services: docker-compose up -d
  4. Start gateway: cd one-mcp && ./start.sh
  5. Index tools: cd mcp-server && npm run index

For Apple Silicon (M1/M2/M3), uncomment the platform: linux/arm64 line in docker-compose.yml.

πŸ“Š Performance

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)

πŸ“ MCP Spec Compliance

Implements MCP Tool Discovery:

  • βœ… listChanged: true capability
  • βœ… notifications/tools/list_changed notifications
  • βœ… Dynamic tool availability based on search

πŸ“„ License

MIT

About

Dynamic MCP - Semantic tool discovery for Model Context Protocol

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • JavaScript 51.4%
  • TypeScript 39.9%
  • Python 4.3%
  • Shell 3.0%
  • Dockerfile 1.4%