hub_kernel-mcp 0.3.0 → 0.5.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 +14 -4
- data/app/controllers/hub_kernel/mcp/messages_controller.rb +7 -1
- data/lib/hub_kernel/mcp/version.rb +1 -1
- data/lib/hub_kernel/mcp.rb +38 -0
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 90fe375e57411dd604b4bbcd46776ba7d3f64b829ab6d79c5ad9b0de4a14c1cd
|
|
4
|
+
data.tar.gz: eefdf79205bb8a4b8a5be1ec171dc4eac15316bede5f3ad3069efe3f1a2301d0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2d964c38b18504184297666e94174507baf671c754dfd131b428be747efb337574e32292c331c7f23908edbc9a11dd44e46414a0e141c1d41a9e9d04e043c24c
|
|
7
|
+
data.tar.gz: 6a98d684583139acc2ace28041202f55f59d19cc06ec894dbd5929101502fecdd91b8904aa356a56690e2a609d9637df0c0bf61232bcd7db194b42ff2e314044
|
data/README.md
CHANGED
|
@@ -21,9 +21,16 @@ serves:
|
|
|
21
21
|
```ruby
|
|
22
22
|
Rails.application.config.to_prepare do
|
|
23
23
|
HubKernel::Interface.hubs = [ Supplies, { "money" => Billing::Ledger } ]
|
|
24
|
+
HubKernel::Mcp.check!
|
|
24
25
|
end
|
|
25
26
|
```
|
|
26
27
|
|
|
28
|
+
`HubKernel::Mcp.check!` raises `HubKernel::Mcp::UnservableHubError` naming every problem
|
|
29
|
+
in one error. It names each problem hub_kernel-interface's own check finds in the served
|
|
30
|
+
list, a served name holding two underscores in a row, and a tool whose name holds a
|
|
31
|
+
character other than a letter, a digit, an underscore or a hyphen or is longer than 64
|
|
32
|
+
characters. Inside `to_prepare` it runs again after every code reload.
|
|
33
|
+
|
|
27
34
|
Mount the engine:
|
|
28
35
|
|
|
29
36
|
```ruby
|
|
@@ -58,10 +65,13 @@ give, and returns the method's answer as JSON text:
|
|
|
58
65
|
{ "content": [ { "type": "text", "text": "\"soap costs 3\"" } ], "isError": false }
|
|
59
66
|
```
|
|
60
67
|
|
|
61
|
-
A hub's refusal,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
A hub's refusal, a value the method requires and the call left out, a value the method is not
|
|
69
|
+
listed with, and a record the call names that does not exist each come back as a tool error
|
|
70
|
+
carrying the reason, with `isError` set. The last two reasons come from hub_kernel-interface, so
|
|
71
|
+
they read the same in every interface gem, such as `price_of does not take colour` and
|
|
72
|
+
`No item has the id 9`. A tool the caller may not call, a tool that does not exist, and a tool
|
|
73
|
+
naming a hub the host does not serve are all answered with the same JSON-RPC error, code
|
|
74
|
+
-32602, `Unknown tool: <name>`, whatever values the call sends.
|
|
65
75
|
|
|
66
76
|
A caller the host's sign-in refuses is refused before any hub is asked.
|
|
67
77
|
|
|
@@ -38,12 +38,18 @@ module HubKernel
|
|
|
38
38
|
def called
|
|
39
39
|
served_name, method_name = tool_name.split("__", 2)
|
|
40
40
|
hub = HubKernel::Interface.find(served_name) || raise(UnknownTool)
|
|
41
|
+
raise UnknownTool unless hub.exposed(method_name)
|
|
42
|
+
HubKernel::Interface::CallReasons.refuse_unlisted_values(hub, method_name, values: arguments, person: caller_person, account: caller_account)
|
|
41
43
|
answer = hub.call_exposed(method_name, values: arguments, person: caller_person, account: caller_account)
|
|
42
44
|
{ content: [ { type: "text", text: answer.to_json } ], isError: false }
|
|
43
45
|
rescue HubKernel::Refused, HubKernel::MissingArgumentError => refusal
|
|
44
|
-
|
|
46
|
+
tool_error(refusal.message)
|
|
47
|
+
rescue ActiveRecord::RecordNotFound => missing
|
|
48
|
+
tool_error(HubKernel::Interface::CallReasons.missing_record(missing))
|
|
45
49
|
end
|
|
46
50
|
|
|
51
|
+
def tool_error(reason) = { content: [ { type: "text", text: reason } ], isError: true }
|
|
52
|
+
|
|
47
53
|
def tool_name = params.dig(:params, :name).to_s
|
|
48
54
|
|
|
49
55
|
def arguments = params.dig(:params, :arguments)&.to_unsafe_h.to_h.deep_symbolize_keys
|
data/lib/hub_kernel/mcp.rb
CHANGED
|
@@ -4,8 +4,46 @@ require "hub_kernel/mcp/engine"
|
|
|
4
4
|
|
|
5
5
|
module HubKernel
|
|
6
6
|
module Mcp
|
|
7
|
+
UnservableHubError = HubKernel::Interface::UnservableHubError
|
|
8
|
+
|
|
7
9
|
mattr_accessor :base_controller, default: "ActionController::API"
|
|
8
10
|
mattr_accessor :person_method
|
|
9
11
|
mattr_accessor :account_method
|
|
12
|
+
|
|
13
|
+
def self.check!
|
|
14
|
+
problems = shared_problems + doubled_underscores + unlisted_characters + long_names
|
|
15
|
+
raise UnservableHubError, problems.join("\n") if problems.any?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.shared_problems
|
|
19
|
+
HubKernel::Interface.check!
|
|
20
|
+
[]
|
|
21
|
+
rescue UnservableHubError => error
|
|
22
|
+
error.message.split("\n")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.doubled_underscores
|
|
26
|
+
HubKernel::Interface.served.select { |name, _hub| name.include?("__") }.map do |name, hub|
|
|
27
|
+
"#{hub.name} is served at #{name}, which holds two underscores in a row"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.unlisted_characters
|
|
32
|
+
tool_names.grep_v(/\A[A-Za-z0-9_-]*\z/).map do |name|
|
|
33
|
+
"The tool #{name} holds a character other than a letter, a digit, an underscore or a hyphen"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.long_names
|
|
38
|
+
tool_names.select { |name| name.length > 64 }.map { |name| "The tool #{name} is longer than 64 characters" }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.tool_names
|
|
42
|
+
HubKernel::Interface.served.select { |_name, hub| hub.respond_to?(:exposures) }.flat_map do |served_name, hub|
|
|
43
|
+
hub.exposures.map { |exposure| "#{served_name}__#{exposure.name}" }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private_class_method :shared_problems, :doubled_underscores, :unlisted_characters, :long_names, :tool_names
|
|
10
48
|
end
|
|
11
49
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hub_kernel-mcp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tylercschneider
|
|
@@ -29,14 +29,14 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '0.
|
|
32
|
+
version: '0.6'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '0.
|
|
39
|
+
version: '0.6'
|
|
40
40
|
description: hub_kernel-mcp serves the methods every hub a host serves exposes as
|
|
41
41
|
MCP tools at one address, with every call going through the host's sign-in, permission
|
|
42
42
|
check and account scope.
|