Skip to content

Commit 4a71fa8

Browse files
authored
Merge pull request #221 from chattermill/md-client-instrumentation
Add client info to instrumentation callback
2 parents 248c1ec + 2d926ab commit 4a71fa8

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ The instrumentation callback receives a hash with the following possible keys:
400400
- `resource_uri`: (String, optional) The URI of the resource called
401401
- `error`: (String, optional) Error code if a lookup failed
402402
- `duration`: (Float) Duration of the call in seconds
403+
- `client`: (Hash, optional) Client information with `name` and `version` keys, from the initialize request
403404

404405
**Type:**
405406

lib/mcp/server.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def initialize(
7575
@resource_index = index_resources_by_uri(resources)
7676
@server_context = server_context
7777
@configuration = MCP.configuration.merge(configuration)
78+
@client = nil
7879

7980
validate!
8081

@@ -258,15 +259,17 @@ def validate_tool_name!
258259
def handle_request(request, method)
259260
handler = @handlers[method]
260261
unless handler
261-
instrument_call("unsupported_method") {}
262+
instrument_call("unsupported_method") do
263+
add_instrumentation_data(client: @client) if @client
264+
end
262265
return
263266
end
264267

265268
Methods.ensure_capability!(method, capabilities)
266269

267270
->(params) {
268271
instrument_call(method) do
269-
case method
272+
result = case method
270273
when Methods::TOOLS_LIST
271274
{ tools: @handlers[Methods::TOOLS_LIST].call(params) }
272275
when Methods::PROMPTS_LIST
@@ -280,6 +283,9 @@ def handle_request(request, method)
280283
else
281284
@handlers[method].call(params)
282285
end
286+
add_instrumentation_data(client: @client) if @client
287+
288+
result
283289
rescue => e
284290
report_exception(e, { request: request })
285291
if e.is_a?(RequestHandlerError)
@@ -314,6 +320,7 @@ def server_info
314320
end
315321

316322
def init(request)
323+
@client = request[:clientInfo] if request
317324
{
318325
protocolVersion: configuration.protocol_version,
319326
capabilities: capabilities,

test/mcp/server_test.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,53 @@ class ServerTest < ActiveSupport::TestCase
159159
assert_instrumentation_data({ method: "initialize" })
160160
end
161161

162+
test "#handle initialize request with clientInfo includes client in instrumentation data" do
163+
client_info = { name: "test_client", version: "1.0.0" }
164+
request = {
165+
jsonrpc: "2.0",
166+
method: "initialize",
167+
id: 1,
168+
params: {
169+
clientInfo: client_info,
170+
},
171+
}
172+
173+
@server.handle(request)
174+
assert_instrumentation_data({ method: "initialize", client: client_info })
175+
end
176+
177+
test "instrumentation data includes client info for subsequent requests after initialize" do
178+
client_info = { name: "test_client", version: "1.0.0" }
179+
initialize_request = {
180+
jsonrpc: "2.0",
181+
method: "initialize",
182+
id: 1,
183+
params: {
184+
clientInfo: client_info,
185+
},
186+
}
187+
@server.handle(initialize_request)
188+
189+
ping_request = {
190+
jsonrpc: "2.0",
191+
method: "ping",
192+
id: 2,
193+
}
194+
@server.handle(ping_request)
195+
assert_instrumentation_data({ method: "ping", client: client_info })
196+
end
197+
198+
test "instrumentation data does not include client key when no clientInfo provided" do
199+
request = {
200+
jsonrpc: "2.0",
201+
method: "ping",
202+
id: 1,
203+
}
204+
205+
@server.handle(request)
206+
assert_instrumentation_data({ method: "ping" })
207+
end
208+
162209
test "#handle returns nil for notification requests" do
163210
request = {
164211
jsonrpc: "2.0",

0 commit comments

Comments
 (0)