Skip to content

Server settings form: typing is laggy; Add Header/Metadata shows no row until PUT round-trips #1361

@cliffhall

Description

@cliffhall

Summary

ServerSettingsModal is a fully controlled component whose settings prop comes from useServers() (the in-memory mirror of ~/.mcp-inspector/mcp.json). On every change, the modal calls onSettingsChange up to App.tsx, which stashes the new value in a useRef and schedules a 300ms-debounced PUT. Because the ref doesn't trigger a re-render, the form's displayed value can only update after the debounced PUT round-trips and useServers refetches.

Repro

  1. Open any server's settings modal.
  2. Click "Add Header" or "Add Metadata" — no input row appears until ~300-500ms later (after debounce + PUT + refetch).
  3. Type in the OAuth Client ID / Client Secret / Scopes fields — characters echo with the same delay; rapid typing means nothing shows until you stop typing for 300ms.

Root cause

clients/web/src/App.tsx:784-849:

const pendingSettingsRef = useRef<{...}>(null);
const onSettingsChange = useCallback((next) => {
  pendingSettingsRef.current = { id, settings: next };  // ← no re-render
  if (timer) clearTimeout(timer);
  timer = setTimeout(flushPendingSettings, 300);
});

The form is "controlled" but the parent never updates state with the new value, so the input's value prop stays stale.

Why it surfaced now

The bug was introduced in #1353 (when the debounced-flush pattern landed). It became user-visible after #1356 because per-keystroke PUTs now also hit the OS keychain, making the round-trip latency more noticeable.

Fix

Replace pendingSettingsRef with useState<InspectorServerSettings | null> so every change re-renders the modal immediately. Keep the 300ms debounce for the PUT side. Initialize the draft from the server-list entry only when the modal opens to a new target (not on every prop change) so background refreshes don't clobber in-progress edits.

Acceptance criteria

  • Clicking "Add Header" / "Add Metadata" shows a new input row instantly.
  • Typing in any field echoes characters with no perceptible lag.
  • Edits still persist via the debounced PUT (no extra round-trips per keystroke).
  • Closing the modal flushes pending edits.

Metadata

Metadata

Assignees

Labels

v2Issues and PRs for v2

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions