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.
Connect
Section titled “Connect”- 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.
Browse
Section titled “Browse”After connecting, the main screen has four tabs:
| Tab | Source | Action |
|---|---|---|
| Tools | tools/list | Enter opens the input form |
| Resources | resources/list | Enter reads and renders content |
| Prompts | prompts/list | Enter retrieves the prompt template |
| Events | server notifications | live 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.
Execute a tool
Section titled “Execute a tool”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.
Server-initiated screens
Section titled “Server-initiated screens”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/createrequest renders as a form built from the requested schema; you fill it in, or decline/cancel. - Roots — press
Rto open the roots editor. Changes propagate to the server via aroots/list_changednotification. See Client features.
Useful keys
Section titled “Useful keys”| Key | Action |
|---|---|
c | On the tool screen: show and copy the equivalent CLI command |
Ctrl+C | Copy current result |
r | Refresh the current tab |
R | Open the roots editor |
d | Disconnect and return to the connection screen |
e | Show schema-error details for the selected tool |
Ctrl+E | Export session recording (.json trace + .sh CLI replay script) |
Ctrl+D / Ctrl+L / F12 | Open the debug screen (main and tool screens) |
b / Alt+← | Back |
q / Esc / Ctrl+C | Quit |
See the keyboard reference for the full list.