active_mcp 0.5.1 → 0.7.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 +118 -63
- data/app/controllers/active_mcp/base_controller.rb +27 -3
- data/app/controllers/concerns/active_mcp/authenticatable.rb +29 -0
- data/app/controllers/concerns/active_mcp/request_handlable.rb +18 -44
- data/app/controllers/concerns/active_mcp/resource_readable.rb +3 -7
- data/app/controllers/concerns/active_mcp/tool_executable.rb +6 -9
- data/app/views/active_mcp/resource_templates_list.json.jbuilder +24 -0
- data/app/views/active_mcp/tools_list.json.jbuilder +14 -2
- data/lib/active_mcp/controller/base.rb +7 -0
- data/lib/active_mcp/engine.rb +11 -14
- data/lib/active_mcp/schema/base.rb +46 -0
- data/lib/active_mcp/server/fetcher.rb +56 -0
- data/lib/active_mcp/server/method.rb +1 -1
- data/lib/active_mcp/server/protocol_handler.rb +58 -22
- data/lib/active_mcp/server.rb +18 -7
- data/lib/active_mcp/tool/base.rb +52 -0
- data/lib/active_mcp/version.rb +1 -1
- data/lib/active_mcp.rb +3 -1
- data/lib/generators/active_mcp/install/install_generator.rb +3 -7
- data/lib/generators/active_mcp/resource/resource_generator.rb +1 -1
- data/lib/generators/active_mcp/resource/templates/resource.rb.erb +4 -12
- data/lib/generators/active_mcp/tool/templates/tool.rb.erb +15 -9
- data/lib/generators/active_mcp/tool/tool_generator.rb +1 -1
- metadata +7 -4
- data/lib/active_mcp/server/resource_manager.rb +0 -150
- data/lib/active_mcp/server/tool_manager.rb +0 -163
- data/lib/active_mcp/tool.rb +0 -82
data/lib/active_mcp/engine.rb
CHANGED
@@ -2,20 +2,17 @@ module ActiveMcp
|
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
isolate_namespace ActiveMcp
|
4
4
|
|
5
|
-
initializer "active_mcp.
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
if Dir.exist?(tools_path)
|
17
|
-
Dir[tools_path.join("*.rb")].sort.each do |file|
|
18
|
-
require_dependency file
|
5
|
+
initializer "active_mcp.eager_load" do |app|
|
6
|
+
[
|
7
|
+
Rails.root.join("app", "mcp", "tools"),
|
8
|
+
Rails.root.join("app", "mcp", "resources"),
|
9
|
+
Rails.root.join("app", "mcp", "resource_templates"),
|
10
|
+
Rails.root.join("app", "mcp", "schemas")
|
11
|
+
].each do |tools_path|
|
12
|
+
if Dir.exist?(tools_path)
|
13
|
+
Dir[tools_path.join("*.rb")].sort.each do |file|
|
14
|
+
require_dependency file
|
15
|
+
end
|
19
16
|
end
|
20
17
|
end
|
21
18
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ActiveMcp
|
2
|
+
module Schema
|
3
|
+
class Base
|
4
|
+
class << self
|
5
|
+
attr_reader :resources, :resource_templates, :tools
|
6
|
+
|
7
|
+
def resource(klass)
|
8
|
+
@resources ||= []
|
9
|
+
@resources << klass
|
10
|
+
end
|
11
|
+
|
12
|
+
def resource_template(klass)
|
13
|
+
@resource_templates ||= []
|
14
|
+
@resource_templates << klass
|
15
|
+
end
|
16
|
+
|
17
|
+
def tool(klass)
|
18
|
+
@tools ||= []
|
19
|
+
@tools << klass
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(context: {})
|
24
|
+
@context = context
|
25
|
+
end
|
26
|
+
|
27
|
+
def resources
|
28
|
+
self.class.resources.filter do |resource|
|
29
|
+
!resource.respond_to?(:visible?) || resource.visible?(context: @context)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def resource_templates
|
34
|
+
self.class.resource_templates.filter do |tool_resource|
|
35
|
+
!tool_resource.respond_to?(:visible?) || tool_resource.visible?(context: @context)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def tools
|
40
|
+
self.class.tools.filter do |tool|
|
41
|
+
!tool.respond_to?(:visible?) || tool.visible?(context: @context)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module ActiveMcp
|
2
|
+
class Server
|
3
|
+
class Fetcher
|
4
|
+
def initialize(base_uri: nil, auth: nil)
|
5
|
+
@base_uri = base_uri
|
6
|
+
|
7
|
+
if auth
|
8
|
+
@auth_header = "#{auth[:type] == :bearer ? "Bearer" : "Basic"} #{auth[:token]}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(params:)
|
13
|
+
return unless @base_uri
|
14
|
+
|
15
|
+
require "net/http"
|
16
|
+
|
17
|
+
unless @base_uri.is_a?(URI) || @base_uri.is_a?(String)
|
18
|
+
Server.log_error("Invalid URI type", StandardError.new("URI must be a String or URI object"))
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
begin
|
23
|
+
uri = URI.parse(@base_uri.to_s)
|
24
|
+
|
25
|
+
unless uri.scheme =~ /\Ahttps?\z/ && !uri.host.nil?
|
26
|
+
Server.log_error("Invalid URI", StandardError.new("URI must have a valid scheme and host"))
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
if defined?(Rails) && Rails.env.production? && uri.scheme != "https"
|
31
|
+
Server.log_error("HTTPS is required in production environment", StandardError.new("Non-HTTPS URI in production"))
|
32
|
+
return
|
33
|
+
end
|
34
|
+
rescue URI::InvalidURIError => e
|
35
|
+
Server.log_error("Invalid URI format", e)
|
36
|
+
return
|
37
|
+
end
|
38
|
+
|
39
|
+
request = Net::HTTP::Post.new(uri)
|
40
|
+
request.body = JSON.generate(params)
|
41
|
+
request["Content-Type"] = "application/json"
|
42
|
+
request["Authorization"] = @auth_header
|
43
|
+
|
44
|
+
begin
|
45
|
+
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
46
|
+
http.request(request)
|
47
|
+
end
|
48
|
+
|
49
|
+
JSON.parse(response.body, symbolize_names: true)
|
50
|
+
rescue => e
|
51
|
+
Server.log_error("Error fetching resource_templates", e)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -17,10 +17,10 @@ module ActiveMcp
|
|
17
17
|
request = JSON.parse(message, symbolize_names: true)
|
18
18
|
handle_request(request)
|
19
19
|
rescue JSON::ParserError => e
|
20
|
-
log_error("JSON parse error", e)
|
20
|
+
Server.log_error("JSON parse error", e)
|
21
21
|
error_response(nil, ErrorCode::PARSE_ERROR, "Invalid JSON format")
|
22
22
|
rescue => e
|
23
|
-
log_error("Internal error during message processing", e)
|
23
|
+
Server.log_error("Internal error during message processing", e)
|
24
24
|
error_response(nil, ErrorCode::INTERNAL_ERROR, "An internal error occurred")
|
25
25
|
end
|
26
26
|
|
@@ -50,10 +50,12 @@ module ActiveMcp
|
|
50
50
|
handle_ping(request)
|
51
51
|
when Method::RESOURCES_LIST
|
52
52
|
handle_list_resources(request)
|
53
|
+
when Method::RESOURCES_TEMPLATES_LIST
|
54
|
+
handle_list_resource_templates(request)
|
53
55
|
when Method::TOOLS_LIST
|
54
56
|
handle_list_tools(request)
|
55
57
|
when Method::TOOLS_CALL
|
56
|
-
|
58
|
+
handle_call_tool(request)
|
57
59
|
when Method::RESOURCES_READ
|
58
60
|
handle_read_resource(request)
|
59
61
|
else
|
@@ -113,23 +115,63 @@ module ActiveMcp
|
|
113
115
|
end
|
114
116
|
|
115
117
|
def handle_list_resources(request)
|
116
|
-
success_response(
|
118
|
+
success_response(
|
119
|
+
request[:id],
|
120
|
+
{
|
121
|
+
resources: @server.fetch(
|
122
|
+
params: {
|
123
|
+
method: Method::RESOURCES_LIST,
|
124
|
+
arguments: {}
|
125
|
+
}
|
126
|
+
)[:result]
|
127
|
+
}
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
131
|
+
def handle_list_resource_templates(request)
|
132
|
+
success_response(
|
133
|
+
request[:id],
|
134
|
+
{
|
135
|
+
resourceTemplates: @server.fetch(
|
136
|
+
params: {
|
137
|
+
method: Method::RESOURCES_TEMPLATES_LIST,
|
138
|
+
arguments: {}
|
139
|
+
}
|
140
|
+
)[:result]
|
141
|
+
}
|
142
|
+
)
|
117
143
|
end
|
118
144
|
|
119
145
|
def handle_list_tools(request)
|
120
|
-
success_response(
|
146
|
+
success_response(
|
147
|
+
request[:id],
|
148
|
+
{
|
149
|
+
tools: @server.fetch(
|
150
|
+
params: {
|
151
|
+
method: Method::TOOLS_LIST,
|
152
|
+
arguments: {}
|
153
|
+
}
|
154
|
+
)[:result]
|
155
|
+
}
|
156
|
+
)
|
121
157
|
end
|
122
158
|
|
123
|
-
def
|
159
|
+
def handle_call_tool(request)
|
124
160
|
name = request.dig(:params, :name)
|
125
161
|
arguments = request.dig(:params, :arguments) || {}
|
126
162
|
|
127
163
|
begin
|
128
|
-
result = @server.
|
164
|
+
result = @server.fetch(
|
165
|
+
params: {
|
166
|
+
method: Method::TOOLS_CALL,
|
167
|
+
name:,
|
168
|
+
arguments:,
|
169
|
+
}
|
170
|
+
)
|
129
171
|
|
130
172
|
success_response(request[:id], result)
|
131
173
|
rescue => e
|
132
|
-
log_error("Error calling tool #{name}", e)
|
174
|
+
Server.log_error("Error calling tool #{name}", e)
|
133
175
|
error_response(request[:id], ErrorCode::INTERNAL_ERROR, "An error occurred while calling the tool")
|
134
176
|
end
|
135
177
|
end
|
@@ -137,11 +179,17 @@ module ActiveMcp
|
|
137
179
|
def handle_read_resource(request)
|
138
180
|
uri = request.dig(:params, :uri)
|
139
181
|
begin
|
140
|
-
result = @server.
|
182
|
+
result = @server.fetch(
|
183
|
+
params: {
|
184
|
+
method: Method::RESOURCES_READ,
|
185
|
+
uri:,
|
186
|
+
arguments: {},
|
187
|
+
}
|
188
|
+
)
|
141
189
|
|
142
190
|
success_response(request[:id], result)
|
143
191
|
rescue => e
|
144
|
-
|
192
|
+
Server.("Error reading resource #{uri}", e)
|
145
193
|
error_response(request[:id], ErrorCode::INTERNAL_ERROR, "An error occurred while reading the resource")
|
146
194
|
end
|
147
195
|
end
|
@@ -166,18 +214,6 @@ module ActiveMcp
|
|
166
214
|
response[:error][:data] = data if data
|
167
215
|
response
|
168
216
|
end
|
169
|
-
|
170
|
-
def log_error(message, error)
|
171
|
-
error_details = "#{message}: #{error.message}\n"
|
172
|
-
error_details += error.backtrace.join("\n") if error.backtrace
|
173
|
-
|
174
|
-
if defined?(Rails)
|
175
|
-
Rails.logger.error(error_details)
|
176
|
-
else
|
177
|
-
# Fresallback to standard error output if Rails is not available
|
178
|
-
$stderr.puts(error_details)
|
179
|
-
end
|
180
|
-
end
|
181
217
|
end
|
182
218
|
end
|
183
219
|
end
|
data/lib/active_mcp/server.rb
CHANGED
@@ -3,13 +3,12 @@ require "English"
|
|
3
3
|
require_relative "server/method"
|
4
4
|
require_relative "server/error_codes"
|
5
5
|
require_relative "server/stdio_connection"
|
6
|
-
require_relative "server/
|
7
|
-
require_relative "server/tool_manager"
|
6
|
+
require_relative "server/fetcher"
|
8
7
|
require_relative "server/protocol_handler"
|
9
8
|
|
10
9
|
module ActiveMcp
|
11
10
|
class Server
|
12
|
-
attr_reader :name, :version, :uri, :
|
11
|
+
attr_reader :name, :version, :uri, :protocol_handler, :fetcher
|
13
12
|
|
14
13
|
def initialize(
|
15
14
|
version: ActiveMcp::VERSION,
|
@@ -20,11 +19,23 @@ module ActiveMcp
|
|
20
19
|
@name = name
|
21
20
|
@version = version
|
22
21
|
@uri = uri
|
23
|
-
@
|
24
|
-
@tool_manager = ToolManager.new(uri: uri, auth:)
|
22
|
+
@fetcher = Fetcher.new(base_uri: uri, auth:)
|
25
23
|
@protocol_handler = ProtocolHandler.new(self)
|
26
|
-
|
27
|
-
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.log_error(message, error)
|
27
|
+
error_details = "#{message}: #{error.message}\n"
|
28
|
+
error_details += error.backtrace.join("\n") if error.backtrace
|
29
|
+
|
30
|
+
if defined?(Rails)
|
31
|
+
Rails.logger.error(error_details)
|
32
|
+
else
|
33
|
+
$stderr.puts(error_details)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def fetch(params:)
|
38
|
+
@fetcher.call(params:)
|
28
39
|
end
|
29
40
|
|
30
41
|
def start
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "json-schema"
|
2
|
+
|
3
|
+
module ActiveMcp
|
4
|
+
module Tool
|
5
|
+
class Base
|
6
|
+
class << self
|
7
|
+
attr_reader :schema
|
8
|
+
|
9
|
+
def argument(name, type, required: false, description: nil)
|
10
|
+
@schema ||= default_schema
|
11
|
+
|
12
|
+
@schema["properties"][name.to_s] = {"type" => type.to_s}
|
13
|
+
@schema["properties"][name.to_s]["description"] = description if description
|
14
|
+
@schema["required"] << name.to_s if required
|
15
|
+
end
|
16
|
+
|
17
|
+
def default_schema
|
18
|
+
{
|
19
|
+
"type" => "object",
|
20
|
+
"properties" => {},
|
21
|
+
"required" => []
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
end
|
28
|
+
|
29
|
+
def name
|
30
|
+
end
|
31
|
+
|
32
|
+
def description
|
33
|
+
end
|
34
|
+
|
35
|
+
def visible?(context: {})
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
def call(context: {}, **args)
|
40
|
+
raise NotImplementedError, "#{self.class.name}#call must be implemented"
|
41
|
+
end
|
42
|
+
|
43
|
+
def validate_arguments(args)
|
44
|
+
return true unless self.class.schema
|
45
|
+
|
46
|
+
JSON::Validator.validate!(self.class.schema, args)
|
47
|
+
rescue JSON::Schema::ValidationError => e
|
48
|
+
{error: e.message}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/active_mcp/version.rb
CHANGED
data/lib/active_mcp.rb
CHANGED
@@ -3,11 +3,13 @@
|
|
3
3
|
require "jbuilder"
|
4
4
|
require_relative "active_mcp/version"
|
5
5
|
require_relative "active_mcp/configuration"
|
6
|
-
require_relative "active_mcp/
|
6
|
+
require_relative "active_mcp/schema/base"
|
7
|
+
require_relative "active_mcp/tool/base"
|
7
8
|
require_relative "active_mcp/server"
|
8
9
|
|
9
10
|
if defined? ::Rails
|
10
11
|
require_relative "active_mcp/engine"
|
12
|
+
require_relative "active_mcp/controller/base"
|
11
13
|
end
|
12
14
|
|
13
15
|
module ActiveMcp
|
@@ -2,16 +2,12 @@ module ActiveMcp
|
|
2
2
|
module Generators
|
3
3
|
class InstallGenerator < Rails::Generators::Base
|
4
4
|
source_root File.expand_path('templates', __dir__)
|
5
|
-
|
6
|
-
desc "Creates an Active MCP initializer
|
7
|
-
|
5
|
+
|
6
|
+
desc "Creates an Active MCP initializer"
|
7
|
+
|
8
8
|
def create_initializer_file
|
9
9
|
template "initializer.rb", "config/initializers/active_mcp.rb"
|
10
10
|
end
|
11
|
-
|
12
|
-
def update_routes
|
13
|
-
route "mount ActiveMcp::Engine, at: '/mcp'"
|
14
|
-
end
|
15
11
|
end
|
16
12
|
end
|
17
13
|
end
|
@@ -4,7 +4,7 @@ module ActiveMcp
|
|
4
4
|
source_root File.expand_path("templates", __dir__)
|
5
5
|
|
6
6
|
def create_resource_file
|
7
|
-
template "resource.rb.erb", File.join("app/resources", "#{file_name}_resource.rb")
|
7
|
+
template "resource.rb.erb", File.join("app/mcp/resources", "#{file_name}_resource.rb")
|
8
8
|
end
|
9
9
|
|
10
10
|
private
|
@@ -1,12 +1,4 @@
|
|
1
1
|
class <%= class_name %>
|
2
|
-
def initialize(auth_info:)
|
3
|
-
@auth_info = auth_info
|
4
|
-
|
5
|
-
# Authentication information can be accessed via @auth_info parameter
|
6
|
-
# @auth_info = { type: :bearer, token: "xxx", header: "Bearer xxx" }
|
7
|
-
# or { type: :basic, token: "base64encoded", header: "Basic base64encoded" }
|
8
|
-
end
|
9
|
-
|
10
2
|
def name
|
11
3
|
"<%= file_name %>"
|
12
4
|
end
|
@@ -25,16 +17,16 @@ class <%= class_name %>
|
|
25
17
|
|
26
18
|
# Uncomment and modify this method to implement authorization control
|
27
19
|
# This controls who can see and use this tool
|
28
|
-
# def visible?
|
20
|
+
# def visible?(context: {})
|
29
21
|
# # Example: require authentication
|
30
|
-
# # return false unless
|
22
|
+
# # return false unless context
|
31
23
|
#
|
32
24
|
# # Example: require a specific authentication type
|
33
|
-
# # return false unless
|
25
|
+
# # return false unless context[:auth_info][:type] == :bearer
|
34
26
|
#
|
35
27
|
# # Example: check for admin permissions
|
36
28
|
# # admin_tokens = ["admin-token"]
|
37
|
-
# # return admin_tokens.include?(
|
29
|
+
# # return admin_tokens.include?(context[:auth_info][:token])
|
38
30
|
#
|
39
31
|
# # Default: allow all access
|
40
32
|
# true
|
@@ -1,5 +1,11 @@
|
|
1
|
-
class <%= class_name %> < ActiveMcp::Tool
|
2
|
-
|
1
|
+
class <%= class_name %> < ActiveMcp::Tool::Base
|
2
|
+
def name
|
3
|
+
"<%= file_name.humanize %>"
|
4
|
+
end
|
5
|
+
|
6
|
+
def description
|
7
|
+
"<%= file_name.humanize %>"
|
8
|
+
end
|
3
9
|
|
4
10
|
argument :param1, :string, required: true, description: "First parameter description"
|
5
11
|
argument :param2, :string, required: false, description: "Second parameter description"
|
@@ -7,25 +13,25 @@ class <%= class_name %> < ActiveMcp::Tool
|
|
7
13
|
|
8
14
|
# Uncomment and modify this method to implement authorization control
|
9
15
|
# This controls who can see and use this tool
|
10
|
-
# def
|
16
|
+
# def visible?(context: {})
|
11
17
|
# # Example: require authentication
|
12
|
-
# # return false unless
|
18
|
+
# # return false unless context
|
13
19
|
#
|
14
20
|
# # Example: require a specific authentication type
|
15
|
-
# # return false unless auth_info[:type] == :bearer
|
21
|
+
# # return false unless context[:auth_info][:type] == :bearer
|
16
22
|
#
|
17
23
|
# # Example: check for admin permissions
|
18
24
|
# # admin_tokens = ["admin-token"]
|
19
|
-
# # return admin_tokens.include?(auth_info[:token])
|
25
|
+
# # return admin_tokens.include?(context[:auth_info][:token])
|
20
26
|
#
|
21
27
|
# # Default: allow all access
|
22
28
|
# true
|
23
29
|
# end
|
24
30
|
|
25
|
-
def call(param1:, param2: nil,
|
31
|
+
def call(param1:, param2: nil, context: {})
|
26
32
|
# Authentication information can be accessed via _auth_info parameter
|
27
|
-
#
|
28
|
-
# or { type: :basic, token: "base64encoded", header: "Basic base64encoded" }
|
33
|
+
# context = { auth_info: { type: :bearer, token: "xxx", header: "Bearer xxx" } }
|
34
|
+
# or { auth_info: { type: :basic, token: "base64encoded", header: "Basic base64encoded" } }
|
29
35
|
|
30
36
|
# Implement tool logic here
|
31
37
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_mcp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Moeki Kawakami
|
@@ -68,6 +68,7 @@ files:
|
|
68
68
|
- README.md
|
69
69
|
- Rakefile
|
70
70
|
- app/controllers/active_mcp/base_controller.rb
|
71
|
+
- app/controllers/concerns/active_mcp/authenticatable.rb
|
71
72
|
- app/controllers/concerns/active_mcp/request_handlable.rb
|
72
73
|
- app/controllers/concerns/active_mcp/resource_readable.rb
|
73
74
|
- app/controllers/concerns/active_mcp/tool_executable.rb
|
@@ -75,6 +76,7 @@ files:
|
|
75
76
|
- app/views/active_mcp/initialize.json.jbuilder
|
76
77
|
- app/views/active_mcp/initialized.json.jbuilder
|
77
78
|
- app/views/active_mcp/no_method.json.jbuilder
|
79
|
+
- app/views/active_mcp/resource_templates_list.json.jbuilder
|
78
80
|
- app/views/active_mcp/resources_list.json.jbuilder
|
79
81
|
- app/views/active_mcp/resources_read.json.jbuilder
|
80
82
|
- app/views/active_mcp/tools_call.json.jbuilder
|
@@ -82,15 +84,16 @@ files:
|
|
82
84
|
- config/routes.rb
|
83
85
|
- lib/active_mcp.rb
|
84
86
|
- lib/active_mcp/configuration.rb
|
87
|
+
- lib/active_mcp/controller/base.rb
|
85
88
|
- lib/active_mcp/engine.rb
|
89
|
+
- lib/active_mcp/schema/base.rb
|
86
90
|
- lib/active_mcp/server.rb
|
87
91
|
- lib/active_mcp/server/error_codes.rb
|
92
|
+
- lib/active_mcp/server/fetcher.rb
|
88
93
|
- lib/active_mcp/server/method.rb
|
89
94
|
- lib/active_mcp/server/protocol_handler.rb
|
90
|
-
- lib/active_mcp/server/resource_manager.rb
|
91
95
|
- lib/active_mcp/server/stdio_connection.rb
|
92
|
-
- lib/active_mcp/
|
93
|
-
- lib/active_mcp/tool.rb
|
96
|
+
- lib/active_mcp/tool/base.rb
|
94
97
|
- lib/active_mcp/version.rb
|
95
98
|
- lib/generators/active_mcp/install/install_generator.rb
|
96
99
|
- lib/generators/active_mcp/install/templates/initializer.rb
|