Skip to content

Commit 6236033

Browse files
Merge pull request #109 from jdnvn/main
Add title to tools, prompts and resources
2 parents 002df2c + 8b40854 commit 6236033

File tree

12 files changed

+94
-40
lines changed

12 files changed

+94
-40
lines changed

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ This gem provides a `MCP::Tool` class that can be used to create tools in two wa
373373

374374
```ruby
375375
class MyTool < MCP::Tool
376+
title "My Tool"
376377
description "This tool performs specific functionality..."
377378
input_schema(
378379
properties: {
@@ -381,7 +382,6 @@ class MyTool < MCP::Tool
381382
required: ["message"]
382383
)
383384
annotations(
384-
title: "My Tool",
385385
read_only_hint: true,
386386
destructive_hint: false,
387387
idempotent_hint: true,
@@ -401,9 +401,9 @@ tool = MyTool
401401
```ruby
402402
tool = MCP::Tool.define(
403403
name: "my_tool",
404+
title: "My Tool",
404405
description: "This tool performs specific functionality...",
405406
annotations: {
406-
title: "My Tool",
407407
read_only_hint: true
408408
}
409409
) do |args, server_context|
@@ -437,6 +437,7 @@ The `MCP::Prompt` class provides two ways to create prompts:
437437
```ruby
438438
class MyPrompt < MCP::Prompt
439439
prompt_name "my_prompt" # Optional - defaults to underscored class name
440+
title "My Prompt"
440441
description "This prompt performs specific functionality..."
441442
arguments [
442443
MCP::Prompt::Argument.new(
@@ -473,6 +474,7 @@ prompt = MyPrompt
473474
```ruby
474475
prompt = MCP::Prompt.define(
475476
name: "my_prompt",
477+
title: "My Prompt",
476478
description: "This prompt performs specific functionality...",
477479
arguments: [
478480
MCP::Prompt::Argument.new(
@@ -558,7 +560,8 @@ The `MCP::Resource` class provides a way to register resources with the server.
558560
```ruby
559561
resource = MCP::Resource.new(
560562
uri: "https://example.com/my_resource",
561-
name: "My Resource",
563+
name: "my-resource",
564+
title: "My Resource",
562565
description: "Lorem ipsum dolor sit amet",
563566
mime_type: "text/html",
564567
)

examples/http_server.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ def template(args, server_context:)
6262
resources: [
6363
MCP::Resource.new(
6464
uri: "https://test_resource.invalid",
65-
name: "Test resource",
65+
name: "test-resource",
66+
title: "Test Resource",
6667
description: "Test resource that echoes back the uri as its content",
6768
mime_type: "text/plain",
6869
),

examples/stdio_server.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ def template(args, server_context:)
5959
resources: [
6060
MCP::Resource.new(
6161
uri: "https://test_resource.invalid",
62-
name: "Test resource",
62+
name: "test-resource",
63+
title: "Test Resource",
6364
description: "Test resource that echoes back the uri as its content",
6465
mime_type: "text/plain",
6566
),

lib/mcp/prompt.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class Prompt
66
class << self
77
NOT_SET = Object.new
88

9+
attr_reader :title_value
910
attr_reader :description_value
1011
attr_reader :arguments_value
1112

@@ -14,12 +15,13 @@ def template(args, server_context: nil)
1415
end
1516

1617
def to_h
17-
{ name: name_value, description: description_value, arguments: arguments_value.map(&:to_h) }.compact
18+
{ name: name_value, title: title_value, description: description_value, arguments: arguments_value.map(&:to_h) }.compact
1819
end
1920

2021
def inherited(subclass)
2122
super
2223
subclass.instance_variable_set(:@name_value, nil)
24+
subclass.instance_variable_set(:@title_value, nil)
2325
subclass.instance_variable_set(:@description_value, nil)
2426
subclass.instance_variable_set(:@arguments_value, nil)
2527
end
@@ -36,6 +38,14 @@ def name_value
3638
@name_value || StringUtils.handle_from_class_name(name)
3739
end
3840

41+
def title(value = NOT_SET)
42+
if value == NOT_SET
43+
@title_value
44+
else
45+
@title_value = value
46+
end
47+
end
48+
3949
def description(value = NOT_SET)
4050
if value == NOT_SET
4151
@description_value
@@ -52,9 +62,10 @@ def arguments(value = NOT_SET)
5262
end
5363
end
5464

55-
def define(name: nil, description: nil, arguments: [], &block)
65+
def define(name: nil, title: nil, description: nil, arguments: [], &block)
5666
Class.new(self) do
5767
prompt_name name
68+
title title
5869
description description
5970
arguments arguments
6071
define_singleton_method(:template) do |args, server_context: nil|

lib/mcp/resource.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,23 @@
33

44
module MCP
55
class Resource
6-
attr_reader :uri, :name, :description, :mime_type
6+
attr_reader :uri, :name, :title, :description, :mime_type
77

8-
def initialize(uri:, name:, description: nil, mime_type: nil)
8+
def initialize(uri:, name:, title: nil, description: nil, mime_type: nil)
99
@uri = uri
1010
@name = name
11+
@title = title
1112
@description = description
1213
@mime_type = mime_type
1314
end
1415

1516
def to_h
1617
{
17-
uri: @uri,
18-
name: @name,
19-
description: @description,
20-
mimeType: @mime_type,
18+
uri: uri,
19+
name: name,
20+
title: title,
21+
description: description,
22+
mimeType: mime_type,
2123
}.compact
2224
end
2325
end

lib/mcp/resource_template.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,23 @@
33

44
module MCP
55
class ResourceTemplate
6-
attr_reader :uri_template, :name, :description, :mime_type
6+
attr_reader :uri_template, :name, :title, :description, :mime_type
77

8-
def initialize(uri_template:, name:, description: nil, mime_type: nil)
8+
def initialize(uri_template:, name:, title: nil, description: nil, mime_type: nil)
99
@uri_template = uri_template
1010
@name = name
11+
@title = title
1112
@description = description
1213
@mime_type = mime_type
1314
end
1415

1516
def to_h
1617
{
17-
uriTemplate: @uri_template,
18-
name: @name,
19-
description: @description,
20-
mimeType: @mime_type,
18+
uriTemplate: uri_template,
19+
name: name,
20+
title: title,
21+
description: description,
22+
mimeType: mime_type,
2123
}.compact
2224
end
2325
end

lib/mcp/server.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,13 @@ def handle_json(request)
9696
end
9797
end
9898

99-
def define_tool(name: nil, description: nil, input_schema: nil, annotations: nil, &block)
100-
tool = Tool.define(name:, description:, input_schema:, annotations:, &block)
99+
def define_tool(name: nil, title: nil, description: nil, input_schema: nil, annotations: nil, &block)
100+
tool = Tool.define(name:, title:, description:, input_schema:, annotations:, &block)
101101
@tools[tool.name_value] = tool
102102
end
103103

104-
def define_prompt(name: nil, description: nil, arguments: [], &block)
105-
prompt = Prompt.define(name:, description:, arguments:, &block)
104+
def define_prompt(name: nil, title: nil, description: nil, arguments: [], &block)
105+
prompt = Prompt.define(name:, title:, description:, arguments:, &block)
106106
@prompts[prompt.name_value] = prompt
107107
end
108108

lib/mcp/tool.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ class Tool
55
class << self
66
NOT_SET = Object.new
77

8+
attr_reader :title_value
89
attr_reader :description_value
910
attr_reader :annotations_value
1011

@@ -15,6 +16,7 @@ def call(*args, server_context: nil)
1516
def to_h
1617
result = {
1718
name: name_value,
19+
title: title_value,
1820
description: description_value,
1921
inputSchema: input_schema_value.to_h,
2022
}
@@ -25,6 +27,7 @@ def to_h
2527
def inherited(subclass)
2628
super
2729
subclass.instance_variable_set(:@name_value, nil)
30+
subclass.instance_variable_set(:@title_value, nil)
2831
subclass.instance_variable_set(:@description_value, nil)
2932
subclass.instance_variable_set(:@input_schema_value, nil)
3033
subclass.instance_variable_set(:@annotations_value, nil)
@@ -46,6 +49,14 @@ def input_schema_value
4649
@input_schema_value || InputSchema.new
4750
end
4851

52+
def title(value = NOT_SET)
53+
if value == NOT_SET
54+
@title_value
55+
else
56+
@title_value = value
57+
end
58+
end
59+
4960
def description(value = NOT_SET)
5061
if value == NOT_SET
5162
@description_value
@@ -74,9 +85,10 @@ def annotations(hash = NOT_SET)
7485
end
7586
end
7687

77-
def define(name: nil, description: nil, input_schema: nil, annotations: nil, &block)
88+
def define(name: nil, title: nil, description: nil, input_schema: nil, annotations: nil, &block)
7889
Class.new(self) do
7990
tool_name name
91+
title title
8092
description description
8193
input_schema input_schema
8294
self.annotations(annotations) if annotations

test/mcp/prompt_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ def template(args, server_context:)
111111
test ".define allows definition of simple prompts with a block" do
112112
prompt = Prompt.define(
113113
name: "mock_prompt",
114+
title: "Mock Prompt",
114115
description: "a mock prompt for testing",
115116
arguments: [
116117
Prompt::Argument.new(name: "test_argument", description: "Test argument", required: true),

test/mcp/server/transports/stdio_notification_integration_test.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ def puts(message)
226226
@server.resources = [
227227
MCP::Resource.new(
228228
uri: "https://test_resource.invalid",
229-
name: "Test Resource",
229+
name: "test-resource",
230+
title: "Test Resource",
230231
description: "A test resource",
231232
mime_type: "text/plain",
232233
),

0 commit comments

Comments
 (0)