# tollbooth [Health: Active]

**Category:** 🧠 Knowledge & Memory  
**Repository:** https://github.com/chrzanowy/agent-tollbooth  
**GitHub Stars:** 0  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/tollbooth

## Description
Stateful backend for AI agents: memory, watch, render, execute, and shared boards with digests.

## Claude Desktop Quick Installation
Remote MCP endpoint (confidence: high). Install path detected from listing signals. Add as a URL/SSE server in your client:

```json
"mcpServers": {
  "tollbooth": {
    "url": "http://localhost:4402"
  }
}
```

## Documentation & README

# tollbooth

**The stateful backend for AI agents.** Agents are stateless: when the session ends they forget, they can't wait, and they can't watch. tollbooth is one small self-hostable box that gives an agent the five things statelessness denies it:

| Primitive | What the agent gets | Why it can't do this itself |
|---|---|---|
| `memory` | store / recall facts across sessions | its context dies with the session |
| `watch` | "what changed on this page since I last looked?" | it can't remember what the page looked like |
| `render` | JS-rendered pages as clean text (real Chromium) | plain fetch can't run JavaScript |
| `execute` | run python/node/bash, get stdout/stderr/exit code | some harnesses ship no sandbox |
| `board` | a shared, append-only log + digest where independently launched agents coordinate | their sessions and parent processes do not overlap |

Every response carries a machine-readable **receipt** (`tool`, `price_usd`, `latency_ms`, `timestamp`). Locally everything is free; the receipt format is stable so tooling built against it also works against the hosted tier.

## Quickstart (Docker)

```sh
docker run -p 4402:4402 -v tollbooth-data:/data ghcr.io/chrzanowy/agent-tollbooth:latest
# tollbooth (local tier) listening on http://localhost:4402
```

Or build from source:

```sh
docker compose up --build
```

Or without Docker (render needs one extra step):

```sh
npm install
npx playwright install chromium   # optional — enables render.extract
npm run dev
```

## Talk to it

```sh
# The homepage is machine-readable — the catalogue with prices and latencies
curl -s localhost:4402/.well-known/tollbooth.json | jq .

# memory: persist a fact, recall it in any future session
curl -s localhost:4402/memory -H 'content-type: application/json' \
  -d '{"key":"deploy-cmd","content":"make deploy ENV=prod","tags":["ops"]}' | jq .
curl -s 'localhost:4402/memory?q=deploy' | jq .

# watch: baseline now...
curl -s localhost:4402/watch -H 'content-type: application/json' \
  -d '{"url":"https://example.com/pricing","note":"competitor pricing"}' | jq .
# ...and any later session asks "what changed since I last looked?"
curl -s -X POST localhost:4402/watch/1/check | jq .

# render: JS-rendered page → clean text
curl -s localhost:4402/render -H 'content-type: application/json' \
  -d '{"url":"https://example.com","format":"text"}' | jq .

# execute: run code, get stdout/stderr/exit code
curl -s localhost:4402/execute -H 'content-type: application/json' \
  -d '{"language":"python","code":"print(6*7)"}' | jq .

# board: open a rendezvous point for a repo or feature
curl -s localhost:4402/board/open -H 'content-type: application/json' \
  -d '{"topic":"repo:github.com/owner/name"}' | jq .
# boards form a namespace: the topic above is the project's inbox, and each
# workstream gets its own board (own digest, own lock) under a ctx: suffix.
# The one-line description is what board listings show as the menu label.
curl -s localhost:4402/board/open -H 'content-type: application/json' \
  -d '{"topic":"repo:github.com/owner/name/ctx:auth-refactor","description":"auth refactor workstream"}' | jq .
# board: list a project's contexts in one call — the prefix query is the map lookup
curl -s 'localhost:4402/board?query=repo:github.com/owner/name' | jq .
# board: post a finding (replace 1 with the returned board id)
curl -s localhost:4402/board/1/post -H 'content-type: application/json' \
  -d '{"author":{"name":"agent-a","model":"haiku"},"content":"Tests pass after the parser change."}' | jq .
# board: catch up from the latest digest
curl -s 'localhost:4402/board/1?limit=200' | jq .
# board: write a digest after reviewing the log
curl -s localhost:4402/board/1/digest -H 'content-type: application/json' \
  -d '{"author":{"name":"janitor","model":"haiku"},"content":"Parser change is tested and ready for review.","expected_version":0}' | jq .
```

## Use from an agent (MCP)

tollbooth exposes a **remote MCP endpoint** (streamable HTTP) at `/mcp` — no local process to spawn, so it also works from harnesses that can make HTTPS calls but can't install anything.

Claude Code:

```sh
claude mcp add --transport http tollbooth http://localhost:4402/mcp
```

Tools exposed: `memory_store`, `memory_recall`, `watch_add`, `watch_check`, `watch_list`, `render_extract`, `execute_run`, `board_open`, `board_list`, `board_post`, `board_read`, `board_digest`.

## Teach your agent to use it

A tool an agent doesn't know *when* to reach for goes unused. This repo ships
five skills under [`.claude/skills/`](https://github.com/chrzanowy/agent-tollbooth/blob/HEAD/.claude/skills/):

| Skill | Teaches |
|---|---|
| `tollbooth` | when to use each primitive — and when not to bother |
| `checkpoint` | on-demand: save this session's durable conclusions to the board |
| `janitor` | compact a board into a digest (run it with a cheap model) |
| `warmstart` | warm-start a new session from a board instead of re-reading transcripts (named to avoid the reserved `/resume` built-in) |
| `toolbox` | a machine-global log of problem → tool that worked (ns=`toolbox` in memory): recall before you build, store only what you watched succeed |

Copy them into `~/.claude/skills/` to have them in every project (or into one
project's `.claude/skills/`), or use their contents as system-prompt sections
for non-Claude harnesses (GPT, DeepSeek, GLM, Grok — the API is plain HTTP, so
the same instructions work everywhere).

```sh
cp -R .claude/skills/* ~/.claude/skills/
```

For zero-token context capture, [`scripts/tollbooth-hook.mjs`](https://github.com/chrzanowy/agent-tollbooth/blob/HEAD/scripts/tollbooth-hook.mjs)
posts each session's closing context to a per-project board automatically —
see [docs/warm-start.md](https://github.com/chrzanowy/agent-tollbooth/blob/HEAD/docs/warm-start.md) for the one-time hook setup and
the cheap-model digest recipe that turns those captures into warm starts.

## Configuration

| Env var | Default | Meaning |
|---|---|---|
| `PORT` | `4402` | HTTP port (402 = Payment Required — the joke is the roadmap) |
| `TOLLBOOTH_DATA_DIR` | `./data` | Where the SQLite state lives |
| `TOLLBOOTH_TIER` | `local` | `cloud` enables non-zero prices in the catalogue/receipts |

## Security note on `execute`

The container is the sandbox boundary: submitted code runs with the container's privileges. Run tollbooth in the shipped Docker image (or an equivalent throwaway container), never bare on a machine you care about, if untrusted agents can reach it.

## Roadmap

- Background watch polling + webhooks (true "notify me", not just diff-on-demand)
- Hosted tier: same API behind Stripe credits and x402 per-call payments, for agents in sandboxes that can't self-host
- `distill` (objective-driven compression of logs/HTML/repos) as a free local tool

## License

MIT

