legion-mcp 0.4.1 → 0.4.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: 37f03ddf4778cc238c0e69b039b9cd6c55acc2ada6207ef32c777c844d60d5e1
4
- data.tar.gz: ffe2b6b6da0930d795ca3965b86f5edabdf8f6b698232b110bd3ae6187ce0c20
3
+ metadata.gz: 423fca2b66220aa4bfd5dce33490a6fb92826da7e999a21be9afed00610fd435
4
+ data.tar.gz: 7e9a664b742ee174140f2463c008bd99475736afe074c056cf298d9742a7ec5d
5
5
  SHA512:
6
- metadata.gz: a4c148c867a384494dd92847f6ec4f25b6010d73ce3f076e6d01c0f5ae47c8a7c6d8cfa909da58f067334612f7b7420e87e388c0910fad2edf604ea45a670206
7
- data.tar.gz: eb8d5f6536df790298e4613a92f61f8a4e136d16d83ede2a99c92a9507ddfd8f7301fe52a12678f891b0227e1568660b77db008b09bd9e1a98f55644e64a56b2
6
+ metadata.gz: d610777e7f105a5b72e4a58fb0a06cd129361639837638b49888de9b6feeb3697a5147184d5d415ba95315d2bafcf3011b9a6c5d7515b8ceec3155a8173477a9
7
+ data.tar.gz: 6c74faf7a062f61e8b9e10d79b6236dc9b361d6b5ff657bfe651bfa731f6a633a8c8acaf0a68f907b49cd333c4328d77e919d45a114c8e8b7a40323bbfeb9dac
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # legion-mcp Changelog
2
2
 
3
+ ## [0.4.2] - 2026-03-22
4
+
5
+ ### Added
6
+ - `legion.ask_peer` — synchronous RPC query to a specific mesh peer via `lex-mesh` `request_task`
7
+ - `legion.list_peers` — list all registered mesh agents, with optional capability filter via `find_agents`
8
+ - `legion.notify_peer` — fire-and-forget unicast notification to a specific mesh agent via `send_message`
9
+ - `legion.broadcast_peers` — broadcast to all agents or multicast to a capability group via `send_message`
10
+ - `legion.mesh_status` — retrieve current mesh network state via `mesh_status`
11
+ - All 5 tools registered in `TOOL_CLASSES`; total tool count raised from 45 to 50
12
+ - Specs for all 5 new tools (25 examples)
13
+ - Updated `server_spec.rb` tool count assertion from 45 to 50
14
+
3
15
  ## [0.4.1] - 2026-03-19
4
16
 
5
17
  ### Added
data/CODEOWNERS ADDED
@@ -0,0 +1,39 @@
1
+ # Default owner — all files
2
+ * @Esity
3
+
4
+ # Core library code
5
+ # lib/ @Esity @future-ai-team
6
+
7
+ # MCP tools (35 tool subclasses)
8
+ # lib/legion/mcp/tools/ @Esity @future-ai-team
9
+
10
+ # MCP resources
11
+ # lib/legion/mcp/resources/ @Esity @future-ai-team
12
+
13
+ # Tiered Behavioral Intelligence (TBI) — pattern store, tier router, context guard
14
+ # lib/legion/mcp/pattern_store.rb @Esity @future-ai-team
15
+ # lib/legion/mcp/tier_router.rb @Esity @future-ai-team
16
+ # lib/legion/mcp/context_guard.rb @Esity @future-ai-team
17
+
18
+ # Semantic matching and embeddings
19
+ # lib/legion/mcp/context_compiler.rb @Esity @future-ai-team
20
+ # lib/legion/mcp/embedding_index.rb @Esity @future-ai-team
21
+
22
+ # Observer pipeline and usage filter
23
+ # lib/legion/mcp/observer.rb @Esity @future-ai-team
24
+ # lib/legion/mcp/usage_filter.rb @Esity @future-ai-team
25
+
26
+ # Tool governance
27
+ # lib/legion/mcp/tool_governance.rb @Esity @future-security-team
28
+
29
+ # Authentication
30
+ # lib/legion/mcp/auth.rb @Esity @future-security-team
31
+
32
+ # Specs
33
+ # spec/ @Esity @future-contributors
34
+
35
+ # Documentation
36
+ # *.md @Esity @future-docs-team
37
+
38
+ # CI/CD
39
+ # .github/ @Esity
@@ -50,6 +50,11 @@ require_relative 'cold_start'
50
50
  require_relative 'tools/do_action'
51
51
  require_relative 'tools/plan_action'
52
52
  require_relative 'tools/discover_tools'
53
+ require_relative 'tools/ask_peer'
54
+ require_relative 'tools/list_peers'
55
+ require_relative 'tools/notify_peer'
56
+ require_relative 'tools/broadcast_peers'
57
+ require_relative 'tools/mesh_status'
53
58
  require_relative 'resources/runner_catalog'
54
59
  require_relative 'resources/extension_info'
55
60
 
@@ -101,7 +106,12 @@ module Legion
101
106
  Tools::EvalResults,
102
107
  Tools::DoAction,
103
108
  Tools::PlanAction,
104
- Tools::DiscoverTools
109
+ Tools::DiscoverTools,
110
+ Tools::AskPeer,
111
+ Tools::ListPeers,
112
+ Tools::NotifyPeer,
113
+ Tools::BroadcastPeers,
114
+ Tools::MeshStatus
105
115
  ].freeze
106
116
 
107
117
  class << self
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module MCP
5
+ module Tools
6
+ class AskPeer < ::MCP::Tool
7
+ tool_name 'legion.ask_peer'
8
+ description 'Send a synchronous query to a specific mesh peer and return the result.'
9
+
10
+ input_schema(
11
+ properties: {
12
+ to: { type: 'string', description: 'Agent ID or capability name to route to' },
13
+ query: { type: 'string', description: 'The question or request to send to the peer' },
14
+ timeout: { type: 'integer', description: 'Seconds to wait for response (default 30)' }
15
+ },
16
+ required: %w[to query]
17
+ )
18
+
19
+ class << self
20
+ def call(to:, query:, timeout: 30)
21
+ return error_response('lex-mesh is not available') unless mesh_available?
22
+
23
+ result = mesh_client.request_task(
24
+ from: 'legion.mcp',
25
+ to: to,
26
+ task: 'query',
27
+ payload: { query: query },
28
+ timeout: timeout
29
+ )
30
+ text_response(result)
31
+ rescue StandardError => e
32
+ error_response("Failed to query peer: #{e.message}")
33
+ end
34
+
35
+ private
36
+
37
+ def mesh_available?
38
+ defined?(Legion::Extensions::Mesh::Client)
39
+ end
40
+
41
+ def mesh_client
42
+ @mesh_client ||= Legion::Extensions::Mesh::Client.new
43
+ end
44
+
45
+ def text_response(data)
46
+ ::MCP::Tool::Response.new([{ type: 'text', text: Legion::JSON.dump(data) }])
47
+ end
48
+
49
+ def error_response(msg)
50
+ ::MCP::Tool::Response.new([{ type: 'text', text: Legion::JSON.dump({ error: msg }) }], error: true)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module MCP
5
+ module Tools
6
+ class BroadcastPeers < ::MCP::Tool
7
+ tool_name 'legion.broadcast_peers'
8
+ description 'Broadcast a message to all mesh agents, or multicast to agents with a specific capability.'
9
+
10
+ input_schema(
11
+ properties: {
12
+ message: { type: 'string', description: 'Message content to broadcast' },
13
+ capability: { type: 'string', description: 'If provided, multicast only to agents with this capability' }
14
+ },
15
+ required: %w[message]
16
+ )
17
+
18
+ class << self
19
+ def call(message:, capability: nil)
20
+ return error_response('lex-mesh is not available') unless mesh_available?
21
+
22
+ pattern = capability ? :multicast : :broadcast
23
+ result = mesh_client.send_message(
24
+ from: 'legion.mcp',
25
+ to: capability || :all,
26
+ pattern: pattern,
27
+ payload: { message: message }
28
+ )
29
+ text_response(result)
30
+ rescue StandardError => e
31
+ error_response("Failed to broadcast: #{e.message}")
32
+ end
33
+
34
+ private
35
+
36
+ def mesh_available?
37
+ defined?(Legion::Extensions::Mesh::Client)
38
+ end
39
+
40
+ def mesh_client
41
+ @mesh_client ||= Legion::Extensions::Mesh::Client.new
42
+ end
43
+
44
+ def text_response(data)
45
+ ::MCP::Tool::Response.new([{ type: 'text', text: Legion::JSON.dump(data) }])
46
+ end
47
+
48
+ def error_response(msg)
49
+ ::MCP::Tool::Response.new([{ type: 'text', text: Legion::JSON.dump({ error: msg }) }], error: true)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module MCP
5
+ module Tools
6
+ class ListPeers < ::MCP::Tool
7
+ tool_name 'legion.list_peers'
8
+ description 'List all registered mesh agents, optionally filtered by capability.'
9
+
10
+ input_schema(
11
+ properties: {
12
+ capability: { type: 'string', description: 'Filter agents by capability' }
13
+ }
14
+ )
15
+
16
+ class << self
17
+ def call(capability: nil)
18
+ return error_response('lex-mesh is not available') unless mesh_available?
19
+
20
+ result = mesh_client.find_agents(capability: capability)
21
+ text_response(result)
22
+ rescue StandardError => e
23
+ error_response("Failed to list peers: #{e.message}")
24
+ end
25
+
26
+ private
27
+
28
+ def mesh_available?
29
+ defined?(Legion::Extensions::Mesh::Client)
30
+ end
31
+
32
+ def mesh_client
33
+ @mesh_client ||= Legion::Extensions::Mesh::Client.new
34
+ end
35
+
36
+ def text_response(data)
37
+ ::MCP::Tool::Response.new([{ type: 'text', text: Legion::JSON.dump(data) }])
38
+ end
39
+
40
+ def error_response(msg)
41
+ ::MCP::Tool::Response.new([{ type: 'text', text: Legion::JSON.dump({ error: msg }) }], error: true)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module MCP
5
+ module Tools
6
+ class MeshStatus < ::MCP::Tool
7
+ tool_name 'legion.mesh_status'
8
+ description 'Get current mesh network status including registered agents and topology.'
9
+
10
+ input_schema(properties: {})
11
+
12
+ class << self
13
+ def call
14
+ return error_response('lex-mesh is not available') unless mesh_available?
15
+
16
+ result = mesh_client.mesh_status
17
+ text_response(result)
18
+ rescue StandardError => e
19
+ error_response("Failed to get mesh status: #{e.message}")
20
+ end
21
+
22
+ private
23
+
24
+ def mesh_available?
25
+ defined?(Legion::Extensions::Mesh::Client)
26
+ end
27
+
28
+ def mesh_client
29
+ @mesh_client ||= Legion::Extensions::Mesh::Client.new
30
+ end
31
+
32
+ def text_response(data)
33
+ ::MCP::Tool::Response.new([{ type: 'text', text: Legion::JSON.dump(data) }])
34
+ end
35
+
36
+ def error_response(msg)
37
+ ::MCP::Tool::Response.new([{ type: 'text', text: Legion::JSON.dump({ error: msg }) }], error: true)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module MCP
5
+ module Tools
6
+ class NotifyPeer < ::MCP::Tool
7
+ tool_name 'legion.notify_peer'
8
+ description 'Send a fire-and-forget async notification to a specific mesh agent.'
9
+
10
+ input_schema(
11
+ properties: {
12
+ to: { type: 'string', description: 'Target agent ID' },
13
+ message: { type: 'string', description: 'Notification content to send' }
14
+ },
15
+ required: %w[to message]
16
+ )
17
+
18
+ class << self
19
+ def call(to:, message:)
20
+ return error_response('lex-mesh is not available') unless mesh_available?
21
+
22
+ result = mesh_client.send_message(
23
+ from: 'legion.mcp',
24
+ to: to,
25
+ pattern: :unicast,
26
+ payload: { message: message }
27
+ )
28
+ text_response(result)
29
+ rescue StandardError => e
30
+ error_response("Failed to notify peer: #{e.message}")
31
+ end
32
+
33
+ private
34
+
35
+ def mesh_available?
36
+ defined?(Legion::Extensions::Mesh::Client)
37
+ end
38
+
39
+ def mesh_client
40
+ @mesh_client ||= Legion::Extensions::Mesh::Client.new
41
+ end
42
+
43
+ def text_response(data)
44
+ ::MCP::Tool::Response.new([{ type: 'text', text: Legion::JSON.dump(data) }])
45
+ end
46
+
47
+ def error_response(msg)
48
+ ::MCP::Tool::Response.new([{ type: 'text', text: Legion::JSON.dump({ error: msg }) }], error: true)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Legion
4
4
  module MCP
5
- VERSION = '0.4.1'
5
+ VERSION = '0.4.2'
6
6
  end
7
7
  end
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.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -110,6 +110,7 @@ files:
110
110
  - ".rubocop.yml"
111
111
  - CHANGELOG.md
112
112
  - CLAUDE.md
113
+ - CODEOWNERS
113
114
  - Gemfile
114
115
  - LICENSE
115
116
  - README.md
@@ -134,6 +135,8 @@ files:
134
135
  - lib/legion/mcp/server.rb
135
136
  - lib/legion/mcp/tier_router.rb
136
137
  - lib/legion/mcp/tool_governance.rb
138
+ - lib/legion/mcp/tools/ask_peer.rb
139
+ - lib/legion/mcp/tools/broadcast_peers.rb
137
140
  - lib/legion/mcp/tools/create_chain.rb
138
141
  - lib/legion/mcp/tools/create_relationship.rb
139
142
  - lib/legion/mcp/tools/create_schedule.rb
@@ -159,10 +162,13 @@ files:
159
162
  - lib/legion/mcp/tools/get_task_logs.rb
160
163
  - lib/legion/mcp/tools/list_chains.rb
161
164
  - lib/legion/mcp/tools/list_extensions.rb
165
+ - lib/legion/mcp/tools/list_peers.rb
162
166
  - lib/legion/mcp/tools/list_relationships.rb
163
167
  - lib/legion/mcp/tools/list_schedules.rb
164
168
  - lib/legion/mcp/tools/list_tasks.rb
165
169
  - lib/legion/mcp/tools/list_workers.rb
170
+ - lib/legion/mcp/tools/mesh_status.rb
171
+ - lib/legion/mcp/tools/notify_peer.rb
166
172
  - lib/legion/mcp/tools/plan_action.rb
167
173
  - lib/legion/mcp/tools/prompt_list.rb
168
174
  - lib/legion/mcp/tools/prompt_run.rb