Class: AIA::Adapter::McpConnector

Inherits:
Object
  • Object
show all
Defined in:
lib/aia/adapter/mcp_connector.rb

Constant Summary collapse

MCP_DEFAULT_TIMEOUT =

Default timeout for MCP client initialization (in milliseconds) RubyLLM::MCP expects timeout in milliseconds (e.g., 8000 = 8 seconds) Using a short timeout to prevent slow servers from blocking startup

8_000

Instance Method Summary collapse

Instance Method Details

#filter_mcp_servers(servers) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/aia/adapter/mcp_connector.rb', line 68

def filter_mcp_servers(servers)
  use_list = Array(AIA.config.mcp_use)
  skip_list = Array(AIA.config.mcp_skip)

  if !use_list.empty?
    servers = servers.select do |server|
      name = server[:name] || server['name']
      use_list.include?(name)
    end
    logger.info("MCP servers filtered by --mcp-use", use: use_list, remaining: servers.size)
  elsif !skip_list.empty?
    servers = servers.reject do |server|
      name = server[:name] || server['name']
      skip_list.include?(name)
    end
    logger.info("MCP servers filtered by --mcp-skip", skip: skip_list, remaining: servers.size)
  end

  servers
end

#support_mcp(tools) ⇒ Object

8 seconds (same as RubyLLM::MCP default)



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/aia/adapter/mcp_connector.rb', line 14

def support_mcp(tools)
  if AIA.config.flags.no_mcp
    logger.debug("MCP processing bypassed via --no-mcp flag")
    return
  end

  if AIA.config.mcp_servers.nil? || AIA.config.mcp_servers.empty?
    logger.debug("No MCP servers configured, skipping MCP setup")
    return
  end

  # Initialize tracking (kept for compatibility with Utility.robot)
  AIA.config.connected_mcp_servers = []
  AIA.config.failed_mcp_servers = []

  servers = filter_mcp_servers(AIA.config.mcp_servers)
  server_names = servers.map { |s| s[:name] || s['name'] }.compact

  logger.info("Starting parallel MCP connection", server_count: servers.size, servers: server_names)
  $stderr.puts "MCP: Connecting to #{server_names.join(', ')}..."
  $stderr.flush

  LoggerManager.configure_mcp_logger

  # Build steps array first (outside the block to preserve self reference)
  # Each step is a [name, callable] pair for parallel execution
  connector = self
  steps = servers.map do |server|
    name = (server[:name] || server['name']).to_sym
    logger.debug("Building connection step", server: name)
    [name, connector.send(:build_mcp_connection_step, server)]
  end

  # Build parallel pipeline - each server is independent (depends_on: :none)
  # All servers will connect concurrently using fiber-based async
  logger.debug("Creating SimpleFlow pipeline", step_count: steps.size)
  pipeline = SimpleFlow::Pipeline.new(concurrency: :async) do
    steps.each do |name, callable|
      step name, callable, depends_on: :none
    end
  end

  # Execute all connections in parallel
  start_time = Time.now
  initial_result = SimpleFlow::Result.new({ tools: [] })
  final_result = pipeline.call_parallel(initial_result)
  elapsed = Time.now - start_time

  logger.info("Parallel MCP connection completed", elapsed_seconds: elapsed.round(2))

  # Extract results and populate config arrays for compatibility
  extract_mcp_results(final_result, tools)
end