hub_kernel-mcp 0.6.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dbd198a0ec695b49e09abc0435889275eb2d8d56197496bad51fcdc7698582d8
4
- data.tar.gz: 3d2e0d358be8c253b6996977d8687ed6b46509e4d33a16f5c74f76e5ca25a836
3
+ metadata.gz: c892de0b21d83e1d2068595a30e59930be423fa5b30dc539ffaedf3c304be263
4
+ data.tar.gz: 22114b0e2e4a5aa6c3389dc7c7580079a9091a5ac46bcfc6e7b53585eddcce16
5
5
  SHA512:
6
- metadata.gz: 18a08e74dfccbf30a4db3cd6831119ce1cc5ad447a4080d1c47e5a208d1b73504f99ec42ed00b3a60dea04286679fdc6ba8713a5ad9eb5cee403104d252a2e9c
7
- data.tar.gz: '028002bdb287b6828ce5e73f8130ab2b818d8710deba05335c508121d27619770848026156cb9bf93e721bd15d001faefd3bb1890dd31643ff343f6bfa8a64c0'
6
+ metadata.gz: 507a819510592862a8a2641075062fecf56f052de877ee8b7dc2fc7dd1ac66b7aace212dd7272cc33c6c65d80a1f9dbd792c7b63cf326a378fdbacca0a257dfb
7
+ data.tar.gz: b9e8d051ef5ef2f781499d69d17866e29b91475a7ba9e49f3648a8c10fcaa3f644da6acac643398d06421ee58e89479dd80c99dc3f7e50456bb848c0b6e3fc4f
data/Rakefile CHANGED
@@ -4,3 +4,5 @@ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
4
  load "rails/tasks/engine.rake"
5
5
 
6
6
  require "bundler/gem_tasks"
7
+
8
+ require "the_local/rake"
@@ -1,5 +1,5 @@
1
1
  module HubKernel
2
2
  module Mcp
3
- VERSION = "0.6.0"
3
+ VERSION = "0.7.0"
4
4
  end
5
5
  end
@@ -0,0 +1,152 @@
1
+ ---
2
+ name: hub_kernel-mcp-develop
3
+ description: Use PROACTIVELY for calling a host's hub methods over MCP — connecting an MCP client to the endpoint, sending initialize and ping, listing the tools a signed-in person may call with tools/list, calling one with tools/call, and handling its tool errors and JSON-RPC errors — MUST BE USED instead of hand-rolling a JSON API or MCP server for the host's hubs.
4
+ tools: Read, Write, Edit, Grep
5
+ scope: hub MCP tools — serving the methods every hub a host serves, from hub_kernel-interface's one served list, as MCP tools at one JSON-RPC endpoint in a host Rails app, each call behind the host's own sign-in and hub_kernel-interface's permission check and account scope, with a boot check for hubs that cannot be served as tools
6
+ ---
7
+
8
+ This local writes the code or configuration that talks to a host's hub_kernel-mcp
9
+ endpoint, following these steps exactly. Where a step names a decision, it asks
10
+ the developer and does not pick.
11
+
12
+ ## What hub_kernel-mcp is
13
+
14
+ A JSON-RPC endpoint in a host Rails app that offers every method the host's hubs
15
+ expose as an MCP tool, for the person and account the host's sign-in gives.
16
+ Fire this local when code or a client needs to list or call those tools, or when
17
+ a test needs to send requests to the endpoint.
18
+
19
+ ## Interface
20
+
21
+ - `POST /` — the endpoint, at the path the host serves it under. It takes one
22
+ JSON-RPC 2.0 request per POST as a JSON body. A GET to the same path is
23
+ answered with status 405 and `Allow: POST`.
24
+ - `initialize` — answers `protocolVersion`, `serverInfo` with name
25
+ `hub_kernel-mcp` and the gem's version, and `capabilities: { tools: {} }`.
26
+ `protocolVersion` is the one the client sent in `params.protocolVersion` when
27
+ it is one of `2025-11-25`, `2025-06-18`, `2025-03-26` or `2024-11-05`, and
28
+ `2025-11-25` otherwise.
29
+ - `ping` — answers an empty result, `{}`.
30
+ - `tools/list` — answers `{ tools: [...] }`, one tool for each hub method the
31
+ signed-in person may call in their account, across every served hub.
32
+ - `tools/call` — runs the hub method a tool names with `params.arguments`, for
33
+ the signed-in person and account, and answers the method's return value as
34
+ JSON text.
35
+
36
+ ## How to use it
37
+
38
+ 1. Find the path the host serves the endpoint at in its `config/routes.rb`. If
39
+ it is not there, stop and tell the developer the endpoint is not installed
40
+ yet.
41
+
42
+ 2. Ask the developer how the client signs in. Every request runs the host's own
43
+ sign-in first, so the client must send whatever that sign-in expects, such as
44
+ a session cookie or a token header. A request the sign-in refuses gets the
45
+ host's refusal, for example status 401, and no hub is asked. Do not choose the
46
+ credential yourself.
47
+
48
+ 3. Send every request as a POST with a JSON body holding exactly one request:
49
+
50
+ ```json
51
+ { "jsonrpc": "2.0", "id": 1, "method": "tools/list" }
52
+ ```
53
+
54
+ `jsonrpc` must be `"2.0"` and `method` must be a string. A batch, a JSON array
55
+ of requests, is refused with -32600. A request with no `id` is a
56
+ notification: it is answered with status 202 and no body, and nothing is run.
57
+
58
+ 4. Send `initialize` first. Ask the developer which protocol version the client
59
+ supports, send it as `params.protocolVersion`, and use the version the answer
60
+ gives. Then send the `notifications/initialized` notification with no `id`.
61
+
62
+ 5. Send `tools/list` to get the tools. Each tool has this shape:
63
+
64
+ ```json
65
+ {
66
+ "name": "supplies__price_of",
67
+ "description": "Reads data from the supplies hub.",
68
+ "inputSchema": { "type": "object", "properties": { "item": {} } },
69
+ "annotations": { "readOnlyHint": true }
70
+ }
71
+ ```
72
+
73
+ `name` is `<served name>__<method>`, split at the first two underscores in a
74
+ row. `inputSchema.properties` names each value the method takes and gives no
75
+ type for any of them. A method that writes has `readOnlyHint: false` and the
76
+ description `Changes data in the <served name> hub.` The list depends on who
77
+ is signed in and in which account, so list again after either changes.
78
+
79
+ 6. Ask the developer whether the client must confirm with the person before it
80
+ calls a tool whose `readOnlyHint` is false. If it must, add that confirmation
81
+ before step 7.
82
+
83
+ 7. Send `tools/call` with the tool's name and its values:
84
+
85
+ ```json
86
+ {
87
+ "jsonrpc": "2.0",
88
+ "id": 2,
89
+ "method": "tools/call",
90
+ "params": { "name": "supplies__price_of", "arguments": { "item": "soap" } }
91
+ }
92
+ ```
93
+
94
+ Send only the values named in that tool's `inputSchema.properties`. A
95
+ successful call answers:
96
+
97
+ ```json
98
+ { "content": [ { "type": "text", "text": "\"soap costs 3\"" } ], "isError": false }
99
+ ```
100
+
101
+ `text` is the method's return value encoded as JSON, so parse it as JSON to
102
+ get the value back.
103
+
104
+ 8. Handle a tool error. These come back as a normal result with `isError: true`
105
+ and the reason as the text:
106
+
107
+ - The hub refused the call.
108
+ - A value the method requires is missing.
109
+ - A value the method is not listed with was sent, such as
110
+ `price_of does not take colour`.
111
+ - A record the call names does not exist, such as `No item has the id 9`.
112
+
113
+ Show the reason to the person or the model making the call. Do not retry it
114
+ unchanged.
115
+
116
+ 9. Handle a JSON-RPC error. These come back as `error: { code, message }` with
117
+ status 200, and with the request's `id` except for -32700 and -32600, whose
118
+ `id` is null:
119
+
120
+ | Code | Message | When |
121
+ |---|---|---|
122
+ | -32700 | `Parse error` | The body is not valid JSON. |
123
+ | -32600 | `Invalid Request` | The body is not one JSON-RPC 2.0 request. |
124
+ | -32601 | `Method not found: <method>` | The MCP method is not one of the four above. |
125
+ | -32602 | `Unknown tool: <name>` | The tool does not exist, names a hub the host does not serve, or is one the caller may not call. |
126
+ | -32603 | `Internal error` | A hub method raised an unexpected error. |
127
+
128
+ -32602 reads the same in all three cases, so do not tell the person a tool
129
+ does not exist when it may only be one they cannot call. -32603 never carries
130
+ the error's own message, so find the cause in the host app's error reporting.
131
+
132
+ 10. In a test of the host app, send requests the same way, as a JSON POST to the
133
+ endpoint's path, signed in as the host's tests sign in:
134
+
135
+ ```ruby
136
+ post "/mcp", params: { jsonrpc: "2.0", id: 1, method: "tools/list" }, as: :json
137
+ ```
138
+
139
+ ## Conventions
140
+
141
+ - One request per POST, always with `"jsonrpc": "2.0"`, and an `id` on every
142
+ request that needs an answer.
143
+ - Build tool names from `tools/list`, never by hand, since the list is what the
144
+ signed-in person may call.
145
+ - Treat `isError: true` as an answer about the call, and a JSON-RPC `error` as an
146
+ answer about the request.
147
+ - The endpoint offers no sessions and no server-sent events, so do not open a GET
148
+ stream or send a session header.
149
+ - Out of scope: installing the endpoint, choosing its controller, sign-in, and
150
+ served hubs, and running the boot check, which belong to
151
+ `hub_kernel-mcp-install`, and setting which methods a hub exposes, who may
152
+ call them and their account scope, which belong to hub_kernel-interface.
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: hub_kernel-mcp-info
3
+ description: Use to learn what hub_kernel-mcp offers — serving a host's hubs as MCP tools, how tools are named and scoped, and the vocabulary the install and develop locals assume.
4
+ tools: Read
5
+ scope: hub MCP tools — serving the methods every hub a host serves, from hub_kernel-interface's one served list, as MCP tools at one JSON-RPC endpoint in a host Rails app, each call behind the host's own sign-in and hub_kernel-interface's permission check and account scope, with a boot check for hubs that cannot be served as tools
6
+ ---
7
+
8
+ This local explains hub_kernel-mcp and makes no changes.
9
+
10
+ ## What hub_kernel-mcp is
11
+
12
+ hub_kernel-mcp lets an MCP client, such as an AI assistant, call the methods a
13
+ Rails host app's hubs expose. It reads the host's one served list from
14
+ hub_kernel-interface, the same list every interface gem reads, and offers each
15
+ method the caller may call as an MCP tool at a single JSON-RPC endpoint inside
16
+ the host app.
17
+
18
+ Reach for it when a host already serves hubs through hub_kernel-interface and
19
+ wants an assistant to read or change that data on a person's behalf. Every call
20
+ passes through the host's own sign-in first, then hub_kernel-interface's
21
+ permission check and account scope, so a tool can do nothing the signed-in
22
+ person could not already do. A boot check refuses to start a host whose served
23
+ hubs cannot be turned into valid tool names.
24
+
25
+ ## Interface
26
+
27
+ This local declares no entry points of its own.
28
+
29
+ - Adding the gem to a host, mounting the endpoint, configuring which controller
30
+ and which person and account methods it uses, and running the boot check are
31
+ owned by the install local, `hub_kernel-mcp-install`.
32
+ - The endpoint itself and the MCP requests it answers are owned by the develop
33
+ local, `hub_kernel-mcp-develop`.
34
+
35
+ ## How to use it
36
+
37
+ - To put hub_kernel-mcp into a Rails app, or to fix a host whose boot check
38
+ fails, use `hub_kernel-mcp-install`.
39
+ - To change what the endpoint answers, add support for another MCP request, or
40
+ change how tools are listed, called or refused, use `hub_kernel-mcp-develop`.
41
+ - To decide which hubs are served at all, or to change permissions and account
42
+ scope, work in hub_kernel-interface, which owns the served list and those
43
+ checks.
44
+
45
+ ## Conventions
46
+
47
+ - **Host** — the Rails app that mounts the endpoint and serves the hubs.
48
+ - **Hub** — a hub_kernel object whose exposed methods are the units a caller may
49
+ call. hub_kernel-mcp defines no hubs.
50
+ - **Served list and served name** — the host's one list of hubs in
51
+ hub_kernel-interface, where each hub is served under a name. A served name may
52
+ not hold two underscores in a row.
53
+ - **Tool** — one exposed hub method, named `<served name>__<method>`, using only
54
+ letters, digits, underscores and hyphens, and at most 64 characters long. Its
55
+ input schema names the values the method takes.
56
+ - **Reads and writes** — a tool for a method that writes is marked as not
57
+ read-only and described as changing data, so a client can ask before calling
58
+ it.
59
+ - **Person and account** — who a request is made for and which account it is
60
+ scoped to, both supplied by methods on the host's own controller.
61
+ - **Tool error and JSON-RPC error** — a hub's refusal, a missing or unlisted
62
+ value, or a record that does not exist comes back as a tool error carrying the
63
+ reason. A tool the caller may not call, or one that does not exist, comes back
64
+ as the same JSON-RPC error, `Unknown tool`, so a caller cannot tell the two
65
+ apart. An unexpected error is reported to the host's error reporting and its
66
+ message is never sent to the client.
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: hub_kernel-mcp-install
3
+ description: Use to hook hub_kernel-mcp into a project — adding the gem, naming the controller the endpoint inherits from and the person and account methods on it, running the boot check after the served list is set, and mounting the engine.
4
+ tools: Bash, Read, Edit
5
+ scope: hub MCP tools — serving the methods every hub a host serves, from hub_kernel-interface's one served list, as MCP tools at one JSON-RPC endpoint in a host Rails app, each call behind the host's own sign-in and hub_kernel-interface's permission check and account scope, with a boot check for hubs that cannot be served as tools
6
+ ---
7
+
8
+ This local follows these steps exactly and invents none. Where a step names a
9
+ decision, it asks the developer and does not pick.
10
+
11
+ ## What hub_kernel-mcp is
12
+
13
+ A Rails engine that serves every method the host's hubs expose as MCP tools at
14
+ one JSON-RPC endpoint. Hook it in when the host already serves hubs through
15
+ hub_kernel-interface and wants an MCP client to call them on a signed-in
16
+ person's behalf.
17
+
18
+ ## Interface
19
+
20
+ - `gem "hub_kernel-mcp"` — adds the gem to the host's `Gemfile`. It requires
21
+ Rails 8.1.3 or later and Ruby 3.2 or later, and brings in
22
+ `hub_kernel-interface` `~> 0.6`.
23
+ - `mount HubKernel::Mcp::Engine` — mounts the endpoint in the host's
24
+ `config/routes.rb` at the path given. The path answers POST with JSON-RPC and
25
+ answers GET with status 405.
26
+ - `HubKernel::Mcp.base_controller=` — the name, as a String, of the host
27
+ controller the endpoint inherits from. Its before-actions, including sign-in,
28
+ run before any hub is asked. Defaults to `"ActionController::API"`, which has
29
+ no sign-in.
30
+ - `HubKernel::Mcp.person_method=` — the name, as a Symbol, of the method on the
31
+ base controller that returns the person a request is made for. No default.
32
+ - `HubKernel::Mcp.account_method=` — the name, as a Symbol, of the method on the
33
+ base controller that returns the account a request is scoped to. No default.
34
+ - `HubKernel::Mcp.check!` — the boot check. Raises
35
+ `HubKernel::Mcp::UnservableHubError` when any served hub cannot be served as
36
+ tools, and returns nothing otherwise.
37
+ - `HubKernel::Mcp::UnservableHubError` — the error `check!` raises. Its message
38
+ names every problem found, one per line. It is the same class as
39
+ `HubKernel::Interface::UnservableHubError`, so rescuing either catches it.
40
+
41
+ ## How to use it
42
+
43
+ 1. Add the gem to the host's `Gemfile` and install it:
44
+
45
+ ```ruby
46
+ gem "hub_kernel-mcp"
47
+ ```
48
+
49
+ ```
50
+ bundle install
51
+ ```
52
+
53
+ 2. Ask the developer which host controller the endpoint should inherit from.
54
+ It must already sign the caller in and refuse a caller who is not signed in,
55
+ in a before-action, since the endpoint adds no sign-in of its own. It must
56
+ also accept a JSON POST with no CSRF token: an `ActionController::API`
57
+ subclass does, and an `ActionController::Base` subclass with forgery
58
+ protection refuses every request unless that protection is skipped for this
59
+ endpoint. Ask whether to use an existing controller or add a new one, and do
60
+ not choose the sign-in method yourself.
61
+
62
+ 3. Ask the developer which method on that controller returns the person a
63
+ request is made for, and which returns the account it is scoped to. Both are
64
+ called on the controller with no arguments, may be private, and must exist
65
+ on the base controller or a class it inherits from. If either is missing,
66
+ ask what it should return before adding it.
67
+
68
+ 4. Create `config/initializers/hub_kernel_mcp.rb` with the three answers:
69
+
70
+ ```ruby
71
+ HubKernel::Mcp.base_controller = "Api::HubBaseController"
72
+ HubKernel::Mcp.person_method = :current_person
73
+ HubKernel::Mcp.account_method = :current_account
74
+ ```
75
+
76
+ Set these in an initializer, not in `to_prepare`, so they are set before the
77
+ endpoint's controller loads. The controller name is a String. Leaving
78
+ `person_method` or `account_method` unset makes every `tools/list` and
79
+ `tools/call` request answer with JSON-RPC error -32603, `Internal error`.
80
+
81
+ 5. Find where the host sets its served list, `HubKernel::Interface.hubs = [...]`,
82
+ inside `Rails.application.config.to_prepare`. Add `HubKernel::Mcp.check!` on
83
+ the line after it, in the same block:
84
+
85
+ ```ruby
86
+ Rails.application.config.to_prepare do
87
+ HubKernel::Interface.hubs = [ Supplies, { "money" => Billing::Ledger } ]
88
+ HubKernel::Mcp.check!
89
+ end
90
+ ```
91
+
92
+ If the block already calls `HubKernel::Interface.check!`, keep or remove it
93
+ as the developer prefers, since `HubKernel::Mcp.check!` reports every problem
94
+ that check finds as well. If the host sets no served list yet, stop and tell
95
+ the developer that the hubs to serve are chosen in hub_kernel-interface
96
+ first, and do not invent the list.
97
+
98
+ 6. Ask the developer what path to mount the endpoint at, then add the mount to
99
+ `config/routes.rb`:
100
+
101
+ ```ruby
102
+ mount HubKernel::Mcp::Engine => "/mcp"
103
+ ```
104
+
105
+ ## Conventions
106
+
107
+ - After installing, boot the app or run `bin/rails runner "HubKernel::Mcp.check!"`.
108
+ An `UnservableHubError` there lists every problem to fix, one per line: a
109
+ problem hub_kernel-interface's own check finds, a served name holding two
110
+ underscores in a row, a tool name holding a character other than a letter, a
111
+ digit, an underscore or a hyphen, or a tool name longer than 64 characters.
112
+ A tool name is `<served name>__<method>`.
113
+ - Fix a check failure by changing the served name or the hub method in the host,
114
+ never by removing the check. Inside `to_prepare` the check runs again after
115
+ every code reload.
116
+ - Run the check again whenever the served list changes or a hub gains a method.
117
+ - A change to `config/initializers/hub_kernel_mcp.rb` takes effect only after
118
+ the app restarts.
119
+ - Out of scope: choosing which hubs are served and setting permissions and
120
+ account scope, which belong to hub_kernel-interface, and changing what the
121
+ endpoint answers, which belongs to `hub_kernel-mcp-develop`.
@@ -0,0 +1,24 @@
1
+ scope: hub MCP tools — serving the methods every hub a host serves, from hub_kernel-interface's one served list, as MCP tools at one JSON-RPC endpoint in a host Rails app, each call behind the host's own sign-in and hub_kernel-interface's permission check and account scope, with a boot check for hubs that cannot be served as tools
2
+
3
+ install:
4
+ - gem "hub_kernel-mcp"
5
+ - mount HubKernel::Mcp::Engine
6
+ - HubKernel::Mcp.base_controller=
7
+ - HubKernel::Mcp.person_method=
8
+ - HubKernel::Mcp.account_method=
9
+ - HubKernel::Mcp.check!
10
+ - HubKernel::Mcp::UnservableHubError
11
+
12
+ develop:
13
+ - POST /
14
+ - initialize
15
+ - ping
16
+ - tools/list
17
+ - tools/call
18
+
19
+ sources:
20
+ - lib/hub_kernel/mcp.rb
21
+ - lib/hub_kernel/mcp/engine.rb
22
+ - config/routes.rb
23
+ - app/controllers/hub_kernel/mcp/messages_controller.rb
24
+ - README.md
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.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tylercschneider
@@ -55,6 +55,10 @@ files:
55
55
  - lib/hub_kernel/mcp.rb
56
56
  - lib/hub_kernel/mcp/engine.rb
57
57
  - lib/hub_kernel/mcp/version.rb
58
+ - the_local/agents/hub_kernel-mcp-develop.md
59
+ - the_local/agents/hub_kernel-mcp-info.md
60
+ - the_local/agents/hub_kernel-mcp-install.md
61
+ - the_local/interface.yml
58
62
  homepage: https://github.com/DYB-Development/hub_kernel-mcp
59
63
  licenses:
60
64
  - MIT