@@ -32,9 +32,14 @@ import Logging
32
32
/// ```swift
33
33
/// import MCP
34
34
///
35
- /// // Create a streaming HTTP transport
35
+ /// // Create a streaming HTTP transport with bearer token authentication
36
36
/// let transport = HTTPClientTransport(
37
- /// endpoint: URL(string: "http://localhost:8080")!,
37
+ /// endpoint: URL(string: "https://api.example.com/mcp")!,
38
+ /// requestModifier: { request in
39
+ /// var modifiedRequest = request
40
+ /// modifiedRequest.addValue("Bearer your-token-here", forHTTPHeaderField: "Authorization")
41
+ /// return modifiedRequest
42
+ /// }
38
43
/// )
39
44
///
40
45
/// // Initialize the client with streaming transport
@@ -60,6 +65,9 @@ public actor HTTPClientTransport: Transport {
60
65
/// Maximum time to wait for a session ID before proceeding with SSE connection
61
66
public let sseInitializationTimeout : TimeInterval
62
67
68
+ /// Closure to modify requests before they are sent
69
+ private let requestModifier : ( URLRequest ) -> URLRequest
70
+
63
71
private var isConnected = false
64
72
private let messageStream : AsyncThrowingStream < Data , Swift . Error >
65
73
private let messageContinuation : AsyncThrowingStream < Data , Swift . Error > . Continuation
@@ -74,19 +82,22 @@ public actor HTTPClientTransport: Transport {
74
82
/// - configuration: URLSession configuration to use for HTTP requests
75
83
/// - streaming: Whether to enable SSE streaming mode (default: true)
76
84
/// - sseInitializationTimeout: Maximum time to wait for session ID before proceeding with SSE (default: 10 seconds)
85
+ /// - requestModifier: Optional closure to customize requests before they are sent (default: no modification)
77
86
/// - logger: Optional logger instance for transport events
78
87
public init (
79
88
endpoint: URL ,
80
89
configuration: URLSessionConfiguration = . default,
81
90
streaming: Bool = true ,
82
91
sseInitializationTimeout: TimeInterval = 10 ,
92
+ requestModifier: @escaping ( URLRequest ) -> URLRequest = { $0 } ,
83
93
logger: Logger ? = nil
84
94
) {
85
95
self . init (
86
96
endpoint: endpoint,
87
97
session: URLSession ( configuration: configuration) ,
88
98
streaming: streaming,
89
99
sseInitializationTimeout: sseInitializationTimeout,
100
+ requestModifier: requestModifier,
90
101
logger: logger
91
102
)
92
103
}
@@ -96,12 +107,14 @@ public actor HTTPClientTransport: Transport {
96
107
session: URLSession ,
97
108
streaming: Bool = false ,
98
109
sseInitializationTimeout: TimeInterval = 10 ,
110
+ requestModifier: @escaping ( URLRequest ) -> URLRequest = { $0 } ,
99
111
logger: Logger ? = nil
100
112
) {
101
113
self . endpoint = endpoint
102
114
self . session = session
103
115
self . streaming = streaming
104
116
self . sseInitializationTimeout = sseInitializationTimeout
117
+ self . requestModifier = requestModifier
105
118
106
119
// Create message stream
107
120
var continuation : AsyncThrowingStream < Data , Swift . Error > . Continuation !
@@ -211,6 +224,9 @@ public actor HTTPClientTransport: Transport {
211
224
request. addValue ( sessionID, forHTTPHeaderField: " Mcp-Session-Id " )
212
225
}
213
226
227
+ // Apply request modifier
228
+ request = requestModifier ( request)
229
+
214
230
#if os(Linux)
215
231
// Linux implementation using data(for:) instead of bytes(for:)
216
232
let ( responseData, response) = try await session. data ( for: request)
@@ -480,6 +496,9 @@ public actor HTTPClientTransport: Transport {
480
496
request. addValue ( sessionID, forHTTPHeaderField: " Mcp-Session-Id " )
481
497
}
482
498
499
+ // Apply request modifier
500
+ request = requestModifier ( request)
501
+
483
502
logger. debug ( " Starting SSE connection " )
484
503
485
504
// Create URLSession task for SSE
0 commit comments