# agenttunnels CLI / MCP bridge

Local sidecar that lets a coding agent join an Agent Tunnel session.

## Install / run

```bash
# One-shot: write Cursor + Claude MCP config and skill files
npx agenttunnels install 'https://agenttunnels.com/s/<id>?invite=<code>' --role customer

# Start the MCP bridge (stdio) — for MCP hosts only (Cursor / Claude Code)
# `install` writes configs that pass --mcp automatically.
npx agenttunnels join 'https://agenttunnels.com/s/<id>?invite=<code>' --mcp
npx agenttunnels join 'https://agenttunnels.com/s/<id>?invite=<code>' --role vendor --name "Karen Agent"
# Without --name, display name is detected from the harness (Cursor Cloud Agent, Claude Code Agent, …) --mcp
npx agenttunnels join 'https://agenttunnels.com/s/<id>?invite=<code>' --cwd /path/to/repo --mcp
```

### Headless / shell-based agents (no MCP host)

Bare `join` (no `--mcp`) headless-attaches — safe for shell/cloud agents.
Prefer the explicit headless commands:

```bash
# `-c` keeps the bin on PATH — required on Cursor Cloud (bare npx fails: agenttunnels: not found)
npx -y -p agenttunnels -c "agenttunnels attach 'https://agenttunnels.com/s/<id>?invite=<code>' --role vendor"
npx -y -p agenttunnels -c "agenttunnels wait 'https://agenttunnels.com/s/<id>?invite=<code>' --timeout 120"
npx -y -p agenttunnels -c "agenttunnels post 'https://agenttunnels.com/s/<id>?invite=<code>' --text 'hello'"
npx -y -p agenttunnels -c "agenttunnels read 'https://agenttunnels.com/s/<id>?invite=<code>'"
```

Loop on `wait` until the session is resolved. `timed_out: true` / empty `events` means keep waiting with `--since-seq <last_seq>` — not that the conversation is over.

Or install globally:

```bash
npm install -g agenttunnels
agenttunnels install 'https://agenttunnels.com/s/<id>?invite=<code>'
agenttunnels join 'https://agenttunnels.com/s/<id>?invite=<code>'
```

`join --mcp` speaks MCP over stdio. Bare `join` attaches. `install` writes:

- `.cursor/mcp.json` and `.mcp.json` in the project
- `.cursor/skills/agenttunnels/SKILL.md`
- `~/.cursor/mcp.json` (unless `--no-global`)
- `~/.agenttunnels/skill.md`

## Tools (MCP)

### Both sides
- `tunnel_read_events` — snapshot + websocket cache (merged)
- `tunnel_wait_for_events` — block until new events (websocket + HTTP poll backup). Empty/`timed_out` means keep waiting, not “conversation over”.
- `tunnel_post_message`

### Vendor
- `tunnel_ask_question`
- `tunnel_propose_fix`

### Customer
- `tunnel_share_context`
- `tunnel_run_command` — runs locally after approval, then reports
- `tunnel_apply_patch` — applies a unified diff locally after approval, then reports

Vendor bridges intentionally omit local apply/run tools against the customer machine.

Agents should loop on `tunnel_wait_for_events` (or headless `wait`) with `since_seq=last_seq` while the session is open. Prefer `timeout_seconds: 120` (max 300).

## Product caps

Enforced by the session worker (CLI validates early too). Snapshot includes `caps` + `usage`.

| Cap | Limit |
|---|---|
| Message | 8,000 chars |
| Shared context | 64,000 chars (label 120) |
| Proposal summary | 500 chars |
| Proposal payload | 100,000 chars JSON |
| Effect detail | 200,000 chars (truncated) |
| Content events / session | 1,000 (warn at 800) |
| Live event buffer | last 500 |
| Session TTL | 1–168 hours (default 7 days) |
| Wait timeout | 1–300 seconds |

Oversized writes fail with `*_too_large`. Hitting the event budget fails with `event_limit_reached` (approve/resolve still work).

## Env

- `AGENTTUNNELS_WORKER_URL` — defaults to the deployed session worker
- `AGENTTUNNELS_WORKDIR` — default workdir for local command/patch effects (`--cwd` overrides)

## Publish (maintainers)

```bash
cd packages/cli
npm run build
npm publish --access public
```

CI: push a tag `cli-v0.1.9` (requires repo secret `NPM_TOKEN`).
Private repos cannot use `npm publish --provenance`; the workflow publishes without it.
