diff --git a/README.md b/README.md index 8f8667b2..d91cf2a9 100644 --- a/README.md +++ b/README.md @@ -155,11 +155,11 @@ You can use the `Server#handle_json` method to handle requests. ```ruby class ApplicationController < ActionController::Base - def index server = MCP::Server.new( name: "my_server", version: "1.0.0", + instructions: "Use the tools of this server as a last resort", tools: [SomeTool, AnotherTool], prompts: [MyPrompt], server_context: { user_id: current_user.id }, diff --git a/lib/mcp/server.rb b/lib/mcp/server.rb index df2a7e8a..e6c2684a 100644 --- a/lib/mcp/server.rb +++ b/lib/mcp/server.rb @@ -31,11 +31,12 @@ def initialize(method_name) include Instrumentation - attr_accessor :name, :version, :tools, :prompts, :resources, :server_context, :configuration, :capabilities, :transport + attr_accessor :name, :version, :instructions, :tools, :prompts, :resources, :server_context, :configuration, :capabilities, :transport def initialize( name: "model_context_protocol", version: DEFAULT_VERSION, + instructions: nil, tools: [], prompts: [], resources: [], @@ -47,6 +48,7 @@ def initialize( ) @name = name @version = version + @instructions = instructions @tools = tools.to_h { |t| [t.name_value, t] } @prompts = prompts.to_h { |p| [p.name_value, p] } @resources = resources @@ -54,6 +56,12 @@ def initialize( @resource_index = index_resources_by_uri(resources) @server_context = server_context @configuration = MCP.configuration.merge(configuration) + + if @configuration.protocol_version == "2024-11-05" && @instructions + message = "`instructions` supported by protocol version 2025-03-26 or higher" + raise ArgumentError, message + end + @capabilities = capabilities || default_capabilities @handlers = { @@ -218,7 +226,8 @@ def init(request) protocolVersion: configuration.protocol_version, capabilities: capabilities, serverInfo: server_info, - } + instructions: instructions, + }.compact end def list_tools(request) diff --git a/test/mcp/server_test.rb b/test/mcp/server_test.rb index ef966daa..b4089907 100644 --- a/test/mcp/server_test.rb +++ b/test/mcp/server_test.rb @@ -64,6 +64,7 @@ class ServerTest < ActiveSupport::TestCase @server = Server.new( name: @server_name, version: "1.2.3", + instructions: "Optional instructions for the client", tools: [@tool, @tool_that_raises], prompts: [@prompt], resources: [@resource], @@ -135,6 +136,7 @@ class ServerTest < ActiveSupport::TestCase name: @server_name, version: "1.2.3", }, + instructions: "Optional instructions for the client", }, } @@ -750,6 +752,33 @@ def call(message:, server_context: nil) assert_equal Server::DEFAULT_VERSION, response[:result][:serverInfo][:version] end + test "server uses instructions when not configured" do + server = Server.new(name: "test_server") + request = { + jsonrpc: "2.0", + method: "initialize", + id: 1, + } + + response = server.handle(request) + refute response[:result].key?(:instructions) + end + + test "server uses instructions when configured with protocol version 2025-03-26" do + configuration = Configuration.new(protocol_version: "2025-03-26") + server = Server.new(name: "test_server", instructions: "The server instructions.", configuration: configuration) + assert_equal("The server instructions.", server.instructions) + end + + test "raises error if instructions are used with protocol version 2024-11-05" do + configuration = Configuration.new(protocol_version: "2024-11-05") + + exception = assert_raises(ArgumentError) do + Server.new(name: "test_server", instructions: "The server instructions.", configuration: configuration) + end + assert_equal("`instructions` supported by protocol version 2025-03-26 or higher", exception.message) + end + test "#define_tool adds a tool to the server" do @server.define_tool( name: "defined_tool",