Merge pull request #266 from koic/allow_client_call_tool_to_accept_a_tool_name
Allow `Client#call_tool` to accept a tool name
This commit is contained in:
commit
ccddd87e96
2 changed files with 37 additions and 3 deletions
|
|
@ -92,12 +92,17 @@ module MCP
|
||||||
|
|
||||||
# Calls a tool via the transport layer and returns the full response from the server.
|
# Calls a tool via the transport layer and returns the full response from the server.
|
||||||
#
|
#
|
||||||
|
# @param name [String] The name of the tool to call.
|
||||||
# @param tool [MCP::Client::Tool] The tool to be called.
|
# @param tool [MCP::Client::Tool] The tool to be called.
|
||||||
# @param arguments [Object, nil] The arguments to pass to the tool.
|
# @param arguments [Object, nil] The arguments to pass to the tool.
|
||||||
# @param progress_token [String, Integer, nil] A token to request progress notifications from the server during tool execution.
|
# @param progress_token [String, Integer, nil] A token to request progress notifications from the server during tool execution.
|
||||||
# @return [Hash] The full JSON-RPC response from the transport.
|
# @return [Hash] The full JSON-RPC response from the transport.
|
||||||
#
|
#
|
||||||
# @example
|
# @example Call by name
|
||||||
|
# response = client.call_tool(name: "my_tool", arguments: { foo: "bar" })
|
||||||
|
# content = response.dig("result", "content")
|
||||||
|
#
|
||||||
|
# @example Call with a tool object
|
||||||
# tool = client.tools.first
|
# tool = client.tools.first
|
||||||
# response = client.call_tool(tool: tool, arguments: { foo: "bar" })
|
# response = client.call_tool(tool: tool, arguments: { foo: "bar" })
|
||||||
# structured_content = response.dig("result", "structuredContent")
|
# structured_content = response.dig("result", "structuredContent")
|
||||||
|
|
@ -105,8 +110,11 @@ module MCP
|
||||||
# @note
|
# @note
|
||||||
# The exact requirements for `arguments` are determined by the transport layer in use.
|
# The exact requirements for `arguments` are determined by the transport layer in use.
|
||||||
# Consult the documentation for your transport (e.g., MCP::Client::HTTP) for details.
|
# Consult the documentation for your transport (e.g., MCP::Client::HTTP) for details.
|
||||||
def call_tool(tool:, arguments: nil, progress_token: nil)
|
def call_tool(name: nil, tool: nil, arguments: nil, progress_token: nil)
|
||||||
params = { name: tool.name, arguments: arguments }
|
tool_name = name || tool&.name
|
||||||
|
raise ArgumentError, "Either `name:` or `tool:` must be provided." unless tool_name
|
||||||
|
|
||||||
|
params = { name: tool_name, arguments: arguments }
|
||||||
if progress_token
|
if progress_token
|
||||||
params[:_meta] = { progressToken: progress_token }
|
params[:_meta] = { progressToken: progress_token }
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,32 @@ module MCP
|
||||||
assert_equal([{ type: "text", text: "Hello, world!" }], content)
|
assert_equal([{ type: "text", text: "Hello, world!" }], content)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_call_tool_by_name
|
||||||
|
transport = mock
|
||||||
|
arguments = { foo: "bar" }
|
||||||
|
mock_response = {
|
||||||
|
"result" => { "content" => [{ "type": "text", "text": "Hello, world!" }] },
|
||||||
|
}
|
||||||
|
|
||||||
|
transport.expects(:send_request).with do |args|
|
||||||
|
args.dig(:request, :params, :name) == "tool1" &&
|
||||||
|
args.dig(:request, :params, :arguments) == arguments
|
||||||
|
end.returns(mock_response).once
|
||||||
|
|
||||||
|
client = Client.new(transport: transport)
|
||||||
|
result = client.call_tool(name: "tool1", arguments: arguments)
|
||||||
|
content = result.dig("result", "content")
|
||||||
|
|
||||||
|
assert_equal([{ type: "text", text: "Hello, world!" }], content)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_call_tool_raises_when_no_name_or_tool
|
||||||
|
client = Client.new(transport: mock)
|
||||||
|
|
||||||
|
error = assert_raises(ArgumentError) { client.call_tool(arguments: { foo: "bar" }) }
|
||||||
|
assert_equal("Either `name:` or `tool:` must be provided.", error.message)
|
||||||
|
end
|
||||||
|
|
||||||
def test_resources_sends_request_to_transport_and_returns_resources_array
|
def test_resources_sends_request_to_transport_and_returns_resources_array
|
||||||
transport = mock
|
transport = mock
|
||||||
mock_response = {
|
mock_response = {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue