π Introduction
Google TV control library β discovery, pairing, a stateful session, and a shared device store
@kud/gtv is the framework-agnostic core of the Google TV stack β the engine
that gtv-cli, mcp-gtv, and the desktop app all build on.
It handles discovery, pairing, a stateful remote session, and a shared device
registry, and leaves every side effect to you.
π§© One idea: pure core, injected I/O
@kud/gtv never reads a terminal, shows a dialog, or owns a UI. Anything that
touches the outside world is something you pass in β which is exactly why three
very different clients can share one core:
- Pairing β
onSecretis your callback (terminalreadline, an MCP round-trip, a Tauri dialogβ¦); the library does no I/O itself. - Discovery β
discover()returns pure data from mDNS, no side effects. - Session β
createSession()returns anEventEmitterthat reduces the raw protocol stream into one observableSessionState. - Shared store β every consumer reads and writes the same
~/.config/gtv/config.json, so one device registry serves them all.
π¦ Install
npm install @kud/gtvπ Quick start
Discover and pair with a TV (the PIN shows on screen):
import { discover, pair } from "@kud/gtv";
const [tv] = await discover();
await pair({
host: tv.host,
hostname: tv.hostname,
port: tv.port,
name: tv.name,
onSecret: async () => promptUserForPin(),
});Then drive a stateful session:
import { createSession, KEYS } from "@kud/gtv";
const session = createSession(); // uses the configured device
session.on("change", (state) => console.log(state));
session.sendKey(KEYS.home);
session.typeText("interstellar");
session.launchApp("market://launch?id=com.netflix.ninja");
session.stop();For scripts that don't need a long-lived connection, the one-shot helpers
(sendKey, launchApp, connect, withRemote) handle connect-act-disconnect
for you.