Class: Ask::MCP::Transport::Stdio

Inherits:
Object
  • Object
show all
Defined in:
lib/ask/mcp/transport/stdio.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(command, args = [], options = {}) ⇒ Stdio

Returns a new instance of Stdio.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/ask/mcp/transport/stdio.rb', line 11

def initialize(command, args = [], options = {})
  @command = command
  @args = args
  @options = options
  @pid = nil
  @stdin = nil
  @stdout = nil
  @stderr = nil
  @wait_thr = nil
  @buffer = +""
  @message_handlers = []
  @running = false
  @mutex = Mutex.new
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



9
10
11
# File 'lib/ask/mcp/transport/stdio.rb', line 9

def args
  @args
end

#commandObject (readonly)

Returns the value of attribute command.



9
10
11
# File 'lib/ask/mcp/transport/stdio.rb', line 9

def command
  @command
end

#pidObject (readonly)

Returns the value of attribute pid.



9
10
11
# File 'lib/ask/mcp/transport/stdio.rb', line 9

def pid
  @pid
end

Instance Method Details

#on_message(&block) ⇒ Object



26
27
28
# File 'lib/ask/mcp/transport/stdio.rb', line 26

def on_message(&block)
  @message_handlers << block
end

#running?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/ask/mcp/transport/stdio.rb', line 63

def running?
  @running && @wait_thr&.alive?
end

#send(message) ⇒ Object



53
54
55
56
57
58
59
60
61
# File 'lib/ask/mcp/transport/stdio.rb', line 53

def send(message)
  data = message.is_a?(String) ? message : message.to_json
  @mutex.synchronize do
    @stdin&.puts(data)
    @stdin&.flush
  end
rescue Errno::EPIPE, IOError => e
  raise ConnectionError, "Failed to send message: #{e.message}"
end

#shutdownObject



67
68
69
# File 'lib/ask/mcp/transport/stdio.rb', line 67

def shutdown
  stop
end

#startObject



30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/ask/mcp/transport/stdio.rb', line 30

def start
  env = @options[:env] || {}
  workdir = @options[:workdir]

  cmd = build_command
  @stdin, @stdout, @stderr, @wait_thr = Open3.popen3(env, *cmd, chdir: workdir || Dir.pwd)
  @pid = @wait_thr.pid
  @running = true

  start_reader
  self
end

#stopObject



43
44
45
46
47
48
49
50
51
# File 'lib/ask/mcp/transport/stdio.rb', line 43

def stop
  @running = false
  @stdin&.close unless @stdin&.closed?
  @stdout&.close unless @stdout&.closed?
  @stderr&.close unless @stderr&.closed?
  @wait_thr&.value
rescue Errno::EPIPE, Errno::ECHILD
  # Process already exited
end