Skip to content

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

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

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions