Skip to content

History: make Pin and Replay work on HistoryEntry items #1438

@cliffhall

Description

@cliffhall

Background

The History screen lists past MCP traffic as HistoryEntry cards. Each card already renders Replay and Pin / Unpin buttons (clients/web/src/components/groups/HistoryEntry/HistoryEntry.tsx:131-139), but neither does anything yet — the handlers are stubbed all the way up the tree.

Current state

The callbacks bubble: HistoryEntryHistoryListPanelHistoryScreen (onReplay / onTogglePin, pinnedIds) → InspectorView (onReplayHistory / onTogglePinHistory, pinnedHistoryIds) → App.

At the top:

  • App.tsx:1997-1998 wires both onReplayHistory and onTogglePinHistory to todoNoop.
  • App never passes pinnedHistoryIds, so InspectorView.tsx:618 falls back to new Set() — pinned state is always empty and the Pin button has no visible effect.

So clicking Replay or Pin today is a no-op.

Proposal

Implement both handlers in App.tsx and thread the pinned set down.

Pin / Unpin

Replay

  • onReplayHistory(id) looks up the MessageEntry by id and re-issues its original request. MessageEntry.message is the original JSON-RPC request (core/mcp/types.ts:171), so dispatch by method:
    • tools/call → resolve the Tool by params.name from the tools list, then inspectorClient.callTool(tool, params.arguments).
    • prompts/getgetPrompt(params.name, params.arguments).
    • resources/readreadResource(params.uri).
    • Define behavior for other request methods (subscribe, completion, logging/setLevel, …) — replay or ignore with a notice.
  • Replay responses are surfaced history-locally. Rather than routing the user to the originating screen (Tools/Prompts/Resources), a replay re-issues the request and shows the fresh result inline on the History screen — i.e. the replayed call produces a new MessageEntry in the history list (and/or updates the originating entry's expanded result view), so the user stays in History and can compare runs in place. The replay still goes through InspectorClient, so the normal traffic is logged as usual.

Open questions

  • Pinned-entry treatment: protected from Clear All, sorted to the top, and/or visually marked beyond the Unpin label?
  • Should pinned ids persist only for the session, or across reconnects/restarts (storage)?
  • Replay scope: just the three "actionable" request types above, or every request method?
  • History-local surfacing detail: does a replay append a brand-new entry, update the existing entry in place, or both?

Acceptance criteria

  • Clicking Pin marks the entry (isPinned true) and Unpin clears it; the state is reflected immediately and persists across tab navigation within a session.
  • pinnedHistoryIds is supplied by App (no longer defaulting to an empty set in InspectorView).
  • Clicking Replay on a tools/call / prompts/get / resources/read entry re-issues the original request with its recorded params.
  • The replay's response is surfaced history-locally (inline on the History screen) rather than navigating to the originating screen.
  • Replay on an unsupported method is handled gracefully (no crash; clear no-op or notice).
  • Tests cover toggle-pin state and replay dispatch for each supported method, including history-local surfacing of the response; the todoNoop wiring is removed for these two handlers.

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