Skip to content

Allow dynamic header creation for MCP Servers - this can be useful for authorization headers #1891

@RRRajput

Description

@RRRajput

Description

Problem

Today, when initializing pydantic_ai.mcp.MCPServerHTTP, it is possible to provide static headers that will be sent along with each request:

from pydantic_ai.mcp import MCPServerHTTP

mcp_server = MCPServerHTTP("http://localhost:8090/mcp", headers={"Authorization": "Bearer wow-much-secret"})

This is fine if your headers are always static (or if your bearer token is static). However, for some cases you might want to dynamically generate the headers before each request.

Example: You want your authorization server (Auth0 or Azure AD) to provide you with an access token that should be sent with that request. You cannot generate that token in a static manner because the tokens expire after some time and would need to be refreshed (or renewed).

Workaround

Currently, there is a work-around for this, so it is not a blocking issue.

You create the MCPServerHTTP object just before connecting to the MCP server and modify the ._mcp_servers attribute of the agent:

# agent.py
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIModel
from pydantic_ai.providers.openai import OpenAIProvider
from .constants import AGENT_MODEL_NAME, AGENT_MODEL_URL


model = OpenAIModel(
    model_name=AGENT_MODEL_NAME, provider=OpenAIProvider(base_url=AGENT_MODEL_URL)
)
my_agent = Agent(
    model=model,
    deps_type=dict[str, str],
)
# main.py
from .agent import my_agent
from .auth import get_token # Custom code
from pydantic_ai.mcp import MCPServerHTTP

async def something() -> None:
    mcp_server = MCPServerHTTP("http://localhost:8090/mcp", headers={"Authorization": get_token()})
    # The line below is the ugly part :-(
    my_agent._mcp_servers = [MCPServerHTTP(url=MCP_SERVER_URL, headers=headers)]
    async with my_agent.run_mcp_servers():
       log.info("Connected to the MCP Server. Running agent...")
       ... # Do something

Not sure how the API should be for allowing dynamically created headers, though.

References

No response

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions