@@ -2233,6 +2233,109 @@ if __name__ == "__main__":
22332233_ Full example: [ examples/snippets/clients/streamable_basic.py] ( https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/streamable_basic.py ) _
22342234<!-- /snippet-source -->
22352235
2236+ ### Per-Request HTTP Headers
2237+
2238+ When using HTTP transports, you can pass custom headers on a per-request basis. This enables various use cases such as request tracing, authentication context, A/B testing, debugging flags, and more while maintaining a single persistent connection:
2239+
2240+ <!-- snippet-source examples/snippets/clients/per_request_headers_example.py -->
2241+ ``` python
2242+ """
2243+ Example demonstrating per-request headers functionality for MCP client.
2244+
2245+ Shows how to use the extra_headers parameter to send different HTTP headers
2246+ with each request, enabling use cases like per-user authentication, request
2247+ tracing, A/B testing, and multi-tenant applications.
2248+ """
2249+
2250+ import asyncio
2251+
2252+ from mcp import ClientSession
2253+ from mcp.client.streamable_http import streamablehttp_client
2254+
2255+
2256+ async def main ():
2257+ """ Demonstrate per-request headers functionality."""
2258+
2259+ # Connection-level headers (static for the entire session)
2260+ connection_headers = {" Authorization" : " Bearer org-level-token" , " X-Org-ID" : " org-123" }
2261+
2262+ async with streamablehttp_client(" https://mcp.example.com/mcp" , headers = connection_headers) as (
2263+ read_stream,
2264+ write_stream,
2265+ _,
2266+ ):
2267+ async with ClientSession(read_stream, write_stream) as session:
2268+ await session.initialize()
2269+
2270+ # Example 1: Request tracing
2271+ tracing_headers = {
2272+ " X-Request-ID" : " req-12345" ,
2273+ " X-Trace-ID" : " trace-abc-456" ,
2274+ }
2275+ result = await session.call_tool(" process_data" , {" type" : " analytics" }, extra_headers = tracing_headers)
2276+ print (f " Traced request result: { result} " )
2277+
2278+ # Example 2: User-specific authentication
2279+ user_headers = {
2280+ " X-User-ID" : " alice" ,
2281+ " X-Auth-Token" : " user-token-12345" ,
2282+ }
2283+ result = await session.call_tool(" get_user_data" , {" fields" : [" profile" ]}, extra_headers = user_headers)
2284+ print (f " User-specific result: { result} " )
2285+
2286+ # Example 3: A/B testing
2287+ experiment_headers = {
2288+ " X-Experiment-ID" : " new-ui-test" ,
2289+ " X-Variant" : " variant-b" ,
2290+ }
2291+ result = await session.call_tool(
2292+ " get_recommendations" , {" user_id" : " user123" }, extra_headers = experiment_headers
2293+ )
2294+ print (f " A/B test result: { result} " )
2295+
2296+ # Example 4: Override connection-level headers
2297+ override_headers = {
2298+ " Authorization" : " Bearer user-specific-token" , # Overrides connection-level
2299+ " X-Special-Permission" : " admin" ,
2300+ }
2301+ result = await session.call_tool(" admin_operation" , {" operation" : " reset" }, extra_headers = override_headers)
2302+ print (f " Admin operation result: { result} " )
2303+
2304+ # Example 5: Works with all ClientSession methods
2305+ await session.list_resources(extra_headers = {" X-Resource-Filter" : " public" })
2306+ await session.get_prompt(" template" , extra_headers = {" X-Context" : " help" })
2307+ await session.set_logging_level(" debug" , extra_headers = {" X-Debug-Session" : " true" })
2308+
2309+
2310+ if __name__ == " __main__" :
2311+ print (" MCP Client Per-Request Headers Example" )
2312+ print (" =" * 50 )
2313+
2314+ try :
2315+ asyncio.run(main())
2316+ except Exception as e:
2317+ print (f " Example requires a running MCP server. Error: { e} " )
2318+ print (" \n This example demonstrates the API usage patterns." )
2319+ ```
2320+
2321+ _ Full example: [ examples/snippets/clients/per_request_headers_example.py] ( https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/per_request_headers_example.py ) _
2322+ <!-- /snippet-source -->
2323+
2324+ The ` extra_headers ` parameter is available for all ` ClientSession ` methods that make server requests:
2325+
2326+ - ` call_tool() `
2327+ - ` get_prompt() `
2328+ - ` read_resource() `
2329+ - ` list_tools() `
2330+ - ` list_prompts() `
2331+ - ` list_resources() `
2332+ - ` list_resource_templates() `
2333+ - ` subscribe() `
2334+ - ` unsubscribe() `
2335+ - ` set_logging_level() `
2336+
2337+ Per-request headers are merged with the transport's default headers, with per-request headers taking precedence for duplicate keys.
2338+
22362339### Client Display Utilities
22372340
22382341When building MCP clients, the SDK provides utilities to help display human-readable names for tools, resources, and prompts:
0 commit comments