# AGENTS.md — Veskslop ## What this is Veskslop is a **headless Discord client daemon** built on the Vesktop codebase. It runs the **real Discord web client** (Vencord-patched Vesktop) without a visible window and puppets the client's own interactions, so traffic and behavior stay as close to the official client as possible. - an **MCP server** (Streamable HTTP) lets AI agents drive the account; - multiple user identities are planned (one read-only collector, one full puppet); - **audio in/out** and **video streaming** come later, using the client's native voice stack plus PipeWire virtual devices on Linux; - everything is **local-first**: clients reach it over LAN/Tailscale only. **Vesktop is a separate project with separate goals.** This repo shares history with it but not direction. ## Decisions (locked unless the user changes them) - **Core:** run the actual Vesktop/Discord client (Electron) headless. Do **not** build on third-party selfbot protocol libraries — the popular ones are archived/deprecated and stale protocol emulation is a ban risk. - **Control:** puppet Vesktop's own interactions through its IPC command bus: `vesktop.sock` (external) → `sendRendererCommand` (main) → renderer handlers that call Vencord/Discord internals (`sendMessage`, stores, voice actions). - **MCP:** an external local daemon speaks a JSON-lines protocol over `vesktop.sock` and exposes Streamable HTTP MCP. It must run without Electron so it is testable standalone. - **QR login:** our own terminal remote-auth tool (`poc/qr-login.ts`) acquires a user token. Feeding that token into the headless client is deferred until it can be tested. - **Accounts:** multiple user tokens. Expected setup is one read-only collector account plus one full-control puppet account; design for N identities behind one control surface. - **Network:** bind localhost by default. Remote access is always over LAN/Tailscale — never expose to the public internet. A client will later authenticate to the proxy for remote control. - **Audio/video:** use the client's native stack first; PipeWire virtual devices for system audio piping. ffmpeg is required for non-Opus media and video encoding. - **GUI:** optional minimal **web debug UI** later. The daemon must never require a visible window; on servers without a display, a virtual display (Xvfb) will be needed for Electron. - **Pacing/safety:** all outbound actions are queued and paced. - **Current policy:** every command sent to the client is spaced by a random **500–2800 ms**, serialized, with identical in-flight queries coalesced; prefer cached state over queries. - **Later policy:** human emulation — snappy first action (~30–80 ms), bulk actions randomized, opt-in risky fast mode, free-account limits by default, ability toggles. ## How to proceed **Current milestone — puppeting bridge (testable without Electron).** 1. Extend Vesktop's `vesktop.sock` server with a JSON-lines request/response protocol (keep the legacy `run-shortcut` line working). 2. Add renderer handlers for `state:get`, `message:send`, `message:read` via Vencord internals. 3. Build the external MCP daemon (`poc/src/control-bridge.ts`) with a mock Vesktop socket (`poc/src/mock-vesktop.ts`) so the whole path is testable in this container. 4. Then: voice join/leave handlers, audio pipes, video streaming, token injection, client lightening, remote client auth. Anything that needs a display, audio device, or a real client instance is **deferred** until it can be tested; note it instead of guessing. ## Architecture sketch ``` MCP clients (agents) ──Streamable HTTP──▶ veskSlop control daemon │ JSON lines over vesktop.sock ▼ Vesktop main process │ sendRendererCommand() ▼ Discord renderer (Vencord patched) │ official client actions ▼ Discord ``` ## Guardrails for agents working here - **Never commit tokens, credentials, or `.env` files.** Use environment variables / a local secret store. - Do not adopt archived/deprecated selfbot libraries. If a library is needed, verify it was pushed recently before proposing it. - Do not hardcode Discord limits from memory — verify current free-tier numbers (upload size, stream resolution, rate limits) at implementation time, and keep them configurable. - All outbound actions go through the pacing queue; no direct sends. - Default to conservative limits and opt-in risky features. - Test against throwaway accounts and private test guilds only. - **Live send tests:** DMs to user **zzib** (`177117296140091393`) are the only sanctioned real-send test target. - Run `pnpm testTypes` and `pnpm lint` before calling work done; `pnpm build` to compile. ## Open questions - Headless Electron strategy: Xvfb vs offscreen rendering, and what to strip to lighten the client. - Token injection path for the official client (localStorage seeding vs client QR UI). - Voice/video: what the client's native stack can be driven to do without UI interaction. - Scope and auth model of the future remote proxy client and web debug UI. - How much of the Vesktop Electron tree gets deleted once the daemon is self-sufficient. ## Dev commands ```sh pnpm install pnpm build # esbuild bundle into dist/ pnpm testTypes # tsc --noEmit pnpm lint ```