From claude-code-tunnels
Deploys HTTP listener to remote machine via SSH or kubectl, enabling Orchestrator to use remote project as workspace without query timeouts. Useful for long-running tasks on servers or K8s pods.
npx claudepluginhub matteblack9/claude-code-clone --plugin claude-tunnelsThis skill uses the workspace's default tool permissions.
Deploys a lightweight HTTP listener to a remote machine (SSH) or Kubernetes Pod,
Connects a single workspace on a remote machine to the Claude Code Orchestrator via SSH or kubectl. Use for adding individual remote workspaces to existing local projects.
Manages remote GPU clusters via rca CLI: run commands, batch jobs, GPU/node inspection, file sync with mutagen. For training, remote exec, status checks.
Establishes SSH connections to remote servers for executing commands, checking logs, restarting services, and managing Docker containers via bash scripts.
Share bugs, ideas, or general feedback.
Deploys a lightweight HTTP listener to a remote machine (SSH) or Kubernetes Pod, allowing the Orchestrator to use the remote environment's project as a workspace.
Key point: claude-agent-sdk query(cwd=) has no timeout. Because the listener calls the SDK directly on the remote machine,
tasks run without time limits, just as they would locally.
Connecting a remote project requires a local orchestrator installation and a means of accessing the remote machine (ssh/kubectl). Check each item in order — if any check fails, do not proceed to the next step until it is resolved.
Why it is needed: the remote_workspaces configuration must be registered in this file, and the executor reads remote host information from it.
Why it is needed: deploy.py (the remote deployment script) and listener.py (the HTTP server to run on the remote machine) must be present for deployment.
if [ ! -f "orchestrator/remote/deploy.py" ] || [ ! -f "orchestrator/remote/listener.py" ]; then
echo "orchestrator/remote/ files not found."
fi
Why they are needed: ssh or kubectl is required to copy listener.py to the remote machine and execute it.
Auto-detect available tools:
tools=()
command -v ssh &>/dev/null && tools+=("ssh")
command -v kubectl &>/dev/null && tools+=("kubectl")
Select the remote access method.
Used to copy and run listener.py on the remote machine.
[1] ssh <- detected
[2] kubectl <- detected
[3] Enter manually (different path to ssh/kubectl)
Number:
Zero candidates detected → "Could not find ssh or kubectl. Please install one and try again."
Why it is needed: display the current registration state to prevent duplicate registration on the same host:port.
Currently registered remote workspaces:
(none)
— or —
my-project/backend → 10.0.0.5:9100
my-project/frontend → 10.0.0.5:9101
What name should the Orchestrator use to identify this remote project?
This name will appear in the execution plan.
Format: project/workspace (e.g. my-project/backend)
Enter:
Validation: must contain / (project/workspace format).
If the user selected ssh:
─────────────────────────────────────────────────────────────────
1. host (required)
The IP address or hostname of the remote machine. Used to connect to the listener via HTTP.
Enter:
2. user
The SSH username.
[1] $USER <- current user
[2] Enter manually
Number:
3. key_file
The SSH key file.
[1] ~/.ssh/id_rsa <- exists
[2] ~/.ssh/id_ed25519 <- exists
[3] Use default key (ssh-agent)
[4] Enter manually
Number:
─────────────────────────────────────────────────────────────────
SSH key candidates are auto-detected by scanning the ~/.ssh/ directory:
for f in ~/.ssh/id_rsa ~/.ssh/id_ed25519 ~/.ssh/id_ecdsa; do
[ -f "$f" ] && echo "$f"
done
After input, immediately run a connection test:
ssh $USER@$HOST "echo 'SSH OK'"
If the user selected kubectl:
Auto-detect available namespaces/pods and present as choices:
# namespace list
kubectl get namespaces -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
Select a namespace.
[1] default
[2] my-namespace
[3] production
[4] Enter manually
Number:
Pod list after namespace selection:
kubectl get pods -n $NAMESPACE -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
Select a Pod.
[1] my-app-abc123
[2] my-app-def456
[3] Enter manually
Number:
Container (for multi-container pods):
kubectl get pod $POD -n $NAMESPACE -o jsonpath='{.spec.containers[*].name}' 2>/dev/null
kubeconfig:
[1] ~/.kube/config <- default
[2] Enter manually
Number:
Connection test: kubectl exec $POD -n $NAMESPACE -- echo 'K8s OK'
Enter the absolute path where the project is located on the remote machine.
The listener will run claude-agent-sdk query(cwd=) from this path.
Enter (e.g. /home/user/my-project):
Validation — verify the path exists on the remote machine:
ssh $USER@$HOST "test -d $REMOTE_CWD && echo OK || echo FAIL"
Listener port:
# Auto-detect available ports on the remote machine
for p in 9100 9101 9102; do
ssh $USER@$HOST "ss -tlnp 2>/dev/null | grep -q ':${p} '" || available+=("$p")
done
Select the listener port.
The executor will send HTTP requests to this port.
[1] 9100 <- available
[2] 9101 <- available
[3] Enter manually
Number:
Auth token:
Would you like to set up Bearer token authentication on the listener?
When configured, only the orchestrator will be able to access the listener.
[1] No authentication (not needed on an internal network)
[2] Enter a token
Number:
Why it is needed: the listener uses Python + claude-agent-sdk + aiohttp on the remote machine. If any of these is missing, execution will fail.
# Check remote Python
ssh $USER@$HOST "python3 --version"
# Check remote packages
ssh $USER@$HOST "python3 -c 'import claude_agent_sdk'" 2>/dev/null
ssh $USER@$HOST "python3 -c 'import aiohttp'" 2>/dev/null
Remote environment check results:
Python: 3.11.5 ✓
claude-agent-sdk: OK ✓
aiohttp: NOT INSTALLED ✗
Some packages are not installed.
[1] Install on remote now (run pip install via ssh)
[2] Install manually and continue
[3] Ignore and continue (errors may occur when the listener starts)
Number:
Show deployment summary and confirm:
Deployment summary:
Target: $USER@$HOST
Path: $REMOTE_CWD/.claude-listener.py
Port: $LISTENER_PORT
Token: (set / none)
listener.py will be copied to the remote machine and started.
Proceed? (yes/no)
Deployment steps:
remote_cwd/.claude-listener.py)/tmp/claude-listener-{port}.log)remote_workspaces:
- name: $WORKSPACE_NAME
host: $HOST
port: $LISTENER_PORT
token: "$LISTENER_TOKEN"
Validation:
curl http://$HOST:$LISTENER_PORT/health
# Expected: {"status": "ok", "cwd": "$REMOTE_CWD", "port": $LISTENER_PORT}
| Endpoint | Method | Description |
|---|---|---|
/health | GET | Check status |
/execute | POST | Execute a task. Body: {"task": "...", "upstream_context": {}} |
ssh $USER@$HOST cat /tmp/claude-listener-$LISTENER_PORT.log
kubectl exec $POD -n $NAMESPACE -- cat /tmp/claude-listener-$LISTENER_PORT.log