stack-service-base 0.0.65 → 0.0.66

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: 93e5d152f7456e78c982d7d872cb726e864c8c7d8b590e138aadec698b34e144
4
- data.tar.gz: 658cb94d84c307962c345bb5c7a6a342a90c2f7f8fa31f424e7b3dcf56041aad
3
+ metadata.gz: e5364bb7f74a8a5882409f1756051e6157203cf89b148cf3ee69ca60456d5285
4
+ data.tar.gz: 532831a451ce25cc18a3310b35f0eec5f2d6aa2b69cf2bfa49ec267c22d462e1
5
5
  SHA512:
6
- metadata.gz: 5d9c4d21e2628fe4122e52ff8f8f1525f558139c2398d0f2b1279aa51175357323e3aea8ec1e1319ef07496cd1d2d3555c6182286ba4f44ec8f2ee360d191377
7
- data.tar.gz: eb1cec3620d180ba68569ba9a3a5faa68c6aa42ca9b0dfe971793f419532adaf38acece7cb3f6000c187c55af3535b3659a269477ae29313e66fa0b7b7364697
6
+ metadata.gz: d7ee6fb74e36aba27c59632ffaa64dcc208f1af6e03c00a295b238c2e6340abe7a73fdf220863e034574df71204326b13555ec5726ac0fe38c7e8243b3902ed3
7
+ data.tar.gz: '08deb1846f8eb0f47983ae3d9a1cb7ea7408d9f254d5f8e922ab6c5f319082ba700fba8cb2ae1d42045571a3903f889638f1610c4f38fedec5ac0f483d7fc98c'
@@ -11,13 +11,13 @@ SERVICES = {
11
11
  }
12
12
  }
13
13
 
14
- require 'stack-service-base/mcp_helper'
14
+ require 'stack-service-base/mcp/mcp_helper'
15
15
  helpers McpHelper
16
16
 
17
17
  Tool :search do
18
18
  description 'Search for a term in the database'
19
19
  input query: { type: "string", description: "Term to search for", required: true }
20
- execute do |inputs|
20
+ call do |inputs|
21
21
  query = inputs[:query]
22
22
  { results: [{id:"doc-1",title:"...",url:"..."}] }
23
23
  end
@@ -26,7 +26,7 @@ end
26
26
  Tool :fetch do
27
27
  description 'Fetch a resource from the database'
28
28
  input resource_id: { type: "string", description: "Resource ID to fetch", required: true }
29
- execute do |inputs|
29
+ call do |inputs|
30
30
  id = inputs[:id]
31
31
  { id: "doc-1", title: "...", text: "full text...", url: "https://example.com/doc", metadata: { source: "vector_store" } }
32
32
  end
@@ -35,10 +35,10 @@ end
35
35
  Tool :service_status do
36
36
  description 'Check current status of a service'
37
37
  input service_name: { type: "string", description: "Service name to inspect", required: true }
38
- execute do |inputs|
38
+ call do |inputs|
39
39
  service_name = inputs[:service_name]
40
40
  service = SERVICES[service_name]
41
- rpc_error!(404, "Unknown service #{service_name}") unless service
41
+ rpc_error!(-32000, "Unknown service #{service_name}") unless service
42
42
  {
43
43
  service_name: service_name,
44
44
  status: service[:status],
@@ -52,10 +52,10 @@ Tool :restart_service do
52
52
  description 'Restart a service'
53
53
  input service_name: { type: "string", description: "Service name to restart", required: true },
54
54
  force: { type: "boolean", default: false, description: "Force restart if graceful fails" }
55
- execute do |inputs|
55
+ call do |inputs|
56
56
  service_name = inputs[:service_name]
57
57
  service = SERVICES[service_name]
58
- rpc_error!(404, "Unknown service #{service_name}") unless service
58
+ rpc_error!(-32000, "Unknown service #{service_name}") unless service
59
59
 
60
60
  service[:status] = "running"
61
61
  service[:last_restart] = Time.now
@@ -12,7 +12,7 @@ module McpHelper
12
12
  err.body
13
13
  end
14
14
 
15
- get '/mcp' do
15
+ get '/mcp' do
16
16
  content_type :json
17
17
  MCP_PROCESSOR.root_endpoint
18
18
  end
@@ -115,7 +115,7 @@ class McpProcessor
115
115
  name = params["name"]
116
116
  arguments = params["arguments"] || {}
117
117
  tool = ToolRegistry.fetch(name) || rpc_error!(-32601, "Unknown tool #{name}")
118
- response = tool.call(arguments)
118
+ response = tool.call_tool(arguments)
119
119
  {
120
120
  content: [
121
121
  { "type": "text", "text": response.is_a?(String) ? response : response.to_json }
@@ -30,10 +30,10 @@ module ToolRegistry
30
30
  properties[field] = cfg.transform_keys(&:to_s)
31
31
  end
32
32
 
33
- { type: "object", properties: properties, required: required }
33
+ { type: 'object', properties: properties, required: required }
34
34
  end
35
35
 
36
- def execute(&block) = @executor = block
36
+ def call(&block) = @executor = block
37
37
 
38
38
  def to_h
39
39
  {
@@ -43,7 +43,7 @@ module ToolRegistry
43
43
  }
44
44
  end
45
45
 
46
- def call(arguments)
46
+ def call_tool(arguments)
47
47
  raise JsonRpcError.new(code: 500, message: "Tool #{name} missing executor") unless @executor
48
48
 
49
49
  ExecutionContext.new.instance_exec(symbolize_keys(arguments || {}), &@executor)
@@ -0,0 +1,52 @@
1
+ require 'json'
2
+
3
+ module Rack
4
+ module Test
5
+ module McpProtocol
6
+ def rpc_request(payload)
7
+ post '/mcp', JSON.dump(payload), { 'CONTENT_TYPE' => 'application/json' }
8
+ expect(last_response.status).to eq(200)
9
+ parsed_response_body
10
+ end
11
+
12
+ def parsed_response_body
13
+ body = +''
14
+ last_response.each { |chunk| body << chunk.to_s }
15
+ data_lines = body.lines.select { |line| line.start_with?('data:') }
16
+ payload_line = data_lines.reverse.find { |l| l !~ /ping/i } || data_lines.last
17
+ payload = (payload_line || body).sub(/\Adata:\s*/, '').sub(/\n\z/, '')
18
+ JSON.parse(payload, symbolize_names: true)
19
+ end
20
+
21
+ def mcp_list_tools
22
+ req_id = next_id
23
+ response = rpc_request(id: req_id, method: 'tools/list', params: {})
24
+ expect(response[:id]).to eq(req_id)
25
+ response.dig(:result, :tools)
26
+ end
27
+
28
+ def mcp_call_tool(name:, arguments:)
29
+ response = mcp_call_tool_raw(name: name, arguments: arguments)
30
+ tool_results = response.dig(:result, :content)
31
+ expect(tool_results[0][:type]).to eq('text')
32
+ JSON.parse(tool_results[0][:text], symbolize_names: true)
33
+ end
34
+
35
+ def mcp_call_tool_raw(name:, arguments:)
36
+ rpc_request(
37
+ id: next_id,
38
+ method: 'tools/call',
39
+ params: { 'name' => name, 'arguments' => arguments }
40
+ )
41
+ end
42
+
43
+ private
44
+
45
+ def next_id
46
+ @next_id ||= -1
47
+ @next_id += 1
48
+ end
49
+ end
50
+ end
51
+ end
52
+
@@ -1,3 +1,3 @@
1
1
  module StackServiceBase
2
- VERSION = '0.0.65'
2
+ VERSION = '0.0.66'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stack-service-base
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.65
4
+ version: 0.0.66
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artyom B
@@ -401,9 +401,10 @@ files:
401
401
  - lib/stack-service-base/examples/mcp_config.ru
402
402
  - lib/stack-service-base/fiber_pool.rb
403
403
  - lib/stack-service-base/logging.rb
404
- - lib/stack-service-base/mcp_helper.rb
405
- - lib/stack-service-base/mcp_processor.rb
406
- - lib/stack-service-base/mcp_tool_registry.rb
404
+ - lib/stack-service-base/mcp/mcp_helper.rb
405
+ - lib/stack-service-base/mcp/mcp_processor.rb
406
+ - lib/stack-service-base/mcp/mcp_tool_registry.rb
407
+ - lib/stack-service-base/mcp/rack_test_mcp_protocol.rb
407
408
  - lib/stack-service-base/nats_patch_1.rb
408
409
  - lib/stack-service-base/nats_service.rb
409
410
  - lib/stack-service-base/open_telemetry.rb