amantus-ai / vibetunnel
- ΠΏΠΎΠ½Π΅Π΄Π΅Π»ΡΠ½ΠΈΠΊ, 2 ΡΠ΅Π²ΡΠ°Π»Ρ 2026β―Π³. Π² 00:00:03
Turn any browser into your terminal & command your agents on the go.
Turn any browser into your Mac terminal.
VibeTunnel proxies your terminals right into the browser, so you can vibe-code anywhere.
Documentation β’ Releases β’ Discord β’ Twitter
Ever wanted to check on your AI agents while you're away? Need to monitor that long-running build from your phone? Want to share a terminal session with a colleague without complex SSH setups? VibeTunnel makes it happen with zero friction.
The native macOS app provides the best experience with menu bar integration and automatic updates.
For Linux servers, Docker containers, or headless macOS systems, install via npm:
npm install -g vibetunnelThis gives you the full VibeTunnel server with web UI, just without the macOS menu bar app. See the npm Package section for detailed usage.
macOS App: Requires an Apple Silicon Mac (M1+). Intel Macs are not supported for the native app.
npm Package: Works on any system with Node.js 22.12+, including Intel Macs and Linux. Windows is not yet supported (#252).
Download VibeTunnel and drag it to your Applications folder.
brew install --cask vibetunnelVibeTunnel lives in your menu bar. Click the icon to start the server.
The vt command is a smart wrapper that forwards your terminal sessions through VibeTunnel:
How it works:
vt is a bash script that internally calls vibetunnel fwd to forward terminal outputInstallation sources:
/usr/local/bin/vt symlink during installationvt globally, with intelligent Mac app detectionSmart detection:
When you run vt from the npm package, it:
/Applications/VibeTunnel.appvt for the best experiencevibetunnel fwdvt always uses the best available implementation# Run any command in the browser
vt pnpm run dev
vt npm test
vt python script.py
# Use your shell aliases
vt gs # Your 'git status' alias works!
vt claude-danger # Custom aliases are resolved
# Open an interactive shell
vt --shell # or vt -i
# Git follow mode
vt follow # Follow current branch
vt follow main # Switch to main and follow
vt unfollow # Stop following
# For more examples and options, see "The vt Forwarding Command" section belowWhen opening a new session for the first time, VibeTunnel's working directory scanner will look for Git repositories. By default, this scans your home directory, which may trigger macOS permission prompts for accessing protected folders (like Desktop, Documents, Downloads, iCloud Drive, or external volumes).
To avoid these prompts:
This only happens on the first session when the scanner discovers your Git repositories. For more details about macOS privacy-protected folders, see this explanation.
Visit http://localhost:4020 to see all your terminal sessions.
Note: The iOS app is still work in progress and not recommended for production use yet.
VibeTunnel consists of three main components:
The server runs as a standalone Node.js executable with embedded modules, providing excellent performance and minimal resource usage.
Tailscale creates a secure peer-to-peer VPN network between your devices. It's the most secure option as traffic stays within your private network without exposing VibeTunnel to the public internet.
How it works: Tailscale creates an encrypted WireGuard tunnel between your devices, allowing them to communicate as if they were on the same local network, regardless of their physical location.
my-mac.tailnet-name.ts.net)http://[your-tailscale-hostname]:4020VibeTunnel now supports advanced Tailscale integration with Private and Public access modes:
https://[your-machine-name].[tailnet-name].ts.netTo use Public mode, you need to enable Funnel on your tailnet:
Enable Funnel for your tailnet by adding this ACL policy in the Tailscale Admin Console:
"nodeAttrs": [
{
"target": ["autogroup:member"], // All members of your tailnet
"attr": ["funnel"],
},
],Switch between modes in VibeTunnel:
Both Private and Public modes automatically provide HTTPS access:
Benefits:
"Tailscale Serve unavailable - using fallback mode": This is normal if you don't have Tailscale admin permissions. VibeTunnel will work perfectly using direct HTTP access at http://[your-tailscale-hostname]:4020.
"Applying mode configuration...": When switching between Private and Public modes, it may take a few seconds for Tailscale to reconfigure. This is normal.
"Funnel requires admin permissions": You need to be a tailnet admin to enable Funnel. Contact your tailnet admin or create your own tailnet if needed.
WebSocket connections fail: Make sure you're using the HTTPS URL when accessing VibeTunnel through Tailscale Serve. The WebSocket authentication tokens are automatically handled.
ngrok creates secure tunnels to your localhost, making VibeTunnel accessible via a public URL. Perfect for quick sharing or temporary access.
How it works: ngrok establishes a secure tunnel from a public endpoint to your local VibeTunnel server, handling SSL/TLS encryption and providing a unique URL for access.
Setup Guide:
https://[random].ngrok-free.app URLBenefits:
Note: Free ngrok URLs change each time you restart the tunnel. You can claim one free static domain per user, or upgrade to a paid plan for multiple domains.
http://[your-mac-ip]:4020cloudflared tunnel --url http://localhost:4020*.trycloudflare.com URLGit Follow Mode keeps your main repository checkout synchronized with the branch you're working on in a Git worktree. This allows agents to work in worktrees while your IDE, server, and other tools stay open on the main repository - they'll automatically update when the worktree switches branches.
Follow mode creates a seamless workflow for agent-assisted development:
# From a worktree - enable follow mode for this worktree
vt follow
# From main repo - follow current branch's worktree (if it exists)
vt follow
# From main repo - follow a specific branch's worktree
vt follow feature/new-api
# From main repo - follow a worktree by path
vt follow ~/project-feature
# Disable follow mode
vt unfollowvt unfollow, Git hooks are automatically removed and any original hooks are restored# Create a worktree for agent development
git worktree add ../project-agent feature/new-feature
# Enable follow mode on the main repo
cd ../project && vt follow
# Agent works in the worktree while you stay in main repo
# When agent switches branches in worktree, your main repo follows!
# Your Xcode/IDE and servers stay running without interruptionFollow mode stores the worktree path in your main repository's Git config:
# Check which worktree is being followed
git config vibetunnel.followWorktree
# Follow mode is active when this returns a path
# The config is managed by vt commands - manual editing not recommendedFor more advanced Git worktree workflows, see our detailed worktree documentation.
VibeTunnel provides terminal title management to help you track sessions:
~/projects/app β npm run devActivity indicators are based on recent input/output and drive active/idle UI states.
VibeTunnel provides multiple authentication modes to secure your terminal sessions:
Uses your operating system's native authentication:
Simple authentication for deployments:
export VIBETUNNEL_USERNAME=admin
export VIBETUNNEL_PASSWORD=your-secure-password
npm run startUse Ed25519 SSH keys from ~/.ssh/authorized_keys:
# Enable SSH key authentication
npm run start -- --enable-ssh-keys
# Make SSH keys mandatory (disable password auth)
npm run start -- --enable-ssh-keys --disallow-user-passwordFor trusted environments only:
npm run start -- --no-authAllow localhost connections to bypass authentication:
# Basic local bypass (DEVELOPMENT ONLY - NOT FOR PRODUCTION)
npm run start -- --allow-local-bypass
# With token for additional security (minimum for production)
npm run start -- --allow-local-bypass --local-auth-token mytokenSecurity Note: Local bypass uses req.socket.remoteAddress which cannot be spoofed remotely due to TCP's three-way handshake. The implementation also rejects requests with proxy headers (X-Forwarded-For, etc.) to prevent header injection attacks. However:
--local-auth-tokenThe macOS menu bar app supports these authentication modes:
~/.ssh/authorized_keys--bind 0.0.0.0)If SSH key generation fails with crypto errors, see the detailed troubleshooting guide for solutions.
The VibeTunnel npm package provides the full server functionality for Linux, Docker, CI/CD environments, and headless macOS systems.
# Install globally via npm
npm install -g vibetunnel
# Or with yarn
yarn global add vibetunnel
# Or with pnpm
pnpm add -g vibetunnelRequirements: Node.js 22.12.0 or higher
# Start local server (no auth)
npx -y vibetunnel --no-auth
# Quick remote share (ngrok)
npx -y vibetunnel --no-auth --ngrok
# One-shot vt wrapper
npx -y --package vibetunnel vt npm test# Start with default settings (localhost:4020)
vibetunnel
# Bind to all network interfaces
vibetunnel --bind 0.0.0.0
# Use a custom port
vibetunnel --port 8080
# With authentication
VIBETUNNEL_USERNAME=admin VIBETUNNEL_PASSWORD=secure vibetunnel --bind 0.0.0.0
# Enable debug logging
VIBETUNNEL_DEBUG=1 vibetunnel
# Run without authentication (trusted networks only!)
vibetunnel --no-authThe vt command wrapper makes it easy to forward terminal sessions:
# Run any command and see it in the browser
vt npm test
vt python script.py
vt cargo build --release
# Open an interactive shell
vt --shell
vt -i # short form
# Control terminal titles
vt --title-mode static npm run dev # Shows path and command
vt --title-mode filter vim # Blocks vim from changing title
# Control output verbosity
vt -q npm test # Quiet mode - no console output
vt -v npm run dev # Verbose mode - show more information
vt -vv cargo build # Extra verbose - all except debug
vt -vvv python app.py # Debug mode - show everything
# Shell aliases work automatically!
vt claude-danger # Your custom alias for claude --dangerously-skip-permissions
# Update session title (inside a VibeTunnel session)
vt title "My Project - Testing"The vt command is VibeTunnel's terminal forwarding wrapper that allows you to run any command while making its output visible in the browser. Under the hood, vt is a convenient shortcut for vibetunnel fwd - it's a bash script that calls the full command with proper path resolution and additional features like shell alias support. The vt wrapper acts as a transparent proxy between your terminal and the command, forwarding all input and output through VibeTunnel's infrastructure.
vt [options] <command> [args...]Terminal Title Control:
--title-mode <mode> - Control how terminal titles are managed:
none - No title management, apps control their own titles (default)filter - Block all title changes from applicationsstatic - Show working directory and command in titleVerbosity Control:
-q, --quiet - Quiet mode, no console output (logs to file only)-v, --verbose - Verbose mode, show errors, warnings, and info messages-vv - Extra verbose, show all messages except debug-vvv - Debug mode, show all messages including debugOther Options:
--shell, -i - Launch your current shell interactively--no-shell-wrap, -S - Execute command directly without shell interpretation--log-file <path> - Override default log file location (defaults to ~/.vibetunnel/log.txt)--help, -h - Show help message with all optionsVibeTunnel uses a hierarchical logging system where each level includes all messages from more severe levels:
| Level | Flag | Environment Variable | Shows |
|---|---|---|---|
| SILENT | -q |
VIBETUNNEL_LOG_LEVEL=silent |
No console output (file logging only) |
| ERROR | (default) | VIBETUNNEL_LOG_LEVEL=error |
Errors only |
| WARN | - | VIBETUNNEL_LOG_LEVEL=warn |
Errors and warnings |
| INFO | -v |
VIBETUNNEL_LOG_LEVEL=info |
Errors, warnings, and informational messages |
| VERBOSE | -vv |
VIBETUNNEL_LOG_LEVEL=verbose |
All messages except debug |
| DEBUG | -vvv |
VIBETUNNEL_LOG_LEVEL=debug |
Everything including debug traces |
Note: All logs are always written to ~/.vibetunnel/log.txt regardless of verbosity settings. The verbosity only controls terminal output.
# Basic command forwarding
vt ls -la # List files with VibeTunnel monitoring
vt npm run dev # Run development server
vt python script.py # Execute Python script
# With verbosity control
vt -q npm test # Run tests silently
vt -v npm install # See detailed installation progress
vt -vvv python debug.py # Full debug output
vt --log-file debug.log npm run dev # Write logs to custom file
# Terminal title management
vt --title-mode static npm run dev # Fixed title showing command
vt --title-mode filter vim # Prevent vim from changing title
# Shell handling
vt --shell # Open interactive shell
vt -S /usr/bin/python # Run python directly without shellvt wrapper first checks if your command is an alias, shell function, or binaryVIBETUNNEL_LOG_LEVEL - Set default verbosity level (silent, error, warn, info, verbose, debug)VIBETUNNEL_TITLE_MODE - Set default title mode (none, filter, static)VIBETUNNEL_DEBUG - Legacy debug flag, equivalent to VIBETUNNEL_LOG_LEVEL=debugShell Alias Support: Your shell aliases and functions work transparently through vt:
alias gs='git status'
vt gs # Works as expectedSession Title Updates: Inside a VibeTunnel session, use vt title to update the session name:
vt title "Building Production Release"The npm package is designed to work seamlessly alongside the Mac app:
vt command automatically detects if the Mac app is installed/Applications/VibeTunnel.app, it defers to the Mac app/usr/local/bin/vt already exists (from another tool), npm won't overwrite itvibetunnel or npx vtvt symlink can't be createdThe npm package includes:
vibetunnel and vt commands)For maintainers who need to build the npm package:
# Build with prebuilt binaries for all platforms
# Requires Docker for Linux cross-compilation
npm run build:npmThis creates prebuilt binaries for:
# Current platform only (faster for development)
node scripts/build-npm.js --current-only
# Specific platform/architecture
node scripts/build-npm.js --platform darwin --arch arm64
# Skip Docker builds
node scripts/build-npm.js --no-docker# Test the package locally
npm pack
# Publish to npm
npm publish# Clone the repository
git clone https://github.com/amantus-ai/vibetunnel.git
cd vibetunnel
# Set up code signing (required for macOS/iOS development)
# Create Local.xcconfig files with your Apple Developer Team ID
# Note: These files must be in the same directory as Shared.xcconfig
cat > mac/VibeTunnel/Local.xcconfig << EOF
// Local Development Configuration
// DO NOT commit this file to version control
DEVELOPMENT_TEAM = YOUR_TEAM_ID
CODE_SIGN_STYLE = Automatic
EOF
cat > ios/VibeTunnel/Local.xcconfig << EOF
// Local Development Configuration
// DO NOT commit this file to version control
DEVELOPMENT_TEAM = YOUR_TEAM_ID
CODE_SIGN_STYLE = Automatic
EOF
# Build the web server
cd web
pnpm install
pnpm run build
# Optional: Build with custom Node.js for smaller binary (46% size reduction)
# export VIBETUNNEL_USE_CUSTOM_NODE=YES
# node build-custom-node.js # Build optimized Node.js (one-time, ~20 min)
# pnpm run build # Will use custom Node.js automatically
# Build the macOS app
cd ../mac
./scripts/build.sh --configuration ReleaseVibeTunnel supports building with a custom Node.js for a 46% smaller executable (61MB vs 107MB):
# Build custom Node.js (one-time, ~20 minutes)
node build-custom-node.js
# Use environment variable for all builds
export VIBETUNNEL_USE_CUSTOM_NODE=YES
# Or use in Xcode Build Settings
# Add User-Defined Setting: VIBETUNNEL_USE_CUSTOM_NODE = YESSee Custom Node Build Flags for detailed optimization information.
For development setup and contribution guidelines, see CONTRIBUTING.md.
mac/VibeTunnel/VibeTunnelApp.swiftweb/src/server/ (TypeScript/Node.js)web/src/client/ (Lit/TypeScript)ios/VibeTunnel/VibeTunnel has comprehensive test suites with code coverage enabled for all projects:
# Run all tests with coverage
./scripts/test-all-coverage.sh
# macOS tests with coverage (Swift Testing)
cd mac && swift test --enable-code-coverage
# iOS tests with coverage (using xcodebuild)
cd ios && ./scripts/test-with-coverage.sh
# Web tests with coverage (Vitest)
cd web && ./scripts/coverage-report.shCoverage Requirements:
VibeTunnel includes a development server with automatic rebuilding for faster iteration:
cd web
pnpm run devWhat this provides:
How it works:
src/http://localhost:4020 and refresh to see changesWhen developing the web interface, you often need to test changes on external devices to debug browser-specific issues. Here's how to do it:
Run the dev server with network access:
cd web
pnpm run dev --port 4021 --bind 0.0.0.0This binds to all network interfaces, making it accessible from other devices.
Find your Mac's IP address:
ipconfig getifaddr en0Access from your external device:
http://[your-mac-ip]:4021
When using VibeTunnel on mobile browsers (Safari, Chrome), pasting works differently than on desktop:
To paste on mobile:
Note: Due to browser security restrictions on non-HTTPS connections, the paste API is limited on mobile devices. The white input box is a workaround that allows clipboard access through the browser's native paste functionality.
For true hot module replacement without manual refresh, see our Vite migration plan which would provide:
The VibeTunnel Mac app includes a special development server mode that integrates with the web development workflow:
Setup:
web/ directoryHow it works:
pnpm run dev in your web directoryBenefits:
Alternative: Standalone Development
If you prefer working outside the Mac app:
cd web && pnpm run buildhttp://[your-mac-ip]:4020Note: This requires rebuilding after each change, so the dev server mode above is preferred for rapid iteration.
Enable debug logging for troubleshooting:
# Enable debug mode
export VIBETUNNEL_DEBUG=1
# Or use inline
VIBETUNNEL_DEBUG=1 vt your-commandDebug logs are written to ~/.vibetunnel/log.txt.
When developing VibeTunnel, you can use the VIBETUNNEL_PREFER_DERIVED_DATA environment variable to make the vt command prefer development builds from Xcode's DerivedData folder:
# Enable DerivedData preference
export VIBETUNNEL_PREFER_DERIVED_DATA=1
# vt will now search for and use the latest VibeTunnel build from DerivedData
vt your-commandWhen this environment variable is set, vt will:
~/Library/Developer/Xcode/DerivedData/Applications/VibeTunnel.app if no DerivedData build existsThis is particularly useful for:
/ApplicationsThe version information is also:
session.json for each sessionvt status outputVIBETUNNEL_PREFER_DERIVED_DATA is setControl the amount of output from VibeTunnel commands:
# Command-line flags
vt -q npm test # Quiet mode - no console output
vt npm test # Default - errors only
vt -v npm run dev # Verbose - errors, warnings, and info
vt -vv cargo build # Extra verbose - all except debug
vt -vvv python script.py # Debug mode - everything
# Environment variable
export VIBETUNNEL_LOG_LEVEL=error # Default
export VIBETUNNEL_LOG_LEVEL=warn # Show errors and warnings
export VIBETUNNEL_LOG_LEVEL=info # Show errors, warnings, and info
export VIBETUNNEL_LOG_LEVEL=verbose # All except debug
export VIBETUNNEL_LOG_LEVEL=debug # Everything
# Or use inline
VIBETUNNEL_LOG_LEVEL=silent vt npm testNote: All logs are always written to ~/.vibetunnel/log.txt regardless of verbosity level. The verbosity settings only control what's displayed in the terminal.
Poltergeist is an intelligent file watcher and auto-builder that can automatically rebuild VibeTunnel as you develop. This is particularly useful for native app development where manual rebuilds can interrupt your flow.
Install Poltergeist (if not already installed):
npm install -g poltergeistStart Poltergeist in the VibeTunnel directory:
cd /path/to/vibetunnel
poltergeistMake changes - Poltergeist will automatically rebuild when it detects changes to:
mac/ or ios/VibeTunnel includes a poltergeist.config.json that configures:
To enable iOS builds, edit poltergeist.config.json and set "enabled": true for the vibetunnel-ios target.
macOS is finicky when it comes to permissions. The system will only remember the first path from where an app requests permissions. If subsequently the app starts somewhere else, it will silently fail. Fix: Delete the entry and restart settings, restart app and next time the permission is requested, there should be an entry in Settings again.
Important: You need to set your Developer ID in Local.xcconfig. If apps are signed Ad-Hoc, each new signing will count as a new app for macOS and the permissions have to be (deleted and) requested again.
Debug vs Release Bundle IDs: The Debug configuration uses a different bundle identifier (sh.vibetunnel.vibetunnel.debug) than Release (sh.vibetunnel.vibetunnel). This allows you to have both versions installed simultaneously, but macOS treats them as separate apps for permissions. You'll need to grant permissions separately for each version.
If that fails, use the terminal to reset:
# This removes Accessibility permission for a specific bundle ID:
sudo tccutil reset Accessibility sh.vibetunnel.vibetunnel
sudo tccutil reset Accessibility sh.vibetunnel.vibetunnel.debug # For debug builds
sudo tccutil reset ScreenCapture sh.vibetunnel.vibetunnel
sudo tccutil reset ScreenCapture sh.vibetunnel.vibetunnel.debug # For debug builds
# This removes all Automation permissions system-wide (cannot target specific apps):
sudo tccutil reset AppleEvents
VibeTunnel uses Apple's unified logging system with the subsystem sh.vibetunnel.vibetunnel. By default, macOS redacts sensitive runtime data in logs, showing <private> instead of actual values. This is a privacy feature to prevent accidental exposure of sensitive information.
VibeTunnel uses the following bundle identifiers:
Production:
sh.vibetunnel.vibetunnel - Main macOS app and logging subsystemsh.vibetunnel.vibetunnel.debug - Debug builds of the macOS appTesting:
sh.vibetunnel.vibetunnel.tests - macOS test suitesh.vibetunnel.ios.tests - iOS test suiteiOS:
sh.vibetunnel.ios - iOS keychain service and URL schemeTo see full log details for debugging, you have several options:
Install the Configuration Profile (Recommended - easiest method):
# Install the logging configuration profile
open apple/logging/VibeTunnel-Logging.mobileconfig
# This enables debug logging for all VibeTunnel components
# To remove later: System Settings β Privacy & Security β ProfilesUse the vtlog script (convenient log viewer):
# View recent logs (requires configuration profile or sudo)
./scripts/vtlog.sh
# Follow logs in real-time
./scripts/vtlog.sh -f
# Show only errors
./scripts/vtlog.sh -e
# Filter by category
./scripts/vtlog.sh -c ServerManagerConfigure passwordless sudo (alternative for vtlog with -p flag):
# Add to sudoers (replace 'yourusername' with your actual username)
sudo visudo
# Add this line:
yourusername ALL=(ALL) NOPASSWD: /usr/bin/log
# Then use vtlog with private flag
./scripts/vtlog.sh -pEnable private data logging using a plist file (alternative):
# Create the plist to enable private data for VibeTunnel
sudo mkdir -p /Library/Preferences/Logging/Subsystems
sudo tee /Library/Preferences/Logging/Subsystems/sh.vibetunnel.vibetunnel.plist > /dev/null << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Enable-Private-Data</key>
<true/>
</dict>
</plist>
EOFApple redacts dynamic values in logs by default to protect user privacy. This prevents accidental logging of passwords, tokens, or personal information. Our configuration profile or the methods above enable full visibility for development and debugging.
For more detailed information about logging privacy and additional methods, see apple/docs/logging-private-fix.md.
We welcome contributions! VibeTunnel is a community-driven project and we'd love to have you join us.
Connect with the VibeTunnel team and other contributors on our Discord server. It's the best place to:
good first issue or help wantedFor technical details on building and developing VibeTunnel, see our Contributing Guide.
Love VibeTunnel? Help us keep the terminal vibes flowing! Your support helps us buy pizza and drinks while we keep hacking on your favorite AI agent orchestration platform.
All donations go directly to the development team. Choose your own amount - one-time or monthly! Visit our Polar page to support us.
Created with β€οΈ by:
VibeTunnel is open source software licensed under the MIT License. See LICENSE for details.
Ready to vibe? Download VibeTunnel and start tunneling!