Skip to content

Grep-Juub/dmcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

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

Tests License

🎯 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 semantic vector search to discover tools on-demand:

User: "Create a GitHub issue for this bug"

LLM calls: search_tools(query="create GitHub issue")
    β†’ Returns top-15 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.

✨ Features

  • πŸ” Semantic Search: ToolRet-trained E5 model for accurate tool retrieval
  • ⚑ Fast: ~50ms search latency, 98% token reduction
  • πŸ”„ Connection Resilience: Auto-retry, health checks, reconnection
  • 🐳 Docker Ready: Full stack with Redis VSS + Embedding service
  • πŸ“Š Observable: Health endpoints, session logging, connection status
  • βœ… Tested: 56 unit tests with vitest

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           VS Code / GitHub Copilot                          β”‚
β”‚                                                                             β”‚
β”‚  User: "search for kubernetes tools"                                        β”‚
β”‚        β†’ search_tools("kubernetes")                                         β”‚
β”‚        ← Returns: 15 k8s tools (get_pods, list_deployments, ...)           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                  β”‚ HTTP (Streamable HTTP Transport)
                                  β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         DMCP Server (port 3001)                             β”‚
β”‚                                                                             β”‚
β”‚  β€’ Exposes 1 meta-tool: search_tools                                        β”‚
β”‚  β€’ Pure vector search (COSINE similarity, HNSW index)                       β”‚
β”‚  β€’ Sends listChanged notifications when tools discovered                    β”‚
β”‚  β€’ Connection keep-alive with health checks (30s interval)                  β”‚
β”‚  β€’ Auto-retry on connection failures (3 attempts, exponential backoff)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚                                                  β”‚
             β”‚ Query embeddings                                 β”‚ Tool calls (SSE)
             β–Ό                                                  β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Redis Stack (port 6380)      β”‚                β”‚     Backend MCP Servers    β”‚
β”‚                                β”‚                β”‚     (via Agent Gateway)    β”‚
β”‚  β€’ Vector Index (HNSW)         β”‚                β”‚                            β”‚
β”‚  β€’ COSINE similarity           β”‚                β”‚  β€’ GitHub, Jira, Confluenceβ”‚
β”‚  β€’ 400+ tools indexed          β”‚                β”‚  β€’ Google Workspace, Notionβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β”‚  β€’ Kubernetes, AWS, Azure  β”‚
             β–²                                    β”‚  β€’ And more...             β”‚
             β”‚                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Infinity Embedding Service    β”‚
β”‚  (port 5000)                   β”‚
β”‚                                β”‚
β”‚  β€’ ToolRet e5-large-v2 model   β”‚
β”‚  β€’ 1024 dimensions             β”‚
β”‚  β€’ OpenAI-compatible API       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Quick Start

Prerequisites

  • Docker & Docker Compose
  • An MCP server gateway exposing your tools (e.g., Agent Gateway)

1. Clone and Start

git clone https://github.com/yourusername/dmcp.git
cd dmcp

# Start everything: Redis, Embedding Service, and DMCP Server
docker compose up -d

# Wait for services to be healthy (~2-3 minutes for embedding model to load)
docker compose ps

2. Index Your Tools

# Run the indexer to populate Redis with tools from your MCP gateway
docker compose run --rm indexer

# Verify tools are indexed
curl http://localhost:3001/health
# β†’ {"status":"healthy","toolCount":420,...}

3. Configure VS Code

Add to your .vscode/mcp.json:

{
  "servers": {
    "dmcp": {
      "type": "http",
      "url": "http://localhost:3001/mcp"
    }
  }
}

That's it! The search_tools meta-tool is now available in VS Code / GitHub Copilot.

πŸ“ Project Structure

dmcp/
β”œβ”€β”€ docker-compose.yml          # Full stack configuration
β”œβ”€β”€ server/                     # DMCP Server (TypeScript)
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ dmcp-server.ts      # Main server with connection management
β”‚   β”‚   β”œβ”€β”€ redis-vss.ts        # Redis vector similarity search
β”‚   β”‚   β”œβ”€β”€ custom-embedding-provider.ts
β”‚   β”‚   β”œβ”€β”€ dmcp-server.test.ts # Unit tests (28 tests)
β”‚   β”‚   └── redis-vss.test.ts   # Unit tests (28 tests)
β”‚   β”œβ”€β”€ vitest.config.ts
β”‚   └── package.json
β”œβ”€β”€ indexer/                    # Tool Indexer (TypeScript)
β”‚   └── src/
β”‚       └── index.ts            # CLI indexer with parallel discovery
└── README.md

🐳 Docker Commands

# Start full stack
docker compose up -d

# View logs
docker compose logs -f dmcp-server

# Run one-shot indexing
docker compose run --rm indexer

# Start continuous sync worker
docker compose --profile worker up -d

# Rebuild after code changes
docker compose build dmcp-server && docker compose up -d dmcp-server

# Stop everything
docker compose down

# Stop and delete indexed data
docker compose down -v

βš™οΈ Configuration

Environment Variables

Variable Default Description
PORT 3000 Server port (inside container)
REDIS_HOST localhost Redis server host
REDIS_PORT 6379 Redis server port
EMBEDDING_URL http://localhost:5000 Embedding service URL
DMCP_TOP_K 15 Max tools returned per search
DMCP_MIN_SCORE 0.3 Minimum similarity threshold

Connection Resilience

Variable Default Description
DMCP_RETRY_ATTEMPTS 3 Max connection retry attempts
DMCP_RETRY_DELAY_MS 1000 Base delay between retries (exponential backoff)
DMCP_HEALTH_INTERVAL_MS 30000 Health check interval for backend connections
DMCP_CONNECTION_TIMEOUT_MS 10000 Connection timeout

Docker Compose Services

Service Container Host Port Description
redis-vss mcp-redis-vss 6380 Redis Stack with vector search
embedding-service mcp-embedding-infinity 5000 Infinity embedding service
dmcp-server dmcp-server 3001 DMCP MCP server
indexer dmcp-indexer - One-shot indexer
indexer-worker dmcp-indexer-worker - Continuous sync (optional)

πŸ” How Search Works

DMCP uses pure vector search with the ToolRet embedding model:

  1. Query is embedded using ToolRet-trained E5-large-v2
  2. Redis performs HNSW nearest neighbor search
  3. Top-K results are returned sorted by COSINE similarity
  4. Tools become available via notifications/tools/list_changed

Example queries:

Query Finds
"create GitHub issue" GitHub tools
"ticket management" Jira tools
"check pod logs" Kubernetes tools
"search emails" Google Workspace
"query Notion database" Notion tools

πŸ₯ Health & Monitoring

Health Endpoint

curl http://localhost:3001/health

Response:

{
  "status": "healthy",
  "toolCount": 440,
  "activeSessions": 2,
  "backendConnections": {
    "total": 5,
    "healthy": 5,
    "details": [
      {"serverId": "github", "healthy": true, "lastCheck": 1704700000000},
      {"serverId": "serena", "healthy": true, "lastCheck": 1704700000000}
    ]
  },
  "config": {
    "retryAttempts": 3,
    "retryDelayMs": 1000,
    "healthIntervalMs": 30000,
    "connectionTimeoutMs": 10000
  },
  "uptime": 3600
}

Server Logs

docker compose logs -f dmcp-server

# Example output:
# 16:38:36 [DMCP] πŸš€ Server listening on http://0.0.0.0:3000
# 16:38:36 [DMCP] βœ“ Found 440 indexed tools
# 16:38:52 [DMCP] POST /mcp [initialize]
# 16:38:52 [DMCP] πŸ“‘ New connection request (session #1)
# 16:39:01 [DMCP] πŸ” Search: "kubernetes pods" (limit: 15)
# 16:39:01 [DMCP] βœ“ Found 12 tools in 45ms

πŸ§ͺ Testing

cd server

# Run tests
npm test

# Run with watch mode
npm run test:watch

# Run with coverage
npm run test:coverage

Test Coverage: 56 tests covering:

  • Tool name sanitization and parsing
  • Connection retry and health check logic
  • Redis vector search operations
  • Embedding operations

πŸ”§ Local Development

# Start only infrastructure
docker compose up -d redis-vss embedding-service

# Run server locally
cd server
npm install
REDIS_PORT=6380 EMBEDDING_URL=http://localhost:5000 npm run start

# Run tests
npm test

βž• Adding MCP Servers

DMCP works with any MCP server. Example configurations are in gateway/config_parts/.

Notion MCP Server

Notion MCP provides tools for searching, reading, and creating Notion pages/databases.

  1. Create a Notion integration at notion.so/my-integrations
  2. Add to your gateway config (gateway/config_parts/70-notion.yaml):
targets:
  - name: notion
    type: mcp
    target_config:
      command: npx
      args:
        - -y
        - "@notionhq/notion-mcp-server"
      env:
        OPENAPI_MCP_HEADERS: '{"Authorization": "Bearer ${NOTION_API_KEY}", "Notion-Version": "2022-06-28"}'
  1. Set your API key: export NOTION_API_KEY=ntn_...
  2. Restart gateway and re-index: docker compose run --rm indexer

Other Popular MCP Servers

Server Package Documentation
GitHub @modelcontextprotocol/server-github GitHub MCP
Slack @modelcontextprotocol/server-slack Slack MCP
Google Drive @modelcontextprotocol/server-gdrive GDrive MCP
PostgreSQL @modelcontextprotocol/server-postgres Postgres MCP

πŸ“Š Performance

Metric Value
Tools indexed 440
Index time ~45 seconds
Search latency ~50ms
Token reduction 98%
Embedding model ToolRet-e5-large-v2 (1024 dims)

πŸ“ MCP Spec Compliance

Implements MCP Specification with Streamable HTTP Transport:

  • βœ… listChanged: true capability
  • βœ… notifications/tools/list_changed notifications
  • βœ… Dynamic tool availability based on search
  • βœ… Streamable HTTP transport (POST/GET/DELETE)
  • βœ… Session management with UUID session IDs
  • βœ… SSE for async notifications

πŸ”¬ Research Foundation

Implementation based on "Retrieval Models Aren't Tool-Savvy" (ACL 2025):

Key Insight: General IR models perform poorly on tool retrieval; tool-specific training is essential.

🎬 Inspiration

πŸ“„ License

MIT

About

Dynamic MCP - Semantic tool discovery for Model Context Protocol

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors