使用说明
OmniMCP
MCP生态系统的语义路由器
跨多个MCP服务器发现和执行工具,而不会造成上下文膨胀
问题
MCP工具定义消耗令牌很快。典型设置:
| 服务器 | 工具 | 令牌 |
|---|---|---|
| GitHub | 35 | ~26K |
| 松弛 | 11 | ~21K |
| 文件系统 | 8 | ~5K |
| 数据库 | 12 | ~8K |
那是 60K+代币 在谈话开始之前。添加更多服务器,您将与实际环境竞争。
为什么这很重要
上下文膨胀会降低性能。 当工具定义消耗50-100K令牌时,您用于实际对话、文档和推理的空间有限。该模型将注意力放在工具模式上,而不是你的任务上。
更多的工具=更多的幻觉。 使用50多种类似工具(如 notification-send-user 对比 notification-send-channel),模型选择了错误的工具并产生了幻觉参数。工具选择精度随着工具集的增长而下降。
动态工具加载会中断缓存。 在推理过程中按需加载工具似乎很聪明,但它会使提示缓存无效。在对话中添加的每一个新工具都意味着重新处理整个上下文。你的“优化”变成了一种绩效税。
工具结果也会使上下文膨胀。 一次文件读取可以返回50K个令牌。图像采用1K+令牌base64编码。这些在对话历史中堆积起来,推翻了早期的背景。
解决方案
OmniMCP公开了 单 semantic_router 工具 作为您整个MCP生态系统的唯一入口点。LLM从不看到单独的工具定义,只看到一个统一的接口。
Traditional: 58 tools → 55K tokens in tool definitions
OmniMCP: 1 tool → ~500 tokens (semantic_router)
它是如何工作的:
- 语义搜索 → 按意图而非名称查找相关工具。工具通过嵌入预先索引,在运行时搜索,作为文本结果返回(不是工具定义)
- 延迟服务器加载 → 服务器仅在需要时启动,完成后关闭
- 渐进式架构加载 → 仅在执行前获取完整的JSON模式,在对话中以文本形式返回
- 内容卸载 → 将大结果分块,描述图像,存储以供检索
关键见解: 工具模式出现在对话文本中,而不是工具定义中。这意味着:
- 快速缓存保持不变(工具定义永远不会改变)
- 只有相关模式才能进入上下文(通过搜索结果)
- 没有类似工具名称的幻觉(型号看到3-5个工具,而不是50个以上)
从约60K代币到约3K。获取一切,几乎无需任何成本。
架构:元工具模式
OmniMCP使用 元工具模式,类似于克劳德·科德的代理技能系统。它没有公开数十个单独的工具,而是公开了一个 semantic_router 元工具,充当整个MCP生态系统的门户。
渐进式披露工作流程
架构和请求流
运作原理
传统MCP方法:
tools: [
{name: "github_create_issue", description: "..."},
{name: "github_create_pr", description: "..."},
{name: "filesystem_read", description: "..."},
// ... 50+ more tools
]
❌ 问题:上下文膨胀、工具幻觉、没有缓存
OmniMCP的元工具方法:
{
"tools": [
{
"name": "semantic_router",
"description": "Universal gateway to MCP ecosystem...\n
OPERATIONS: search_tools, get_server_info, execute_tool...\n
LIST OF INDEXED SERVERS:\n
filesystem: 8 tools (file operations, read/write)\n
github: 35 tools (issues, PRs, repos)\n
...",
"input_schema": {
"operation": "search_tools | execute_tool | ..."
}
}
]
}
✅ 优点:单一工具定义、描述中的服务器列表、动态发现
与克劳德技能平行
Claude Skills和OmniMCP有着相同的架构见解:
| 方面 | 克劳德技能 | OmniMCP |
|---|---|---|
| 元工具 | Skill 工具 |
semantic_router 工具 |
| 发现 | 工具描述中的技能描述 | 服务器列表+工具描述中提示 |
| 调用 | Skill(command="skill-name") |
semantic_router(operation="execute_tool", server_name=...) |
| 上下文注入 | 调用时加载技能说明 | 按需获取工具模式,以文本形式返回 |
| 缓存友好 | 工具定义永远不会改变 | 工具定义永远不变 |
| 动态列表 | <available_skills> 部分 |
LIST OF INDEXED SERVERS 部分 |
| 行为暗示 | 技能描述指南LLM | 服务器 hints 现场指南LLM |
关键见解: 两个系统都通过以下方式注入指令 迅速扩张 而不是传统的函数调用。工具描述成为LLM读取和推理的动态目录,而实际执行细节则延迟加载。
行为指导示例:
克劳德技能:
<available_skills>
skill-creator: "When user wants to create a new skill..."
internal-comms: "When user wants to write internal communications..."
</available_skills>
OmniMCP hints:
{
"elevenlabs": {
"hints": [
"When the user requests audio generation (speech or music), always execute in background mode",
"Proactively offer to play audio using the ElevenLabs tool when contextually relevant"
]
}
}
两者都注射 行为指示 这决定了LLM如何使用这些工具,而不仅仅是它们做什么。
真实世界示例
多服务器编排正在进行中:
Claude Code使用OmniMCP(以前是脉冲星mcp)来协调多个mcp服务器,从而生成了一个视频。
过程:
- Exa(背景模式) -并行网络搜索以收集最新消息
- 模态沙盒 -根据新闻数据计算和生成视频
- 文件系统 -从Modal的输出中检索到视频文件
- FFmpeg -将视频转换为GIF格式
工作流程:
search_tools("web search news")
→ execute_tool(exa, search, in_background=True) × 3 parallel calls
→ poll_task_result() → aggregate results
→ execute_tool(modal-sandbox, generate_video, data)
→ execute_tool(filesystem, read_file, video_path)
→ execute_tool(modal-sandbox, ffmpeg_convert, video_to_gif)
这表明:
- 语义发现 -在不知道确切名称的情况下跨服务器查找正确的工具
- 后台执行 -并行考试搜索而不阻止对话
- 跨服务器协调 模态→ 文件系统→ 具有自动状态管理的模态管道
- 接口 -所有操作通过一个
semantic_router工具
没有OmniMCP:50多个工具定义、复杂的编排、上下文溢出。 使用OmniMCP:探索→ 执行→ 协调。无缝。
安装
uv pip install omnimcp // or uv add omnimcp
配置
环境变量
OmniMCP需要几个环境变量才能运行。您必须在运行之前配置这些 index 或 serve 命令。
所需变量:
| 变量 | 描述 | 示例 |
|---|---|---|
OPENAI_API_KEY |
用于嵌入和描述的OpenAI API密钥 | sk-proj-... |
TOOL_OFFLOADED_DATA_PATH |
存储卸载内容(大结果、图像)的路径 | /path/to/tool_offloaded_data |
Qdrant连接(选择一种模式):
| 模式 | 变量 | 描述 |
|---|---|---|
| 本地文件 | QDRANT_DATA_PATH=/path/to/data |
嵌入式Qdrant,持久到磁盘 |
| 在存储器中 | QDRANT_DATA_PATH=:memory: |
嵌入式Qdrant,无持久性(测试) |
| 远程服务器 | QDRANT_URL=http://localhost:6333 |
Docker或自托管Qdrant |
| Qdrant云 | QDRANT_URL=https://xxx.qdrant.ioQDRANT_API_KEY=your-api-key |
管理Qdrant云 |
可选变量(默认值):
| 变量 | 默认值 | 描述 |
|---|---|---|
EMBEDDING_MODEL_NAME |
text-embedding-3-small |
OpenAI嵌入模型 |
DESCRIPTOR_MODEL_NAME |
gpt-4.1-mini |
生成工具描述的模型 |
VISION_MODEL_NAME |
gpt-4.1-mini |
图像描述模型 |
MAX_RESULT_TOKENS |
5000 |
大结果的块阈值 |
DESCRIBE_IMAGES |
true |
用视觉来描述图像 |
DIMENSIONS |
1024 |
嵌入尺寸 |
设置方法:
选项1:本地文件存储(最简单)
export OPENAI_API_KEY="sk-proj-..."
export QDRANT_DATA_PATH="/path/to/qdrant_data"
export TOOL_OFFLOADED_DATA_PATH="/path/to/tool_offloaded_data"
选项2:Docker Qdrant服务器
# Start Qdrant in Docker
docker run -p 6333:6333 -p 6334:6334 qdrant/qdrant
# Configure OmniMCP
export OPENAI_API_KEY="sk-proj-..."
export QDRANT_URL="http://localhost:6333"
export TOOL_OFFLOADED_DATA_PATH="/path/to/tool_offloaded_data"
选项3:Qdrant Cloud
export OPENAI_API_KEY="sk-proj-..."
export QDRANT_URL="https://your-cluster.qdrant.io"
export QDRANT_API_KEY="your-qdrant-api-key"
export TOOL_OFFLOADED_DATA_PATH="/path/to/tool_offloaded_data"
选项4:创建 .env 文件
# .env
OPENAI_API_KEY=sk-proj-...
QDRANT_DATA_PATH=/path/to/qdrant_data
# OR for remote: QDRANT_URL=http://localhost:6333
TOOL_OFFLOADED_DATA_PATH=/path/to/tool_offloaded_data
然后使用 --env-file 运行命令时标记:
uvx --env-file .env omnimcp index --config-path mcp-servers.json
注: 寻找环境变量(例如。, source .env)不能可靠地工作 uvx。始终使用 --env-file 或者直接导出变量。
注: 对于stdio传输,环境变量也必须包含在MCP客户端配置中(请参阅 stdio运输段 在......下面
快速开始
1.创建MCP服务器配置 (mcp-servers.json):
这是Claude Desktop MCP配置的增强模式,带有额外的OmniMCP特定字段。OmniMCP支持 两种运输方式 用于连接到MCP服务器:
服务器传输类型
stdio运输(本地子流程)
使用 command + args 生成本地MCP服务器作为子进程。这是Claude Desktop、Cursor等使用的标准MCP方法。
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/directory"],
"env": {},
"timeout": 30.0
}
}
}
HTTP传输(远程服务器)
使用 url 通过Streamable HTTP连接到远程MCP服务器。这消除了对 mcp-remote 或 mcp-proxy 桥接器——只需直接提供URL。
{
"mcpServers": {
"remote-api": {
"url": "https://mcp.example.com/api",
"headers": {"Authorization": "Bearer your-token"},
"timeout": 60.0
}
}
}
何时使用HTTP传输:
- 远程MCP服务器(云API、共享服务)
- 服务器已作为HTTP端点运行
- 避免为每台服务器生成子流程
- 无需直接连接
mcp-remote高架桥
混合配置示例
您可以在一个配置中混合使用这两种传输类型:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/directory"],
"env": {},
"timeout": 30.0,
"hints": ["file operations", "read write files"],
"blocked_tools": [],
"ignore": false,
"overwrite": false
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {"GITHUB_TOKEN": "..."},
"blocked_tools": ["delete_repository", "fork_repository"]
},
"elevenlabs": {
"command": "uvx",
"args": ["elevenlabs-mcp"],
"env": {"ELEVENLABS_API_KEY": "..."},
"hints": [
"When the user requests audio generation (speech or music), always execute in background mode",
"Proactively offer to play audio using the ElevenLabs tool when contextually relevant"
]
},
"exa-direct": {
"url": "https://mcp.exa.ai/mcp",
"headers": {"Authorization": "Bearer your-exa-api-key"},
"timeout": 60.0,
"hints": [
"Always execute web searches in background mode to avoid blocking the conversation",
"Multiple Exa tool calls can be fired in parallel to efficiently gather information from different sources"
]
},
"company-internal-api": {
"url": "http://internal-mcp.company.com:8080/mcp",
"headers": {"X-API-Key": "internal-key"},
"timeout": 120.0,
"hints": ["Internal company data access", "Use for employee and project queries"]
}
}
}
配置字段参考
特定于运输的字段(选择一个):
| 字段 | 类型 | 描述 |
|---|---|---|
command |
字符串 | stdio传输: 可执行文件(npx、uvx、docker、python等) |
args |
阵列 | stdio传输: 传递给可执行文件的命令行参数 |
env |
对象 | stdio传输: 此MCP服务器的环境变量 |
url |
字符串 | HTTP传输: 远程MCP服务器端点的URL |
headers |
对象 | HTTP传输: HTTP头(例如授权、API密钥) |
共享字段(适用于两种传输方式):
| 字段 | 类型 | 描述 |
|---|---|---|
timeout |
number | 等待服务器启动/连接的秒数(默认值:30.0) |
hints |
阵列 | 强大! 指导LLM如何使用此服务器。用于发现和执行指令。示例:“始终在后台模式下执行”,“可以并行发起多个调用”,“在上下文相关时主动提供” |
blocked_tools |
array | 将被索引但被阻止执行的工具名称 |
ignore |
boolean | 如果为true,则完全跳过对此服务器的索引(默认值:false) |
overwrite |
boolean | 如果为true,即使已经索引,也强制重新索引(默认值:false) |
注: 您必须指定 command (stdio)或 url (HTTP),但不是两者都有。根据存在的字段自动检测传输类型。
2.设置环境变量:
export OPENAI_API_KEY="sk-..."
export QDRANT_DATA_PATH="/path/to/qdrant_data"
export TOOL_OFFLOADED_DATA_PATH="/path/to/tool_offloaded_data"
3.为服务器建立索引 (食用前推荐):
uvx --env-file .env omnimcp index --config-path mcp-servers.json
4.运行服务器:
# Default: HTTP transport (recommended)
uvx --env-file .env omnimcp serve --config-path mcp-servers.json --transport http --host 0.0.0.0 --port 8000
# stdio transport (for local MCP clients - requires pre-indexing)
uvx --env-file .env omnimcp serve --config-path mcp-servers.json --transport stdio
或者,直接使用CLI选项:
# With local Qdrant storage
uvx omnimcp serve \
--config-path mcp-servers.json \
--openai-api-key "sk-..." \
--qdrant-data-path /path/to/qdrant_data \
--tool-offloaded-data-path /path/to/tool_offloaded_data
# With remote Qdrant (Docker or Cloud)
uvx omnimcp serve \
--config-path mcp-servers.json \
--openai-api-key "sk-..." \
--qdrant-url "http://localhost:6333" \
--qdrant-api-key "optional-api-key" \
--tool-offloaded-data-path /path/to/tool_offloaded_data
运输方式
OmniMCP支持两种传输协议,每种协议都针对不同的部署场景进行了优化:
HTTP传输(默认-推荐)
最适合大多数用例:远程访问、web集成或与 mcp-remote 或 mcp-proxy.
uvx omnimcp serve --config-path mcp-servers.json --transport http --host 0.0.0.0 --port 8000
使用案例:
- 远程访问 -在服务器上为OmniMCP提供服务,随时随地连接
- 多个客户端 -跨多个代理共享一个OmniMCP实例
- Web集成 -REST API访问MCP生态系统
- mcp远程/mcp代理 -通过MCP代理层公开OmniMCP
示例 mcp遥控器:
npm install mcp-remote
{
"mcpServers": {
"omnimcp-remote": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://your-server:port/mcp"]
}
}
}
HTTP模式优势:
- 索引在服务器启动时发生一次
- 多个客户端共享相同的索引数据
stdio运输
最适合通过标准输入/输出(Claude Desktop、Cline等)进行通信的本地MCP客户端。
⚠️ 重要提示:你必须跑步 uvx omnimcp index 在使用stdio模式之前,避免启动时间缓慢。
uvx omnimcp serve --config-path mcp-servers.json --transport stdio
推荐工作流程:
- 索引优先 -快跑
omnimcp index在添加到MCP客户端配置之前 - 然后安装 -将OmniMCP添加到客户的MCP配置中
- 开始服务 -客户端通过stdio自动启动OmniMCP
客户端配置示例 (claude_desktop_config.json):
{
"mcpServers": {
"omnimcp": {
"command": "uvx",
"args": ["omnimcp", "serve"],
"env": {
"CONFIG_PATH": "/path/mcp/config/file",
"TRANSPORT": "stdio|http",
"OPENAI_API_KEY": "sk-...",
"QDRANT_DATA_PATH": "/path/to/qdrant_data",
"TOOL_OFFLOADED_DATA_PATH": "/path/to/tool_offloaded_data"
// add other env keys
}
}
}
}
为什么要在挂载前进行索引? 对许多服务器进行索引可能需要时间。预索引确保您的MCP客户端启动OmniMCP时立即启动。
故障排除 uvx 问题
错误: spawn uvx ENOENT 或 command not found: uvx
这意味着 uv 未安装或不在您的PATH中。 详细的故障排除指南 • MCP官方文件.
快速修复:
-
安装uv (如果未安装):
# macOS/Linux brew install uv # or official installer curl -LsSf https://astral.sh/uv/install.sh | sh -
确保紫外线在路径中 (macOS/Linux):
# Check if installed which uvx # If not found, add to PATH (add to ~/.zshrc or ~/.bashrc) export PATH="$HOME/.local/bin:$PATH" # Or create symlink sudo ln -s ~/.local/bin/uvx /usr/local/bin/uvx -
使用绝对路径 在配置中(使用查找
which uvx):"command": "/Users/you/.local/bin/uvx" // macOS "command": "C:\\Users\\you\\.local\\bin\\uvx.exe" // Windows
替代方案:使用mcp-remote进行HTTP模式
如果 uvx 问题仍然存在,请通过HTTP运行OmniMCP并通过 mcp-remote:
# Terminal 1: Run OmniMCP HTTP server
uvx omnimcp serve --config-path mcp-servers.json --transport http --port 8000
// Claude Desktop config
{
"mcpServers": {
"omnimcp": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:8000/mcp"]
}
}
}
这绕过了stdio问题,并在跨平台上可靠地工作。
运作原理
OmniMCP公开了一个 semantic_router 作为通往整个MCP生态系统的门户的工具:
search_tools("read CSV files and analyze data")
→ Returns: filesystem.read_file, database.query (ranked by relevance)
get_tool_details("filesystem", "read_file")
→ Returns: Full JSON schema with parameters
manage_server("filesystem", "start")
→ Launches the server process
execute_tool("filesystem", "read_file", {"path": "/data/sales.csv"})
→ Returns: File content (chunked if large)
运营
| 操作 | 说明 |
|---|---|
search_tools |
跨所有索引工具的语义搜索 |
get_server_info |
查看服务器功能和限制 |
list_server_tools |
浏览特定服务器上的工具 |
get_tool_details |
执行前获取完整架构 |
manage_server |
启动或关闭服务器实例 |
list_running_servers |
显示活动服务器 |
execute_tool |
使用可选后台模式运行工具 |
poll_task_result |
检查后台任务状态 |
get_content |
通过引用检索卸载的内容 |
内容管理
自动处理大型工具结果:
- 文本 >5000个代币→ 分块,预览返回参考ID
- 图像 → 卸载,用GPT-4视觉描述,返回参考
- 音频 → 卸载,返回引用
使用检索完整内容 get_content(ref_id, chunk_index).
后台执行
对于长时间运行的工具:
# Queue for background execution
execute_tool("server", "slow_tool", args, in_background=True, priority=1)
# Returns: task_id
# Check status
poll_task_result(task_id)
# Returns: status, result when done
码头工人
OmniMCP可以在Docker容器中运行,并完全支持两者 npx (Node.js MCP服务器)和 uvx (Python MCP服务器)。
从Docker Hub拉取
docker pull milkymap/omnimcp:latest
本地构建(可选)
docker build -t omnimcp:latest -f Dockerfile .
跑
使用本地Qdrant存储:
docker run --rm -it \
-v /path/to/qdrant_data:/data/qdrant \
-v /path/to/tool_offloaded_data:/data/tool_offloaded_data \
-v /path/to/mcp-servers.json:/app/config/mcp-servers.json:ro \
--env-file .env.docker \
-p 8000:8000 \
milkymap/omnimcp:latest serve
使用远程Qdrant(云或Docker):
docker run --rm -it \
-v /path/to/tool_offloaded_data:/data/tool_offloaded_data \
-v /path/to/mcp-servers.json:/app/config/mcp-servers.json:ro \
--env-file .env.docker \
-p 8000:8000 \
milkymap/omnimcp:latest serve
环境文件 (.env.docker)-选择一个Qdrant模式:
OPENAI_API_KEY=sk-proj-...
CONFIG_PATH=/app/config/mcp-servers.json
TOOL_OFFLOADED_DATA_PATH=/data/tool_offloaded_data
TRANSPORT=http
HOST=0.0.0.0
PORT=8000
# Option 1: Local Qdrant storage
QDRANT_DATA_PATH=/data/qdrant
# Option 2: Remote Qdrant (comment out QDRANT_DATA_PATH above)
# QDRANT_URL=https://your-cluster.qdrant.io
# QDRANT_API_KEY=your-api-key
可用命令:
# Show help
docker run --rm milkymap/omnimcp:latest --help
# Index servers
docker run --rm \
-v /path/to/mcp-servers.json:/app/config/mcp-servers.json:ro \
--env-file .env.docker \
milkymap/omnimcp:latest index
# Serve (HTTP mode)
docker run --rm -d \
-v /path/to/mcp-servers.json:/app/config/mcp-servers.json:ro \
--env-file .env.docker \
-p 8000:8000 \
--name omnimcp \
milkymap/omnimcp:latest serve
发展
git clone https://github.com/milkymap/omnimcp.git
cd omnimcp
uv sync
uv run pytest
相关研究
OmniMCP建立在LLM代理可扩展工具选择的新兴研究之上:
ScaleMCP:动态和自动同步模型上下文协议工具
Lumer等人(2025年) 介绍 ScaleMCP,大规模解决MCP工具选择中的类似挑战。他们的方法强调:
- 动态刀具检索 -赋予代理在多回合交互中发现和添加工具的自主权
- 自动同步存储 -通过CRUD操作使用MCP服务器作为唯一的事实来源
- 工具文档加权平均值(TDWA) -有选择地强调关键工具文档组件的新型嵌入策略
他们在5000个财务指标服务器上的评估表明,工具检索和代理调用性能有了显著提高,验证了语义搜索在MCP生态系统中的重要性。
关键洞察:OmniMCP和ScaleMCP都认识到传统的单片工具库无法扩展。未来需要动态的、语义优先的工具发现方法。
Anthropic的高级工具使用
Anthropic的工具搜索功能 (2025)引入了三种与OmniMCP架构相一致的功能:
- 工具搜索工具 -在不占用上下文窗口的情况下发现数千种工具
- 程序化工具调用 -在代码执行环境中调用工具以减少上下文影响
- 工具使用示例 -学习JSON模式定义之外的正确使用模式
引自Anthropic: “在代理读取请求之前,工具结果和定义有时会消耗50000多个令牌。代理应按需发现和加载工具,只保留与当前任务相关的内容。”
这反映了OmniMCP的核心理念:预先暴露最小的接口(单个 semantic_router 工具),从语义上发现工具,逐步加载模式。
趋同进化
这些独立的努力都遵循类似的原则:
- 语义发现 过于详尽的列举
- 又称渐进负重 超过前期工具定义
- 代理人自主权 查询和重新查询工具库
- 上下文效率 作为一流的设计约束
OmniMCP通过语义路由、延迟服务器加载和内容卸载来实现这些原则,使大规模MCP生态系统在今天变得实用。
许可证
MIT许可证-请参阅 许可证 了解详情。
经过几个月的研究和开发
多个架构迭代•真实世界的代理部署•在不同的MCP生态系统中进行广泛的测试
OmniMCP源于解决传统方法失败的生产代理系统中的实际问题。从语义路由到后台执行再到内容卸载,每个功能都经过了战斗测试,以应对将MCP生态系统扩展到玩具示例之外的挑战。
我们希望OmniMCP在构建更强大、更高效的代理系统方面对社区有用。