Internal Release 0.6.0

Rename Context Arg
This commit is contained in:
Tyler Rowsell 2025-04-23 16:30:01 -04:00 • committed by Topher Bullock
commit 62184957e0
11 changed files with 52 additions and 52 deletions

View file

@ -1,7 +1,7 @@
PATH
remote: .
specs:
model_context_protocol (0.5.2)
model_context_protocol (0.6.0)
json_rpc_handler (~> 0.1)
GEM

View file

@ -49,7 +49,7 @@ module ModelContextProtocol
name: "my_server",
tools: [SomeTool, AnotherTool],
prompts: [MyPrompt],
context: { user_id: current_user.id },
server_context: { user_id: current_user.id },
)
render(json: server.handle_json(request.body.read).to_h)
end
@ -69,7 +69,7 @@ module ModelContextProtocol
name: "my_server",
tools: [SomeTool, AnotherTool],
prompts: [MyPrompt],
context: { user_id: current_user.id },
server_context: { user_id: current_user.id },
)
render(json: server.handle(JSON.parse(request.body.read)).to_h)
end
@ -96,7 +96,7 @@ class ExampleTool < ModelContextProtocol::Tool
required: ["message"]
class << self
def call(message:, context:)
def call(message:, server_context:)
ModelContextProtocol::Tool::Response.new([{
type: "text",
text: "Hello from example tool! Message: #{message}",
@ -137,7 +137,7 @@ server = ModelContextProtocol::Server.new(
name: "my_server",
tools: [SomeTool, AnotherTool],
prompts: [MyPrompt],
context: { user_id: current_user.id },
server_context: { user_id: current_user.id },
)
request = {
jsonrpc: "2.0",
@ -154,11 +154,11 @@ The gem can be configured using the `ModelContextProtocol.configure` block:
```ruby
ModelContextProtocol.configure do |config|
config.exception_reporter = ->(exception, context) do
config.exception_reporter = ->(exception, server_context) do
# Your exception reporting logic here
# For example with Bugsnag:
Bugsnag.notify(exception) do |report|
report.add_metadata(:model_context_protocol, context)
report.add_metadata(:model_context_protocol, server_context)
end
end
@ -170,11 +170,11 @@ This is useful for systems where an application hosts more than one MCP server b
they might require different instrumentation callbacks.
configuration = ModelContextProtocol::Configuration.new
configuration.exception_reporter = ->(exception, context) do
configuration.exception_reporter = ->(exception, server_context) do
# Your exception reporting logic here
# For example with Bugsnag:
Bugsnag.notify(exception) do |report|
report.add_metadata(:model_context_protocol, context)
report.add_metadata(:model_context_protocol, server_context)
end
end
@ -207,9 +207,9 @@ Be sure to check the [MCP spec](https://spec.modelcontextprotocol.io/specificati
The exception reporter receives two arguments:
- `exception`: The Ruby exception object that was raised
- `context`: A hash containing contextual information about where the error occurred
- `server_context`: A hash containing contextual information about where the error occurred
The context hash includes:
The server_context hash includes:
- For tool calls: `{ tool_name: "name", arguments: { ... } }`
- For general request handling: `{ request: { ... } }`
@ -248,7 +248,7 @@ class MyTool < ModelContextProtocol::Tool
},
required: ['message']
def self.call(message:, context:)
def self.call(message:, server_context:)
Tool::Response.new([{ type: "text", text: "OK" }])
end
end
@ -266,12 +266,12 @@ tool = ModelContextProtocol::Tool.define(
title: "My Tool",
read_only_hint: true
}
) do |args, context|
) do |args, server_context|
Tool::Response.new([{ type: "text", text: "OK" }])
end
```
The context parameter is the context passed into the server and can be used to pass per request information,
The server_context parameter is the server_context passed into the server and can be used to pass per request information,
e.g. around authentication state.
### Tool Annotations
@ -307,7 +307,7 @@ class MyPrompt < ModelContextProtocol::Prompt
]
class << self
def template(args, context:)
def template(args, server_context:)
Prompt::Result.new(
description: "Response description",
messages: [
@ -341,7 +341,7 @@ prompt = ModelContextProtocol::Prompt.define(
required: true
)
]
) do |args, context:|
) do |args, server_context:|
Prompt::Result.new(
description: "Response description",
messages: [
@ -358,7 +358,7 @@ prompt = ModelContextProtocol::Prompt.define(
end
```
The context parameter is the context passed into the server and can be used to pass per request information,
The server_context parameter is the server_context passed into the server and can be used to pass per request information,
e.g. around authentication state or user preferences.
### Key Components
@ -376,7 +376,7 @@ Register prompts with the MCP server:
server = ModelContextProtocol::Server.new(
name: "my_server",
prompts: [MyPrompt],
context: { user_id: current_user.id },
server_context: { user_id: current_user.id },
)
```

View file

@ -15,7 +15,7 @@ class ExampleTool < ModelContextProtocol::Tool
required: ["message"]
class << self
def call(message:, context:)
def call(message:, server_context:)
ModelContextProtocol::Tool::Response.new([{
type: "text",
text: "Hello from example tool! Message: #{message}",

View file

@ -65,7 +65,7 @@ module ModelContextProtocol
private
def default_exception_reporter
@default_exception_reporter ||= ->(exception, context) {}
@default_exception_reporter ||= ->(exception, server_context) {}
end
def default_instrumentation_callback

View file

@ -50,7 +50,7 @@ module ModelContextProtocol
attr_reader :description_value
attr_reader :arguments_value
def template(args, context:)
def template(args, server_context:)
raise NotImplementedError, "Subclasses must implement template"
end
@ -98,8 +98,8 @@ module ModelContextProtocol
prompt_name name
description description
arguments arguments
define_singleton_method(:template) do |args, context:|
instance_exec(args, context:, &block)
define_singleton_method(:template) do |args, server_context:|
instance_exec(args, server_context:, &block)
end
end
end

View file

@ -20,16 +20,16 @@ module ModelContextProtocol
include Instrumentation
attr_accessor :name, :tools, :prompts, :resources, :context, :configuration
attr_accessor :name, :tools, :prompts, :resources, :server_context, :configuration
def initialize(name: "model_context_protocol", tools: [], prompts: [], resources: [], context: nil,
def initialize(name: "model_context_protocol", tools: [], prompts: [], resources: [], server_context: nil,
configuration: nil)
@name = name
@tools = tools.to_h { |t| [t.name_value, t] }
@prompts = prompts.to_h { |p| [p.name_value, p] }
@resources = resources
@resource_index = index_resources_by_uri(resources)
@context = context
@server_context = server_context
@configuration = ModelContextProtocol.configuration.merge(configuration)
@handlers = {
Methods::RESOURCES_LIST => method(:list_resources),
@ -154,7 +154,7 @@ module ModelContextProtocol
add_instrumentation_data(tool_name:)
begin
tool.call(**request[:arguments], context:).to_h
tool.call(**request[:arguments], server_context:).to_h
rescue => e
raise RequestHandlerError.new("Internal error calling tool #{tool_name}", request, original_error: e)
end
@ -179,7 +179,7 @@ module ModelContextProtocol
prompt_args = request[:arguments]
prompt.validate_arguments!(prompt_args)
prompt.template(prompt_args, context:).to_h
prompt.template(prompt_args, server_context:).to_h
end
def list_resources(request)
@ -202,8 +202,8 @@ module ModelContextProtocol
resource.to_h
end
def report_exception(exception, context = {})
configuration.exception_reporter.call(exception, context)
def report_exception(exception, server_context = {})
configuration.exception_reporter.call(exception, server_context)
end
def index_resources_by_uri(resources)

View file

@ -44,7 +44,7 @@ module ModelContextProtocol
attr_reader :input_schema_value
attr_reader :annotations_value
def call(*args, context:)
def call(*args, server_context:)
raise NotImplementedError, "Subclasses must implement call"
end
@ -108,8 +108,8 @@ module ModelContextProtocol
description description
input_schema input_schema
self.annotations(annotations) if annotations
define_singleton_method(:call) do |*args, context:|
instance_exec(*args, context:, &block)
define_singleton_method(:call) do |*args, server_context:|
instance_exec(*args, server_context:, &block)
end
end
end

View file

@ -1,5 +1,5 @@
# frozen_string_literal: true
module ModelContextProtocol
VERSION = "0.5.2"
VERSION = "0.6.0"
end

View file

@ -10,10 +10,10 @@ module ModelContextProtocol
# The default reporter should be callable but do nothing
exception = StandardError.new("test error")
context = { test: "context" }
server_context = { test: "context" }
# Should not raise any errors
config.exception_reporter.call(exception, context)
config.exception_reporter.call(exception, server_context)
end
test "allows setting a custom exception reporter" do
@ -21,9 +21,9 @@ module ModelContextProtocol
reported_exception = nil
reported_context = nil
config.exception_reporter = ->(exception, context) do
config.exception_reporter = ->(exception, server_context) do
reported_exception = exception
reported_context = context
reported_context = server_context
end
test_exception = StandardError.new("test error")

View file

@ -12,7 +12,7 @@ module ModelContextProtocol
]
class << self
def template(args, context:)
def template(args, server_context:)
Prompt::Result.new(
description: "Hello, world!",
messages: [
@ -35,7 +35,7 @@ module ModelContextProtocol
],
}
result = prompt.template({ "test_argument" => "Hello, friend!" }, context: { user_id: 123 })
result = prompt.template({ "test_argument" => "Hello, friend!" }, server_context: { user_id: 123 })
assert_equal expected_template_result, result.to_h
end
@ -49,7 +49,7 @@ module ModelContextProtocol
]
class << self
def template(args, context:)
def template(args, server_context:)
Prompt::Result.new(
description: "Hello, world!",
messages: [
@ -77,7 +77,7 @@ module ModelContextProtocol
],
}
result = prompt.template({ "test_argument" => "Hello, friend!" }, context: { user_id: 123 })
result = prompt.template({ "test_argument" => "Hello, friend!" }, server_context: { user_id: 123 })
assert_equal expected_template_result, result.to_h
end
@ -89,7 +89,7 @@ module ModelContextProtocol
]
class << self
def template(args, context:)
def template(args, server_context:)
Prompt::Result.new(
description: "Hello, world!",
messages: [
@ -115,8 +115,8 @@ module ModelContextProtocol
arguments: [
Prompt::Argument.new(name: "test_argument", description: "Test argument", required: true),
],
) do |args, context:|
content = Content::Text.new(args["test_argument"] + " user: #{context[:user_id]}")
) do |args, server_context:|
content = Content::Text.new(args["test_argument"] + " user: #{server_context[:user_id]}")
Prompt::Result.new(
description: "Hello, world!",
@ -139,7 +139,7 @@ module ModelContextProtocol
],
}
result = prompt.template({ "test_argument" => "Hello, friend!" }, context: { user_id: 123 })
result = prompt.template({ "test_argument" => "Hello, friend!" }, server_context: { user_id: 123 })
assert_equal expected, result.to_h
end
end

View file

@ -182,7 +182,7 @@ module ModelContextProtocol
tool_args = { "arg" => "value" }
tool_response = Tool::Response.new([{ "result" => "success" }])
@tool.expects(:call).with(**tool_args, context: @server.context).returns(tool_response)
@tool.expects(:call).with(**tool_args, server_context: @server.server_context).returns(tool_response)
request = {
jsonrpc: "2.0",
@ -204,7 +204,7 @@ module ModelContextProtocol
tool_args = { arg: "value" }
tool_response = Tool::Response.new([{ result: "success" }])
@tool.expects(:call).with(**tool_args, context: @server.context).returns(tool_response)
@tool.expects(:call).with(**tool_args, server_context: @server.server_context).returns(tool_response)
request = JSON.generate({
jsonrpc: "2.0",
@ -219,7 +219,7 @@ module ModelContextProtocol
end
test "#handle tools/call returns internal error and reports exception if the tool raises an error" do
@server.configuration.exception_reporter.expects(:call).with do |exception, context|
@server.configuration.exception_reporter.expects(:call).with do |exception, server_context|
assert_not_nil exception
assert_equal(
{
@ -230,7 +230,7 @@ module ModelContextProtocol
id: 1,
},
},
context,
server_context,
)
end
@ -553,8 +553,8 @@ module ModelContextProtocol
test "the server configuration takes precedence over the global configuration" do
configuration = ModelContextProtocol::Configuration.new
local_callback = ->(data) { puts "Local callback #{data.inspect}" }
local_exception_reporter = ->(exception, context) {
puts "Local exception reporter #{exception.inspect} #{context.inspect}"
local_exception_reporter = ->(exception, server_context) {
puts "Local exception reporter #{exception.inspect} #{server_context.inspect}"
}
configuration.instrumentation_callback = local_callback
configuration.exception_reporter = local_exception_reporter