fix: Pass RequestInit options to auth requests - #1066
Merged
Merged
Conversation
dsp-ant
force-pushed
the
fix/auth-requestinit-headers
branch
from
November 3, 2025 18:25
80747de to
4005a0e
Compare
Member
Author
|
@pcarleton checking if we can review this. The underlying problem is that @dcramer is trying to ban clients that spam auth endpoint. because we dont pass user-agent to the http client for auth discovery, he ends up getting generic user-agents and cant ban a specific client. |
pcarleton
requested changes
Nov 7, 2025
| let result: AuthResult; | ||
| try { | ||
| // Wrap fetch to automatically include base RequestInit options | ||
| const fetchFn = createFetchWithInit(this._fetch, this._requestInit); |
Member
There was a problem hiding this comment.
is there a reason to do this each time vs. in the constructor?
Member
Author
There was a problem hiding this comment.
let me ask claude why it thought this is a good idea :p
pcarleton
approved these changes
Nov 7, 2025
commit: |
dsp-ant
enabled auto-merge (squash)
November 12, 2025 16:03
Fixes an issue where custom headers (like user-agent) and other RequestInit options set when creating transports were not being passed through to authorization requests (.well-known/ discovery, token exchange, DCR, etc.). Changes: - Created createFetchWithInit() utility in shared/transport.ts to wrap fetch with base RequestInit options - Transports now wrap their fetch function before passing to auth module - All RequestInit options (headers, credentials, mode, etc.) are now preserved - Auth-specific headers properly override base headers when needed - Extracted normalizeHeaders() to shared/transport.ts for reuse 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Added comprehensive tests to verify that: - Custom headers (like user-agent) from RequestInit are passed to auth requests - Auth-specific headers override base headers when needed - All RequestInit options (credentials, mode, cache, etc.) are preserved All 553 tests pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Fix linting errors by removing unused destructured url variables.
Move the createFetchWithInit() call from _authThenStart() to the constructor to avoid recreating the wrapper function on every auth attempt. This is more efficient and follows better practices. The wrapped fetch function is now stored in _fetchWithInit and reused across all auth-related calls in _authThenStart(), finishAuth(), and send(). Addresses code review feedback from @pcarleton 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Match the pattern used in StreamableHTTPClientTransport by creating the wrapped fetch function once in the constructor instead of recreating it on every auth call. This improves consistency between the two transport implementations and avoids unnecessary function recreation. Changes: - Add _fetchWithInit field to store the wrapped fetch function - Initialize _fetchWithInit in constructor using createFetchWithInit - Use _fetchWithInit in all auth() calls instead of creating inline - Remove redundant createFetchWithInit calls from 3 locations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
dsp-ant
force-pushed
the
fix/auth-requestinit-headers
branch
from
November 17, 2025 15:57
1a39051 to
2f207ac
Compare
The three RequestInit tests were incorrectly using jest.fn() instead of vi.fn(), causing CI failures. The rest of the test file uses Vitest. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes an issue where custom headers (like
user-agent) and otherRequestInitoptions set when creating transports were not being passed through to authorization requests.Problem
When clients set custom headers via
requestInit.headerswhen instantiating transports (StreamableHTTPClientTransport,SSEClientTransport), these headers were correctly used for normal MCP operations but were lost during authorization requests such as:.well-known/metadata discoverySolution
Created a
createFetchWithInit()utility function insrc/shared/transport.tsthat wraps the fetch function to automatically include baseRequestInitoptions. The transports now use this wrapper before passing fetch to auth functions.Key Changes
Added
createFetchWithInit()utility (src/shared/transport.ts)RequestInitoptionsRequestInitoptions (credentials, mode, cache, etc.)Updated transports (
src/client/streamableHttp.ts,src/client/sse.ts)createFetchWithInit()to create wrapped fetch for auth requestsExtracted
normalizeHeaders()utility (src/shared/transport.ts)Benefits
RequestInitoptions preserved, not just headersTesting
Added comprehensive tests in
src/client/auth.test.ts:RequestInitare passed to auth discovery requestsRequestInitoptions are preservedAll 553 tests pass ✅
Test plan
Run the test suite:
npm testAll tests should pass (pre-existing failures in some test suites are due to missing dependencies, not related to these changes).
🤖 Generated with Claude Code