modelcontextprotocol / modelcontextprotocol/java-sdk

SSE client rejects valid `retry:` field and ignores reconnection timing (Streamable HTTP)

Đang mở
#1,047 2 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

area/client area/transport P2 waiting for user
Ngôn ngữ chính
Java
Star
3.7k
Fork
1.1k
Merge trung bình
1 ngày 15 giờ
Pull request đã merge (30 ngày)
9

Mô tả

Bug description

The client SSE line parser in ResponseSubscribers rejects the standard SSE retry: field, throwing:

io.modelcontextprotocol.spec.McpTransportException: Invalid SSE response. Status code: 200 Line: retry: 500

Per the SSE specification, retry: sets the stream's reconnection time, and unknown fields MUST be ignored (never error the stream). Because of this, the Streamable HTTP client:

  1. can error a live SSE stream when the server sends a retry: line, and
  2. does not honor the server-provided reconnection delay, reconnecting immediately.

This is the MUST-level client-sse-retry-timing failure already noted as a known limitation in conformance-tests/VALIDATION_RESULTS.md.

Environment

  • java-sdk main (2.0.1-SNAPSHOT)
  • Java 17+
  • Transport: HttpClientStreamableHttpTransport (client), SSE / Streamable HTTP

Steps to reproduce
Run the official MCP conformance sse-retry client scenario:

./mvnw clean package -DskipTests -pl conformance-tests/client-jdk-http-client -am
npx -y @modelcontextprotocol/conformance client \
  --command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-2.0.1-SNAPSHOT.jar" \
  --scenario sse-retry

Observed:

Error: Invalid SSE response. Status code: 200 Line: retry: 500
[client-sse-retry-timing ] FAILURE  Client MUST respect the retry field (reconnected ~0ms instead of 500ms)
[client-sse-last-event-id] WARNING  Client SHOULD send Last-Event-ID on reconnection
OVERALL: FAILED

Expected behavior

  • The SSE parser parses/ignores retry: (and any unknown SSE field) without erroring the stream.
  • On reconnection after a drop, the client waits the server-specified retry interval before reconnecting.

Minimal reproducible example
Feeding the SSE lines id: e1 / retry: 500 / data: hello / (blank) to the SSE line subscriber currently throws McpTransportException instead of yielding a single event.

Proposed scope (two parts)

  1. Parser robustness (small, self-contained): parse retry: and ignore unknown fields in ResponseSubscribers. (Implemented locally with unit tests.)
  2. Reconnect timing: honor the parsed retry value before reconnecting in HttpClientStreamableHttpTransport / DefaultMcpTransportStream. This touches the McpTransportStream SPI, so I'd like to confirm the preferred approach before opening a PR.

The related Last-Event-ID SHOULD warning appears covered by #830, so I would keep it out of scope here.

Happy to open a PR for part 1 immediately and follow up on part 2 per maintainer guidance.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu với trình đăng ký dòng SSE trong ResponseSubscribers và các unit test của nó, tái hiện trường hợp retry tối thiểu: 500. Sau đó lần theo cách xử lý kết nối lại qua HttpClientStreamableHttpTransport và DefaultMcpTransportStream, bao gồm cả SPI McpTransportStream. Chạy kịch bản tuân thủ sse-retry; được xem là hoàn tất khi các trường retry không còn lỗi khi phân tích cú pháp và việc kết nối lại tuân theo độ trễ do máy chủ cung cấp.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
java
Lĩnh vực
api, networking
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
45/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.