Skip to content

Custom Headers hint misstates OAuth precedence; key/value rows have indistinguishable accessible names #2040

Closed

Description

@cliffhall

Two defects in the Server Settings key/value editors, found while reading ServerSettingsForm.

1. The Custom Headers hint is factually backwards

The hint reads:

Headers sent with every HTTP request to this server. If OAuth is configured below, the Authorization header is owned by the OAuth flow and any value set here is ignored.

That is the opposite of what happens. In @modelcontextprotocol/client@2.x, both SSEClientTransport._commonHeaders() and the streamable-HTTP equivalent do:

if (token) headers["Authorization"] = `Bearer ${token}`;
...
const extraHeaders = normalizeHeaders(this._requestInit?.headers);
return new Headers({ ...headers, ...extraHeaders });

The custom headers are spread after the OAuth bearer, so a custom Authorization value overrides the OAuth access token rather than being ignored.

Why it matters: a user who set a bearer by hand before configuring OAuth is told, by the UI, that the stale value is harmless. It is not — it silently suppresses the token the OAuth flow just obtained, and the resulting 401 has no visible cause.

Expected: the hint tells the user a custom Authorization wins, so they know to remove it once OAuth is configured.

2. Key/value rows are indistinguishable to a screen reader

KeyValueRows renders Custom Headers, Request Metadata and Environment Variables. Nothing associates a control with its row:

  • The key and value inputs carry only a placeholder ("Key" / "Value"), which is not a label.
  • Every remove button announces as "X".
  • Every clear button announces as "Clear".

So a settings form with three headers and two metadata entries presents ten identically-named text boxes, five identical "X" buttons and up to ten identical "Clear" buttons, with no way to tell which row any of them belongs to.

Expected: each control names the entity and the row it belongs to. The row number has to be part of it, not just a fallback for a blank key — two rows can carry the same key while being edited, and a server can persist duplicate metadata keys.

Scope

Both are in clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.tsx. No behavior change beyond the copy and the accessible names.

Activity

  1. added this to the v2.3.0 milestone on Aug 17, 2026
  2. added
    bugSomething isn't working
    v2Issues and PRs for v2
    on Aug 17, 2026
  3. cliffhall commented on Aug 17, 2026

    @cliffhall
    MemberAuthor

    Triage: Priority Medium (total 7)

    • Severity 3 — a real defect in each half: the hint states the opposite of what the transports do (a user can break their own auth while the UI says it is safe), and the rows are unusable with a screen reader. Neither blocks a core workflow for a sighted user not using OAuth.
    • Urgency 3 — wanted this milestone; the fix is already written.
    • Bonuses: +1 bug label, +1 milestone (v2.3.0 — created through the documented flow, so approved on filing).

    Board: #28, Status In Review (PR #2038).

  4. self-assigned this
    on Aug 17, 2026
  5. added a commit that references this issue on Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingv2Issues and PRs for v2

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions