Nexus 是一款强大的工具,它可以连接所有的 MCP 服务器、API 和大语言模型(LLM)提供商,通过统一的端点进行路由。它能够聚合、管理和控制你的 AI 栈,为开发者和企业提供便捷的 AI 服务管理方案。
curl -fsSL https://nexusrouter.com/install | bash
拉取最新镜像:
docker pull ghcr.io/grafbase/nexus:latest
或者使用稳定版本:
docker pull ghcr.io/grafbase/nexus:stable
或者使用特定版本:
docker pull ghcr.io/grafbase/nexus:X.Y.Z
git clone https://github.com/grafbase/nexus
cd nexus
cargo build --release
nexus
docker run -p 8000:8000 -v /path/to/config:/etc/nexus.toml ghcr.io/grafbase/nexus:latest
services:
nexus:
image: ghcr.io/grafbase/nexus:latest
ports:
- "8000:8000"
volumes:
- ./nexus.toml:/etc/nexus.toml
environment:
- GITHUB_TOKEN=${GITHUB_TOKEN}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
安装步骤如上述快速开始部分所述,可根据不同的操作系统和需求选择合适的安装方式。
curl http://localhost:8000/llm/models
curl -X POST http://localhost:8000/llm/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "openai_primary/gpt-4-turbo",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello, how are you?"}
],
"temperature": 0.7,
"max_tokens": 150
}'
curl -X POST http://localhost:8000/llm/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-3-5-sonnet-20241022",
"messages": [
{"role": "user", "content": "Write a short poem"}
],
"stream": true,
"max_tokens": 100
}'
创建 nexus.toml
文件来配置 Nexus:
# LLM 提供商配置
[llm.providers.openai]
type = "openai"
api_key = "{{ env.OPENAI_API_KEY }}"
forward_token = true
# 模型配置(每个提供商至少需要一个模型)
[llm.providers.openai.models.gpt-4]
[llm.providers.openai.models.gpt-3-5-turbo]
[llm.providers.anthropic]
type = "anthropic"
api_key = "{{ env.ANTHROPIC_API_KEY }}"
[llm.providers.anthropic.models.claude-3-5-sonnet-20241022]
# MCP 服务器配置
[mcp.servers.github]
url = "https://api.githubcopilot.com/mcp/"
auth.token = "{{ env.GITHUB_TOKEN }}"
[mcp.servers.filesystem]
cmd = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/YOUR_USERNAME/Desktop"]
[mcp.servers.python_server]
cmd = ["python", "-m", "mcp_server"]
env = { PYTHONPATH = "/opt/mcp" }
cwd = "/workspace"
server.listen_address
:Nexus 监听的地址和端口(默认:127.0.0.1:8000
)server.health.enabled
:启用健康检查端点(默认:true
)server.health.path
:健康检查端点路径(默认:/health
)llm.enabled
:启用 LLM 功能(默认:true
)llm.path
:LLM 端点路径(默认:/llm
)mcp.enabled
:启用 MCP 功能(默认:true
)mcp.path
:MCP 端点路径(默认:/mcp
)mcp.enable_structured_content
:控制 MCP 搜索工具响应格式(默认:true
)
true
时:使用现代 structuredContent
字段以获得更好的性能和类型安全性false
时:使用旧的 content
字段和 Content::json
对象以兼容旧的 MCP 客户端[mcp.servers.my_tool]
cmd = ["path/to/executable", "--arg1", "--arg2"]
# 可选:设置环境变量
env = { DEBUG = "1", API_KEY = "{{ env.MY_API_KEY }}" }
# 可选:设置工作目录
cwd = "/path/to/working/directory"
# 可选:配置 stderr 处理(默认:"null")
stderr = "inherit" # 在控制台显示
# 或者
stderr = { file = "/var/log/mcp/server.log" } # 记录到文件
[mcp.servers.my_sse_server]
protocol = "sse"
url = "http://example.com/sse"
message_url = "http://example.com/messages" # 可选
[mcp.servers.my_http_server]
protocol = "streamable-http"
url = "https://api.example.com/mcp"
为任何服务器添加服务令牌认证:
[mcp.servers.my_server.auth]
token = "your-token-here"
# 或者使用环境变量
token = "{{ env.MY_API_TOKEN }}"
配置 OAuth2 认证以保护你的 Nexus 端点:
[server.oauth]
url = "https://your-oauth-provider.com/.well-known/jwks.json"
poll_interval = "5m"
expected_issuer = "https://your-oauth-provider.com"
expected_audience = "your-service-audience"
[server.oauth.protected_resource]
resource = "https://your-nexus-instance.com"
authorization_servers = ["https://your-oauth-provider.com"]
Nexus 支持全面的速率限制,以防止滥用并确保公平使用资源:
# 全局速率限制配置
[server.rate_limits]
enabled = true
# 存储后端配置
[server.rate_limits.storage]
type = "memory" # 或者 "redis" 用于分布式速率限制
# 对于 Redis 后端:
# url = "redis://localhost:6379"
# key_prefix = "nexus:rate_limit:"
# 全局速率限制(适用于所有请求)
[server.rate_limits.global]
limit = 1000
interval = "60s"
# 每个 IP 的速率限制
[server.rate_limits.per_ip]
limit = 100
interval = "60s"
# 每个 MCP 服务器的速率限制
[mcp.servers.my_server.rate_limits]
limit = 50
interval = "60s"
# 特定工具的速率限制(覆盖服务器默认值)
[mcp.servers.my_server.rate_limits.tools]
expensive_tool = { limit = 10, interval = "60s" }
cheap_tool = { limit = 100, interval = "60s" }
Nexus 为 LLM 提供商提供基于令牌的速率限制,以帮助控制成本并防止滥用。
[server.client_identification]
enabled = true
# 选择识别方法(至少需要一种)
client_id.jwt_claim = "sub" # 从 JWT 'sub' 声明中提取 ID
# 或者
client_id.http_header = "X-Client-ID" # 从 HTTP 头中提取 ID
# 可选:限制每个用户的组(最多允许一个)
group_id.jwt_claim = "groups" # 包含用户组的 JWT 声明
# 或者
group_id.http_header = "X-Group-ID" # 从 HTTP 头中提取 ID
# 你必须提供允许的组列表
[server.client_identification.validation]
group_values = ["free", "pro", "max"]
令牌速率限制可以在四个级别进行配置,从最具体到最不具体:
# 提供商级别的默认速率限制(适用于所有模型)
[llm.providers.openai.rate_limits.per_user]
input_token_limit = 100000 # 100K 输入令牌
interval = "1m" # 每分钟
# 特定模型的速率限制(覆盖提供商默认值)
[llm.providers.openai.models.gpt-4.rate_limits.per_user]
input_token_limit = 50000 # 对于昂贵的模型更严格
interval = "30s"
[llm]
enabled = true # 启用 LLM 功能(默认:true)
path = "/llm" # LLM 端点路径(默认:"/llm")
Nexus 目前支持四个主要的 LLM 提供商:
[llm.providers.openai]
type = "openai"
api_key = "{{ env.OPENAI_API_KEY }}"
# 可选:使用自定义基本 URL(适用于 Azure OpenAI、代理或兼容 API)
base_url = "https://api.openai.com/v1" # 默认
# 模型配置(必需 - 至少必须配置一个模型)
[llm.providers.openai.models.gpt-4]
# 可选:为用户重命名模型
# rename = "smart-model" # 用户将看到 "openai/smart-model"
[llm.providers.openai.models.gpt-3-5-turbo]
# 未重命名的模型使用其原始 ID
[llm.providers.anthropic]
type = "anthropic"
api_key = "{{ env.ANTHROPIC_API_KEY }}"
# 可选:使用自定义基本 URL
base_url = "https://api.anthropic.com/v1" # 默认
# 模型配置(必需 - 至少必须配置一个模型)
[llm.providers.anthropic.models.claude-3-opus-20240229]
[llm.providers.anthropic.models.claude-3-5-sonnet-20241022]
[llm.providers.google]
type = "google"
api_key = "{{ env.GOOGLE_API_KEY }}"
# 可选:使用自定义基本 URL
base_url = "https://generativelanguage.googleapis.com/v1beta" # 默认
# 模型配置(必需 - 至少必须配置一个模型)
# 注意:TOML 中包含点的模型 ID 必须加引号
[llm.providers.google.models."gemini-1.5-flash"]
[llm.providers.google.models.gemini-pro]
[llm.providers.bedrock]
type = "bedrock"
# 可选:使用的 AWS 配置文件(默认为环境设置)
profile = "{{ env.AWS_PROFILE }}"
# 可选:AWS 区域(默认为环境或 us-east-1)
region = "us-west-2"
# 模型配置(必需 - 至少必须配置一个模型)
# Bedrock 使用包含点的模型 ID,因此必须加引号
[llm.providers.bedrock.models."anthropic.claude-3-5-sonnet-20241022-v2:0"]
[llm.providers.bedrock.models."anthropic.claude-3-opus-20240229-v1:0"]
[llm.providers.bedrock.models."amazon.nova-micro-v1:0"]
[llm.providers.bedrock.models."meta.llama3-8b-instruct-v1:0"]
[llm.providers.bedrock.models."ai21.jamba-1.5-mini-v1:0"]
# 重命名模型以简化访问
[llm.providers.bedrock.models.claude-haiku]
rename = "anthropic.claude-3-5-haiku-20241022-v1:0" # 用户将以 "bedrock/claude-haiku" 访问
[llm.providers.bedrock.models.jamba-mini]
rename = "ai21.jamba-1.5-mini-v1:0" # 用户将以 "bedrock/jamba-mini" 访问
[llm.providers.openai]
type = "openai"
api_key = "{{ env.OPENAI_API_KEY }}"
# 你要暴露的每个模型都必须明确配置
[llm.providers.openai.models.gpt-4]
[llm.providers.openai.models.gpt-3-5-turbo]
[llm.providers.openai.models.gpt-4]
rename = "smart-model" # 用户将以 "openai/smart-model" 访问
[llm.providers.openai.models.gpt-3-5-turbo]
rename = "fast-model" # 用户将以 "openai/fast-model" 访问
# 主要 OpenAI 账户
[llm.providers.openai_primary]
type = "openai"
api_key = "{{ env.OPENAI_PRIMARY_KEY }}"
[llm.providers.openai_primary.models.gpt-4]
[llm.providers.openai_primary.models.gpt-3-5-turbo]
# 次要 OpenAI 账户或 Azure OpenAI
[llm.providers.openai_secondary]
type = "openai"
api_key = "{{ env.OPENAI_SECONDARY_KEY }}"
base_url = "https://my-azure-instance.openai.azure.com/v1"
[llm.providers.openai_secondary.models.gpt-4]
rename = "azure-gpt-4" # 与主要账户区分
# Anthropic
[llm.providers.claude]
type = "anthropic"
api_key = "{{ env.ANTHROPIC_API_KEY }}"
[llm.providers.claude.models.claude-3-opus-20240229]
# Google Gemini
[llm.providers.gemini]
type = "google"
api_key = "{{ env.GOOGLE_API_KEY }}"
[llm.providers.gemini.models."gemini-1.5-flash"]
[llm.providers.openai]
type = "openai"
api_key = "{{ env.OPENAI_API_KEY }}" # 备用密钥(令牌转发时可选)
forward_token = true # 为该提供商启用令牌转发
[llm.providers.openai.models.gpt-4]
[llm.providers.openai.models.gpt-3-5-turbo]
[llm.providers.anthropic]
type = "anthropic"
# 启用令牌转发时不需要 api_key
forward_token = true
[llm.providers.anthropic.models.claude-3-5-sonnet-20241022]
[llm.providers.google]
type = "google"
api_key = "{{ env.GOOGLE_API_KEY }}"
forward_token = false # 显式禁用(默认)
[llm.providers.google.models."gemini-1.5-flash"]
# 使用你自己的 OpenAI 密钥
curl -X POST http://localhost:8000/llm/v1/chat/completions \
-H "Content-Type: application/json" \
-H "X-Provider-API-Key: sk-your-openai-key" \
-d '{
"model": "openai/gpt-4",
"messages": [{"role": "user", "content": "Hello"}]
}'
# 使用你自己的 Anthropic 密钥
curl -X POST http://localhost:8000/llm/v1/chat/completions \
-H "Content-Type: application/json" \
-H "X-Provider-API-Key: sk-ant-your-anthropic-key" \
-d '{
"model": "anthropic/claude-3-opus-20240229",
"messages": [{"role": "user", "content": "Hello"}]
}'
curl http://localhost:8000/llm/models
curl -X POST http://localhost:8000/llm/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "openai_primary/gpt-4-turbo",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello, how are you?"}
],
"temperature": 0.7,
"max_tokens": 150
}'
curl -X POST http://localhost:8000/llm/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-3-5-sonnet-20241022",
"messages": [
{"role": "user", "content": "Write a short poem"}
],
"stream": true,
"max_tokens": 100
}'
system
字段中max_tokens
参数(如果未指定,默认为 4096)systemInstruction
字段中from openai import OpenAI
# 指向你的 Nexus 实例
client = OpenAI(
base_url="http://localhost:8000/llm",
api_key="your-service-token" # 如果启用了 OAuth2,则使用 JWT 令牌,否则使用任何字符串
)
# 使用任何配置的提供商/模型
response = client.chat.completions.create(
model="anthropic/claude-3-5-sonnet-20241022",
messages=[
{"role": "user", "content": "Hello!"}
]
)
# 流式传输无缝工作
stream = client.chat.completions.create(
model="openai/gpt-4-turbo",
messages=[
{"role": "user", "content": "Write a poem"}
],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
import OpenAI from 'openai';
// 配置为使用 Nexus
const openai = new OpenAI({
baseURL: 'http://localhost:8000/llm',
apiKey: 'your-service-token', // 如果启用了 OAuth2,则使用 JWT 令牌,否则使用任何字符串
});
// 通过 Nexus 使用任何提供商
const response = await openai.chat.completions.create({
model: 'google/gemini-1.5-pro',
messages: [
{ role: 'user', content: 'Explain quantum computing' }
],
});
// 与任何提供商进行流式传输
const stream = await openai.chat.completions.create({
model: 'anthropic/claude-3-opus-20240229',
messages: [
{ role: 'user', content: 'Write a story' }
],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || '');
}
from langchain_openai import ChatOpenAI
# 使用 Nexus 作为 LLM 提供商
llm = ChatOpenAI(
base_url="http://localhost:8000/llm",
api_key="your-service-token", # 如果启用了 OAuth2,则使用 JWT 令牌
model="openai/gpt-4-turbo"
)
# 适用于任何配置的提供商
claude = ChatOpenAI(
base_url="http://localhost:8000/llm",
api_key="your-service-token", # 如果启用了 OAuth2,则使用 JWT 令牌
model="anthropic/claude-3-5-sonnet-20241022"
)
# 常规完成(如果启用了 OAuth2 认证)
curl -s http://localhost:8000/llm/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-jwt-token" \
-d '{
"model": "openai/gpt-4",
"messages": [{"role": "user", "content": "Hello"}]
}' | jq -r '.choices[0].message.content'
# 使用 SSE 解析进行流式传输
curl -s http://localhost:8000/llm/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-jwt-token" \
-d '{
"model": "anthropic/claude-3-5-sonnet-20241022",
"messages": [{"role": "user", "content": "Write a haiku"}],
"stream": true
}' | grep "^data: " | sed 's/^data: //' | jq -r 'select(.choices != null) | .choices[0].delta.content // empty'
Nexus 为所有提供商提供一致的错误响应:
将以下配置添加到你的 Cursor 设置中:
{
"nexus": {
"transport": {
"type": "http",
"url": "http://localhost:8000/mcp"
}
}
}
将以下配置添加到你的 Claude Code 配置中:
claude mcp add --transport http nexus http://localhost:8000/mcp
.mcp.json
文件中:{
"mcpServers": {
"nexus": {
"type": "http",
"url": "http://localhost:8000/mcp"
}
}
}
claude mcp list
Nexus 为 AI 助手提供两个主要工具:
search
:一种上下文感知的工具搜索,使用模糊匹配在所有连接的 MCP 服务器中查找相关工具execute
:使用提供的参数执行特定工具Nexus 作为多个 LLM 提供商的统一网关:
STDIO 服务器作为子进程启动,并通过标准输入/输出上的 JSON-RPC 进行通信:
[mcp.servers.python_tools]
cmd = ["python", "-m", "my_mcp_server"]
env = { PYTHONPATH = "/opt/mcp", PYTHONUNBUFFERED = "1" }
stderr = "inherit" # 在开发期间查看 Python 输出
[mcp.servers.node_tools]
cmd = ["node", "mcp-server.js"]
cwd = "/path/to/project"
env = { NODE_ENV = "production" }
[mcp.servers.filesystem]
cmd = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/home/user"]
stderr = "inherit"
以查看错误消息cwd
路径,请确保其存在当使用 OAuth2 认证时:
expected_issuer
和 expected_audience
以验证 JWT 声明。/.well-known/oauth-protected-resource
端点提供 OAuth2 元数据,并且是公开可访问的。/health
端点绕过 OAuth2 认证,用于监控系统。Nexus 采用 Mozilla Public License 2.0 (MPL-2.0) 许可。有关详细信息,请参阅 LICENSE 文件。
有关如何为 Nexus 做出贡献的指南,请参阅 CONTRIBUTING.md。