anthilll-inside

thunderbird89/anthilll-inside
0 starsMITCommunity

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

MCP server that reproduces SSE response-size hangs with Anthropic MCP clients by providing a configurable 'generate_lipsum' tool.

README.md

anthilll-inside

PoC MCP server for reproducing Anthropic hosted MCP client SSE response-size hangs.

The server uses @modelcontextprotocol/sdk@1.29.0 with stateless StreamableHTTPServerTransport in default SSE mode (enableJsonResponse: false), matching the conditions described in the bug report. A single tool — generate_lipsum — returns a configurable number of pseudo-Latin sentences so you can bracket the suspected ~10–333 KiB threshold.

Quick start (local)

cp .env.example .env
npm install
npm run dev

The MCP endpoint is http://127.0.0.1:3000/mcp.

Tool: generate_lipsum

| sentence_count | Approx. SSE response | | --- | --- | | 50 | ~8 KiB | | 500 | ~55 KiB | | 2000 | ~222 KiB | | 3000 | ~333 KiB |

Test with curl (SSE)

# Initialize + list tools (small SSE response)
curl -sS -X POST http://127.0.0.1:3000/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'

# Call generate_lipsum with 3000 sentences (~333 KiB SSE — matches bug report)
curl -sS -X POST http://127.0.0.1:3000/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"generate_lipsum","arguments":{"sentence_count":3000}}}'

Workaround mode (JSON)

Set ENABLE_JSON_RESPONSE=true to serve Content-Type: application/json instead of SSE — the known workaround from the bug report.

Logging

This PoC logs everything useful for layer-by-layer debugging:

Server-side (Pino structured logs to stdout):

  • request_received / request_completed — per-request access log with reqId, responseBytes, durationMs, writableEnded
  • jsonrpc_request_body — inbound JSON-RPC body (Bearer tokens redacted)
  • mcp_request_dispatch — method, Accept header, transport mode
  • tool_invoked / lipsum_generated / tool_response_ready — tool lifecycle with byte counts

Client-visible (MCP notifications/message via logging capability):

  • tool_start, lipsum_generated, tool_response_ready events with payloadBytes and toolReqId

Note: client-visible log notifications are only delivered in SSE mode; they are dropped when ENABLE_JSON_RESPONSE=true (SDK behavior).

Docker

docker build -t mcp-sse-repro .
docker run --rm -p 3000:3000 mcp-sse-repro

Kubernetes (Helm)

docker build -t your-registry/mcp-sse-repro:latest .
docker push your-registry/mcp-sse-repro:latest

helm upgrade --install mcp-sse-repro ./helm/mcp-sse-repro \
  --set image.repository=your-registry/mcp-sse-repro \
  --set image.tag=latest \
  --set ingress.enabled=true \
  --set ingress.hosts[0].host=mcp.example.com \
  --set env.ALLOWED_HOSTS=mcp.example.com

When deploying behind an ingress, set ALLOWED_HOSTS to your public hostname for DNS rebinding protection.

Configuration

| Variable | Default | Description | | --- | --- | --- | | PORT | 3000 | HTTP listen port | | HOST | 127.0.0.1 | Bind address (0.0.0.0 in container/K8s) | | ALLOWED_HOSTS | — | Comma-separated allowed Host headers | | ENABLE_JSON_RESPONSE | false | true = JSON workaround; false = SSE repro | | LOG_LEVEL | debug | Pino log level | | LOG_REQUEST_BODY | true | Log inbound JSON-RPC bodies | | LOG_RESPONSE_BODY_PREVIEW_BYTES | 2048 | Max bytes of request body to log | | MAX_SENTENCE_COUNT | 10000 | Upper bound for sentence_count |

Bug report

See anthropic-mcp-sse-bug-report.md for the full write-up with layer-by-layer evidence. File issues at anthropics/claude-ai-mcp.

Related MCP servers

Browse all →