MCP服务器框架

一个可插拔、协议无关的MCP服务器框架,用于基于Rack的Ruby应用程序,支持动态加载工具、提示和资源。

  • by ajentik
  • Ruby
  • 本地部署
  • 4 星标
  • 更新于
在 GitHub 查看 ajentik/mcp_server

使用说明

mcp服务器

一个可插拔的、与协议无关的MCP(模型上下文协议)服务器,用于 基于机架的Ruby应用程序。

安装

将此行添加到应用程序的Gemfile中:

gem 'mcp_server'

然后执行:

bundle install

或者自己安装:

gem install mcp_server

用法

基本配置

使用您的身份验证逻辑和MCP组件配置MCP服务器 (工具、提示、资源):

require 'mcp_server'
require 'mcp'

# Define your MCP tools
class CalculatorTool < MCP::Tool
  tool_name "calculator"
  description "Performs basic arithmetic operations"
  input_schema(
    properties: {
      operation: { type: "string", enum: ["add", "subtract", "multiply", "divide"] },
      a: { type: "number" },
      b: { type: "number" }
    },
    required: ["operation", "a", "b"]
  )

  def self.call(operation:, a:, b:, server_context:)
    # Access context data in your tool
    user = server_context[:user]
    permissions = server_context[:permissions]
    
    # Your tool logic here
    result = case operation
    when "add" then a + b
    when "subtract" then a - b
    when "multiply" then a * b
    when "divide" then b != 0 ? a / b : "Error: Division by zero"
    end
    
    MCP::Tool::Response.new(
      content: [MCP::Content.text("Result: #{result}")]
    )
  end
end

# Configure the server
MCPServer.configure do |config|
  # Define how to authenticate requests (optional)
  config.authenticate_with do |request|
    # Your authentication logic here
    # Return true/false or raise an error
    request.env['HTTP_AUTHORIZATION'] == 'Bearer secret-token'
  end

  # Define how to build the server context (optional)
  config.build_context_with do |request|
    # Return a hash with any context data your tools need
    {
      user: User.find_by_token(request.env['HTTP_AUTHORIZATION']),
      organization: Organization.from_request(request),
      permissions: Permission.for_request(request),
      locale: request.env['HTTP_ACCEPT_LANGUAGE'],
      custom_data: "any other context you need"
    }
  end

  # Configure MCP components (as callables for dynamic loading)
  config.tools = -> { [CalculatorTool] }
  config.prompts = -> { [] }  # Add your MCP::Prompt classes here
  config.resources = -> { [] } # Add your MCP::Resource instances here

  # Refer to https://github.com/modelcontextprotocol/ruby-sdk?tab=readme-ov-file#resources
  # for more details on how to define resources
  config.resources_read_handler do |request_params|
    # Handle resource read requests
    resource = Resource.find_by_id(request_params['id'])
    [{
      uri: request_params[:uri],
      mimeType: 'application/json',
      text: resource.to_json
    }]
  end

  # Only when using the MCP gem's version after commit hash 382ae13
  # https://github.com/modelcontextprotocol/ruby-sdk/commit/382ae13e25ba095fbe227b186b3287c3c7eb7ff4
  config.transport = MCP::Server::Transports::StdioTransport

  # Define a response handler to modify responses (optional)
  config.response_handler do |response, request|
    # Modify response headers, status, or body
    status, headers, body = response
    headers['X-Custom-Header'] = 'Modified'

    # Disable SSE (Server-Sent Events) by removing the session ID header
    # headers.delete('Mcp-Session-Id')

    [status, headers, body]
  end
end

服务器发送事件(SSE)和多进程服务器

重要提示: 当前的SSE实现需要将流对象保存在内存中。这意味着SSE将无法与多进程服务器(如Unicorn、集群模式下的Puma或Passenger)正常工作,因为:

  • 流对象存储在处理初始请求的进程中
  • 后续请求可能会被路由到无法访问这些流的不同进程
  • 当请求由不同进程处理时,这会导致SSE连接失败

解决:

  1. 使用单进程、多线程服务器(例如,具有多线程的单模式Puma)
  2. 通过删除以下命令禁用SSE Mcp-Session-Id 响应处理程序中的标头(见上面的示例)

在机架应用中安装

在Rails应用程序中

添加到您的 config/routes.rb:

mount MCPServer::RackApp => '/mcp'

在Sinatra应用程序中

require 'sinatra'
require 'mcp_server'

# Configure MCPServer...

use MCPServer::RackApp

在普通的Rack应用程序中(config.ru)

require 'mcp_server'

# Configure MCPServer...

run MCPServer::RackApp

发展

签出repo后,运行 bundle install 安装依赖项。

运行测试

# Run all tests
rake test

# Run a specific test file
ruby -Ilib:test test/test_configuration.rb

掉毛

本项目使用StandardRB for Ruby风格指南:

standardrb

建造宝石

gem build mcp_server.gemspec

建筑

该宝石采用模块化架构:

  • 配置:存储以下内容的中心配置对象:
    • 身份验证回调(可选)
    • 上下文构建回调(可选)-构建传递给工具的服务器上下文
    • 返回MCP工具、提示和资源数组的可调用项(用于动态加载)
    • 响应处理程序回调(可选)-用于在发送之前修改响应
  • RackApp:主机架应用程序:
    • 处理带有JSON-RPC有效载荷的HTTP请求(支持所有HTTP方法)
    • 如果已配置,则执行身份验证
    • 创建具有已配置组件的MCP::服务器实例
    • 代表向MCP gem或配置的传输请求处理
    • 处理各种响应体类型(nil、string、array、object)
  • MCP集成:利用官方MCP Ruby SDK实现协议合规性

贡献

  1. 叉起来
  2. 创建功能分支(git checkout -b my-new-feature)
  3. 提交您的更改(git commit -am 'Add some feature')
  4. 推到分支(git push origin my-new-feature)
  5. 创建新的Pull请求

许可证

根据以下条款,gem可作为开源软件使用 MIT许可证.