typemux-cc
Health Pass
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 10 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
This tool is a Python type-checker LSP multiplexer proxy for Claude Code. It automatically detects local .venv environments and dynamically routes type-checking requests to backends like pyright, eliminating the need to restart your session when virtual environments change.
Security Assessment
Overall risk: Low. The codebase is written in Rust and was scanned with no dangerous patterns found. It does not request any dangerous system permissions. As a local proxy, it facilitates communication between your IDE, the language server protocol, and your local Python virtual environments. It does not appear to make external network requests, execute arbitrary hidden shell commands, or contain hardcoded secrets. Its function is strictly limited to local filesystem and process routing.
Quality Assessment
The project appears to be highly active and well-maintained, with the last code push occurring today. It uses the standard, permissive MIT license. The documentation is clear, addressing a specific and recognized pain point with git worktrees and virtual environment detection. The community trust is currently low but growing, standing at 10 GitHub stars. While it is a very new and small tool, it passes all baseline health and code quality checks.
Verdict
Safe to use.
Claude Code plugin: Python type-checker LSP multiplexer. Auto-detects .venv and routes to pyright/ty/pyrefly—no Claude Code restart.
typemux-cc
Python type-checker LSP multiplexer for Claude Code — pyright, ty, pyrefly
Quickstart ◆ Problems Solved ◆ Backends ◆ Installation ◆ Typical Use Case ◆ Architecture
Claude Code's official pyright plugin spawns a single LSP backend at startup and holds onto it. If .venv doesn't exist yet — or you create a new one later — it never picks it up. You have to restart Claude Code.
This is especially painful with git worktrees, now common in AI-assisted development: you spin up a fresh worktree, create .venv, and then must restart Claude Code just to get type-checking.
typemux-cc is a Python LSP proxy that fixes this — .venv changes are reflected within your running session, no restarts required.
Quickstart
# 1. Install a backend (pyright recommended)
npm install -g pyright
# 2. Disable the official pyright plugin
/plugin disable pyright-lsp@claude-plugins-official
# 3. Add marketplace and install
/plugin marketplace add K-dash/typemux-cc
/plugin install typemux-cc@typemux-cc-marketplace
# 4. Restart Claude Code (initial installation only)
For ty/pyrefly, set
TYPEMUX_CC_BACKENDin your config.
Problems Solved
- ⚡ Late
.venvcreation (worktrees, hooks) — Spin up a git worktree, create.venvlater, and typemux-cc picks it up on the next file open. No Claude Code restart needed. - 🔄 Multi-project venv switching (monorepos) — typemux-cc keeps a per-
.venvbackend pool and routes requests to the correct one. Switching between projects is instant. - 🔀 Multi-backend support — Not locked into pyright. Choose between pyright, ty, or pyrefly — switch via a single env var.
Why LSP over text search? In monorepos, grep returns false positives from same-named types across projects. LSP resolves references at the type-system level. See real-world benchmarks.
Supported Backends
| Backend | Command | Status |
|---|---|---|
| pyright | pyright-langserver --stdio |
✅ Stable (default if TYPEMUX_CC_BACKEND is not set) |
| ty | ty server |
✅ Stable |
| pyrefly | pyrefly lsp |
✅ Stable |
Requirements
Supported OS
| Platform | Architecture |
|---|---|
| macOS | arm64 only |
| Linux | x86_64 / arm64 |
[!Note]
Windows is currently unsupported (due to path handling differences).
Intel macOS users must build from source (prebuilt binaries are arm64 only).
Prerequisites
- One of the supported LSP backends available in PATH:
pyright-langserver(install vianpm install -g pyrightorpip install pyright)ty(install viapip install tyoruvx ty)pyrefly(install viapip install pyrefly)
- Git (used to determine
.venvsearch boundary, works without it)
Installation
[!Note]
Claude Code restart is required only for initial installation. After installation,.venvcreation and switching no longer require restarts.
Prerequisites
1. Install your preferred LSP backend
# pyright (default, recommended)
npm install -g pyright
# ty (by the creators of uv)
pip install ty
# pyrefly (by Meta)
pip install pyrefly
2. Disable Official pyright Plugin
[!Important]
You must disable the official pyright plugin. Having both enabled causes conflicts.
/plugin disable pyright-lsp@claude-plugins-official
Method A: From GitHub Marketplace (Recommended)
[!Note]
Installation uses GitHub API andcurl. It may fail in offline environments or under rate limiting.
# 1. Add marketplace
/plugin marketplace add K-dash/typemux-cc
# 2. Install plugin
/plugin install typemux-cc@typemux-cc-marketplace
# 3. Restart Claude Code (initial installation only)
After installation, verify in ~/.claude/settings.json:
{
"enabledPlugins": {
"pyright-lsp@claude-plugins-official": false,
"typemux-cc@typemux-cc-marketplace": true
}
}
Update / Uninstall
# Update
/plugin update typemux-cc@typemux-cc-marketplace
# Uninstall
/plugin uninstall typemux-cc@typemux-cc-marketplace
/plugin marketplace remove typemux-cc-marketplace
Method B: Local Build (For Developers)
Requires Rust 1.75 or later.
git clone https://github.com/K-dash/typemux-cc.git
cd typemux-cc
cargo build --release
/plugin marketplace add /path/to/typemux-cc
/plugin install typemux-cc@typemux-cc-marketplace
# Restart Claude Code (initial installation only)
Usage
Automatically starts as a Claude Code plugin — no manual setup required.
Configuration
Settings are stored in ~/.config/typemux-cc/config. The file uses KEY=VALUE format (shell expansion is not supported):
mkdir -p ~/.config/typemux-cc
cat > ~/.config/typemux-cc/config << 'EOF'
# Select backend (pyright, ty, or pyrefly)
TYPEMUX_CC_BACKEND=pyright
# Enable file logging
TYPEMUX_CC_LOG_FILE=/tmp/typemux-cc.log
EOF
Note:
export KEY=VALUEsyntax is also accepted for compatibility with older config files.
Settings priority: CLI flag > environment variable > config file > default
| Variable | Description | Default |
|---|---|---|
TYPEMUX_CC_LOG_FILE |
Log file path | Not set (stderr only) |
TYPEMUX_CC_BACKEND |
LSP backend to use | pyright |
TYPEMUX_CC_MAX_BACKENDS |
Max concurrent backend processes | 8 |
TYPEMUX_CC_BACKEND_TTL |
Backend TTL in seconds (0 = disabled) | 1800 |
TYPEMUX_CC_FANOUT_TIMEOUT |
Fan-out timeout in seconds for workspace/symbol (0 = no timeout) |
5 |
RUST_LOG |
Log level | typemux_cc=debug |
Typical Use Case
Git Worktree (AI-Assisted Development)
A common workflow with AI coding agents:
my-project/ # main worktree
├── .venv/
└── src/main.py
my-project-worktree/ # new worktree (no .venv yet)
└── src/main.py
| Step | What Happens |
|---|---|
| 1. Create worktree | git worktree add ../my-project-worktree feat/new-feature — no .venv exists |
2. Create .venv |
cd ../my-project-worktree && uv sync — .venv now exists |
| 3. Open a file | Claude Code opens my-project-worktree/src/main.py → typemux-cc detects the new .venv and spawns a backend automatically |
With the official plugin, step 3 would require restarting Claude Code. With typemux-cc, it just works.
Monorepo Structure
my-monorepo/
├── project-a/
│ ├── .venv/ # project-a specific virtual environment
│ └── src/main.py
├── project-b/
│ ├── .venv/ # project-b specific virtual environment
│ └── src/main.py
└── project-c/
├── .venv/ # project-c specific virtual environment
└── src/main.py
Operation Sequence
| Claude Code Action | Proxy Behavior |
|---|---|
| 1. Session starts | Search for fallback .venv (start without venv if not found) |
2. Opens project-a/src/main.py |
Detect project-a/.venv → spawn backend (session 1), add to pool |
3. Opens project-b/src/main.py |
Detect project-b/.venv → spawn backend (session 2), add to pool |
4. Returns to project-a/src/main.py |
project-a/.venv already in pool → route to session 1 (no restart) |
What Actually Happens
When Claude Code moves from project-a/main.py to project-b/main.py:
- Proxy detects different
.venv(project-a/.venv → project-b/.venv) - Checks the backend pool —
project-b/.venvnot found - Spawns new backend with
VIRTUAL_ENV=project-b/.venv(session 2) - Session 1 (project-a) stays alive in the pool — no restart
- Restores open documents under project-b/ to session 2
- Clears diagnostics for documents outside project-b/
- All LSP requests for project-b files now use project-b dependencies
When Claude Code returns to project-a/main.py later, session 1 is still in the pool — zero restart overhead.
Backends are evicted only when the pool is full (LRU) or after idle timeout (TTL, default 30 min).
From the user's perspective: Nothing visible happens. LSP just works.
Environment Variables
Each backend process is spawned with VIRTUAL_ENV and PATH set to point at the detected .venv. These are only applied to the child backend process — your shell environment and system PATH are never modified.
Troubleshooting
Self-Diagnosis (--doctor)
Run --doctor to dump configuration, environment, and system info at a glance:
# Find the binary in the plugin cache, then run --doctor
ls ~/.claude/plugins/cache/typemux-cc-marketplace/typemux-cc/
# → 0.2.9
~/.claude/plugins/cache/typemux-cc-marketplace/typemux-cc/0.2.9/bin/typemux-cc --doctor
The binary reads ~/.config/typemux-cc/config directly, so your settings are reflected in the output:
typemux-cc v0.2.9
Config file:
Path /Users/foo/.config/typemux-cc/config
Status loaded
Configuration:
backend pyright (default)
max_backends 8 (default)
backend_ttl 1800 (default)
warmup_timeout 2 (default)
fanout_timeout 5 (default)
log_file /tmp/typemux-cc.log (config: /Users/foo/.config/typemux-cc/config)
Environment:
Backend binary pyright-langserver
Path /usr/local/bin/pyright-langserver
Version pyright 1.1.350
Git toplevel /Users/foo/project
Fallback venv /Users/foo/project/.venv
System:
OS macos (Darwin 24.0.0)
Arch aarch64
Add --json for machine-readable output:
~/.claude/plugins/cache/typemux-cc-marketplace/typemux-cc/0.2.9/bin/typemux-cc --doctor --json
LSP Not Working
Tip: Run
--doctorfirst to check your configuration and backend availability. For detailed logs, addTYPEMUX_CC_LOG_FILE=/tmp/typemux-cc.logto your config.
# Quick self-diagnosis (replace version number as needed)
~/.claude/plugins/cache/typemux-cc-marketplace/typemux-cc/0.2.9/bin/typemux-cc --doctor
cat ~/.claude/settings.json | grep typemux # Check plugin settings
tail -100 /tmp/typemux-cc.log # Check logs (if file logging enabled)
Plugin Update Not Taking Effect
Due to a known Claude Code issue, /plugin update may not refresh the cached plugin files. If you still see the old version after updating, manually clear the cache:
# 1. Remove cached plugin
rm -rf ~/.claude/plugins/cache/typemux-cc-marketplace/
# 2. Reinstall
/plugin install typemux-cc@typemux-cc-marketplace
# 3. Restart Claude Code
.venv Not Switching
- Verify
.venv/pyvenv.cfgexists - Verify file is within git repository
- Use
RUST_LOG=tracefor detailed venv search logs
[!Note]
If.venvdidn't exist when a file was first opened, typemux-cc automatically re-searches for it on the next LSP request. No need to reopen the file.
Known Limitations
| Item | Limitation | Workaround |
|---|---|---|
| Windows unsupported | Path handling assumes Unix-like systems | Use WSL2 |
| macOS Intel unsupported | Prebuilt is arm64 only | Use Apple Silicon |
| Fixed venv name | Only .venv with pyvenv.cfg — intentionally strict to avoid silently wrong environments (poetry/conda/etc. not supported) |
Rename to .venv or create a .venv symlink |
| Symlinks | May fail to detect pyvenv.cfg if .venv is a symlink |
Use actual directory |
| setuptools editable installs | Not a typemux-cc bug. All LSP backends (pyright, ty, pyrefly) cannot resolve imports from setuptools-style editable installs that use import hooks (ty#475) | Switch build backend to hatchling/flit, or add source paths to extra-paths in backend config |
workspace/symbol fan-out latency |
With multiple backends, workspace/symbol fans out to all backends and merges results; response time equals the slowest backend (timeout: 5s default) |
Adjust via TYPEMUX_CC_FANOUT_TIMEOUT env var |
workspace/symbol always returns empty |
Claude Code's LSP tool does not pass a query parameter to workspace/symbol requests. The LSP spec requires { query: "search string" }, but the tool interface only exposes operation, filePath, line, character. With an empty query, pyright returns no results. This is a Claude Code limitation, not a typemux-cc bug. |
Use Grep/Glob for cross-project symbol search until Claude Code adds query support |
goToDefinition/findReferences return empty in worktrees |
typemux-cc correctly rewrites rootUri per-backend and forwards pyright's valid response (confirmed via trace logging: pyright returns correct Location[], proxy forwards with has_result=true). However, Claude Code's LSP tool reports "No definition found" when the session's cwd differs from the worktree root. The root cause within Claude Code is unknown. hover and documentSymbol work correctly for the same files and paths. |
Launch Claude Code directly inside the worktree directory (e.g., cd .worktree/branch && claude), or use hover to check types and Grep/Glob for cross-file navigation |
Architecture
For design philosophy, state transitions, and internal implementation details, see:
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found