active_mcp 0.9.3 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: faf657746457a11ca96f625b591bfbf82a9e2fe0f89e63629fd9402b14b414af
4
- data.tar.gz: 4b457a166d61a70751546a2c30a77d4d650e4ed018f4d2e7225a9fad77a4cbaa
3
+ metadata.gz: 40c074a297950ebddab382dabdb7e373e3aeebf5e11017bd40f6dea597ca7215
4
+ data.tar.gz: 72ac9984228f99aa5a787e09af86b144a1f66837b1eadb38c6b857be8d455416
5
5
  SHA512:
6
- metadata.gz: e46fa704ad3ec0a901c506c15616f82cf54de6614fd9dba1433cdbe8948e8901c9baa540ed1b0472f76c80eb3547b676cbad9ae8de4e9f17f06a4e5b235c9eff
7
- data.tar.gz: be0fc4c8a010d6be63efd0985ab256c685a1e2325b9eb1d35dd6bd84c021f0b960e6bba38dc57567b0079d346e68559930a3a5b24797b3c6fa02e42896fff7bf
6
+ metadata.gz: 984057ffb2c91a788e0c69e19101a98aae9a6b526471e346cb4fc5151f0a978aaa454eb1ab6ed4e4c9e598c55e074027212214e19c37187c288a2d35621a84c5
7
+ data.tar.gz: c046c53ec3523d3f800fbd8350fe44233ddd13218ff72022f5367e0b15062774e40de789644f609a56cc5e1e163f9a1d8ceb80d915d695dd96fec183f1bd9857
data/README.md CHANGED
@@ -95,7 +95,7 @@ $ rails generate active_mcp:tool create_note
95
95
  ```ruby
96
96
  class CreateNoteTool < ActiveMcp::Tool::Base
97
97
  def tool_name
98
- "Create Note"
98
+ "create_note"
99
99
  end
100
100
 
101
101
  def description
@@ -117,7 +117,11 @@ end
117
117
 
118
118
  ```ruby
119
119
  class MySchema < ActiveMcp::Schema::Base
120
- tool CreateNoteTool.new
120
+ def tools
121
+ [
122
+ CreateNoteTool.new
123
+ ]
124
+ end
121
125
  end
122
126
  ```
123
127
 
@@ -125,6 +129,9 @@ end
125
129
 
126
130
  ```ruby
127
131
  class MyMcpController < ActiveMcp::BaseController
132
+
133
+ private
134
+
128
135
  def schema
129
136
  MySchema.new(context:)
130
137
  end
@@ -271,7 +278,7 @@ Control access to tools by overriding the `visible?` class method:
271
278
  ```ruby
272
279
  class AdminOnlyTool < ActiveMcp::Tool::Base
273
280
  def tool_name
274
- "Admin-only tool"
281
+ "admin_only_tool"
275
282
  end
276
283
 
277
284
  def description
@@ -380,8 +387,10 @@ end
380
387
 
381
388
  ```ruby
382
389
  class MySchema < ActiveMcp::Schema::Base
383
- User.all.each do |user|
384
- resource UserResource.new(id: user.id)
390
+ def resources
391
+ User.all.each do |user|
392
+ UserResource.new(id: user.id)
393
+ end
385
394
  end
386
395
  end
387
396
  ```
@@ -500,8 +509,10 @@ end
500
509
 
501
510
  ```ruby
502
511
  class MySchema < ActiveMcp::Schema::Base
503
- User.all.each do |user|
504
- resource UserResource.new(id: user.id)
512
+ def resources
513
+ User.all.each do |user|
514
+ UserResource.new(id: user.id)
515
+ end
505
516
  end
506
517
  end
507
518
  ```
@@ -516,33 +527,31 @@ Resources are Ruby classes `**Prompt`:
516
527
 
517
528
  ```ruby
518
529
  class HelloPrompt < ActiveMcp::Prompt::Base
519
- class << self
520
- def prompt_name
521
- "hello"
522
- end
530
+ argument :name, ->(value) do
531
+ User.all.pluck(:name).filter { _1.match(value) }
532
+ end
523
533
 
524
- def description
525
- "This is a test."
526
- end
534
+ def initialize(greeting:)
535
+ @greeting = greeting
536
+ end
527
537
 
528
- def visible?(context:)
529
- # Your logic...
530
- end
538
+ def prompt_name
539
+ "hello"
531
540
  end
532
541
 
533
- argument :name, ->(value) do
534
- User.all.pluck(:name).filter { _1.match(value) }
542
+ def description
543
+ "This is a test."
535
544
  end
536
545
 
537
- def initialize(name:)
538
- @name = name
546
+ def visible?(context:)
547
+ # Your logic...
539
548
  end
540
549
 
541
- def messages
550
+ def messages(name:)
542
551
  [
543
552
  ActiveMcp::Message::Text.new(
544
553
  role: "user",
545
- text: "Hello! #{@name}"
554
+ text: "#{@greeting} #{name}"
546
555
  ),
547
556
  ActiveMcp::Message::Image.new(
548
557
  role: "assistant",
@@ -565,7 +574,11 @@ end
565
574
 
566
575
  ```ruby
567
576
  class MySchema < ActiveMcp::Schema::Base
568
- prompt HelloPrompt
577
+ def prompts
578
+ [
579
+ HelloPrompt.new(greeting: "Hello!")
580
+ ]
581
+ end
569
582
  end
570
583
  ```
571
584
 
@@ -624,7 +637,7 @@ end
624
637
 
625
638
  ## 🧪 Development
626
639
 
627
- After checking out the repo, run `bundle install` to install dependencies. Then, run `bundle exec rake` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
640
+ After checking out the repo, run `bundle install` to install dependencies. Then, run `bundle exec rake` to run the tests.
628
641
 
629
642
  ## 👥 Contributing
630
643
 
@@ -21,11 +21,11 @@ module ActiveMcp
21
21
  when Method::CANCELLED
22
22
  render "active_mcp/cancelled", formats: :json
23
23
  when Method::RESOURCES_LIST
24
- @resources = schema.resources
24
+ @resources = schema.visible_resources
25
25
  @format = :jsonrpc
26
26
  render "active_mcp/resources_list", formats: :json
27
27
  when Method::RESOURCES_TEMPLATES_LIST
28
- @resource_templates = schema.resource_templates
28
+ @resource_templates = schema.visible_resource_templates
29
29
  @format = :jsonrpc
30
30
  render "active_mcp/resource_templates_list", formats: :json
31
31
  when Method::RESOURCES_READ
@@ -33,7 +33,7 @@ module ActiveMcp
33
33
  @format = :jsonrpc
34
34
  render "active_mcp/resources_read", formats: :json
35
35
  when Method::TOOLS_LIST
36
- @tools = schema.tools
36
+ @tools = schema.visible_tools
37
37
  @format = :jsonrpc
38
38
  render "active_mcp/tools_list", formats: :json
39
39
  when Method::TOOLS_CALL
@@ -42,15 +42,15 @@ module ActiveMcp
42
42
  render "active_mcp/tools_call", formats: :json
43
43
  when Method::COMPLETION_COMPLETE
44
44
  type = params.dig(:params, :ref, :type)
45
- @completion = ActiveMcp::Completion.new.complete(params: params[:params], context:, refs: (type === "ref/resource") ? schema.resource_templates : schema.prompts)
45
+ @completion = ActiveMcp::Completion.new.complete(params: params[:params], context:, refs: (type === "ref/resource") ? schema.visible_resource_templates : schema.visible_prompts)
46
46
  @format = :jsonrpc
47
47
  render "active_mcp/completion_complete", formats: :json
48
48
  when Method::PROMPTS_LIST
49
- @prompts = schema.prompts
49
+ @prompts = schema.visible_prompts
50
50
  @format = :jsonrpc
51
51
  render "active_mcp/prompts_list", formats: :json
52
52
  when Method::PROMPTS_GET
53
- @prompt = schema.prompts.find { _1.prompt_name == params[:params][:name] }.new(**params[:params][:arguments].permit!.to_h.symbolize_keys)
53
+ @prompt = schema.visible_prompts.find { _1.prompt_name == params[:params][:name] }
54
54
  @format = :jsonrpc
55
55
  render "active_mcp/prompts_get", formats: :json
56
56
  else
@@ -62,7 +62,7 @@ module ActiveMcp
62
62
  def handle_mcp_server_request
63
63
  case params[:method]
64
64
  when Method::RESOURCES_LIST
65
- @resources = schema.resources
65
+ @resources = schema.visible_resources
66
66
  @format = :json
67
67
  render "active_mcp/resources_list", formats: :json
68
68
  when Method::RESOURCES_READ
@@ -70,11 +70,11 @@ module ActiveMcp
70
70
  @format = :json
71
71
  render "active_mcp/resources_read", formats: :json
72
72
  when Method::RESOURCES_TEMPLATES_LIST
73
- @resource_templates = schema.resource_templates
73
+ @resource_templates = schema.visible_resource_templates
74
74
  @format = :json
75
75
  render "active_mcp/resource_templates_list", formats: :json
76
76
  when Method::TOOLS_LIST
77
- @tools = schema.tools
77
+ @tools = schema.visible_tools
78
78
  @format = :json
79
79
  render "active_mcp/tools_list", formats: :json
80
80
  when Method::TOOLS_CALL
@@ -83,15 +83,15 @@ module ActiveMcp
83
83
  render "active_mcp/tools_call", formats: :json
84
84
  when Method::COMPLETION_COMPLETE
85
85
  type = params.dig(:params, :ref, :type)
86
- @completion = ActiveMcp::Completion.new.complete(params: params[:params], context:, refs: (type == "ref/resource") ? schema.resource_templates : schema.prompts)
86
+ @completion = ActiveMcp::Completion.new.complete(params: params[:params], context:, refs: (type == "ref/resource") ? schema.visible_resource_templates : schema.visible_prompts)
87
87
  @format = :json
88
88
  render "active_mcp/completion_complete", formats: :json
89
89
  when Method::PROMPTS_LIST
90
- @prompts = schema.prompts
90
+ @prompts = schema.visible_prompts
91
91
  @format = :json
92
92
  render "active_mcp/prompts_list", formats: :json
93
93
  when Method::PROMPTS_GET
94
- @prompt = schema.prompts&.find { _1.prompt_name == params[:params][:name] }&.new(**params[:params][:arguments].permit!.to_h.symbolize_keys)
94
+ @prompt = schema.visible_prompts&.find { _1.prompt_name == params[:params][:name] }
95
95
  @format = :json
96
96
  render "active_mcp/prompts_get", formats: :json
97
97
  else
@@ -18,7 +18,7 @@ module ActiveMcp
18
18
  }
19
19
  end
20
20
 
21
- resource = schema.resources.find do |r|
21
+ resource = schema.visible_resources.find do |r|
22
22
  r.uri == uri
23
23
  end
24
24
 
@@ -25,7 +25,7 @@ module ActiveMcp
25
25
  }
26
26
  end
27
27
 
28
- tool = schema.tools.find do |tc|
28
+ tool = schema.visible_tools.find do |tc|
29
29
  tc.tool_name == tool_name
30
30
  end
31
31
 
@@ -2,6 +2,6 @@ json.jsonrpc ActiveMcp::JSON_RPC_VERSION if @format == :jsonrpc
2
2
  json.id @id if @format == :jsonrpc && @id.present?
3
3
 
4
4
  json.result do
5
- json.description @prompt.class.description
6
- json.messages @prompt.messages.map(&:to_h)
5
+ json.description @prompt.description
6
+ json.messages @prompt.messages(**params[:params][:arguments].permit!.to_h.symbolize_keys).map(&:to_h)
7
7
  end
@@ -6,7 +6,7 @@ json.result do
6
6
  json.array!(@prompts) do |prompt|
7
7
  json.name prompt.prompt_name
8
8
  json.description prompt.description
9
- json.arguments prompt.arguments.map { _1.except(:complete) }
9
+ json.arguments prompt.class.arguments.map { _1.except(:complete) }
10
10
  end
11
11
  end
12
12
  end
@@ -1,54 +1,34 @@
1
1
  module ActiveMcp
2
2
  module Schema
3
3
  class Base
4
- class << self
5
- attr_reader :resources, :resource_templates, :tools, :prompts
6
-
7
- def resource(klass)
8
- @resources ||= []
9
- @resources << klass
10
-
11
- if klass.class.respond_to?(:uri_template)
12
- @resource_templates ||= []
13
- @resource_templates << klass.class unless klass.class.in?(@resource_templates)
14
- end
15
- end
16
-
17
- def tool(klass)
18
- @tools ||= []
19
- @tools << klass
20
- end
21
-
22
- def prompt(klass)
23
- @prompts ||= []
24
- @prompts << klass
25
- end
26
- end
4
+ attr_reader :context
27
5
 
28
6
  def initialize(context: {})
29
7
  @context = context
30
8
  end
31
9
 
32
- def resources
33
- self.class.resources&.filter do |resource|
34
- !resource.respond_to?(:visible?) || resource.visible?(context: @context)
10
+ def visible_resources
11
+ resources&.filter do |resource|
12
+ !resource.class.respond_to?(:uri_template) && !resource.respond_to?(:visible?) || resource.visible?(context: @context)
35
13
  end
36
14
  end
37
15
 
38
- def resource_templates
39
- self.class.resource_templates&.filter do |template|
40
- !template.respond_to?(:visible?) || template.visible?(context: @context)
16
+ def visible_resource_templates
17
+ resource_instances = resources&.filter do |resource|
18
+ resource.class.respond_to?(:uri_template) && (!resource.respond_to?(:visible?) || resource.visible?(context: @context))
41
19
  end
20
+
21
+ resource_instances.map(&:class)
42
22
  end
43
23
 
44
- def tools
45
- self.class.tools&.filter do |tool|
24
+ def visible_tools
25
+ tools&.filter do |tool|
46
26
  !tool.respond_to?(:visible?) || tool.visible?(context: @context)
47
27
  end
48
28
  end
49
29
 
50
- def prompts
51
- self.class.prompts&.filter do |resource|
30
+ def visible_prompts
31
+ prompts&.filter do |resource|
52
32
  !resource.respond_to?(:visible?) || resource.visible?(context: @context)
53
33
  end
54
34
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveMcp
2
- VERSION = "0.9.3"
2
+ VERSION = "0.10.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Moeki Kawakami
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-04-08 00:00:00.000000000 Z
11
+ date: 2025-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails