Project

rasti-ai

0.0
The project is in a healthy, maintained state
AI for apps
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 5.0, < 5.11
~> 0.2
~> 12.0
~> 0.12
~> 3.0

Runtime

 Project Readme

Rasti::AI

Gem Version CI

AI for apps

Installation

Add this line to your application's Gemfile:

gem 'rasti-ai'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rasti-ai

Usage

Configuration

Rasti::AI.configure do |config|
  config.logger = Logger.new 'log/development.log'
  config.openai_api_key = 'abcd12345' # Default ENV['OPENAI_API_KEY']
  config.openai_default_model = 'gpt-4o-mini' # Default ENV['OPENAI_DEFAULT_MODEL']
end

Open AI

Assistant

assistant = Rasti::AI::OpenAI::Assistant.new
assistant.call 'who is the best player' # => 'The best player is Lionel Messi'

Tools

class GetCurrentTime
  def call(params={})
    Time.now.iso8601
  end
end

class GetCurrentWeather
  def self.form
    Rasti::Form[location: Rasti::Types::String]
  end

  def call(params={})
    response = HTTP.get "https://api.wheater.com/?location=#{params['location']}"
    response.body.to_s
  end
end

tools = [
  GetCurrentTime.new,
  GetCurrentWeather.new
]

assistant = Rasti::AI::OpenAI::Assistant.new tools: tools

assistant.call 'what time is it' # => 'The current time is 3:03 PM on April 28, 2025.'

assistant.call 'what is the weather in Buenos Aires' # => 'In Buenos Aires it is 15 degrees'

Context and state

state = Rasti::AI::OpenAI::AssistantState.new context: 'Act as sports journalist'

assistant = Rasti::AI::OpenAI::Assistant.new state: state

assistant.call 'who is the best player'

state.messages
# [
#   {
#     role: 'system',
#     content: 'Act as sports journalist'
#   },
#   {
#     role: 'user',
#     content: 'who is the best player'
#   },
#   {
#     role: 'assistant',
#     content: 'The best player is Lionel Messi'
#   }
# ]

MCP (Model Context Protocol)

Rasti::AI includes support for the Model Context Protocol, allowing you to create MCP servers and clients for tool communication.

MCP Server

The MCP Server acts as a Rack middleware that exposes registered tools through a JSON-RPC 2.0 interface.

Configuration
Rasti::AI::MCP::Server.configure do |config|
  config.server_name = 'My MCP Server'
  config.server_version = '1.0.0'
  config.relative_path = '/mcp' # Default endpoint path
end
Registering Tools

Tools must inherit from Rasti::AI::Tool and can be registered with the server:

class HelloWorldTool < Rasti::AI::Tool
  def self.description
    'Returns a hello world message'
  end

  def execute(form)
    {text: 'Hello world'}
  end
end

class SumTool < Rasti::AI::Tool
  class Form < Rasti::Form
    attribute :number_a, Rasti::Types::Float
    attribute :number_b, Rasti::Types::Float
  end

  def execute(form)
    {result: form.number_a + form.number_b}
  end
end

# Register tools
Rasti::AI::MCP::Server.register_tool HelloWorldTool.new
Rasti::AI::MCP::Server.register_tool SumTool.new
Using as Rack Middleware
# In your config.ru
require 'rasti/ai'

# Register your tools
Rasti::AI::MCP::Server.register_tool HelloWorldTool.new
Rasti::AI::MCP::Server.register_tool SumTool.new

# Use as middleware
use Rasti::AI::MCP::Server

run YourApp

The server will handle POST requests to the configured path (/mcp by default) and pass all other requests to your application.

Supported MCP Methods
  • initialize - Returns protocol version and server capabilities
  • tools/list - Returns all registered tools with their schemas
  • tools/call - Executes a specific tool with provided arguments

MCP Client

The MCP Client allows you to communicate with MCP servers.

Basic Usage
# Create a client
client = Rasti::AI::MCP::Client.new(
  url: 'https://mcp.server.ai/mcp'
)

# List available tools
tools = client.list_tools
# => [
#      { "name" => "hello_world_tool", "description" => "Hello World", ... },
#      { "name" => "sum_tool", "description" => "Sum two numbers", ... }
#    ]

# Call a tool
result = client.call_tool 'sum_tool', number_a: 5, number_b: 3
# => '{"type":"text","text":"{\"result\":8.0}"}'

result = client.call_tool 'hello_world_tool'
# => '{"type":"text","text":"{\"text\":\"Hello world\"}"}'
Restricting Available Tools

You can restrict which tools the client can access:

client = Rasti::AI::MCP::Client.new(
  url: 'https://mcp.server.ai/mcp',
  allowed_tools: ['sum_tool', 'multiply_tool']
)

# Only returns allowed tools
tools = client.list_tools
# => [{ "name" => "sum_tool", ... }]

# Calling a non-allowed tool raises an error
client.call_tool 'hello_world_tool'
# => RuntimeError: Invalid tool: hello_world_tool
Custom Logger
client = Rasti::AI::MCP::Client.new(
  url: 'https://mcp.server.ai/mcp',
  logger: Logger.new(STDOUT)
)
Integration with OpenAI Assistant

You can use MCP clients as tools for the OpenAI Assistant:

# Create an MCP client
mcp_client = Rasti::AI::MCP::Client.new(
  url: 'https://mcp.server.ai/mcp'
)

# Use it with the assistant
assistant = Rasti::AI::OpenAI::Assistant.new(
  mcp_servers: {
    my_mcp: mcp_client
  }
)

# The assistant can now call tools from the MCP server
assistant.call 'What is 5 plus 3?'
# The assistant will use the sum_tool from the MCP server

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/gabynaiman/rasti-ai.

License

The gem is available as open source under the terms of the MIT License.