Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lib/mcp_client/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -486,13 +486,15 @@ def send_notification(method, params: {}, server: nil)
# Request completion suggestions from a server (MCP 2025-06-18)
# @param ref [Hash] reference object (e.g., { 'type' => 'ref/prompt', 'name' => 'prompt_name' })
# @param argument [Hash] the argument being completed (e.g., { 'name' => 'arg_name', 'value' => 'partial' })
# @param context [Hash, nil] optional context for the completion (MCP 2025-11-25),
# e.g., { 'arguments' => { 'arg1' => 'value1' } } for previously-resolved arguments
# @param server [Integer, String, Symbol, MCPClient::ServerBase, nil] server selector
# @return [Hash] completion result with 'values', optional 'total', and 'hasMore' fields
# @raise [MCPClient::Errors::ServerNotFound] if no server is available
# @raise [MCPClient::Errors::ServerError] if server returns an error
def complete(ref:, argument:, server: nil)
def complete(ref:, argument:, context: nil, server: nil)
srv = select_server(server)
srv.complete(ref: ref, argument: argument)
srv.complete(ref: ref, argument: argument, context: context)
end

# Set the logging level on all connected servers (MCP 2025-06-18)
Expand Down
7 changes: 5 additions & 2 deletions lib/mcp_client/server_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,13 @@ def read_resource(uri)
# Request completion suggestions from the server (MCP 2025-06-18)
# @param ref [Hash] reference to complete (prompt or resource)
# @param argument [Hash] the argument being completed (e.g., { 'name' => 'arg_name', 'value' => 'partial' })
# @param context [Hash, nil] optional context for the completion (MCP 2025-11-25)
# @return [Hash] completion result with 'values', optional 'total', and 'hasMore' fields
# @raise [MCPClient::Errors::ServerError] if server returns an error
def complete(ref:, argument:)
result = rpc_request('completion/complete', { ref: ref, argument: argument })
def complete(ref:, argument:, context: nil)
params = { ref: ref, argument: argument }
params[:context] = context if context
result = rpc_request('completion/complete', params)
result['completion'] || { 'values' => [] }
rescue MCPClient::Errors::ConnectionError, MCPClient::Errors::TransportError
raise
Expand Down
7 changes: 5 additions & 2 deletions lib/mcp_client/server_sse.rb
Original file line number Diff line number Diff line change
Expand Up @@ -330,10 +330,13 @@ def call_tool(tool_name, parameters)
# Request completion suggestions from the server (MCP 2025-06-18)
# @param ref [Hash] reference object (e.g., { 'type' => 'ref/prompt', 'name' => 'prompt_name' })
# @param argument [Hash] the argument being completed (e.g., { 'name' => 'arg_name', 'value' => 'partial' })
# @param context [Hash, nil] optional context for the completion (MCP 2025-11-25)
# @return [Hash] completion result with 'values', optional 'total', and 'hasMore' fields
# @raise [MCPClient::Errors::ServerError] if server returns an error
def complete(ref:, argument:)
result = rpc_request('completion/complete', { ref: ref, argument: argument })
def complete(ref:, argument:, context: nil)
params = { ref: ref, argument: argument }
params[:context] = context if context
result = rpc_request('completion/complete', params)
result['completion'] || { 'values' => [] }
rescue MCPClient::Errors::ConnectionError, MCPClient::Errors::TransportError
raise
Expand Down
7 changes: 5 additions & 2 deletions lib/mcp_client/server_stdio.rb
Original file line number Diff line number Diff line change
Expand Up @@ -345,16 +345,19 @@ def call_tool(tool_name, parameters)
# Request completion suggestions from the server (MCP 2025-06-18)
# @param ref [Hash] reference object (e.g., { 'type' => 'ref/prompt', 'name' => 'prompt_name' })
# @param argument [Hash] the argument being completed (e.g., { 'name' => 'arg_name', 'value' => 'partial' })
# @param context [Hash, nil] optional context for the completion (MCP 2025-11-25)
# @return [Hash] completion result with 'values', optional 'total', and 'hasMore' fields
# @raise [MCPClient::Errors::ServerError] if server returns an error
def complete(ref:, argument:)
def complete(ref:, argument:, context: nil)
ensure_initialized
req_id = next_id
params = { 'ref' => ref, 'argument' => argument }
params['context'] = context if context
req = {
'jsonrpc' => '2.0',
'id' => req_id,
'method' => 'completion/complete',
'params' => { 'ref' => ref, 'argument' => argument }
'params' => params
}
send_request(req)
res = wait_response(req_id)
Expand Down
7 changes: 5 additions & 2 deletions lib/mcp_client/server_streamable_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,13 @@ def call_tool_streaming(tool_name, parameters)
# Request completion suggestions from the server (MCP 2025-06-18)
# @param ref [Hash] reference object (e.g., { 'type' => 'ref/prompt', 'name' => 'prompt_name' })
# @param argument [Hash] the argument being completed (e.g., { 'name' => 'arg_name', 'value' => 'partial' })
# @param context [Hash, nil] optional context for the completion (MCP 2025-11-25)
# @return [Hash] completion result with 'values', optional 'total', and 'hasMore' fields
# @raise [MCPClient::Errors::ServerError] if server returns an error
def complete(ref:, argument:)
result = rpc_request('completion/complete', { ref: ref, argument: argument })
def complete(ref:, argument:, context: nil)
params = { ref: ref, argument: argument }
params[:context] = context if context
result = rpc_request('completion/complete', params)
result['completion'] || { 'values' => [] }
rescue MCPClient::Errors::ConnectionError, MCPClient::Errors::TransportError
raise
Expand Down
92 changes: 90 additions & 2 deletions spec/lib/mcp_client/completion_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require 'spec_helper'

RSpec.describe 'Completion (MCP 2025-06-18)' do
RSpec.describe 'Completion (MCP 2025-06-18 / 2025-11-25 context)' do
let(:mock_server) { instance_double(MCPClient::ServerStdio, name: 'stdio-server') }

before do
Expand Down Expand Up @@ -37,7 +37,7 @@

result = client.complete(ref: ref, argument: argument)

expect(mock_server).to have_received(:complete).with(ref: ref, argument: argument)
expect(mock_server).to have_received(:complete).with(ref: ref, argument: argument, context: nil)
expect(result['values']).to eq(%w[python pytho])
end

Expand All @@ -49,6 +49,15 @@
expect(mock_server).to have_received(:complete)
end

it 'passes context to the server when provided' do
context = { 'arguments' => { 'language' => 'python' } }
allow(mock_server).to receive(:complete).and_return(completion_result)

client.complete(ref: ref, argument: argument, context: context)

expect(mock_server).to have_received(:complete).with(ref: ref, argument: argument, context: context)
end

context 'when no server is available' do
let(:empty_client) { described_class.new(mcp_server_configs: []) }

Expand Down Expand Up @@ -113,6 +122,28 @@
server.complete(ref: ref, argument: argument)
end.to raise_error(MCPClient::Errors::ServerError)
end

it 'includes context in params when provided' do
context = { 'arguments' => { 'language' => 'python' } }
server.complete(ref: ref, argument: argument, context: context)

expect(server).to have_received(:send_request).with(
hash_including(
'method' => 'completion/complete',
'params' => { 'ref' => ref, 'argument' => argument, 'context' => context }
)
)
end

it 'omits context from params when not provided' do
server.complete(ref: ref, argument: argument)

expect(server).to have_received(:send_request).with(
hash_including(
'params' => { 'ref' => ref, 'argument' => argument }
)
)
end
end
end

Expand Down Expand Up @@ -153,6 +184,25 @@

expect(result['values']).to eq([])
end

it 'includes context in rpc_request when provided' do
context = { 'arguments' => { 'path' => '/home' } }
server.complete(ref: ref, argument: argument, context: context)

expect(server).to have_received(:rpc_request).with(
'completion/complete',
{ ref: ref, argument: argument, context: context }
)
end

it 'omits context from rpc_request when not provided' do
server.complete(ref: ref, argument: argument)

expect(server).to have_received(:rpc_request).with(
'completion/complete',
{ ref: ref, argument: argument }
)
end
end
end

Expand Down Expand Up @@ -192,6 +242,25 @@

expect(result['values']).to eq([])
end

it 'includes context in rpc_request when provided' do
context = { 'arguments' => { 'style' => 'casual' } }
server.complete(ref: ref, argument: argument, context: context)

expect(server).to have_received(:rpc_request).with(
'completion/complete',
{ ref: ref, argument: argument, context: context }
)
end

it 'omits context from rpc_request when not provided' do
server.complete(ref: ref, argument: argument)

expect(server).to have_received(:rpc_request).with(
'completion/complete',
{ ref: ref, argument: argument }
)
end
end
end

Expand Down Expand Up @@ -231,6 +300,25 @@

expect(result['values']).to eq([])
end

it 'includes context in rpc_request when provided' do
context = { 'arguments' => { 'language' => 'english' } }
server.complete(ref: ref, argument: argument, context: context)

expect(server).to have_received(:rpc_request).with(
'completion/complete',
{ ref: ref, argument: argument, context: context }
)
end

it 'omits context from rpc_request when not provided' do
server.complete(ref: ref, argument: argument)

expect(server).to have_received(:rpc_request).with(
'completion/complete',
{ ref: ref, argument: argument }
)
end
end
end
end