Skip to main content
Glama
README.md
# ScriptIt

One control plane for your agent's tools. Connect remote MCP servers once; every agent —
in any sandbox — gets them back two ways:

- **a remote MCP endpoint** (`/mcp`) with compact meta-tools (no tool-list bloat), and
- **a CLI** (`scriptit`) an agent can pair from inside any sandbox via a public-key
  handshake approved **over an MCP tool call** — upstream credentials never enter the sandbox.

Plus a proxied **LLM endpoint** for scripting, and **watches**: run a command or tool on an
interval, optionally have an LLM verify the output, and emit structured events your agent
can poll or stream.

Local-first build: everything runs on your machine (SQLite, one server process).

## Quick start

```bash
pnpm install
pnpm build
pnpm start            # control plane on http://127.0.0.1:4747 (prints admin + mcp tokens)
```

Dev mode (server + web UI + demo upstream MCP, all watching):

```bash
pnpm dev
```

- Dashboard: http://127.0.0.1:4747 (dev UI: http://127.0.0.1:5173) — sign in with the admin token.
- Demo upstream MCP server: http://127.0.0.1:4748/mcp (`echo`, `get_time`, `list_cronjobs`).
- LLM features need `ANTHROPIC_API_KEY` (or an `ant auth login` profile) in the server's env.

## Connect an agent (MCP)

Add to Claude Code (or any MCP client):

```bash
claude mcp add --transport http scriptit http://127.0.0.1:4747/mcp --header "Authorization: Bearer <mcp token>"
```

Tools: `list_connectors`, `search_tools`, `call_tool`, `approve_cli`, `create_watch`,
`list_watches`, `run_watch`, `delete_watch`, `get_events`, `llm`.

## Pair the CLI (the handshake)

In the sandbox / any shell:

```bash
scriptit pair                 # prints a code like AB3D-9XKQ and waits
```

Then either ask your agent to call `approve_cli` with that code over its ScriptIt MCP
connection, or approve it in the dashboard. From then on:

```bash
scriptit connectors
scriptit call demo list_cronjobs
scriptit llm "summarize:" - < notes.txt
scriptit watch create --name failed-crons \
  --connector demo --tool list_cronjobs --interval 5m \
  --verify "Emit an event iff any cronjob is failing; type=cron_failure, summarize which."
scriptit events --follow --json      # structured events, one JSON per line
```

The CLI signs every request with an ed25519 key; sessions are short-lived and revocable
from the dashboard. Upstream tokens live only in the control plane, encrypted at rest.

## Layout

| Path | What |
|---|---|
| `apps/server` | control plane: REST + MCP endpoint + OAuth broker + watch engine (port 4747) |
| `apps/web` | dashboard SPA |
| `packages/cli` | `scriptit` CLI |
| `packages/shared` | shared types + ed25519 signing |
| `packages/demo-mcp` | demo upstream MCP server (port 4748) |
| `PROTOCOL.md` | the contract: pairing, signing, REST, MCP tools, watches |

## Notes

- Local build trusts localhost: admin/mcp tokens are the auth boundary. Don't expose 4747.
- OAuth connectors use Dynamic Client Registration + PKCE (works with Linear, Notion, Sentry,
  Atlassian, Stripe, Supabase, …). Bearer/PAT connectors cover GitHub's MCP and friends.
- `scriptit watch` command-type watches execute shell commands **on the server host** — that's
  the point (local build), but remember it when you deploy this anywhere shared.