wso2 / wso2/api-platform

[Bug]: MCP proxy buffers SSE responses, deadlocking elicitation and all server-initiated requests

Open
#2,968 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Aspect/AI Aspect/API Severity/Blocker Type/Bug
Dominant language
Go
Stars
71
Forks
111
Avg merge
1d 14h
Merged PRs (30d)
110

Description

Please select the area the issue is related to

Gateway

Please select the aspect the issue is related to

Aspect/API (API backends, definitions, contracts, interfaces, OpenAPI), Aspect/AI (AI/LLM integration, MCP, AI readiness)

Description

An MCP proxy (kind: Mcp) does not stream responses to the client. Envoy holds the entire response body until end-of-stream, so any MCP response that stays open, which is every server-to-client interaction, is never delivered.

This reproduces on a bare MCP proxy with no policies attached.

Ordinary request/response MCP tools are unaffected, because their responses complete on their own and the buffered body is released immediately. That is why this has not surfaced before: the failure only appears for MCP features where the server deliberately pauses mid-response (elicitation/create).

The failure mode is a silent hang, not an error. The server blocks waiting for a reply the client can never send; the client blocks waiting for a request it never receives. Nothing is logged as an error until a timeout fires - Envoy's stream_idle_timeout at 300 s, or the client's own deadline.

Steps to Reproduce
1. Start the gateway
cd gateway
docker compose up -d gateway-controller gateway-runtime
2. Start the mock MCP server

It exposes a confirm_action tool that sends an elicitation and waits for the answer before returning.

docker run -d --name mock-mcp-survey --network gateway_gateway-network \
  -p 3010:3010 thinal04/mock-mcp-survey:1.0.0
3. Deploy it as an MCP proxy (no policies)
curl -X POST http://localhost:9090/api/management/v1/mcp-proxies \
  -H "Content-Type: application/yaml" \
  -H "Authorization: Basic YWRtaW46YWRtaW4=" \
  --data-binary @- <<'EOF'
apiVersion: gateway.api-platform.wso2.com/v1
kind: Mcp
metadata:
  name: survey-mcp-v1.0
spec:
  displayName: Survey
  version: v1.0
  context: /survey
  specVersion: "2025-11-25"
  upstream:
    url: http://mock-mcp-survey:3010
EOF
4. Call the tool directly - works

Using any MCP client that supports elicitation (MCP Inspector):

 npx @modelcontextprotocol/inspector@latest

connect to http://localhost:3010/mcp and call confirm_action tool.

5. Call the same tool through the gateway - hangs

Same client, endpoint http://localhost:8080/survey/mcp and call confirm_action tool.

7. View Logs
docker compose logs -f gateway-runtime
Severity Level of the Issue

Severity/Blocker (Core functionality is broken and consumer is blocked. Need immediate attention)

Environment Details (with versions)
  • ghcr.io/wso2/api-platform/gateway-controller:latest — image id e30f1dfd17a9
  • ghcr.io/wso2/api-platform/gateway-runtime:latest — image id 99412b259fad
  • Deployed with gateway/docker-compose.yaml, default profile
  • Host: Windows 11 Pro 22621, Docker Desktop
  • Backend MCP server: github.com/modelcontextprotocol/go-sdk v1.6.1, Streamable HTTP transport
  • MCP spec version 2025-11-25 (also reproduces with 2025-06-18)
  • Clients tested: MCP Inspector, go-sdk client with ElicitationHandler, raw curl
  • No policies attached to the MCP proxy
  • Reproduction image: thinal04/mock-mcp-survey:1.0.0 (linux/amd64 + linux/arm64)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the hang with the gateway/docker-compose setup, the mock MCP server, and the MCP Inspector or curl commands described in the issue. Start by tracing the gateway runtime's MCP proxy response path and its handling of open streams; done means server-initiated MCP requests and elicitation responses are delivered through the proxy instead of waiting for end-of-stream.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, go
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.