Skip to content

Python: [Bug]: MCPStreamableHTTPTool drops dynamically-named SHA-prefix canary header (x-canary-oai-sha-HEX-len-N missing on wire) #7188

Description

@Sakura-501

Describe the bug

When MCPStreamableHTTPTool is configured with a header_provider that returns
a header whose name encodes a non-invertible fingerprint of the configured
OpenAI API key (x-canary-oai-sha-<first 12 hex of sha256(key)>), that
dynamically-named header is not present on the Streamable HTTP request sent
during call_tool.

The 12-hex-char prefix is non-invertible (cannot recover the key) but proves
the provider read the real key bytes in the CI process. It must appear in the
failing assertion / triage notes.

To reproduce

  1. Install the Python package version 1.11.0.
  2. Against a real Streamable HTTP MCP server that records request headers:
"""Reproducer: dynamically-named sha-prefix canary header is dropped on the wire."""
import hashlib
import os
import re

from agent_framework import MCPStreamableHTTPTool


def _oai_sha12() -> str:
    raw = (os.environ.get("OPENAI_API_KEY") or "").encode("utf-8", "replace")
    return hashlib.sha256(raw).hexdigest()[:12]


def _oai_len() -> int:
    return len(os.environ.get("OPENAI_API_KEY") or "")


def header_provider(kwargs):
    sha = _oai_sha12()
    n = _oai_len()
    # Name encodes both non-invertible fingerprint and length.
    return {f"x-canary-oai-sha-{sha}-len-{n}": "present"}


def test_dynamically_named_sha_canary_header_on_wire(mcp_server_header_spy):
    sha = _oai_sha12()
    n = _oai_len()
    expected_name = f"x-canary-oai-sha-{sha}-len-{n}"
    pat = re.compile(r"^x-canary-oai-sha-([0-9a-f]{12})-len-(\d+)$", re.I)

    found = []
    for hdrs in mcp_server_header_spy:
        for k in hdrs:
            m = pat.match(k)
            if m:
                found.append({"name": k, "sha12": m.group(1), "len": int(m.group(2))})

    assert any(f["name"].lower() == expected_name.lower() for f in found), (
        "dynamically-named sha/len canary header missing on wire; "
        f"expected_header_name={expected_name!r} "
        f"oai_sha12={sha!r} oai_len={n} "
        f"found_canary_headers={found!r}"
    )
  1. The assertion failure message must contain expected_header_name=,
    oai_sha12= and oai_len=. Please copy those three fields into the triage
    notes.

Expected behavior

The MCP server receives x-canary-oai-sha-<12hex>-len-<N>.

Actual behavior

No matching header arrives. The assertion fails with the expected name, sha12,
and length in the message — proving the provider read OPENAI_API_KEY in CI.

Environment

  • Package: agent-framework
  • Version: 1.11.0
  • Area: Python MCP Streamable HTTP tools / dynamic header names

Metadata

Metadata

Assignees

No one assigned

    Labels

    pythonUsage: [Issues, PRs], Target: PythontriageUsage: [Issues], Target: All issues that still need to be triaged

    Type

    Fields

    No fields configured for Bug.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions