diff --git a/.github/assets/architecture.svg b/.github/assets/architecture.svg new file mode 100644 index 0000000..e0be9b3 --- /dev/null +++ b/.github/assets/architecture.svg @@ -0,0 +1,193 @@ + + sealg architecture + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Agents & shells + + + + + + + + $ sealg list + $ sealg call <tool> + $ sealg doctor + + + + + + argv / stdout + + + + + + sealg + Rust binary · thin MCP client + + + crates/cli + transport surface · list / call / doctor + + + crates/engine + gateway client · config · doctor + + stateless · no config files · no policy + + + + + + MCP · HTTPS + initialize + tools/list · tools/call + + + + + + + per-user MCP endpoint + owns ALL policy + trifecta ·  + PII enforcement + every allow / deny decision lives here + + + + + + + + + + + Connectors + + + Slack + + Gmail + + GitHub + + · · · + and more + + + + + + + + sealg doctor → local env facts + runs offline · never touches the gateway + + + + Policy lives in the gateway. + The client carries none. + diff --git a/.github/assets/banner.png b/.github/assets/banner.png new file mode 100644 index 0000000..770becd Binary files /dev/null and b/.github/assets/banner.png differ diff --git a/.github/assets/icons/bolt.svg b/.github/assets/icons/bolt.svg new file mode 100644 index 0000000..aef38cc --- /dev/null +++ b/.github/assets/icons/bolt.svg @@ -0,0 +1,4 @@ + + quick start + + diff --git a/.github/assets/icons/code.svg b/.github/assets/icons/code.svg new file mode 100644 index 0000000..6942b8d --- /dev/null +++ b/.github/assets/icons/code.svg @@ -0,0 +1,6 @@ + + python client + + + + diff --git a/.github/assets/icons/flow.svg b/.github/assets/icons/flow.svg new file mode 100644 index 0000000..1ee526c --- /dev/null +++ b/.github/assets/icons/flow.svg @@ -0,0 +1,8 @@ + + request lifecycle + + + + + + diff --git a/.github/assets/icons/gear.svg b/.github/assets/icons/gear.svg new file mode 100644 index 0000000..eb5fea3 --- /dev/null +++ b/.github/assets/icons/gear.svg @@ -0,0 +1,5 @@ + + configuration + + + diff --git a/.github/assets/icons/network.svg b/.github/assets/icons/network.svg new file mode 100644 index 0000000..2006836 --- /dev/null +++ b/.github/assets/icons/network.svg @@ -0,0 +1,9 @@ + + architecture + + + + + + + diff --git a/.github/assets/icons/package.svg b/.github/assets/icons/package.svg new file mode 100644 index 0000000..7a35d56 --- /dev/null +++ b/.github/assets/icons/package.svg @@ -0,0 +1,6 @@ + + requirements + + + + diff --git a/.github/assets/icons/puzzle.svg b/.github/assets/icons/puzzle.svg new file mode 100644 index 0000000..ac17b35 --- /dev/null +++ b/.github/assets/icons/puzzle.svg @@ -0,0 +1,4 @@ + + agent skills + + diff --git a/.github/assets/icons/scale.svg b/.github/assets/icons/scale.svg new file mode 100644 index 0000000..ec5c36b --- /dev/null +++ b/.github/assets/icons/scale.svg @@ -0,0 +1,8 @@ + + license + + + + + + diff --git a/.github/assets/lifecycle.svg b/.github/assets/lifecycle.svg new file mode 100644 index 0000000..4caf778 --- /dev/null +++ b/.github/assets/lifecycle.svg @@ -0,0 +1,86 @@ + + sealg request lifecycle + + + + + + + + + + + + + + + + + + + + Request lifecycle + Every subcommand resolves the gateway from the environment, then does one thing. + + + + + sealg list + + + + + initialize + + + + + tools/list + + + + + the user's tool names + text, or --json array + + + + + + sealg call <tool> + + + + + initialize + + + + + tools/call + + + + + result content + exit 0 ok · 6 tool error · 1 transport + + + + + + sealg doctor + + + local only · no network + + + collect env facts + + + + + env summary + human text, or --json / --out + + diff --git a/.github/assets/terminal.svg b/.github/assets/terminal.svg new file mode 100644 index 0000000..1552c8a --- /dev/null +++ b/.github/assets/terminal.svg @@ -0,0 +1,6 @@ + + terminal + + + + diff --git a/README.md b/README.md index 4200a8c..75b38a2 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,8 @@ -# SealGate - -

- banner -

-

-Command-line interface for SealGate, the agentic data firewall + SealGate: connect and govern how AI interacts with your data

-

- Key Features • - Architecture • - Quick Start • - Agent Skills • - Credits -

+

sealg

Rust Version @@ -22,57 +10,77 @@ GitHub Actions Workflow Status

---- +terminal The command-line +interface for [SealGate](https://sealgate.ai), the agentic data firewall. `sealg` +is a thin MCP (Model Context Protocol) client to the SealGate **gateway**: `list` +and `call` forward `tools/list` / `tools/call` to your per-user gateway endpoint, +where all policy and enforcement live. The binary is **stateless** and resolves +every coordinate from the **environment** (no config files), so it drops into any +sandbox and carries no policy of its own. + +### The `sealg` surface + +`sealg` is one small binary with three subcommands. `list` and `call` talk to the +live gateway over MCP; `doctor` stays local and reports environment facts. -## Key Features +```bash +export SEALGATE_URL=https://dashboard.sealgate.ai +sealg list # the tools your gateway exposes +sealg call slack_send --args '{"channel": "#eng", "text": "shipped"}' +sealg doctor --json # local env facts, no network +``` -`sealg` is a thin MCP client to the SealGate gateway: `list` and `call` forward -`tools/list` / `tools/call` to the per-user gateway endpoint, where all policy -and enforcement live. +| Command | What it does | +|---------|--------------| +| `sealg list` | Run the MCP `initialize` handshake, then `tools/list`, and print the tools your gateway exposes. `--json` emits an array of `{name, description}`. | +| `sealg call --args '{...}'` | Forward one `tools/call` to the gateway with a JSON arguments object, print the result, and exit `0` on success, `6` on a tool error, `1` on a transport failure. | +| `sealg doctor` | Collect local environment facts and emit a summary. Runs offline and never touches the gateway. `--json` / `--out ` write machine-readable output. | -| Feature | Tech Stack | -|---------|:----------:| -| **Core** | `engine` crate - env-resolved gateway config + hand-rolled MCP client (no transport deps) | -| **CLI** | `sealg` binary - `list` / `call` / `doctor` | -| **Transport** | MCP Streamable HTTP to the gateway's `/mcp/{api_key}/` endpoint | -| **Logging** | `tracing` + redaction layer | -| **Packaging** | `cargo-dist` (binaries + installers) | -| **Package Manager** | Bun | -| **Formatting** | Biome + `cargo fmt` | +Both `list` and `call` accept `--gateway-url ` to override `SEALGATE_URL` +for a single invocation. Everything else, including the API key and CA bundle, is +read from the environment (see [Configuration](#configuration)). -## Architecture +## Architecture -``` - ┌──────────────────────────────────────────────────────────┐ - │ TRANSPORT (crates/cli - one binary `sealg`) │ - │ │ - │ sealg list tools/list │ - │ sealg call --args '{...}' tools/call │ - │ sealg doctor local env facts │ - └───────────────────────────┬──────────────────────────────┘ - │ engine::gateway (MCP over HTTP) - ┌───────────────────────────▼──────────────────────────────┐ - │ crates/engine - the service core (no transport deps) │ - │ GatewayConfig - coordinates resolved from the env │ - │ GatewayClient - initialize / tools/list / tools/call │ - │ doctor / types - env facts + stable result contract │ - └───────────────────────────┬──────────────────────────────┘ - │ HTTPS - ┌───────────────────────────▼──────────────────────────────┐ - │ SealGate gateway - per-user MCP endpoint; owns ALL │ - │ policy, trifecta, and PII enforcement │ - └──────────────────────────────────────────────────────────┘ -``` +

+ sealg architecture: an agent or shell runs the stateless sealg binary, which forwards tools/list and tools/call over HTTPS to the per-user SealGate gateway, where all policy, trifecta, and PII enforcement live before reaching connectors; the doctor command is local only. +

-- `crates/engine/` - the gateway client + config, `doctor` env facts, and the - shared result contract. No transport dependency. -- `crates/cli/` - the `sealg` binary. The `cli` surface (`doctor`) is a cargo - feature. +- **`sealg` is a thin client.** It runs the MCP handshake and forwards requests. + It holds no allow/deny logic, so the trust boundary is the gateway, not the + binary you drop into a sandbox. +- **The gateway owns everything that matters.** Policy, trifecta classification, + and PII enforcement run per-user on the gateway before any connector is + reached. Swapping the client never changes what is allowed. +- **`doctor` is local.** It reads OS, session, and environment facts and prints + them without opening a connection, so it is safe to run anywhere. -## Quick Start +### Request lifecycle + +

+ Request lifecycle: sealg list runs initialize then tools/list and prints tool names; sealg call runs initialize then tools/call and prints the result with an exit code; sealg doctor collects local environment facts and prints a summary with no network call. +

+ +The workspace splits along the same boundary as the diagram: + +- **`crates/engine/`** the service core: `GatewayConfig` (env-resolved + coordinates), `GatewayClient` (a hand-rolled MCP-over-HTTP client), the + `doctor` env facts, and the shared result contract. No transport dependency. +- **`crates/cli/`** the `sealg` binary. The `cli` surface (`doctor`) is a cargo + feature, so the gateway commands build without the diagnostics code. + +## Requirements + +- Rust 1.75+ and Cargo +- A reachable SealGate gateway (or `SEALGATE_URL=http://localhost:3000` for local + development) +- [Bun](https://bun.sh/) and [prek](https://github.com/j178/prek) for the + formatting and pre-commit hooks + +## Quick Start ```bash -# 1. Build + test the workspace +# 1. Build and test the workspace cargo build --workspace cargo test --workspace @@ -85,7 +93,14 @@ cargo run -p sealg -- call some_tool --args '{"query": "hello"}' cargo run -p sealg -- list --gateway-url https://dashboard.sealgate.ai ``` -### Python client +Before your first contribution, enable the hooks so `cargo fmt`, Clippy, and Biome +run on every commit: + +```bash +bun add -g prek && prek install +``` + +### Python client A `uvx`-installable Python client exposing the same `sealg` surface lives in [`python/`](python/) and is published to PyPI: @@ -94,13 +109,29 @@ A `uvx`-installable Python client exposing the same `sealg` surface lives in uvx sealg doctor ``` -It mirrors the Rust binary's commands and exit codes; the two are kept in sync -by `scripts/check_wire_contract.py`. See [`python/README.md`](python/README.md). +It mirrors the Rust binary's commands and exit codes; the two are kept in sync by +`scripts/check_wire_contract.py`. See [`python/README.md`](python/README.md). + +## Configuration + +`sealg` reads its gateway coordinates once at startup with +`GatewayConfig::from_env` ([`crates/engine/src/gateway/config.rs`](crates/engine/src/gateway/config.rs)). +Nothing is stored on disk. -## Agent Skills +| Variable | Purpose | +|----------|---------| +| `SEALGATE_URL` | Gateway origin. Defaults to `http://localhost:3000`. The `--gateway-url` flag overrides it per invocation. | +| `SEALGATE_API_KEY` | Optional. Present, it is embedded in the `/mcp/{key}/` path; absent, the path is `/mcp/` and auth is injected by an upstream proxy. | +| `SEALGATE_SECRET_KEY` | Zero-knowledge secret, sent as the `sealgate_secret_key` header. | +| `SEALGATE_CONVERSATION_ID` | Stable conversation id, sent as `x-sealgate-conversation-id`. Falls back to Centaur's `CENTAUR_THREAD_KEY`. | +| `SSL_CERT_FILE` / `REQUESTS_CA_BUNDLE` / `NODE_EXTRA_CA_CERTS` | Extra CA bundle to trust, for MITM inspection. The first one set wins. | -Claude Code skills live in `.claude/skills/`. Invoke them with `/skill-name` -(run `/onboarding`, `/update-backend`, `/code-quality`, `/cleanup`, and more). +## Agent Skills + +Claude Code and Codex skills live in `.claude/skills/`. Invoke them with +`/skill-name`: run `/onboarding`, `/update-backend`, `/code-quality`, +`/cleanup`, and more. Making backend changes? Start with the `update-backend` +skill for architecture details, command patterns, and `sealg` testing workflows. ## Credits @@ -116,3 +147,7 @@ This software uses the following tools: Made with [contrib.rocks](https://contrib.rocks). + +## License + +See [LICENSE](LICENSE).