@@ -2153,6 +2153,109 @@ if __name__ == "__main__":
21532153_ Full example: [ examples/snippets/clients/streamable_basic.py] ( https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/streamable_basic.py ) _
21542154<!-- /snippet-source -->
21552155
2156+ ### Per-Request HTTP Headers
2157+
2158+ 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:
2159+
2160+ <!-- snippet-source examples/snippets/clients/per_request_headers_example.py -->
2161+ ``` python
2162+ """
2163+ Example demonstrating per-request headers functionality for MCP client.
2164+
2165+ Shows how to use the extra_headers parameter to send different HTTP headers
2166+ with each request, enabling use cases like per-user authentication, request
2167+ tracing, A/B testing, and multi-tenant applications.
2168+ """
2169+
2170+ import asyncio
2171+
2172+ from mcp import ClientSession
2173+ from mcp.client.streamable_http import streamablehttp_client
2174+
2175+
2176+ async def main ():
2177+ """ Demonstrate per-request headers functionality."""
2178+
2179+ # Connection-level headers (static for the entire session)
2180+ connection_headers = {" Authorization" : " Bearer org-level-token" , " X-Org-ID" : " org-123" }
2181+
2182+ async with streamablehttp_client(" https://mcp.example.com/mcp" , headers = connection_headers) as (
2183+ read_stream,
2184+ write_stream,
2185+ _,
2186+ ):
2187+ async with ClientSession(read_stream, write_stream) as session:
2188+ await session.initialize()
2189+
2190+ # Example 1: Request tracing
2191+ tracing_headers = {
2192+ " X-Request-ID" : " req-12345" ,
2193+ " X-Trace-ID" : " trace-abc-456" ,
2194+ }
2195+ result = await session.call_tool(" process_data" , {" type" : " analytics" }, extra_headers = tracing_headers)
2196+ print (f " Traced request result: { result} " )
2197+
2198+ # Example 2: User-specific authentication
2199+ user_headers = {
2200+ " X-User-ID" : " alice" ,
2201+ " X-Auth-Token" : " user-token-12345" ,
2202+ }
2203+ result = await session.call_tool(" get_user_data" , {" fields" : [" profile" ]}, extra_headers = user_headers)
2204+ print (f " User-specific result: { result} " )
2205+
2206+ # Example 3: A/B testing
2207+ experiment_headers = {
2208+ " X-Experiment-ID" : " new-ui-test" ,
2209+ " X-Variant" : " variant-b" ,
2210+ }
2211+ result = await session.call_tool(
2212+ " get_recommendations" , {" user_id" : " user123" }, extra_headers = experiment_headers
2213+ )
2214+ print (f " A/B test result: { result} " )
2215+
2216+ # Example 4: Override connection-level headers
2217+ override_headers = {
2218+ " Authorization" : " Bearer user-specific-token" , # Overrides connection-level
2219+ " X-Special-Permission" : " admin" ,
2220+ }
2221+ result = await session.call_tool(" admin_operation" , {" operation" : " reset" }, extra_headers = override_headers)
2222+ print (f " Admin operation result: { result} " )
2223+
2224+ # Example 5: Works with all ClientSession methods
2225+ await session.list_resources(extra_headers = {" X-Resource-Filter" : " public" })
2226+ await session.get_prompt(" template" , extra_headers = {" X-Context" : " help" })
2227+ await session.set_logging_level(" debug" , extra_headers = {" X-Debug-Session" : " true" })
2228+
2229+
2230+ if __name__ == " __main__" :
2231+ print (" MCP Client Per-Request Headers Example" )
2232+ print (" =" * 50 )
2233+
2234+ try :
2235+ asyncio.run(main())
2236+ except Exception as e:
2237+ print (f " Example requires a running MCP server. Error: { e} " )
2238+ print (" \n This example demonstrates the API usage patterns." )
2239+ ```
2240+
2241+ _ 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 ) _
2242+ <!-- /snippet-source -->
2243+
2244+ The ` extra_headers ` parameter is available for all ` ClientSession ` methods that make server requests:
2245+
2246+ - ` call_tool() `
2247+ - ` get_prompt() `
2248+ - ` read_resource() `
2249+ - ` list_tools() `
2250+ - ` list_prompts() `
2251+ - ` list_resources() `
2252+ - ` list_resource_templates() `
2253+ - ` subscribe() `
2254+ - ` unsubscribe() `
2255+ - ` set_logging_level() `
2256+
2257+ Per-request headers are merged with the transport's default headers, with per-request headers taking precedence for duplicate keys.
2258+
21562259### Client Display Utilities
21572260
21582261When building MCP clients, the SDK provides utilities to help display human-readable names for tools, resources, and prompts:
0 commit comments