legion-mcp 0.8.0 → 0.9.1
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/.gitignore +1 -0
- data/CHANGELOG.md +49 -0
- data/CLAUDE.md +34 -42
- data/README.md +169 -45
- data/legion-mcp.gemspec +1 -1
- data/lib/legion/mcp/actors/self_generate_cycle.rb +3 -5
- data/lib/legion/mcp/audit.rb +50 -0
- data/lib/legion/mcp/auth.rb +70 -11
- data/lib/legion/mcp/catalog_dispatcher.rb +29 -50
- data/lib/legion/mcp/client/connection.rb +163 -59
- data/lib/legion/mcp/client/pool.rb +40 -5
- data/lib/legion/mcp/client/server_registry.rb +7 -0
- data/lib/legion/mcp/client.rb +4 -1
- data/lib/legion/mcp/cold_start.rb +7 -9
- data/lib/legion/mcp/context_compiler.rb +12 -1
- data/lib/legion/mcp/context_guard.rb +1 -3
- data/lib/legion/mcp/deferred_registry.rb +15 -5
- data/lib/legion/mcp/discovery.rb +18 -0
- data/lib/legion/mcp/dynamic_injector.rb +4 -1
- data/lib/legion/mcp/embedding_index.rb +5 -3
- data/lib/legion/mcp/function_discovery.rb +46 -6
- data/lib/legion/mcp/gap_detector.rb +8 -3
- data/lib/legion/mcp/observer.rb +11 -9
- data/lib/legion/mcp/override_broadcast.rb +4 -3
- data/lib/legion/mcp/patterns/compiler.rb +59 -0
- data/lib/legion/mcp/patterns/exchange.rb +63 -0
- data/lib/legion/mcp/patterns/gossip.rb +68 -0
- data/lib/legion/mcp/patterns/schema.rb +92 -0
- data/lib/legion/mcp/patterns/store.rb +469 -0
- data/lib/legion/mcp/patterns.rb +25 -0
- data/lib/legion/mcp/resources/extension_info.rb +1 -3
- data/lib/legion/mcp/resources/runner_catalog.rb +24 -3
- data/lib/legion/mcp/self_generate.rb +6 -9
- data/lib/legion/mcp/server.rb +185 -84
- data/lib/legion/mcp/state_tracker.rb +4 -4
- data/lib/legion/mcp/structural_index.rb +6 -4
- data/lib/legion/mcp/tier_router.rb +55 -95
- data/lib/legion/mcp/tool_adapter.rb +101 -1
- data/lib/legion/mcp/tool_governance.rb +71 -5
- data/lib/legion/mcp/tool_quality.rb +3 -0
- data/lib/legion/mcp/tools/create_chain.rb +1 -3
- data/lib/legion/mcp/tools/create_relationship.rb +1 -3
- data/lib/legion/mcp/tools/create_schedule.rb +0 -2
- data/lib/legion/mcp/tools/delete_chain.rb +1 -3
- data/lib/legion/mcp/tools/delete_relationship.rb +1 -3
- data/lib/legion/mcp/tools/delete_schedule.rb +0 -2
- data/lib/legion/mcp/tools/delete_task.rb +0 -2
- data/lib/legion/mcp/tools/describe_runner.rb +0 -2
- data/lib/legion/mcp/tools/discover_tools.rb +2 -2
- data/lib/legion/mcp/tools/do_action.rb +102 -116
- data/lib/legion/mcp/tools/get_task.rb +0 -2
- data/lib/legion/mcp/tools/get_task_logs.rb +0 -2
- data/lib/legion/mcp/tools/list_chains.rb +1 -3
- data/lib/legion/mcp/tools/list_relationships.rb +0 -2
- data/lib/legion/mcp/tools/list_schedules.rb +0 -2
- data/lib/legion/mcp/tools/list_tasks.rb +0 -2
- data/lib/legion/mcp/tools/plan_action.rb +0 -2
- data/lib/legion/mcp/tools/run_task.rb +0 -2
- data/lib/legion/mcp/tools/search_sessions.rb +1 -2
- data/lib/legion/mcp/tools/skills.rb +2 -4
- data/lib/legion/mcp/tools/state_diff.rb +0 -1
- data/lib/legion/mcp/tools/structural_index.rb +0 -1
- data/lib/legion/mcp/tools/tool_audit.rb +0 -1
- data/lib/legion/mcp/tools/update_chain.rb +1 -3
- data/lib/legion/mcp/tools/update_relationship.rb +1 -3
- data/lib/legion/mcp/tools/update_schedule.rb +0 -2
- data/lib/legion/mcp/tools_loader.rb +13 -50
- data/lib/legion/mcp/tracing_context.rb +58 -0
- data/lib/legion/mcp/transport/exchanges/audit.rb +15 -0
- data/lib/legion/mcp/transport/messages/client_call_event.rb +23 -0
- data/lib/legion/mcp/transport/messages/governance_event.rb +23 -0
- data/lib/legion/mcp/transport/messages/tool_call_event.rb +23 -0
- data/lib/legion/mcp/usage_filter.rb +6 -1
- data/lib/legion/mcp/{logging_support.rb → utils.rb} +3 -29
- data/lib/legion/mcp/version.rb +1 -1
- data/lib/legion/mcp.rb +27 -5
- metadata +17 -48
- data/lib/legion/mcp/pattern_compiler.rb +0 -55
- data/lib/legion/mcp/pattern_exchange.rb +0 -61
- data/lib/legion/mcp/pattern_gossip.rb +0 -68
- data/lib/legion/mcp/pattern_schema.rb +0 -80
- data/lib/legion/mcp/pattern_store.rb +0 -492
- data/lib/legion/mcp/tools/absorb.rb +0 -64
- data/lib/legion/mcp/tools/ask_peer.rb +0 -61
- data/lib/legion/mcp/tools/broadcast_peers.rb +0 -60
- data/lib/legion/mcp/tools/dataset_list.rb +0 -55
- data/lib/legion/mcp/tools/dataset_show.rb +0 -61
- data/lib/legion/mcp/tools/disable_extension.rb +0 -57
- data/lib/legion/mcp/tools/enable_extension.rb +0 -57
- data/lib/legion/mcp/tools/eval_list.rb +0 -55
- data/lib/legion/mcp/tools/eval_results.rb +0 -86
- data/lib/legion/mcp/tools/eval_run.rb +0 -64
- data/lib/legion/mcp/tools/experiment_results.rb +0 -86
- data/lib/legion/mcp/tools/get_config.rb +0 -68
- data/lib/legion/mcp/tools/get_extension.rb +0 -63
- data/lib/legion/mcp/tools/get_status.rb +0 -61
- data/lib/legion/mcp/tools/knowledge_context.rb +0 -108
- data/lib/legion/mcp/tools/knowledge_health.rb +0 -62
- data/lib/legion/mcp/tools/list_extensions.rb +0 -53
- data/lib/legion/mcp/tools/list_peers.rb +0 -52
- data/lib/legion/mcp/tools/list_workers.rb +0 -61
- data/lib/legion/mcp/tools/mesh_status.rb +0 -48
- data/lib/legion/mcp/tools/mind_growth_approve.rb +0 -53
- data/lib/legion/mcp/tools/mind_growth_build_queue.rb +0 -48
- data/lib/legion/mcp/tools/mind_growth_cognitive_profile.rb +0 -48
- data/lib/legion/mcp/tools/mind_growth_health.rb +0 -48
- data/lib/legion/mcp/tools/mind_growth_propose.rb +0 -60
- data/lib/legion/mcp/tools/mind_growth_status.rb +0 -48
- data/lib/legion/mcp/tools/notify_peer.rb +0 -59
- data/lib/legion/mcp/tools/prompt_list.rb +0 -55
- data/lib/legion/mcp/tools/prompt_run.rb +0 -66
- data/lib/legion/mcp/tools/prompt_show.rb +0 -62
- data/lib/legion/mcp/tools/query_knowledge.rb +0 -56
- data/lib/legion/mcp/tools/rbac_assignments.rb +0 -50
- data/lib/legion/mcp/tools/rbac_check.rb +0 -51
- data/lib/legion/mcp/tools/rbac_grants.rb +0 -46
- data/lib/legion/mcp/tools/routing_stats.rb +0 -58
- data/lib/legion/mcp/tools/show_worker.rb +0 -55
- data/lib/legion/mcp/tools/team_summary.rb +0 -62
- data/lib/legion/mcp/tools/worker_costs.rb +0 -62
- data/lib/legion/mcp/tools/worker_lifecycle.rb +0 -63
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79ba0ac270a1e93bfb9558d37194307398336a43d759c7a9457daa28ca2e01a6
|
|
4
|
+
data.tar.gz: d97d87371fe9b4127d07a907abbd3b623015ce58be95425229eb17f9ad1885d6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 633cef5680447266ec2276df835d4f571f3d3d7ece699c857e26cf2f2208d1823d655d2c9d8ecdf3a0431beaea0761d6c0fa0752fe92e134c7d82bede4f62c79
|
|
7
|
+
data.tar.gz: 66ccd7b86d37ecb681c1fe83dd719c2fff4daa45a6b67bf4c9cd8eef5d51aa444068d8cb6f4edf24bf7271cdadb6eced92cc91eccaabe4326c6bc92b8cef1b54
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# legion-mcp Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.1] - 2026-04-30
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- `Audit.transport_connected?` rescue block now calls `handle_exception` at `:debug` level instead of silently swallowing the error
|
|
7
|
+
- `ToolAdapter.dispatch_tool_instance` `rescue ArgumentError` (keyword-to-positional fallback) now calls `handle_exception` at `:debug` level
|
|
8
|
+
- `SkillInvoke.invoke_skill` cleanup rescue now calls `handle_exception` at `:warn` level before re-raising
|
|
9
|
+
- `Client::Connection.verify_connection!` rescue now calls `handle_exception` at `:error` level before re-raising as `ConnectionError`
|
|
10
|
+
- `Client::Connection.fetch_tools` rescue now calls `handle_exception` at `:warn` level before re-raising as `ConnectionError`
|
|
11
|
+
- `Client::Connection.execute_tool_call` `RequestHandlerError` rescue now calls `handle_exception` at `:warn` level before re-raising as `ConnectionError`
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Added debug-level logging to `Client.register`, `Client.deregister`, `ServerRegistry.deregister`, and `ServerRegistry.mark_healthy` for full action traceability
|
|
15
|
+
- Updated README.md to reflect 0.9.x architecture: DeferredRegistry, Client pool, Settings::Extensions integration, correct version, dependency floors, and file map
|
|
16
|
+
|
|
17
|
+
## [0.9.0] - 2026-04-29
|
|
18
|
+
|
|
19
|
+
### Removed
|
|
20
|
+
- 38 hardcoded tool files that duplicated dynamic extension discovery (extensions, workers, RBAC, status, config, prompts, datasets, evals, mind-growth, knowledge, mesh, absorb) — these are now auto-discovered via `Settings::Extensions`
|
|
21
|
+
- `LoggingSupport` module — replaced by direct `Legion::Logging::Helper` + `Utils` module
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- `FunctionDiscovery.discover_and_register` now prefers reading tools from `Legion::Settings::Extensions` (the centralized registry in `legion-settings`) when available and populated, falling back to existing `Legion::Tools::Discovery` and runner-module discovery paths for backward compatibility
|
|
25
|
+
- `ToolAdapter.from_registry_entry` builds MCP tool classes from registry entry hashes; delegates to `from_legion_tool` when the entry contains a loaded tool class, otherwise builds a thin metadata-driven adapter
|
|
26
|
+
- `ToolAdapter.build_from_metadata` handles `:mcp_remote` dispatch type by proxying calls through `MCP::Client::Pool` instead of dispatching to a local tool class
|
|
27
|
+
- `Resources::RunnerCatalog#catalog_json` reads from `Settings::Extensions.runners` when available, falling back to the existing `legion-data` database query path
|
|
28
|
+
- `tools_loader.rb` now requires only 8 MCP-specific and 18 legion-data CRUD tool files (down from 65)
|
|
29
|
+
- All logging in server, catalog_dispatcher, observer, pattern_store, tier_router, do_action, and client/connection migrated from `LoggingSupport` to direct `log.*` calls with `Utils.format_fields`
|
|
30
|
+
- Bumped `legion-settings` dependency floor to `>= 1.4.0` (requires `Settings::Extensions` module)
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
- `Utils` module (`lib/legion/mcp/utils.rb`) — pure-function summarization and formatting helpers extracted from `LoggingSupport`
|
|
34
|
+
- `Client::Pool.refresh_tools!` — re-fetches and re-registers all remote server tools
|
|
35
|
+
- `Client::Pool.all_tools` now registers each remote tool into `Settings::Extensions` with `dispatch_type: :mcp_remote`
|
|
36
|
+
- `Server.register_mcp_tools_in_settings_extensions` — registers `MCP_SPECIFIC_TOOLS` into `Settings::Extensions` with `dispatch_type: :class_call` after build
|
|
37
|
+
- `patterns.rb` barrel file — requires all 13 Tier 0 pattern routing modules
|
|
38
|
+
- `discovery.rb` barrel file — requires all 12 tool discovery and adaptation modules
|
|
39
|
+
- `FunctionDiscovery.settings_extensions_available?` — guard method checking if `Settings::Extensions` is defined and populated
|
|
40
|
+
- `FunctionDiscovery.register_from_settings_extensions` — registers tools from the centralized registry into the MCP server
|
|
41
|
+
- `ToolAdapter.from_registry_entry` — factory method to build MCP tools from registry entry hashes
|
|
42
|
+
- `ToolAdapter.build_from_metadata` — builds thin MCP tool adapters from metadata when no tool class is loaded
|
|
43
|
+
- `RunnerCatalog#settings_extensions_runners_available?` — guard for registry-based runner catalog
|
|
44
|
+
- `RunnerCatalog#catalog_from_settings_extensions` — builds runner catalog JSON from the centralized registry
|
|
45
|
+
|
|
46
|
+
## [0.8.1] - 2026-04-14
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
- `ContextCompiler::CATEGORIES` now includes a `:skills` category listing all four `legion.skill.*` tools (`legion.skill.list`, `legion.skill.describe`, `legion.skill.invoke`, `legion.skill.cancel`). Previously they were absent from `CATEGORIES` so `compressed_catalog` never surfaced them and `legion.do intent:"list all skills"` would misroute to an auto-discovered swarm-github runner, returning "missing keywords: :owner, :repo, :pull_number"
|
|
50
|
+
- `ContextCompiler#keyword_score_map` now adds a +3 bonus per intent keyword that matches tool name terms (split on `.`), preventing semantic-score drift from lifting generic runner stubs above correctly-named skill tools when embeddings are active
|
|
51
|
+
|
|
3
52
|
## [0.8.0] - 2026-04-12
|
|
4
53
|
|
|
5
54
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
Standalone gem providing the Model Context Protocol (MCP) server for LegionIO. Extracted from LegionIO to enable independent versioning and reuse. Includes semantic tool matching, observation pipeline, context compilation, tiered inference (Tier 0/1/2), and tool governance.
|
|
8
8
|
|
|
9
9
|
**GitHub**: https://github.com/LegionIO/legion-mcp
|
|
10
|
-
**Version**: 0.
|
|
10
|
+
**Version**: 0.9.0
|
|
11
11
|
**License**: Apache-2.0
|
|
12
12
|
**Ruby**: >= 3.4
|
|
13
13
|
|
|
@@ -15,29 +15,27 @@ Standalone gem providing the Model Context Protocol (MCP) server for LegionIO. E
|
|
|
15
15
|
|
|
16
16
|
```
|
|
17
17
|
Legion::MCP
|
|
18
|
-
├── Server # MCP::Server builder, governance-aware build; tool list sourced from Legion::
|
|
18
|
+
├── Server # MCP::Server builder, governance-aware build; tool list sourced from Legion::Settings::Extensions via DeferredRegistry
|
|
19
19
|
├── Auth # JWT + API key authentication
|
|
20
|
+
├── Utils # Pure-function summarization and formatting helpers (extracted from LoggingSupport)
|
|
20
21
|
├── ToolGovernance # Risk-tier tool filtering + invocation audit
|
|
21
|
-
├──
|
|
22
|
-
├──
|
|
23
|
-
├──
|
|
24
|
-
├──
|
|
25
|
-
├──
|
|
26
|
-
├──
|
|
27
|
-
├──
|
|
28
|
-
├──
|
|
29
|
-
├── DeferredRegistry # Reads deferred tools from Legion::Tools::Registry at request time
|
|
30
|
-
├── Tools/ # MCP_SPECIFIC_TOOLS only (6 registered); remaining tool files exist but are not registered in Server.tool_registry — extension tools discovered via Legion::Tools::Discovery
|
|
22
|
+
├── ToolAdapter # Adapts Legion::Tools::Base to MCP SDK format; handles :mcp_remote dispatch
|
|
23
|
+
├── DeferredRegistry # Reads deferred/always-loaded tools from Legion::Settings::Extensions at request time
|
|
24
|
+
├── Client::Pool # Remote MCP server connections; registers tools into Settings::Extensions
|
|
25
|
+
├── Client::Connection # stdio and HTTP transport connections with TTL-cached tool lists
|
|
26
|
+
├── Client::ServerRegistry # Static and dynamic server registration with health tracking
|
|
27
|
+
├── patterns.rb # Barrel: PatternStore, TierRouter, ContextGuard, Observer, etc. (13 modules)
|
|
28
|
+
├── discovery.rb # Barrel: FunctionDiscovery, ToolAdapter, ToolGovernance, etc. (12 modules)
|
|
29
|
+
├── Tools/ # MCP_SPECIFIC_TOOLS (10) + legion-data CRUD tools (18); extension tools via Settings::Extensions
|
|
31
30
|
└── Resources/ # RunnerCatalog, ExtensionInfo
|
|
32
31
|
```
|
|
33
32
|
|
|
34
|
-
### Tool Registry
|
|
33
|
+
### Tool Registry
|
|
35
34
|
|
|
36
|
-
- **
|
|
37
|
-
- **
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
- `EmbeddingIndex` uses `Legion::Tools::EmbeddingCache` (5-tier L0–L4) instead of its own in-memory store.
|
|
35
|
+
- **MCP_SPECIFIC_TOOLS** (10 tools): do_action, discover_tools, plan_action, structural_index, tool_audit, state_diff, search_sessions, skill_list, skill_describe, skill_invoke, skill_cancel
|
|
36
|
+
- **legion-data CRUD** (18 tools): run_task, describe_runner, list/get/delete tasks, get_task_logs, CRUD chains/relationships/schedules
|
|
37
|
+
- **Extension tools**: Auto-discovered via `Legion::Settings::Extensions` at runtime; not shipped as static files
|
|
38
|
+
- **Remote MCP tools**: Fetched from remote servers via `Client::Pool.all_tools`, registered into `Settings::Extensions` with `dispatch_type: :mcp_remote`
|
|
41
39
|
|
|
42
40
|
## Dependencies
|
|
43
41
|
|
|
@@ -46,8 +44,8 @@ Legion::MCP
|
|
|
46
44
|
| `mcp` (~> 0.8) | Yes | MCP server SDK |
|
|
47
45
|
| `legion-data` (>= 1.4) | Yes | Sequel models, migrations |
|
|
48
46
|
| `legion-json` (>= 1.2) | Yes | JSON serialization |
|
|
49
|
-
| `legion-logging` (>=
|
|
50
|
-
| `legion-settings` (>= 0
|
|
47
|
+
| `legion-logging` (>= 1.4.3) | Yes | Logging via Helper |
|
|
48
|
+
| `legion-settings` (>= 1.4.0) | Yes | Configuration + Settings::Extensions |
|
|
51
49
|
| `legion-cache` | Optional | L1 pattern cache (memcached/redis) |
|
|
52
50
|
| `legion-llm` | Optional | Embeddings for semantic matching |
|
|
53
51
|
| `legionio` | Dev only | Full framework for integration testing |
|
|
@@ -58,6 +56,7 @@ All optional dependencies use `defined?()` guards:
|
|
|
58
56
|
- `defined?(Legion::Cache)` for L1 cache operations
|
|
59
57
|
- `defined?(Legion::Data::Local)` for L2 SQLite persistence
|
|
60
58
|
- `defined?(Legion::LLM)` for embedding generation
|
|
59
|
+
- `defined?(Legion::Settings::Extensions)` for central tool registry
|
|
61
60
|
- `defined?(Legion::MCP::EmbeddingIndex)` for semantic matching
|
|
62
61
|
- `defined?(Legion::MCP::TierRouter)` for Tier 0 routing
|
|
63
62
|
- Every storage write wraps in `begin/rescue => nil` -- failed persistence never blocks Tier 0
|
|
@@ -68,6 +67,7 @@ All optional dependencies use `defined?()` guards:
|
|
|
68
67
|
- **Tier routing**: Tier 0 (>= 0.8 confidence, cached), Tier 1 (0.6-0.8, local/fleet), Tier 2 (< 0.6, cloud)
|
|
69
68
|
- **Pattern promotion**: Observer records intent+tool pairs; after 3 successful observations, promotes to PatternStore with seeded confidence 0.5
|
|
70
69
|
- **Context guards**: Staleness (1hr), rapid-fire (5 in 10min), anomaly (2 consecutive misses) prevent stale Tier 0
|
|
70
|
+
- **Settings::Extensions integration**: MCP-specific tools register with `dispatch_type: :class_call`; remote MCP tools register with `dispatch_type: :mcp_remote`
|
|
71
71
|
|
|
72
72
|
## File Map
|
|
73
73
|
|
|
@@ -75,33 +75,25 @@ All optional dependencies use `defined?()` guards:
|
|
|
75
75
|
|------|---------|
|
|
76
76
|
| `lib/legion/mcp.rb` | Entry point: `Legion::MCP.server` singleton factory |
|
|
77
77
|
| `lib/legion/mcp/version.rb` | `Legion::MCP::VERSION` constant |
|
|
78
|
-
| `lib/legion/mcp/
|
|
78
|
+
| `lib/legion/mcp/utils.rb` | Pure-function summarization and formatting helpers |
|
|
79
|
+
| `lib/legion/mcp/server.rb` | MCP::Server builder, governance-aware build; reads tools from Settings::Extensions |
|
|
79
80
|
| `lib/legion/mcp/auth.rb` | JWT + API key authentication |
|
|
80
|
-
| `lib/legion/mcp/
|
|
81
|
-
| `lib/legion/mcp/
|
|
82
|
-
| `lib/legion/mcp/
|
|
83
|
-
| `lib/legion/mcp/
|
|
84
|
-
| `lib/legion/mcp/
|
|
85
|
-
| `lib/legion/mcp/
|
|
86
|
-
| `lib/legion/mcp/
|
|
87
|
-
| `lib/legion/mcp/context_guard.rb` | Staleness, rapid-fire, anomaly detection |
|
|
88
|
-
| `lib/legion/mcp/tool_adapter.rb` | MCP::ToolAdapter — wraps Legion::Tools::Base for MCP SDK (McpToolAdapter kept as alias) |
|
|
89
|
-
| `lib/legion/mcp/deferred_registry.rb` | DeferredRegistry — reads deferred tools from Legion::Tools::Registry at request time |
|
|
90
|
-
| `lib/legion/mcp/tools/` | All tool implementations; only MCP_SPECIFIC_TOOLS (6 tools) registered in Server.tool_registry — extension tools sourced via Legion::Tools::Discovery |
|
|
81
|
+
| `lib/legion/mcp/patterns.rb` | Barrel file for 13 Tier 0 pattern routing modules |
|
|
82
|
+
| `lib/legion/mcp/discovery.rb` | Barrel file for 12 tool discovery and adaptation modules |
|
|
83
|
+
| `lib/legion/mcp/tool_adapter.rb` | MCP::ToolAdapter — wraps tools for MCP SDK; handles :mcp_remote dispatch |
|
|
84
|
+
| `lib/legion/mcp/client.rb` | Client boot/shutdown, server registration |
|
|
85
|
+
| `lib/legion/mcp/client/pool.rb` | Connection pool; all_tools registers into Settings::Extensions |
|
|
86
|
+
| `lib/legion/mcp/client/connection.rb` | stdio/HTTP transport connections |
|
|
87
|
+
| `lib/legion/mcp/client/server_registry.rb` | Server health tracking and registration |
|
|
91
88
|
| `lib/legion/mcp/tools/do_action.rb` | Natural language intent routing with Tier 0 fast path |
|
|
92
89
|
| `lib/legion/mcp/tools/discover_tools.rb` | Dynamic tool discovery with context |
|
|
93
90
|
| `lib/legion/mcp/tools/run_task.rb` | Execute runner function via dot notation |
|
|
94
|
-
| `lib/legion/mcp/tools/query_knowledge.rb` | Query Apollo knowledge store |
|
|
95
|
-
| `lib/legion/mcp/tools/knowledge_health.rb` | Knowledge store health and quality report |
|
|
96
|
-
| `lib/legion/mcp/tools/knowledge_context.rb` | Scoped RAG query (local/global/all) for current-task context |
|
|
97
|
-
| `lib/legion/mcp/tools/eval_*.rb` | Evaluation management (list/run/results) |
|
|
98
|
-
| `lib/legion/mcp/tools/experiment_results.rb` | A/B experiment result comparison |
|
|
99
|
-
| `lib/legion/mcp/tools/dataset_*.rb` | Dataset browsing (list/show) |
|
|
100
|
-
| `lib/legion/mcp/tools/prompt_*.rb` | Prompt template management (list/show/run) |
|
|
101
91
|
| `lib/legion/mcp/tools/plan_action.rb` | Agentic planning with action decomposition |
|
|
102
|
-
| `lib/legion/mcp/tools/
|
|
103
|
-
| `lib/legion/mcp/tools/
|
|
104
|
-
| `lib/legion/mcp/tools/
|
|
92
|
+
| `lib/legion/mcp/tools/skills.rb` | Skill list/describe/invoke/cancel tools |
|
|
93
|
+
| `lib/legion/mcp/tools/structural_index.rb` | Query precomputed structural index |
|
|
94
|
+
| `lib/legion/mcp/tools/tool_audit.rb` | Audit registered tools quality |
|
|
95
|
+
| `lib/legion/mcp/tools/state_diff.rb` | Changed system state since timestamp |
|
|
96
|
+
| `lib/legion/mcp/tools/search_sessions.rb` | Search past conversation sessions |
|
|
105
97
|
| `lib/legion/mcp/resources/runner_catalog.rb` | `legion://runners` resource |
|
|
106
98
|
| `lib/legion/mcp/resources/extension_info.rb` | `legion://extensions/{name}` resource template |
|
|
107
99
|
|
data/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# legion-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Model Context Protocol (MCP) server for the LegionIO framework. Provides semantic tool matching, observation pipeline, context compilation, tiered behavioral intelligence (Tier 0/1/2 routing), tool governance, deferred tool loading, and MCP client pooling for remote server federation.
|
|
4
4
|
|
|
5
|
-
**Version**: 0.
|
|
5
|
+
**Version**: 0.9.1
|
|
6
|
+
**License**: Apache-2.0
|
|
7
|
+
**Ruby**: >= 3.4
|
|
6
8
|
|
|
7
9
|
Extracted from [LegionIO](https://github.com/LegionIO/LegionIO) for independent versioning and reuse.
|
|
8
10
|
|
|
@@ -15,27 +17,53 @@ gem 'legion-mcp'
|
|
|
15
17
|
Or in a Gemfile:
|
|
16
18
|
|
|
17
19
|
```ruby
|
|
18
|
-
gem 'legion-mcp', '~> 0.
|
|
20
|
+
gem 'legion-mcp', '~> 0.9'
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
## Architecture
|
|
22
24
|
|
|
23
25
|
```
|
|
24
26
|
Legion::MCP
|
|
25
|
-
├── Server # MCP::Server builder,
|
|
27
|
+
├── Server # MCP::Server builder, governance-aware build; tool list sourced via DeferredRegistry
|
|
26
28
|
├── Auth # JWT + API key authentication
|
|
29
|
+
├── Utils # Pure-function summarization and formatting helpers
|
|
27
30
|
├── ToolGovernance # Risk-tier tool filtering + invocation audit
|
|
28
|
-
├──
|
|
31
|
+
├── ToolAdapter # Adapts Legion::Tools::Base to MCP SDK format; handles :mcp_remote dispatch
|
|
32
|
+
├── DeferredRegistry # Reads deferred/always-loaded tools from Settings::Extensions at request time
|
|
33
|
+
├── ContextCompiler # Keyword + semantic tool matching (60/40 blend), 17 categories
|
|
29
34
|
├── EmbeddingIndex # In-memory vector cache for semantic matching
|
|
30
|
-
├── Observer # Instrumentation: counters, ring buffer, pattern promotion
|
|
35
|
+
├── Observer # Instrumentation: counters, ring buffer, intent tracking, pattern promotion
|
|
31
36
|
├── UsageFilter # Frequency/recency/keyword scoring for dynamic tool filtering
|
|
32
|
-
├──
|
|
37
|
+
├── DynamicInjector # Context-aware tool injection/removal with tools/list_changed notification
|
|
38
|
+
├── CatalogDispatcher # Dispatch layer routing MCP calls through Legion::Ingress
|
|
39
|
+
├── Patterns::Store # 3-layer degrading storage (L0 memory -> L1 cache -> L2 SQLite)
|
|
40
|
+
├── Patterns::Schema # Portable pattern format with trust-level confidence capping
|
|
41
|
+
├── Patterns::Exchange # Bulk import/export of patterns via JSON files
|
|
42
|
+
├── Patterns::Gossip # AMQP-based pattern sharing between instances
|
|
43
|
+
├── Patterns::Compiler # Compressed tool definitions and compiled workflows
|
|
33
44
|
├── TierRouter # Confidence-gated tier selection (0/1/2)
|
|
34
|
-
├── ContextGuard # Staleness, rapid-fire, anomaly detection
|
|
35
|
-
├──
|
|
45
|
+
├── ContextGuard # Staleness, rapid-fire, anomaly detection guards
|
|
46
|
+
├── StateTracker # In-memory state snapshots with delta diff computation
|
|
47
|
+
├── StructuralIndex # Precomputed index of extensions, runners, actors, and tools
|
|
48
|
+
├── ToolQuality # Docstring quality audit, category resolution, capability matrix
|
|
49
|
+
├── GapDetector # Unmatched intents, high-failure tools, stale candidate detection
|
|
50
|
+
├── SelfGenerate # Gap detection + publication cycles with cooldown
|
|
51
|
+
├── OverrideBroadcast # Mesh-wide override confirmation via RabbitMQ
|
|
52
|
+
├── TracingContext # Thread-local conversation/request/exchange/trace ID propagation
|
|
53
|
+
├── Client::Pool # Remote MCP server connections; registers tools into Settings::Extensions
|
|
54
|
+
├── Client::Connection # stdio and HTTP transport connections with TTL-cached tool lists
|
|
55
|
+
├── Client::ServerRegistry # Static and dynamic server registration with health tracking
|
|
56
|
+
├── Tools/ # 10 MCP-specific + 18 legion-data CRUD tools; extension tools via Settings::Extensions
|
|
36
57
|
└── Resources/ # RunnerCatalog, ExtensionInfo
|
|
37
58
|
```
|
|
38
59
|
|
|
60
|
+
### Tool Registry
|
|
61
|
+
|
|
62
|
+
- **MCP_SPECIFIC_TOOLS** (10 tools): `do_action`, `discover_tools`, `plan_action`, `structural_index`, `tool_audit`, `state_diff`, `search_sessions`, `skill_list`, `skill_describe`, `skill_invoke`, `skill_cancel`
|
|
63
|
+
- **legion-data CRUD** (18 tools): `run_task`, `describe_runner`, list/get/delete tasks, `get_task_logs`, CRUD chains/relationships/schedules
|
|
64
|
+
- **Extension tools**: Auto-discovered via `Legion::Settings::Extensions` at runtime; not shipped as static files
|
|
65
|
+
- **Remote MCP tools**: Fetched from remote servers via `Client::Pool.all_tools`, registered into `Settings::Extensions` with `dispatch_type: :mcp_remote`
|
|
66
|
+
|
|
39
67
|
## Tiered Behavioral Intelligence
|
|
40
68
|
|
|
41
69
|
Requests flow through three tiers, each with increasing latency and capability:
|
|
@@ -65,7 +93,7 @@ If any guard triggers, the request escalates to Tier 1.
|
|
|
65
93
|
|
|
66
94
|
### Storage Layers
|
|
67
95
|
|
|
68
|
-
PatternStore degrades gracefully across
|
|
96
|
+
PatternStore degrades gracefully across 3 layers:
|
|
69
97
|
|
|
70
98
|
| Layer | Backend | Requirement |
|
|
71
99
|
|-------|---------|-------------|
|
|
@@ -73,40 +101,31 @@ PatternStore degrades gracefully across 4 layers:
|
|
|
73
101
|
| L1 | Legion::Cache (memcached/redis) | `defined?(Legion::Cache)` |
|
|
74
102
|
| L2 | Legion::Data::Local (SQLite) | `defined?(Legion::Data::Local)` |
|
|
75
103
|
|
|
76
|
-
All persistence wraps in `begin/rescue => nil`
|
|
104
|
+
All persistence wraps in `begin/rescue => nil` -- failed writes never block Tier 0.
|
|
77
105
|
|
|
78
106
|
## Tools
|
|
79
107
|
|
|
80
|
-
|
|
108
|
+
28 built-in MCP tools in the `legion.*` namespace (10 MCP-specific + 18 legion-data CRUD). Extension-owned tools are auto-discovered at runtime via `Legion::Settings::Extensions`.
|
|
81
109
|
|
|
82
110
|
| Tool | Purpose |
|
|
83
111
|
|------|---------|
|
|
84
112
|
| `legion.do` | Natural language intent routing (Tier 0 fast path) |
|
|
85
|
-
| `legion.
|
|
113
|
+
| `legion.tools` | Dynamic tool discovery by category, intent, or schema resolution |
|
|
114
|
+
| `legion.plan` | Multi-step workflow planning with LLM narrative |
|
|
115
|
+
| `legion.structural_index` | Precomputed structural index of extensions/runners/actors/tools |
|
|
116
|
+
| `legion.tool_audit` | Quality audit of registered tools (summary/matrix/issues) |
|
|
117
|
+
| `legion.state_diff` | Delta state polling since a given timestamp |
|
|
118
|
+
| `legion.search_sessions` | Search past conversation sessions by keyword |
|
|
119
|
+
| `legion.skill.list` | List all registered LLM skills |
|
|
120
|
+
| `legion.skill.describe` | Describe a specific skill |
|
|
121
|
+
| `legion.skill.invoke` | Invoke a skill for a conversation |
|
|
122
|
+
| `legion.skill.cancel` | Cancel an active skill run |
|
|
86
123
|
| `legion.run_task` | Execute a runner function via dot notation |
|
|
87
124
|
| `legion.describe_runner` | Runner/function discovery |
|
|
88
|
-
| `legion.list_tasks` / `get_task` / `delete_task` | Task CRUD |
|
|
89
|
-
| `legion.get_task_logs` | Task execution logs |
|
|
125
|
+
| `legion.list_tasks` / `get_task` / `delete_task` / `get_task_logs` | Task CRUD + logs |
|
|
90
126
|
| `legion.list_chains` / `create_chain` / `update_chain` / `delete_chain` | Chain management |
|
|
91
|
-
| `legion.list_relationships` / `
|
|
92
|
-
| `legion.
|
|
93
|
-
| `legion.list_schedules` / `create_schedule` / `update_schedule` / `delete_schedule` | Schedule CRUD |
|
|
94
|
-
| `legion.get_status` / `get_config` | System introspection |
|
|
95
|
-
| `legion.list_workers` / `show_worker` / `worker_lifecycle` / `worker_costs` | Worker management |
|
|
96
|
-
| `legion.team_summary` / `routing_stats` | Team and routing metrics |
|
|
97
|
-
| `legion.rbac_assignments` / `rbac_check` / `rbac_grants` | Access control |
|
|
98
|
-
| `legion.mind_growth_status` / `mind_growth_propose` / `mind_growth_approve` | Cognitive architecture growth |
|
|
99
|
-
| `legion.mind_growth_build_queue` / `mind_growth_cognitive_profile` / `mind_growth_health` | Growth analysis and health |
|
|
100
|
-
| `legion.query_knowledge` | Query Apollo knowledge store |
|
|
101
|
-
| `legion.knowledge_health` | Knowledge store health and quality report |
|
|
102
|
-
| `legion.knowledge_context` | Scoped RAG knowledge retrieval (local/global/all) |
|
|
103
|
-
| `legion.eval_list` / `eval_run` / `eval_results` | Evaluation management |
|
|
104
|
-
| `legion.experiment_results` | A/B experiment result comparison |
|
|
105
|
-
| `legion.dataset_list` / `dataset_show` | Dataset browsing |
|
|
106
|
-
| `legion.prompt_list` / `prompt_show` / `prompt_run` | Prompt template management |
|
|
107
|
-
| `legion.plan_action` | Agentic planning with action decomposition |
|
|
108
|
-
| `legion.ask_peer` / `notify_peer` / `broadcast_peers` / `list_peers` | Agent mesh communication |
|
|
109
|
-
| `legion.mesh_status` | Mesh topology status |
|
|
127
|
+
| `legion.list_relationships` / `create_*` / `update_*` / `delete_*` | Relationship CRUD |
|
|
128
|
+
| `legion.list_schedules` / `create_*` / `update_*` / `delete_*` | Schedule CRUD |
|
|
110
129
|
|
|
111
130
|
## Resources
|
|
112
131
|
|
|
@@ -115,6 +134,24 @@ All persistence wraps in `begin/rescue => nil` — failed writes never block Tie
|
|
|
115
134
|
| `legion://runners` | All registered extension.runner.function paths |
|
|
116
135
|
| `legion://extensions/{name}` | Extension detail template |
|
|
117
136
|
|
|
137
|
+
## MCP Client (Federation)
|
|
138
|
+
|
|
139
|
+
Connect to remote MCP servers via stdio or HTTP transport:
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
# Via settings (loaded at boot)
|
|
143
|
+
# settings/mcp.json:
|
|
144
|
+
# { "mcp": { "servers": { "code_server": { "transport": "stdio", "command": "npx @example/mcp-server" } } } }
|
|
145
|
+
|
|
146
|
+
Legion::MCP::Client.boot
|
|
147
|
+
|
|
148
|
+
# Or register at runtime
|
|
149
|
+
Legion::MCP::Client.register(:my_server, transport: :http, url: 'http://localhost:9393/mcp')
|
|
150
|
+
|
|
151
|
+
# All remote tools are registered into Settings::Extensions with dispatch_type: :mcp_remote
|
|
152
|
+
tools = Legion::MCP::Client::Pool.all_tools
|
|
153
|
+
```
|
|
154
|
+
|
|
118
155
|
## Usage
|
|
119
156
|
|
|
120
157
|
### Standalone MCP server
|
|
@@ -123,7 +160,6 @@ All persistence wraps in `begin/rescue => nil` — failed writes never block Tie
|
|
|
123
160
|
require 'legion/mcp'
|
|
124
161
|
|
|
125
162
|
server = Legion::MCP.server
|
|
126
|
-
# Start via stdio transport
|
|
127
163
|
server.start
|
|
128
164
|
```
|
|
129
165
|
|
|
@@ -153,6 +189,13 @@ when 2 then puts "Escalate to cloud LLM"
|
|
|
153
189
|
end
|
|
154
190
|
```
|
|
155
191
|
|
|
192
|
+
### Identity-scoped server
|
|
193
|
+
|
|
194
|
+
```ruby
|
|
195
|
+
server = Legion::MCP.server_for(token: jwt_token)
|
|
196
|
+
# Returns governance-filtered tool set based on JWT claims
|
|
197
|
+
```
|
|
198
|
+
|
|
156
199
|
## Configuration
|
|
157
200
|
|
|
158
201
|
All configuration is optional and read via `Legion::Settings` when available:
|
|
@@ -160,12 +203,40 @@ All configuration is optional and read via `Legion::Settings` when available:
|
|
|
160
203
|
```json
|
|
161
204
|
{
|
|
162
205
|
"mcp": {
|
|
163
|
-
"
|
|
164
|
-
"
|
|
165
|
-
"
|
|
166
|
-
"
|
|
167
|
-
"
|
|
168
|
-
|
|
206
|
+
"auth": {
|
|
207
|
+
"enabled": false,
|
|
208
|
+
"require_auth": false,
|
|
209
|
+
"jwt_secret": null,
|
|
210
|
+
"jwt_algorithm": "HS256",
|
|
211
|
+
"jwt_issuer": "legion",
|
|
212
|
+
"allowed_api_keys": []
|
|
213
|
+
},
|
|
214
|
+
"governance": {
|
|
215
|
+
"enabled": false,
|
|
216
|
+
"audit_invocations": true,
|
|
217
|
+
"tool_risk_tiers": {}
|
|
218
|
+
},
|
|
219
|
+
"deferred_loading": {
|
|
220
|
+
"enabled": true,
|
|
221
|
+
"always_loaded": []
|
|
222
|
+
},
|
|
223
|
+
"dynamic_tools": {
|
|
224
|
+
"enabled": false,
|
|
225
|
+
"max_injected": 10
|
|
226
|
+
},
|
|
227
|
+
"tier0": {
|
|
228
|
+
"guards": {
|
|
229
|
+
"max_stale_seconds": 3600,
|
|
230
|
+
"rapid_fire_threshold": 5,
|
|
231
|
+
"rapid_fire_window_seconds": 600
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"auto_expose_runners": false,
|
|
235
|
+
"servers": {},
|
|
236
|
+
"cold_start": {
|
|
237
|
+
"patterns_path": null
|
|
238
|
+
},
|
|
239
|
+
"roles": {}
|
|
169
240
|
}
|
|
170
241
|
}
|
|
171
242
|
```
|
|
@@ -177,10 +248,32 @@ All configuration is optional and read via `Legion::Settings` when available:
|
|
|
177
248
|
| `mcp` (~> 0.8) | Yes | MCP server SDK |
|
|
178
249
|
| `legion-data` (>= 1.4) | Yes | Sequel models, migrations |
|
|
179
250
|
| `legion-json` (>= 1.2) | Yes | JSON serialization |
|
|
180
|
-
| `legion-logging` (>=
|
|
181
|
-
| `legion-settings` (>= 0
|
|
182
|
-
| `legion-cache` | Optional | L1 pattern cache |
|
|
183
|
-
| `legion-llm` | Optional | Embeddings for semantic matching |
|
|
251
|
+
| `legion-logging` (>= 1.4.3) | Yes | Structured logging via Helper |
|
|
252
|
+
| `legion-settings` (>= 1.4.0) | Yes | Configuration + Settings::Extensions |
|
|
253
|
+
| `legion-cache` | Optional | L1 pattern cache (memcached/redis) |
|
|
254
|
+
| `legion-llm` | Optional | Embeddings for semantic matching, Tier 1/2 LLM |
|
|
255
|
+
|
|
256
|
+
## Guard Strategy
|
|
257
|
+
|
|
258
|
+
All optional dependencies use `defined?()` guards:
|
|
259
|
+
- `defined?(Legion::Cache)` for L1 cache operations
|
|
260
|
+
- `defined?(Legion::Data::Local)` for L2 SQLite persistence
|
|
261
|
+
- `defined?(Legion::LLM)` for embedding generation and tiered LLM routing
|
|
262
|
+
- `defined?(Legion::Settings::Extensions)` for central tool registry
|
|
263
|
+
- `defined?(Legion::MCP::EmbeddingIndex)` for semantic matching
|
|
264
|
+
- `defined?(Legion::MCP::TierRouter)` for Tier 0 routing
|
|
265
|
+
|
|
266
|
+
Every storage write wraps in `begin/rescue => nil` -- failed persistence never blocks Tier 0.
|
|
267
|
+
|
|
268
|
+
## Key Conventions
|
|
269
|
+
|
|
270
|
+
- `Legion::JSON.load` returns **symbol keys** -- use `body[:data]`, not `body['data']`
|
|
271
|
+
- `Legion::JSON.dump` takes exactly 1 positional arg -- wrap kwargs in explicit `{}`
|
|
272
|
+
- `::Process` and `::JSON` must be explicit inside the `Legion::` namespace
|
|
273
|
+
- `Legion::MCP.server` is a memoized singleton -- call `Legion::MCP.reset!` in tests
|
|
274
|
+
- MCP tool naming: `legion.snake_case_name` (dot namespace)
|
|
275
|
+
- Every rescue block calls `handle_exception(e, level:, handled:, operation:)`
|
|
276
|
+
- Logging via `extend Legion::Logging::Helper` (modules) or `include Legion::Logging::Helper` (classes/class << self)
|
|
184
277
|
|
|
185
278
|
## Development
|
|
186
279
|
|
|
@@ -191,6 +284,37 @@ bundle exec rubocop -A # auto-fix
|
|
|
191
284
|
bundle exec rubocop # lint check
|
|
192
285
|
```
|
|
193
286
|
|
|
287
|
+
## File Map
|
|
288
|
+
|
|
289
|
+
| Path | Purpose |
|
|
290
|
+
|------|---------|
|
|
291
|
+
| `lib/legion/mcp.rb` | Entry point: `Legion::MCP.server` singleton factory |
|
|
292
|
+
| `lib/legion/mcp/version.rb` | `Legion::MCP::VERSION` constant |
|
|
293
|
+
| `lib/legion/mcp/utils.rb` | Pure-function summarization and formatting helpers |
|
|
294
|
+
| `lib/legion/mcp/server.rb` | MCP::Server builder, governance-aware build; reads tools from Settings::Extensions |
|
|
295
|
+
| `lib/legion/mcp/auth.rb` | JWT + API key authentication |
|
|
296
|
+
| `lib/legion/mcp/patterns.rb` | Barrel file for 13 Tier 0 pattern routing modules |
|
|
297
|
+
| `lib/legion/mcp/discovery.rb` | Barrel file for 12 tool discovery and adaptation modules |
|
|
298
|
+
| `lib/legion/mcp/tool_adapter.rb` | MCP::ToolAdapter -- wraps tools for MCP SDK; handles :mcp_remote dispatch |
|
|
299
|
+
| `lib/legion/mcp/deferred_registry.rb` | Deferred/always-loaded tool list management |
|
|
300
|
+
| `lib/legion/mcp/catalog_dispatcher.rb` | Dispatch layer routing through Legion::Ingress |
|
|
301
|
+
| `lib/legion/mcp/dynamic_injector.rb` | Context-aware tool injection/removal |
|
|
302
|
+
| `lib/legion/mcp/client.rb` | Client boot/shutdown, server registration |
|
|
303
|
+
| `lib/legion/mcp/client/pool.rb` | Connection pool; all_tools registers into Settings::Extensions |
|
|
304
|
+
| `lib/legion/mcp/client/connection.rb` | stdio/HTTP transport connections |
|
|
305
|
+
| `lib/legion/mcp/client/server_registry.rb` | Server health tracking and registration |
|
|
306
|
+
| `lib/legion/mcp/tools/do_action.rb` | Natural language intent routing with Tier 0 fast path |
|
|
307
|
+
| `lib/legion/mcp/tools/discover_tools.rb` | Dynamic tool discovery with context |
|
|
308
|
+
| `lib/legion/mcp/tools/run_task.rb` | Execute runner function via dot notation |
|
|
309
|
+
| `lib/legion/mcp/tools/plan_action.rb` | Agentic planning with action decomposition |
|
|
310
|
+
| `lib/legion/mcp/tools/skills.rb` | Skill list/describe/invoke/cancel tools |
|
|
311
|
+
| `lib/legion/mcp/tools/structural_index.rb` | Query precomputed structural index |
|
|
312
|
+
| `lib/legion/mcp/tools/tool_audit.rb` | Audit registered tools quality |
|
|
313
|
+
| `lib/legion/mcp/tools/state_diff.rb` | Changed system state since timestamp |
|
|
314
|
+
| `lib/legion/mcp/tools/search_sessions.rb` | Search past conversation sessions |
|
|
315
|
+
| `lib/legion/mcp/resources/runner_catalog.rb` | `legion://runners` resource |
|
|
316
|
+
| `lib/legion/mcp/resources/extension_info.rb` | `legion://extensions/{name}` resource template |
|
|
317
|
+
|
|
194
318
|
## License
|
|
195
319
|
|
|
196
320
|
Apache-2.0
|
data/legion-mcp.gemspec
CHANGED
|
@@ -30,6 +30,6 @@ Gem::Specification.new do |spec|
|
|
|
30
30
|
spec.add_dependency 'legion-data', '>= 1.4.19'
|
|
31
31
|
spec.add_dependency 'legion-json', '>= 1.2.0'
|
|
32
32
|
spec.add_dependency 'legion-logging', '>= 1.4.3'
|
|
33
|
-
spec.add_dependency 'legion-settings', '>= 1.
|
|
33
|
+
spec.add_dependency 'legion-settings', '>= 1.4.0'
|
|
34
34
|
spec.add_dependency 'mcp', '~> 0.8'
|
|
35
35
|
end
|
|
@@ -14,14 +14,13 @@ module Legion
|
|
|
14
14
|
def generate_task? = false
|
|
15
15
|
|
|
16
16
|
def time
|
|
17
|
-
if
|
|
18
|
-
Legion::Settings.dig(:codegen, :self_generate, :cycle_interval) || 300
|
|
19
|
-
else
|
|
17
|
+
if Legion::Settings[:codegen].nil?
|
|
20
18
|
300
|
|
19
|
+
else
|
|
20
|
+
Legion::Settings.dig(:codegen, :self_generate, :cycle_interval) || 300
|
|
21
21
|
end
|
|
22
22
|
rescue StandardError => e
|
|
23
23
|
handle_exception(e, level: :warn, operation: 'legion.mcp.actors.self_generate_cycle.time')
|
|
24
|
-
log.warn(e.message)
|
|
25
24
|
300
|
|
26
25
|
end
|
|
27
26
|
|
|
@@ -29,7 +28,6 @@ module Legion
|
|
|
29
28
|
SelfGenerate.enabled?
|
|
30
29
|
rescue StandardError => e
|
|
31
30
|
handle_exception(e, level: :warn, operation: 'legion.mcp.actors.self_generate_cycle.enabled?')
|
|
32
|
-
log.warn(e.message)
|
|
33
31
|
false
|
|
34
32
|
end
|
|
35
33
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module MCP
|
|
5
|
+
module Audit
|
|
6
|
+
extend Legion::Logging::Helper
|
|
7
|
+
|
|
8
|
+
ROUTING_KEYS = {
|
|
9
|
+
tool_call: 'mcp.audit.tool_call',
|
|
10
|
+
client_call: 'mcp.audit.client_call',
|
|
11
|
+
governance: 'mcp.audit.governance'
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
def emit_tool_call(**event)
|
|
17
|
+
publish(ROUTING_KEYS[:tool_call], event, :ToolCallEvent)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def emit_client_call(**event)
|
|
21
|
+
publish(ROUTING_KEYS[:client_call], event, :ClientCallEvent)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def emit_governance(**event)
|
|
25
|
+
publish(ROUTING_KEYS[:governance], event, :GovernanceEvent)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def transport_available?
|
|
29
|
+
!!(defined?(Legion::Transport::Message) &&
|
|
30
|
+
defined?(Legion::MCP::Transport::Exchanges::Audit))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def transport_connected?
|
|
34
|
+
Legion::Settings.dig(:transport, :connected) == true
|
|
35
|
+
rescue StandardError => e
|
|
36
|
+
handle_exception(e, level: :debug, handled: true, operation: 'mcp.audit.transport_connected?')
|
|
37
|
+
false
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def publish(routing_key, event, message_sym)
|
|
41
|
+
return unless transport_available? && transport_connected?
|
|
42
|
+
|
|
43
|
+
message_class = Legion::MCP::Transport::Messages.const_get(message_sym)
|
|
44
|
+
message_class.new(routing_key: routing_key, **event).publish
|
|
45
|
+
rescue StandardError => e
|
|
46
|
+
handle_exception(e, level: :warn, handled: true, operation: 'mcp.audit.publish')
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|