Metadata-Version: 2.3
Name: mcp-server-iterm2
Version: 0.1.1
Summary: MCP server exposing iTerm2 to agents for observation and non-destructive annotation.
Keywords: mcp,iterm2,claude,ai,agent
Author: Rob Trame
Author-email: Rob Trame <me@r6e.dev>
License: MIT License
         
         Copyright (c) 2026 Rob Trame
         
         Permission is hereby granted, free of charge, to any person obtaining a copy
         of this software and associated documentation files (the "Software"), to deal
         in the Software without restriction, including without limitation the rights
         to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         copies of the Software, and to permit persons to whom the Software is
         furnished to do so, subject to the following conditions:
         
         The above copyright notice and this permission notice shall be included in all
         copies or substantial portions of the Software.
         
         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
         SOFTWARE.
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: mcp>=1.12
Requires-Dist: iterm2>=2.7
Requires-Python: >=3.12
Project-URL: Homepage, https://github.com/r6e/mcp-server-iterm2
Project-URL: Repository, https://github.com/r6e/mcp-server-iterm2
Project-URL: Issues, https://github.com/r6e/mcp-server-iterm2/issues
Description-Content-Type: text/markdown

# mcp-server-iterm2

[![CI](https://github.com/r6e/mcp-server-iterm2/actions/workflows/ci.yml/badge.svg)](https://github.com/r6e/mcp-server-iterm2/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/mcp-server-iterm2.svg)](https://pypi.org/project/mcp-server-iterm2/)
[![Python](https://img.shields.io/pypi/pyversions/mcp-server-iterm2.svg)](https://pypi.org/project/mcp-server-iterm2/)

A Model Context Protocol (MCP) server that exposes iTerm2 to agents for **observation** and **non-destructive annotation**. Agents can inspect sessions and decorate them (badge, title, tab color, user variables, notifications) but cannot inject keystrokes, close or spawn sessions, or otherwise alter the user's working environment.

## Install

Configure your MCP client (e.g. Claude Desktop, Claude Code):

```json
{
  "mcpServers": {
    "iterm2": {
      "command": "uvx",
      "args": ["mcp-server-iterm2"]
    }
  }
}
```

Requires macOS, iTerm2, and [`uv`](https://docs.astral.sh/uv/) installed.

## First run

On first invocation, iTerm2 prompts you to authorize API access for the script. Approve it. Subsequent runs are silent.

If you previously denied access: iTerm2 → Preferences → General → Magic → enable "Python API" and remove `mcp-server-iterm2` from the denial list.

## Tools

### Read

| Tool                  | Description                                                                 |
| --------------------- | --------------------------------------------------------------------------- |
| `list_sessions`       | Tree of windows → tabs → sessions, plus a top-level `buried_sessions` list. |
| `get_session_info`    | Title, working dir, profile, badge, dimensions, TTY                         |
| `get_screen_contents` | Visible buffer + cursor position                                            |
| `get_scrollback`      | Last N lines (default 200, max 5000)                                        |
| `get_recent_output`   | Output since a cursor marker (cursor-based pagination)                      |
| `get_selection`       | Currently-selected text                                                     |
| `get_variable`        | Read a variable by fully-qualified name (e.g. `session.path`, `user.badge`) |
| `list_profiles`       | Available profiles by name and GUID                                         |

### Write (non-destructive)

| Tool                | Description                      |
| ------------------- | -------------------------------- |
| `set_badge`         | Set session badge text           |
| `set_title`         | Override session title           |
| `set_tab_color`     | Tint the tab (RGB 0-255)         |
| `set_user_variable` | Set a `user.*` session variable  |
| `post_notification` | Post a macOS notification banner |

Every session-targeted tool accepts an optional `session_id`. If omitted, the server uses `$ITERM_SESSION_ID` from its environment — which works automatically when the agent runs inside iTerm2.

## Notes on rendering

- **Badge:** for `set_badge` to display anything, your iTerm2 profile's badge format must include `\(user.badge)`. Configure in iTerm2 → Profiles → General → Badge.
- **Title:** whether a `set_title` override sticks depends on the profile's "Allow terminal apps to change title" and "Title Components" settings. The server always sets the override; iTerm2 controls the rendering.
- **Tab color:** `set_tab_color` writes the legacy tab color plus both light- and dark-mode variants, so the tint takes effect regardless of the profile's split-color preference.
- **Notifications:** routed through macOS via `osascript`. Make sure Terminal/iTerm2 notifications are allowed in System Settings if banners don't appear.

## Excluded by design

For safety, these are not exposed: `send_text`/keystroke injection, closing or spawning sessions/tabs/windows, splitting panes, focus changes, broadcasting input.

## Security model

Installing this server gives any MCP client that uses it broad read access to your iTerm2 sessions (screen contents, scrollback, working directories, variables) and limited write access (badge, title, tab color, `user.*` variables, macOS notifications). Read tools can capture passwords visible on screen; write tools can spoof titles and notifications. The full threat model and reporting flow live in [SECURITY.md](SECURITY.md).

## Development

```bash
uv sync
uv run pytest tests/unit       # 122 unit tests
uv run ruff check .            # lint
uv run ruff format --check .   # format check
uv run ty check src            # type check
```

Integration tests (`pytest -m integration`) and the smoke script (`scripts/smoke.py`) require running inside an iTerm2 session. See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development guide and [ARCHITECTURE.md](ARCHITECTURE.md) for how the pieces fit together.

## API stability

This project follows [semantic versioning](https://semver.org/). The current release is in the `0.x` series; expect schema refinements between minor versions as the tool surface settles in response to real-world feedback. Pin to a specific version in production.

From `1.0` onward the following will be part of the stable contract — breaking any of them requires a major bump:

- **Tool names and the set of tools.** Names and removal of tools are stable; new tools may be added in minor releases.
- **Tool argument names and types.** New optional arguments may be added; existing argument names, types, and required-ness do not change.
- **Top-level response keys and value types.** New keys may be added in minor releases; existing keys and their types do not change.
- **Error envelope shape.** `MCPIterm2Error` subclasses surface actionable text via `to_error_text`; unknown exceptions collapse to `Internal error: <ExceptionClass>`. Callers may pattern-match on this envelope.

Not part of the stable surface:

- Internal Python modules (`server.py`, `connection.py`, `tools/*`, `errors.py`, `output_cursor.py`) — these are implementation details.
- Specific cursor payload encoding for `get_recent_output`. Treat the cursor as opaque; pass back whatever the server returned.
- iTerm2 SDK and macOS version compatibility windows — these follow upstream and may change in minor releases.

## Documentation

- [ARCHITECTURE.md](ARCHITECTURE.md) — module layout, lifecycle, data flow
- [CONTRIBUTING.md](CONTRIBUTING.md) — dev setup, quality gates, PR process
- [SECURITY.md](SECURITY.md) — threat model and how to report a vulnerability
- [CHANGELOG.md](CHANGELOG.md) — version history
- [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) — community standards

## License

MIT — see [LICENSE](LICENSE).
