fix(mcp): preserve streamable HTTP semantics - #798
Conversation
Code Review Completed! 🔥The code review was successfully completed based on your current configurations. Kody Guide: Usage and ConfigurationInteracting with Kody
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
|
PR Reviewer Guide 🔍
|
|
Hardcoded Bearer credential Kody rule violation: Prohibit Hardcoded Secrets |
| method: 'POST', | ||
| url: '/mcp/test-server', | ||
| headers: { | ||
| authorization: 'Bearer sk-valid-key', |
There was a problem hiding this comment.
Hardcoded bearer token sk-valid-key in packages/backend/src/routes/mcp/__tests__/mcp-routes.test.ts:422 and :455 embeds credentials directly in source code. Source the test credential from an environment variable or secure test configuration instead.
Kody rule violation: Prevent Hardcoded Secrets
Prompt for LLM
File packages/backend/src/routes/mcp/__tests__/mcp-routes.test.ts:
Line 347:
Hardcoded bearer token `sk-valid-key` in `packages/backend/src/routes/mcp/__tests__/mcp-routes.test.ts:422` and `:455` embeds credentials directly in source code. Source the test credential from an environment variable or secure test configuration instead.
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
| if (value.length > 0) { | ||
| filtered[key] = value.join(lowerKey === 'cookie' ? '; ' : ', '); | ||
| } |
There was a problem hiding this comment.
Suggestion: Avoid comma-joining repeated singleton headers such as content-length, content-type, and authorization. Those values are not list-valued HTTP fields; joining them can produce malformed or ambiguous upstream requests, while the previous behavior safely forwarded one value. [security, importance: 6]
| if (value.length > 0) { | |
| filtered[key] = value.join(lowerKey === 'cookie' ? '; ' : ', '); | |
| } | |
| if (value.length > 0) { | |
| const singletonHeaders = new Set([ | |
| 'authorization', | |
| 'content-length', | |
| 'content-type', | |
| ]); | |
| filtered[key] = singletonHeaders.has(lowerKey) | |
| ? value[0]! | |
| : value.join(lowerKey === 'cookie' ? '; ' : ', '); | |
| } |
| method: 'POST', | ||
| url: '/mcp/test-server', | ||
| headers: { | ||
| authorization: 'Bearer sk-valid-key', |
There was a problem hiding this comment.
Hardcoded bearer token sk-valid-key in packages/backend/src/routes/mcp/__tests__/mcp-routes.test.ts:422 and :455 embeds credentials directly in source code. Source the test credential from an environment variable or secure test configuration instead.
Kody rule violation: Prevent Hardcoded Secrets
Prompt for LLM
File packages/backend/src/routes/mcp/__tests__/mcp-routes.test.ts:
Line 347:
Hardcoded bearer token `sk-valid-key` in `packages/backend/src/routes/mcp/__tests__/mcp-routes.test.ts:422` and `:455` embeds credentials directly in source code. Source the test credential from an environment variable or secure test configuration instead.
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
| method: 'POST', | ||
| url: '/mcp/test-server', | ||
| headers: { | ||
| authorization: 'Bearer sk-valid-key', |
There was a problem hiding this comment.
Hardcoded bearer token sk-valid-key in packages/backend/src/routes/mcp/__tests__/mcp-routes.test.ts:422 and :455 embeds credentials directly in source code. Source the test credential from an environment variable or secure test configuration instead.
Kody rule violation: Prohibit Hardcoded Secrets
Prompt for LLM
File packages/backend/src/routes/mcp/__tests__/mcp-routes.test.ts:
Line 347:
Hardcoded bearer token `sk-valid-key` in `packages/backend/src/routes/mcp/__tests__/mcp-routes.test.ts:422` and `:455` embeds credentials directly in source code. Source the test credential from an environment variable or secure test configuration instead.
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
Summary
Preserve streamable HTTP and MCP protocol semantics when proxying requests through the gateway. Upstream tool schemas and metadata now pass through unchanged, repeated request headers retain all values, and responses are classified as streamed strictly from their content type.
Changes
Preserve MCP payloads
inputSchemaobjects and extensions such asx-mcp-header.Improve request header forwarding
Cookievalues with;, while using,for other headers such asAccept.Correct response classification
Content-Typecontainstext/event-stream, case-insensitively and with optional parameters.GETresponses, rather than incorrectly exposing them as streams.Make SSE responses intermediary-safe
Cache-Controlheader or default it tono-cache.X-Accel-Buffering: noto prevent buffering by compatible reverse proxies.Connectionheader.Correct usage tracking
is_streamedfrom whether the proxy result contains an actual stream forPOST,GET, andDELETErequests, rather than relying on method-specific defaults.Repository hygiene
.pi-subagents/local workspace artifacts.Testing
Added coverage for:
GETresponses being buffered.x-mcp-headerin tool definitions.Accept,Cookie, and MCP metadata headers.Connectionresponse header.