Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Modern subscriptions: a subscriptions/listen refused with HTTP 403 is retried eight times in silence

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

Maintainer thường phản hồi trong vòng 1 ngày

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

Đánh giá

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

Hướng nghiên cứu

Start in core/mcp/inspectorClient.ts: the reconnect path runs from reconcileModernStreamStateAfterFailedRefresh (around lines 5762-5775) into scheduleModernReconnect (5806-5828) and onModernReconnectFailed (5835-5862), with the cap at MODERN_RECONNECT_MAX_ATTEMPTS (502-504). Compare with the never-acknowledged predicate in core/mcp/subscriptionAck.ts (49-52) and the tests in inspectorClient-subscriptions-era.test.ts. Done means a bare 403 on subscriptions/listen stops after one attempt with a visible refusal, while 5xx, 408, 429 and network errors still retry and 401 or insufficient_scope still goes through auth.

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

Mô tả

bug v2

Problem

On a modern-era server, when subscriptions/listen is refused with a bare HTTP 403 Forbidden (no WWW-Authenticate), the Inspector keeps re-sending the listen. It backs off exponentially up to its 8-attempt cap (roughly 60 s), then settles on a bare ended. The denial is never shown to the user.

That is the same silent eight-retry experience #2097 fixed for one failure shape, reached here through a different one.

This is a gap, not a regression.

  • #2097 / PR #2176 deliberately covered only one case: a listen the server closes gracefully before acknowledging it. Its predicate explicitly leaves "a transport failure, a timeout, or a pre-ack error response" retryable (core/mcp/subscriptionAck.ts:49-52).
  • That guarantee still holds: inspectorClient-subscriptions-era.test.ts passes 38/38 on the v2.11.0 tree.
  • The retry code is byte-identical between the #2176 merge (4d69dbf9) and v2/main.

It was found during the v2.11.0 milestone smoke (#2718) while driving #2515.

Observed

A logging proxy in front of a modern subscriptions test server answered every subscriptions/listen with a bare 403. Both versions sent the same 7 listens in about 6.6 s before the driver moved on:

Listen 2.11.0 2.10.1
1, on connect 0.00 s 0.00 s
2 +0.59 s +0.70 s
3 +1.05 s +1.16 s
4, user clicks Subscribe (attempt counter resets) (resets)
5 +0.56 s +0.68 s
6 +1.06 s +1.18 s
7 +2.07 s +2.16 s

The gaps are the reconnect backoff, min(500·2^n, 15000) ms. The only difference between versions is that 2.10.1 also ran OAuth discovery after every 403, which #2515 fixed in 2.11.0.

In the UI:

  • The Subscriptions section shows Subscriptions (0), because the URI was rolled back. The badge is gated on active, which the rollback clears, so the refusal appears nowhere.
  • The Protocol tab leaves each listen PENDING. That half is #2721.

Why it retries

  1. subscribeToResource → reconcileModernStreamStateAfterFailedRefresh (core/mcp/inspectorClient.ts:5762-5775) ends the stream only when modernNeverAcknowledged is set. Otherwise it calls scheduleModernReconnect() (:5806-5828).
  2. The filter stays non-empty after the rollback, because the resourcesListChanged opt-in remains (wantsModernStream, :5521). The later listens carry only that.
  3. onModernReconnectFailed (:5835-5862) counts up to MODERN_RECONNECT_MAX_ATTEMPTS = 8 (:502-504).
  4. The SDK (@modelcontextprotocol/client 2.3.1) does not retry the POST. It surfaces a bare 403 as SdkHttpError(ClientHttpNotImplemented, "Error POSTing to endpoint: Forbidden", {status: 403}). The error code is the same for every non-auth HTTP failure, so only data.status distinguishes them.

Expected

  • Don't retry a deterministic HTTP refusal. That covers a bare 403 (no WWW-Authenticate), 400, 404 and 405 from subscriptions/listen, classified by the HTTP status in the error data, not the SDK error code. A 401, or a 403 carrying insufficient_scope, keeps going through the auth flow.
  • Keep retrying transient failures: 5xx, 408 and 429 (consider honoring Retry-After), network errors and timeouts.
  • Say what happened. Give the refusal its own stream status, or reuse #2097's notice pattern, e.g. "The server refused subscriptions/listen (HTTP 403 Forbidden). Not retrying." Show it in the Subscriptions section even after the URI rollback.

Related: #2097 (the never-acknowledged case), #2721 (the Protocol tab leaves these requests PENDING), #2515 (a bare 403 no longer starts OAuth).

Ngôn ngữ chính
TypeScript
Star
11.1k
Fork
1.5k
Merge trung bình
4 giờ 32 phút
Pull request đã merge (30 ngày)
136

Chuẩn bị môi trường

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.

Issue khác của modelcontextprotocol/inspector

Tất cả issue của modelcontextprotocol/inspector

Issue tương tự

Thêm issue về TypeScript

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.