Class: VSM::MCP::Client
- Inherits:
-
Object
- Object
- VSM::MCP::Client
- Defined in:
- lib/vsm/mcp/client.rb
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Instance Method Summary collapse
-
#call_tool(name:, arguments: {}) ⇒ Object
Returns a String (first text content) or a JSON string fallback.
-
#initialize(cmd:, env: {}, cwd: nil, name: nil) ⇒ Client
constructor
A new instance of Client.
-
#list_tools ⇒ Object
Returns Array<Hash> with symbol keys: :name, :description, :input_schema.
- #start ⇒ Object
- #stop ⇒ Object
Constructor Details
#initialize(cmd:, env: {}, cwd: nil, name: nil) ⇒ Client
Returns a new instance of Client.
11 12 13 14 15 16 |
# File 'lib/vsm/mcp/client.rb', line 11 def initialize(cmd:, env: {}, cwd: nil, name: nil) @cmd, @env, @cwd, @name = cmd, env, cwd, (name || cmd.split.first) @stdin = @stdout = @stderr = @wait_thr = nil @rpc = nil @stderr_thread = nil end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
9 10 11 |
# File 'lib/vsm/mcp/client.rb', line 9 def name @name end |
Instance Method Details
#call_tool(name:, arguments: {}) ⇒ Object
Returns a String (first text content) or a JSON string fallback
72 73 74 75 76 77 |
# File 'lib/vsm/mcp/client.rb', line 72 def call_tool(name:, arguments: {}) res = @rpc.request("tools/call", { "name" => name, "arguments" => arguments }) content = Array(res["content"]) item = content.find { |c| c["type"] == "text" } || content.first item ? (item["text"] || item.to_s) : res.to_s end |
#list_tools ⇒ Object
Returns Array<Hash> with symbol keys: :name, :description, :input_schema
59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/vsm/mcp/client.rb', line 59 def list_tools raw = @rpc.request("tools/list") arr = (raw && raw["tools"]) || [] arr.map do |t| { name: t["name"].to_s, description: t["description"].to_s, input_schema: (t["input_schema"] || {}) } end end |
#start ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/vsm/mcp/client.rb', line 18 def start opts = {} opts[:chdir] = @cwd if @cwd args = @cmd.is_a?(Array) ? @cmd : Shellwords.split(@cmd.to_s) @stdin, @stdout, @stderr, @wait_thr = Open3.popen3(@env || {}, *args, **opts) # Drain stderr to avoid blocking if the server writes logs @stderr_thread = Thread.new do begin @stderr.each_line { |_line| } rescue StandardError end end @rpc = JSONRPC::Stdio.new(r: @stdout, w: @stdin) self end |
#stop ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/vsm/mcp/client.rb', line 34 def stop begin @stdin&.close rescue StandardError end begin @stdout&.close rescue StandardError end begin @stderr&.close rescue StandardError end begin @stderr_thread&.kill rescue StandardError end begin @wait_thr&.kill rescue StandardError end nil end |