Skip to content

Python: [Bug]: Unable to pass AgentContext to MCPStreamableHTTPTool #4808

@ashishmundra4001

Description

@ashishmundra4001

Issue

Unable to pass AgentContext values from Agent Middleware into MCPStreamableHttpTool

Description

I am unsure if this is a missing feature or simply a missing sample. Raising this as a Bug to get clarification.

Setup:

  • My Agent is hosted as a Foundry Hosted Agent using HostingAdapter.from_agent_framework(agent).run().
  • In my Agent-level Middleware, I set some kwargs values. These are populated from the /responses API metadata field (which is sent to _request_headers).
  • I want these kwargs values to be available to my Tool.
  • I attempted to use function_invocation_kwargs, but that failed at runtime (not the main issue here).

MCP Server Integration:

  • My Agent has tools accessible from an MCP server hosted externally.
  • The MCP server requires certain headers.
  • Currently, I send these headers using http_client.
  • Ideally, I would prefer to send headers without creating a separate http_client, but that’s secondary.

Main Issue: When the MCP server is called from my Agent, it should receive the AgentContext variables I set in kwargs (from _request_headers). These values should be passed as additional headers to the MCP server, since they are required on every /responses API call.

I could not find any example showing how to send values extracted in middleware into MCPStreamableHttpTool.

Question
How can I pass AgentContext values (set in Agent Middleware) into MCPStreamableHttpTool so that they are forwarded as headers to the MCP server?

Code Sample

Middleware Code:

from agent_framework import AgentMiddleware, AgentContext
from collections.abc import Callable, Awaitable

class UserContextAgentMiddleware(AgentMiddleware):
    """Agent middleware that obtains user context."""

    async def process(
        self,
        context: AgentContext,
        next: Callable[[], Awaitable[None]],
    ) -> None:
        if hasattr(context.agent, '_request_headers'):
            request_data = context.agent._request_headers

            # Runtime values that will be forwarded to tools
            if 'x-some-token' in request_data:
                context.kwargs.setdefault("some_token", request_data['x-some-token'])
                context.metadata["some_token"] = request_data['x-some-token']

        await next()

from agent_framework import FunctionInvocationContext
from agent_framework import FunctionMiddleware
from collections.abc import Callable, Awaitable
import time

class UserContextFunctionMiddleware(FunctionMiddleware):
    """Function middleware that logs function calls."""

    async def process(
        self,
        context: FunctionInvocationContext,
        call_next: Callable[[], Awaitable[None]],
    ) -> None:
        function_name = context.function.name
        print(f"[UserContextFunctionMiddleware] About to call function: {function_name}.")
        print(f"[UserContextFunctionMiddleware] Function context: {context.metadata}, {context.kwargs}, {context.arguments}")

        start_time = time.time()

        await call_next()

        end_time = time.time()
        duration = end_time - start_time

        print(f"[UserContextFunctionMiddleware] Function {function_name} completed in {duration:.5f}s.")


When I send /responses api call, I only see context.kwargs is populated in UserContextFunctionMiddleware and context.metadata and context.arguments are empty.


MCP Server Tool Setup Code:


    def create_mcp_tool(self, kwargs: Any = None) -> MCPStreamableHTTPTool:
        """Create and configure MCP tool."""
        
        print("Running MCP tool with URL:", kwargs)
        # Set up HTTP client if not already done
        if not self.http_client:
            self.setup_http_client()
            
        logger.info(f"Creating MCP tool for server: {self.config.mcp_server_url}")
        
        self.mcp_tool = MCPStreamableHTTPTool(
            name="University MCP Tool",
            description="Access to resources in ",
            url=self.config.mcp_server_url,
            http_client=self.http_client,
            load_tools=True,
            load_prompts=False,
            approval_mode="never_require",
        )
        
        return self.mcp_tool


Http Client needs some fixed headers and some dynamic per request headers. Code to set fixed header is something like below (its not exact code, but so far fixed header works):


    def setup_http_client(self) -> None:
        """Create HTTP client with dynamic authentication for MCP tools."""        
        keyvault_manager = KeyVaultManager(
            key_vault_url=self.config.azure_keyvault_url
        )
        
        # Retrieve API keys using the same KeyVault client
        mcp_subscription_key = keyvault_manager.get_secret(self.config.mcp_key_subscription_key)

        self.http_client = AsyncClient(auth=mcp_subscription_key, timeout=30.0)


Main question is - How can I send per call additional headers that goes to MCP Server. These headers will be dynamically populated from /responses api metadata field.

Error Messages / Stack Traces

Package Versions

azure-ai-agentserver-agentframework==1.0.0b17
agent-framework-azure-ai

Python Version

3.12

Additional Context

No response

Metadata

Metadata

Labels

bugSomething isn't workingpython

Type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions