mcp_on_ruby 0.3.0 → 1.0.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/CHANGELOG.md +56 -28
- data/CODE_OF_CONDUCT.md +30 -58
- data/CONTRIBUTING.md +61 -67
- data/LICENSE.txt +2 -2
- data/README.md +159 -509
- data/bin/console +11 -0
- data/bin/setup +6 -0
- data/docs/advanced-usage.md +132 -0
- data/docs/api-reference.md +35 -0
- data/docs/testing.md +55 -0
- data/examples/claude/README.md +171 -0
- data/examples/claude/claude-bridge.js +122 -0
- data/lib/mcp_on_ruby/configuration.rb +74 -0
- data/lib/mcp_on_ruby/errors.rb +137 -0
- data/lib/mcp_on_ruby/generators/install_generator.rb +46 -0
- data/lib/mcp_on_ruby/generators/resource_generator.rb +63 -0
- data/lib/mcp_on_ruby/generators/templates/README +31 -0
- data/lib/mcp_on_ruby/generators/templates/application_resource.rb +20 -0
- data/lib/mcp_on_ruby/generators/templates/application_tool.rb +18 -0
- data/lib/mcp_on_ruby/generators/templates/initializer.rb +41 -0
- data/lib/mcp_on_ruby/generators/templates/resource.rb +50 -0
- data/lib/mcp_on_ruby/generators/templates/resource_spec.rb +67 -0
- data/lib/mcp_on_ruby/generators/templates/sample_resource.rb +57 -0
- data/lib/mcp_on_ruby/generators/templates/sample_tool.rb +59 -0
- data/lib/mcp_on_ruby/generators/templates/tool.rb +38 -0
- data/lib/mcp_on_ruby/generators/templates/tool_spec.rb +55 -0
- data/lib/mcp_on_ruby/generators/tool_generator.rb +51 -0
- data/lib/mcp_on_ruby/railtie.rb +108 -0
- data/lib/mcp_on_ruby/resource.rb +161 -0
- data/lib/mcp_on_ruby/server.rb +378 -0
- data/lib/mcp_on_ruby/tool.rb +134 -0
- data/lib/mcp_on_ruby/transport.rb +330 -0
- data/lib/mcp_on_ruby/version.rb +6 -0
- data/lib/mcp_on_ruby.rb +142 -0
- metadata +62 -173
- data/lib/ruby_mcp/client.rb +0 -43
- data/lib/ruby_mcp/configuration.rb +0 -90
- data/lib/ruby_mcp/errors.rb +0 -17
- data/lib/ruby_mcp/models/context.rb +0 -52
- data/lib/ruby_mcp/models/engine.rb +0 -31
- data/lib/ruby_mcp/models/message.rb +0 -60
- data/lib/ruby_mcp/providers/anthropic.rb +0 -269
- data/lib/ruby_mcp/providers/base.rb +0 -57
- data/lib/ruby_mcp/providers/openai.rb +0 -265
- data/lib/ruby_mcp/schemas.rb +0 -56
- data/lib/ruby_mcp/server/app.rb +0 -84
- data/lib/ruby_mcp/server/base_controller.rb +0 -49
- data/lib/ruby_mcp/server/content_controller.rb +0 -68
- data/lib/ruby_mcp/server/contexts_controller.rb +0 -67
- data/lib/ruby_mcp/server/controller.rb +0 -29
- data/lib/ruby_mcp/server/engines_controller.rb +0 -34
- data/lib/ruby_mcp/server/generate_controller.rb +0 -140
- data/lib/ruby_mcp/server/messages_controller.rb +0 -30
- data/lib/ruby_mcp/server/router.rb +0 -84
- data/lib/ruby_mcp/storage/active_record.rb +0 -414
- data/lib/ruby_mcp/storage/base.rb +0 -43
- data/lib/ruby_mcp/storage/error.rb +0 -8
- data/lib/ruby_mcp/storage/memory.rb +0 -69
- data/lib/ruby_mcp/storage/redis.rb +0 -197
- data/lib/ruby_mcp/storage_factory.rb +0 -43
- data/lib/ruby_mcp/validator.rb +0 -45
- data/lib/ruby_mcp/version.rb +0 -6
- data/lib/ruby_mcp.rb +0 -71
metadata
CHANGED
@@ -1,59 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mcp_on_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nagendra Dhanakeerthi
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.2'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.2'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: dry-schema
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.13'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.13'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: faraday
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '2.7'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '2.7'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: faraday-net_http
|
14
|
+
name: json-schema
|
57
15
|
requirement: !ruby/object:Gem::Requirement
|
58
16
|
requirements:
|
59
17
|
- - "~>"
|
@@ -66,20 +24,6 @@ dependencies:
|
|
66
24
|
- - "~>"
|
67
25
|
- !ruby/object:Gem::Version
|
68
26
|
version: '3.0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: jwt
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '2.7'
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '2.7'
|
83
27
|
- !ruby/object:Gem::Dependency
|
84
28
|
name: rack
|
85
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,20 +38,6 @@ dependencies:
|
|
94
38
|
- - "~>"
|
95
39
|
- !ruby/object:Gem::Version
|
96
40
|
version: '2.2'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rack-cors
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '1.1'
|
104
|
-
type: :runtime
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '1.1'
|
111
41
|
- !ruby/object:Gem::Dependency
|
112
42
|
name: webrick
|
113
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,91 +53,77 @@ dependencies:
|
|
123
53
|
- !ruby/object:Gem::Version
|
124
54
|
version: '1.7'
|
125
55
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
56
|
+
name: rake
|
127
57
|
requirement: !ruby/object:Gem::Requirement
|
128
58
|
requirements:
|
129
59
|
- - "~>"
|
130
60
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
61
|
+
version: '13.0'
|
132
62
|
type: :development
|
133
63
|
prerelease: false
|
134
64
|
version_requirements: !ruby/object:Gem::Requirement
|
135
65
|
requirements:
|
136
66
|
- - "~>"
|
137
67
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
68
|
+
version: '13.0'
|
139
69
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
70
|
+
name: rspec
|
141
71
|
requirement: !ruby/object:Gem::Requirement
|
142
72
|
requirements:
|
143
73
|
- - "~>"
|
144
74
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
75
|
+
version: '3.12'
|
146
76
|
type: :development
|
147
77
|
prerelease: false
|
148
78
|
version_requirements: !ruby/object:Gem::Requirement
|
149
79
|
requirements:
|
150
80
|
- - "~>"
|
151
81
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
82
|
+
version: '3.12'
|
153
83
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
84
|
+
name: rubocop
|
155
85
|
requirement: !ruby/object:Gem::Requirement
|
156
86
|
requirements:
|
157
87
|
- - "~>"
|
158
88
|
- !ruby/object:Gem::Version
|
159
|
-
version: '1.
|
89
|
+
version: '1.50'
|
160
90
|
type: :development
|
161
91
|
prerelease: false
|
162
92
|
version_requirements: !ruby/object:Gem::Requirement
|
163
93
|
requirements:
|
164
94
|
- - "~>"
|
165
95
|
- !ruby/object:Gem::Version
|
166
|
-
version: '1.
|
96
|
+
version: '1.50'
|
167
97
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
169
|
-
requirement: !ruby/object:Gem::Requirement
|
170
|
-
requirements:
|
171
|
-
- - "~>"
|
172
|
-
- !ruby/object:Gem::Version
|
173
|
-
version: 0.6.0
|
174
|
-
type: :development
|
175
|
-
prerelease: false
|
176
|
-
version_requirements: !ruby/object:Gem::Requirement
|
177
|
-
requirements:
|
178
|
-
- - "~>"
|
179
|
-
- !ruby/object:Gem::Version
|
180
|
-
version: 0.6.0
|
181
|
-
- !ruby/object:Gem::Dependency
|
182
|
-
name: rack-test
|
98
|
+
name: simplecov
|
183
99
|
requirement: !ruby/object:Gem::Requirement
|
184
100
|
requirements:
|
185
101
|
- - "~>"
|
186
102
|
- !ruby/object:Gem::Version
|
187
|
-
version: '
|
103
|
+
version: '0.22'
|
188
104
|
type: :development
|
189
105
|
prerelease: false
|
190
106
|
version_requirements: !ruby/object:Gem::Requirement
|
191
107
|
requirements:
|
192
108
|
- - "~>"
|
193
109
|
- !ruby/object:Gem::Version
|
194
|
-
version: '
|
110
|
+
version: '0.22'
|
195
111
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
112
|
+
name: webmock
|
197
113
|
requirement: !ruby/object:Gem::Requirement
|
198
114
|
requirements:
|
199
115
|
- - "~>"
|
200
116
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
117
|
+
version: '3.18'
|
202
118
|
type: :development
|
203
119
|
prerelease: false
|
204
120
|
version_requirements: !ruby/object:Gem::Requirement
|
205
121
|
requirements:
|
206
122
|
- - "~>"
|
207
123
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
124
|
+
version: '3.18'
|
209
125
|
- !ruby/object:Gem::Dependency
|
210
|
-
name:
|
126
|
+
name: rack-test
|
211
127
|
requirement: !ruby/object:Gem::Requirement
|
212
128
|
requirements:
|
213
129
|
- - "~>"
|
@@ -220,40 +136,14 @@ dependencies:
|
|
220
136
|
- - "~>"
|
221
137
|
- !ruby/object:Gem::Version
|
222
138
|
version: '2.1'
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
requirements:
|
227
|
-
- - "~>"
|
228
|
-
- !ruby/object:Gem::Version
|
229
|
-
version: '6.1'
|
230
|
-
type: :development
|
231
|
-
prerelease: false
|
232
|
-
version_requirements: !ruby/object:Gem::Requirement
|
233
|
-
requirements:
|
234
|
-
- - "~>"
|
235
|
-
- !ruby/object:Gem::Version
|
236
|
-
version: '6.1'
|
237
|
-
- !ruby/object:Gem::Dependency
|
238
|
-
name: webmock
|
239
|
-
requirement: !ruby/object:Gem::Requirement
|
240
|
-
requirements:
|
241
|
-
- - "~>"
|
242
|
-
- !ruby/object:Gem::Version
|
243
|
-
version: '3.18'
|
244
|
-
type: :development
|
245
|
-
prerelease: false
|
246
|
-
version_requirements: !ruby/object:Gem::Requirement
|
247
|
-
requirements:
|
248
|
-
- - "~>"
|
249
|
-
- !ruby/object:Gem::Version
|
250
|
-
version: '3.18'
|
251
|
-
description: |-
|
252
|
-
A comprehensive Ruby gem for implementing Model Context Protocol servers
|
253
|
-
to standardize interactions with AI language models
|
139
|
+
description: A comprehensive Ruby library for building Model Context Protocol (MCP)
|
140
|
+
servers in Rails applications, featuring tools, resources, authentication, and real-time
|
141
|
+
capabilities.
|
254
142
|
email:
|
255
143
|
- nagendra.dhanakeerthi@gmail.com
|
256
|
-
executables:
|
144
|
+
executables:
|
145
|
+
- console
|
146
|
+
- setup
|
257
147
|
extensions: []
|
258
148
|
extra_rdoc_files: []
|
259
149
|
files:
|
@@ -262,43 +152,42 @@ files:
|
|
262
152
|
- CONTRIBUTING.md
|
263
153
|
- LICENSE.txt
|
264
154
|
- README.md
|
265
|
-
-
|
266
|
-
-
|
267
|
-
-
|
268
|
-
-
|
269
|
-
-
|
270
|
-
-
|
271
|
-
-
|
272
|
-
- lib/
|
273
|
-
- lib/
|
274
|
-
- lib/
|
275
|
-
- lib/
|
276
|
-
- lib/
|
277
|
-
- lib/
|
278
|
-
- lib/
|
279
|
-
- lib/
|
280
|
-
- lib/
|
281
|
-
- lib/
|
282
|
-
- lib/
|
283
|
-
- lib/
|
284
|
-
- lib/
|
285
|
-
- lib/
|
286
|
-
- lib/
|
287
|
-
- lib/
|
288
|
-
- lib/
|
289
|
-
- lib/
|
290
|
-
- lib/
|
291
|
-
- lib/
|
292
|
-
- lib/
|
293
|
-
|
155
|
+
- bin/console
|
156
|
+
- bin/setup
|
157
|
+
- docs/advanced-usage.md
|
158
|
+
- docs/api-reference.md
|
159
|
+
- docs/testing.md
|
160
|
+
- examples/claude/README.md
|
161
|
+
- examples/claude/claude-bridge.js
|
162
|
+
- lib/mcp_on_ruby.rb
|
163
|
+
- lib/mcp_on_ruby/configuration.rb
|
164
|
+
- lib/mcp_on_ruby/errors.rb
|
165
|
+
- lib/mcp_on_ruby/generators/install_generator.rb
|
166
|
+
- lib/mcp_on_ruby/generators/resource_generator.rb
|
167
|
+
- lib/mcp_on_ruby/generators/templates/README
|
168
|
+
- lib/mcp_on_ruby/generators/templates/application_resource.rb
|
169
|
+
- lib/mcp_on_ruby/generators/templates/application_tool.rb
|
170
|
+
- lib/mcp_on_ruby/generators/templates/initializer.rb
|
171
|
+
- lib/mcp_on_ruby/generators/templates/resource.rb
|
172
|
+
- lib/mcp_on_ruby/generators/templates/resource_spec.rb
|
173
|
+
- lib/mcp_on_ruby/generators/templates/sample_resource.rb
|
174
|
+
- lib/mcp_on_ruby/generators/templates/sample_tool.rb
|
175
|
+
- lib/mcp_on_ruby/generators/templates/tool.rb
|
176
|
+
- lib/mcp_on_ruby/generators/templates/tool_spec.rb
|
177
|
+
- lib/mcp_on_ruby/generators/tool_generator.rb
|
178
|
+
- lib/mcp_on_ruby/railtie.rb
|
179
|
+
- lib/mcp_on_ruby/resource.rb
|
180
|
+
- lib/mcp_on_ruby/server.rb
|
181
|
+
- lib/mcp_on_ruby/tool.rb
|
182
|
+
- lib/mcp_on_ruby/transport.rb
|
183
|
+
- lib/mcp_on_ruby/version.rb
|
184
|
+
homepage: https://github.com/rubyonai/mcp_on_ruby
|
294
185
|
licenses:
|
295
186
|
- MIT
|
296
187
|
metadata:
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
changelog_uri: https://github.com/nagstler/mcp_on_ruby/blob/main/CHANGELOG.md
|
301
|
-
rubygems_mfa_required: 'true'
|
188
|
+
homepage_uri: https://github.com/rubyonai/mcp_on_ruby
|
189
|
+
source_code_uri: https://github.com/rubyonai/mcp_on_ruby
|
190
|
+
changelog_uri: https://github.com/rubyonai/mcp_on_ruby/blob/main/CHANGELOG.md
|
302
191
|
post_install_message:
|
303
192
|
rdoc_options: []
|
304
193
|
require_paths:
|
@@ -307,15 +196,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
307
196
|
requirements:
|
308
197
|
- - ">="
|
309
198
|
- !ruby/object:Gem::Version
|
310
|
-
version: 2.
|
199
|
+
version: 2.7.0
|
311
200
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
312
201
|
requirements:
|
313
202
|
- - ">="
|
314
203
|
- !ruby/object:Gem::Version
|
315
204
|
version: '0'
|
316
205
|
requirements: []
|
317
|
-
rubygems_version: 3.
|
206
|
+
rubygems_version: 3.4.10
|
318
207
|
signing_key:
|
319
208
|
specification_version: 4
|
320
|
-
summary:
|
209
|
+
summary: Production-ready MCP server for Rails applications
|
321
210
|
test_files: []
|
data/lib/ruby_mcp/client.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
# lib/ruby_mcp/client.rb
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
module RubyMCP
|
5
|
-
class Client
|
6
|
-
attr_reader :storage
|
7
|
-
|
8
|
-
def initialize(storage)
|
9
|
-
@storage = storage
|
10
|
-
end
|
11
|
-
|
12
|
-
def create_context(messages = [], metadata = {})
|
13
|
-
context = RubyMCP::Models::Context.new(messages: messages, metadata: metadata)
|
14
|
-
storage.create_context(context)
|
15
|
-
end
|
16
|
-
|
17
|
-
def list_contexts(limit: 50, offset: 0)
|
18
|
-
storage.list_contexts(limit: limit, offset: offset)
|
19
|
-
end
|
20
|
-
|
21
|
-
def get_context(context_id)
|
22
|
-
storage.get_context(context_id)
|
23
|
-
end
|
24
|
-
|
25
|
-
def delete_context(context_id)
|
26
|
-
storage.delete_context(context_id)
|
27
|
-
end
|
28
|
-
|
29
|
-
def add_message(context_id, role, content, metadata: {})
|
30
|
-
message = RubyMCP::Models::Message.new(role: role, content: content, metadata: metadata)
|
31
|
-
storage.add_message(context_id, message)
|
32
|
-
end
|
33
|
-
|
34
|
-
def add_content(context_id, content_data, content_id = nil)
|
35
|
-
content_id ||= "cnt_#{SecureRandom.hex(10)}"
|
36
|
-
storage.add_content(context_id, content_id, content_data)
|
37
|
-
end
|
38
|
-
|
39
|
-
def get_content(context_id, content_id)
|
40
|
-
storage.get_content(context_id, content_id)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyMCP
|
4
|
-
class Configuration
|
5
|
-
attr_accessor :providers, :storage, :server_port, :server_host,
|
6
|
-
:auth_required, :jwt_secret, :token_expiry, :max_contexts,
|
7
|
-
:redis, :active_record
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
@providers = {}
|
11
|
-
@storage = :memory
|
12
|
-
@server_port = 3000
|
13
|
-
@server_host = '0.0.0.0'
|
14
|
-
@auth_required = false
|
15
|
-
@jwt_secret = nil
|
16
|
-
@token_expiry = 3600 # 1 hour
|
17
|
-
@max_contexts = 1000
|
18
|
-
@redis = {} # Default empty Redis config
|
19
|
-
@active_record = {} # Default empty ActiveRecord config
|
20
|
-
end
|
21
|
-
|
22
|
-
def storage_config
|
23
|
-
case @storage
|
24
|
-
when :redis
|
25
|
-
{
|
26
|
-
type: :redis,
|
27
|
-
connection: redis_connection_config,
|
28
|
-
namespace: @redis[:namespace] || 'ruby_mcp',
|
29
|
-
ttl: @redis[:ttl] || 86_400
|
30
|
-
}
|
31
|
-
when :active_record
|
32
|
-
{
|
33
|
-
type: :active_record,
|
34
|
-
connection: @active_record[:connection],
|
35
|
-
table_prefix: @active_record[:table_prefix] || 'mcp_'
|
36
|
-
}
|
37
|
-
else
|
38
|
-
{ type: @storage }
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def storage_instance
|
43
|
-
@storage_instance ||= case @storage
|
44
|
-
when :memory
|
45
|
-
RubyMCP::Storage::Memory.new
|
46
|
-
when :redis
|
47
|
-
begin
|
48
|
-
require 'redis'
|
49
|
-
require_relative 'storage/redis'
|
50
|
-
RubyMCP::Storage::Redis.new(storage_config)
|
51
|
-
rescue LoadError
|
52
|
-
raise RubyMCP::Errors::ConfigurationError,
|
53
|
-
"Redis storage requires the redis gem. Add it to your Gemfile with:
|
54
|
-
gem 'redis', '~> 5.0'"
|
55
|
-
end
|
56
|
-
when :active_record
|
57
|
-
begin
|
58
|
-
require 'active_record'
|
59
|
-
require_relative 'storage/active_record'
|
60
|
-
RubyMCP::Storage::ActiveRecord.new(storage_config)
|
61
|
-
rescue LoadError
|
62
|
-
raise RubyMCP::Errors::ConfigurationError,
|
63
|
-
"ActiveRecord storage requires the activerecord gem. Add it to your Gemfile with:
|
64
|
-
gem 'activerecord', '~> 6.0'"
|
65
|
-
end
|
66
|
-
else
|
67
|
-
unless @storage.is_a?(RubyMCP::Storage::Base)
|
68
|
-
raise RubyMCP::Errors::ConfigurationError, "Unknown storage type: #{@storage}"
|
69
|
-
end
|
70
|
-
|
71
|
-
@storage # Allow custom storage instance
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
private
|
76
|
-
|
77
|
-
def redis_connection_config
|
78
|
-
if @redis[:url]
|
79
|
-
{ url: @redis[:url] }
|
80
|
-
else
|
81
|
-
{
|
82
|
-
host: @redis[:host] || 'localhost',
|
83
|
-
port: @redis[:port] || 6379,
|
84
|
-
db: @redis[:db] || 0,
|
85
|
-
password: @redis[:password]
|
86
|
-
}.compact
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
data/lib/ruby_mcp/errors.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyMCP
|
4
|
-
module Errors
|
5
|
-
class Error < StandardError; end
|
6
|
-
|
7
|
-
class ConfigurationError < Error; end
|
8
|
-
class AuthenticationError < Error; end
|
9
|
-
class ValidationError < Error; end
|
10
|
-
class ProviderError < Error; end
|
11
|
-
class ContextError < Error; end
|
12
|
-
class EngineError < Error; end
|
13
|
-
class MessageError < Error; end
|
14
|
-
class ContentError < Error; end
|
15
|
-
class ServerError < Error; end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'securerandom'
|
4
|
-
|
5
|
-
module RubyMCP
|
6
|
-
module Models
|
7
|
-
class Context
|
8
|
-
attr_reader :id, :messages, :content_map, :created_at, :updated_at
|
9
|
-
attr_accessor :metadata
|
10
|
-
|
11
|
-
def initialize(id: nil, messages: [], metadata: {})
|
12
|
-
@id = id || "ctx_#{SecureRandom.hex(10)}"
|
13
|
-
@messages = messages || []
|
14
|
-
@content_map = {}
|
15
|
-
@metadata = metadata || {}
|
16
|
-
@created_at = Time.now.utc
|
17
|
-
@updated_at = @created_at
|
18
|
-
end
|
19
|
-
|
20
|
-
def add_message(message)
|
21
|
-
@messages << message
|
22
|
-
@updated_at = Time.now.utc
|
23
|
-
message
|
24
|
-
end
|
25
|
-
|
26
|
-
def add_content(content_id, content_data)
|
27
|
-
@content_map[content_id] = content_data
|
28
|
-
@updated_at = Time.now.utc
|
29
|
-
content_id
|
30
|
-
end
|
31
|
-
|
32
|
-
def get_content(content_id)
|
33
|
-
@content_map[content_id]
|
34
|
-
end
|
35
|
-
|
36
|
-
def to_h
|
37
|
-
{
|
38
|
-
id: @id,
|
39
|
-
messages: @messages.map(&:to_h),
|
40
|
-
content_map: @content_map,
|
41
|
-
created_at: @created_at.iso8601,
|
42
|
-
updated_at: @updated_at.iso8601,
|
43
|
-
metadata: @metadata
|
44
|
-
}
|
45
|
-
end
|
46
|
-
|
47
|
-
def estimated_token_count
|
48
|
-
@messages.sum(&:estimated_token_count)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyMCP
|
4
|
-
module Models
|
5
|
-
class Engine
|
6
|
-
attr_reader :id, :provider, :model, :capabilities, :config
|
7
|
-
|
8
|
-
def initialize(id:, provider:, model:, capabilities: [], config: {})
|
9
|
-
@id = id
|
10
|
-
@provider = provider
|
11
|
-
@model = model
|
12
|
-
@capabilities = capabilities
|
13
|
-
@config = config
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_h
|
17
|
-
{
|
18
|
-
id: @id,
|
19
|
-
provider: @provider,
|
20
|
-
model: @model,
|
21
|
-
capabilities: @capabilities,
|
22
|
-
config: @config
|
23
|
-
}
|
24
|
-
end
|
25
|
-
|
26
|
-
def supports?(capability)
|
27
|
-
@capabilities.include?(capability.to_s)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'securerandom'
|
4
|
-
|
5
|
-
module RubyMCP
|
6
|
-
module Models
|
7
|
-
class Message
|
8
|
-
VALID_ROLES = %w[user assistant system tool].freeze
|
9
|
-
|
10
|
-
attr_reader :id, :role, :content, :created_at
|
11
|
-
attr_accessor :metadata
|
12
|
-
|
13
|
-
def initialize(role:, content:, id: nil, metadata: {})
|
14
|
-
@id = id || "msg_#{SecureRandom.hex(10)}"
|
15
|
-
|
16
|
-
unless VALID_ROLES.include?(role)
|
17
|
-
raise RubyMCP::Errors::ValidationError, "Invalid role: #{role}. Must be one of: #{VALID_ROLES.join(', ')}"
|
18
|
-
end
|
19
|
-
|
20
|
-
@role = role
|
21
|
-
@content = content
|
22
|
-
@created_at = Time.now.utc
|
23
|
-
@metadata = metadata || {}
|
24
|
-
end
|
25
|
-
|
26
|
-
def to_h
|
27
|
-
{
|
28
|
-
id: @id,
|
29
|
-
role: @role,
|
30
|
-
content: @content,
|
31
|
-
created_at: @created_at.iso8601,
|
32
|
-
metadata: @metadata
|
33
|
-
}
|
34
|
-
end
|
35
|
-
|
36
|
-
def content_type
|
37
|
-
return 'array' if @content.is_a?(Array)
|
38
|
-
|
39
|
-
'text'
|
40
|
-
end
|
41
|
-
|
42
|
-
def estimated_token_count
|
43
|
-
# Very basic estimation, would need to be improved with a real tokenizer
|
44
|
-
if @content.is_a?(String)
|
45
|
-
@content.split(/\s+/).size
|
46
|
-
elsif @content.is_a?(Array)
|
47
|
-
@content.sum do |part|
|
48
|
-
if part.is_a?(String) || part[:text]
|
49
|
-
(part.is_a?(String) ? part : part[:text]).split(/\s+/).size
|
50
|
-
else
|
51
|
-
10 # Arbitrary count for non-text content
|
52
|
-
end
|
53
|
-
end
|
54
|
-
else
|
55
|
-
10 # Default for unknown content format
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|