Skip to content

Latest commit

 

History

History
543 lines (409 loc) · 19.7 KB

File metadata and controls

543 lines (409 loc) · 19.7 KB

Maniple MCP Server

An MCP server that allows one Claude Code session to spawn and manage a team of other Claude Code (or Codex) sessions via terminal backends (tmux or iTerm2).

Introduction

maniple is an MCP server and a set of slash commands for allowing Claude Code to orchestrate a "team" of other Claude Code or Codex sessions. It uses terminal backends (tmux or iTerm2) to spawn new terminal sessions and run Claude Code or Codex within them.

Why?

  • Parallelism: Many development tasks can be logically parallelized, but managing that parallelism is difficult for humans with limited attention spans. Claude, meanwhile, is very effective at it.
  • Context management: Offloading implementation to a worker gives the implementing agent a fresh context window (smarter), and keeps the manager's context free of implementation details.
  • Background work: Sometimes you want to have Claude Code go research something or answer a question without blocking the main thread of work.
  • Visibility: maniple spawns real Claude Code or Codex sessions. You can watch them, interrupt and take control, or close them out.

But, why not just use Claude Code sub-agents, you ask? They're opaque -- they go off and do things and you, the user, cannot effectively monitor their work, interject, or continue a conversation with them. Using a full Claude Code session obviates this problem.

Terminal Backends

maniple supports two terminal backends:

Backend Platform Status
tmux macOS, Linux Primary. Auto-selected when running inside tmux.
iTerm2 macOS only Fully supported. Requires Python API enabled.

Backend selection order:

  1. MANIPLE_TERMINAL_BACKEND environment variable (tmux or iterm)
  2. Config file setting (terminal.backend)
  3. Auto-detect: if TMUX env var is set, use tmux; otherwise iTerm2

Git Worktrees: Isolated Branches per Worker

A key feature of maniple is git worktree support. When spawning workers with use_worktree: true (the default), each worker gets:

  • Its own working directory - A git worktree at {repo}/.worktrees/{name}/
  • Its own branch - Automatically created from the current HEAD
  • Shared repository history - All worktrees share the same .git database, so commits are immediately visible across workers

Worktree naming depends on how workers are spawned:

  • With an issue ID: {repo}/.worktrees/{issue_id}-{badge}/
  • Without: {repo}/.worktrees/{worker-name}-{uuid}-{badge}/

The .worktrees directory is automatically added to .gitignore.

Codex Support

Workers can run either Claude Code or OpenAI Codex. Set agent_type: "codex" in the worker config (or set the default in the config file) to spawn Codex workers instead of Claude Code workers.

Features

  • Spawn Workers: Create Claude Code or Codex sessions with multi-pane layouts
  • Terminal Backends: tmux (cross-platform) and iTerm2 (macOS)
  • Git Worktrees: Isolate each worker in its own branch and working directory
  • Send Messages: Inject prompts into managed workers (single or broadcast)
  • Read Logs: Retrieve conversation history from worker JSONL files
  • Monitor Status: Check if workers are idle, processing, or waiting for input
  • Idle Detection: Wait for workers to complete using stop-hook markers
  • Event Polling: Track worker lifecycle events (started, completed, stuck)
  • Visual Identity: Each worker gets a unique tab color and themed name (Marx Brothers, Beatles, etc.)
  • Session Recovery: Discover and adopt orphaned sessions after MCP server restarts
  • HTTP Mode: Run as a persistent service with streamable-http transport
  • Config File: Centralized configuration at ~/.maniple/config.json

Requirements

  • Python 3.11+
  • uv package manager
  • tmux backend: tmux installed (macOS or Linux)
  • iTerm2 backend: macOS with iTerm2 and Python API enabled (Preferences > General > Magic > Enable Python API)
  • Codex workers (optional): OpenAI Codex CLI installed

Installation

As Claude Code Plugin (recommended)

# Add the Martian Engineering marketplace
/plugin marketplace add Martian-Engineering/maniple

# Install the plugin
/plugin install maniple@martian-engineering

This automatically configures the MCP server - no manual setup needed.

From PyPI

uvx --from maniple-mcp@latest maniple

From Source

git clone https://github.com/Martian-Engineering/maniple.git
cd maniple
uv sync

Configuration for Claude Code

Add to your Claude Code MCP settings. You can configure this at:

  • Global: ~/.claude/settings.json
  • Project: .claude/settings.json in your project directory

Using PyPI package

{
  "mcpServers": {
    "maniple": {
      "command": "uvx",
      "args": ["--from", "maniple-mcp@latest", "maniple"]
    }
  }
}

Using local clone

{
  "mcpServers": {
    "maniple": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/maniple", "python", "-m", "maniple_mcp"]
    }
  }
}

Project-level with auto project path

For project-scoped .mcp.json files, use MANIPLE_PROJECT_DIR so workers inherit the project path:

{
  "mcpServers": {
    "maniple": {
      "command": "uvx",
      "args": ["--from", "maniple-mcp@latest", "maniple"],
      "env": { "MANIPLE_PROJECT_DIR": "${PWD}" }
    }
  }
}

After adding the configuration, restart Claude Code for it to take effect.

Config File

maniple reads configuration from ~/.maniple/config.json. Manage it with the CLI:

maniple config init          # Create default config
maniple config init --force  # Overwrite existing config
maniple config show          # Show effective config (file + env overrides)
maniple config get <key>     # Get value by dotted path (e.g. defaults.layout)
maniple config set <key> <value>  # Set and persist a value

Migration Notes (from claude-team)

  • Config directory: ~/.claude-team/ is auto-migrated to ~/.maniple/ on first run.
  • Environment variables: MANIPLE_* takes precedence; CLAUDE_TEAM_* is supported as a fallback and may emit a deprecation warning to stderr.

Config Schema

{
  "version": 1,
  "commands": {
    "claude": null,
    "codex": null
  },
  "defaults": {
    "agent_type": "claude",
    "skip_permissions": false,
    "use_worktree": true,
    "layout": "auto"
  },
  "terminal": {
    "backend": null
  },
  "events": {
    "max_size_mb": 1,
    "recent_hours": 24
  },
  "issue_tracker": {
    "override": null
  }
}
Section Key Description
commands.claude string Override Claude CLI command (e.g. "happy")
commands.codex string Override Codex CLI command (e.g. "happy codex")
defaults.agent_type "claude" or "codex" Default agent type for new workers
defaults.skip_permissions bool Default --dangerously-skip-permissions flag
defaults.use_worktree bool Create git worktrees by default
defaults.layout "auto" or "new" Default layout mode for spawn_workers
terminal.backend "tmux" or "iterm" Terminal backend override (null = auto-detect)
events.max_size_mb int Max event log file size before rotation
events.recent_hours int Hours of events to retain
issue_tracker.override "beads" or "pebbles" Force a specific issue tracker

Environment Variables

Variable Default Description
MANIPLE_TERMINAL_BACKEND (auto-detect) Force terminal backend: tmux or iterm. Highest precedence.
MANIPLE_PROJECT_DIR (none) Enables "project_path": "auto" in worker configs.
MANIPLE_COMMAND claude Override the CLI command for Claude Code workers.
MANIPLE_CODEX_COMMAND codex Override the CLI command for Codex workers.

MCP Tools

Worker Management

Tool Description
spawn_workers Create workers with multi-pane layouts. Supports Claude Code and Codex agents.
list_workers List all managed workers with status. Filter by status or project.
examine_worker Get detailed worker status including conversation stats and last response preview.
close_workers Gracefully terminate one or more workers. Worktree branches are preserved.
discover_workers Find existing Claude Code/Codex sessions running in tmux or iTerm2.
adopt_worker Import a discovered session into the managed registry.

Communication

Tool Description
message_workers Send a message to one or more workers. Supports wait modes: none, any, all.
read_worker_logs Get paginated conversation history from a worker's JSONL file.
annotate_worker Add a coordinator note to a worker (visible in list_workers output).

Monitoring

Tool Description
check_idle_workers Quick non-blocking check if workers are idle.
wait_idle_workers Block until workers are idle. Modes: all (fan-out/fan-in) or any (pipeline).
poll_worker_changes Read worker event log for started/completed/stuck workers since a timestamp.

Utilities

Tool Description
list_worktrees List git worktrees created by maniple for a repository. Supports orphan cleanup.
issue_tracker_help Quick reference for the detected issue tracker (Beads or Pebbles).

Worker Identification

Workers can be referenced by any of three identifiers:

  • Internal ID: Short hex string (e.g., 3962c5c4)
  • Terminal ID: Prefixed terminal session ID (e.g., iterm:UUID or tmux:%1)
  • Worker name: Human-friendly name (e.g., Groucho, Aragorn)

All tools accept any of these formats.

Tool Details

spawn_workers

WorkerConfig fields:
  project_path: str         - Required. Explicit path or "auto" (uses MANIPLE_PROJECT_DIR)
  agent_type: str           - "claude" (default) or "codex"
  name: str                 - Optional worker name override (auto-picked from themed sets if omitted)
  badge: str                - Task description (shown in badge, used in branch names)
  issue_id: str             - Issue tracker ID (for badge, branch naming, and workflow instructions)
  prompt: str               - Additional instructions (combined with standard worker prompt)
  skip_permissions: bool    - Start with --dangerously-skip-permissions
  use_worktree: bool        - Create isolated git worktree (default: true)
  worktree: WorktreeConfig  - Optional worktree settings:
                              branch: Explicit branch name (auto-generated if omitted)
                              base: Ref/branch to branch FROM (default: HEAD). Set this
                                    when subtask workers need a feature branch's commits
                                    (e.g. {"base": "epic-id/feature-branch"})

Top-level arguments:
  workers: list[WorkerConfig]  - 1-4 worker configurations
  layout: str                  - "auto" (reuse windows) or "new" (fresh window)

Returns:
  sessions, layout, count, coordinator_guidance

Worker assignment is determined by issue_id and/or prompt:

  • issue_id only: Worker follows issue tracker workflow (mark in_progress, implement, close, commit)
  • issue_id + prompt: Issue tracker workflow plus additional custom instructions
  • prompt only: Custom task with no issue tracking
  • neither: Worker spawns idle, waiting for a message

message_workers

Arguments:
  session_ids: list[str]   - Worker IDs to message (accepts any identifier format)
  message: str             - The prompt to send
  wait_mode: str           - "none" (default), "any", or "all"
  timeout: float           - Max seconds to wait (default: 600)

Returns:
  success, session_ids, results, [idle_session_ids, all_idle, timed_out]

wait_idle_workers

Arguments:
  session_ids: list[str]   - Worker IDs to wait on
  mode: str                - "all" (default) or "any"
  timeout: float           - Max seconds to wait (default: 600)
  poll_interval: float     - Seconds between checks (default: 2)

Returns:
  session_ids, idle_session_ids, all_idle, waiting_on, mode, waited_seconds, timed_out

poll_worker_changes

Arguments:
  since: str                    - ISO timestamp to filter events from (or null for latest)
  stale_threshold_minutes: int  - Minutes without activity before marking stuck (default: 20)
  include_snapshots: bool       - Include periodic snapshot events (default: false)

Returns:
  events, summary (started/completed/stuck), active_count, idle_count, poll_ts

HTTP Server Mode

Run maniple as a persistent HTTP service instead of stdio:

maniple --http              # Default port 8766
maniple --http --port 9000  # Custom port

HTTP mode enables:

  • Streamable HTTP transport for MCP communication
  • Worker poller that periodically snapshots worker state and emits lifecycle events
  • MCP Resources for read-only session access:
    • sessions://list - List all managed sessions
    • sessions://{session_id}/status - Detailed session status
    • sessions://{session_id}/screen - Terminal screen content

Slash Commands

Install slash commands for common workflows:

make install-commands
Command Description
/spawn-workers Analyze tasks, create worktrees, and spawn workers with appropriate prompts
/check-workers Generate a status report for all active workers
/merge-worker Directly merge a worker's branch back to parent (for internal changes)
/pr-worker Create a pull request from a worker's branch
/team-summary Generate end-of-session summary of all worker activity
/cleanup-worktrees Remove worktrees for merged branches

Issue Tracker Support

maniple supports both Pebbles (pb) and Beads (bd --no-db). The tracker is auto-detected by marker directories in the project root:

  • .pebbles -> Pebbles
  • .beads -> Beads

If both markers exist, Pebbles is selected by default. This can be overridden in the config file with issue_tracker.override. Worker prompts and coordination guidance use the detected tracker commands.

Usage Patterns

Basic: Spawn and Message

From your Claude Code session, spawn workers and send them tasks:

"Spawn two workers for frontend and backend work"
-> Uses spawn_workers with two WorkerConfigs pointing at different project paths
-> Returns workers named e.g. "Simon" and "Garfunkel"

"Send Simon the message: Review the React components"
-> Uses message_workers with session_ids=["Simon"]

"Check on Garfunkel's progress"
-> Uses examine_worker with session_id="Garfunkel"

Parallel Work with Worktrees

Spawn workers in isolated branches for parallel development:

"Spawn three workers with worktrees to work on different features"
-> Uses spawn_workers with use_worktree=true (default)
-> Creates worktrees at {repo}/.worktrees/
-> Each worker gets their own branch

"Message all workers with their tasks, then wait for completion"
-> Uses message_workers with wait_mode="all"

"Create PRs for each worker's branch"
-> Uses /pr-worker for each completed worker

Issue Tracker Integration

Assign workers to issue tracker items for structured workflows:

"Spawn a worker for issue cic-123"
-> spawn_workers with issue_id="cic-123", badge="Fix auth bug"
-> Worker automatically marks issue in_progress, implements, closes, and commits

"Spawn workers for all ready issues"
-> Check `bd ready` or `pb ready` for available work
-> Spawn one worker per issue with issue_id assignments

Coordinated Workflow

Use the manager to coordinate between workers:

"Spawn a backend worker to create a new API endpoint"
-> Wait for completion with wait_idle_workers

"Now spawn a frontend worker and tell it about the new endpoint"
-> Pass context from read_worker_logs of the backend worker

"Spawn a test worker to write integration tests"
-> Coordinate based on both previous workers' output

Architecture

┌──────────────────────────────────────────────────────────────────┐
│                Manager Claude Code Session                       │
│                (has maniple MCP server)                          │
├──────────────────────────────────────────────────────────────────┤
│                         MCP Tools                                │
│  spawn_workers | message_workers | wait_idle_workers | etc.      │
└───────────────────────────┬──────────────────────────────────────┘
                            │
               ┌────────────┼────────────┐
               ▼            ▼            ▼
         ┌──────────┐ ┌──────────┐ ┌──────────┐
         │ Groucho  │ │ Harpo    │ │ Chico    │
         │ (tmux)   │ │ (tmux)   │ │ (tmux)   │
         │          │ │          │ │          │
         │  Claude  │ │  Claude  │ │  Codex   │
         │   Code   │ │   Code   │ │          │
         │          │ │          │ │          │
         │ worktree │ │ worktree │ │ worktree │
         │ .worktrees/ │ .worktrees/ │ .worktrees/ │
         └──────────┘ └──────────┘ └──────────┘

The manager maintains:

  • Session Registry: Maps worker IDs/names to terminal sessions
  • Terminal Backend: Persistent connection to tmux or iTerm2 for terminal control
  • JSONL Monitoring: Reads Claude/Codex session files for conversation state and idle detection
  • Worktree Tracking: Manages git worktrees for isolated worker branches
  • Event Log: Records worker lifecycle events for polling and diagnostics

Development

# Sync dependencies (with dev tools)
uv sync --group dev

# Run tests
uv run pytest

# Run the server directly (for debugging)
uv run python -m maniple_mcp

# Run in HTTP mode
uv run python -m maniple_mcp --http

# Install slash commands
make install-commands

Troubleshooting

tmux backend

"tmux not found"

  • Install tmux: brew install tmux (macOS) or apt install tmux (Linux)
  • Ensure tmux is in your PATH

Workers not detected after restart

  • Use discover_workers to find orphaned sessions
  • Use adopt_worker to re-register them
  • Sessions are matched via markers written to JSONL files

iTerm2 backend

"Could not connect to iTerm2"

  • Make sure iTerm2 is running
  • Enable: iTerm2 > Preferences > General > Magic > Enable Python API

General

"Session not found"

  • The worker may have been closed externally
  • Use list_workers to see active workers
  • Workers can be referenced by ID, terminal ID, or name

"No JSONL session file found"

  • Claude Code may still be starting up
  • Wait a few seconds and try again
  • Check that Claude Code is actually running in the worker pane

Worktree issues

  • Use list_worktrees to see worktrees for a repository
  • Orphaned worktrees can be cleaned up with list_worktrees + remove_orphans=true
  • Worktrees are stored at {repo}/.worktrees/

Upgrading

After a new version is published to PyPI, you may need to force-refresh the cached version:

uv cache clean --force
uv tool install --force --refresh maniple

This is necessary because uvx aggressively caches tool environments.

License

MIT