Skip to content

feat: log which MCP client connected, fix missing logging capability - #43

Open
mattpodwysocki wants to merge 1 commit into
mainfrom
feat/client-identification
Open

feat: log which MCP client connected, fix missing logging capability#43
mattpodwysocki wants to merge 1 commit into
mainfrom
feat/client-identification

Conversation

@mattpodwysocki

Copy link
Copy Markdown
Contributor

Summary

Two fixes in the same startup path:

  1. The McpServer never declared the logging capability, so every sendLoggingMessage call — including the existing "server started" / "shutting down" / "Fatal error" messages — was a silent no-op regardless of when it was sent. Declared logging: {} in the server's capabilities.
  2. server.server.getClientVersion() is only populated once the client's initialize request has been processed. Reading it synchronously right after server.connect() races that request, since connect() only waits for the transport to start, not for the handshake to finish. Moved the read into a server.server.oninitialized callback, which only fires once the handshake is fully done.

The client's identity (name/version from its initialize request) is now logged on connect, e.g. Client identified as: claude-ai v1.0.0, and recorded as mcp.client.name/mcp.client.version on every subsequent tool-execution trace span (withToolSpan), so OTel-backed traces can be filtered or grouped by client. Matches the equivalent changes landing in @mapbox/mcp-server (#253) and @mapbox/mcp-devkit-server (#139).

Test plan

  • New unit tests (test/utils/tracing.test.ts) cover withToolSpan picking up mcp.client.name/mcp.client.version once setClientInfo is called
  • npx vitest run — all 85 tests pass
  • npm run build succeeds
  • Live-verified against the real built server with a real MCP client: server now logs Mapbox Documentation MCP Server v0.3.1 started and Client identified as: pretend-vscode-client v2.1.0 (previously neither message reached the client at all, since logging wasn't declared)
  • CHANGELOG.md updated

🤖 Generated with Claude Code

Two fixes in the same startup path:

1. The McpServer never declared the logging capability, so every
   sendLoggingMessage call (including the existing startup/shutdown/fatal
   error messages) was a silent no-op regardless of when it was sent.
   Declared logging: {} in capabilities.

2. server.server.getClientVersion() is only populated once the client's
   initialize request has been processed -- reading it synchronously right
   after server.connect() races that request, since connect() only waits
   for the transport to start, not for the handshake to finish. Moved the
   read into a server.server.oninitialized callback, which fires only once
   the handshake is fully done.

The client's identity (name/version from its initialize request) is now
logged on connect and recorded as mcp.client.name/mcp.client.version on
every subsequent tool-execution trace span, matching the equivalent
changes in @mapbox/mcp-server and @mapbox/mcp-devkit-server.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mattpodwysocki
mattpodwysocki requested a review from a team as a code owner August 25, 2026 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants