Skip to content

Commit e72bcfa

Browse files
committed
Add basic HTTP client support
1 parent d1e7a83 commit e72bcfa

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,24 @@ The HTTP client supports:
141141
- Tool invocation via the `tools/call` method
142142
- Automatic JSON-RPC 2.0 message formatting
143143
- UUID v7 request ID generation
144+
- Setting headers for things like authorization
145+
146+
### HTTP Authorization
147+
148+
By default, the HTTP client has no authentication, but it supports custom headers for authentication. For example, to use Bearer token authentication:
149+
150+
```ruby
151+
client = ModelContextProtocol::Client::Http.new(
152+
url: "https://api.example.com/mcp",
153+
headers: {
154+
"Authorization" => "Bearer my_token"
155+
}
156+
)
157+
158+
client.tools # will make the call using Bearer auth
159+
```
160+
161+
You can add any custom headers needed for your authentication scheme. The client will include these headers in all requests.
144162

145163
### Tool Objects
146164

lib/model_context_protocol/client/http.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ class Http
77

88
attr_reader :url, :version
99

10-
def initialize(url:, version: DEFAULT_VERSION)
10+
def initialize(url:, version: DEFAULT_VERSION, headers: {})
1111
@url = url
1212
@version = version
13+
@headers = headers
1314
end
1415

1516
def tools
@@ -29,12 +30,17 @@ def call_tool(tool:, input:)
2930

3031
private
3132

32-
# TODO: support auth
33+
attr_reader :headers
34+
3335
def client
3436
@client ||= Faraday.new(url) do |faraday|
3537
faraday.request(:json)
3638
faraday.response(:json)
3739
faraday.response(:raise_error)
40+
41+
headers.each do |key, value|
42+
faraday.headers[key] = value
43+
end
3844
end
3945
end
4046

test/model_context_protocol/client/http_test.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,39 @@ def test_initialization_with_custom_version
1919
assert_equal(custom_version, client.version)
2020
end
2121

22+
def test_headers_are_added_to_the_request
23+
headers = { "Authorization" => "Bearer token" }
24+
client = Http.new(url:, headers:)
25+
client.stubs(:request_id).returns(mock_request_id)
26+
27+
stub_request(:post, url)
28+
.with(
29+
headers: {
30+
"Authorization" => "Bearer token",
31+
"Content-Type" => "application/json",
32+
},
33+
body: {
34+
method: "tools/list",
35+
jsonrpc: "2.0",
36+
id: mock_request_id,
37+
mcp: {
38+
method: "tools/list",
39+
jsonrpc: "2.0",
40+
id: mock_request_id,
41+
},
42+
},
43+
)
44+
.to_return(
45+
status: 200,
46+
headers: { "Content-Type" => "application/json" },
47+
body: { result: { tools: [] } }.to_json,
48+
)
49+
50+
# The test passes if the request is made with the correct headers
51+
# If headers are wrong, the stub_request won't match and will raise
52+
client.tools
53+
end
54+
2255
def test_tools_returns_tools_instance
2356
stub_request(:post, url)
2457
.with(

0 commit comments

Comments
 (0)