Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Queuebird 🐦

Private, restricted remote control for YouTube Music in your browser.

Let AI agents safely select, queue, and catalog the music you play.

Queuebird lets a local application or automation agent control YouTube Music without exposing Chrome DevTools Protocol, accepting arbitrary JavaScript, or navigating the browser between track URLs.

It consists of:

  • Queuebird Server — a small authenticated Docker service that stores commands, playback state, sessions, and optional playback events in SQLite.
  • Queuebird Extension — a Chrome Manifest V3 extension restricted to music.youtube.com. It polls the server and performs a fixed allowlist of native player and queue operations.
CLI / agent / application
          │ authenticated HTTP
          ▼
   Queuebird Server
          │ bounded commands
          ▼
 Queuebird Extension
          │ native YouTube Music UI
          ▼
    YouTube Music

Once tracks have been placed in YouTube Music's native queue, playback no longer depends on the controlling application remaining online.

Why Queuebird?

General browser automation is powerful, but it is an unnecessarily broad security boundary for changing a song. Queuebird exposes only these operations:

  • play a specific track
  • append a track or ordered micro-playlist
  • pause or resume
  • skip
  • clear or replace the managed queue
  • read bounded playback and queue state

There is no endpoint for executing code, choosing selectors, reading cookies, or controlling other sites. Managed track changes use YouTube Music's SPA and native queue rather than location.assign, avoiding page departures and “Leave site?” prompts.

Status

Queuebird is an early public release extracted from a working private system. The controller has extensive unit coverage, but YouTube Music's private DOM is not a stable API and may change without notice. Use it as experimental self-hosted software, not as a safety-critical playback service.

Queuebird is not affiliated with or endorsed by Google or YouTube.

Quick start

1. Start the server

Requirements: Docker with Compose.

git clone https://github.com/Empathos/queuebird.git
cd queuebird
cp .env.example .env
# Set QUEUEBIRD_API_KEY to the same long random secret used in the extension.
docker compose up --build -d
curl http://127.0.0.1:8080/healthz

The server listens only on 127.0.0.1:8080 by default and stores durable data in the queuebird-data Docker volume.

2. Build and install the extension

Requirements: Node.js 20+ and Chromium/Chrome with Manifest V3 support.

cd extension
npm ci
npm run typecheck
npm run test:unit
npm run build

Open chrome://extensions, enable Developer mode, choose Load unpacked, and select extension/dist.

Open Queuebird's options page and configure:

  • Collector URL: http://127.0.0.1:8080
  • Device ID: queuebird-browser
  • API key: the value from .env

Then open YouTube Music in the same browser profile, sign in, and leave the tab open. The tab need not remain focused, but the browser may require one manual play action before it permits unattended audio playback.

3. Submit a playlist

export QUEUEBIRD_API_KEY='your-secret'

curl -X POST http://127.0.0.1:8080/v1/music-control/commands \
  -H "X-API-Key: $QUEUEBIRD_API_KEY" \
  -H 'X-Device-ID: queuebird-browser' \
  -H 'Content-Type: application/json' \
  -d '{
    "action": "replace_queue",
    "items": [
      {
        "url": "https://music.youtube.com/watch?v=dQw4w9WgXcQ",
        "title": "Never Gonna Give You Up",
        "artist": "Rick Astley"
      }
    ],
    "session": {
      "id": "demo-1",
      "name": "First Queuebird session",
      "mood": "upbeat",
      "criteria": "demo"
    }
  }'

The extension polls for the command, resolves tracks through native YouTube Music controls, and acknowledges only after the page verifies the result. The POST returns {"accepted":true,"command_id":1}; acceptance means the server stored the command, not yet that the browser executed it.

Verify browser-reported state:

curl http://127.0.0.1:8080/v1/music-control/state \
  -H "X-API-Key: $QUEUEBIRD_API_KEY" \
  -H 'X-Device-ID: queuebird-browser'

API overview

All /v1/* routes require X-API-Key. Command, state, and event routes use X-Device-ID for routing; it is not an additional authentication factor.

Method Path Purpose
GET /healthz Liveness check
POST /v1/music-control/commands Submit an allowlisted command
GET /v1/music-control/commands?after=N Poll durable commands
POST /v1/music-control/state Report bounded player state
GET /v1/music-control/state Read latest player state
GET /v1/music-sensor/time Clock synchronization
POST /v1/music-events/batch Optional playback-event archive

Interactive OpenAPI documentation is available at http://127.0.0.1:8080/docs while the server is running.

Command shapes

  • {"action":"play","video_id":"…","title":"…","artist":"…"}
  • {"action":"enqueue","video_id":"…","title":"…","artist":"…"}
  • {"action":"pause"}, {"action":"resume"}, or {"action":"skip"}
  • {"action":"clear_queue"}
  • replace_queue uses the full example above and accepts 1–20 items.

A device ID is created implicitly and must contain only letters, numbers, periods, underscores, or hyphens (maximum 64 characters). Each browser profile should use a distinct ID. Commands are durable in SQLite and monotonically numbered; the extension persists its last cursor and requests only newer commands. Queue operations are acknowledged after observed page state, retried within bounded limits, and aborted rather than silently appended out of order.

replace_queue manages Queuebird's requested session; it does not promise to erase unrelated entries already present in YouTube Music's native queue. Native-queue cleanup and deduplication remain roadmap items.

Security model

Queuebird's central design constraint is least authority:

  • fixed command allowlist; no arbitrary browser operations
  • extension host permission limited to YouTube Music and loopback collectors
  • API credential retained in trusted extension storage
  • content script cannot read the credential or choose a network destination
  • no CDP, remote-debugging port, eval, external scripts, or general page API
  • server bound to loopback in the supplied Compose configuration

See SECURITY.md before changing the network boundary.

The supplied extension intentionally accepts loopback collector URLs only. Running Chrome and Docker on different hosts therefore requires an audited extension policy change in addition to TLS and network authentication.

Troubleshooting

  1. Confirm curl http://127.0.0.1:8080/healthz returns {"ok":true}.
  2. Open the extension popup and confirm the sensor is attached and delivery is healthy.
  3. Confirm the API key, collector URL, and device ID match the server command.
  4. Keep one signed-in YouTube Music tab open and manually start playback once.
  5. Inspect docker compose logs queuebird and the state endpoint above.

If Docker runs in a VM, container host, or another machine, its loopback is not the browser host's loopback; that topology is outside the secure default.

Repository layout

extension/       Manifest V3 extension, tests, and build scripts
server/          FastAPI + SQLite command broker
docker-compose.yml
SECURITY.md

Development

cd extension
npm ci
npm run typecheck
npm run test:unit
npm run build

cd ../server
python -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
QUEUEBIRD_API_KEY=development-only QUEUEBIRD_DB=/tmp/queuebird.db \
  uvicorn app.main:app --reload

The source-level navigation guard prevents managed URL navigation from being reintroduced. Browser integration tests require a Chromium build that supports --load-extension; set CHROME_PATH if it is not discovered automatically.

Roadmap

  • clean native-queue deduplication and removal
  • WebSocket command delivery alongside polling
  • signed extension releases and Chrome Web Store packaging
  • CLI and OpenClaw/Home Assistant adapters
  • additional music services through separate site-restricted controllers

Contributing

Issues and focused pull requests are welcome. Please include tests for changes to the controller, command validation, or security boundary. Do not add generic browser-evaluation or selector-control endpoints.

License

MIT © 2026 Empathos

About

Private, restricted remote control for YouTube Music. Let AI agents safely select, queue, and catalog the music you play.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages