update README and cursor rule

This commit is contained in:
Topher Bullock 2025-05-29 17:11:45 -04:00
commit bf07d4a02c
2 changed files with 69 additions and 53 deletions

View file

@ -1,23 +1,20 @@
--- ---
description: writing changelog markdown when cutting a new release of the gem description: writing changelog markdown when cutting a new release of the gem
globs: globs:
alwaysApply: false alwaysApply: false
--- ---
- output the changelog as markdown when asked. - output the changelog as markdown when asked.
- git tags are used to mark the commit that cut a new release of the gem - git tags are used to mark the commit that cut a new release of the gem
- the gem version is located in [version.rb](mdc:lib/model_context_protocol/version.rb) - the gem version is located in [version.rb](mdc:lib/mcp/version.rb)
- use the git history, especially merge commits from PRs to construct the changelog - use the git history, especially merge commits from PRs to construct the changelog
- when necessary, look at the diff of files changed to determine whether a PR should be listed in - when necessary, look at the diff of files changed to determine whether a PR should be listed in
- ## Added; adds new functionality - ## Added; adds new functionality
- ## Changed; alters functionality; especially backward compatible changes - ## Changed; alters functionality; especially backward compatible changes
- ## Fixed; bugfixes that are forward compatible - ## Fixed; bugfixes that are forward compatible
use the following format for changelogs: use the following format for changelogs:
https://cloudsmith.io/~shopify/repos/gems/packages/detail/ruby/mcp-ruby/{gem version}/ ```
# Changelog
## Added ## Added
- New functionality added that was not present before - New functionality added that was not present before
@ -25,8 +22,9 @@ https://cloudsmith.io/~shopify/repos/gems/packages/detail/ruby/mcp-ruby/{gem ver
- Alterations to functionality that may indicate breaking changes - Alterations to functionality that may indicate breaking changes
## Fixed ## Fixed
- Bug fixes - Bug fixes
#### Full change list: #### Full change list:
- [Name of the PR #123](mdc:https:/github.com/Shopify/mcp-ruby/pull/123) @github-author-username - [Name of the PR #123](https:/github.com/modelcontextprotocol/ruby-sdk/pull/123) @github-author-username
- [Name of the PR #456](mdc:https:/github.com/Shopify/mcp-ruby/pull/456) @another-github-author - [Name of the PR #456](https:/github.com/modelcontextprotocol/ruby-sdk/pull/456) @another-github-author
```

View file

@ -2,9 +2,29 @@
A Ruby gem for implementing Model Context Protocol servers A Ruby gem for implementing Model Context Protocol servers
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'mcp'
```
And then execute:
```bash
$ bundle install
```
Or install it yourself as:
```bash
$ gem install mcp
```
## MCP Server ## MCP Server
The `ModelContextProtocol::Server` class is the core component that handles JSON-RPC requests and responses. The `MCP::Server` class is the core component that handles JSON-RPC requests and responses.
It implements the Model Context Protocol specification, handling model context requests and responses. It implements the Model Context Protocol specification, handling model context requests and responses.
### Key Features ### Key Features
@ -44,19 +64,17 @@ requests.
You can use the `Server#handle_json` method to handle requests. You can use the `Server#handle_json` method to handle requests.
```ruby ```ruby
module ModelContextProtocol class ApplicationController < ActionController::Base
class ApplicationController < ActionController::Base
def index def index
server = ModelContextProtocol::Server.new( server = MCP::Server.new(
name: "my_server", name: "my_server",
version: "1.0.0", version: "1.0.0",
tools: [SomeTool, AnotherTool], tools: [SomeTool, AnotherTool],
prompts: [MyPrompt], prompts: [MyPrompt],
server_context: { user_id: current_user.id }, server_context: { user_id: current_user.id },
) )
render(json: server.handle_json(request.body.read).to_h) render(json: server.handle_json(request.body.read))
end
end end
end end
``` ```
@ -67,11 +85,11 @@ If you want to build a local command-line application, you can use the stdio tra
```ruby ```ruby
#!/usr/bin/env ruby #!/usr/bin/env ruby
require "model_context_protocol" require "mcp"
require "model_context_protocol/transports/stdio" require "mcp/transports/stdio"
# Create a simple tool # Create a simple tool
class ExampleTool < ModelContextProtocol::Tool class ExampleTool < MCP::Tool
description "A simple example tool that echoes back its arguments" description "A simple example tool that echoes back its arguments"
input_schema( input_schema(
properties: { properties: {
@ -82,7 +100,7 @@ class ExampleTool < ModelContextProtocol::Tool
class << self class << self
def call(message:, server_context:) def call(message:, server_context:)
ModelContextProtocol::Tool::Response.new([{ MCP::Tool::Response.new([{
type: "text", type: "text",
text: "Hello from example tool! Message: #{message}", text: "Hello from example tool! Message: #{message}",
}]) }])
@ -91,13 +109,13 @@ class ExampleTool < ModelContextProtocol::Tool
end end
# Set up the server # Set up the server
server = ModelContextProtocol::Server.new( server = MCP::Server.new(
name: "example_server", name: "example_server",
tools: [ExampleTool], tools: [ExampleTool],
) )
# Create and start the transport # Create and start the transport
transport = ModelContextProtocol::Transports::StdioTransport.new(server) transport = MCP::Transports::StdioTransport.new(server)
transport.open transport.open
``` ```
@ -112,10 +130,10 @@ $ ./stdio_server.rb
## Configuration ## Configuration
The gem can be configured using the `ModelContextProtocol.configure` block: The gem can be configured using the `MCP.configure` block:
```ruby ```ruby
ModelContextProtocol.configure do |config| MCP.configure do |config|
config.exception_reporter = ->(exception, server_context) { config.exception_reporter = ->(exception, server_context) {
# Your exception reporting logic here # Your exception reporting logic here
# For example with Bugsnag: # For example with Bugsnag:
@ -135,7 +153,7 @@ This is useful for systems where an application hosts more than one MCP server b
they might require different instrumentation callbacks. they might require different instrumentation callbacks.
```ruby ```ruby
configuration = ModelContextProtocol::Configuration.new configuration = MCP::Configuration.new
configuration.exception_reporter = ->(exception, server_context) { configuration.exception_reporter = ->(exception, server_context) {
# Your exception reporting logic here # Your exception reporting logic here
# For example with Bugsnag: # For example with Bugsnag:
@ -148,7 +166,7 @@ configuration.instrumentation_callback = ->(data) {
puts "Got instrumentation data #{data.inspect}" puts "Got instrumentation data #{data.inspect}"
} }
server = ModelContextProtocol::Server.new( server = MCP::Server.new(
# ... all other options # ... all other options
configuration:, configuration:,
) )
@ -167,7 +185,7 @@ server_context: { [String, Symbol] => Any }
**Example:** **Example:**
```ruby ```ruby
server = ModelContextProtocol::Server.new( server = MCP::Server.new(
name: "my_server", name: "my_server",
server_context: { user_id: current_user.id, request_id: request.uuid } server_context: { user_id: current_user.id, request_id: request.uuid }
) )
@ -218,13 +236,13 @@ config.instrumentation_callback = ->(data) {
The server's protocol version can be overridden using the `protocol_version` class method: The server's protocol version can be overridden using the `protocol_version` class method:
```ruby ```ruby
ModelContextProtocol::Server.protocol_version = "2024-11-05" MCP::Server.protocol_version = "2024-11-05"
``` ```
This will make all new server instances use the specified protocol version instead of the default version. The protocol version can be reset to the default by setting it to `nil`: This will make all new server instances use the specified protocol version instead of the default version. The protocol version can be reset to the default by setting it to `nil`:
```ruby ```ruby
ModelContextProtocol::Server.protocol_version = nil MCP::Server.protocol_version = nil
``` ```
Be sure to check the [MCP spec](https://spec.modelcontextprotocol.io/specification/2024-11-05/) for the protocol version to understand the supported features for the version being set. Be sure to check the [MCP spec](https://spec.modelcontextprotocol.io/specification/2024-11-05/) for the protocol version to understand the supported features for the version being set.
@ -253,12 +271,12 @@ If no exception reporter is configured, a default no-op reporter is used that si
MCP spec includes [Tools](https://modelcontextprotocol.io/docs/concepts/tools) which provide functionality to LLM apps. MCP spec includes [Tools](https://modelcontextprotocol.io/docs/concepts/tools) which provide functionality to LLM apps.
This gem provides a `ModelContextProtocol::Tool` class that can be used to create tools in two ways: This gem provides a `MCP::Tool` class that can be used to create tools in two ways:
1. As a class definition: 1. As a class definition:
```ruby ```ruby
class MyTool < ModelContextProtocol::Tool class MyTool < MCP::Tool
description "This tool performs specific functionality..." description "This tool performs specific functionality..."
input_schema( input_schema(
properties: { properties: {
@ -275,17 +293,17 @@ class MyTool < ModelContextProtocol::Tool
) )
def self.call(message:, server_context:) def self.call(message:, server_context:)
Tool::Response.new([{ type: "text", text: "OK" }]) MCP::Tool::Response.new([{ type: "text", text: "OK" }])
end end
end end
tool = MyTool tool = MyTool
``` ```
2. By using the `ModelContextProtocol::Tool.define` method with a block: 2. By using the `MCP::Tool.define` method with a block:
```ruby ```ruby
tool = ModelContextProtocol::Tool.define( tool = MCP::Tool.define(
name: "my_tool", name: "my_tool",
description: "This tool performs specific functionality...", description: "This tool performs specific functionality...",
annotations: { annotations: {
@ -316,12 +334,12 @@ Annotations can be set either through the class definition using the `annotation
MCP spec includes [Prompts](https://modelcontextprotocol.io/docs/concepts/prompts), which enable servers to define reusable prompt templates and workflows that clients can easily surface to users and LLMs. MCP spec includes [Prompts](https://modelcontextprotocol.io/docs/concepts/prompts), which enable servers to define reusable prompt templates and workflows that clients can easily surface to users and LLMs.
The `ModelContextProtocol::Prompt` class provides two ways to create prompts: The `MCP::Prompt` class provides two ways to create prompts:
1. As a class definition with metadata: 1. As a class definition with metadata:
```ruby ```ruby
class MyPrompt < ModelContextProtocol::Prompt class MyPrompt < MCP::Prompt
prompt_name "my_prompt" # Optional - defaults to underscored class name prompt_name "my_prompt" # Optional - defaults to underscored class name
description "This prompt performs specific functionality..." description "This prompt performs specific functionality..."
arguments [ arguments [
@ -354,10 +372,10 @@ end
prompt = MyPrompt prompt = MyPrompt
``` ```
2. Using the `ModelContextProtocol::Prompt.define` method: 2. Using the `MCP::Prompt.define` method:
```ruby ```ruby
prompt = ModelContextProtocol::Prompt.define( prompt = MCP::Prompt.define(
name: "my_prompt", name: "my_prompt",
description: "This prompt performs specific functionality...", description: "This prompt performs specific functionality...",
arguments: [ arguments: [
@ -399,7 +417,7 @@ e.g. around authentication state or user preferences.
Register prompts with the MCP server: Register prompts with the MCP server:
```ruby ```ruby
server = ModelContextProtocol::Server.new( server = MCP::Server.new(
name: "my_server", name: "my_server",
prompts: [MyPrompt], prompts: [MyPrompt],
server_context: { user_id: current_user.id }, server_context: { user_id: current_user.id },
@ -417,7 +435,7 @@ The server allows registering a callback to receive information about instrument
To register a handler pass a proc/lambda to as `instrumentation_callback` into the server constructor. To register a handler pass a proc/lambda to as `instrumentation_callback` into the server constructor.
```ruby ```ruby
ModelContextProtocol.configure do |config| MCP.configure do |config|
config.instrumentation_callback = ->(data) { config.instrumentation_callback = ->(data) {
puts "Got instrumentation data #{data.inspect}" puts "Got instrumentation data #{data.inspect}"
end end
@ -439,16 +457,16 @@ This is to avoid potential issues with metric cardinality
MCP spec includes [Resources](https://modelcontextprotocol.io/docs/concepts/resources) MCP spec includes [Resources](https://modelcontextprotocol.io/docs/concepts/resources)
The `ModelContextProtocol::Resource` class provides a way to register resources with the server. The `MCP::Resource` class provides a way to register resources with the server.
```ruby ```ruby
resource = ModelContextProtocol::Resource.new( resource = MCP::Resource.new(
uri: "example.com/my_resource", uri: "example.com/my_resource",
mime_type: "text/plain", mime_type: "text/plain",
text: "Lorem ipsum dolor sit amet" text: "Lorem ipsum dolor sit amet"
) )
server = ModelContextProtocol::Server.new( server = MCP::Server.new(
name: "my_server", name: "my_server",
resources: [resource], resources: [resource],
) )