VectorMCP について
VectorMCP は、MCP サーバーを構築するための Ruby フレームワークで、Ruby や Rails の開発者を対象としています。Streamable HTTP による通信に加え、ツール、リソース、プロンプト、セキュリティ機能、ミドルウェアを備えています。
主な機能
- 01ツール、リソース、プロンプトの登録
- 02セッション管理付き Streamable HTTP
- 03Rack と Rails へのマウント
- 04任意で有効化できる認証・認可
- 05ログやリクエスト処理用ミドルウェア
- 06トークンによるフィールド匿名化
活用シーン
- 01Ruby アプリの機能を MCP クライアントに公開
- 02Rack または Rails アプリに MCP サーバーをマウント
- 03ツールの結果に含まれる機密フィールドを保護
- 04公開 MCP エンドポイントに認証を追加
MCP 対応
MCP サーバー仕様を実装し、Streamable HTTP 経由でツール、リソース、プロンプト、ルート、サンプリングを MCP クライアントに公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
VectorMCP
VectorMCP は、Model Context Protocol(MCP)のサーバー側仕様を Ruby で実装したものです。MCP のストリーミング可能な HTTP トランスポートを介して、ツール、リソース、プロンプト、ルート、サンプリング、ミドルウェア、セキュリティを公開するためのフレームワークを提供します。
主な機能
- ストリーミング可能な HTTP を組み込みトランスポートとして採用し、セッション管理、再開機能、MCP 2025-11-25 への準拠を提供します
VectorMCP::Toolによるクラスベースのツールに加え、従来のブロックベースのregister_toolAPI にも対応していますserver.rack_appを介して Rack や Rails にマウントできます- オプトイン方式の認証と認可、構造化ログ、ミドルウェアフックを利用できます
- リクエスト単位の ID 管理:各リクエストは独自の呼び出しを通じてディスパッチされるため、同じセッション上の同時リクエストが互いのヘッダーや認証情報を参照することはありません
- 画像に対応したツール/リソース/プロンプト、ルート、サーバー起点のサンプリングに対応しています
- トークンベースのフィールド匿名化ミドルウェアにより、機密情報が LLM のコンテキストに含まれないようにします
要件
- Ruby 3.2+
インストール
gem install vector_mcp
gem "vector_mcp"
クイックスタート
require "vector_mcp"
class Greet < VectorMCP::Tool
description "Say hello to someone"
param :name, type: :string, desc: "Name to greet", required: true
def call(args, _session)
"Hello, #{args["name"]}!"
end
end
server = VectorMCP::Server.new(name: "MyApp", version: "1.0.0")
server.register(Greet)
server.run(port: 8080)
クラスベース DSL は任意です。既存のブロックベース API も引き続き利用できます。
server.register_tool(
name: "echo",
description: "Echo back the supplied text",
input_schema: {
type: "object",
properties: { text: { type: "string" } },
required: ["text"]
}
) { |args| args["text"] }
Rack と Rails
VectorMCP はスタンドアロンの HTTP サーバーとして実行することも、既存の Rack アプリにマウントすることもできます。
require "vector_mcp"
server = VectorMCP::Server.new(name: "MyApp", version: "1.0.0")
server.register(Greet)
MCP_APP = server.rack_app
Rails では、config/routes.rb にマウントします。
mount MCP_APP => "/mcp"
ActiveRecord を使用するツールでは、VectorMCP::Rails::Tool をオプトインで利用できます。
require "vector_mcp/rails/tool"
class FindUser < VectorMCP::Rails::Tool
description "Find a user by id"
param :id, type: :integer, required: true
def call(args, _session)
user = find!(User, args[:id])
{ id: user.id, email: user.email }
end
end
設定手順の詳細は、docs/rails-setup-guide.md を参照してください。
ツール、リソース、プロンプト
呼び出し可能なツールを公開します。
server.register_tool(
name: "calculate",
description: "Performs basic math",
input_schema: {
type: "object",
properties: {
operation: { type: "string", enum: ["add", "subtract", "multiply"] },
a: { type: "number" },
b: { type: "number" }
},
required: ["operation", "a", "b"]
}
) do |args|
case args["operation"]
when "add" then args["a"] + args["b"]
when "subtract" then args["a"] - args["b"]
when "multiply" then args["a"] * args["b"]
end
end
読み取り可能なリソースを公開します。
server.register_resource(
uri: "file://config.json",
name: "App Configuration",
description: "Current application settings"
) { File.read("config.json") }
プロンプトテンプレートを定義します。
server.register_prompt(
name: "code_review",
description: "Reviews code for best practices",
arguments: [
{ name: "language", description: "Programming language", required: true },
{ name: "code", description: "Code to review", required: true }
]
) do |args|
{
messages: [{
role: "user",
content: {
type: "text",
text: "Review this #{args["language"]} code:\n\n#{args["code"]}"
}
}]
}
end
VectorMCP::Tool は type: :date と type: :datetime にも対応しています。これらは JSON Schema では文字列として検証され、#call の実行前に Date と Time に変換されます。
第 2 引数を受け取るハンドラーには、リクエストごとの呼び出しが渡されます。この呼び出しには、セッション ID、リクエストのヘッダー/パラメーター、認証済みユーザーがまとめて公開されています。
server.register_tool(
name: "whoami",
description: "Reports the caller's identity",
input_schema: { type: "object", properties: {} }
) do |_args, invocation|
{
session: invocation.id,
user: invocation.user,
api_key_header: invocation.request_header("X-API-Key")
}
end
リソースハンドラーも、第 2 引数として同じ呼び出しを受け取ります(おなじみの user/authenticated?/can? クエリにも応答するため、以前のセキュリティコンテキスト引数を使って書かれたハンドラーも、変更せずに引き続き動作します)。
セキュリティとミドルウェア
VectorMCPではセキュリティはオプトインですが、基本機能は組み込まれています。
server.enable_authentication!(
strategy: :api_key,
keys: [ENV.fetch("MCP_API_KEY")],
rate_limit: { max_attempts: 10, window_seconds: 60 }
)
server.enable_authorization! do
authorize_tools do |user, _action, tool|
user[:role] == "admin" || !tool.name.start_with?("admin_")
end
end
カスタム認証にも対応しています。
server.enable_authentication!(strategy: :custom) do |request|
api_key = request[:headers]["X-API-Key"]
user = User.find_by(api_key: api_key)
user ? { user_id: user.id, role: user.role } : false
end
認証を有効にすると、VectorMCPは組み込みおよびカスタムのリクエスト/通知ハンドラーに認証を一元的に適用します。公開されるのは initialize、ping、initialized 通知のみです。HTTP GETストリームとDELETEによるセッションリクエストにも認証情報が必要です。
公開環境では、rate_limit: true を設定して認証失敗のレート制限を有効にしてください(デフォルトでは60秒間に10回)。または、max_attempts、window_seconds、max_entries を指定できます。繰り返し発生する認証失敗はクライアントIPと一方向の認証情報フィンガープリントを使って追跡され、ブロックされたリクエストにはHTTP 429、JSON-RPC -32029、および Retry-After が返されます。レート制限はプロセス内で動作するため、マルチプロセス環境や分散環境では、プロキシまたはゲートウェイでも共有の制限を適用してください。256ビット以上のエントロピーを持つAPIキーを生成し、たとえば ruby -rsecurerandom -e 'puts SecureRandom.hex(32)' を使用してください。キーはシークレットマネージャーまたは環境変数から読み込んでください。
OAuth 2.1に対応するMCPクライアント(Claude Desktopなど)では、resource_metadata_url: を渡してRFC 9728のディスカバリーを有効にできます。認証されていないリクエストが /mcp に送信されると、設定されたメタデータドキュメントを指す WWW-Authenticate ヘッダーとともに 401 が返され、以降のOAuthフローはクライアントが自動的に処理します。機能のリファレンスはdocs/oauth_resource_server.md、RailsとDoorkeeperを使った詳しい手順はdocs/rails_oauth_integration.mdをご覧ください。
ミドルウェアでは、before_auth、after_auth、on_auth_error、before_request、after_response、on_transport_error など、ツール、リソース、プロンプト、サンプリング、認証、トランスポートの各イベントにフックできます。
セキュリティガイドの全文はsecurity/README.mdをご覧ください。
フィールドの匿名化
安定した不透明なトークンに置き換えることで、機密性の高い文字列値がLLMのコンテキストに含まれないようにします。送信時のツール結果では値をトークン化し、受信時のツール引数では元の値に戻すため、LLMにはトークンだけが表示され、ハンドラーには元のデータが渡されます。
anonymizer = VectorMCP::Middleware::Anonymizer.new(
store: VectorMCP::TokenStore.new,
field_rules: [
{ pattern: /email/i, prefix: "EMAIL" },
{ pattern: /\bssn\b/i, prefix: "SSN" }
]
)
anonymizer.install_on(server)
トランスポートに関する注意事項
- VectorMCPには、組み込みトランスポートとしてストリーミング可能なHTTPが付属しています
POST /mcpは単一のJSON-RPCリクエスト、通知、またはレスポンスを受け付けます。バッチ配列は拒否されますGET /mcpは、サーバーから開始されるメッセージ用のSSEストリームを開きますDELETE /mcpはセッションを終了します- サーバーはMCPプロトコル
2025-11-25を通知し、互換性のため2025-03-26と2024-11-05のヘッダーを受け付けます - デフォルトで許可されるオリジンは、localhostとループバックアドレスに制限されています
- POST本文の上限はデフォルトで16 MiBです。必要に応じて
runまたはrack_appにmax_body_bytes:を設定してください - Rackアプリをマウントする場合は、Rackでバッファリングされる前にリクエストを拒否できるよう、前段のWebサーバーまたはリバースプロキシにも同じ上限を設定してください
curlでセッションを初期化します。
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
その他の機能
register_rootとregister_root_from_pathによるルート- 画像リソースと画像対応のツール/プロンプト
- コンポーネントロガーによる構造化ログ
- ストリーミング/ツール呼び出しに対応した、サーバーから開始するサンプリング
- ミドルウェアを活用したリクエストの整形と可観測性
ドキュメント
- CHANGELOG.md
- examples/
- docs/rails-setup-guide.md
- docs/rails_oauth_integration.md
- docs/oauth_resource_server.md
- docs/streamable-http-spec-compliance.md
- security/README.md
- MCP Specification
コントリビューション
バグ報告やプルリクエストはGitHubで歓迎しています。
ライセンス
MIT Licenseのもと、オープンソースとして利用できます。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。