mcp 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +13 -0
- data/lib/mcp/client.rb +1 -0
- data/lib/mcp/configuration.rb +22 -1
- data/lib/mcp/server.rb +13 -3
- data/lib/mcp/tool/schema.rb +22 -4
- data/lib/mcp/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5b7c0c225e89be4cfc9c73a0707b8a6a61d0d76a8a21340b20b3dd276f36eec6
|
|
4
|
+
data.tar.gz: fdd1b11cbe6ac733820bc604f72c95c6f0aa67162776c8778de7adb04aa7ca39
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c6dce7fe76f5f3996c9f5caffe884237147c74840d4d68dce5ec6ec24be49e65e0eea39306c2c52353c5014c8247295491b3337e166cec662eca19742565d741
|
|
7
|
+
data.tar.gz: b944ae1938952c5e4fd20fb4b5d1ade071cf5ffa193b6c0cd56ba25e79aa583e2de38804045ce0d038eb2e38b5ea5bed4fd6b6073a16fea8bdba02f7e1e8b148
|
data/README.md
CHANGED
|
@@ -645,6 +645,19 @@ MCP spec for the [Output Schema](https://modelcontextprotocol.io/specification/l
|
|
|
645
645
|
|
|
646
646
|
The output schema follows standard JSON Schema format and helps ensure consistent data exchange between MCP servers and clients.
|
|
647
647
|
|
|
648
|
+
By default, server-side validation of tool results against `output_schema` is disabled for backwards compatibility. To validate successful tool responses, enable `validate_tool_call_results`:
|
|
649
|
+
|
|
650
|
+
```ruby
|
|
651
|
+
configuration = MCP::Configuration.new(validate_tool_call_results: true)
|
|
652
|
+
server = MCP::Server.new(
|
|
653
|
+
name: "example_server",
|
|
654
|
+
tools: [WeatherTool],
|
|
655
|
+
configuration: configuration
|
|
656
|
+
)
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
When enabled, successful tool responses for tools with an `output_schema` must include `structured_content` that conforms to the schema. Error responses are not validated against the output schema.
|
|
660
|
+
|
|
648
661
|
### Tool Responses with Structured Content
|
|
649
662
|
|
|
650
663
|
Tools can return structured data alongside text content using the `structured_content` parameter.
|
data/lib/mcp/client.rb
CHANGED
data/lib/mcp/configuration.rb
CHANGED
|
@@ -16,7 +16,7 @@ module MCP
|
|
|
16
16
|
attr_writer :instrumentation_callback
|
|
17
17
|
|
|
18
18
|
def initialize(exception_reporter: nil, around_request: nil, instrumentation_callback: nil, protocol_version: nil,
|
|
19
|
-
validate_tool_call_arguments: true)
|
|
19
|
+
validate_tool_call_arguments: true, validate_tool_call_results: false)
|
|
20
20
|
@exception_reporter = exception_reporter
|
|
21
21
|
@around_request = around_request
|
|
22
22
|
@instrumentation_callback = instrumentation_callback
|
|
@@ -25,8 +25,10 @@ module MCP
|
|
|
25
25
|
validate_protocol_version!(protocol_version)
|
|
26
26
|
end
|
|
27
27
|
validate_value_of_validate_tool_call_arguments!(validate_tool_call_arguments)
|
|
28
|
+
validate_value_of_validate_tool_call_results!(validate_tool_call_results)
|
|
28
29
|
|
|
29
30
|
@validate_tool_call_arguments = validate_tool_call_arguments
|
|
31
|
+
@validate_tool_call_results = validate_tool_call_results
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def protocol_version=(protocol_version)
|
|
@@ -41,6 +43,12 @@ module MCP
|
|
|
41
43
|
@validate_tool_call_arguments = validate_tool_call_arguments
|
|
42
44
|
end
|
|
43
45
|
|
|
46
|
+
def validate_tool_call_results=(validate_tool_call_results)
|
|
47
|
+
validate_value_of_validate_tool_call_results!(validate_tool_call_results)
|
|
48
|
+
|
|
49
|
+
@validate_tool_call_results = validate_tool_call_results
|
|
50
|
+
end
|
|
51
|
+
|
|
44
52
|
def protocol_version
|
|
45
53
|
@protocol_version || LATEST_STABLE_PROTOCOL_VERSION
|
|
46
54
|
end
|
|
@@ -80,11 +88,16 @@ module MCP
|
|
|
80
88
|
end
|
|
81
89
|
|
|
82
90
|
attr_reader :validate_tool_call_arguments
|
|
91
|
+
attr_reader :validate_tool_call_results
|
|
83
92
|
|
|
84
93
|
def validate_tool_call_arguments?
|
|
85
94
|
!!@validate_tool_call_arguments
|
|
86
95
|
end
|
|
87
96
|
|
|
97
|
+
def validate_tool_call_results?
|
|
98
|
+
!!@validate_tool_call_results
|
|
99
|
+
end
|
|
100
|
+
|
|
88
101
|
def merge(other)
|
|
89
102
|
return self if other.nil?
|
|
90
103
|
|
|
@@ -113,6 +126,7 @@ module MCP
|
|
|
113
126
|
end
|
|
114
127
|
|
|
115
128
|
validate_tool_call_arguments = other.validate_tool_call_arguments
|
|
129
|
+
validate_tool_call_results = other.validate_tool_call_results
|
|
116
130
|
|
|
117
131
|
Configuration.new(
|
|
118
132
|
exception_reporter: exception_reporter,
|
|
@@ -120,6 +134,7 @@ module MCP
|
|
|
120
134
|
instrumentation_callback: instrumentation_callback,
|
|
121
135
|
protocol_version: protocol_version,
|
|
122
136
|
validate_tool_call_arguments: validate_tool_call_arguments,
|
|
137
|
+
validate_tool_call_results: validate_tool_call_results,
|
|
123
138
|
)
|
|
124
139
|
end
|
|
125
140
|
|
|
@@ -138,6 +153,12 @@ module MCP
|
|
|
138
153
|
end
|
|
139
154
|
end
|
|
140
155
|
|
|
156
|
+
def validate_value_of_validate_tool_call_results!(validate_tool_call_results)
|
|
157
|
+
unless validate_tool_call_results.is_a?(TrueClass) || validate_tool_call_results.is_a?(FalseClass)
|
|
158
|
+
raise ArgumentError, "validate_tool_call_results must be a boolean"
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
141
162
|
def default_exception_reporter
|
|
142
163
|
@default_exception_reporter ||= ->(exception, server_context) {}
|
|
143
164
|
end
|
data/lib/mcp/server.rb
CHANGED
|
@@ -162,8 +162,8 @@ module MCP
|
|
|
162
162
|
end
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
-
def define_tool(name: nil, title: nil, description: nil, input_schema: nil, annotations: nil, meta: nil, &block)
|
|
166
|
-
tool = Tool.define(name: name, title: title, description: description, input_schema: input_schema, annotations: annotations, meta: meta, &block)
|
|
165
|
+
def define_tool(name: nil, title: nil, description: nil, input_schema: nil, output_schema: nil, annotations: nil, meta: nil, &block)
|
|
166
|
+
tool = Tool.define(name: name, title: title, description: description, input_schema: input_schema, output_schema: output_schema, annotations: annotations, meta: meta, &block)
|
|
167
167
|
tool_name = tool.name_value
|
|
168
168
|
|
|
169
169
|
@tool_names << tool_name
|
|
@@ -586,9 +586,11 @@ module MCP
|
|
|
586
586
|
|
|
587
587
|
progress_token = request.dig(:_meta, :progressToken)
|
|
588
588
|
|
|
589
|
-
call_tool_with_args(
|
|
589
|
+
result = call_tool_with_args(
|
|
590
590
|
tool, arguments, server_context_with_meta(request), progress_token: progress_token, session: session, related_request_id: related_request_id, cancellation: cancellation
|
|
591
591
|
)
|
|
592
|
+
validate_tool_call_result!(tool, result)
|
|
593
|
+
result
|
|
592
594
|
rescue RequestHandlerError, CancelledError
|
|
593
595
|
# CancelledError is intentionally not wrapped so `handle_request` can turn it into
|
|
594
596
|
# `JsonRpcHandler::NO_RESPONSE` per the MCP cancellation spec.
|
|
@@ -745,6 +747,14 @@ module MCP
|
|
|
745
747
|
).to_h
|
|
746
748
|
end
|
|
747
749
|
|
|
750
|
+
def validate_tool_call_result!(tool, result)
|
|
751
|
+
return unless configuration.validate_tool_call_results
|
|
752
|
+
return unless tool.output_schema
|
|
753
|
+
return if result[:isError]
|
|
754
|
+
|
|
755
|
+
tool.output_schema.validate_result(result[:structuredContent])
|
|
756
|
+
end
|
|
757
|
+
|
|
748
758
|
# Whether a tool/prompt handler opts in to receiving an `MCP::ServerContext`.
|
|
749
759
|
# Recognizes `:keyrest` (`**kwargs`) because tools are invoked without a positional argument
|
|
750
760
|
# (`tool.call(**args, server_context:)`), soa `**kwargs`-only signature safely captures `server_context:`.
|
data/lib/mcp/tool/schema.rb
CHANGED
|
@@ -5,6 +5,12 @@ require "json-schema"
|
|
|
5
5
|
module MCP
|
|
6
6
|
class Tool
|
|
7
7
|
class Schema
|
|
8
|
+
# JSON Schema 2020-12 is the default dialect for MCP schema definitions
|
|
9
|
+
# per MCP 2025-11-25 (SEP-1613). Note: emission only — runtime validation
|
|
10
|
+
# is still performed against the JSON Schema draft-04 metaschema because
|
|
11
|
+
# the `json-schema` gem does not yet support 2020-12.
|
|
12
|
+
JSON_SCHEMA_2020_12_URI = "https://json-schema.org/draft/2020-12/schema"
|
|
13
|
+
|
|
8
14
|
attr_reader :schema
|
|
9
15
|
|
|
10
16
|
def initialize(schema = {})
|
|
@@ -18,17 +24,18 @@ module MCP
|
|
|
18
24
|
end
|
|
19
25
|
|
|
20
26
|
def to_h
|
|
21
|
-
@schema
|
|
27
|
+
return @schema if @schema.key?(:"$schema")
|
|
28
|
+
|
|
29
|
+
{ "$schema": JSON_SCHEMA_2020_12_URI }.merge(@schema)
|
|
22
30
|
end
|
|
23
31
|
|
|
24
32
|
private
|
|
25
33
|
|
|
26
34
|
def fully_validate(data)
|
|
27
|
-
JSON::Validator.fully_validate(
|
|
35
|
+
JSON::Validator.fully_validate(schema_for_validation, data)
|
|
28
36
|
end
|
|
29
37
|
|
|
30
38
|
def validate_schema!
|
|
31
|
-
schema = to_h
|
|
32
39
|
gem_path = File.realpath(Gem.loaded_specs["json-schema"].full_gem_path)
|
|
33
40
|
schema_reader = JSON::Schema::Reader.new(
|
|
34
41
|
accept_uri: false,
|
|
@@ -38,11 +45,22 @@ module MCP
|
|
|
38
45
|
# Converts metaschema to a file URI for cross-platform compatibility
|
|
39
46
|
metaschema_uri = JSON::Util::URI.file_uri(metaschema_path.expand_path.cleanpath.to_s.tr("\\", "/"))
|
|
40
47
|
metaschema = metaschema_uri.to_s
|
|
41
|
-
errors = JSON::Validator.fully_validate(metaschema,
|
|
48
|
+
errors = JSON::Validator.fully_validate(metaschema, schema_for_validation, schema_reader: schema_reader)
|
|
42
49
|
if errors.any?
|
|
43
50
|
raise ArgumentError, "Invalid JSON Schema: #{errors.join(", ")}"
|
|
44
51
|
end
|
|
45
52
|
end
|
|
53
|
+
|
|
54
|
+
# The `json-schema` gem's draft-04 validator cannot resolve newer or unknown `$schema`
|
|
55
|
+
# dialect URIs. Strip the top-level `$schema` before validation so a dialect URI
|
|
56
|
+
# (whether SDK-injected by `to_h` or user-supplied) does not break the validator.
|
|
57
|
+
def schema_for_validation
|
|
58
|
+
return @schema unless @schema.key?(:"$schema")
|
|
59
|
+
|
|
60
|
+
copy = @schema.dup
|
|
61
|
+
copy.delete(:"$schema")
|
|
62
|
+
copy
|
|
63
|
+
end
|
|
46
64
|
end
|
|
47
65
|
end
|
|
48
66
|
end
|
data/lib/mcp/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mcp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.16.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Model Context Protocol
|
|
@@ -81,7 +81,7 @@ licenses:
|
|
|
81
81
|
- Apache-2.0
|
|
82
82
|
metadata:
|
|
83
83
|
allowed_push_host: https://rubygems.org
|
|
84
|
-
changelog_uri: https://github.com/modelcontextprotocol/ruby-sdk/releases/tag/v0.
|
|
84
|
+
changelog_uri: https://github.com/modelcontextprotocol/ruby-sdk/releases/tag/v0.16.0
|
|
85
85
|
homepage_uri: https://ruby.sdk.modelcontextprotocol.io
|
|
86
86
|
source_code_uri: https://github.com/modelcontextprotocol/ruby-sdk
|
|
87
87
|
bug_tracker_uri: https://github.com/modelcontextprotocol/ruby-sdk/issues
|
|
@@ -100,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
100
100
|
- !ruby/object:Gem::Version
|
|
101
101
|
version: '0'
|
|
102
102
|
requirements: []
|
|
103
|
-
rubygems_version: 4.0.
|
|
103
|
+
rubygems_version: 4.0.10
|
|
104
104
|
specification_version: 4
|
|
105
105
|
summary: The official Ruby SDK for Model Context Protocol servers and clients
|
|
106
106
|
test_files: []
|