## 🚀 Nexus
Nexusは、あらゆるMCPサーバー、API、およびLLMプロバイダーを接続し、統一されたエンドポイントを介してすべてをルーティングします。AIスタックを集約、管理、制御することができます。
## 🚀 クイックスタート
Nexusを使用するには、まずインストールが必要です。以下のセクションでは、さまざまなインストール方法と実行方法について説明します。
## ✨ 主な機能
- **MCPサーバー集約**:単一のエンドポイントを介して複数のMCPサーバー(STDIO、SSE、HTTP)を接続します。
- **LLMプロバイダールーティング**:OpenAI、Anthropic、GoogleなどのLLMプロバイダーに対する統一インターフェイスを提供します。
- **コンテキスト認識型ツール検索**:自然言語クエリを使用して、接続されたすべてのツールをインテリジェントにファジー検索します。
- **プロトコルサポート**:STDIO(サブプロセス)、SSE(Server-Sent Events)、およびストリーム可能なHTTP MCPサーバーをサポートします。
- **柔軟な構成**:環境変数置換をサポートするTOMLベースの構成を提供します。
- **セキュリティ**:組み込みのCORS、CSRF保護、OAuth2、およびTLSサポートを備えています。
- **レート制限**:メモリ内またはRedisバックエンドを使用した多レベルのレート制限を提供します。
- **Docker対応**:最小限の構成で使用できるコンテナイメージとして提供されます。
## 📦 インストール
### クイックインストール (Linux/Windows (WSL)/macOS)
```bash
curl -fsSL https://nexusrouter.com/install | bash
Docker
最新のイメージを取得します:
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を使用する場合
docker run -p 8000:8000 -v /path/to/config:/etc/nexus.toml ghcr.io/grafbase/nexus:latest
Docker Composeの例
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
📚 ドキュメント
構成
nexus.tomlファイルを作成して、Nexusを構成します:
[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.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構成
llm.enabled:LLM機能を有効にする (デフォルト: true)
llm.path:LLMエンドポイントのパス (デフォルト: /llm)
詳細なLLMプロバイダーの構成については、以下のLLMプロバイダー構成セクションを参照してください。
MCP構成
mcp.enabled:MCP機能を有効にする (デフォルト: true)
mcp.path:MCPエンドポイントのパス (デフォルト: /mcp)
mcp.enable_structured_content:MCP検索ツールの応答形式を制御する (デフォルト: true)
trueの場合:パフォーマンスと型安全性を向上させるために、最新のstructuredContentフィールドを使用します。
falseの場合:古いMCPクライアントとの互換性のために、Content::jsonオブジェクトを持つレガシーのcontentフィールドを使用します。
MCPサーバーの種類
-
STDIOサーバー:標準入出力を介して通信するローカルプロセスを起動します。
[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 = "inherit"
stderr = { file = "/var/log/mcp/server.log" }
注意:STDIOサーバーは、stdoutに有効なJSON-RPCメッセージを出力する必要があります。cmd配列には、少なくとも1つの要素(実行可能ファイル)が必要です。
-
SSEサーバー:Server-Sent Eventsエンドポイントに接続します。
[mcp.servers.my_sse_server]
protocol = "sse"
url = "http://example.com/sse"
message_url = "http://example.com/messages"
-
HTTPサーバー:ストリーム可能なHTTPエンドポイントに接続します。
[mcp.servers.my_http_server]
protocol = "streamable-http"
url = "https://api.example.com/mcp"
リモートのMCPサーバーの場合、プロトコルを省略すると、Nexusは最初にストリーム可能なHTTPを試し、次にSSEを試します。
認証
任意のサーバーにサービストークン認証を追加します:
[mcp.servers.my_server.auth]
token = "your-token-here"
token = "{{ env.MY_API_TOKEN }}"
サーバーにOAuth2認証を有効にし、下流のサーバーがすべて同じ認証サーバーを使用する場合、Nexusを構成して、リクエストのアクセストークンを下流のサーバーに転送することができます。
[mcp.servers.my_server.auth]
type = "forward"
OAuth2認証
Nexusエンドポイントを保護するために、OAuth2認証を構成します:
[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"]
OAuth2の構成オプション:
url:トークン検証用のJWKsエンドポイントのURL
poll_interval:JWKsを更新する頻度 (オプション、デフォルト: ポーリングなし)
expected_issuer:JWTトークンで期待されるissクレーム (オプション)
expected_audience:JWTトークンで期待されるaudクレーム (オプション)
protected_resource.resource:この保護されたリソースのURL
protected_resource.authorization_servers:認証サーバーのURLのリスト
OAuth2が有効になっている場合、/healthと/.well-known/oauth-protected-resourceを除くすべてのエンドポイントは、Authorization: Bearer <token>ヘッダーに有効なJWTトークンを必要とします。
レート制限
Nexusは、乱用を防止し、公平なリソース使用を確保するために、包括的なレート制限をサポートしています:
[server.rate_limits]
enabled = true
[server.rate_limits.storage]
type = "memory"
[server.rate_limits.global]
limit = 1000
interval = "60s"
[server.rate_limits.per_ip]
limit = 100
interval = "60s"
[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" }
レート制限の機能:
- 複数のレベル:グローバル、1IPあたり、サーバーごと、およびツールごとの制限
- ストレージバックエンド:メモリ内(単一インスタンス)またはRedis(分散型)
- 柔軟なインターバル:各制限の時間ウィンドウを構成できます
- ツール固有の上書き:高価な操作に対して異なる制限を設定できます
Redisバックエンドの構成:
[server.rate_limits.storage]
type = "redis"
url = "redis://localhost:6379"
key_prefix = "nexus:rate_limit:"
response_timeout = "1s"
connection_timeout = "5s"
[server.rate_limits.storage.pool]
max_size = 16
min_idle = 0
timeout_create = "5s"
timeout_wait = "5s"
timeout_recycle = "300s"
[server.rate_limits.storage.tls]
enabled = true
ca_cert_path = "/path/to/ca.crt"
client_cert_path = "/path/to/client.crt"
client_key_path = "/path/to/client.key"
注意:ツール固有のレート制限を構成する場合、存在しないツールを参照すると、Nexusは警告を表示します。
LLMトークンレート制限
Nexusは、LLMプロバイダーに対するトークンベースのレート制限を提供し、コストを管理し、乱用を防止するのに役立ちます。リクエストベースのレート制限とは異なり、トークンレート制限は、実際に消費されたトークンの推定値をカウントします。
前提条件
重要:LLMのレート制限には、クライアント識別を有効にする必要があります:
[server.client_identification]
enabled = true
client_id.jwt_claim = "sub"
client_id.http_header = "X-Client-ID"
group_id.jwt_claim = "groups"
group_id.http_header = "X-Group-ID"
[server.client_identification.validation]
group_values = ["free", "pro", "max"]
クライアント識別がない場合、レート制限を適用できず、リクエストは構成エラーで失敗します。
構成の階層
トークンレート制限は、最も具体的なものから最も一般的なものまで、4つのレベルで構成できます:
- ユーザー+グループごとのモデル:グループ内の各ユーザーに対する特定のモデル
- ユーザーごとのモデル:各ユーザーに対する特定のモデル
- ユーザー+グループごとのプロバイダー:グループ内の各ユーザーに対するプロバイダーのすべてのモデル
- ユーザーごとのプロバイダー:各ユーザーに対するプロバイダーのすべてのモデル
常に最も具体的な適用可能な制限が使用されます。
基本的な構成
[llm.providers.openai.rate_limits.per_user]
input_token_limit = 100000
interval = "1m"
[llm.providers.openai.models.gpt-4.rate_limits.per_user]
input_token_limit = 50000
interval = "30s"
グループベースのレート制限
ユーザーグループに対して異なる制限を構成します(クライアント識別にgroup_idとgroup_valuesが必要):
[llm.providers.openai.rate_limits.per_user.groups]
free = { input_token_limit = 10000, interval = "60s" }
pro = { input_token_limit = 100000, interval = "60s" }
enterprise = { input_token_limit = 1000000, interval = "60s" }
[llm.providers.openai.models.gpt-4.rate_limits.per_user.groups]
free = { input_token_limit = 5000, interval = "60s" }
pro = { input_token_limit = 50000, interval = "60s" }
制限はユーザーごとに適用されますが、ユーザーが特定のグループに属している場合、異なる制限を定義することができます。ユーザーがどのグループにも属していない場合、ユーザーごとの制限が適用されます。
完全な例
[server.client_identification]
enabled = true
client_id.jwt_claim = "sub"
group_id.jwt_claim = "subscription_tier"
[server.client_identification.validation]
group_values = ["free", "pro", "enterprise"]
[llm.providers.openai]
type = "openai"
api_key = "{{ env.OPENAI_API_KEY }}"
[llm.providers.openai.rate_limits.per_user]
input_token_limit = 100000
interval = "60s"
[llm.providers.openai.rate_limits.per_user.groups]
free = { input_token_limit = 10000, interval = "60s" }
pro = { input_token_limit = 100000, interval = "60s" }
[llm.providers.openai.models.gpt-4]
[llm.providers.openai.models.gpt-4.rate_limits.per_user]
input_token_limit = 50000
interval = "60s"
[llm.providers.openai.models.gpt-4.rate_limits.per_user.groups]
free = { input_token_limit = 5000, interval = "60s" }
pro = { input_token_limit = 50000, interval = "60s" }
[llm.providers.openai.models.gpt-3-5-turbo]
トークンカウントの仕組み
- 入力トークンのみ:レート制限は、リクエストのメッセージとシステムプロンプトからカウントされる入力トークンのみに基づいています。
- 出力バッファリングなし:出力トークンと
max_tokensパラメータは、レート制限の計算には考慮されません。
- 事前チェック:入力トークンは、処理前にレート制限と照合されます。
- トークンの累積:時間経過に伴う使用状況を追跡するために、スライディングウィンドウアルゴリズムを使用します。
注意:レート制限は、クライアントが送信する内容のみに基づいて予測可能に設計されており、可変の出力サイズには基づいていません。
レート制限の応答
レート制限に達した場合、サーバーは429ステータスコードを返します。下流のLLMプロバイダーの動作との一貫性を保つために、Retry-Afterヘッダーは送信されません。
エラー応答
レート制限を超えた場合:
{
"error": {
"message": "Rate limit exceeded: Token rate limit exceeded. Please try again later.",
"type": "rate_limit_error",
"code": 429
}
}
重要な注意事項
- ユーザーごとの制限:すべての制限は、個々のユーザー/クライアントIDごとに設定されています。
- 共有プールなし:現在、共有/グローバルなトークンプールはありません。
- ストリーミングサポート:トークンカウントは、通常の応答とストリーミング応答の両方で機能します。
- プロバイダー非依存:すべてのLLMプロバイダーで一貫して機能します。
- 検証:構成は起動時に検証され、無効なグループ名はエラーを引き起こします。
TLS構成
下流の接続にTLSを構成します:
[mcp.servers.my_server.tls]
verify_certs = true
accept_invalid_hostnames = false
root_ca_cert_path = "/path/to/ca.pem"
client_cert_path = "/path/to/client.pem"
client_key_path = "/path/to/client.key"
LLMプロバイダーの構成
Nexusは、複数のLLMプロバイダーに対する統一インターフェイスを提供し、一貫したAPIを使用してさまざまなサービスを介してチャット補完をルーティングすることができます。
LLMルーティングの有効化
[llm]
enabled = true
path = "/llm"
サポートされるプロバイダー
Nexusは現在、4つの主要なLLMプロバイダーをサポートしています:
- OpenAI (OpenAI互換APIを含む)
- Anthropic (Claudeモデル)
- Google (Geminiモデル)
- AWS Bedrock (AWSを介した複数のモデルファミリー)
プロバイダーの構成
nexus.tomlに1つ以上のLLMプロバイダーを構成します:
OpenAIプロバイダー
[llm.providers.openai]
type = "openai"
api_key = "{{ env.OPENAI_API_KEY }}"
base_url = "https://api.openai.com/v1"
[llm.providers.openai.models.gpt-4]
[llm.providers.openai.models.gpt-3-5-turbo]
Anthropicプロバイダー
[llm.providers.anthropic]
type = "anthropic"
api_key = "{{ env.ANTHROPIC_API_KEY }}"
base_url = "https://api.anthropic.com/v1"
[llm.providers.anthropic.models.claude-3-opus-20240229]
[llm.providers.anthropic.models.claude-3-5-sonnet-20241022]
Googleプロバイダー
[llm.providers.google]
type = "google"
api_key = "{{,