openai/openai-agents-python

Add Custom HTTP Header Support to HostedMCPTool

Closed this issue · 0 comments

Please read this first

  • Have you read the docs?
    Yes – I reviewed the official Agents SDK docs (https://openai.github.io/openai-agents-python/) and confirmed there is no mention of forwarding arbitrary HTTP headers from HostedMCPTool to an MCP server.

  • Have you searched for related issues?
    Yes – I searched open and closed issues for “HostedMCPTool headers”, “custom headers”, and “MCP header”. No existing feature request or bug report covers this gap.


Describe the feature

Summary

HostedMCPTool should forward custom HTTP headers supplied in its tool_config to the remote MCP server for every request the Responses API makes (list_tools and call_tool). This brings feature-parity with self-managed server classes and unlocks several enterprise use cases that cannot be solved today without abandoning the hosted flow.


Motivation / Use-cases

Use-case Header Example Why headers (vs query params / URL)?
Tenant routing in a multi-tenant MCP X-Tenant-ID: 92c3f Avoids tenant leakage in caches / logs
Feature gating / canary control X-Feature-Flag: beta-embeddings Keeps internal flags off the public path
Zero-trust auth where bearer token cannot be shared in Authorization X-Service-Token: abc123 Distinct from user OAuth / external API keys
Regulatory or data-residency tagging X-Data-Region: eu-central Lets load-balancers route to correct shards

Without header support, teams must fall back to MCPServerStreamableHttp / MCPServerSse, giving up:

  • Zero-round-trip latency improvements of hosted MCP
  • Built-in approval flows handled by OpenAI infrastructure
  • Simpler network egress (no public inbound firewall rules required)

Proposed Design

  1. API Schema Change
    Add an optional headers: { [key: string]: string } field to the Responses API’s Mcp schema.
    • Must be allowed in both POST /v1/mcp/list_tools and POST /v1/mcp/call_tool payloads.
    Validation: keys ≤ 256 chars, values ≤ 1 kB, total header count ≤ 50 to prevent abuse.

  2. Agents SDK Changes
    • Update the HostedMCPTool dataclass:

    class HostedMCPTool(ToolBase):
        tool_config: Mcp  # typed dict extended to include `headers`

    • Plumb tool_config["headers"] through _run_impl.py when constructing the hosted tool invocation request.

  3. Backward Compatibility
    • Omit headers → current behaviour (no custom headers)
    • Unknown keys continue to be rejected or ignored exactly as today (depends on server-side validation).


Example Usage

HostedMCPTool(
    tool_config={
        "type": "mcp",
        "server_label": "gitmcp",
        "server_url": "https://gitmcp.example.com/openai/codex",
        "require_approval": "never",
        "headers": {
            "X-Workspace": "demo",
            "X-Feature-Flag": "beta"
        }
    }
)
Resulting Wire Request (illustrative)
POST /v1/mcp/call_tool HTTP/1.1
Content-Type: application/json
OpenAI-API-Key: sk-...
X-Workspace: demo
X-Feature-Flag: beta
...
{
  "tool_config": {
    "type": "mcp",
    ...
  },
  "message": "..."
}

Acceptance Criteria

  1. Functional
    • When headers present, MCP server receives them on both list_tools and call_tool requests.
    • When absent, behaviour is unchanged.

  2. Limits & Errors
    • Exceeding any header validation limit returns a clear error (HTTP 400 / error code mcp_invalid_headers).

  3. Tests
    • Unit tests in tests/mcp/ asserting the header dictionary reaches the mocked server.
    • Integration test behind a feature flag once the Responses API change is live.

  4. Documentation
    • Update docs (docs/mcp.md) with new field description and code snippet.
    • Changelog entry under “Added”.


Alternatives Considered

Approach Pros Cons
Metadata field (dictionary forwarded but not used as HTTP headers) Easiest schema change Still requires MCP implementors to map metadata → headers, drifts from existing self-managed pattern
Environment-style key prefix (e.g. header_X_Workspace) No schema change Leaks impl details; confusing for users
Custom connector option Flexible High complexity; overkill for simple header forwarding

Risks & Mitigations

Risk Mitigation
Header abuse / very large payloads Enforce size / count limits (see validation above).
Conflicts with Responses API internal headers Namespacing guidance in docs; prefixes like X-App-*.
Security of secrets in headers Recommend short-lived tokens or mTLS; document that headers traverse OpenAI infra encrypted in-transit.

Additional Context

A full problem statement, motivation, and code references live in this repository’s issue.md (commit <sha>). Self-managed implementations already accept a headers param (MCPServerStreamableHttp, MCPServerSse), so the request is primarily about extending the hosted path for consistency.