README来源: main@0d497dd1
dsh-mcp-orchestrator
MCP orchestration layer for DeepSeek Harness (DSH) — multi-server management, health monitoring, auto-restart, tool aggregation with collision handling, fallback routing, and usage statistics.
What It Does
DSH has built-in MCP client support, but it lacks orchestration: there's no health monitoring, no auto-restart on crash, no tool collision detection, no fallback routing, and no unified tool discovery. This plugin fills that gap.
Key capabilities:
- Connect to multiple stdio MCP servers simultaneously
- Health monitoring via periodic ping checks
- Auto-restart with exponential backoff on unexpected disconnection
- Tool aggregation across all servers with collision detection
- Three namespace modes for tool name conflicts (
collision,server,dot) - Fallback routing: when a tool call fails on one server, auto-retry on others providing the same tool
- Priority-weighted sorting: servers sorted by success rate then priority
- Usage statistics: per-server, per-tool, and overall call tracking with response times
- Four DSH management tools for the agent to discover, call, and monitor MCP tools
Status: v0.2.0 — Orchestration
Verified Capabilities
| Capability | Status | Test |
|---|---|---|
| MCP SDK Client API (connect, ping, listTools, callTool, close) | Pass | test/spike.mjs |
| Multi-client support (2+ servers) | Pass | test/spike.mjs |
| Error handling (non-existent tool, missing args) | Pass | test/spike.mjs |
| ServerManager connect/disconnect/restart | Pass | test/integration.mjs |
| Tool discovery and calling | Pass | test/integration.mjs |
| Auto-restart with exponential backoff | Pass | test/integration.mjs |
| Tool collision detection | Pass | test/integration.mjs |
| Namespace modes (collision/server/dot) | Pass | test/integration.mjs |
| Health monitoring (ping-based) | Pass | test/integration.mjs |
| Zod config schema validation (incl. Phase 3 fields) | Pass | test/integration.mjs |
| Plugin lifecycle (apply, tools, system prompt, cleanup) | Pass | test/integration.mjs |
| Multi-server plugin with collision handling | Pass | test/integration.mjs |
| Fallback routing on server failure | Pass | test/integration.mjs |
| Priority-weighted candidate sorting | Pass | test/integration.mjs |
| Success-rate-based server ordering | Pass | test/integration.mjs |
| UsageTracker (record, stats, getRecent, clear) | Pass | test/integration.mjs |
| mcp_stats tool (summary/server/tool/all detail modes) | Pass | test/integration.mjs |
| Fallback disabled mode (direct routing path) | Pass | test/integration.mjs |
Test Results
Spike: 34 passed, 0 failed
Integration: 236 passed, 0 failed
Total: 270 passed, 0 failed
Architecture
DSH Agent (Node.js process)
└─ Cordis Framework
└─ dsh-mcp-orchestrator plugin (apply(ctx, config))
├─ Config Schema (zod: servers[], healthCheckInterval, namespaceMode,
│ enableFallback, maxFallbackAttempts, preferHealthyServers, enableStats)
├─ System Prompt: "mcp-orchestrator" (management tools + workflow guide)
├─ Tool: mcp_list_servers (status, health, tool count per server)
├─ Tool: mcp_list_tools (aggregated tools, collision info, namespaced names)
├─ Tool: mcp_call_tool (auto-resolve, fallback routing, metadata in results)
├─ Tool: mcp_stats (usage statistics: summary/server/tool/all)
├─ ServerManager
│ ├─ Multi-server stdio connections (StdioClientTransport)
│ ├─ Auto-restart (exponential backoff, max restarts)
│ ├─ Tool sync (listTools on connect/reconnect)
│ ├─ Health ping
│ └─ findServerForTool (priority-based resolution)
├─ ToolRegistry
│ ├─ Tool aggregation across all servers
│ ├─ Collision detection (same tool name on multiple servers)
│ └─ Namespace modes: collision / server / dot
├─ HealthMonitor
│ └─ Periodic ping checks (configurable interval)
├─ UsageTracker
│ ├─ Records every call (success/failure, response time, fallback)
│ ├─ Per-server, per-tool, overall statistics
│ └─ Recent call log (configurable max records)
├─ FallbackRouter
│ ├─ Resolves tool → finds all servers providing it
│ ├─ Sorts candidates by success rate (if enabled) then priority
│ ├─ preferredServer override (try specific server first)
│ └─ Sequential fallback with max attempts limit
└─ ctx.effect() cleanup (stop monitor, close all servers, clear tracker)
Installation
Prerequisites
- Node.js >= 22.19 (or >= 24)
- DSH installed:
npm install -g @deepseek-ai/dsh - At least one MCP server to connect to
Build
cd dsh-mcp-orchestrator
npm install
npm run build
Install into DSH
Option A: From GitHub (recommended)
dsh plugin --profile web add github:Daseanle/dsh-mcp-orchestrator
dsh web
Option B: From local clone
git clone https://github.com/Daseanle/dsh-mcp-orchestrator.git
cd dsh-mcp-orchestrator && npm install && npm run build
dsh plugin --profile web add file:./dsh-mcp-orchestrator
dsh web
Configuration
Create or edit cordis.patch.yml in your DSH config directory:
- id: dsh-mcp-orchestrator
config:
servers:
- name: filesystem
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
autoRestart: true
priority: 10
- name: memory
command: npx
args: ["-y", "@modelcontextprotocol/server-memory"]
autoRestart: true
priority: 5
healthCheckInterval: 30000
namespaceMode: collision
Config Schema (zod)
| Field | Type | Default | Description |
|---|---|---|---|
servers |
array | [] |
MCP server configurations |
servers[].name |
string | — | Unique server name |
servers[].command |
string | — | Executable to run |
servers[].args |
string[] | [] |
Command line arguments |
servers[].env |
Record<string, string> | {} |
Environment variables |
servers[].autoRestart |
boolean | true |
Auto-restart on crash |
servers[].restartDelay |
number | 2000 |
Base restart delay (ms) |
servers[].maxRestarts |
number | 3 |
Max restart attempts |
servers[].priority |
number | 0 |
Priority for tool resolution (higher = preferred) |
healthCheckInterval |
number | 30000 |
Ping interval (ms) |
namespaceMode |
enum | collision |
Tool name collision handling |
enableFallback |
boolean | true |
Enable fallback routing on tool call failure |
maxFallbackAttempts |
number | 3 |
Max servers to try before giving up |
preferHealthyServers |
boolean | true |
Sort candidates by success rate (false = priority only) |
enableStats |
boolean | true |
Register mcp_stats tool and track usage |
Namespace Modes
| Mode | Behavior | Example |
|---|---|---|
collision |
Namespace only when same tool name exists on 2+ servers | echo → server1__echo (if collision) |
server |
Always namespace with serverName__toolName |
echo → server1__echo |
dot |
Always namespace with serverName.toolName |
echo → server1.echo |
Project Structure
dsh-mcp-orchestrator/
├── src/
│ ├── index.ts # Plugin entry: apply(ctx, config) with zod schema
│ ├── server-manager.ts # MCP server connections, auto-restart, tool sync
│ ├── tool-registry.ts # Tool aggregation, collision detection, namespacing
│ ├── health-monitor.ts # Periodic ping-based health checks
│ ├── usage-tracker.ts # Tool call statistics (per-server, per-tool, overall)
│ ├── fallback-router.ts # Fallback routing with priority and success-rate sorting
│ └── tools/
│ ├── list-servers.ts # mcp_list_servers tool
│ ├── list-tools.ts # mcp_list_tools tool
│ ├── call-tool.ts # mcp_call_tool tool (with fallback routing)
│ └── stats.ts # mcp_stats tool (usage statistics)
├── dist/ # Compiled JavaScript (tsc output)
├── test/
│ ├── mock-server.mjs # Mock MCP server (echo, add, greet)
│ ├── mock-server-2.mjs # Second mock server (echo, subtract) for collision tests
│ ├── spike.mjs # Spike: MCP SDK API validation (34 tests)
│ └── integration.mjs # Integration: full plugin tests (236 tests)
├── cordis.patch.yml # Example plugin configuration
├── package.json
├── tsconfig.json
├── CHANGELOG.md
└── LICENSE
Roadmap
| Phase | Scope | Status |
|---|---|---|
| Phase 1 — Spike | MCP SDK validation, connect/listTools/callTool, multi-client | Complete |
| Phase 2 — MVP | ServerManager, ToolRegistry, HealthMonitor, auto-restart, 3 DSH tools | Complete |
| Phase 3 — Orchestration | Fallback routing, usage statistics, priority weighting, mcp_stats tool | Complete |
License
MIT
还没有评论,来写第一条。