Class: RosettAi::Thor::Tasks::Mcp
- Inherits:
-
Thor
- Object
- Thor
- RosettAi::Thor::Tasks::Mcp
- Defined in:
- lib/rosett_ai/thor/tasks/mcp.rb
Overview
Thor CLI for MCP server and administration.
Provides serve, list, validate, status, audit, key management, and trust source subcommands for MCP server management.
Instance Method Summary collapse
-
#add(name, uri) ⇒ void
Add a new entry.
-
#audit ⇒ void
Run a security audit on MCP configuration.
-
#generate_key ⇒ void
Generate a new MCP API key.
-
#list ⇒ void
List available items.
-
#list_keys ⇒ void
List all MCP API keys.
-
#remove(name) ⇒ void
Remove the component.
-
#revoke_key ⇒ void
Revoke an MCP API key.
-
#rotate_key ⇒ void
Rotate an MCP API key.
-
#serve ⇒ void
Start the MCP JSON-RPC server.
-
#status ⇒ String
Return the current status.
-
#tools ⇒ void
List registered MCP tools.
-
#trust_add(domain) ⇒ void
Add a trusted MCP source.
-
#trust_remove(domain) ⇒ void
Remove a trusted MCP source.
-
#trust_sources ⇒ void
List trusted MCP sources.
-
#validate ⇒ Array<Hash>
Validate the input and return any errors.
Instance Method Details
#add(name, uri) ⇒ void
This method returns an undefined value.
Add a new entry.
211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 211 def add(name, uri) installer = build_installer result = installer.install(name: name, uri: uri, transport: [:transport]) if result[:success] say(Rainbow(result[:message]).green) else warn(Rainbow(result[:message]).red) exit(result[:trusted] == false ? 1 : 2) end end |
#audit ⇒ void
This method returns an undefined value.
Run a security audit on MCP configuration.
180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 180 def audit registry = build_registry checker = RosettAi::Mcp::Admin::HealthChecker.new validator = RosettAi::Mcp::Admin::SchemaValidator.new auditor = RosettAi::Mcp::Admin::Auditor.new( registry: registry, health_checker: checker, schema_validator: validator ) report = auditor.audit render_audit_report(report) end |
#generate_key ⇒ void
This method returns an undefined value.
Generate a new MCP API key.
371 372 373 374 375 376 377 378 379 380 381 382 383 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 371 def generate_key path = RosettAi::Mcp::Keyfile.create_if_missing([:keyfile]) plaintext = RosettAi::Mcp::KeyHasher.generate_key key_hash = RosettAi::Mcp::KeyHasher.hash_key(plaintext) keyfile = RosettAi::Mcp::Keyfile.new(path) keyfile.load! keyfile.add_key(name: [:name], key_hash: key_hash) say(Rainbow("API key generated for '#{[:name]}':").green) say(plaintext) say(Rainbow('Store this key securely — it cannot be recovered.').yellow) end |
#list ⇒ void
This method returns an undefined value.
List available items.
93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 93 def list registry = build_registry servers = registry.list if servers.empty? say(t('no_servers')) return end render_server_list(servers) end |
#list_keys ⇒ void
This method returns an undefined value.
List all MCP API keys.
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 401 def list_keys path = File.([:keyfile]) unless File.exist?(path) say(Rainbow('No keyfile found.').yellow) return end keyfile = RosettAi::Mcp::Keyfile.new(path) keyfile.load! keys = keyfile.enabled_keys if keys.empty? say('No keys configured.') return end table = ::Terminal::Table.new( headings: ['Name', 'Created', 'Enabled', 'Expires'], rows: keys.map { |k| [k[:name], k[:created_at], k[:enabled], k[:expires_at] || 'never'] } ) say(table) end |
#remove(name) ⇒ void
This method returns an undefined value.
Remove the component.
242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 242 def remove(name) installer = build_installer result = installer.remove(name: name, force: [:force]) if result[:success] say(Rainbow(result[:message]).green) else warn(Rainbow(result[:message]).red) exit(1) end end |
#revoke_key ⇒ void
This method returns an undefined value.
Revoke an MCP API key.
440 441 442 443 444 445 446 447 448 449 450 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 440 def revoke_key keyfile = RosettAi::Mcp::Keyfile.new(File.([:keyfile])) keyfile.load! if keyfile.revoke_key([:name]) say(Rainbow("Key '#{[:name]}' revoked.").green) else warn(Rainbow("Key '#{[:name]}' not found.").red) exit(1) end end |
#rotate_key ⇒ void
This method returns an undefined value.
Rotate an MCP API key.
468 469 470 471 472 473 474 475 476 477 478 479 480 481 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 468 def rotate_key keyfile = RosettAi::Mcp::Keyfile.new(File.([:keyfile])) keyfile.load! result = keyfile.rotate_key([:name]) if result say(Rainbow("Key '#{[:name]}' rotated. New key:").green) say(result[:plaintext]) say(Rainbow('Store this key securely — it cannot be recovered.').yellow) else warn(Rainbow("Key '#{[:name]}' not found.").red) exit(1) end end |
#serve ⇒ void
This method returns an undefined value.
Start the MCP JSON-RPC server.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 50 def serve server = RosettAi::Mcp::Server.new( config_path: [:config], plugins: [:plugin] ) if [:http] unless ENV.fetch('RAI_MCP_API_KEY', nil) warn Rainbow('[rosett-ai-mcp] WARNING: Starting HTTP server with no API key configured. ' \ 'Set RAI_MCP_API_KEY or use a keyfile for authentication.').yellow end server.serve_http( port: [:port], host: [:host], tls_cert: [:tls_cert], tls_key: [:tls_key], allow_remote: [:allow_remote] ) else server.serve end rescue RosettAi::McpError => e warn Rainbow(e.).red exit(5) end |
#status ⇒ String
Return the current status.
149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 149 def status registry = build_registry checker = RosettAi::Mcp::Admin::HealthChecker.new results = checker.check_all(registry) if results.empty? say(t('no_servers')) return end render_health_results(results) end |
#tools ⇒ void
This method returns an undefined value.
List registered MCP tools.
343 344 345 346 347 348 349 350 351 352 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 343 def tools server = RosettAi::Mcp::Server.new tool_list = server.tools table = ::Terminal::Table.new( headings: ['Tool', 'Description', 'Read-Only'], rows: tool_list.map { |t| [t[:name], t[:description], t[:annotations]['readOnlyHint']] } ) say(table) end |
#trust_add(domain) ⇒ void
This method returns an undefined value.
Add a trusted MCP source.
296 297 298 299 300 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 296 def trust_add(domain) manager = build_trust_manager manager.add_trust(domain, description: [:description]) say(Rainbow("Trust added for: #{domain}").green) end |
#trust_remove(domain) ⇒ void
This method returns an undefined value.
Remove a trusted MCP source.
320 321 322 323 324 325 326 327 328 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 320 def trust_remove(domain) manager = build_trust_manager if manager.remove_trust(domain) say(Rainbow("Trust removed for: #{domain}").green) else warn(Rainbow("Domain not found in user trust sources: #{domain}").red) exit(1) end end |
#trust_sources ⇒ void
This method returns an undefined value.
List trusted MCP sources.
272 273 274 275 276 277 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 272 def trust_sources manager = build_trust_manager sources = manager.list render_trust_sources(sources) end |
#validate ⇒ Array<Hash>
Validate the input and return any errors.
122 123 124 125 126 127 128 129 130 |
# File 'lib/rosett_ai/thor/tasks/mcp.rb', line 122 def validate registry = build_registry validator = RosettAi::Mcp::Admin::SchemaValidator.new results = validator.validate_all(registry) render_validation_results(results) all_valid = results.all? { |r| r[:valid] } exit(all_valid ? 0 : 2) end |