stimulus_plumbers_mcp 0.4.10 → 0.4.12
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/lib/stimulus_plumbers/mcp/cli.rb +6 -4
- data/lib/stimulus_plumbers/mcp/loaders/support/gem_vendor_path.rb +7 -5
- data/lib/stimulus_plumbers/mcp/plugins/aria.rb +6 -2
- data/lib/stimulus_plumbers/mcp/plugins/base.rb +8 -3
- data/lib/stimulus_plumbers/mcp/plugins/component_docs.rb +6 -2
- data/lib/stimulus_plumbers/mcp/plugins/component_schema.rb +6 -2
- data/lib/stimulus_plumbers/mcp/plugins/component_theme.rb +6 -2
- data/lib/stimulus_plumbers/mcp/plugins/controller_docs.rb +6 -2
- data/lib/stimulus_plumbers/mcp/plugins/controller_schema.rb +6 -2
- data/lib/stimulus_plumbers/mcp/plugins/guide.rb +6 -2
- data/lib/stimulus_plumbers/mcp/plugins/icons.rb +6 -2
- data/lib/stimulus_plumbers/mcp/plugins/tailwind.rb +6 -2
- data/lib/stimulus_plumbers/mcp/plugins/versions.rb +6 -2
- data/lib/stimulus_plumbers/mcp/server.rb +51 -47
- data/lib/stimulus_plumbers/mcp/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a7e1a463be23b0151bf5c76cdc2472d5108b3ae7e2c663cdc309675a1c26ea63
|
|
4
|
+
data.tar.gz: ad60a395adac43fc03f0194e77f7bf5de86d048be7d1d52014a94705fcf3063c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4f006fe0c56518de69f5bf1cb0edf2f934ae5bf144096cd580d89fa607574419c7c38fa612b1eaad58e873f6ddf8bcae199f15a023c082ebfbada01add2af32e
|
|
7
|
+
data.tar.gz: 3b258e6a04bc5e01030c650daf914d09d66daee3b80030ab838f50b96a995128e1dcd2b679fb22fab06894cc05baaeba12007257b84fd78e091b00916843d3e5
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
module StimulusPlumbers
|
|
4
4
|
module MCP
|
|
5
5
|
module CLI
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
class << self
|
|
7
|
+
def run
|
|
8
|
+
server = Server.build
|
|
9
|
+
warn "[stimulus-plumbers-mcp] server started (version #{VERSION})"
|
|
10
|
+
::MCP::Server::Transports::StdioTransport.new(server).open
|
|
11
|
+
end
|
|
10
12
|
end
|
|
11
13
|
end
|
|
12
14
|
end
|
|
@@ -7,11 +7,13 @@ module StimulusPlumbers
|
|
|
7
7
|
module GemVendorPath
|
|
8
8
|
GEM_NAME = "stimulus_plumbers"
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
class << self
|
|
11
|
+
def resolve(*relative)
|
|
12
|
+
gem_dir = Gem::Specification.find_by_name(GEM_NAME).gem_dir
|
|
13
|
+
File.join(gem_dir, "vendor", *relative)
|
|
14
|
+
rescue Gem::MissingSpecError
|
|
15
|
+
nil
|
|
16
|
+
end
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
end
|
|
@@ -21,11 +21,16 @@ module StimulusPlumbers
|
|
|
21
21
|
raise NotImplementedError, "#{name} must define .read"
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def static_resources
|
|
24
|
+
def static_resources
|
|
25
|
+
[]
|
|
26
|
+
end
|
|
25
27
|
|
|
26
|
-
def dynamic_resource_templates
|
|
28
|
+
def dynamic_resource_templates
|
|
29
|
+
[]
|
|
30
|
+
end
|
|
27
31
|
|
|
28
|
-
def register_tools(_server, _store)
|
|
32
|
+
def register_tools(_server, _store)
|
|
33
|
+
end
|
|
29
34
|
|
|
30
35
|
def not_found(message)
|
|
31
36
|
NotFound.new(message)
|
|
@@ -5,9 +5,13 @@ module StimulusPlumbers
|
|
|
5
5
|
module Plugins
|
|
6
6
|
class ComponentDocs < Base
|
|
7
7
|
class << self
|
|
8
|
-
def loader_key
|
|
8
|
+
def loader_key
|
|
9
|
+
:component_docs
|
|
10
|
+
end
|
|
9
11
|
|
|
10
|
-
def loader
|
|
12
|
+
def loader
|
|
13
|
+
ComponentDocsLoader
|
|
14
|
+
end
|
|
11
15
|
|
|
12
16
|
def dynamic_resource_templates
|
|
13
17
|
[
|
|
@@ -5,9 +5,13 @@ module StimulusPlumbers
|
|
|
5
5
|
module Plugins
|
|
6
6
|
class ComponentSchema < Base
|
|
7
7
|
class << self
|
|
8
|
-
def loader_key
|
|
8
|
+
def loader_key
|
|
9
|
+
:component_schema
|
|
10
|
+
end
|
|
9
11
|
|
|
10
|
-
def loader
|
|
12
|
+
def loader
|
|
13
|
+
ComponentSchemaLoader
|
|
14
|
+
end
|
|
11
15
|
|
|
12
16
|
def static_resources
|
|
13
17
|
[
|
|
@@ -5,9 +5,13 @@ module StimulusPlumbers
|
|
|
5
5
|
module Plugins
|
|
6
6
|
class ComponentTheme < Base
|
|
7
7
|
class << self
|
|
8
|
-
def loader_key
|
|
8
|
+
def loader_key
|
|
9
|
+
:component_theme
|
|
10
|
+
end
|
|
9
11
|
|
|
10
|
-
def loader
|
|
12
|
+
def loader
|
|
13
|
+
ComponentThemeLoader
|
|
14
|
+
end
|
|
11
15
|
|
|
12
16
|
def static_resources
|
|
13
17
|
[
|
|
@@ -8,9 +8,13 @@ module StimulusPlumbers
|
|
|
8
8
|
# narrative markdown, grouped by controller family, not individual identifier).
|
|
9
9
|
class ControllerDocs < Base
|
|
10
10
|
class << self
|
|
11
|
-
def loader_key
|
|
11
|
+
def loader_key
|
|
12
|
+
:controller_docs
|
|
13
|
+
end
|
|
12
14
|
|
|
13
|
-
def loader
|
|
15
|
+
def loader
|
|
16
|
+
ControllerDocsLoader
|
|
17
|
+
end
|
|
14
18
|
|
|
15
19
|
def static_resources
|
|
16
20
|
[
|
|
@@ -5,9 +5,13 @@ module StimulusPlumbers
|
|
|
5
5
|
module Plugins
|
|
6
6
|
class ControllerSchema < Base
|
|
7
7
|
class << self
|
|
8
|
-
def loader_key
|
|
8
|
+
def loader_key
|
|
9
|
+
:controller_schema
|
|
10
|
+
end
|
|
9
11
|
|
|
10
|
-
def loader
|
|
12
|
+
def loader
|
|
13
|
+
ControllerSchemaLoader
|
|
14
|
+
end
|
|
11
15
|
|
|
12
16
|
def static_resources
|
|
13
17
|
[
|
|
@@ -7,9 +7,13 @@ module StimulusPlumbers
|
|
|
7
7
|
GUIDE_NAMES = %w[component controller tailwind theme].freeze
|
|
8
8
|
|
|
9
9
|
class << self
|
|
10
|
-
def loader_key
|
|
10
|
+
def loader_key
|
|
11
|
+
:guide
|
|
12
|
+
end
|
|
11
13
|
|
|
12
|
-
def loader
|
|
14
|
+
def loader
|
|
15
|
+
GuideLoader
|
|
16
|
+
end
|
|
13
17
|
|
|
14
18
|
def static_resources
|
|
15
19
|
[
|
|
@@ -5,9 +5,13 @@ module StimulusPlumbers
|
|
|
5
5
|
module Plugins
|
|
6
6
|
class Tailwind < Base
|
|
7
7
|
class << self
|
|
8
|
-
def loader_key
|
|
8
|
+
def loader_key
|
|
9
|
+
:tailwind
|
|
10
|
+
end
|
|
9
11
|
|
|
10
|
-
def loader
|
|
12
|
+
def loader
|
|
13
|
+
TailwindLoader
|
|
14
|
+
end
|
|
11
15
|
|
|
12
16
|
def static_resources
|
|
13
17
|
[
|
|
@@ -5,9 +5,13 @@ module StimulusPlumbers
|
|
|
5
5
|
module Plugins
|
|
6
6
|
class Versions < Base
|
|
7
7
|
class << self
|
|
8
|
-
def loader_key
|
|
8
|
+
def loader_key
|
|
9
|
+
:versions
|
|
10
|
+
end
|
|
9
11
|
|
|
10
|
-
def loader
|
|
12
|
+
def loader
|
|
13
|
+
VersionsLoader
|
|
14
|
+
end
|
|
11
15
|
|
|
12
16
|
def static_resources
|
|
13
17
|
[
|
|
@@ -19,64 +19,68 @@ module StimulusPlumbers
|
|
|
19
19
|
Plugins::Versions
|
|
20
20
|
].freeze
|
|
21
21
|
|
|
22
|
-
INSTRUCTIONS =
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
INSTRUCTIONS = <<~MSG.strip
|
|
23
|
+
Use these resources and tools for accurate API references when
|
|
24
|
+
generating Rails/ERB view code with the stimulus-plumbers UI library.
|
|
25
|
+
Read guide://overview first for a map of the form/view/stimulus API.
|
|
26
|
+
MSG
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
class << self
|
|
29
|
+
def build
|
|
30
|
+
store = build_store
|
|
31
|
+
report_sources(store)
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
server = new_server
|
|
34
|
+
server.resources_read_handler do |params|
|
|
35
|
+
PLUGINS.lazy.filter_map { |plugin| plugin.read(params[:uri], store) }.first ||
|
|
36
|
+
unknown_resource(params[:uri])
|
|
37
|
+
end
|
|
38
|
+
PLUGINS.each { |plugin| plugin.register_tools(server, store) }
|
|
39
|
+
server
|
|
34
40
|
end
|
|
35
|
-
PLUGINS.each { |plugin| plugin.register_tools(server, store) }
|
|
36
|
-
server
|
|
37
|
-
end
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
def build_store
|
|
43
|
+
PLUGINS.to_h { |plugin| [plugin.loader_key, plugin.loader.call] }
|
|
44
|
+
end
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
def unknown_resource(uri)
|
|
47
|
+
message = "unknown resource: #{uri} — read guide://overview for a map of available resources"
|
|
48
|
+
[{ uri: uri, mimeType: "application/json", text: JSON.generate(error: message) }]
|
|
49
|
+
end
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
def new_server
|
|
52
|
+
::MCP::Server.new(
|
|
53
|
+
name: "stimulus-plumbers",
|
|
54
|
+
version: StimulusPlumbers::MCP::VERSION,
|
|
55
|
+
instructions: INSTRUCTIONS,
|
|
56
|
+
resources: PLUGINS.flat_map(&:static_resources),
|
|
57
|
+
resource_templates: PLUGINS.flat_map(&:dynamic_resource_templates)
|
|
58
|
+
)
|
|
59
|
+
end
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
# Loaders fail soft (sibling paths may be absent), so report what resolved
|
|
62
|
+
# and warn loudly on any empty source instead of starting silently wrong.
|
|
63
|
+
def report_sources(store)
|
|
64
|
+
summary = store.map { |key, value| "#{key}=#{source_size(value)}" }.join(" ")
|
|
65
|
+
StimulusPlumbers::Logger.info("sources: #{summary}")
|
|
66
|
+
store.each_key do |key|
|
|
67
|
+
StimulusPlumbers::Logger.warn("source '#{key}' is empty") if empty_source?(store[key])
|
|
68
|
+
end
|
|
65
69
|
end
|
|
66
|
-
end
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
def source_size(value)
|
|
72
|
+
case value
|
|
73
|
+
when String then value.empty? ? 0 : "ok"
|
|
74
|
+
when Hash then value.key?(:components) ? value[:components].size : value.size
|
|
75
|
+
when Enumerable then value.size
|
|
76
|
+
else value.nil? ? 0 : 1
|
|
77
|
+
end
|
|
74
78
|
end
|
|
75
|
-
end
|
|
76
79
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
def empty_source?(value)
|
|
81
|
+
content = value.is_a?(Hash) && value.key?(:components) ? value[:components] : value
|
|
82
|
+
content.respond_to?(:empty?) && content.empty?
|
|
83
|
+
end
|
|
80
84
|
end
|
|
81
85
|
end
|
|
82
86
|
end
|