Skip to content

TUI Mode

The TUI is the default when you run mcp-tui without a subcommand. It opens to a connection screen with three tabs: Saved, Discovery, and Manual.

Verify an MCP tool in seconds. Connect to a server, pick a tool, fill the form mcp-tui builds from its input schema, run it, and copy the same call as a CLI command.
  • Saved — last successful connections, ready to re-launch.
  • Discovery — auto-finds Claude Desktop, VS Code MCP, and native MCP-TUI configs on disk.
  • Manual — type a --cmd-style command directly, or fill in transport/URL.

Tab cycles tabs; ↑/↓ selects within a list; Enter connects.

Answer elicitation and sampling requests. When a tool needs input mid-call, mcp-tui shows the server's form or its sampling request, interactively in the TUI or from stub flags in the CLI.

After connecting, the main screen has four tabs:

TabSourceAction
Toolstools/listEnter opens the input form
Resourcesresources/listEnter reads and renders content
Promptsprompts/listEnter retrieves the prompt template
Eventsserver notificationslive feed of notifications; Enter opens a detail pane

Tab / Shift+Tab (or ←/→) moves between tabs. ↑/↓ (or j/k) selects within a tab. Number keys 1–9 quick-select an item.

Markers after a tool’s name show its annotations: [D] destructive, [R] read-only, [I] idempotent, [O] open-world. A legend under the list explains them, and the detail pane spells out the selected tool’s (Annotations: read-only, idempotent).

The Events tab streams every server-to-client notification — logging, progress, list-changed, resource updates, cancellations — as it arrives.

On protocol 2026-07-28 servers attach a cache lifetime to every list (ttlMs, cacheScope; SEP-2549), and the SDK answers repeat lists from its own cache until it expires. The rule under the tabs shows how the current tab’s list was served, e.g. cached · ttl 30s · private or fetched · ttl 30s · public; the debug log records the same per list. r cannot bypass that cache: only a list_changed notification from the server or reconnecting forces a fresh fetch.

The input form is generated from the tool’s JSON Schema. Required fields are marked. Each label shows the field’s type, or an enum’s allowed values in its place, then a number’s range and any default: status [open | pending | closed], limit [integer 1–50, default 10]. Type coercion runs automatically — numbers, booleans, and JSON literals are parsed from text. A field of several types (integer|string) reads the type from what you type and shows it (integer|string → integer). Ctrl+N sends null from a nullable field. Ctrl+E on an object field with declared properties opens it as an indented sub-form; an optional object whose fields are all empty is left out. On an array of such objects it opens a list of elements, each an object sub-form: Ctrl+A adds an element and Ctrl+X removes the one under the cursor. Before a call the arguments are checked against the whole schema, including rules no field shows (if/then/else, not, patternProperties), and a failing call is not sent; the error names the argument. Ctrl+O sends such calls anyway, showing the violation, to see how the server rejects them. A schema the form cannot hold opens a raw JSON editor with the reason.

The fields come first, the tool’s description after the buttons. A form taller than the screen shows the fields around the cursor, with ▲ 2 more fields above / ▼ 3 more fields below where it leaves some out, so the title and buttons stay on screen. On a terminal 120 columns or wider the result panel sits right of the form and runs its full height; narrower, it fills the space below the form. It is drawn before the first call, and wraps long lines to its width. Its heading shows which lines are on screen and points to more with PgUp ▲ / PgDn ▼; PgUp/PgDn, Shift+↑/↓ and Ctrl+Home/Ctrl+End scroll it wherever the cursor is, and the help line names the keys that work from there. Several content blocks each get a heading; images and audio are shown by MIME type and size rather than their bytes, resource links by URI, and structuredContent follows when the text blocks do not already repeat it. JSON is coloured on screen; Ctrl+C copies it plain. v picks one field of the result (from structuredContent when present) to copy.

Every copy goes two ways at once. It is sent to the terminal as an OSC 52 escape, which Windows Terminal, iTerm2, kitty, WezTerm and tmux (with set-clipboard on) put on the clipboard, and to the system clipboard through wl-copy, xclip or xsel (pbcopy on macOS, the Windows clipboard on Windows). The system copy runs in the background and is given up after 2 seconds, so a clipboard program that never returns, as wl-copy and xclip can under WSLg or over SSH, does not stop the TUI. The status line then says which copy took: Copied result to clipboard, or Sent result to the terminal clipboard (OSC 52); system clipboard unavailable: and the reason. Ctrl+V in a field pastes from the system clipboard under the same limit.

Some MCP servers call back into the client. The TUI renders each request as a dedicated interactive screen:

  • Sampling — when a server issues sampling/createMessage, a screen shows the requested messages and lets you compose or approve a reply.
  • Elicitation — an elicitation/create request renders as a form built from the requested schema; you fill it in, or decline/cancel.
  • Roots — press R to open the roots editor. Changes propagate to the server via a roots/list_changed notification. See Client features.
KeyAction
cOn the tool screen: show and copy the equivalent CLI command
Ctrl+CCopy current result
rRefresh the current tab
ROpen the roots editor
dDisconnect and return to the connection screen
eShow schema-error details for the selected tool
Ctrl+EExport session recording (.json trace + .sh CLI replay script)
Ctrl+D / Ctrl+L / F12Open the debug screen (main and tool screens)
b / Alt+←Back
q / Esc / Ctrl+CQuit

See the keyboard reference for the full list.