Conversation
📝 WalkthroughWalkthroughIntroduces client telemetry and richer context propagation: a ClientContext object (clientInfo, clientIp, apiKey, transport), clientInfo caching with TTL and probabilistic cleanup, API key hashing, HTTP /ping and 404 handling, and updated library search/docs APIs to accept and forward the unified context. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant HTTPServer as HTTP Server
participant Cache as Client Info Cache
participant LibraryAPI as Library Search/Docs API
Client->>HTTPServer: POST /mcp (body includes clientInfo, apiKey, sessionId)
HTTPServer->>HTTPServer: extractClientInfoFromBody()
HTTPServer->>HTTPServer: gen cacheKey (sessionId / apiKey hash / clientIp)
HTTPServer->>Cache: lookup(cacheKey)
alt cache hit
Cache-->>HTTPServer: clientInfo
else cache miss
HTTPServer-->>Cache: store(clientInfo, TTL)
end
HTTPServer->>HTTPServer: hashApiKey(apiKey)
HTTPServer->>HTTPServer: build ClientContext (clientIp, apiKey, clientInfo, transport)
HTTPServer->>LibraryAPI: searchLibraries / fetchLibraryDocumentation (ClientContext)
LibraryAPI->>LibraryAPI: build headers (Server-Version, Client-IDE, Client-Version, Transport)
LibraryAPI-->>HTTPServer: response
HTTPServer-->>Client: MCP response
Note over Cache,HTTPServer: probabilistic cache cleanup may run during request handling
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/mcp/src/index.ts (1)
13-15: LGTM!Crypto imports are appropriate for the hashing and UUID generation functionality.
(SERVER_VERSION duplication already noted in api.ts review)
🧹 Nitpick comments (3)
packages/mcp/src/lib/api.ts (2)
7-7:SERVER_VERSIONis duplicated across files.This constant is also defined in
packages/mcp/src/index.ts(line 15). Having duplicate version constants risks them drifting apart during updates. Consider exporting from a single source (e.g., a shared constants file orpackage.json).
153-171: Extract header construction to a shared helper.The header construction logic (generating clientId, merging baseHeaders, adding conditional X-Context7-* headers) is duplicated nearly verbatim in
fetchLibraryDocumentation(lines 224-242). Extract this to a helper function to reduce duplication and ensure consistency.🔎 Proposed helper function
function buildTelemetryHeaders(context: ClientContext): Record<string, string> { const clientId = generateClientId(context); const baseHeaders = generateHeaders(context.clientIp, context.apiKey); const headers: Record<string, string> = { ...baseHeaders, "X-Context7-Source": "mcp-server", "X-Context7-Server-Version": SERVER_VERSION, "X-Context7-Client-Id": clientId, }; if (context.clientInfo?.ide) { headers["X-Context7-Client-IDE"] = context.clientInfo.ide; } if (context.clientInfo?.version) { headers["X-Context7-Client-Version"] = context.clientInfo.version; } if (context.transport) { headers["X-Context7-Transport"] = context.transport; } return headers; }Then in both functions:
- const clientId = generateClientId(context); - const baseHeaders = generateHeaders(context.clientIp, context.apiKey); - - const headers: Record<string, string> = { - ...baseHeaders, - "X-Context7-Source": "mcp-server", - "X-Context7-Server-Version": SERVER_VERSION, - "X-Context7-Client-Id": clientId, - }; - - if (context.clientInfo?.ide) { - headers["X-Context7-Client-IDE"] = context.clientInfo.ide; - } - if (context.clientInfo?.version) { - headers["X-Context7-Client-Version"] = context.clientInfo.version; - } - if (context.transport) { - headers["X-Context7-Transport"] = context.transport; - } + const headers = buildTelemetryHeaders(context);packages/mcp/src/index.ts (1)
83-84: Consider adding a size limit to the cache.The
clientInfoCachehas no maximum size, which could lead to unbounded memory growth in high-traffic HTTP scenarios. Consider either:
- Adding a maximum entry limit with LRU eviction
- Using a size-bounded cache library
The 1% probabilistic cleanup (line 433) only removes expired entries, not excess entries.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/mcp/src/index.tspackages/mcp/src/lib/api.ts
🧰 Additional context used
🧬 Code graph analysis (2)
packages/mcp/src/lib/api.ts (2)
packages/mcp/src/lib/types.ts (1)
SearchResponse(16-19)packages/mcp/src/lib/encryption.ts (1)
generateHeaders(34-47)
packages/mcp/src/index.ts (3)
packages/mcp/src/lib/types.ts (1)
SearchResponse(16-19)packages/mcp/src/lib/api.ts (1)
searchLibraries(145-189)packages/sdk/src/http/index.ts (1)
request(124-186)
🪛 GitHub Actions: Test
packages/mcp/src/index.ts
[error] 123-123: Prettier formatting issue. Delete ⏎ (prettier/prettier)
🔇 Additional comments (13)
packages/mcp/src/lib/api.ts (5)
9-20: LGTM!The
ClientContextinterface is well-structured with appropriate optional fields for telemetry. The type constraints ontransportare appropriately restrictive.
22-30: LGTM!The lazy initialization pattern for stdio session ID is correct. The session persists for the process lifetime as intended for stdio mode.
32-50: Approve with minor observation.The client ID generation logic is sound with proper privacy-preserving hashing. Note that similar API key hashing logic exists in
index.ts(hashApiKeyfunction at line 119). Consider extracting a shared utility if more hashing use cases emerge.
173-188: LGTM!Error handling is comprehensive with proper use of
context.apiKeyfor contextual error messages.
199-208: LGTM!The function signature and default parameter handling are well-designed, maintaining backward compatibility with the empty object default.
packages/mcp/src/index.ts (8)
69-76: LGTM!The
RequestContextDatainterface extension is consistent with theClientContext.clientInfotype inapi.ts.
161-176: LGTM with minor note.Good approach to capture client version from MCP SDK during initialization. The null check on
ctx(line 170) correctly handles the case where this may be called outside an active request context.
208-218: LGTM!Correct context propagation with appropriate fallback chain for
clientInfo.
296-314: LGTM!Consistent context propagation pattern matching the
resolve-library-idhandler.
394-411: LGTM!The function correctly extracts client info from MCP initialize requests with appropriate null checks and type guards.
413-449: LGTM!The client info caching logic correctly handles the initialize/subsequent request pattern. The cache key priority and TTL refresh on access are well-designed for session continuity.
433-435: LGTM!Probabilistic cleanup is a reasonable approach to amortize the cleanup cost across requests.
496-506: LGTM!Stdio mode correctly initializes with API key from CLI/env, and client info is populated via the
oninitializedhandler when the client connects.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/mcp/src/lib/api.ts (1)
124-178: Add missing transport header in fetchLibraryDocumentation.The
searchLibrariesfunction includes a conditionalX-Context7-Transportheader (lines 106-108) for telemetry, butfetchLibraryDocumentationomits it. Add the same block after the version header check to maintain consistency and ensure complete backend telemetry:if (context.transport) { headers["X-Context7-Transport"] = context.transport; }
♻️ Duplicate comments (1)
packages/mcp/src/index.ts (1)
119-121: Address the Prettier formatting issue.A past review flagged a formatting error after this function (reported at line 123). Ensure there's only a single newline after the closing brace and run Prettier to resolve the issue.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/mcp/src/index.tspackages/mcp/src/lib/api.ts
🧰 Additional context used
🧬 Code graph analysis (2)
packages/mcp/src/index.ts (3)
packages/mcp/src/lib/types.ts (1)
SearchResponse(16-19)packages/mcp/src/lib/api.ts (1)
searchLibraries(85-122)packages/sdk/src/http/index.ts (1)
request(124-186)
packages/mcp/src/lib/api.ts (2)
packages/mcp/src/lib/types.ts (2)
SearchResponse(16-19)DocumentationMode(32-32)packages/mcp/src/lib/encryption.ts (1)
generateHeaders(34-47)
🔇 Additional comments (11)
packages/mcp/src/lib/api.ts (2)
11-19: LGTM: Well-structured context interface.The
ClientContextinterface provides a clean, unified way to propagate telemetry and authentication data. Optional fields are appropriate for flexibility across different transport modes.
85-122: LGTM: Context-based header enrichment implemented correctly.The refactored
searchLibrariesfunction properly extracts telemetry fields from theClientContextand conditionally populates headers. Error handling correctly usescontext.apiKeyfor tailored messaging.packages/mcp/src/index.ts (9)
13-13: LGTM: Appropriate crypto imports.The addition of
createHashandrandomUUIDsupports the new API key hashing and session ID generation features.
69-76: LGTM: Context data structure properly extended.The
RequestContextDatainterface now includesclientInfo, maintaining consistency with theClientContextinterface inapi.ts.
83-113: LGTM: Sensible clientInfo caching with TTL.The caching strategy is well-designed:
- 30-minute TTL balances freshness and cache hit rate
- Key priority (session → hashed API key → IP) is logical
- Probabilistic cleanup (1% per request, see line 432) avoids blocking overhead
160-175: Verify globalClientInfo handling in concurrent scenarios.Setting
globalClientInfoin theoninitializedhandler creates shared state. In HTTP mode with concurrent requests from different clients, verify that:
- Each request's
requestContextcorrectly isolates per-client infoglobalClientInfoonly serves as a fallback (confirmed in tool handlers at lines 210, 298)The current implementation appears correct (context takes precedence), but ensure this behavior is intentional.
207-216: LGTM: Tool handler properly propagates clientInfo.The handler correctly retrieves
clientInfowith fallback logic and passes it tosearchLibrariesvia the newClientContextparameter.
295-313: LGTM: Consistent clientInfo propagation in docs handler.The docs tool handler follows the same fallback pattern and properly forwards
clientInfotofetchLibraryDocumentation.
393-410: LGTM: Safe clientInfo extraction from MCP initialize.The function correctly parses the MCP
initializerequest structure and safely extracts client metadata. Type guards and null checks are appropriate.
412-459: LGTM: Robust HTTP transport with caching and context propagation.The HTTP handler effectively:
- Extracts and caches
clientInfoper session/API key/IP- Updates cache timestamps on hits (line 428)
- Triggers probabilistic cleanup (line 432-434)
- Uses secure
randomUUID()for session IDs (line 437)- Properly isolates each request via
requestContext.run
461-471: LGTM: Useful HTTP endpoints added.The
/pinghealth-check endpoint and informative 404 handler improve operational visibility and developer experience.
Resolved conflicts by integrating 2.0.0 API changes with simplified context handling: - Updated searchLibraries to use new query+libraryName params with ClientContext - Updated fetchLibraryContext (new in 2.0.0) with ClientContext support - Kept getClientContext() helper for simplified tool handler context passing - All tool handlers now use getClientContext() for cleaner code
…ion in workflows Moved SERVER_VERSION constant from index.ts to lib/constants.ts for better organization. Updated GitHub workflows to inject version into the new location during ECR deployment and release processes.
Summary by CodeRabbit
New Features
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.