Skip to content

Opt-in automation surface (list sessions, read buffers, send input) so agent/MCP tooling can drive the terminal #20403

Description

@steven-pribilinskiy

Description of the new feature

AI coding agents live in terminal panes now, and the tooling around them keeps needing the same three primitives from the terminal that hosts them: enumerate sessions/panes, read a pane's buffer, and send input to a specific pane. Every other major terminal ships some opt-in form of this today. Windows Terminal ships none of it, so it's become the one terminal where this whole class of tooling dead-ends.

Concrete case from my own tooling. I maintain a small CLI that bookmarks and renames AI coding sessions (Claude Code). A live rename means injecting a /rename <title> command into the exact pane hosting a given session, identified by the session id its statusline renders into the buffer. The flow today:

  • tmux: list-panes + capture-pane to find the pane whose buffer shows the session id, then send-keys
  • Tabby: the identical flow through its community MCP plugin, tabby-mcp-server: get_session_list, get_terminal_buffer, send_input
  • kitty: the remote control protocol (kitty @ ls / get-text / send-text), opt-in via allow_remote_control with an optional password
  • iTerm2: the Python API, off by default with explicit user consent
  • WezTerm: wezterm cli send-text and wezterm cli list
  • Windows Terminal: nothing. The tool prints "paste /rename <title> yourself"

There's nothing to build on here: wt.exe subcommands are structural only (new-tab, split-pane, focus-tab, move-focus, move-pane, swap-pane, focus-pane), there's no enumeration that carries content, no buffer read, no input path. The only read surface is UIA, which is an accessibility contract, not an automation one.

The MCP angle is what makes the gap so visible in 2026. Community MCP servers already exist for iTerm2 (ferrislucas/iterm-mcp), tmux (nickgnd/tmux-mcp) and Tabby (linked above), so any MCP-capable agent can drive those terminals out of the box. Nobody can build the equivalent for Windows Terminal because there's no control surface underneath to wrap.

I know wt send-input was rejected a few months ago (#9368, PR #20106) over the injection risk, and that rejection makes sense for what it was: an unauthenticated CLI verb any process on the box could invoke. This proposal is a different shape. It's the opt-in, authenticated, consent-gated model that kitty and iTerm2 already ship. And half the value is the read side (session enumeration + buffer), which #9368 never covered and which carries a much smaller risk profile than injection.

Proposed technical implementation details

  • Off by default. No endpoint exists unless the user turns it on
  • Consent can't live in settings.json alone. @zadjii-msft's concern in Add support for send-input subcommand #9368 was that malicious.exe could just edit the settings file, agreed. So: a UI-only toggle persisted outside settings.json, plus a first-connection consent prompt that names the connecting process (the iTerm2 per-script consent model, it works)
  • Transport: an ACL'd named pipe (caller identity comes for free) or localhost HTTP with a per-boot token
  • Hard elevation boundary: elevated windows and tabs are never serviceable, not even by opt-in. That keeps the mixed-elevation concern that killed Add support for send-input subcommand #9368 out of scope entirely
  • Minimal v1 surface: list_sessions (window/tab/pane tree with ids and titles), read_buffer(pane, lastNLines), send_input(pane, text). Input could sit behind a second, separate opt-in so read-only automation never carries injection risk
  • A visible indicator while an automation client is connected (tab decoration or statusline badge), so it's never silent
  • MCP itself doesn't need to be first-party. Ship the control surface and the community will build the MCP server on top, exactly the way it happened for iTerm2, tmux and Tabby

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs-Tag-FixDoesn't match tag requirementsNeeds-TriageIt's a new issue that the core contributor team needs to triage at the next triage meeting

    Type

    No type

    Fields

    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