Skip to content

Commit e51e562

Browse files
committed
Add instructions support to MCP::Server
The response of the `init` method can include `instructions`. https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle `instructions` appear to be supported starting from the 2025-03-26 specification. - https://modelcontextprotocol.io/specification/2025-03-26/basic/lifecycle (supports `instructions`) - https://modelcontextprotocol.io/specification/2024-11-05/basic/lifecycle (does not support `instructions`) If `instructions` is used with an unsupported protocol version, an `ArgumentError` will be raised. As additional context, the TypeScript SDK also treats `instructions` as optional. https://github.com/modelcontextprotocol/typescript-sdk/blob/1.16.0/src/types.ts#L356-L361
1 parent 6bace86 commit e51e562

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,11 @@ You can use the `Server#handle_json` method to handle requests.
155155

156156
```ruby
157157
class ApplicationController < ActionController::Base
158-
159158
def index
160159
server = MCP::Server.new(
161160
name: "my_server",
162161
version: "1.0.0",
162+
instructions: "A simple MCP server with custom tools and prompts",
163163
tools: [SomeTool, AnotherTool],
164164
prompts: [MyPrompt],
165165
server_context: { user_id: current_user.id },

lib/mcp/server.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ def initialize(method_name)
3131

3232
include Instrumentation
3333

34-
attr_accessor :name, :version, :tools, :prompts, :resources, :server_context, :configuration, :capabilities, :transport
34+
attr_accessor :name, :version, :instructions, :tools, :prompts, :resources, :server_context, :configuration, :capabilities, :transport
3535

3636
def initialize(
3737
name: "model_context_protocol",
3838
version: DEFAULT_VERSION,
39+
instructions: nil,
3940
tools: [],
4041
prompts: [],
4142
resources: [],
@@ -47,13 +48,19 @@ def initialize(
4748
)
4849
@name = name
4950
@version = version
51+
@instructions = instructions
5052
@tools = tools.to_h { |t| [t.name_value, t] }
5153
@prompts = prompts.to_h { |p| [p.name_value, p] }
5254
@resources = resources
5355
@resource_templates = resource_templates
5456
@resource_index = index_resources_by_uri(resources)
5557
@server_context = server_context
5658
@configuration = MCP.configuration.merge(configuration)
59+
if @configuration.protocol_version == "2024-11-05" && @instructions
60+
message = "`instructions` supported by protocol version 2025-03-26 or higher"
61+
raise ArgumentError, message
62+
end
63+
5764
@capabilities = capabilities || default_capabilities
5865

5966
@handlers = {
@@ -218,7 +225,8 @@ def init(request)
218225
protocolVersion: configuration.protocol_version,
219226
capabilities: capabilities,
220227
serverInfo: server_info,
221-
}
228+
instructions: instructions,
229+
}.compact
222230
end
223231

224232
def list_tools(request)

test/mcp/server_test.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class ServerTest < ActiveSupport::TestCase
5353
@server = Server.new(
5454
name: @server_name,
5555
version: "1.2.3",
56+
instructions: "Optional instructions for the client",
5657
tools: [@tool, @tool_that_raises],
5758
prompts: [@prompt],
5859
resources: [@resource],
@@ -124,6 +125,7 @@ class ServerTest < ActiveSupport::TestCase
124125
name: @server_name,
125126
version: "1.2.3",
126127
},
128+
instructions: "Optional instructions for the client",
127129
},
128130
}
129131

@@ -739,6 +741,33 @@ def call(message:, server_context: nil)
739741
assert_equal Server::DEFAULT_VERSION, response[:result][:serverInfo][:version]
740742
end
741743

744+
test "server uses instructions when not configured" do
745+
server = Server.new(name: "test_server")
746+
request = {
747+
jsonrpc: "2.0",
748+
method: "initialize",
749+
id: 1,
750+
}
751+
752+
response = server.handle(request)
753+
refute response[:result].key?(:instructions)
754+
end
755+
756+
test "server uses instructions when configured with protocol version 2025-03-26" do
757+
configuration = Configuration.new(protocol_version: "2025-03-26")
758+
server = Server.new(name: "test_server", instructions: "The server instructions.", configuration: configuration)
759+
assert_equal("The server instructions.", server.instructions)
760+
end
761+
762+
test "raises error if instructions are used with protocol version 2024-11-05" do
763+
configuration = Configuration.new(protocol_version: "2024-11-05")
764+
765+
exception = assert_raises(ArgumentError) do
766+
Server.new(name: "test_server", instructions: "The server instructions.", configuration: configuration)
767+
end
768+
assert_equal("`instructions` supported by protocol version 2025-03-26 or higher", exception.message)
769+
end
770+
742771
test "#define_tool adds a tool to the server" do
743772
@server.define_tool(
744773
name: "defined_tool",

0 commit comments

Comments
 (0)