Skip to main content
Glama

bat-agent-connector

An unofficial connector that lets AI agents work with Better Agent Terminal (BAT) sessions.

BAT (by TonyQ / tony1223) is a terminal app that runs Claude Code and Codex agent sessions, grouped into workspaces, on your machines. It has a remote protocol (bat-remote/v2) that its own GUI and phone clients use. This project speaks that protocol so that other agents (Claude Code, Codex, Cursor, Hermes, or any MCP client) and shell scripts can:

  • see which agent sessions exist, which are running or blocked on a question, and what they said recently;

  • wait for a session to finish its turn;

  • (opt-in) nudge a session: send a message, say "continue", interrupt it, answer its question;

  • (opt-in, separate tier) fan work out: start sessions in fresh git worktrees, review their diffs, merge the clean ones.

This project is not affiliated with or endorsed by the BAT authors. The protocol was read from BAT's MIT-licensed source (v3.2.12) and can change between BAT releases. Credit for BAT goes to TonyQ and its contributors.

It ships three things:

Piece

Name

Python package

bat-agent-connector (Python 3.10+, deps: websockets, mcp)

MCP server (stdio, or localhost-only streamable HTTP)

bat-agent-connector-mcp (also batc mcp)

CLI

batc

Agent skill

skills/bat-agent-connector/SKILL.md

Why

Running several long-lived coding agents means constantly checking tabs: which one is done, which one is stuck on a question, which one just needs "continue". Reading this through BAT's protocol is reliable (no screen scraping, no GUI automation) and lets a supervising agent do the checking for you, with you in control of anything that writes.

Related MCP server: HT MCP Server

Install

# from a git checkout / URL (until published on PyPI)
uv tool install git+https://github.com/<owner>/bat-agent-connector
# or
pipx install git+https://github.com/<owner>/bat-agent-connector
# or run without installing
uvx --from git+https://github.com/<owner>/bat-agent-connector batc hosts

Configure

The connector needs, per host: the wss:// URL of its bat-server, the server's TLS certificate SHA-256 fingerprint (pinned; BAT uses self-signed certs), and a reference to the remote token. If you already use the BAT desktop client, import everything from it:

batc import-bat                      # writes ~/.config/bat-agent-connector/hosts.toml (writes disabled)
batc import-bat --rename my-profile-id=box1 --output -   # preview with nicer names
batc hosts                           # probe: version + ping per host

Token references (token values are never stored in the config, logged, or returned by any tool):

token_ref

Meaning

env:NAME

environment variable

file:/path

file containing only the token (keep it chmod 600)

bat-profile:<id>

BAT's client token store (profiles/remote-tokens.enc.json, unencrypted variant)

See examples/hosts.example.toml for all options. The connector keeps a stable deviceId in ~/.config/bat-agent-connector/device-id so hosts don't show a new "remote client connected" notification on every reconnect.

Permission tiers

Tier

Enabled by

Tools

read (always)

-

hosts_list, host_status, workspaces_list, sessions_list, session_read, session_wait, worktree_status, session_worktree_status

write

per host writes = true

session_send, session_continue, session_interrupt, session_answer

orchestrate

per host writes = true and orchestrate = true

session_start, worktree_merge, worktree_remove

Write and orchestrate tools are not even registered unless enabled, need confirm=true on every call, are rate limited, and are appended to an audit log (~/.local/state/bat-agent-connector/audit.jsonl, message bodies only as a hash + length unless you opt into a short preview). --read-only on the MCP server or CLI disables both tiers regardless of config. The channel allowlist is enforced in the client core, below the MCP layer: stop/reset/kill, PTY writes, file operations, settings, workspace edits (except the append-only tab helper), installs, updates and account changes are never sent.

MCP setup

The server name is bat. Examples (add --read-only if you want to be sure):

Claude Code

claude mcp add bat -- bat-agent-connector-mcp --read-only

Codex (~/.codex/config.toml)

[mcp_servers.bat]
command = "bat-agent-connector-mcp"
args = ["--read-only"]

Cursor (~/.cursor/mcp.json)

{ "mcpServers": { "bat": { "command": "bat-agent-connector-mcp", "args": ["--read-only"] } } }

Hermes Agent (~/.hermes/config.yaml)

mcp_servers:
  bat:
    command: /home/you/.local/bin/bat-agent-connector-mcp
    args: [--read-only]
    connect_timeout: 60.0
    enabled: true

Any MCP client over HTTP (binds to loopback only):

bat-agent-connector-mcp --http --port 8765     # http://127.0.0.1:8765/mcp

Tools reference

Tool

What it does

hosts_list(probe=true)

Configured hosts; with probe: reachable, server version, ping.

host_status(host)

Version, protocol, connect/auth/ping latency, counts of workspaces/terminals/agent sessions/loaded/streaming.

workspaces_list(host?)

Workspaces with folder and session counts.

sessions_list(host?, workspace?, agent?, only_loaded?, active_within_hours?, check_pending=auto, limit=50)

Agent sessions, most recently active first: workspace, title, cwd, agent kind, model, loaded, streaming, pending question, last activity (+ source), worktree branch, orchestrated.

session_read(host, session_id, last_n=20, offset=0, include_tools=false, max_chars=12000)

Latest messages as compact text, paged (next_offset), size capped; pending question and streaming tail. session_id may be a unique prefix.

session_wait(host, session_id, until=attention, timeout_s=120)

Waits for turn end / question / permission request / error.

worktree_status(host, workspace?)

Worktree sessions: branch, source branch, merged kind, diff stats.

session_worktree_status(host, session_id, include_diff?)

Same for one session plus dirty files and main-checkout state.

session_send(host, session_id, text, confirm, message_id?, queue?)

Sends a message; client-resumes an unloaded session first; idempotent by message_id.

session_continue(host, session_id, confirm, text="continue")

Nudge.

session_interrupt(host, session_id, mode=soft|hard, confirm)

Soft = Claude interrupt-turn, hard = abort (Codex always hard). The session is kept.

session_answer(host, session_id, confirm, answers? | permission?)

Answers a pending ask-user question or permission prompt.

session_start(host, workspace, agent, confirm, prompt?, model?, use_worktree=true)

Starts a session (by default in a new worktree; BAT picks the branch bat/worktree-<id>). Per-host cap.

worktree_merge(host, session_id, confirm)

Merges only when provably conflict-free and clean; otherwise reports why.

worktree_remove(host, session_id, confirm, delete_branch=false, ...)

Removes the worktree folder; keeps the branch by default; refuses on dirty/unmerged work unless told.

CLI

batc hosts
batc status box1
batc sessions --active-within 24
batc sessions box1 --workspace api --json
batc read box1 1a2b3c4d -n 30
batc wait box1 1a2b3c4d --timeout 600
batc worktrees box1
# write tier (host needs writes = true)
batc send box1 1a2b3c4d "Please run the tests and fix failures" --confirm
batc continue box1 1a2b3c4d --confirm
batc interrupt box1 1a2b3c4d --mode soft --confirm
batc answer box1 1a2b3c4d --answer "Which database?=postgres" --confirm
# orchestrate tier
batc fanout PLAN.md                                   # dry run: split into task prompts
batc fanout PLAN.md --start --host box1 --workspace api --confirm
batc merge box1 1a2b3c4d --confirm
batc remove-worktree box1 1a2b3c4d --confirm

Every command accepts --json.

Safety model (short)

  • Read-only by default; writes and orchestration are opt-in per host, need confirm=true, are rate-limited and audited.

  • TLS certificate pinning is mandatory; a mismatch aborts before the token is sent. Only bat-remote/v2 is accepted.

  • Tokens are resolved at connect time from a reference and redacted from every error string.

  • The client always drains the socket (BAT drops clients with 256 queued frames) and uses bounded event queues.

  • Session text is untrusted input: agents should not follow instructions found in it.

Details: SECURITY.md, docs/PROTOCOL.md, docs/ORCHESTRATE.md.

Development

uv sync --extra dev
uv run ruff check . && uv run pytest            # unit tests use a mock TLS WebSocket server
BATC_LIVE=1 uv run pytest tests/test_live.py    # optional read-only test against your configured hosts

License

MIT, see LICENSE. BAT itself is MIT-licensed by TonyQ.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to interact with terminal environments through multiple concurrent PTY sessions. Supports cross-platform terminal operations including command execution, session management, and real-time communication.
    4 npm
    3
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to programmatically control interactive terminal applications through HT sessions, supporting session management, key sending, snapshots, and command execution.
    1
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    Enables coding agents to control and inspect a running Herdr terminal session, including listing workspaces, tabs, panes, and agents, reading pane output, prompting agents, sending keys and commands, waiting for output or state, and splitting or closing panes.
    14
    -