Use GitHub Copilot from your phone by chatting in Discord.
You run this bot on a server/PC (home lab, VM, cloud box) that has:
- GitHub Copilot CLI + authentication
- Your repos under a configured root folder (
Bot:ReposRoot)
Then you use Discord mobile to:
- Create a session (Discord thread)
- Pick a repo with reactions (1️⃣..🔟)
- Approve/deny tool actions with reactions (👍/👎)
- Watch a single “CLI panel” status message update in-place
Video: media/copilot-discord-bot.mp4
- Emoji-first UX: threads + reactions work great on mobile.
- Single status panel: no spam; one message edits in-place.
- Repo sandbox: agent work is scoped under
Bot:ReposRoot. - Interactive approvals: prompts show what’s being approved.
- Set
Bot:OwnerDiscordUserId(recommended). If set, the bot ignores everyone else. - Keep
Bot:ReposRoottight. The bot should only see repos you want it to touch. - Keep approvals on (
cp approve ask) unless you fully trust your tools + repos. - Optional:
Bot:AutoApproveReadPermissions=truereduces prompt spam for read-only actions.
- .NET 10 (SDK or runtime)
- Verify:
dotnet --versionshould be10.x
- Verify:
- GitHub Copilot CLI installed on the server and authenticated
- Verify:
copilot --version(should not prompt) - Authenticate (interactive): run
copilotonce and complete sign-in - Authenticate (service-friendly): set
GH_TOKEN/COPILOT_GITHUB_TOKEN
- Verify:
- A Discord application + bot token
In the Discord Developer Portal:
- Create an Application
- Create a Bot and copy the token
- Enable Privileged Gateway Intents:
- Message Content Intent (required)
- Invite the bot to your server (OAuth2 → URL Generator):
- Scopes:
bot - Permissions (minimum recommended):
- View Channels
- Send Messages
- Read Message History
- Create Public Threads
- Send Messages in Threads
- Add Reactions
- Use External Emojis (optional)
- Scopes:
You can put defaults in src/CopilotDiscordBot/appsettings.json, but for production it’s recommended to use environment variables (especially when running as a service).
Required settings:
Bot:DiscordBotToken– your bot tokenBot:OwnerDiscordUserId– your Discord user id (recommended)Bot:ReposRoot– root folder containing repos (example:e:\\Git)
Environment variable equivalents:
Bot__DiscordBotTokenBot__OwnerDiscordUserIdBot__ReposRootBot__DataDir(recommended to set to an absolute path when running as a service)
Dev-friendly option (user-secrets), from repo root:
dotnet user-secrets set "Bot:DiscordBotToken" "YOUR_TOKEN" --project src/CopilotDiscordBot/CopilotDiscordBot.csprojdotnet user-secrets set "Bot:OwnerDiscordUserId" "123456789012345678" --project src/CopilotDiscordBot/CopilotDiscordBot.csprojdotnet user-secrets set "Bot:ReposRoot" "e:\\Git" --project src/CopilotDiscordBot/CopilotDiscordBot.csproj
From repo root:
dotnet run -c Release --project src/CopilotDiscordBot/CopilotDiscordBot.csproj
Health endpoint:
http://localhost:5000/health
These scripts publish the app, set environment variables, and register an always-on service.
Run from an elevated PowerShell:
powershell -ExecutionPolicy Bypass -File .\\scripts\\install-service-windows.ps1
Common options:
-ReposRoot "E:\\Git"-OwnerDiscordUserId 123456789012345678-GhToken "..."(recommended for services)-CopilotCliPath "C:\\Path\\to\\copilot.exe"
Uninstall:
powershell -ExecutionPolicy Bypass -File .\\scripts\\uninstall-service-windows.ps1
Make scripts executable and run with sudo:
chmod +x scripts/*.shsudo ./scripts/install-service-linux.sh --user <username> --repos-root /path/to/repos
The installer writes an env file at /etc/copilot-discord-bot.env (mode 600) and creates a systemd unit.
Uninstall:
sudo ./scripts/uninstall-service-linux.sh --remove-env
In any normal text channel:
cp new my-session
The bot creates a thread (that thread is the session) and posts a repo picker.
In the session thread:
- React with 1️⃣..🔟 on the repo picker message.
Fallback: cp repo <path>
Just send normal messages in the thread.
You’ll see a single status panel updated in-place (state/repo/model/doing).
In the session thread:
cp model(shows current)cp model gpt-5.2(sets for this session)
When Copilot requests permission, the bot posts a prompt message.
- React 👍 to approve
- React 👎 to deny
This usually means the copilot process exited immediately (often because PATH resolved to a VS Code shim that prints an interactive install prompt).
- Run
where copilot(Windows) and verify it points to the winget-installedcopilot.exe - Run
copilot --versionin the same shell you launch the bot from - If it prompts to install/reinstall, restart your terminal (PATH update) and try again
- If it still points to the shim, set
Bot:CopilotCliPathto the fullcopilot.exepath
The Copilot SDK is preview and permission payload fields can vary. You can temporarily enable:
Bot:DebugPermissionPayload=true
This adds a redacted debug panel to permission prompts.
cp approve ask(recommended)cp approve always
Enable the GitHub MCP server for a session:
cp config set {"model":"gpt-5.2","mcpServers":{"github":{"type":"http","url":"https://api.githubcopilot.com/mcp/","tools":["*"]}}}


