remote-opencode
v1.5.2
Published
Discord bot for remote OpenCode CLI access
Readme
remote-opencode
Control your AI coding assistant from anywhere — your phone, tablet, or another computer.
📦 Used by developers worldwide — 2,000+ weekly downloads on npm
🆕 New in v1.5! Session management — browse, attach, and manage OpenCode CLI sessions from Discord with
/session. Plus: model autocomplete for/model set. See changelog🎤 v1.4: Voice message support — send voice messages that are automatically transcribed and processed. See demo
remote-opencode is a Discord bot that bridges your local OpenCode CLI to Discord, enabling you to interact with your AI coding assistant remotely. Perfect for developers who want to:
- 📱 Code from mobile — Send coding tasks from your phone while away from your desk
- 💻 Access from any device — Use your powerful dev machine from a laptop or tablet
- 🌍 Work remotely — Control your home/office workstation from anywhere
- 👥 Collaborate — Share AI coding sessions with team members in Discord
- 🤖 Automated Workflows — Queue up multiple tasks and let the bot process them sequentially
- 🎤 Voice Messages — Send voice messages that are automatically transcribed and processed as text
How It Works
flowchart LR
A["📱 Your Phone / Other Device"] <-->|"Discord API"| B["🤖 Discord Bot"]
subgraph Workflow
direction TB
B --> C["💻 OpenCode CLI"]
C --> D["📁 Your Codebase"]
endThe bot runs on your development machine alongside OpenCode. When you send a command via Discord, it's forwarded to OpenCode, and the output streams back to you in real-time.
Demo
https://github.com/user-attachments/assets/b6239cb6-234e-41e2-a4d1-d4dd3e86c7b9
🎤 Voice Mode Demo
https://github.com/user-attachments/assets/59cf162a-ec86-41b5-a1f3-9b1379acd9fd
Table of Contents
- Installation
- Quick Start
- Proxy Support
- Discord Bot Setup
- CLI Commands
- Discord Slash Commands
- Usage Workflow
- Access Control
- Configuration
- Troubleshooting
- Development
- Changelog
- License
Installation
Prerequisites
- Node.js 22+ — Download
- OpenCode CLI — Must be installed and working on your machine
- Discord Account — With a server where you have admin permissions
Install via npm
# Global installation (recommended)
npm install -g remote-opencode
# Or run directly with npx
npx remote-opencodeInstall from source
git clone https://github.com/RoundTable02/remote-opencode.git
cd remote-opencode
npm install
npm run build
npm link # Makes 'remote-opencode' available globallyQuick Start
# Step 1: Run the interactive setup wizard
remote-opencode setup
# Step 2: Start the Discord bot
remote-opencode startThat's it! Now use Discord slash commands to interact with OpenCode.
Proxy Support
remote-opencode supports HTTP proxy environments for Discord and other external API requests.
Supported environment variables:
HTTP_PROXYHTTPS_PROXYALL_PROXYNO_PROXY
Proxy settings are applied app-wide. Local OpenCode traffic is kept direct automatically, so localhost, 127.0.0.1, and ::1 are always excluded from proxying.
Example
export HTTPS_PROXY=http://proxy.company.local:8080
export NO_PROXY=internal.company.local
remote-opencode startIf your network uses a single proxy for everything, ALL_PROXY is also supported:
export ALL_PROXY=http://proxy.company.local:8080
remote-opencode startDiscord Bot Setup
The setup wizard (remote-opencode setup) guides you through the entire process interactively:
- Opens Discord Developer Portal in your browser
- Walks you through creating an application, enabling intents, and getting your bot token
- Generates the invite link automatically and opens it in your browser
- Deploys slash commands to your server
Just run remote-opencode setup and follow the prompts — no manual URL copying needed!
If you prefer manual setup or need to troubleshoot:
- Create Application: Go to Discord Developer Portal, create a new application
- Enable Intents: In "Bot" section, enable SERVER MEMBERS INTENT and MESSAGE CONTENT INTENT
- Get Bot Token: In "Bot" section, reset/view token and copy it
- Get Guild ID: Enable Developer Mode in Discord settings, right-click your server → Copy Server ID
- Invite Bot: Use this URL format:
https://discord.com/api/oauth2/authorize?client_id=YOUR_CLIENT_ID&permissions=2147534848&scope=bot+applications.commands
CLI Commands
| Command | Description |
| --------------------------------------- | ---------------------------------------------------- |
| remote-opencode | Start the bot (shows setup guide if not configured) |
| remote-opencode setup | Interactive setup wizard — configures bot token, IDs |
| remote-opencode start | Start the Discord bot |
| remote-opencode deploy | Deploy/update slash commands to Discord |
| remote-opencode undeploy | Remove slash commands from Discord |
| remote-opencode config | Display current configuration info |
| remote-opencode allow add <userId> | Add a Discord user ID to the allowlist |
| remote-opencode allow remove <userId> | Remove a Discord user ID from the allowlist |
| remote-opencode allow list | List all user IDs in the allowlist |
| remote-opencode allow reset | Clear the entire allowlist (removes access control) |
| remote-opencode voice set <apiKey> | Set OpenAI API key for voice message transcription |
| remote-opencode voice remove | Remove the stored OpenAI API key |
| remote-opencode voice status | Show voice transcription status and API key source |
Discord Slash Commands
Once the bot is running, use these commands in your Discord server:
/setpath — Register a Project
Register a local project path with an alias for easy reference.
/setpath alias:myapp path:/Users/you/projects/my-app| Parameter | Description |
| --------- | ----------------------------------------------------- |
| alias | Short name for the project (e.g., myapp, backend) |
| path | Absolute path to the project on your machine |
/projects — List Registered Projects
View all registered project paths and their aliases.
/projects/use — Bind Project to Channel
Set which project a Discord channel should interact with.
/use alias:myappAfter binding, all /opencode commands in that channel will work on the specified project.
/opencode — Send Command to AI
The main command — sends a prompt to OpenCode and streams the response.
/opencode prompt:Add a dark mode toggle to the settings pageFeatures:
- 🧵 Auto-creates a thread for each conversation
- ⚡ Real-time streaming — see output as it's generated (1-second updates)
- ⏸️ Interrupt button — stop the current task if needed
- 📝 Session persistence — continue conversations in the same thread
/work — Create a Git Worktree
Start isolated work on a new branch with its own worktree.
/work branch:feature/dark-mode description:Implement dark mode toggle| Parameter | Description |
| ------------- | ----------------------------------- |
| branch | Git branch name (will be sanitized) |
| description | Brief description of the work |
Features:
- 🌳 Creates a new git worktree for isolated work
- 🧵 Opens a dedicated thread for the task
- 🗑️ Delete button — removes worktree and archives thread
- 🚀 Create PR button — automatically creates a pull request
This is perfect for working on multiple features simultaneously without branch switching.
/code — Toggle Passthrough Mode
Enable passthrough mode in a thread to send messages directly to OpenCode without slash commands.
/codeHow it works:
- Run
/codein any thread to enable passthrough mode - Type messages naturally — they're sent directly to OpenCode
- Run
/codeagain to disable
Example:
You: /code
Bot: ✅ Passthrough mode enabled for this thread.
Your messages will be sent directly to OpenCode.
You: Add a dark mode toggle to settings
Bot: 📌 Prompt: Add a dark mode toggle to settings
[streaming response...]
You: Now add a keyboard shortcut for it
Bot: 📌 Prompt: Now add a keyboard shortcut for it
[streaming response...]
You: /code
Bot: ❌ Passthrough mode disabled.Features:
- 📱 Mobile-friendly — no more typing slash commands on phone
- 🧵 Thread-scoped — only affects the specific thread, not the whole channel
- ⏳ Busy indicator — shows ⏳ reaction if previous task is still running
- 🔒 Safe — ignores bot messages (no infinite loops)
/autowork — Toggle Automatic Worktree Creation
Enable automatic worktree creation for a project. When enabled, new /opencode sessions will automatically create isolated git worktrees.
/autoworkHow it works:
- Run
/autoworkin a channel bound to a project - The setting toggles on/off for that project
- When enabled, new sessions automatically create worktrees with branch names like
auto/abc12345-1738600000000
Features:
- 🌳 Automatic isolation — each session gets its own branch and worktree
- 📱 Mobile-friendly — no need to type
/workwith branch names - 🗑️ Delete button — removes worktree when done
- 🚀 Create PR button — easily create pull requests from worktree
- ⚡ Per-project setting — enable/disable independently for each project
/queue — Manage Message Queue
Control the automated job queue for the current thread.
/queue list
/queue clear
/queue pause
/queue resume
/queue settings continue_on_failure:True fresh_context:FalseHow it works:
- Send multiple messages to a thread (or use
/opencodemultiple times) - If the bot is busy, it reacts with
📥and adds the task to the queue - Once the current job is done, the bot automatically picks up the next one
Settings:
continue_on_failure: IfTrue, the bot moves to the next task even if the current one fails.fresh_context: IfTrue, the AI forgets previous chat history for each new queued task, starting a fresh session while maintaining the same code state. Default:False(conversation context is preserved within the same thread).
/diff — View Git Diff
Show git diffs for the current project directly in Discord — perfect for reviewing AI-made changes from your phone.
/diff
/diff target:staged
/diff target:branch base:develop
/diff stat:true| Parameter | Description |
| --------- | ------------------------------------------------------------------ |
| target | unstaged (default), staged, or branch |
| stat | Show --stat summary only instead of full diff (default: false) |
| base | Base branch for target:branch diff (default: main) |
How it works:
- Inside a worktree thread → diffs the worktree path for that branch
- In a regular channel → diffs the channel-bound project path
- Output is formatted in a
diffcode block (truncated if over Discord's 2000-char limit)
Examples:
/diff → unstaged changes (git diff)
/diff target:staged → staged changes (git diff --cached)
/diff target:branch → changes vs main (git diff main...HEAD)
/diff target:branch base:dev → changes vs dev branch
/diff stat:true → summary only (git diff --stat)/allow — Manage Allowlist
Manage the user allowlist directly from Discord. This command is only available when the allowlist has already been initialized (at least one user exists).
/allow action:add user:@username
/allow action:remove user:@username
/allow action:list| Parameter | Description |
| --------- | --------------------------------------------- |
| action | add, remove, or list |
| user | Target user (required for add and remove) |
Behavior:
- Requires authorization — only users already on the allowlist can use this command
- Cannot remove last user — prevents accidental lockout
- Disabled when allowlist is empty — initial setup must be done via CLI or setup wizard (see Access Control)
/voice — Manage Voice Transcription
Manage voice message transcription settings. Requires an OpenAI API key (set via CLI).
/voice status Show voice transcription status
/voice remove Remove the stored OpenAI API key| Parameter | Description |
| --------- | ----------------------------------------- |
| (none) | Subcommands only: status, remove |
How it works:
- Set your OpenAI API key via CLI:
remote-opencode voice set <apiKey> - Enable passthrough mode in a thread with
/code - Send a voice message using Discord's 🎤 button
- The bot adds a 🎙️ reaction, transcribes the audio via OpenAI Whisper, and processes it as a text prompt
- If the bot is busy, voice messages are queued (with 📥 reaction) and transcribed when dequeued
Note: The
setsubcommand is intentionally CLI-only to avoid API key exposure in Discord command history.
/model — List & Set AI Model
View available AI models or set the model for the current channel.
/model list
/model set name:anthropic/claude-sonnet-4-20250514| Subcommand | Description |
| ---------- | ------------------------------------------------- |
| list | Show all available models grouped by provider |
| set | Set the AI model for the current channel/thread |
Features:
- 🔍 Autocomplete — start typing a model name and get instant suggestions
- 📋 Full model list — all models are shown with automatic message splitting when output exceeds Discord's limit
- 💾 Per-channel persistence — model preferences are saved per channel/thread
- ⚡ Fast validation — model names are validated against a background-cached list (no blocking CLI calls)
/session — Browse & Manage Sessions
Browse OpenCode CLI sessions and manage session-thread mappings. Useful for resuming previous conversations or sharing sessions across threads.
/session list
/session attach
/session detach
/session info| Subcommand | Description |
| ---------- | ------------------------------------------------------------ |
| list | List all sessions for the current project (active + mapped) |
| attach | Attach an existing session to this thread (interactive menu) |
| detach | Disconnect the session from this thread |
| info | Show detailed status of the attached session |
How it works:
- Use
/session listto see all sessions for the bound project - In a thread, use
/session attach→ select a session from the dropdown - The thread now continues that session's conversation (with
freshContextautomatically disabled) - Use
/session infoto check if the session is alive, see its port, creation time, etc. - Use
/session detachto disconnect and start fresh
Features:
- 📋 Merged view — combines active server sessions with persisted thread mappings
- 🔗 Interactive attach — dropdown menu shows session title, ID, mapping status, and recency
- ⚠️ Cross-thread warning — notifies when attaching a session already used in another thread
- 📊 Rich info embed — session status, port, SSE state, timestamps in a clean embed
- 🧹 Clean detach — properly disconnects SSE and clears session mapping
Usage Workflow
Basic Workflow
Register your project:
/setpath alias:webapp path:/home/user/my-webappBind to a channel:
/use alias:webappStart coding remotely:
/opencode prompt:Refactor the authentication module to use JWTContinue the conversation in the created thread:
/opencode prompt:Now add refresh token support
Mobile Workflow
Perfect for when you're away from your desk:
- 📱 Open Discord on your phone
- Navigate to your bound channel
- Use
/opencodeto send tasks - Watch real-time progress
- Use the Interrupt button if needed
Pro tip: Enable passthrough mode with /code in a thread for an even smoother mobile experience — just type messages directly without slash commands! You can also send voice messages via the 🎤 button — they're automatically transcribed and processed as text.
Team Collaboration Workflow
Share AI coding sessions with your team:
- Create a dedicated Discord channel for your project
- Bind the project:
/use alias:team-project - Team members can watch sessions in real-time
- Discuss in threads while AI works
Automated Iteration Workflow
Perfect for "setting and forgetting" several tasks:
Send multiple instructions:
You: Refactor the API Bot: [Starts working] You: Add documentation to the new methods Bot: 📥 [Queued] You: Run tests and fix any issues Bot: 📥 [Queued]The bot will finish the API refactor, then automatically start the documentation task, then run the tests.
Monitor progress: Use
/queue listto see pending tasks.
Access Control
remote-opencode supports an optional user allowlist to restrict who can interact with the bot. This is essential when your bot runs in a shared Discord server where untrusted users could otherwise execute commands on your machine.
How It Works
- No allowlist configured (default): All Discord users in the server can use the bot. This preserves backward compatibility for existing installations.
- Allowlist configured (1+ user IDs): Only users whose Discord IDs are in the allowlist can use slash commands, buttons, and passthrough messages. Unauthorized users receive a rejection message.
Setting Up Access Control
⚠️ SECURITY WARNING: If your bot operates in a Discord channel accessible to untrusted users, you MUST configure the allowlist before starting the bot. The initial allowlist setup can ONLY be done via the CLI or the setup wizard — NOT from Discord. This prevents unauthorized users from adding themselves to an empty allowlist.
Option 1: Setup Wizard (Recommended for first-time setup)
remote-opencode setupStep 5 of the wizard prompts you to enter your Discord user ID. This becomes the first entry in the allowlist.
Option 2: CLI
# Add your Discord user ID
remote-opencode allow add 123456789012345678
# Verify
remote-opencode allow listManaging the Allowlist
Once at least one user is on the allowlist, authorized users can manage it from Discord:
/allow action:add user:@teammate
/allow action:remove user:@teammate
/allow action:listOr via CLI at any time:
remote-opencode allow add <userId>
remote-opencode allow remove <userId>
remote-opencode allow list
remote-opencode allow reset # Clears entire allowlist (disables access control)Safety Guardrails
- Cannot remove the last user via Discord
/allowor CLIallow remove— prevents accidental lockout allow resetis the only way to fully clear the allowlist (intentional action to disable access control)- Discord
/allowis disabled when allowlist is empty — prevents bootstrap attacks - Config file permissions are set to
0o600(owner-read/write only)
Configuration
All configuration is stored in ~/.remote-opencode/:
| File | Purpose |
| ------------- | --------------------------------------------- |
| config.json | Bot credentials (token, client ID, guild ID) |
| data.json | Project paths, channel bindings, session data |
config.json Structure
{
"discordToken": "your-bot-token",
"clientId": "your-application-id",
"guildId": "your-server-id",
"allowedUserIds": ["123456789012345678"],
"openaiApiKey": "sk-..."
}
allowedUserIdsis optional. When omitted or empty, access control is disabled and all users can use the bot.openaiApiKeyis optional. When omitted, voice message transcription is disabled. Can also be set viaOPENAI_API_KEYenvironment variable (takes priority).
data.json Structure
{
"projects": [
{ "alias": "myapp", "path": "/Users/you/projects/my-app", "autoWorktree": true }
],
"bindings": [
{ "channelId": "channel-id", "projectAlias": "myapp" }
],
"threadSessions": [ ... ],
"worktreeMappings": [ ... ]
}| Field | Description |
| ------------------------- | --------------------------------------------------------- |
| projects[].autoWorktree | Optional. When true, new sessions auto-create worktrees |
Troubleshooting
Bot doesn't respond to commands
- Check bot is online: Look for the bot in your server's member list
- Verify permissions: Bot needs these permissions:
- Send Messages
- Create Public Threads
- Send Messages in Threads
- Embed Links
- Read Message History
- Redeploy commands:
remote-opencode deploy
"No project set for this channel"
You need to bind a project to the channel:
/setpath alias:myproject path:/path/to/project
/use alias:myprojectCommands not appearing in Discord
Slash commands can take up to an hour to propagate globally. For faster updates:
- Kick the bot from your server
- Re-invite it
- Run
remote-opencode deploy
OpenCode server errors
- Verify OpenCode is installed:
opencode --version - Check if another process is using the port
- Ensure the project path exists and is accessible
Session connection issues
The bot maintains persistent sessions. If you encounter issues:
- Start a new thread with
/opencodeinstead of continuing in an old one - Restart the bot:
remote-opencode start
Bot crashes on startup
- Check Node.js version:
node --version # Should be 22+ - Verify configuration:
remote-opencode config - Re-run setup:
remote-opencode setup
Proxy environments still fail
- Confirm
HTTP_PROXY,HTTPS_PROXY, orALL_PROXYis set in the same shell where you start the bot - Check whether a custom
NO_PROXYvalue is excluding a required remote host - Leave loopback traffic direct; the bot already auto-adds
localhost,127.0.0.1, and::1
Development
Run from source
git clone https://github.com/RoundTable02/remote-opencode.git
cd remote-opencode
npm install
# Development mode (with ts-node)
npm run dev setup # Run setup
npm run dev start # Start bot
# Build and run production
npm run build
npm startRun tests
npm testProject Structure
src/
├── cli.ts # CLI entry point
├── bot.ts # Discord client initialization
├── commands/ # Slash command definitions
│ ├── opencode.ts # Main AI interaction command
│ ├── code.ts # Passthrough mode toggle
│ ├── work.ts # Worktree management
│ ├── diff.ts # Git diff viewer
│ ├── model.ts # AI model list/set with autocomplete
│ ├── session.ts # Session browsing and management
│ ├── allow.ts # Allowlist management
│ ├── voice.ts # Voice transcription settings
│ ├── setpath.ts # Project registration
│ ├── projects.ts # List projects
│ └── use.ts # Channel binding
├── handlers/ # Interaction handlers
│ ├── interactionHandler.ts
│ ├── buttonHandler.ts
│ └── messageHandler.ts # Passthrough + voice message handling
├── services/ # Core business logic
│ ├── serveManager.ts # OpenCode process management
│ ├── sessionManager.ts # Session state management
│ ├── queueManager.ts # Automated job queuing (incl. voice)
│ ├── executionService.ts # Core prompt execution logic
│ ├── voiceService.ts # Voice message STT (OpenAI Whisper)
│ ├── sseClient.ts # Real-time event streaming
│ ├── dataStore.ts # Persistent storage
│ ├── configStore.ts # Bot configuration
│ └── worktreeManager.ts # Git worktree operations
├── setup/ # Setup wizard
│ ├── wizard.ts # Interactive setup (incl. voice opt-in)
│ └── deploy.ts # Command deployment
└── utils/ # Utilities
├── messageFormatter.ts
└── threadHelper.tsChangelog
See CHANGELOG.md for a full history of changes.
[1.5.1] - 2026-03-24
Added
- Proxy Support: HTTP proxy environments for Discord requests via
HTTP_PROXY,HTTPS_PROXY,ALL_PROXY, andNO_PROXY. Local OpenCode traffic is automatically excluded.
Fixed
- Shell Spawn Removed: OpenCode is now launched directly instead of through a shell, fixing service-environment failures.
- Silent Error Swallowing: Discord message edit failures now fall back to sending new messages instead of silently dropping AI responses.
- Model Provider Prefix:
/model setno longer strips the provider prefix, fixing "Model not found" errors. Carriage returns in model names are now sanitized.
[1.5.0] - 2026-03-16
Added
/sessionCommand: Browse, attach, detach, and inspect OpenCode CLI sessions from Discord — resume previous conversations or share sessions across threads.- Model Autocomplete:
/model setnow suggests model names as you type. - Full Model List:
/model listshows all available models without per-provider caps.
Changed
- Model validation now uses a fast in-memory cache instead of blocking CLI calls.
[1.4.0] - 2026-03-10
Added
- Voice Message Transcription: Send voice messages in
/codepassthrough threads — automatically transcribed via OpenAI Whisper and processed as text prompts. /voiceSlash Command: Check status and manage voice transcription settings from Discord.- CLI Voice Management:
remote-opencode voice set|remove|statuscommands for managing the OpenAI API key. - Setup Wizard Integration: Optional step to configure voice transcription during initial setup.
[1.3.0] - 2026-03-02
Added
/diffCommand: View git diffs directly from Discord — ideal for reviewing AI-made changes on mobile.
[1.2.0] - 2026-02-15
Added
- Owner/Admin Authentication: User allowlist system to restrict bot access to authorized Discord users only.
/allowSlash Command: Manage the allowlist directly from Discord (add, remove, list users).- CLI Allowlist Management:
remote-opencode allow add|remove|list|resetcommands for managing access control from the terminal. - Setup Wizard Integration: Step 5 prompts for owner Discord user ID during initial setup.
Security
- Initial allowlist setup is restricted to CLI and setup wizard only — prevents bootstrap attacks from Discord.
- Config file permissions hardened to
0o600(owner-read/write only). - Discord user ID validation enforces snowflake format (
/^\d{17,20}$/). - Cannot remove the last authorized user via Discord or CLI
remove— prevents lockout.
[1.1.0] - 2026-02-05
Added
- Automated Message Queuing: Added a new system to queue multiple prompts in a thread. If the bot is busy, new messages are automatically queued and processed sequentially.
- Queue Management: New
/queueslash command suite to list, clear, pause, resume, and configure queue settings.
[1.0.10] - 2026-02-04
Added
- New
/setportsslash command to configure the port range for OpenCode server instances.
Fixed
- Fixed Windows-specific spawning issue (targeting
opencode.cmd). - Resolved
spawn EINVALerrors on Windows. - Improved server reliability and suppressed
DEP0190security warnings.
[1.0.9] - 2026-02-04
Added
- New
/modelslash command to set AI models per channel. - Support for
--modelflag in OpenCode server instances.
Fixed
- Fixed connection timeout issues.
- Standardized internal communication to use
127.0.0.1.
License
MIT
Contributing
Contributions are welcome! Please read our Contributing Guide before submitting a Pull Request.
