Claude Code CLI wrapper with tmux session management, subprocess execution, and OAuth token handling
Project description
claude-tmux
Python wrapper for Claude Code CLI with tmux session management, subprocess execution, and OAuth token handling.
Features
- Subprocess Execution: Run Claude Code CLI in
--printmode for programmatic access - Tmux Visibility: Optionally run commands in tmux sessions for visibility and debugging
- Conversation Continuity: Automatic session management with
--continueflag - OAuth Token Management: Automatic detection and refresh of expired tokens
- Multi-Agent Support: Manage multiple independent Claude agents
- Activity Timeouts: Smart handling of long-running tasks with status checks
- Stream JSON Parsing: Extract responses from Claude's stream-json output format
Installation
# Install from PyPI
pip install claude-tmux
# Or for development (from source)
pip install -e .
Quick Start
from claude_tmux import TmuxClaudeClient
# Create a client
client = TmuxClaudeClient(
session_name="my-project",
working_dir="/path/to/project",
system_prompt_text="You are a helpful coding assistant.",
)
# Send a message
response = client.chat("Hello! What files are in this directory?")
print(response)
# Continue the conversation (uses same session)
response = client.chat("What does the main.py file do?")
print(response)
Usage
Basic Chat
from claude_tmux import TmuxClaudeClient
client = TmuxClaudeClient(working_dir="/my/project")
# Simple chat
response = client.chat("Explain this codebase")
# Chat with context
response = client.chat(
"Fix this bug",
context="Error log: Connection refused on port 8080"
)
# Separate conversation threads
response = client.chat("Question 1", conversation_key="thread-a")
response = client.chat("Question 2", conversation_key="thread-b")
With Tmux Visibility
# Enable tmux for visibility during long operations
client = TmuxClaudeClient(
session_name="debug-session",
working_dir="/project",
use_tmux=True, # Commands run in tmux session
)
# You can attach to the tmux session to watch:
# tmux attach -t debug-session-run
Custom System Prompt
# From text
client = TmuxClaudeClient(
system_prompt_text="You are a security auditor. Review code for vulnerabilities."
)
# From file
client = TmuxClaudeClient(
system_prompt_file="/path/to/prompt.txt"
)
MCP Server Configuration
# Pass MCP config for custom tools
client = TmuxClaudeClient(
mcp_config="/path/to/mcp-config.json"
)
# Or as a dict
client = TmuxClaudeClient(
mcp_config={
"mcpServers": {
"custom-tools": {
"command": "node",
"args": ["/path/to/server.js"]
}
}
}
)
Session Management
# List available sessions
sessions = client.list_sessions(limit=10)
for s in sessions:
print(f"{s['id']}: {s['first_input'][:50]}...")
# Resume a specific session
client.select_session("abc123-session-id")
response = client.chat("Continue where we left off")
# Clear history (starts fresh)
client.clear_history()
Process Control
# Check if Claude is processing
if client.is_busy():
status = client.get_status()
print(f"Running for {status['duration']:.1f}s")
# Get last activity
chunk = client.get_last_chunk()
if chunk:
print(f"Last activity: {chunk}")
# Interrupt a long-running operation
if client.is_busy():
client.interrupt()
Multi-Agent Management
from claude_tmux import TmuxAgentManager
manager = TmuxAgentManager(base_session_name="project")
# Spawn specialized agents
review_agent = manager.spawn_agent(
"reviewer",
working_dir="/repo",
system_prompt_text="You review pull requests."
)
docs_agent = manager.spawn_agent(
"documenter",
working_dir="/repo/docs",
system_prompt_text="You write documentation."
)
# Use agents
review = review_agent.chat("Review the latest changes")
docs_agent.chat("Update the API docs")
# List active agents
print(manager.list_agents()) # ["reviewer", "documenter"]
# Get status of all agents
status = manager.get_all_status()
# Stop specific agent
manager.stop_agent("reviewer")
# Stop all agents
manager.stop_all()
OAuth Token Management
from claude_tmux import OAuthTokenManager, check_and_refresh_token
# Quick check and refresh
if check_and_refresh_token():
print("Token is valid")
# More control
manager = OAuthTokenManager()
# Check expiry
if manager.is_token_expired():
print("Token needs refresh")
manager.refresh_token()
# Get expiry time
expiry = manager.get_expiry_time()
print(f"Token expires at: {expiry}")
# Ensure valid token (refresh if needed)
manager.ensure_valid_token()
Configuration
Environment Variables
The client respects these environment variables:
HOME: Home directory for Claude credentials (~/.claude/)
Timeout Settings
- Status check interval: 60 seconds of no output triggers a status prompt
- Maximum runtime: 30 minutes absolute limit
- Maximum status checks: 10 prompts before giving up
API Reference
TmuxClaudeClient
| Method | Description |
|---|---|
chat(message, context, conversation_key) |
Send message and get response |
list_sessions(limit) |
List available Claude sessions |
select_session(session_id) |
Resume a specific session |
get_current_session() |
Get currently selected session |
clear_history(conversation_key) |
Clear conversation history |
is_busy() |
Check if processing |
get_status() |
Get processing status |
get_last_chunk(max_length) |
Get last output chunk |
interrupt() |
Interrupt current operation |
TmuxAgentManager
| Method | Description |
|---|---|
spawn_agent(agent_id, working_dir, ...) |
Create new agent |
get_agent(agent_id) |
Get existing agent |
stop_agent(agent_id) |
Stop and remove agent |
list_agents() |
List all agent IDs |
stop_all() |
Stop all agents |
get_agent_status(agent_id) |
Get agent status |
get_all_status() |
Get all agents' status |
OAuthTokenManager
| Method | Description |
|---|---|
is_token_expired(buffer_seconds) |
Check if token needs refresh |
get_expiry_time() |
Get token expiry timestamp |
refresh_token() |
Refresh the OAuth token |
ensure_valid_token() |
Check and refresh if needed |
Requirements
- Python 3.10+
- Linux or macOS (uses Unix-specific APIs)
- Claude Code CLI installed and configured
- httpx (for OAuth token refresh)
- tmux (optional, for visibility mode)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
rb_claude_tmux-0.1.0.tar.gz
(23.1 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rb_claude_tmux-0.1.0.tar.gz.
File metadata
- Download URL: rb_claude_tmux-0.1.0.tar.gz
- Upload date:
- Size: 23.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b774ce4c625b28b6073c199923722e7cd5262a47191317c09e0d0940d9ca4134
|
|
| MD5 |
d9572cd4c38e7452f4b74a3532f55e53
|
|
| BLAKE2b-256 |
d4c867de3747420f797fe717e6e61e663840a8db6e3108d5b035ab1293f2f021
|
File details
Details for the file rb_claude_tmux-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rb_claude_tmux-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f7a39053a4bb7a40e1fea018e5015138c811c57af680b67362275556a097938
|
|
| MD5 |
c2ac2dcf61fcb4696dc1aa9f3cf1509f
|
|
| BLAKE2b-256 |
305733bf73d9edbf6279eda72f9dfd7e2d730c9b4f63637fc7442de91d750ad4
|