Files
Veskslop/poc/README.md
T

3.6 KiB
Raw Blame History

Veskslop Phase 0 spikes

Timeboxed proof-of-concept scripts, not production code. Project direction lives in ../AGENTS.md.

Setup

pnpm install

Current query policy

  • Every command sent to the client is spaced by a random 500–2800 ms and serialized through one queue (src/pacing.ts).
  • Identical concurrent reads are coalesced (dedupe), and state reads are cache-only.
  • DEBUG=1 logs every command and its delay.

Spikes

0. QR login / token acquisition — src/qr-login.ts

pnpm poc:qr
TOKEN_FILE=/path/to/token DEBUG=1 pnpm poc:qr

Connects to wss://remote-auth-gateway.discord.gg/?v=2, renders the approval QR directly in the terminal, waits for a phone scan, exchanges the login ticket and writes the token to poc/.token (mode 600, gitignored; override with TOKEN_FILE). No existing token required. If Discord responds with an hCaptcha challenge, the script prints the challenge and prompts for a HCAPTCHA_KEY (or takes it from the environment).

1. Vesktop control bridge — src/control-bridge.ts

The MCP daemon. Exposes Streamable HTTP and forwards tool calls over the JSON-lines protocol on Vesktop's control socket (default $XDG_RUNTIME_DIR/vesktop.sock, override with VESKSLOP_SOCKET).

pnpm control:bridge                 # http://127.0.0.1:8788/mcp
VESKSLOP_SOCKET=... MCP_PORT=... pnpm control:bridge

Tools: get_state (cache-only), send_message, read_messages (coalesced), send_dm.

Vesktop side lives in this repo:

  • src/main/ipcSocket.ts — parses JSON lines { id, command, data } and forwards them through sendRendererCommand.
  • src/renderer/ipcCommands.ts — handlers that use official client interactions (sendMessage, openPrivateChannel, guild/channel/message stores).

Protocol commands: ping, state:get, message:send, message:read, dm:send.

2. Mock Vesktop — src/mock-vesktop.ts

VESKSLOP_SOCKET=/tmp/veskslop-mock.sock pnpm control:mock

Stands in for the real Vesktop process so the bridge can be developed without Electron/Xvfb.

3. Live DM test — src/test-dm.ts

TEST_DM_USER_ID=... pnpm poc:dm

Talks to a real running Vesktop's control socket and sends one paced DM. The only sanctioned live-send target is user zzib (provide their user ID).

Verified

  • QR login works end-to-end; the token in .token came from a phone scan.
  • MCP bridge path: initialize, tools/list, get_state, send_message, read_messages, send_dm all round-trip correctly through the mock.
  • Pacing observed live: consecutive commands reached the mock 592 ms, 1862 ms and 1439 ms apart — inside the 500–2800 ms window.

Deferred (not testable in this container)

  • Real renderer handlers against a live Discord session (needs Electron + display).
  • Headless display strategy (Xvfb/offscreen) and client lightening.
  • Token injection into the official client.
  • Voice join/leave and audio/video pipelines (need a voice channel; ffmpeg/PipeWire absent).
  • Remote client auth over LAN/Tailscale and the web debug UI.

Findings

  • Official discord.js is bot-only (/gateway/bot → 401 with a user token), and discord.js-selfbot-v13 is archived — do not build on either. The core is the real Vesktop client, puppeted through its own interactions.
  • MCP SDK 1.30.0 stateless Streamable HTTP works as used here.
  • Vesktop's existing sendRendererCommand/onIpcCommand bus is enough to puppet interactions; the socket only needed a JSON-lines framing and a command map.
  • pnpm 11: this folder is its own workspace root; build approvals live in pnpm-workspace.yaml (allowBuilds).