Skip to content

balianbaleno/cursor-remote

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cursor-remote 🎮

Control Cursor IDE from anywhere — Telegram, Slack, Discord, AI

Send prompts, get screenshots, manage your AI coding sessions from your phone or any device.

macOS Python 3.9+ License: MIT

Architecture

┌─────────────────────────────────────────────────────────┐
│                    INTERFACES                           │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌─────────┐ │
│  │ Telegram │  │  Slack   │  │ Discord  │  │   AI    │ │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬────┘ │
│       │             │             │             │       │
│       └─────────────┴──────┬──────┴─────────────┘       │
│                            ▼                            │
│              ┌─────────────────────────┐                │
│              │   CORE (WebSocket)      │                │
│              │   ws://localhost:9876   │                │
│              └────────────┬────────────┘                │
│                           ▼                             │
│              ┌─────────────────────────┐                │
│              │   CursorController      │                │
│              │   (AppleScript)         │                │
│              └────────────┬────────────┘                │
│                           ▼                             │
│              ┌─────────────────────────┐                │
│              │      Cursor IDE         │                │
│              └─────────────────────────┘                │
└─────────────────────────────────────────────────────────┘

Quick Start (5 minutes)

1. Clone & Install

git clone https://github.com/ivanpasichnyk/cursor-remote.git
cd cursor-remote
pip install websockets python-telegram-bot

2. Create Telegram Bot

  1. Open Telegram, message @BotFather
  2. Send /newbot, follow instructions
  3. Copy the bot token (looks like 123456789:ABCdefGHI...)

3. Get Your Telegram ID

  1. Message @userinfobot on Telegram
  2. Copy your numeric ID (looks like 394755411)

4. Configure

cp env.example .env

Edit .env:

TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrsTUVwxyz
ALLOWED_USER_ID=394755411

5. Grant Accessibility Permissions (IMPORTANT!)

The bot uses AppleScript to control Cursor. macOS requires permission:

  1. Open System SettingsPrivacy & SecurityAccessibility
  2. Click + and add Terminal (or your terminal app)

⚠️ Without this, the bot will connect but can't control Cursor!

6. Run

# Make sure Cursor IDE is open!
python examples/run_telegram.py

7. Test!

Open your bot in Telegram:

  • /help — see all commands
  • /screen — take screenshot
  • /mode — toggle Agent/Ask mode
  • Send any text — it goes to Cursor AI

Commands

Command Description
/screen Take screenshot
/up / /down Scroll up/down + screenshot
/accept Accept (Cmd+Enter)
/reject Reject (Cmd+Backspace)
/stop Stop (Escape)
/enter Press Enter
/mode Toggle mode (Cmd+.)
/lang Switch keyboard layout (Cmd+Space x2)
/ai AI model selector
/file <path> Open file
/run <cmd> Run shell command
/terminal <cmd> Run in IDE terminal
<any text> Send as prompt

How It Works (Technical Details)

AppleScript Key Codes

The bot uses AppleScript to simulate keyboard input. Key codes used:

Key Code Notes
Arrow Up 126 Used for scrolling (10 presses = 1 page)
Arrow Down 125 Used for scrolling
Enter 36 Submit prompts
Escape 53 Stop AI generation
Backspace 51 Reject with Cmd
Space 49 Used with Cmd for language switch
Period 47 Mode switch (Cmd+.)
Slash 44 AI selector (Cmd+/)

Keyboard Layout Switching

The /lang command uses Cmd+Space twice:

  1. First press opens the language selector menu
  2. Second press (after 0.5s delay) switches to next language

This is required because macOS Cmd+Space first shows a menu, then cycles through layouts.

Scroll Implementation

Scrolling uses Arrow Keys (not Page Up/Down) because:

  • Arrow keys work reliably in all contexts (editor, chat, panels)
  • Page Up/Down may not work in focused text areas
  • 10 arrow key presses ≈ 1 page of content

Project Structure

cursor-remote/
├── cursor_core/           # Core module (WebSocket server)
│   ├── controller.py      # AppleScript commands
│   ├── server.py          # WebSocket server
│   ├── protocol.py        # JSON message format
│   └── keybindings.json   # Cursor/VSCode keyboard shortcuts
├── interfaces/            # External interfaces
│   └── telegram/          # Telegram bot
│       └── bot.py
├── examples/
│   └── run_telegram.py    # Launcher script
├── README.md
├── requirements.txt
└── env.example

Keybindings Reference

cursor_core/keybindings.json contains Cursor IDE keyboard shortcuts.

Use cases:

  • Voice commands → translate to keyboard actions
  • AI reasoning → plan complex actions from natural language
  • Future: LLM-based controller that maps "open settings" → Cmd+,

Example:

{ "key": "cmd+p", "command": "workbench.action.quickOpen" }
{ "key": "cmd+i", "command": "composer.startComposerPrompt" }
{ "key": "cmd+.", "command": "composer.cycleMode" }

WebSocket Protocol

Interfaces communicate with Core via JSON over WebSocket:

Request:

{"action": "screenshot"}
{"action": "send_prompt", "params": {"text": "Hello"}}
{"action": "switch_mode"}

Response:

{"success": true, "message": "Screenshot taken", "data": {"path": "/tmp/screen.png"}}
{"success": false, "message": "Error message"}

Adding New Interfaces

  1. Create interfaces/your_interface/bot.py
  2. Connect to ws://localhost:9876
  3. Send JSON commands, receive JSON responses
  4. Handle responses in your interface

Example (Python):

import websockets
import json

async with websockets.connect("ws://localhost:9876") as ws:
    # Take screenshot
    await ws.send(json.dumps({"action": "screenshot"}))
    response = json.loads(await ws.recv())
    print(response)  # {"success": true, "data": {"path": "/tmp/..."}}

Requirements

  • macOS only — Uses AppleScript for IDE control
  • Accessibility permissions — Grant to Terminal/Python
  • Cursor or VSCode — Must be running
  • Python 3.9+

Dependencies

websockets>=12.0
python-telegram-bot>=20.0

Running the Bot

Manual Start

cd cursor-remote
TELEGRAM_BOT_TOKEN=your_token ALLOWED_USER_ID=your_id python3 examples/run_telegram.py

Or with .env file:

export $(grep -v '^#' .env | xargs) && python3 examples/run_telegram.py

Auto-Start on Login (macOS launchd)

Create ~/Library/LaunchAgents/com.cursor-remote.plist:

<?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>Label</key>
    <string>com.cursor-remote</string>

    <key>ProgramArguments</key>
    <array>
      <string>/usr/bin/python3</string>
      <string>/path/to/cursor-remote/examples/run_telegram.py</string>
    </array>

    <key>EnvironmentVariables</key>
    <dict>
      <key>TELEGRAM_BOT_TOKEN</key>
      <string>your_bot_token</string>
      <key>ALLOWED_USER_ID</key>
      <string>your_telegram_id</string>
    </dict>

    <key>RunAtLoad</key>
    <true/>

    <key>KeepAlive</key>
    <true/>

    <key>StandardOutPath</key>
    <string>/tmp/cursor_remote.out</string>
    <key>StandardErrorPath</key>
    <string>/tmp/cursor_remote.err</string>

    <key>WorkingDirectory</key>
    <string>/path/to/cursor-remote</string>
  </dict>
</plist>

Load and start:

launchctl load ~/Library/LaunchAgents/com.cursor-remote.plist

Stop:

launchctl unload ~/Library/LaunchAgents/com.cursor-remote.plist

Check logs:

tail -f /tmp/cursor_remote.err

Troubleshooting

Bot conflict error (terminated by other getUpdates):

pkill -f run_telegram.py
# Then restart

Check if running:

ps aux | grep run_telegram

Commands not working (no response from Cursor):

  1. Check Accessibility permissions:
    • System Settings → Privacy & Security → Accessibility
    • Ensure Terminal/Python is in the list
  2. Check Cursor is in foreground:
    • The bot activates Cursor before each command
    • If another app takes focus during the command, it may fail

Scroll buttons not working:

  • Scroll uses Arrow Keys (key codes 126/125), not Page Up/Down
  • If still not working, check if Cursor is focused on the correct panel
  • Try clicking inside the Cursor window first

Language switch (/lang) not working:

  • Uses Cmd+Space twice with 0.5s delay
  • First press opens language menu, second press switches
  • If your Mac uses Ctrl+Space or another shortcut, modify controller.py

Timeout errors:

  • Increase timeout parameter in _run_applescript() (default: 30s)
  • Check if Cursor is frozen or very slow
  • WebSocket connection may have dropped — restart the bot

Security

  • Whitelist users — Only specified user IDs can control the bot
  • Command blacklist — Dangerous commands like rm -rf / are blocked
  • Local only — Core runs on localhost, no external access

License

MIT — use it however you want.

Credits

Built by Ivan Pasichnyk


⭐ Star this repo if you find it useful!

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages