@roxy-agent/agents
v0.5.1
Published
MCP server that proxies all agent actions, classifies risk, enforces natural-language policies, and logs to a local SQLite audit DB with a live dashboard.
Downloads
1,390
Maintainers
Readme
@roxy-agent/agents
An MCP server that proxies all agent actions — bash, filesystem, network — through a sub-millisecond risk classifier and an audit log. Streams to the hosted dashboard at roxy-agent-web.vercel.app.
Quick start
For the safest onboarding, run the client hardening flow instead of only pasting an MCP snippet:
npx -y @roxy-agent/agents protect --all
npx -y @roxy-agent/agents connect
npx -y @roxy-agent/agents doctorprotect installs Roxy MCP and a client-specific lockdown profile where the
client supports one. doctor verifies the local protection level:
- Advisory: MCP/rules are installed, but the client may still expose direct built-in tools.
- Enforced: direct shell/file/network paths are denied, hooked, or sandboxed for the detected client.
- Enterprise locked: managed config or runtime policy prevents local users from weakening the profile.
- Bypass detected: Roxy is configured, but no audited events are appearing.
You can scope the install to one client:
npx -y @roxy-agent/agents protect --client claude-code
npx -y @roxy-agent/agents protect --client codex
npx -y @roxy-agent/agents protect --client cursorCursor currently remains advisory unless you run it inside a Roxy-controlled runtime or custom mode that removes direct side-effect tools. Claude Code gets the strongest local profile today: Roxy MCP, direct-tool deny rules, Roxy MCP allowlisting, and a PreToolUse bypass hook.
Manual MCP setup
Add this to your MCP config (~/.cursor/mcp.json for Cursor, ~/Library/Application Support/Claude/claude_desktop_config.json for Claude Desktop, the equivalent for Codex):
{
"mcpServers": {
"agent-proxy": {
"command": "npx",
"args": ["-y", "@roxy-agent/agents"]
}
}
}Reload MCP servers (or restart the host). On first launch npx downloads the package and:
Creates an audit DB at
~/.agent-proxy/audit.db.Begins streaming each tool call (metadata only, by default) to the hosted dashboard.
Prints a one-time pairing URL like:
[agent-proxy] ────────────────────────────────────────────── [agent-proxy] Sign in to view this proxy's audit log online: [agent-proxy] https://roxy-agent-web.vercel.app/pair?code=W79M-5BVD [agent-proxy] (Pairing code: W79M-5BVD — valid 10 minutes.) [agent-proxy] ──────────────────────────────────────────────Open it. The page asks you to sign in (or create an account), then "Link this device" attaches the running proxy to your account. The proxy detects the link within ~3 seconds and from then on uploads under your user id.
Visit roxy-agent-web.vercel.app/dashboard. Once signed in, it shows events from all devices you've paired — codex on your laptop, claude on your desktop, etc.
You can also create and wait on a pairing link directly:
npx -y @roxy-agent/agents connectPrivacy / what gets uploaded
Cloud sync sends metadata only by default:
- Tool name + action type (e.g.
bash.execute) - Risk level, decision, reason
- A 240-character truncation of the command / path / URL the dashboard already shows
- Timestamps, durations, error strings (truncated)
It does not send full stdout/stderr, file contents, or response bodies unless you set AGENT_PROXY_CLOUD_PAYLOADS=full. To disable cloud sync entirely:
AGENT_PROXY_CLOUD_SYNC=0 npx -y @roxy-agent/agents(or set it as an env value in your MCP config block).
Environment variables
| Variable | Default | Meaning |
| --- | --- | --- |
| AGENT_PROXY_DATA_DIR | ~/.agent-proxy | Where audit.db and license.json live |
| AGENT_PROXY_ML_CACHE | ~/.agent-proxy/models | Where the embedding model is cached |
| AGENT_PROXY_CLOUD_SYNC | 1 | Set to 0 to disable hosted-dashboard uploads |
| AGENT_PROXY_CLOUD_URL | https://roxy-agent-web.vercel.app | Override the hosted dashboard URL (self-host) |
| AGENT_PROXY_CLOUD_PAYLOADS | metadata | Set to full to send raw command/result bodies |
| AGENT_PROXY_CLOUD_INTERVAL_MS | 5000 | How often to flush the upload queue |
| AGENT_PROXY_PAIRING | 1 | Set to 0 to skip the device-pairing prompt on launch |
| AGENT_PROXY_SESSION_ID | random UUID | Override the session id for traceability |
Run from source (for local development)
git clone https://github.com/dwang88/agent-proxy
cd agent-proxy
npm install
npm run build
npm run dev # tsx src/index.tsThen point your MCP config at node /path/to/agent-proxy/dist/index.js instead of npx -y @roxy-agent/agents.
Self-hosting the dashboard
The dashboard lives in web/ and is a vanilla Next.js app deployed to Vercel. To run your own hosted dashboard:
cd web
npm install
npm run bundle # copies dashboard JS/CSS from ../src/dashboard
DATABASE_URL=postgres://... npm run devSet AGENT_PROXY_CLOUD_URL on every machine running the local proxy to point at your deployment. The local proxy no longer serves a browser dashboard; all UI lives in the hosted app.
The dashboard is a four-tab single-page app:
- Overview — today's KPIs, 24h sparkline, recent activity, top firing policies
- Activity — full event log with search, tool/decision filters, time range, and a drawer that shows the full payload, classifier reasoning, and adjacent session events
- Policies — manage natural-language allow/block rules; inline tester scores any command against every policy with a similarity bar
- Insights — stacked area chart of allowed/flagged/denied per hour, tool & decision distributions, ML model stats, top denied/flagged actions, recent sessions
Set in Geist Sans + Geist Mono + Geist Pixel, self-hosted from the geist npm package — no Google Fonts dependency, works offline. Includes a ⌘K command palette and g o/g a/g p/g i keyboard navigation.
MCP config — alternatives
The recommended config is npx -y @roxy-agent/agents (see Quick start above). You can also point your MCP host at a local checkout:
Built from source:
{
"mcpServers": {
"agent-proxy": {
"command": "node",
"args": ["/absolute/path/to/agent-proxy/dist/index.js"]
}
}
}Source mode (no build step), useful while iterating:
{
"mcpServers": {
"agent-proxy": {
"command": "npx",
"args": ["tsx", "/absolute/path/to/agent-proxy/src/index.ts"]
}
}
}Pin a specific version (recommended for teams to avoid surprise updates):
{
"mcpServers": {
"agent-proxy": {
"command": "npx",
"args": ["-y", "@roxy-agent/[email protected]"]
}
}
}Project rules snippet
Drop this into a project's AGENTS.md or .cursor/rules/ to nudge the agent toward the proxy:
You have access to an `agent-proxy` MCP server. Use it for all side effects:
- Use the `bash` tool from agent-proxy instead of running shell commands directly.
- Use `read_file`, `write_file`, `delete_file`, `list_directory` instead of direct file ops.
- Use `fetch_url` for any HTTP requests.
All actions are logged. The audit dashboard is at https://roxy-agent-web.vercel.app/dashboard.Environment variables
| Variable | Default | Purpose |
| --- | --- | --- |
| AGENT_PROXY_DATA_DIR | ~/.agent-proxy | Where the audit DB, license, and model cache live. Falls back to <repo>/data/ if you launched from a source checkout that already has one. |
| AGENT_PROXY_SESSION_ID | random UUID | Override the session id (handy for per‑task traceability). |
| AGENT_PROXY_ML | enabled | Set to 0 to disable the embedding-based bash classifier and use rules only. |
| AGENT_PROXY_ML_MODEL | Xenova/all-MiniLM-L6-v2 | Hugging Face model id used for the bash classifier embedder. |
| AGENT_PROXY_ML_CACHE | ~/.agent-proxy/models | Where transformers.js caches model files. |
| AGENT_PROXY_POLICIES | enabled | Set to 0 to disable natural-language policies. |
| AGENT_PROXY_POLICY_THRESHOLD | 0.40 | Minimum cosine similarity for a policy to match. |
| AGENT_PROXY_SCOPES | global | Comma-separated list of scopes whose policies are active in this session. |
| AGENT_PROXY_POLICY_SUGGEST_API_KEY | unset | OpenAI-compatible API key for Policies → Industry templates (LLM-generated policy suggestions). |
| AGENT_PROXY_POLICY_SUGGEST_BASE_URL | https://api.openai.com/v1 | Chat Completions API base URL (OpenRouter, Azure, etc.). |
| AGENT_PROXY_POLICY_SUGGEST_MODEL | gpt-5.4 | Model id for suggestions. |
| AGENT_PROXY_POLICY_SUGGEST_HEADERS | unset | Optional JSON object of extra HTTP headers for the completions request. |
Layout
src/
index.ts # MCP server entry point
db.ts # SQLite + queries
classifier.ts # rule-based + ML + policy combined classifier
policies.ts # natural-language allow/block policies (CRUD + matching)
logger.ts # logEvent + updateEventResult, mirrors to stderr
cloud-sync.ts # Hosted dashboard upload, pairing, and command polling
tools/
bash.ts
filesystem.ts
network.ts
ml/
embedder.ts # transformers.js feature-extraction pipeline
prototypes.ts # labeled bash command prototypes
bash-classifier.ts # k-NN classifier over embedded prototypes
data/
audit.db # auto-created (events + policies tables)
models/ # cached ONNX model filesAudit DB schema
CREATE TABLE events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT NOT NULL,
session_id TEXT NOT NULL,
tool TEXT NOT NULL,
action_type TEXT NOT NULL,
payload TEXT NOT NULL, -- JSON
risk_level TEXT NOT NULL, -- low|medium|high
decision TEXT NOT NULL, -- allowed|denied|flagged
result TEXT, -- summary string
duration_ms INTEGER,
error TEXT,
reason TEXT -- classifier reason
);
CREATE TABLE policies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
kind TEXT NOT NULL, -- allow|block
description TEXT NOT NULL, -- natural language
scope TEXT NOT NULL DEFAULT 'global',
applies_to TEXT NOT NULL DEFAULT '*', -- bash|filesystem|network|*
enabled INTEGER NOT NULL DEFAULT 1,
match_count INTEGER NOT NULL DEFAULT 0,
embedding BLOB, -- 384-dim float32, lazily filled
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);