╔════════════════════════════════════════════════════════════╗
║ ║
║ ███╗ ███╗ ██████╗██████╗ ██╗ ██╗ ███╗ ███╗║
║ ████╗ ████║██╔════╝██╔══██╗ ██║ ██║ ████╗ ████║║
║ ██╔████╔██║██║ ██████╔╝ ██║ ██║ ██╔████╔██║║
║ ██║╚██╔╝██║██║ ██╔═══╝ ██║ ██║ ██║╚██╔╝██║║
║ ██║ ╚═╝ ██║╚██████╗██║ ███████╗███████╗██║ ╚═╝ ██║║
║ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚══════╝╚══════╝╚═╝ ╚═╝║
║ ║
║ L L M R O U T E R ║
║ ║
╚════════════════════════════════════════════════════════════╝MCP LLM路由器
一种模型上下文协议(MCP)服务器,用于在多个提供者之间路由LLM请求并连接到其他MCP服务器。 采用“除大脑外的所有局部”架构设计 为了隐私和控制。
功能(统一路由器+法官)
- 一台服务器,两个角色:
mcp_llm_router.server现在正在运送Judge工具——没有单独的mcp-as-a-judge需要服务器。 - 多提供商LLM路由:将请求路由到OpenAI、OpenRouter、DeepInfra和其他与OpenAI兼容的API。
- 可配置的“大脑”模型:选择DeepSeek推理或任何与OpenAI兼容的模型作为路由器大脑。
- 会话管理:使用目标、约束和事件日志跟踪代理会话。
- 质量把关(评委):计划→ code → test → 使用嵌入式Judge工具集进行完成验证。
- MCP本地上下文:嵌入式判断资源公开当前任务状态、历史、量规和工作流状态快照。
- 本地第一存储器: 默认:通过Ollama进行本地嵌入 具有可选的ChromaDB矢量存储,用于高效的语义搜索。支持OpenAI兼容端点作为回退。
- 本地交叉编码器重新排序:可选的以隐私为中心的重新排序,使用Qwen3-Reranker-0.6B提高搜索相关性,无需外部API调用。
- MCP服务器编排:连接并协调多个MCP服务器。
- 跨服务器工具调用:跨不同MCP服务器调用工具。
- 通用MCP兼容性:适用于任何兼容MCP的客户端(不依赖于特定的IDE)。
建筑:除大脑外的所有地方
该项目遵循 “除了大脑,都是局部的” 设计理念:
- ✅ 嵌入:通过Ollama在本地运行(默认值:
qwen3-embedding:0.6b) - ✅ 向量存储:SQLite(默认)或带HNSW索引的ChromaDB(可选RAG包)
- ✅ 文档分块:基于令牌的重叠分块(可选RAG包)
- ✅ 语义搜索:与L2归一化向量的局部余弦相似性
- ✅ 重新排序:可选择使用Qwen3-Reranker-0.6B进行本地交叉编码器重新排序
- 🌐 LLM“大脑”:可配置的外部API(DeepSeek、OpenAI等),用于推理和生成
为什么? 这种架构使您的数据和语义搜索保持私密和快速,同时仅将强大的外部LLM用于高级推理任务。
安装
该项目在 Python 3.12和3.13.
快速安装(推荐)
一个命令自动安装:
./install.sh此脚本将:
- ✅ 创建Python虚拟环境
- ✅ 从安装所有依赖项
pyproject.toml - ✅ 检查Ollama的安装情况
- ✅ 验证设置
- ✅ 使用您的特定路径显示下一步
手动安装
如果您更喜欢手动安装或需要Conda环境:
# Clone the repository
git clone https://github.com/groxaxo/mcp-llm-router.git
cd mcp-llm-router
# Option 1: Using venv (recommended)
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
pip install -U pip
pip install -e .
# Option 2: Using Conda
conda create -n mcp-router python=3.13 -y
conda activate mcp-router
pip install -U pip
pip install -e .Ollama设置(局部嵌入所需)
安装Ollama以实现本地、注重隐私的嵌入:
# Linux/macOS
curl -fsSL https://ollama.ai/install.sh | sh
# Or download from https://ollama.ai拉动嵌入模型:
ollama pull qwen3-embedding:0.6b确认Ollama正在运行:
curl http://localhost:11434/api/version替代嵌入模型:
nomic-embed-text-通用嵌入件mxbai-embed-large-更大的型号,质量更好
通过环境变量设置:
export EMBEDDINGS_MODEL="nomic-embed-text"项目结构
mcp-llm-router/
├── install.sh # Automated installation script
├── README.md # This file
├── pyproject.toml # Python package configuration
│
├── mcp_llm_router/ # Main package
│ ├── server.py # MCP server entry point
│ ├── brain.py # LLM routing logic
│ ├── memory.py # Memory management (embeddings, search, rerank)
│ ├── codex.py # MCP server orchestration
│ └── judge/ # Embedded judge tools for quality gating
│
├── rag/ # Optional RAG package (ChromaDB, chunking)
│ ├── main.py # CLI for indexing and queries
│ ├── indexer.py # Document indexing
│ ├── retriever.py # Vector search
│ └── reranker.py # Local cross-encoder reranking
│
├── scripts/ # Utility scripts
│ ├── verify_server.py # Installation verification
│ ├── opencode # CLI tool for direct LLM requests
│ ├── mcp_client.py # MCP client for testing
│ └── mcp_manager.py # MCP server management
│
├── examples/ # Example configurations and demos
│ ├── demo_judge_gating.py # End-to-end judge workflow demo
│ ├── local_reranker_example.py # Local reranking example
│ ├── mcp-config.deepseek-ollama.json
│ └── mcp-config.local-reranker.json
│
└── tests/ # Test suite
├── test_server.py
├── test_mcp.py
└── test_local_reranker.py配置
MCP服务器配置(mcp-config.json)
规范最小配置
{
"mcpServers": {
"llm-router": {
"command": "python",
"args": ["-m", "mcp_llm_router.server"],
"env": {
"DEEPSEEK_API_KEY": "your-deepseek-key",
"ROUTER_BRAIN_PROVIDER": "deepseek",
"ROUTER_BRAIN_MODEL": "deepseek-reasoner",
"ROUTER_BRAIN_API_KEY_ENV": "DEEPSEEK_API_KEY",
"EMBEDDINGS_PROVIDER": "ollama",
"EMBEDDINGS_BASE_URL": "http://localhost:11434",
"EMBEDDINGS_MODEL": "qwen3-embedding:0.6b"
}
}
}
}提供程序覆盖示例
{
"mcpServers": {
"llm-router": {
"command": "python",
"args": ["-m", "mcp_llm_router.server"],
"env": {
"OPENROUTER_API_KEY": "sk-or-...",
"ROUTER_BRAIN_PROVIDER": "openrouter",
"ROUTER_BRAIN_MODEL": "anthropic/claude-3.7-sonnet",
"ROUTER_BRAIN_API_KEY_ENV": "OPENROUTER_API_KEY",
"ROUTER_BRAIN_BASE_URL": "https://openrouter.ai/api/v1",
"EMBEDDINGS_PROVIDER": "ollama",
"EMBEDDINGS_BASE_URL": "http://localhost:11434",
"EMBEDDINGS_MODEL": "qwen3-embedding:0.6b"
}
}
}
}配置+演示示例
examples/mcp-config.deepseek-ollama.json-DeepSeek大脑+Ollama嵌入+判断历史持久性。examples/mcp-config.local-reranker.json-DeepSeek大脑+Ollama嵌入+本地交叉编码器重新排序。examples/demo_judge_gating.py-端到端演示,对内存进行索引,并通过判断门控引导任务router_chat.examples/local_reranker_example.py-使用本地交叉编码器重新排序来提高搜索相关性的示例。
运行演示:
python examples/demo_judge_gating.py --config examples/mcp-config.deepseek-ollama.json运行本地重新登录示例:
python examples/local_reranker_example.py注意:演示跳过 request_plan_approval 因为它需要用户启发。确保 DEEPSEEK_API_KEY (或 LLM_API_KEY)设置完毕,Ollama正在进行嵌入。
嵌入式裁判资源+提示
嵌入式法官现在公开了附加的MCP资源,并在现有工具旁边给出提示:
- 资源:
- judge://current-task - judge://task/{task_id} - judge://task/{task_id}/history - judge://policy/rubric - judge://workflow/states
- 提示:
- start_judged_coding_task - submit_implementation_for_review - prepare_testing_evidence
当MCP客户端公开根时,判断审查/测试工具会根据这些根验证提交的路径。当根不可用时,服务器将保留现有的stdio优先行为。
环境变量
在您的环境中或在配置中设置API密钥:
export OPENAI_API_KEY="sk-proj-..."
export DEEPINFRA_API_KEY="..."
export OPENROUTER_API_KEY="sk-or-..."
export DEEPSEEK_API_KEY="..."大脑配置(路由器LLM)
本README中的规范示例使用 DeepSeek大脑+本地Olama植入物 基线。提供者覆盖只需要更改 ROUTER_BRAIN_* 变量和API键。
# Core brain settings
export ROUTER_BRAIN_MODEL="deepseek-reasoner"
export ROUTER_BRAIN_PROVIDER="deepseek"
export ROUTER_BRAIN_API_KEY_ENV="DEEPSEEK_API_KEY"
# Optional overrides
export ROUTER_BRAIN_BASE_URL="https://api.deepseek.com"
export ROUTER_BRAIN_MAX_TOKENS="4000"
export ROUTER_BRAIN_TEMPERATURE="0.2"您还可以使用以下命令设置每次会话的大脑 configure_brain 工具。
内存配置(嵌入+重新排序)
默认值:本地Olama嵌入(推荐)
不需要API密钥! 默认配置使用本地Ollama嵌入:
# Storage paths
export MCP_ROUTER_DATA_DIR="./.mcp-llm-router"
export MCP_ROUTER_MEMORY_DB="./.mcp-llm-router/memory.db"
# Local embeddings via Ollama (DEFAULT - no API key needed)
export EMBEDDINGS_PROVIDER="ollama"
export EMBEDDINGS_BASE_URL="http://localhost:11434"
export EMBEDDINGS_MODEL="qwen3-embedding:0.6b"
export EMBEDDINGS_PATH="/api/embed"
# No EMBEDDINGS_API_KEY_ENV needed for local Ollama!替代方案:OpenAI兼容嵌入
如果你更喜欢基于云的嵌入:
# Embeddings via OpenAI
export EMBEDDINGS_PROVIDER="openai"
export EMBEDDINGS_BASE_URL="https://api.openai.com/v1"
export EMBEDDINGS_MODEL="text-embedding-3-small"
export EMBEDDINGS_API_KEY_ENV="OPENAI_API_KEY"
export EMBEDDINGS_PATH="/embeddings"重新排名(可选)
重新排名是可选的,默认为“无”。有三种模式可供选择:
1.本地交叉编码器重新排序(出于隐私考虑建议)
在没有外部API调用的情况下,使用本地Qwen3-Reranker-0.6B模型进行重新排序:
# Local cross-encoder reranking (requires transformers and torch)
export RERANK_PROVIDER="local"
export RERANK_MODE="local"
export RERANK_MODEL="tomaarsen/Qwen3-Reranker-0.6B-seq-cls" # Default model需求:
- 安装PyTorch:
pip install torch - 安装变压器:
pip install transformers - 该模型将在首次使用时自动下载(~1.2GB)
2.基于LLM的重新排名
使用外部LLM API进行重新排序:
# Rerank using OpenAI-compatible LLM (optional)
export RERANK_PROVIDER="openai"
export RERANK_BASE_URL="https://api.openai.com/v1"
export RERANK_MODEL="gpt-4o-mini"
export RERANK_API_KEY_ENV="OPENAI_API_KEY"
export RERANK_PATH="/chat/completions"
export RERANK_MODE="llm"3.禁用重新排名
# Or disable reranking entirely (default)
export RERANK_PROVIDER="none"法官恒心(嵌入式法官)
# Persist judge conversation history + task metadata
export MCP_JUDGE_DATABASE_URL="sqlite:///./.mcp-llm-router/judge_history.db"高级:ChromaDB+代币分块(RAG包)
为了通过矢量索引和智能分块增强语义搜索,该存储库包括一个可选的 rag 该软件包提供:
- 基于令牌的分块 重叠以实现一致的语义粒度
- ChromaDB矢量存储 使用HNSW索引进行快速相似性搜索
- L2归一化嵌入 一致余弦相似性
- 批量嵌入 以及高效的扰乱
使用RAG包
- 安装其他依赖项 (已包含在
pyproject.toml):
pip install -e . # chromadb, transformers are now included- 索引你的代码库:
python -m rag.main --path . --exts .py,.md --interactive这将:
- 扫描当前目录 .py 和 .md 文件 - 将它们分为400个令牌段,其中80个令牌重叠 - 使用Olama嵌入(qwen3-embedding:0.6b) - 存储在ChromaDB data/chroma/ - 进入测试查询的交互模式
- 在代码中使用:
from rag.retriever import retrieve
from rag.indexer import index_path
# Index documents
stats = index_path("/path/to/docs", exts=[".py", ".md"])
print(f"Indexed {stats['files_indexed']} files")
# Retrieve relevant chunks
results = retrieve("How does authentication work?", top_k=5)
for hit in results:
print(f"Score: {hit['distance']:.4f}")
print(f"File: {hit['meta']['path']}")
print(f"Content: {hit['doc']}\n")RAG包装组件:
rag/embedding_config.py-配置常数rag/chunker.py-基于令牌的文本分块rag/ollama_embedder.py-Ollama嵌入并归一化rag/chroma_store.py-ChromaDB初始化和管理rag/indexer.py-文档索引管道rag/retriever.py-矢量搜索和检索rag/main.py-用于索引和查询的CLI
注: RAG包是一个自包含的增强功能。核心MCP服务器与其内置的SQLite内存存储一起工作,不需要ChromaDB。
用法
正在运行MCP服务器
使用服务器运行程序
# List configured servers
python scripts/mcp_server_runner.py list
# Run a specific server
python scripts/mcp_server_runner.py run llm-router使用服务器管理器
# Add a new server
python scripts/mcp_manager.py add my-server python -m my_mcp_server
# List servers
python scripts/mcp_manager.py list
# Test server connection
python scripts/mcp_manager.py test llm-router
# Remove a server
python scripts/mcp_manager.py remove my-server连接到MCP服务器
使用MCP客户端
# List tools on a server
python scripts/mcp_client.py list-tools llm-router
# Call a tool on a server
python scripts/mcp_client.py call-tool llm-router start_session '{"goal": "Test session"}'使用服务器管理器进行跨服务器操作
# Call a tool across all configured servers
python scripts/mcp_manager.py call start_session '{"goal": "Test all servers"}'MCP工具可用
会话管理
start_session(goal, constraints, context, metadata)-启动新的代理会话log_event(session_id, kind, message, details)-将事件记录到会话中get_session_context(session_id)-检索完整会话数据
LLM路由
agent_llm_request(session_id, prompt, model, base_url, api_key_env, ...)-通往LLM提供商的路线configure_brain(...)-设置全局或每次会话的大脑模型/设置get_brain_config(session_id)-阅读活动大脑配置router_chat(session_id, message, ...)-主脑聊天(记忆+工作流程指导)
内存(嵌入+重新排序)
configure_memory(...)-全局或按会话设置嵌入/重新排序配置memory_index(namespace, texts, metadatas, doc_ids)-将文本索引到内存中memory_search(namespace, query, top_k, rerank)-检索相关内存点击memory_delete(namespace, doc_id)-删除一个文档或整个命名空间memory_list_namespaces()-列出命名空间memory_stats()-显示内存计数
MCP服务器编排
connect_mcp_server(server_name, command, args, env)-配置与另一个MCP服务器的连接list_mcp_servers()-列出已配置的MCP服务器连接call_mcp_tool(server_name, tool_name, arguments)-调用其他MCP服务器上的工具list_mcp_tools(server_name)-列出其他MCP服务器上可用的工具
判断工具(内置)
set_coding_task(...)get_current_coding_task()request_plan_approval(...)judge_coding_plan(...)judge_code_change(...)judge_testing_implementation(...)judge_coding_task_completion(...)raise_obstacle(...)raise_missing_requirements(...)
与MCP客户端集成
任何MCP兼容客户端
服务器与支持MCP协议的任何客户端一起工作:
{
"mcpServers": {
"llm-router": {
"command": "python",
"args": ["-m", "mcp_llm_router.server"],
"env": {
"OPENAI_API_KEY": "your-key"
}
}
}
}示例:克劳德桌面
添加到您的Claude Desktop MCP配置中:
{
"mcpServers": {
"llm-router": {
"command": "python",
"args": ["-m", "mcp_llm_router.server"],
"env": {
"OPENAI_API_KEY": "sk-...",
"DEEPINFRA_API_KEY": "..."
}
}
}
}示例:自定义MCP客户端
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
server_params = StdioServerParameters(
command="python",
args=["-m", "mcp_llm_router.server"],
env={"OPENAI_API_KEY": "your-key"}
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# Start a session
result = await session.call_tool("start_session", {
"goal": "Test the MCP server"
})
print("Session started:", result)
if __name__ == "__main__":
asyncio.run(main())提供者配置
开放人工智能
{
"base_url": null, # Uses default
"api_key_env": "OPENAI_API_KEY"
}开放路由
{
"base_url": "https://openrouter.ai/api/v1",
"api_key_env": "OPENROUTER_API_KEY"
}DeepInfra
{
"base_url": "https://api.deepinfra.com/v1/openai",
"api_key_env": "DEEPINFRA_API_KEY"
}CLI工具
这 opencode 命令提供直接CLI访问:
# Basic usage
scripts/opencode run "What is Python"
# Use specific provider
scripts/opencode run "Explain Docker" --provider deepinfra --model meta-llama/Meta-Llama-3.1-70B-Instruct发展
直接运行服务器
cd ~/mcp-llm-router
conda activate mcp-router
python -m mcp_llm_router.server测试
# Test server startup
timeout 5 python -m mcp_llm_router.server
# Test CLI
scripts/opencode run "Hello world"
# Test MCP client
python scripts/mcp_client.py list-tools llm-router建筑
┌─────────────────┐ ┌──────────────────────────────────────┐
│ MCP Client │◄──►│ LLM Router MCP Server │
│ (Claude, etc.) │ │ ┌────────────────────────────────┐ │
└─────────────────┘ │ │ Session & Memory Management │ │
│ │ • SQLite/ChromaDB (local) │ │
│ │ • Ollama Embeddings (local) │ │
│ │ • L2-normalized vectors │ │
│ └────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────┐ │
│ │ Brain (External LLM API) │ │
│ │ • DeepSeek / OpenAI / etc. │ │
│ │ • Reasoning & Generation │ │
│ └────────────────────────────────┘ │
└──────────────────────────────────────┘
│
▼
┌──────────────────┐
│ Other MCP Servers│
│ • File system │
│ • Database │
│ • APIs │
└──────────────────┘
All-Local Except the Brain:
✅ Embeddings: Ollama (local, no API key)
✅ Vector Store: SQLite or ChromaDB (local)
✅ Semantic Search: Local cosine similarity
🌐 LLM Brain: External API (configurable)许可证
MIT许可证-有关详细信息,请参阅许可证文件。
# Basic usage with OpenAI (default)
scripts/opencode run "Explain quantum computing"
# Use a specific provider
scripts/opencode run "Write a Python function" --provider openrouter --model anthropic/claude-3-opus
# Use DeepInfra
scripts/opencode run "Summarize this text" --provider deepinfra --model meta-llama/Llama-3.1-70B-Instruct可用提供商:
openai(默认)-使用OPENAI_API_KEYopenrouter-使用OPENROUTER_API_KEYdeepinfra-使用DEEPINFRA_API_KEY
MCP工具
在Antigravity中用作MCP服务器时,可以使用以下工具:
start_session
使用目标和约束启动新的代理会话。
{
"goal": "Implement user authentication",
"constraints": "Use JWT tokens, no external dependencies",
"context": "FastAPI application"
}log_事件
记录代理会话期间的事件(信息、错误、警告、成功)。
{
"session_id": "uuid-here",
"kind": "error",
"message": "Build failed",
"details": {"exit_code": 1}
}agent_llm_request
在会话中向LLM提供者发出请求。
{
"session_id": "uuid-here",
"prompt": "How do I fix this error?",
"model": "gpt-4",
"base_url": "https://openrouter.ai/api/v1", # optional
"api_key_env": "OPENROUTER_API_KEY"
}get_session_context
检索完整的会话历史记录和事件。
{
"session_id": "uuid-here"
}反重力中的代理工作流示例
- 开始会话:
Call start_session with goal="Build a REST API for task management"- 完成任务:
Create files, run commands, etc.- 日志进度:
Call log_event with kind="info", message="Created database schema"- 卡住时:
Call agent_llm_request with prompt="How do I handle authentication?"- 评审背景:
Call get_session_context to see full history发展
直接运行MCP服务器:
cd ~/mcp-llm-router
conda activate mcp-router
python -m mcp_llm_router.server或者在安装后使用打包的CLI入口点:
mcp-llm-router检查员风格的烟雾检查能力:
python scripts/inspector_smoke.py架构和贡献者指南:
docs/architecture.mddocs/how-to-add-a-judge-tool.md
环境变量
将这些设置在您的 ~/.bashrc 或反重力配置:
export OPENAI_API_KEY="sk-..."
export OPENROUTER_API_KEY="sk-or-..."
export DEEPINFRA_API_KEY="..."