nice
by fainir
README.md
# nice.
**The access layer between your AI agents and everything they touch.**
[](https://github.com/fainir/nice/actions/workflows/ci.yml)
[](LICENSE)


Add an API key or connect an app **once**, in a web UI. Pair each machine **once**, with a single command. Every agent you run - Claude Code, custom scripts, any CLI - gets exactly the access you scope to it: injected as env vars, or proxied through the hub so the agent **never holds a raw key at all**. Every access is audited. Any device can be cut off in one click.
Your keys today: pasted into `.env` files and MCP configs across every laptop, unrotated, unauditable, unrevocable. This replaces that.
## How it works
```
┌─────────────┐ pair once ┌──────────────┐ scoped, audited ┌──────────────┐
│ nice hub │ ◄──────────────── │ your machine │ ◄──────────────── │ your agents │
│ (self-host) │ │ (nice CLI) │ env or MCP │ claude, ... │
└─────────────┘ └──────────────┘ └──────────────┘
encrypted vault, web UI, device token, nice run -- claude
OAuth refresh, audit log ~/.nice/config nice mcp serve
```
## Quickstart
Requires Node 22+. Zero dependencies - nothing to install.
```sh
git clone https://github.com/fainir/nice && cd nice
node server/server.js
# nice hub listening on http://localhost:8787
```
1. Open http://localhost:8787, create your account, and add a connection (an API key, or OAuth once configured). Secrets are AES-256-GCM encrypted before touching disk; the UI only ever shows the last 4 characters again.
2. Install the CLI and pair the machine your agents run on (Devices tab → "Pair a device"):
```sh
npm install -g . # from the repo; gives you the `nice` command
nice pair <CODE> --server http://localhost:8787
```
3. Give every agent access:
```sh
nice run -- claude # any command, all scoped keys injected as env vars
nice run --only GITHUB_TOKEN -- npx -y @modelcontextprotocol/server-github
eval "$(nice env)" # or load into the current shell
nice status # what this machine can reach
nice unpair # revoke this machine, server-side too
```
## Gateway mode - agents never see your keys
```sh
nice mcp serve
```
runs an MCP server (stdio) exposing `list_connections` and `http_request`. When an agent calls `http_request`, the **hub** makes the API call and injects auth server-side - the credential never enters the agent's process. Requests are restricted to each provider's real API origin, client-supplied auth headers are stripped, and every call is audited.
Plug into Claude Code via `.mcp.json`:
```json
{ "mcpServers": { "nice-hub": { "command": "nice", "args": ["mcp", "serve"] } } }
```
## Scoping, audit, revocation
- **Scope per device**: in the Devices tab, limit any paired machine to exactly the connections it should see - enforced for both env injection and the gateway.
- **Audit everything**: every login, key save, pairing, secret read, and proxied call lands in a per-user audit log with the acting device.
- **Revoke instantly**: delete a device in the UI (or `nice unpair` from the machine) and its access dies immediately.
## Connect apps with sign-in (OAuth)
The full authorization-code flow (single-use state, encrypted token storage, automatic refresh) is built in for GitHub, Google, and Slack - and any custom OAuth provider. Register an OAuth app with the provider (callback: `<your hub>/oauth/callback`), then:
```json
// data/oauth.json
{ "github": { "clientId": "...", "clientSecret": "..." } }
```
A "Connect with sign-in" button lights up on the Connections tab - no restart needed. Tokens refresh automatically whenever an agent uses them.
## Deploy
```sh
docker build -t nice-hub .
docker run -d -p 8787:8787 -v nice-data:/data --name nice-hub nice-hub
```
The vault (store + master key) lives in the `nice-data` volume - back it up. **Always put TLS in front** (Caddy, nginx, or your platform) for any non-localhost deployment.
| Env var | Default | Meaning |
|---------|---------|---------|
| `NICE_PORT` | `8787` | server port |
| `NICE_DATA` | `./data` | server data dir (store + master key + oauth.json) |
| `NICE_HOME` | `~/.nice` | CLI config dir |
## Security model
Self-host trust model: your machine, your keys, your master key. Vault encrypted with AES-256-GCM; passwords scrypt-hashed; tokens stored only as SHA-256 hashes; single-use expiring pairing codes; rate-limited auth; origin-allowlisted proxy. Full details and reporting instructions in [SECURITY.md](SECURITY.md).
## FAQ
**Why trust this with my keys?** You don't have to trust anyone - it's self-hosted, zero-dependency, and small enough to read in an afternoon (~1500 lines). Your keys never leave your infrastructure.
**How is this different from 1Password CLI or Doppler?** Those inject secrets for humans and CI. Nice is agent-native: per-device pairing and scoping, an audit trail of what each agent read, one-click revocation, OAuth refresh handled for you, and an MCP gateway where agents call APIs without ever holding credentials.
**What if the hub is down?** `nice run` fails closed (no stale secrets on disk). Run the hub on the same machine or your LAN for zero-dependency startups.
**Is there a hosted version?** Not yet. The roadmap includes a zero-knowledge hosted mode - where the server cannot decrypt your vault - after an external audit.
## Contributing
PRs welcome - see [CONTRIBUTING.md](CONTRIBUTING.md). Security reports: [SECURITY.md](SECURITY.md) (please, not public issues).
## License
[MIT](LICENSE)
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues