博客 / 詳情

返回

使用 Ruby 和 Gemini CLI 進行本地 MCP 開發

這年頭,會用AI不算什麼,要學會構建自己的MCP,才叫厲害。

Python 長期以來主導着 AI 和機器學習領域的開發。然而,模型上下文協議(MCP)的一大優勢在於其實現細節與開發語言無關。並非所有項目都基於 Python,MCP 可以讓開發者使用自己熟悉的語言來連接最新的 AI 能力。

本文的目標是構建一個最小可用的 Ruby MCP Stdio 服務器,並在本地通過 Gemini CLI 進行交互。

image.png

為什麼選擇 Ruby?

Ruby 是一種動態的、通用的編程語言,以注重簡潔和開發效率著稱。它是一種開源的面嚮對象語言,旨在提供優雅的語法,讀起來自然,寫起來容易。通過 MCP,Ruby 代碼可以無縫對接大模型,充當連接本地數據與 AI 的橋樑。

Ruby 版本管理

Ruby 的廣泛部署,會出現一些坑。在不同平台上管理語言版本以及維護受支持的版本較為困難。通常,開發者會使用 RVM 或 rbenv 這樣的版本管理工具。

然而,這些工具的安裝過程往往涉及 GPG 密鑰驗證、編譯源代碼等複雜步驟,對於初學者或希望快速上手的開發者來説,這往往是第一道門檻。

使用 ServBay 管理 Ruby 環境

為了跳過繁瑣的編譯和配置步驟,我們推薦使用 ServBay。ServBay 是一個集成的開發環境管理工具,它內置了預編譯好的、維護良好的 Ruby 環境。

使用 ServBay,無需處理複雜的安裝腳本。只需下載安裝 ServBay (https://www.servbay.com),在「軟件包」中啓用 Ruby 模塊即可。

image.png

在終端中驗證 Ruby 環境是否就緒:

# 驗證 Ruby 版本
ruby -v

image.png

這樣,一個 Ruby 環境就準備好了。

Gemini CLI

Gemini CLI 是 Google 提供的命令行工具,用於與源文件交互並提供實時輔助。在 MCP 開發中,它扮演客户端的角色。

Node 版本管理

Gemini CLI 依賴於 Node.js 環境。這裏我們還是使用ServBay來管理Node.js版本。

ServBay 同樣內置了標準的 Node.js 環境,這使得安裝基於 Node 的工具變得非常直接。我們無需額外安裝 NVM,直接使用 ServBay 提供的 npm 即可。

image.png

在確保 ServBay 運行且 Node 模塊已啓用的情況下,安裝 Gemini CLI:

npm install -g @google/gemini-cli

測試 Gemini CLI 環境

安裝完成並確保擁有正確的 Node.js 版本後,可以測試 Gemini CLI 的啓動。這裏需要使用 API Key 或 Google 賬户進行認證:

gemini auth

image.png

登錄成功後,運行 gemini 命令將進入交互模式。

從哪裏開始?

MCP 開發的策略是採用循序漸進的方法。

  1. 首先,設置基本的開發環境,配置所需的系統變量,並確保 Gemini CLI 正常工作。
  2. 然後,構建一個具有 stdio 傳輸功能的最小 "Hello World" 風格的 Ruby MCP 服務器。
  3. 驗證 Gemini CLI 與本地進程通過 MCP 的連接。
  4. 最後,擴展基本的 MCP 服務器,添加更多實用工具。

使用 STDIO 傳輸的 Hello World

MCP 庫的一個主要功能是抽象各種傳輸方法。無論 MCP 客户端使用何種低級傳輸通道/方法連接到 MCP 服務器,高級工具的實現都是相同的。

SDK 支持的最簡單的傳輸方式是 stdio(標準輸入/輸出)傳輸,它連接本地運行的進程。MCP 客户端和 MCP 服務器必須在同一環境中運行。

連接建立的代碼邏輯如下:

# 代碼示例
logger.info "啓動 MCP 服務器..."
transport = MCP::Server::Transports::Stdio.new
server.run(transport)

項目配置 (Gemfile)

在項目目錄中創建 Gemfile,引入 MCP SDK 和日誌庫:

# frozen_string_literal: true

source 'https://rubygems.org'

# 使用 ServBay 提供的 Ruby 版本
ruby '3.2.0'

gem 'logger'
gem 'mcp-sdk' # 注意:此處需根據實際可用的 gem 名稱調整

運行安裝命令:

bundle install

編寫 Ruby 代碼

我們在項目目錄下創建一個名為 server.rb 的文件。這段代碼將初始化服務器、註冊工具並啓動監聽。

require 'mcp'
require 'logger'
require 'json'

# 設置日誌輸出到標準錯誤流 (stderr),因為 stdout 被協議佔用
$logger = Logger.new($stderr)
$logger.level = Logger::INFO

class SimpleRubyServer
  def initialize
    @mcp_server = MCP::Server.new("MyLocalRubyServer", "1.0.0")
    register_capabilities
  end

  def register_capabilities
    # 註冊一個簡單的問候工具
    @mcp_server.register_tool("say_hello", "向用户致以問候", {
      type: "object",
      properties: {
        username: { type: "string", description: "用户的名字" }
      },
      required: ["username"]
    }) do |params|
      execute_hello(params)
    end
  end

  def execute_hello(params)
    user = params['username'] || "Anonymous"
    $logger.info "收到問候請求,對象: #{user}"
    
    # 返回符合 MCP 協議的響應格式
    { 
      content: [
        { 
          type: "text", 
          text: "你好, #{user}! 這裏是運行在本地的 Ruby MCP 服務器。" 
        }
      ] 
    }
  end

  def start
    $logger.info "服務器準備就緒,正在監聽 Stdio..."
    # 實例化 Stdio 傳輸層並運行
    transport = MCP::Server::Transports::Stdio.new
    @mcp_server.run(transport)
  rescue => e
    $logger.error "服務器運行出錯: #{e.message}"
  end
end

# 入口點
if __FILE__ == $0
  SimpleRubyServer.new.start
end

運行測試

在連接 Gemini 之前,可以先嚐試運行腳本確保無語法錯誤:

ruby server.rb

程序啓動後會掛起等待輸入,這是正常的。

配置 Gemini CLI (settings.json)

Gemini CLI 需要知道如何啓動我們的 Ruby 服務器。修改 Gemini 的配置文件:

{
  "mcpServers": {
    "ruby-demo": {
      "command": "ruby",
      "args": [
        "/你的/項目/絕對路徑/server.rb"
      ]
    }
  }
}

使用 Gemini CLI 審查項目

啓動 Gemini CLI,它將讀取配置並嘗試連接服務器。

gemini

image.png

在交互界面中,我們可以檢查服務器狀態:

> /mcp list

Configured MCP servers:
🟢 ruby-demo - Ready (1 tool)
  Tools:
  - say_hello

驗證與交互

現在,通過 Gemini CLI 與 Ruby 代碼進行實際交互。

輸入指令:

> 請使用 ruby-demo 服務器向 "ServBay 開發者" 打個招呼。

Gemini 將解析請求,調用本地 Ruby 進程,並輸出結果:

✦ I will call the say_hello tool with the username "ServBay 開發者".

╭──────────────────────────────────────────────────────────────────╮
│ ✓  say_hello (ruby-demo MCP Server) {"username":"ServBay 開發者"}  │
│                                                                  │
│ 你好, ServBay 開發者! 這裏是運行在本地的 Ruby MCP 服務器。             │
╰──────────────────────────────────────────────────────────────────╯

擴展 Ruby MCP 服務器

基本的 MCP 功能已通過 Gemini CLI 驗證。接下來,我們可以通過添加獲取系統信息的工具來擴展服務器。

server.rbregister_capabilities 方法中添加新工具:

    # 註冊系統信息工具
    @mcp_server.register_tool("system_specs", "獲取當前運行環境的 Ruby 和系統信息", {}) do |_|
      get_specs
    end

並添加對應的處理方法:

  def get_specs
    specs = {
      ruby_v: RUBY_VERSION,
      platform: RUBY_PLATFORM,
      servbay_env: ENV['SERVBAY_ROOT'] ? "Detected" : "Not Detected",
      time: Time.now.to_s
    }
    { content: [{ type: "text", text: JSON.pretty_generate(specs) }] }
  end

重啓 Gemini CLI 後,新的工具即可被調用。

> 獲取當前系統的 Ruby 環境信息。

Gemini 將返回包含 Ruby 版本和 ServBay 環境檢測結果的 JSON 數據,並據此回答你的問題。

總結

通過循序漸進的方法,我們驗證了使用 Ruby 和 Gemini CLI 進行 MCP 開發的可行性。

藉助 ServBay,我們省去了配置 Ruby 版本管理器和 Node.js 環境的繁雜過程,能夠直接專注於代碼實現。通過構建最小的 Stdio 傳輸服務器,我們成功讓本地 Ruby 代碼與 Gemini 大模型建立了連接。這種方法可以進一步擴展,利用 Ruby 豐富的生態系統處理更復雜的本地任務。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.