den-tanui

Kitty MCP Server

Community den-tanui
Updated

MCP Server for interacting with kitty terminal

Kitty MCP Server

A production-grade MCP server for controlling kitty terminal instances

A production-grade Model Context Protocol (MCP) server for controlling kitty terminal instances.

Overview

  • Create, manage, and control kitty terminal instances programmatically
  • Send text and key combinations to kitty windows
  • Capture scrollback buffer content for command output analysis
  • Useful for long running processes, analyzing logs, and automation workflows
  • All instances launched with --app-id for window identification

Features

  • Launch kitty instances with unique Unix sockets and app-id
  • Send text and key combinations to windows
  • Launch windows within existing instances
  • Capture scrollback buffer content
  • Manage app-ids for window identification
  • List and close instances
  • JSON structured logging
  • Async/await throughout
  • Comprehensive error handling

Installation

Prerequisites

  • Python 3.11+
  • kitty terminal installed and in PATH
  • uv (recommended) or pip

Install from PyPI

# Install from PyPI
pip install kitty-mcp

# Install with uv (recommended)
uv add kitty-mcp

Install from Source

# Clone repository
git clone https://github.com/your-username/kitty-mcp.git
cd kitty-mcp

# Install with uv
uv pip install -e ".[dev]"

# Or with pip
pip install -e ".[dev]"

Usage

Running the Server

# Run directly
python -m kitty_mcp

# Or using the installed script
kitty-mcp

The server communicates via stdio (standard input/output) for MCP compatibility.

Configuration

Create a configuration file at ~/.config/kitty-mcp/config.json:

{
  "socket_dir": "/tmp/kitty-mcp",
  "max_instances": 10,
  "socket_permissions": "0600",
  "logging": {
    "level": "INFO"
  },
  "kitty": {
    "launch_timeout": 30,
    "command_timeout": 30
  }
}

Configuration options:

  • socket_dir: Directory for Unix sockets (default: /tmp/kitty-mcp-<uid>)
  • max_instances: Maximum concurrent instances (default: 10, max: 100)
  • socket_permissions: Socket file permissions (default: "0600")
  • logging.level: Log level (DEBUG, INFO, WARNING, ERROR)
  • kitty.launch_timeout: Timeout for launching kitty (seconds)
  • kitty.command_timeout: Timeout for RC commands (seconds)

Available Tools

launch

Launch a new kitty instance with remote control enabled.

Parameters:

  • app_id (string, required): Unique identifier for the instance
  • working_directory (string, optional): Working directory
  • window_class (string, optional): Window class (defaults to app_id)

Returns: {"success": true, "app_id": "...", "socket_path": "...", "pid": 1234}

send_text

Send text to a kitty window.

Parameters:

  • app_id (string, required): Instance identifier
  • text (string, required): Text to send
  • match (string, optional): Window matching criteria

send_key

Send key combination to a kitty window.

Parameters:

  • app_id (string, required): Instance identifier
  • key (string, required): Key combination (e.g., "ctrl+c", "enter")
  • match (string, optional): Window matching criteria

launch_window

Launch a new window in an existing kitty instance.

Parameters:

  • app_id (string, required): Instance identifier
  • command (array, required): Command to run
  • cwd (string, optional): Working directory

get_scrollback

Capture scrollback buffer content.

Parameters:

  • app_id (string, required): Instance identifier
  • lines (integer, optional): Number of lines (default: all)
  • match (string, optional): Window matching criteria

Returns: {"success": true, "content": "..."}

close

Close a kitty instance.

Parameters:

  • app_id (string, required): Instance identifier
  • force (boolean, optional): Force close

get_app_id

Get the app-id of a running kitty instance.

Parameters:

  • app_id (string, required): Instance identifier

Returns: {"success": true, "app_id": "...", "configured_app_id": "..."}

set_app_id

Update the app-id tracking for an instance.

Parameters:

  • app_id (string, required): Current instance identifier
  • new_app_id (string, required): New identifier

list_instances

List all active managed kitty instances.

Returns: {"success": true, "instances": [...]}

Development

Running Tests

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=kitty_mcp --cov-report=term-missing

# Run only unit tests
uv run pytest tests/unit/

# Run only integration tests (requires kitty)
uv run pytest tests/integration/

Quick Start

  1. Install kitty-mcp and configure with your MCP client (e.g., OpenCode, Claude Desktop)
  2. Launch a kitty instance:
    result = kitty_launch(app_id="my-terminal", working_directory="/home/user")
    
  3. Send commands:
    kitty_send_text(app_id="my-terminal", text="echo 'Hello World!'")
    kitty_send_key(app_id="my-terminal", key="enter")
    
  4. Get output:
    output = kitty_get_scrollback(app_id="my-terminal", lines=5)
    print(output["content"])  # Hello World!
    
  5. Clean up:
    kitty_close(app_id="my-terminal")
    

MCP Client Configuration

OpenCode

Add to .opencode/opencode.jsonc:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "kitty": {
      "type": "local",
      "command": ["kitty-mcp"],
      "enabled": true
    }
  }
}

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "kitty": {
      "command": "kitty-mcp"
    }
  }
}

Code Quality

# Type checking
mypy src/

# Linting
ruff check src/

# Format code
ruff format src/

Architecture

┌─────────────────┐
│   MCP Client    │ (opencode/Claude Desktop)
│   (stdio IPC)   │
└────────┬────────┘
         │
         ▼
┌──────────────────────┐
│  KittyMCP Server     │ FastMCP framework
│  ├─ Tool handlers    │
│  ├─ State management │
│  ├─ Configuration    │
│  └─ Logging          │
└────────┬─────────────┘
         │ asyncio subprocess
         ▼
┌──────────────────────┐
│  Kitty RC Commands   │ kitten @ --to unix:/socket
└────────┬─────────────┘
         │ Unix socket
         ▼
┌──────────────────────┐
│  Kitty Instance      │ allow_remote_control=yes
│  └─ --app-id set     │
└──────────────────────┘

Examples

Terminal Automation

# Launch and run commands
kitty_launch(app_id="automation", working_directory="/tmp")
kitty_send_text(app_id="automation", text="ls -la")
kitty_send_key(app_id="automation", key="enter")
output = kitty_get_scrollback(app_id="automation")
print(output["content"])

TUI Application Control

# Control nvim with complex workflows
kitty_launch(app_id="editor", working_directory="/project")
kitty_send_text(app_id="editor", text="nvim")
kitty_send_key(app_id="editor", key="enter")

# Navigate nvim interfaces
kitty_send_key(app_id="editor", key="space")
kitty_send_key(app_id="editor", key="p")  # Open projects
kitty_send_key(app_id="editor", key="enter")

Multiple Instance Management

# Launch multiple terminals
for i in range(3):
    kitty_launch(app_id=f"terminal-{i}", working_directory=f"/tmp/term-{i}")

# List all instances
instances = kitty_list_instances()
print(f"Active instances: {len(instances['instances'])}")

# Close all
for instance in instances["instances"]:
    kitty_close(app_id=instance["app_id"])

Performance

  • Command latency: <100ms for RC operations
  • Startup time: ~0.5s for MCP server initialization
  • Memory usage: <50MB for 10 active instances
  • Concurrent support: Up to 100 instances (configurable)

Security

  • Socket permissions: User-only (0600) by default
  • Command validation: Input sanitization and validation
  • Error handling: No sensitive data in logs
  • Atomic operations: Safe state persistence

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

MIT License - see LICENSE for details.

Changelog

See CHANGELOG.md for version history and release notes.

MCP Server · Populars

MCP Server · New