npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@chatpanel/gateway

v0.6.60

Published

Local privacy gateway — redacts PII out of OpenAI/Anthropic API traffic before it reaches a model, then restores it in the reply. Point opencode, codex, aider, Claude Code, etc. at it.

Downloads

3,050

Readme

ChatPanel Privacy Gateway

A localhost server that puts ChatPanel's PII redaction / pseudonymization in the middle of two CLI agents — so you can use the privacy features outside the ChatPanel extension. Point opencode / pi at the gateway, and it drives codex / Claude Code behind your existing subscription login (via the bridge), redacting on the way out and restoring on the way back. The model only ever sees opaque placeholders like [[PERSON_1]] / [[EMAIL_2]]the real values never leave your machine.

  opencode / pi   (configured with a custom provider → the gateway)
        │   baseURL → http://127.0.0.1:4320/v1
        ▼
  ┌──────────────────────────────────────────────┐
  │  ChatPanel Privacy Gateway                    │
  │   1. detect + redact   →  [[PERSON_1]] …       │
  │   2. drive the agent behind your login        │
  │   3. restore placeholders in the reply         │
  └──────────────────────────────────────────────┘
        │   POST /chat  (bridge: subscription-authed CLI)
        ▼
  chatpanel-bridge ──spawns──▶ codex / claude   (your ChatGPT / enterprise / Claude login)

Two backends (config backend):

  • bridge (default) — drive the bridge's subscription-authed CLI agents (codex / claude / opencode / pi). No API keys, uses your login. This is the "privacy bridge between two agents" path above.
  • api — forward redacted traffic to a native OpenAI/Anthropic-compatible endpoint (local models, BYO keys). The client's own auth header passes through; the gateway stores no keys.

The redaction engine is the same code the ChatPanel extension runs — the @chatpanel/pii package is the single source of truth, so a privacy feature added once is shared everywhere.

Quick start (bridge backend)

You need the ChatPanel bridge running and logged into codex/claude (the same bridge the extension uses).

# Standalone binary — no Node.js required:
curl -fsSL https://dl.chatpanel.net/gateway/install.sh | bash   # macOS / Linux
#   Windows (PowerShell):  irm https://dl.chatpanel.net/gateway/install.ps1 | iex

# Or via npm (needs Node):
npm install -g @chatpanel/gateway
chatpanel-gateway
# → ChatPanel Privacy Gateway on http://127.0.0.1:4320
#     backend  : bridge (agent: codex, via http://127.0.0.1:4319)

Binary vs. npm — same features, very different local-AI speed. Both run identical redaction/routing. But the standalone binary runs the local models (speech-to-text, diarization, NER) on the WASM runtime — fp32-only, single-threaded, slow. The npm install uses the native runtime with quantized (q8) models — in our tests ~10× faster speech-to-text (real-time even on larger, more accurate models). If you'll use voice/meeting features, install via npm. Don't run both — they can shadow each other on PATH; check GET /healthstt.runtime (native vs wasm).

Then point your front-end agent at it. opencode (opencode.json):

{
  "provider": {
    "chatpanel": {
      "npm": "@ai-sdk/openai-compatible",
      "options": { "baseURL": "http://127.0.0.1:4320/v1" },
      "models": { "codex": {}, "claude": {} }   // selects the agent behind the gateway
    }
  }
}

Now opencode talks to codex through the gateway — every prompt is redacted before codex sees it, and the reply is restored before opencode renders it. The request's model (codex/claude/opencode/pi) picks which agent the bridge drives; otherwise the configured default (codex) is used.

Quick start (api backend — no bridge)

If all you want is the gateway as a redacting proxy in front of an API model, you do not need the bridge. Set backend: "api" and (optionally) point the gateway's upstream at your provider — in ~/.chatpanel/gateway.config.json:

{
  "backend": "api",
  "upstreams": {
    "openai":    { "baseUrl": "https://api.openai.com" },
    "anthropic": { "baseUrl": "https://api.anthropic.com" }
  }
}

Then point your client at the gateway and send your own API key — the gateway redacts, forwards to the provider with your key (it stores none), and restores the reply:

# In your CLIENT's environment (NOT the gateway's — see the footgun below):
export OPENAI_BASE_URL=http://127.0.0.1:4320/v1     # OpenAI-compatible: codex / aider / cursor / SDKs
export ANTHROPIC_BASE_URL=http://127.0.0.1:4320     # Claude Code / Anthropic SDK

To target a non-OpenAI provider (a local model, OpenRouter, Azure, …) change the gateway's upstreams.*.baseUrl in the config above — that's where the gateway forwards to. Flow: client → gateway (redact) → provider (your key) → gateway (restore) → client.

⚠️ Footgun: OPENAI_BASE_URL means two different things — for your client it's "where the gateway is", for the gateway it's "where my upstream is". Don't set OPENAI_BASE_URL=…:4320 in the gateway's own environment, or it forwards to itself (the loop guard returns 508). Set the gateway's upstream in the config file; use the env var only in the client's shell.

Name/org redaction is built in (in-process NER, no Python)

Deterministic redaction (emails, phones, cards, SSNs, API keys, IPs) needs no setup. To also blind names, organizations and locations, the gateway runs an in-process entity detector — an ONNX transformer model via transformers.js — with ner.autostart on (the default). There's no Python, no second port, no separate process: the same model runs identically on macOS / Windows / Linux. The model loads from ~/.chatpanel/models and is downloaded once on first run if absent (set ner.allowDownload: false to require it be pre-placed). It's fail-open, so if the model can't load the gateway just runs deterministic-only. Once the detector is ready, redaction switches to the full tier automatically.

The default model (Xenova/bert-base-NER) matches or beats spaCy's small model on people/orgs/locations. Larger or alternative models can be installed from the ChatPanel extension's Gateway settings.

Prefer a local LLM or your own external NER service? Set redaction.detection yourself and the gateway won't load the bundled one (yours takes precedence).

Configuration

Precedence: defaults < gateway.config.json (or $CHATPANEL_GATEWAY_CONFIG) < env vars. See gateway.config.example.json.

| Key | Env | Default | Meaning | |-----|-----|---------|---------| | backend | — | bridge | bridge (drive CLI agents via login) or api (forward to a provider) | | bridge.url | — | http://127.0.0.1:4319 | the ChatPanel bridge | | bridge.agent | — | codex | default agent the bridge drives | | bridge.token | — | (auto) | bridge bearer token; empty = read ~/.chatpanel/bridge-token | | host / port | CHATPANEL_GATEWAY_HOST / _PORT | 127.0.0.1 / 4320 | bind address | | upstreams.openai.baseUrl | OPENAI_BASE_URL | https://api.openai.com | api backend only | | upstreams.anthropic.baseUrl | ANTHROPIC_BASE_URL | https://api.anthropic.com | api backend only | | redaction.tier | CHATPANEL_REDACTION_TIER | basic | basic (regex) or full (+ NER + dictionary) | | redaction.detection | — | (off → bundled engine) | external detector; set to override the bundled in-process one | | redaction.dictionary | — | [] | custom { value\|pattern, type, alias? } entries | | ner.autostart | — | true | load the bundled in-process NER on startup | | ner.model | — | Xenova/bert-base-NER | model id under ~/.chatpanel/models | | ner.allowDownload | — | true | download the model on first run if absent |

Endpoints

| Route | Behavior | |-------|----------| | GET /health | { ok, version, backend, tier } | | GET /v1/models | the agent(s) this gateway exposes | | POST /v1/chat/completions | OpenAI protocol — redact → backend → restore | | POST /v1/responses | OpenAI Responses protocol (Codex) | | POST /v1/messages | Anthropic protocol (Claude Code) |

Streaming (SSE) is supported on all three: placeholders are restored on the fly, holding back a tail so a token split across chunks ([[PERSON_1]]) still restores cleanly.

Use it as an MCP server (Codex, Claude Code, any MCP client)

Point one MCP server at the gateway and any CLI agent can reach your local history (past chats, meeting transcripts, notes — redacted on the way out) and every skill installed on your machine — across Claude Code, Codex, Copilot, Gemini, Hermes, ~/.agents/skills and any folder you configure. History is served by the gateway; skills are proxied from the bridge (optional — if it is not running, the history tools still work and the skill tools say so).

It is a stdio MCP server: chatpanel-gateway mcp.

Codex — add to ~/.codex/config.toml:

[mcp_servers.chatpanel]
command = "chatpanel-gateway"
args = ["mcp"]

Corporate Codex with an approval guardian? If a tool call is rejected with "Automatic approval review failed" (an approvals_reviewer = "auto_review" policy can't assess a tool it doesn't know), pre-approve ChatPanel's read-only tools the same way you would any other server — one block per tool:

[mcp_servers.chatpanel.tools.search_history]
approval_mode = "approve"
[mcp_servers.chatpanel.tools.get_record]
approval_mode = "approve"
[mcp_servers.chatpanel.tools.list_history]
approval_mode = "approve"
[mcp_servers.chatpanel.tools.list_skills]
approval_mode = "approve"
[mcp_servers.chatpanel.tools.open_skill]
approval_mode = "approve"
[mcp_servers.chatpanel.tools.read_skill_file]
approval_mode = "approve"

All six only read local data (your redacted history and your installed skills), so approving them carries no write or network risk.

Claude Code — one command (--scope user makes it available in every project):

claude mcp add --scope user chatpanel chatpanel-gateway mcp

Any other MCP client — run the stdio server chatpanel-gateway mcp, or point at it the way your client configures a command + args stdio server.

If your client launches with a stripped PATH and cannot find chatpanel-gateway, use the absolute path (find it with which chatpanel-gateway).

Tools it exposes

| Tool | What it does | |------|--------------| | search_history | Full-text search your chats, meetings and notes by relevance | | get_record | Fetch one record's full text by id (chat:…, meeting:…, note:…) | | list_history | Browse/page the corpus (newest first, no bodies) | | list_skills | List every installed skill (name + one-line description, and where it came from) | | open_skill | Load one skill's full instructions by name | | read_skill_file | Read a reference file a skill's instructions point at |

Everything a history tool returns is redacted with the same engine (@chatpanel/pii) the gateway uses for model traffic — the real values never leave your device. Skill scripts are never served as text.

One local view

chatpanel-gateway local

prints what is running — the gateway (this) and the bridge (your agents + skills) — so you can see the whole local runtime at a glance. The bridge is an optional companion; a missing one is reported plainly, never as an error.

How it fits with ChatPanel

The extension redacts inside the browser; the bridge lets the browser drive local CLI agents. This gateway reuses the bridge to put the same redaction engine (@chatpanel/pii) in front of any agent — so non-browser tools get the privacy too, and the agent's own multi-turn loop is blinded, not just the first prompt.

Caveats

  • Reversibility is best-effort: if the model paraphrases a placeholder instead of echoing it, that one reference shows the token. The privacy guarantee (the real value never left the device) always holds.
  • A dictionary alias is a permanent pseudonym — the agent sees the alias, not the original, by design.
  • Code edits: redacting values that appear inside source can affect round-trip edits. The default tier touches only structured secrets and (in full) detected entities — keep your dictionary prose-focused.

Using it as an MCP server:

  • The gateway must be running for any of its tools to work — it is a background service (chatpanel-gateway --install registers it to start at login). If a tool returns "the ChatPanel gateway is not running", start it and retry; the message tells you the command.
  • Skills need the bridge (an optional companion). Without it, the history tools still work and the skill tools return a one-line "the bridge is not running — install it with …" — no silent empty result.
  • History tools search the gateway's warm store, which is seeded from your ChatPanel backups. If list_history says it is empty, the gateway has not been seeded yet — open ChatPanel so a backup lands, or check the ingest docs.
  • Everything returned is redacted at the configured tier. A tool result may contain a placeholder like [[EMAIL_1]] where a value was blinded — that is the privacy guarantee working, not a bug.

License

Source-available under the same license as the ChatPanel extension and bridge — see LICENSE.