legion-mcp 0.5.0 → 0.5.2

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: 2eff77018e5f5162f17ce2582bee76bff4e78d73e3129c9cf3adac4f40922bd1
4
- data.tar.gz: fbc6a1ad1463750b1381a8d48e56b36c78a2166fd7514db74e0e1cba7a904df0
3
+ metadata.gz: d595c78d49bd3c3a7fc1a9fdde240f6a969b30b0aae59d2edbfaf246187f31a5
4
+ data.tar.gz: 680ce4836c3d6dc3351d9af4f8a312596b865d92038506782f1c203af8083de3
5
5
  SHA512:
6
- metadata.gz: 3e098a68af07e9af9c554fa77b116c2de2ed36a076ee332ff5bbb040d96957ec7f5afc390a4b4d743244b3b524a045b9390a19c4ed8ca2cddb279b17006e4a55
7
- data.tar.gz: 051acdc2bc2c3164400932f98fdc5a79a52f283766c8832d672cfdc44bdeed79c12a38745b450dbb501afe3ced38361418d0bbd279fc6d63ff28b25600ba1d11
6
+ metadata.gz: 2d0f20c472bcd79155cfa7e159887f2b40121945224bfcd5298b56ad27da71f100b4e7d516f87b55d9634ca08e42b2cb7288e4e8870ebd452634200975302ff4
7
+ data.tar.gz: 59fc5625a6779a9e5c1dd95d75793ae6effdfffcafd014144888784b72a9e6454605d87476b1e5990afd1a097129b7673e4a5904d2f4420f4266eb8e28c9e002
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # legion-mcp Changelog
2
2
 
3
+ ## [0.5.2] - 2026-03-23
4
+
5
+ ### Changed
6
+ - Bump legion-data dependency to >= 1.4.19
7
+
8
+ ## [0.5.1] - 2026-03-23
9
+
10
+ ### Added
11
+ - Dynamic tool list from `Catalog::Registry` merged with static TOOL_CLASSES
12
+ - `dispatch_catalog_tool` routes Catalog-sourced MCP tool calls to extension runners
13
+ - `CatalogBridge` module extracted for catalog integration (hydration, listener, dispatch, dynamic tools)
14
+ - `OverrideBroadcast` for mesh-wide override confirmation via RabbitMQ
15
+ - Hydrate `OverrideConfidence` from SQLite (L2) and Apollo (L3) at server boot
16
+ - MCP server resets automatically when Catalog registry changes
17
+
3
18
  ## [0.5.0] - 2026-03-23
4
19
 
5
20
  ### Added
data/legion-mcp.gemspec CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.add_dependency 'concurrent-ruby', '>= 1.2'
30
30
  spec.add_dependency 'mcp', '~> 0.8'
31
- spec.add_dependency 'legion-data', '>= 1.4.15'
31
+ spec.add_dependency 'legion-data', '>= 1.4.19'
32
32
  spec.add_dependency 'legion-json', '>= 1.2.0'
33
33
  spec.add_dependency 'legion-logging', '>= 1.2.8'
34
34
  spec.add_dependency 'legion-settings', '>= 1.3.12'
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module MCP
5
+ module CatalogBridge
6
+ def hydrate_override_confidence
7
+ return unless defined?(Legion::LLM::OverrideConfidence)
8
+ return unless Legion::LLM::OverrideConfidence.respond_to?(:hydrate_from_l2)
9
+
10
+ Legion::LLM::OverrideConfidence.hydrate_from_l2
11
+ Legion::LLM::OverrideConfidence.hydrate_from_apollo if Legion::LLM::OverrideConfidence.respond_to?(:hydrate_from_apollo)
12
+ end
13
+
14
+ def register_catalog_listener
15
+ return unless defined?(Legion::Extensions::Catalog::Registry)
16
+ return unless Legion::Extensions::Catalog::Registry.respond_to?(:on_change)
17
+
18
+ Legion::Extensions::Catalog::Registry.on_change { Legion::MCP.reset! }
19
+ end
20
+
21
+ def dispatch_catalog_tool(tool_name, arguments)
22
+ return nil unless defined?(Legion::Extensions::Catalog::Registry)
23
+
24
+ cap = Legion::Extensions::Catalog::Registry.find_by_mcp_name(tool_name)
25
+ return nil unless cap
26
+
27
+ segments = cap.extension.delete_prefix('lex-').split('-')
28
+ runner_path = (%w[Legion Extensions] + segments.map(&:capitalize) + ['Runners', cap.runner]).join('::')
29
+ runner = Kernel.const_get(runner_path)
30
+ fn = cap.function.to_sym
31
+ result = runner.send(fn, **(arguments || {}).transform_keys(&:to_sym))
32
+ { status: :success, result: result, source: :catalog }
33
+ rescue NameError => e
34
+ Legion::Logging.warn("Catalog dispatch failed: #{e.message}") if defined?(Legion::Logging)
35
+ nil
36
+ rescue StandardError => e
37
+ { status: :error, error: e.message, source: :catalog }
38
+ end
39
+
40
+ def dynamic_tool_list
41
+ static = Server::TOOL_CLASSES.map do |klass|
42
+ { name: klass.tool_name, description: klass.description,
43
+ input_schema: klass.input_schema, source: :builtin, klass: klass }
44
+ end
45
+
46
+ dynamic = if defined?(Legion::Extensions::Catalog::Registry)
47
+ Legion::Extensions::Catalog::Registry.for_mcp.map(&:to_mcp_tool)
48
+ else
49
+ []
50
+ end
51
+
52
+ static + dynamic
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module MCP
5
+ module OverrideBroadcast
6
+ EXCHANGE = 'legion.mesh'
7
+ ROUTING_KEY = 'override.confirmed'
8
+ CORROBORATION_BOOST = 0.3
9
+
10
+ module_function
11
+
12
+ def publish_confirmation(tool:, lex:, confidence:, tests:)
13
+ return unless defined?(Legion::Transport::Messages::Dynamic)
14
+
15
+ node_id = Legion::Settings.dig(:node, :id) rescue 'unknown' # rubocop:disable Style/RescueModifier
16
+ Legion::Transport::Messages::Dynamic.new(
17
+ function: 'override_confirmed',
18
+ exchange: EXCHANGE,
19
+ routing_key: ROUTING_KEY,
20
+ opts: {
21
+ tool: tool, lex: lex, confidence: confidence,
22
+ tests: tests, node: node_id, timestamp: Time.now.iso8601
23
+ }
24
+ ).publish
25
+ rescue StandardError => e
26
+ Legion::Logging.warn("Override broadcast failed: #{e.message}") if defined?(Legion::Logging)
27
+ end
28
+
29
+ def receive_confirmation(tool:, lex:, confidence:, tests:, node:)
30
+ return unless defined?(Legion::LLM::OverrideConfidence)
31
+
32
+ existing = Legion::LLM::OverrideConfidence.lookup(tool)
33
+
34
+ if existing
35
+ new_confidence = (existing[:confidence] + CORROBORATION_BOOST).clamp(0.0, 1.0)
36
+ Legion::LLM::OverrideConfidence.record(tool: tool, lex: lex, confidence: new_confidence)
37
+ else
38
+ Legion::LLM::OverrideConfidence.record(tool: tool, lex: lex, confidence: confidence * 0.8)
39
+ end
40
+
41
+ store_to_apollo(tool: tool, lex: lex, confidence: confidence, tests: tests, node: node)
42
+ rescue StandardError => e
43
+ Legion::Logging.warn("Override receive failed: #{e.message}") if defined?(Legion::Logging)
44
+ end
45
+
46
+ def store_to_apollo(tool:, lex:, confidence:, tests:, node:)
47
+ return unless defined?(Legion::Extensions::Apollo::Runners::Knowledge)
48
+
49
+ Legion::Extensions::Apollo::Runners::Knowledge.handle_ingest(
50
+ content: "Override confirmed: #{tool} -> #{lex} (confidence: #{confidence}, tests: #{tests})",
51
+ content_type: 'fact',
52
+ tags: %w[override mesh_confirmed] + [tool],
53
+ source_agent: "mesh:#{node}",
54
+ knowledge_domain: 'system',
55
+ context: { tool: tool, lex: lex, confidence: confidence, tests: tests }
56
+ )
57
+ rescue StandardError
58
+ nil
59
+ end
60
+
61
+ private_class_method :store_to_apollo
62
+ end
63
+ end
64
+ end
@@ -55,6 +55,7 @@ require_relative 'tools/list_peers'
55
55
  require_relative 'tools/notify_peer'
56
56
  require_relative 'tools/broadcast_peers'
57
57
  require_relative 'tools/mesh_status'
58
+ require_relative 'catalog_bridge'
58
59
  require_relative 'resources/runner_catalog'
59
60
  require_relative 'resources/extension_info'
60
61
 
@@ -115,6 +116,8 @@ module Legion
115
116
  ].freeze
116
117
 
117
118
  class << self
119
+ include CatalogBridge
120
+
118
121
  def build(identity: nil)
119
122
  tools = if ToolGovernance.governance_enabled?
120
123
  ToolGovernance.filter_tools(TOOL_CLASSES, identity)
@@ -153,6 +156,9 @@ module Legion
153
156
  Resources::RunnerCatalog.register(server)
154
157
  Resources::ExtensionInfo.register_read_handler(server)
155
158
 
159
+ register_catalog_listener
160
+ hydrate_override_confidence
161
+
156
162
  server
157
163
  end
158
164
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Legion
4
4
  module MCP
5
- VERSION = '0.5.0'
5
+ VERSION = '0.5.2'
6
6
  end
7
7
  end
data/lib/legion/mcp.rb CHANGED
@@ -8,6 +8,7 @@ require_relative 'mcp/settings'
8
8
  require_relative 'mcp/auth'
9
9
  require_relative 'mcp/tool_governance'
10
10
  require_relative 'mcp/server'
11
+ require_relative 'mcp/override_broadcast'
11
12
  require_relative 'mcp/client'
12
13
 
13
14
  module Legion
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legion-mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -43,14 +43,14 @@ dependencies:
43
43
  requirements:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: 1.4.15
46
+ version: 1.4.19
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: 1.4.15
53
+ version: 1.4.19
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: legion-json
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -119,6 +119,7 @@ files:
119
119
  - lib/legion/mcp.rb
120
120
  - lib/legion/mcp/auth.rb
121
121
  - lib/legion/mcp/capability_generator.rb
122
+ - lib/legion/mcp/catalog_bridge.rb
122
123
  - lib/legion/mcp/client.rb
123
124
  - lib/legion/mcp/client/connection.rb
124
125
  - lib/legion/mcp/client/pool.rb
@@ -129,6 +130,7 @@ files:
129
130
  - lib/legion/mcp/embedding_index.rb
130
131
  - lib/legion/mcp/gap_detector.rb
131
132
  - lib/legion/mcp/observer.rb
133
+ - lib/legion/mcp/override_broadcast.rb
132
134
  - lib/legion/mcp/pattern_compiler.rb
133
135
  - lib/legion/mcp/pattern_exchange.rb
134
136
  - lib/legion/mcp/pattern_gossip.rb