active_mcp 0.1.0 → 0.1.1
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 +17 -1
- data/lib/active_mcp/server/protocol_handler.rb +18 -3
- data/lib/active_mcp/server/tool_manager.rb +80 -4
- data/lib/active_mcp/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f768454eb918802f12f22205183172abcddeee402f1747c0223810e0622945f5
|
4
|
+
data.tar.gz: 336a6e84d15e9899240ef15de5912063cfe7729848a3617cf584cf987603d4d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a9db4bc9729b90fdc34caf1aae7715c73bb9596162641d34e5ca0ca12f03cac1b1b8576def4198bdc59d1967a4184377a1ee9dbf050d73d82c69385b8a2df40
|
7
|
+
data.tar.gz: 7027f29f2402272a75cce1e96791e4218b006558787efdbe6aa0ddadb93bc0ff84aa82afc36523eda1b16ba5d264f6e5be8df47316adb9f1b69d3b60ab691ddf
|
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
# Active
|
1
|
+
# Active MCP
|
2
2
|
|
3
3
|
A Ruby on Rails engine that provides [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) capabilities to Rails applications. This gem allows you to easily create and expose MCP-compatible tools from your Rails application.
|
4
4
|
|
5
|
+

|
6
|
+
|
5
7
|
## Installation
|
6
8
|
|
7
9
|
Add this line to your application's Gemfile:
|
@@ -54,6 +56,7 @@ end
|
|
54
56
|
3. Start the MCP server:
|
55
57
|
|
56
58
|
```ruby
|
59
|
+
# server.rb
|
57
60
|
server = ActiveMcp::Server.new(
|
58
61
|
name: "ActiveMcp DEMO",
|
59
62
|
uri: 'https://your-app.example.com/mcp'
|
@@ -61,6 +64,19 @@ server = ActiveMcp::Server.new(
|
|
61
64
|
server.start
|
62
65
|
```
|
63
66
|
|
67
|
+
4. Set up MCP Client
|
68
|
+
|
69
|
+
```json
|
70
|
+
{
|
71
|
+
"mcpServers": {
|
72
|
+
"active-mcp-demo": {
|
73
|
+
"command": "/path/to/ruby",
|
74
|
+
"args": ["/path/to/server.rb"]
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
```
|
79
|
+
|
64
80
|
## Rails Generators
|
65
81
|
|
66
82
|
MCP Rails provides generators to help you quickly create new MCP tools:
|
@@ -17,9 +17,11 @@ module ActiveMcp
|
|
17
17
|
request = JSON.parse(message, symbolize_names: true)
|
18
18
|
handle_request(request)
|
19
19
|
rescue JSON::ParserError => e
|
20
|
-
|
20
|
+
log_error("JSON parse error", e)
|
21
|
+
error_response(nil, ErrorCode::PARSE_ERROR, "Invalid JSON format")
|
21
22
|
rescue => e
|
22
|
-
|
23
|
+
log_error("Internal error during message processing", e)
|
24
|
+
error_response(nil, ErrorCode::INTERNAL_ERROR, "An internal error occurred")
|
23
25
|
end
|
24
26
|
|
25
27
|
json_result = JSON.generate(result).force_encoding("UTF-8") if result
|
@@ -123,7 +125,8 @@ module ActiveMcp
|
|
123
125
|
|
124
126
|
success_response(request[:id], result)
|
125
127
|
rescue => e
|
126
|
-
|
128
|
+
log_error("Error calling tool #{name}", e)
|
129
|
+
error_response(request[:id], ErrorCode::INTERNAL_ERROR, "An error occurred while calling the tool")
|
127
130
|
end
|
128
131
|
end
|
129
132
|
|
@@ -162,6 +165,18 @@ module ActiveMcp
|
|
162
165
|
response[:error][:data] = data if data
|
163
166
|
response
|
164
167
|
end
|
168
|
+
|
169
|
+
def log_error(message, error)
|
170
|
+
error_details = "#{message}: #{error.message}\n"
|
171
|
+
error_details += error.backtrace.join("\n") if error.backtrace
|
172
|
+
|
173
|
+
if defined?(Rails)
|
174
|
+
Rails.logger.error(error_details)
|
175
|
+
else
|
176
|
+
# Fallback to standard error output if Rails is not available
|
177
|
+
$stderr.puts(error_details)
|
178
|
+
end
|
179
|
+
end
|
165
180
|
end
|
166
181
|
end
|
167
182
|
end
|
@@ -35,7 +35,43 @@ module ActiveMcp
|
|
35
35
|
|
36
36
|
def invoke_tool(name, arguments)
|
37
37
|
require "net/http"
|
38
|
-
|
38
|
+
|
39
|
+
# URIの検証
|
40
|
+
unless @uri.is_a?(URI) || @uri.is_a?(String)
|
41
|
+
log_error("Invalid URI type", StandardError.new("URI must be a String or URI object"))
|
42
|
+
return {
|
43
|
+
isError: true,
|
44
|
+
content: [{type: "text", text: "Invalid URI configuration"}]
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
begin
|
49
|
+
uri = URI.parse(@uri.to_s)
|
50
|
+
|
51
|
+
# 有効なスキームとホストの検証
|
52
|
+
unless uri.scheme =~ /\Ahttps?\z/ && !uri.host.nil?
|
53
|
+
log_error("Invalid URI", StandardError.new("URI must have a valid scheme and host"))
|
54
|
+
return {
|
55
|
+
isError: true,
|
56
|
+
content: [{type: "text", text: "Invalid URI configuration"}]
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
# 本番環境ではHTTPSを強制
|
61
|
+
if defined?(Rails) && Rails.env.production? && uri.scheme != "https"
|
62
|
+
return {
|
63
|
+
isError: true,
|
64
|
+
content: [{type: "text", text: "HTTPS is required in production environment"}]
|
65
|
+
}
|
66
|
+
end
|
67
|
+
rescue URI::InvalidURIError => e
|
68
|
+
log_error("Invalid URI format", e)
|
69
|
+
return {
|
70
|
+
isError: true,
|
71
|
+
content: [{type: "text", text: "Invalid URI format"}]
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
39
75
|
request = Net::HTTP::Post.new(uri)
|
40
76
|
request.body = JSON.generate({
|
41
77
|
method: "tools/call",
|
@@ -67,9 +103,11 @@ module ActiveMcp
|
|
67
103
|
}
|
68
104
|
end
|
69
105
|
rescue => e
|
106
|
+
# ログに詳細を記録
|
107
|
+
log_error("Error calling tool", e)
|
70
108
|
{
|
71
109
|
isError: true,
|
72
|
-
content: [{type: "text", text: "Error calling tool
|
110
|
+
content: [{type: "text", text: "Error calling tool"}]
|
73
111
|
}
|
74
112
|
end
|
75
113
|
end
|
@@ -78,7 +116,32 @@ module ActiveMcp
|
|
78
116
|
return unless @uri
|
79
117
|
|
80
118
|
require "net/http"
|
81
|
-
|
119
|
+
|
120
|
+
# URIの検証
|
121
|
+
unless @uri.is_a?(URI) || @uri.is_a?(String)
|
122
|
+
log_error("Invalid URI type", StandardError.new("URI must be a String or URI object"))
|
123
|
+
return
|
124
|
+
end
|
125
|
+
|
126
|
+
begin
|
127
|
+
uri = URI.parse(@uri.to_s)
|
128
|
+
|
129
|
+
# 有効なスキームとホストの検証
|
130
|
+
unless uri.scheme =~ /\Ahttps?\z/ && !uri.host.nil?
|
131
|
+
log_error("Invalid URI", StandardError.new("URI must have a valid scheme and host"))
|
132
|
+
return
|
133
|
+
end
|
134
|
+
|
135
|
+
# 本番環境ではHTTPSを強制
|
136
|
+
if defined?(Rails) && Rails.env.production? && uri.scheme != "https"
|
137
|
+
log_error("HTTPS is required in production environment", StandardError.new("Non-HTTPS URI in production"))
|
138
|
+
return
|
139
|
+
end
|
140
|
+
rescue URI::InvalidURIError => e
|
141
|
+
log_error("Invalid URI format", e)
|
142
|
+
return
|
143
|
+
end
|
144
|
+
|
82
145
|
request = Net::HTTP::Post.new(uri)
|
83
146
|
request.body = JSON.generate({
|
84
147
|
method: "tools/list",
|
@@ -94,7 +157,8 @@ module ActiveMcp
|
|
94
157
|
|
95
158
|
result = JSON.parse(response.body, symbolize_names: true)
|
96
159
|
@tools = result[:result]
|
97
|
-
rescue
|
160
|
+
rescue => e
|
161
|
+
log_error("Error fetching tools", e)
|
98
162
|
@tools = []
|
99
163
|
end
|
100
164
|
end
|
@@ -109,6 +173,18 @@ module ActiveMcp
|
|
109
173
|
{content: [{type: "text", text: result.to_s}]}
|
110
174
|
end
|
111
175
|
end
|
176
|
+
|
177
|
+
def log_error(message, error)
|
178
|
+
error_details = "#{message}: #{error.message}\n"
|
179
|
+
error_details += error.backtrace.join("\n") if error.backtrace
|
180
|
+
|
181
|
+
if defined?(Rails)
|
182
|
+
Rails.logger.error(error_details)
|
183
|
+
else
|
184
|
+
# Fallback to standard error output if Rails is not available
|
185
|
+
$stderr.puts(error_details)
|
186
|
+
end
|
187
|
+
end
|
112
188
|
end
|
113
189
|
end
|
114
190
|
end
|
data/lib/active_mcp/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_mcp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Your Name
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-04-
|
10
|
+
date: 2025-04-03 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rails
|