Skip to content

Case-normalize client names in telemetry labels#73

Merged
ChiragAgg5k merged 1 commit into
mainfrom
fix/normalize-client-ids
Jul 9, 2026
Merged

Case-normalize client names in telemetry labels#73
ChiragAgg5k merged 1 commit into
mainfrom
fix/normalize-client-ids

Conversation

@ChiragAgg5k

Copy link
Copy Markdown
Member

Summary

The MCP dashboard showed Trae and trae as two distinct clients in "Active Sessions by Client". The split happens because client_id is bound from two sources with different casing rules:

  • On the initialize request, clientInfo.name is used raw (http_app.pyrecord_connection), e.g. Trae.
  • On every other request, the name is derived from the User-Agent product token, which is lowercased (_client_from_user_agent), e.g. trae.

So a single client contributes two label values across handshake vs per-request metrics, splitting session counts, connection counts, and tool-call attribution.

Change

Add _normalize_client_name() in telemetry.py and apply it at both identity entry points (set_request_identity, record_connection): strip surrounding whitespace, lowercase, collapse internal whitespace runs to hyphens (matching the product-token shape of UA-derived names), cap at 64 chars. Empty/whitespace-only names still fall through to the existing unknown handling.

Normalizing at the telemetry layer (rather than the HTTP middleware) covers every caller and keeps the invariant documented in the module docstring: client_id is a small bounded set of client names.

Tests

  • test_client_names_are_case_normalized — a Trae handshake followed by a trae request produces a single client_id="trae" session and connection label.
  • test_client_name_normalization_shapes — table test for casing, whitespace-to-hyphen, empty/None, and length-cap behavior.

Full pre-PR checklist passes: ruff, black, pyright, 168 unit tests.

clientInfo.name is used raw from the initialize request while
User-Agent-derived names are lowercased product tokens, so the same
client splits into two client_id label values (Trae vs trae) across
handshake and per-request identity binding. Normalize at both telemetry
entry points: strip, lowercase, collapse whitespace runs to hyphens,
cap at 64 chars.
@greptile-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes a label-split bug where the same MCP client appeared as two distinct client_id values in telemetry dashboards (e.g. Trae from the initialize handshake vs trae from User-Agent-derived names on subsequent requests) by normalizing client names at both identity entry points in telemetry.py.

  • Adds _normalize_client_name(): strips surrounding whitespace, lowercases, collapses internal whitespace runs to hyphens (matching the UA product-token shape), and caps at 64 characters; empty/whitespace-only inputs return None and fall through to existing unknown handling.
  • Applies the normalizer in set_request_identity and record_connection, with two new tests — one integration test confirming a single client_id across mixed-case handshake + request, and one table-driven unit test covering casing, whitespace collapse, empty/None, and the length cap.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to a normalization helper and its two call sites, with no behavioral changes to anything outside the telemetry label path.

The normalization logic is correct and well-covered: every meaningful edge case (case, internal whitespace, leading/trailing whitespace, empty, None, length cap) has an explicit test assertion. The two call sites in set_request_identity and record_connection are the only places that write the client_id label, and the fallback behaviour (_request_client.get() / "unknown") is preserved. As a side benefit the change also fixes a latent issue where a whitespace-only string (truthy, so not caught by the old or short-circuit) would have become a bare whitespace label value.

No files require special attention.

Important Files Changed

Filename Overview
src/mcp_server_appwrite/telemetry.py Adds _normalize_client_name() (strip, lowercase, collapse whitespace→hyphen, cap at 64 chars) and applies it at both identity entry points; logic is correct and handles all edge cases including whitespace-only strings.
tests/unit/test_telemetry.py Adds an integration test verifying a single client_id label across different casings, and a table-driven unit test covering casing, whitespace collapse, empty/None, and length-cap behavior.

Reviews (1): Last reviewed commit: "(fix): case-normalize client names in te..." | Re-trigger Greptile

@ChiragAgg5k ChiragAgg5k merged commit d47db46 into main Jul 9, 2026
5 checks passed
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.

1 participant