Skip to content

Agent Integration

maiTerm integrates deeply with coding agents — Claude Code and OpenAI Codex — through a single runtime-neutral pipeline. Both connect to the same MCP/IDE server, drive the same live agent-state indicators, auto-resume after a restart, pair through Agent Bridge, and send notifications — all without a manual setup step. maiTerm detects which agent connected from its own identity, so the right integration just lights up the moment you run claude or codex.

Supported agents

AgentOn by defaultIntegration
Claude CodeYesMCP/IDE tools, hooks + the maiTerm mod, auto-resume, Agent Bridge (fork or connect), SSH bridge, /maiterm skill + status line
CodexYesMCP/IDE tools, lifecycle hooks, auto-resume, Agent Bridge (connect, or fork — new), SSH bridge, maiterm prompt

Both agents get the same core treatment: live state in the sidebar and footer, tab activity indicators, auto-resume after a crash or relaunch, and notifications — all driven through the same hooks pipeline. Integration is on by default for each; it only takes effect once you actually run that agent.

How It Works

Claude Code / Codex CLI ←→ Streamable HTTP ←→ axum server (Rust) ←→ Tauri events ←→ Frontend (Svelte)

There’s one MCP/IDE server, shared by every agent. It starts automatically when maiTerm launches and listens on a single port with a single auth token. What differs per agent is only the on-disk config a CLI reads to discover it:

  • Claude Code — a lock file in ~/.claude/ide/, an mcpServers entry in ~/.claude.json, lifecycle hooks in ~/.claude/settings.json, and a small Claude Code mod each tab’s shell points Claude at.
  • Codex — an MCP block in ~/.codex/config.toml, lifecycle hooks in ~/.codex/hooks.json, and a maiterm prompt in ~/.codex/prompts/.

When an agent connects, maiTerm identifies the runtime from the client’s own handshake — so a Codex connection never binds to a Claude tab. And no agent needs a manual registration step: a tab names itself on the wire, and the session links itself the moment the agent process starts. See Acting as the right tab.

The same server can also hand your agents other remote MCP servers, under one sign-in maiTerm holds for all of them — see MCP Servers.

Choosing your agents

Agent settings live in one runtime-neutral AI Agents section in Preferences, with a subsection per agent. Toggling an agent on or off installs or removes its integration immediately — no restart required.

Claude Code

  • Enable IDE Integration — the MCP/IDE server and tools
  • Enable Hooks Integration — lifecycle hooks for real-time state, and the maiTerm mod in each tab
  • Enable Auto-Resume via Hooks — capture session IDs and reconnect on restore
  • Enable IDE Integration over SSH — expose IDE tools to remote Claude Code via reverse tunnel

Codex

  • Enable Codex IDE integration — the MCP/IDE server and tools for Codex
  • Codex lifecycle hooks — the 9 Codex hook events that drive state and auto-resume. Turning this off removes the hooks rather than just leaving them unrefreshed, so Codex stops reporting to maiTerm
  • Codex auto-resume — capture session IDs and reconnect on restore
  • Codex MCP bridge over SSH — expose IDE tools to remote Codex
  • Skip the one-time Codex hook-trust prompt (advanced) — the only agent toggle off by default; Codex’s one-time hook-trust approval is deliberately kept unless you opt out

A separate Deshittification section switches off the vendor-serving parts of an agent — telemetry, feedback nags, Remote Control, and the Co-Authored-By trailer in your commits — and stops Claude Code asking permission for its own memory writes. Those rules edit the agent’s own config rather than maiTerm’s, so they hold in every terminal. See Deshittification.

SSH MCP Bridge

When you’re SSH’d into a remote server, maiTerm bridges the MCP connection so an agent running remotely still has access to all IDE tools. A reverse SSH tunnel is set up automatically in the background — no manual port forwarding needed. For each enabled agent maiTerm writes the matching remote config (Claude Code’s lock file and ~/.claude.json, or Codex’s ~/.codex/config.toml and hooks.json), gracefully no-op’ing on a host that doesn’t have that CLI installed. The bridge status is shown in the tab bar with a bolt icon (green = connected).

If a tunnel goes down — a network blip, or your Mac putting its displays to sleep — maiTerm rebuilds it on its own, backing off between attempts and staggering the tabs that share a host so they rejoin one connection rather than all re-authenticating at once. A tab whose shell has since ssh’d somewhere else follows the shell instead of being reconnected to the host it left.

A rebuilt tunnel comes back on the port it had. An agent learns maiTerm’s port once, when it starts, and keeps it for life — so a tunnel that reconnected on a different number would leave every agent already running on that host talking to a dead port, with each of its tools answering “Unable to connect”. While tabs are riding on it, a reconnect keeps asking for its own port for several seconds (the remote end can take that long to let go of the old connection) and only moves to another if something else genuinely holds it. If it ever does have to move, agents started before the move need restarting to reach maiTerm again.

Two computers, one remote account

The remote configuration files live in the account’s home directory, one copy shared by every session on that host — so if they named a particular maiTerm’s connection, whichever machine connected last would own the account and every agent belonging to the other one would silently lose its tools and its hooks. A laptop and a desktop are enough to hit that; so are your own dev and release builds.

Those files now name no maiTerm at all. Each agent works out which one to talk to from its own terminal session’s environment, which maiTerm sets per tab when it opens the connection — so every machine writes identical bytes and there is nothing left to fight over. maiTerm also asks the remote host for a fixed port of its own rather than taking whatever it’s given, and a tab that was told the old number is corrected as soon as its tunnel is up.

It now keeps that port, too. Tunnels are closed when maiTerm exits, and anything an earlier run left behind is cleared out at startup instead of squatting the port and pushing the next launch onto a different number. If you have more than one copy of maiTerm running — a dev build beside a release one — the cleanup only ever removes connections nobody owns, never the live ones belonging to the other copy.

One consequence worth knowing: a remote shell that maiTerm didn’t start itself — one you opened inside tmux, or after su, or by typing ssh in another window — has none of that environment and can’t reach maiTerm at all. (Before, it would reach some maiTerm, often the wrong one.) The remedy depends on how many tabs you have open to that host:

  • One tab on the host — maiTerm leaves the values in ~/.aiterm, so source ~/.aiterm in the stray shell is enough.
  • Several tabs on the same host — that file is deliberately removed rather than written. Every tab on a host shares one tunnel, so a shell with no environment of its own can’t be told apart from its siblings, and a fallback file would quietly hand it another tab’s identity. Start the shell from a maiTerm tab instead.

claude mcp list names what’s missing if you’re not sure which case you’re in.

Available Tools

Both agents connect to the same MCP server and can call the same tools.

Editor Tools

ToolDescription
getOpenEditorsList open editor tabs (path, language, dirty state)
getWorkspaceFoldersWorkspace root paths
getDiagnosticsLanguage diagnostics for a file
checkDocumentDirtyCheck if file has unsaved changes
saveDocumentSave file to disk
getCurrentSelectionActive editor selection + cursor
getLatestSelectionMost recent selection in any tab
openFileOpen file in editor tab (with optional line/text selection)
openDiffShow side-by-side diff for review (blocking — accept/reject)
showDiffView a git diff read-only (non-blocking)
closeAllDiffTabsClose all pending diff tabs

Workspace & Tab Navigation

ToolDescription
listWorkspacesList all workspaces with panes, tabs (IDs, display names, types, active state, notes)
switchTabNavigate to a tab by ID (auto-resolves workspace and pane)
getTabContextGet recent terminal output or editor content for tab discovery

Notes Management

ToolDescription
getTabNotesRead notes for a tab (defaults to active tab)
setTabNotesWrite or clear notes for a tab
listWorkspaceNotesList workspace-level notes (IDs, previews, timestamps)
readWorkspaceNoteRead full content of a workspace note
writeWorkspaceNoteCreate or update a workspace note
deleteWorkspaceNoteDelete a workspace note
moveNoteMove notes between tab and workspace (with conflict detection)
openNotesPanelOpen, close, or toggle the notes panel
setNotesScopeSwitch notes panel between tab and workspace views

Tab State & Preferences

ToolDescription
getActiveTabGet the currently active workspace, pane, and tab info
setTriggerVariableSet or clear a trigger variable for a tab
getTriggerVariablesRead all trigger variables for a tab
setAutoResumeEnable/disable auto-resume with optional command/cwd/ssh overrides
getAutoResumeGet current auto-resume configuration for a tab
getPreferencesRead maiTerm preferences
setPreferenceUpdate an maiTerm preference
findNotesSearch all tabs and workspaces for notes in one call
getDiagnosticsApp diagnostics — version, PTY stats, memory, WebGL state
readLogsTail the log file with level filter and search
getClaudeSessionsList all active agent sessions across tabs with state, tool, and model info
listWindowsList all maiTerm windows with workspace summaries
createBackupCreate a state backup on demand
sendNotificationSend a toast or OS notification from your agent — from a muted tab it reports that nothing was shown
setMutedMute or unmute notifications for a tab or a whole workspace — only when you ask it to

Agent Bridge

ToolDescription
sendToBridgedAgentSend a message to the peer agent this tab is bridged with — async, the reply arrives as a new prompt turn
getBridgedAgentReport whether this tab is bridged and, if so, the partner’s label and working directory

An agent can also ask for a bridge itself, or for its bridge to close, with bridgeWith and disconnectBridge — requests you approve, like a mesh change; see Organising tabs, meshes and maiTerm. See Agent Bridge for the full feature.

Tasks

ToolDescription
listTasksList the project’s tasks, grouped by workstream — this tab’s or the whole workspace, narrowed to what’s ready to start, ranked and bounded
createTasksCreate a batch of tasks, optionally into a named workstream
updateTasksUpdate a batch — status, title, detail, workstream, assignee, dependencies, and an appended note
deleteTasksRemove rows or whole workstreams for good — never another tab’s unfinished work, nor a task something unfinished still waits on

Four batched tools over one list you and your agent both edit. Work an agent filed by mistake is normally retracted to Dropped, which you can reverse; deleting is for rows that should never have existed, and it is guarded. See Tasks for the full feature; it can be switched off entirely in Preferences → AI Agents → Task tracking, which removes both the tools and the instruction that goes with them.

Workspace stack

ToolDescription
listStackWhat this project runs and what state each service is in — status, uptime, port or URL and where that address came from, command, last exit code
getServiceOutputA service’s recent output — its log
startService / stopService / restartServiceStart, stop or restart one service
startStack / stopStackStart every auto-start service, or stop everything running
waitForServiceBlock until a service announces it’s serving, and show its last lines if it doesn’t
updateServiceCorrect an address maiTerm read wrong or supply one it couldn’t read, leave a one-line note, or edit the definition
createServiceRegister a service — or, called with no arguments, return what this directory already declares
removeServiceRetract a service definition (never one a human created, never one that’s running)

Every agent session is also told what the workspace runs and what’s up right now — including where each service is serving, because maiTerm reads that address out of the service’s own output rather than waiting for an agent to notice it — so a session stops starting a dev server that’s already up, and knows the URL to call without hunting for it. See Workspace Stack; the tools and the briefing are gated on Preferences → AI Agents → Workspace stack.

Send files to your phone

ToolDescription
sendFilesToPhoneSend files from this machine to your paired maiLink phone

Files land in that tab’s chat on the phone and in a cross-chat Files list. Any file type, up to 1 GB each; each path succeeds or fails on its own, so one bad path doesn’t sink the batch. An agent on an SSH tab passes its own remote paths and maiTerm fetches them back over the bridge tunnel. The bytes are copied at the moment of sending, so rewriting the file afterwards can’t retroactively change what you were already given.

Follow-ups

ToolDescription
createFollowUpSchedule a prompt back into this tab — at a time, when a stack service comes up or stops, when a task ends, or when a watch script passes
listFollowUpsThis tab’s pending follow-ups
cancelFollowUpCancel one of this tab’s follow-ups

An agent’s way to pick work back up later without you having to remember it — delivered when it’s due, even mid-turn, into its own tab only. A watch script runs only after you approve it. Available while Overlord and Preferences → Overlord → Enable follow-ups are both on. See Follow-ups.

Organising tabs, meshes and maiTerm

ToolWhat happens
getMeshLayoutEvery window’s workspaces as meshes see them — which are Mesh Workspaces, which are linked, and the agent tabs in each. Read-only
moveTabMove a tab into another workspace, in this window or another — at once, unless it changes the tab’s mesh
moveWorkspaceMove a whole workspace to another window — at once, unless it’s a mesh linked with another in its window, which the move would break
setMeshMake a workspace a Mesh Workspace, or stop it being one — asks you
linkMeshes / unlinkMeshLink two mesh workspaces into one mesh, or take one back out — asks you
createTabOpen a new Claude Code, Codex or Gemini tab in a workspace, in a local folder or in a folder on an SSH host, optionally named — asks you
bridgeWithBridge this agent 1:1 with another agent’s tab in the same window, or fork that agent into a new tab and bridge with the copy — asks you
disconnectBridgeClose this agent’s Agent Bridge — asks you
reloadTabReload a terminal tab as Cmd+Shift+R does — its own tab at once (only if it will come back), another agent’s tab asks you
reloadWindowReload a maiTerm window, as Reload Current Window does — asks you
restartMaitermRestart maiTerm, optionally installing the available update first — asks you
addMcpServerAdd a remote MCP server for every agent through maiTerm — asks you; the sign-in is yours to do
getRequestStatusWhat became of a request the agent filed: pending, approved, done, failed, denied or expired
listMcpServersThe MCP servers maiTerm manages for every agent, with their state and tools. Read-only

Tidying up is the agent’s to do: reading the layout and moving tabs and workspaces around happen straight away. The line is who can message whom. Anything that changes it — making or unmaking a mesh, linking or unlinking meshes, a move into, out of or between meshes, opening or closing a 1:1 bridge — and starting a new agent, which could ask for more, reloading another agent’s tab or a window, restarting maiTerm, or adding an MCP server every agent will load, doesn’t act. It files a request, and nothing happens until you approve it.

  • You answer it on a card, in the Loom’s Decisions or on your phone with maiLink, and a notification takes you there. The card is in maiTerm’s own words, built from what maiTerm knows: what will change, which agents gain or lose whom, how many agents a restart would interrupt mid-turn. The agent’s only say is a one-line reason, shown as a quote.
  • Only that card counts. An agent asking you in chat, or Claude Code’s permission dialog for the tool call, is not an approval — an allowlist or auto mode passes those without you seeing them.
  • You approve what the card showed. maiTerm carries the request out from what it stored, and checks first that nothing has changed: a tab that has moved since, a mesh whose workspaces or agents differ from the card, or a different update on offer, and it fails rather than doing something you didn’t see.
  • The agent is told how it went — done, failed or denied — in its own tab. A restart is the exception: the agent is restarted instead.
  • Unanswered requests lapse after 30 minutes, and the agent is told nothing was done. A tab can have five waiting at once; asking for the same thing twice doesn’t add a second card.

A new tab opens in the background in the workspace’s active pane, and the agent that asked is told its id. A named tab in a mesh workspace joins that mesh, and its card says so. Asked for on an SSH host, the agent runs there, in the folder it named on that host, and the card says so and shows the ssh command it will go through. The host is taken as [user@]host or an ssh alias with at most a port, user, key file or jump host — nothing after it — so nothing can run anywhere but the place the card names. The tab comes back after a restart the way any SSH tab does: the connection, then maiTerm’s bridge, then the agent.

An agent can reload its own tab straight away — it’s the one interrupted — but only when the tab’s auto-resume will bring it back, it has no request still waiting on you, and you haven’t typed anything into its input box. The tab is replaced under a new id, as Cmd+Shift+R does, and the agent comes back in the same conversation. Reloading another agent’s tab is a request, and its card says whether that agent will come back. Reloading a window is always a request: its shells and agents keep running and every tab reattaches, but unsaved editor changes in it are lost, and the card counts them for the agent’s own window. If what the card said has changed by the time you approve — the tab’s auto-resume, or the unsaved editors it counted — nothing is done.

A bridge follows the Agent Bridge picker’s rules: an agent already bridged with a third is neither connected to nor forked, and only Claude Code and Codex can be forked. If the asking agent is bridged with someone else, the card says that bridge closes. A fork’s card says where the copy will run: on this machine, or — when the agent being forked is over SSH — on that host, showing the ssh command it will run through. If that has changed by the time you approve, nothing is done. A bridge to a tab that has since closed carries nothing, so disconnectBridge closes that one at once.

Files

ToolDescription
revealInTreePoint you at a file or folder in the Files column of the agent’s own window. Never opens a closed column or takes the keyboard
getTreeSelectionWhat you’ve selected in the Files tree: paths only, never contents
getAgentFileActivityThe files an agent read and changed this turn or session, as maiTerm recorded them from its tool calls — its own tab’s, or another agent tab’s in its mesh

Listed while Preferences → Files → Enable Files is on. See Files.

Browser

With Preferences → Chrome extension on, an agent gets ten browser… tools for the Chrome tabs you linked to it: read their console errors and failing requests (with their responses), read the page, click, type, navigate and take screenshots, signed in as you. Only you link a tab. See Chrome Extension.

Supervision

If Overlord is enabled and this window has an Overlord workspace, every supervised agent also gets replyToOverlord, and the supervisor agent gets a set of tools of its own — driving another tab, answering a prompt it’s stuck at, proposing rule changes, and putting a finished session away. See Overlord.

Acting as the right tab

Every tool call an agent makes has to be attributed to the tab it’s running in — that’s what makes getTabNotes read your notes and switchTab mean something. maiTerm establishes that two ways, both automatic:

  • A tab names itself on every request. maiTerm sets MAITERM_TAB_ID in each tab’s environment, and the agent’s own MCP configuration carries it as a header on every call it makes. Nothing is printed into the model’s context and nothing is typed by anyone.
  • A SessionStart hook links the session. It runs inside the tab’s own shell — so it can see which tab it is — and registers the agent’s session id the moment the agent process starts, which is what wires up auto-resume and hands the agent its standing instructions.

Between them, a restart, a resume, a fork or a compaction all come back correctly bound with nothing typed. That last part used to be the sharp edge: a resumed agent takes no turn until you type something, so before this there was no moment at which it could announce itself, and every restored tab sat unregistered — no tools, no hooks, invisible to maiLink and the mesh — until you noticed and re-registered it by hand.

The two sources are cross-checked rather than trusted blindly. The session is durable and wins on which tab; the header is exact but only as good as the shell that launched the agent, so it raises confidence when the two agree. When they disagree, or when only a deduction is available — an SSH connection re-mints its transport every few seconds, and a shell started inside tmux or after su inherits somebody else’s environment — the identity is treated as inferred, and the tools whose effect leaves the tab are refused on one: messaging or listing bridge peers, mesh topics, posting to a Mattermost thread, and sending files to your phone. Those speak under the tab’s name into someone else’s session, where a wrong guess can’t be taken back. The refusal says so and names the fix.

/maiterm init is a repair tool now

It still exists, and it still works — but it is no longer a startup step, and agents are told not to spend an opening turn on it. Run it when identity is genuinely wrong: a stale MAITERM_TAB_ID inherited from another shell, or an inferred-identity refusal like the one above. Everything else takes care of itself.

Tab Context Discovery

The getTabContext tool lets your agent peek at what’s happening in your tabs — recent terminal output or editor file content. If you have fewer than 10 tabs, it automatically returns context for all of them, making it easy for the agent to find the right tab without you having to specify. For larger workspaces, you can pass specific tab IDs.

Agent Hooks

maiTerm integrates with each agent’s hook system for real-time session awareness — no regex triggers needed. Claude Code’s hooks are registered in ~/.claude/settings.json; Codex’s lifecycle events are registered in ~/.codex/hooks.json. Both feed the same pipeline:

  • Session lifecycle — tracks session start, end, and compaction events
  • Active tool overlay — see what the agent is doing right now (editing files, running bash, etc.) in the terminal corner
  • Agent state indicators — per-tab, per-workspace, and a global footer dot show whether each agent is working, waiting for permission, or done — see Agent State Indicators below
  • Auto-resume — automatically captures session IDs and reconnects on tab restore (see Auto-resume below)
  • Multi-agent awareness — getClaudeSessions lets any session discover other active agent sessions across tabs for coordination, and Agent Bridge lets two sessions talk to each other directly
  • Compaction notifications — alerts during and after context compaction
  • Model switches without the extra confirm — newer Claude Code builds stop a /model switch at a “Switch model?” confirmation when the current model’s cache is warm, which a switch from your phone or the Loom can’t see. maiTerm answers it for sessions running in its own tabs, so the switch you asked for goes through; a Claude session in another terminal keeps its confirm, and a Claude Code too old to know the hook isn’t given it

The maiTerm mod (Claude Code)

Every Claude tab — local, or on a host you’ve reached over the SSH bridge — also loads a small Claude Code mod called maiterm-tab. maiTerm points each tab’s shell at it, so any claude you start there picks it up; over SSH the bridge copies it to the host (into ~/.maiterm/claude-mod/) and the remote shell is pointed at that copy. It comes with Enable Hooks Integration, and only Claude Code versions that support mods load it. An older Claude ignores it and runs on the settings hooks exactly as before. On Windows the mod isn’t loaded yet, so Claude tabs there run on the settings hooks too.

The mod works from inside Claude Code rather than by pressing keys in its terminal, which changes a few things you’ll notice:

  • Every event names its tab. The settings hooks are shared by every Claude on the machine and mostly can’t say which tab they came from; the mod’s copy can, and its duplicate from the settings hooks is dropped.
  • Answers are given by meaning. A permission answered from your phone, the Loom or the Overlord is handed to Claude as an allow or a deny, whichever row Yes and No sit on, and a No stops the turn as the dialog’s own No does. Answers to an agent’s AskUserQuestion go in as data, so multi-select and Other answers work. An answer that doesn’t take is withdrawn whole rather than left half-typed. Other rows — Yes, and don’t ask again for…, say — are still pressed as their key, because only the dialog knows the rule that row saves.
  • Prompts go around your draft, not into it. A message maiTerm sends the agent — from the phone or the Loom, a follow-up, an Overlord directive, a mesh or bridge peer, a Mattermost reply — is handed to the mod while the agent is between turns, and submitted beside whatever you’re typing in its input box, which stays where it is. While the agent is mid-turn, a message is typed into the empty box, where Claude queues it or takes it into the running turn as it would your own typing; while you have a draft there, it waits, and goes to the mod once the turn ends. Slash commands and images are still typed, so they still wait for an empty box.
  • Other Claude sessions are off limits. Claude Code lets sessions on the same machine message each other directly with its SendMessage tool. An agent in a maiTerm tab is refused a send to another session, and told to use sendToBridgedAgent instead — so a bridge or a mesh, which you set up, is the only way one maiTerm agent reaches another. Its own subagents and teammates are unaffected.
  • SSH transcripts stream. For an agent over SSH, the mod tells maiTerm as each part of the conversation is written, so text the agent wrote before a slow tool call reaches the phone and the Loom as the tool starts, not when it finishes.

Codex tabs, and Claude Code versions without mods, keep the keystroke paths described on each feature’s page.

Agent State Indicators

maiTerm surfaces what every agent is doing at three levels, all driven by hooks — no terminal-output guessing:

  • Per tab — each tab’s indicator reflects its agent: a pulse while working, ❗ when it needs permission, and a green dot when it’s done and waiting for input. Ordinary terminal output stays a dim dot, so a finished agent is never mistaken for a stray line of output.
  • Per workspace — the sidebar rolls a workspace’s tabs into one dot using batch semantics (permission > working > done). It turns green only once every agent in the workspace has settled, so green unambiguously means “all done.”
  • Global footer dot — rolls up every agent in the current window: red pulse = needs permission, accent pulse = working, green = finished, dim = no agents. Click it to jump straight to an agent’s tab; when several agents share the dominant state, each click cycles to the next.

Read vs. unread

A finished agent shows a filled green dot (unread); once you view its tab it relaxes to a hollow green ring (seen). This rolls up too — a workspace dot stays filled until every finished agent inside it has been seen, then goes hollow — so you can tell at a glance which completed agents still need a look.

Auto-resume

The moment an agent’s session starts, maiTerm captures its session ID and arms auto-resume so a restored or relaunched tab reconnects to the same conversation. Auto-resume is runtime-aware: the resume modal preselects the right command for whichever agent is running — claude --resume … for Claude Code, codex resume … for Codex — and hides itself entirely when a tab has no agent.

Agent Bridge

Bridge two running agent sessions so they can collaborate directly — one local and one over SSH, two related projects, even a Claude Code and a Codex. Press Cmd+Shift+L to pick a peer session; maiTerm forks it into a split pane beside you (when the target supports forking) or links an existing tab, and the two agents talk through sendToBridgedAgent. Every message is stamped with the sender’s real identity so the recipient knows it’s a peer, not you — and the agents stay deferring to you for decisions. Bridges persist across restarts.

See the dedicated Agent Bridge page for the full walkthrough. To scale past a single pair to a whole roster of agents that can each address any other by role — with topics, loop control, and a cockpit — see Mesh Workspace, the N:M generalization of a bridge.

The same hooks that drive the state indicators can ring your phone. maiLink is a companion app that connects directly to maiTerm over your LAN — encrypted and authenticated, with no cloud in the data path — so you can watch live transcripts, answer AskUserQuestion prompts, approve permissions, and interrupt a running agent from anywhere in the house. See the dedicated maiLink Companion page.

File Drop & Image Paste

Drag files onto a terminal running an agent over SSH — maiTerm SCP uploads them to a temp directory on the remote and pastes the paths so the agent can read them as file references. On local terminals, file paths are pasted directly. Either way the paths are only typed onto the line, never sent, and nothing is typed while the agent is showing a permission or trust dialog. The same goes for files dragged in from the Files tree.

You can also paste images from your clipboard (Cmd+V) into an agent session. maiTerm saves the image to a temp file and pastes the path, so the agent can view it directly — useful for sharing screenshots, diagrams, or error messages without leaving the terminal.

The /maiterm Skill

For Claude Code, maiTerm installs a skill that gives your agent fast slash-command access to the most common tools — /maiterm notes, /maiterm tabs, /maiterm diag, and more — without making it hunt through every MCP tool. It’s written on launch and removed on exit, and it works the same way over SSH on bridged remote hosts. Codex gets an equivalent maiterm prompt written to ~/.codex/prompts/.

It also ships a recommended status line for Claude Code. Run /maiterm statusline and your agent installs a compact status line showing host · cwd · git branch · model · reasoning effort · context usage. The installer renders a live colored preview first, only writes to ~/.claude/statusline-command.sh and your settings (it’s idempotent — safe to re-run), and tells you if jq is missing instead of leaving a broken line. It works on local sessions and on SSH-bridged hosts.

Dev/Production Isolation

Dev builds register as maiterm-dev (with display name “maiTermDev”), so development and production instances don’t interfere with each other.