Skip to content

[Agentcore-Harness BUG] MCP client does not send required Accept header for Streamable HTTP transport, causing 406 on spec-compliant servers #2263

@syedwasimwb

Description

@syedwasimwb

Checks

  • I have updated to the lastest minor and patch version of Strands
  • I have checked the documentation and this is not expected behavior
  • I have searched ./issues and there are no duplicates of my issue

Strands Version

1.38.0

Python Version

3.10

Operating System

Linux

Installation Method

pip

Steps to Reproduce

  1. Set up an MCP server using Streamable HTTP transport (protocol version 2025-03-26) that enforces the Accept header per spec — returns HTTP 406 if the client does not send Accept: application/json, text/event-stream

  2. Configure a Strands agent (or Bedrock AgentCore Harness) with a remote_mcp tool pointing to that server URL

  3. Invoke the agent/harness

  4. The MCP client initialization fails with:
    Failed to start MCP client: the client initialization failed Deserialization error: to see the raw response, inspect the hidden field {error}.$response on this object.

========================

1. Create a spec-compliant MCP server that enforces the Accept header (mcp_server.py):

from flask import Flask, request, jsonify, Response
import json

app = Flask(__name__)

@app.route("/mcp", methods=["POST"])
def mcp_endpoint():
    accept_header = request.headers.get("Accept", "")
    has_json = "application/json" in accept_header
    has_sse = "text/event-stream" in accept_header

    if not (has_json and has_sse):
        return jsonify({
            "jsonrpc": "2.0",
            "error": {
                "code": -32000,
                "message": "Not Acceptable: Client must accept both application/json and text/event-stream"
            },
            "id": None
        }), 406

    body = request.get_json(force=True)
    method = body.get("method", "")
    req_id = body.get("id")

    if method == "initialize":
        result = {"protocolVersion": "2025-03-26", "capabilities": {"tools": {}}, "serverInfo": {"name": "TestMCP", "version": "1.0.0"}}
        event_data = json.dumps({"result": result, "jsonrpc": "2.0", "id": req_id})
        return Response(f"event: message\ndata: {event_data}\n\n", content_type="text/event-stream")
    elif method == "notifications/initialized":
        return "", 202
    elif method == "tools/list":
        result = {"tools": [{"name": "hello", "description": "Test tool", "inputSchema": {"type": "object", "properties": {"name": {"type": "string"}}, "required": ["name"]}}]}
        event_data = json.dumps({"result": result, "jsonrpc": "2.0", "id": req_id})
        return Response(f"event: message\ndata: {event_data}\n\n", content_type="text/event-stream")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5555)

2. Connect a Strands agent to it:

from strands import Agent
from strands.tools.mcp import MCPClient
from mcp import stdio_client
from mcp.client.streamable_http import streamablehttp_client

mcp_client = MCPClient(lambda: streamablehttp_client(url="http://your-mcp-server:5555/mcp"))

agent = Agent(tools=[mcp_client])
agent("hello")

3. Observe the failure:

The MCP client sends Accept: */* instead of Accept: application/json, text/event-stream, causing the server to return 406 and the client to throw MCPClientInitializationError.

4. Verify the server works with correct headers:

import requests

# This succeeds (200)
r = requests.post("http://localhost:5555/mcp",
    json={"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2025-03-26", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0"}}},
    headers={"Content-Type": "application/json", "Accept": "application/json, text/event-stream"})
print(r.status_code)  # 200

# This fails (406) - same as what the Strands MCP client sends
r = requests.post("http://localhost:5555/mcp",
    json={"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2025-03-26", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0"}}},
    headers={"Content-Type": "application/json"})
print(r.status_code)  # 406

Expected Behavior

The MCP client should send Accept: application/json, text/event-stream on all POST requests to the MCP server endpoint, as required by the MCP Streamable HTTP transport specification (2025-03-26):

"The client MUST include an Accept header, listing both application/json and text/event-stream as supported content types."

Reference: https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#sending-messages-to-the-server

Actual Behavior

The client sends Accept: */* (default httpx behavior), causing spec-compliant MCP servers to reject with HTTP 406 "Not Acceptable":

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32000,
    "message": "Not Acceptable: Client must accept both application/json and text/event-stream"
  },
  "id": null
}

Stack trace from Harness runtime logs:


File "/opt/amazon/lib/python3.10/site-packages/mcp/client/streamable_http.py", line 358, in _handle_post_request
    response.raise_for_status()
httpx.HTTPStatusError: Client error '406 Not Acceptable'

### Additional Context

```markdown
- This is a known issue across multiple MCP clients in the ecosystem
- The underlying issue is in `mcp/client/streamable_http.py` (the MCP Python SDK) which the Strands SDK depends on
- Other AgentCore components (e.g., Gateway client in `A3CFabricDemoAgent`) correctly send this header
- Affects all users of `remote_mcp` tool type in Bedrock AgentCore Harness

### Possible Solution

Add the required Accept header in the httpx client configuration within `streamable_http.py`:

```python
headers["Accept"] = "application/json, text/event-stream"


### Related Issues

https://github.com/junjiem/dify-plugin-tools-mcp_sse/issues/70

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions