Skip to content
Agent Orchestration
Skill

/tether

Beta — Stay in the loop over email during a long-running coding session. The agent sends threaded status updates to your inbox as it sees fit and picks up your emailed replies (questions/instructions) within a few minutes, so you can steer a working agent while AFK. Transport is

BOOST
From plugin
e2a
1949 skills1 MCP
Install
$ npx -y skills add tokencanopy/e2a --skill tether --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/tether

Context preview

The summary Claude sees to decide when to auto-load this skill.

Beta — Stay in the loop over email during a long-running coding session. The agent sends threaded status updates to your inbox as it sees fit and picks up your emailed replies (questions/instructions) within a few minutes, so you can steer a working agent while AFK. Transport is

SKILL.md

tether.SKILL.md
name: tether
description: Beta — Stay in the loop over email during a long-running coding session. The agent sends threaded status updates to your inbox as it sees fit and picks up your emailed replies (questions/instructions) within a few minutes, so you can steer a working agent while AFK. Transport is e2a. Use when you want to walk away from a session but keep commanding it from your inbox.

tether — steer a long-running session from your inbox

> **Beta.** The transport (e2a) and the flow are real; polish (adaptive > backoff, richer digests) is still open.

`/tether` keeps you connected to a working session over email. The agent emails you updates **when it judges there's something worth reporting** (not on a timer, not every turn), and checks your inbox on an interval so your replies — questions or new instructions — are picked up within a few minutes. Reply `stop` to end.

> **Transport primer.** tether rides on e2a. The e2a *operate-well manual* — > the dependency-provided `e2a` skill — carries the > mental model this skill assumes: how threading really works (reply headers + > stable subject, **not** `conversation_id`), when a shared `agents.e2a.dev` > address is all you need vs. a custom domain, and how to handle send statuses. > Read the `e2a` skill by name if you're new to e2a; tether does not re-explain > those.

Architecture (why this shape)

Coding agents are turn-based; nothing native listens to an inbox mid-session. So the two directions use different mechanisms:

  • **Send = agent-driven.** The agent calls `tether.sh update "…"` at meaningful

moments (finished a slice, hit a blocker, needs a decision). Cadence is the model's judgment → no per-turn spam, nothing to throttle.

  • **Receive = real-time wait.** The agent runs `tether.sh listen` — it blocks

on the e2a CLI's WebSocket (`e2a listen --once`; no LLM tokens while waiting) for the duration set at `start --for`, so replies are picked up within seconds; if the WebSocket is unavailable it degrades automatically to interval polling. It wakes the agent *only* when a reply actually arrives (or the window ends). See **Durability tiers** for keeping it alive across idle/sleep.

  • **Questions = ask by email.** When the agent needs a decision or clarification

from you, it must **not** use a terminal prompt / AskUserQuestion — you're AFK and can't see it, which would stall the whole session. It calls `tether.sh ask "<question>"`, which emails the question into the thread and **blocks until you reply**, then prints your answer. This is the hard rule: **while tethered, every question goes over email, never the terminal.**

  • **Blocked-alert = hook (optional).** A `Notification` hook emails you when the

agent is stuck on a *permission prompt* it can't proceed past. Note: an emailed reply cannot answer a CLI permission prompt (there's no native way to inject approval), so for unattended runs **pre-authorize** the tools the session needs (a permission allowlist / a less-prompting mode). The hook is the safety net, not the approval channel.

Setup (once)

> **Prerequisites:** Node (the transport is the `e2a` CLI, currently the **2.x** > line pinned as `TETHER_MIN_CLI` in `lib.sh` — resolved from `$E2A_CLI`, then > PATH, then fetched automatically via `npx -y @e2a/cli@^MIN`, so there is > nothing to install by hand) and Python 3 (local state handling only). > > The range is **major-bounded on purpose**. tether parses the CLI's TSV columns > and branches on its exit codes, and a major bump is allowed to change both — > 2.0.0 did. So a CLI newer than the pinned major is *not* adopted automatically > (tether falls back to npx and says so); someone re-verifies tether against the > new major and bumps `TETHER_MIN_CLI`. Failing inert beats failing silently in > an unattended session.

Fast path (recommended): `tether.sh setup`

`tether.sh`, `install.sh`, and `tether.env.example` all sit in this skill's own directory, next to this `SKILL.md`. Substitute its absolute path for `$TETHER_DIR` in every command below; the scripts resolve their own resources, so any working directory works.

If the e2a CLI is logged in (`e2a login` in a browser, or a key persisted with `e2a config set api_key <key>` on a headless box), one command does the whole bootstrap:

"$TETHER_DIR/tether.sh" setup

It verifies the credential (`e2a whoami`), ensures a tether inbox (reusing an existing `tether-…` agent or creating one on the shared domain — it will **not** silently adopt a non-tether inbox), mints a **least-privilege agent-scoped key** (`e2a_agt_…`), and writes `~/.e2a-tether.env` (previous file kept as `.bak`). Every step fails hard — it never stores the broad account key and never reports "ready" with a half-working config. Flags: `--email you@yourdomain` to use/create a specific inbox, `--new` to force a fresh one.

Manual setup (fallback)

1. **Get an agent-scoped API key** (`e2a_agt_…` — least privilege, so a leaked key can't touch the rest of the account): from the CLI with `e2a keys create --agent <inbox>`, or from **https://e2a.dev/api-keys**. No domain? Create the agent on the **shared `agents.e2a.dev`** domain (`e2a agents create name@agents.e2a.dev` — live immediately, no DNS). 2. **Save the credentials:**

   cp "$TETHER_DIR/tether.env.example" ~/.e2a-tether.env
   chmod 600 ~/.e2a-tether.env   # fill E2A_API_KEY (e2a_agt_…) + E2A_AGENT_EMAIL

3. **(Optional) blocked-alert hook:**

   "$TETHER_DIR/install.sh" --to <repo-root>

Credentials resolve in order: explicit env vars → `~/.e2a-tether.env` → `~/.e2a/config.json`. Note that `e2a login` saves an **account-scoped** key and does **not** set `agent_email` — so `~/.e2a/config.json` alone is not enough for tether, which needs a specific inbox. Either set both explicitly:

e2a keys create --agent <inbox>          # least-privilege e2a_agt_… key
e2a config set agent_email <inbox>
Read more
Ships withe2a

Open-source email API for applications and AI agents. Managed hosting at e2a.dev, or self-host with Docker.

Get the whole plugin

Other skills on e2a.