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

umans-gate

v0.6.2

Published

LLM capture proxy with Anthropic cache_control TTL stamping, vision handoff, concurrency gating, rate limiting, and a live inspection dashboard

Downloads

4,052

Readme

umans-gate: stop guessing what your harness sends upstream

npm version npm downloads License: MIT CI CodeQL

umans-gate is a local capture proxy for LLM APIs that intercepts Anthropic and OpenAI-compatible traffic, stores every request and response in a SQLite ring buffer, and serves a live inspection dashboard over WebSocket. Run one command; point your agent harness at it; observe every byte on the wire.

Personal-use project, MIT-licensed, maintained by codegiveness. Not affiliated with, endorsed by, or an official product of Umans AI. Last updated: 2026-07-31 · Version 0.6.1.

Author: codegiveness, independent developer building LLM tooling and observability infrastructure. Source code published under MIT for transparency. No commercial support tier.

Setup in 30 seconds.

npm install -g umans-gate && umans-gate service install

This installs the proxy as a background service — it auto-starts on boot, survives terminal close, and auto-restarts on crash. The proxy listens on http://localhost:1945. The dashboard is served at http://localhost:1945/dashboard/. Point any Anthropic or OpenAI-compatible harness at the proxy URL. Every request and response is captured to SQLite.

What is umans-gate?

umans-gate is a local LLM API capture proxy that sits between an agent harness and the upstream LLM provider, stores every request and response in a SQLite ring buffer, and exposes a React dashboard with live WebSocket updates for inspecting traffic, cache behavior, and usage economics. It runs on Bun, requires no client-side code changes, and captures Anthropic and OpenAI-compatible endpoints in a single process.

Who should use umans-gate?

  • umans.ai users who need visibility into API traffic, cache control TTL behavior, and per-request token economics.
  • Agent harness users who must inspect and debug what their harness sends upstream: stamp pipeline output, thinking blocks, vision handoff.
  • Developers integrating Anthropic or OpenAI-compatible APIs who need traffic capture, concurrency gating, and rate-limit validation in one local tool.

Features

| Feature | Description | |---------|-------------| | Capture proxy | Intercepts LLM API traffic (Anthropic + OpenAI-compatible); stores in SQLite with optional zstd compression | | Stamp pipeline | Applies TTL, top_k, max_tokens, thinking, output_config, context_management, temperature stamps. Two toggles (Anthropic / OpenAI). | | Vision handoff | Replaces image blocks with text descriptions from a vision model; cached 7 days with persistent SQLite storage | | Concurrency gate | Semaphore + circuit breaker with intention-based reservations; hard cap and soft limit auto-sized from /v1/usage; queue timeout | | Rate limiting | Two gates: an upstream snapshot gate that rejects at hardCap - request_rate_margin based on the unweighted usage.requests_in_window, plus an optional local sliding-window weighted limiter (fallback) | | Connection warmer | Periodic /v1/models pings keep TLS warm; skips when real traffic occurred recently | | Usage tracking | Fetches /v1/usage to size concurrency, detect rate-boxing, manage priority demotion | | Live inspector | React + shadcn/ui dashboard with WebSocket live updates | | SSE rendering | Streaming responses captured and rendered with expandable event previews | | Ring buffer storage | Last N captures (default 200) in WAL-mode SQLite | | Write-behind queue | Batched DB writes to minimize blocking during streaming | | Hop-by-hop header stripping | Correct HTTP proxy behavior per RFC 7230 | | Protocol flexibility | Upstream HTTP/1.1 (default) or HTTP/2 |

Important notes

  1. The proxy modifies your requests. Stamping is on by default (STAMP_CLAUDE_CODE_ENABLED and STAMP_REASONING_EFFORT_ENABLED both default to true), so the proxy rewrites request bodies before forwarding upstream. The stamped body is what gets sent upstream AND captured. The proxy also forces accept-encoding: identity and strips content-encoding unconditionally. Toggle stamping off in the Config tab if you need a clean passthrough.
  2. Vision strategy and non-Claude Code harnesses. Vision handoff defaults to VISION_STRATEGY=never, so images pass through untouched unless you opt in. catalog means a cache miss halts the request, calls When reenabled, catalog means a cache miss halts the request, calls the vision model to describe the image, rewrites the body with the text description, then forwards — so non-vision models receive text they can process. Subsequent requests for the same image hit the cache and skip the vision call. Do NOT configure the model as vision-capable on the harness side (except Claude Code).
  3. Upstream target is hardcoded. Forwards to https://api.code.umans.ai. OpenAI chat path, warmer path, and vision target are also hardcoded, not configurable. Listen address is hardcoded to 127.0.0.1 (loopback only).
  4. Ring buffer overwrites old captures. Keeps only the last N (default MAX_CAPTURES=200). Increase in config for longer history.
  5. API key unlocks key features. Without UMANS_API_KEY, the proxy still captures traffic, but /v1/usage polling, concurrency gate sizing, rate-limit validation, and vision handoff stay disabled.
  6. Service install recommended. Without service install, umans-gate runs in the foreground and won't survive reboots or terminal close. Run umans-gate service install to register as a managed service.
  7. Default concurrency and the hard cap toggle. CONCURRENCY_HARD_CAP defaults to 16, CONCURRENCY_SOFT_LIMIT to 8. By default (USE_HARD_CAP=true), the effective limit is the hard cap. Both are auto-sized from /v1/usage when UMANS_API_KEY is set. Toggle in the dashboard Config tab. No restart needed.

Usage rights

Personal-use project with architecture modeled on production patterns but single-maintainer support. Source published under MIT for transparency and educational purposes. No guaranteed response time. No backward-compatibility commitment across versions; config shapes, flags, and APIs may change between releases without a deprecation cycle. No production support tier, no SLA. Security vulnerabilities are the one exception: see SECURITY.md for the 48-hour acknowledgment SLA on confirmed reports.

Not an official Umans product. Not affiliated with, endorsed by, or supported by Umans AI. All upstream service names, model names, and API endpoints belong to their respective owners.

How to install umans-gate

umans-gate ships as a pre-compiled npm binary and a standalone Bun/TypeScript source. The npm path requires no prerequisites; the Bun path requires Bun ≥ 1.1.0.

npm (recommended):

npm install -g umans-gate && umans-gate service install

The service install step registers umans-gate as a background service — it auto-starts on boot and survives terminal close. If you skip it, umans-gate runs in the foreground and dies when you close your terminal.

npx (temporary, no install):

npx umans-gate

⚠️ npx runs a temporary instance that dies when you close the terminal. Don't use it for regular use — install with npm install -g and service install instead.

Bun (for developers):

git clone https://github.com/codegiveness/umans-gate.git
cd umans-gate && bun install && bun src/cli.ts

No prerequisites for npm/npx. The package bundles a pre-compiled binary. For development, Bun ≥ 1.1.0 is required.

Platform support

| OS | Arch | npm Package | |----|------|-------------| | macOS | arm64/x64 | umans-gate-darwin-{arm64,x64} | | Linux | x64/arm64 | umans-gate-linux-{x64,arm64} | | Windows | x64/arm64 | umans-gate-win32-{x64,arm64} |

How to use umans-gate

Point any Anthropic or OpenAI-compatible agent harness at the proxy URL (http://localhost:1945). Every request and response is captured to SQLite and visible in the live dashboard at /dashboard/.

  1. Start the proxy: umans-gate service install (installs as background service — auto-starts on boot, survives terminal close). Already installed? Start it with umans-gate service start.

  2. Point your harness to http://localhost:1945:

    export ANTHROPIC_BASE_URL=http://localhost:1945
    export OPENAI_BASE_URL=http://localhost:1945
  3. Open the dashboard at http://localhost:1945/dashboard/

  4. Set your API key (optional but recommended):

    export UMANS_API_KEY=your-key-here
    # Or edit config.json: umans-gate config show
    # Or use the dashboard Config tab

    Enables /v1/usage polling, concurrency gate sizing, rate-limit validation, and vision handoff.

  5. Secure the dashboard (optional): export DASHBOARD_TOKEN=your-secret-token. When set, all /dashboard/api/* routes, /health, and /metrics require Authorization: Bearer <token>. WebSocket requires ?token=<token>. Includes brute-force protection.

  6. Make it survive reboots: umans-gate service install (already done if you followed the install steps above; this is just for reference).

Updating

umans-gate update          # self-update (npm global or standalone binary)
umans-gate update --check # check without installing
umans-gate uninstall      # removes service, config, database, binary

The updater detects install method and acts accordingly. If running as a managed service, stops before update and restarts after. Pass --keep-config to preserve config.json and the database.

Service persistence

umans-gate service install        # register as managed service
umans-gate service install --force # overwrite existing definition
umans-gate service start|stop|restart|status|logs|uninstall

| Platform | Service manager | Unit location | |----------|----------------|---------------| | Linux | systemd (user unit + linger) | ~/.config/systemd/user/umans-gate.service | | macOS | launchd (LaunchAgent) | ~/Library/LaunchAgents/com.umans.gate.plist | | Windows | Windows Service (via NSSM) | Registered with sc.exe |

The service uses Restart=always / KeepAlive=true and auto-starts on boot. API keys set via env var are stored securely (separate EnvironmentFile with chmod 600 on systemd, in the plist on launchd, in the service registry on Windows). When running as a managed service, the dashboard Restart button works automatically.

How configuration works

umans-gate loads configuration from a JSON file with environment variable overrides. On first run, loadConfig() writes defaults if the file does not exist; existing configs are never overwritten. All env vars have snake_case JSON equivalents. Precedence, highest to lowest: env vars > JSON config > built-in defaults.

Dashboard-first: Edit config via the Config tab at http://localhost:1945/dashboard/. The dashboard validates, shows field descriptions, and can hot-reload or restart.

| OS | Path | |----|------| | Linux/macOS | $XDG_CONFIG_HOME/umans-gate/config.json or ~/.config/umans-gate/config.json | | Windows | %APPDATA%/umans-gate/config.json |

Precedence (highest to lowest): env vars > JSON config > built-in defaults.

Key config fields

| Variable | Default | Description | |---|---|---| | PORT | 1945 | Listen port | | MAX_CAPTURES | 200 | Ring buffer size | | DB_PATH | ./umans-gate.db | SQLite database path | | UPSTREAM_PROTOCOL | http1.1 | http1.1 or http2 | | UPSTREAM_TIMEOUT_MS | 1800000 | Upstream fetch timeout (30 min) | | STAMP_CLAUDE_CODE_ENABLED | true | Toggle Claude Code stamp bundle (Anthropic) | | STAMP_REASONING_EFFORT_ENABLED | true | Toggle reasoning_effort stamping (OpenAI) | | STAMP_MODEL_RULES | [] | Per-model thinking-shape rules table (ADR-0029, hot-reloadable) | | UMANS_API_KEY | (empty) | Unlocks /v1/usage, gate sizing, rate-limit, vision | | DASHBOARD_TOKEN | (empty) | Secures dashboard + /health + /metrics + WS | | CONCURRENCY_HARD_CAP | 16 | Max concurrent upstream (auto from /v1/usage) | | CONCURRENCY_SOFT_LIMIT | 8 | Soft limit (auto from /v1/usage) | | USE_HARD_CAP | true | true = use hard cap; false = use soft limit | | VISION_STRATEGY | never | never, catalog, or always | | VISION_MODEL | umans-flash | Vision model for image description | | BREAKER_THRESHOLD | 5 | Circuit breaker failure threshold | | RATE_LIMIT_REQUESTS | 0 | 0 = auto, -1 = unlimited, N = explicit |

See AGENTS.md for the complete config field table.

Hot reload

The Config tab can save and hot-reload via POST /dashboard/api/config/reload. Hot-reloadable: all fields except those marked restartRequired (e.g. port, db_path, upstream_protocol, vision_strategy, vision_model, warmer_*, umans_api_key, dashboard_token). The full set of hot-reloadable fields is defined in src/config/reload.ts (RELOAD_FIELDS). Fields marked restartRequired require a server restart.

How the stamp pipeline works

When STAMP_CLAUDE_CODE_ENABLED is true, the proxy applies the following stamps to Anthropic requests before forwarding upstream. The stamped body is what gets sent upstream AND what gets captured. The inspector shows exactly what went to the API.

  • TTL: "1h" on cache_control ephemeral blocks
  • top_k: 20
  • temperature: 1.0
  • max_tokens: 131071 for umans-glm* models, 32767 for others
  • thinking: { "type": "adaptive" } as the overlay default; per-model shapes via STAMP_MODEL_RULES (ADR-0029)
  • output_config: effort high or max
  • context_management: clear_thinking

Per-model rules (STAMP_MODEL_RULES, ADR-0029): a config-driven rules table that overrides the adaptive thinking shape per model family on both Anthropic and OpenAI routes. Each rule matches a model name pattern (glob, first-match-wins) and can set anthropic_thinking_shape, openai_thinking_shape, openai_extra_body, and openai_veto_reasoning_effort. Rules are independent of the master toggles and hot-reloadable. See ADR-0029 for the full spec and target table.

For OpenAI-compatible requests, STAMP_REASONING_EFFORT_ENABLED injects reasoning_effort, strips output_config and context_management, and forces temperature: 1.0. The thinking field is controlled by STAMP_MODEL_RULES (PerModelRuleStep), not by reasoning_effort stamping.

How vision handoff works

The vision handoff replaces image blocks in requests with text descriptions generated by a vision model. This reduces token cost and enables text-only models to process image-bearing requests. Descriptions are cached for 7 days in persistent SQLite storage.

Vision handoff defaults to never (2026-08). umans.ai discontinued its subscription plan; only the wallet mechanism remains, so a fresh install ships with VISION_STRATEGY=never (no image handling). The pipeline is fully configurable — set VISION_STRATEGY to catalog or always in the dashboard Config tab or via config.json/env to opt in. No existing workflow is affected: with the default, images pass through untouched.

Strategies (VISION_STRATEGY):

| Strategy | Behavior | |----------|----------| | never (default) | Never replace images; pass through untouched | | catalog | Replace images only if the target model lacks vision capability | | always | Always replace images with text descriptions |

Intent-aware prompting (VISION_INTENT_STRATEGY, default auto): accepts off, slotted, crafted, or auto. When auto, a deterministic triage function routes each request to one of four strategies (generic, slotted, crafted, decomposed) based on adjacent text, image count, and tool-result status. off forces generic only. Vision calls are serialized by the concurrency gate (default concurrency = 4). Descriptions are cached for 7 days in persistent SQLite storage.

How the concurrency gate works

The concurrency gate regulates upstream parallelism using three mechanisms: a semaphore enforcing soft/hard limits, a circuit breaker for failure isolation, and intention-based reservations with a bounded queue.

  1. Semaphore: enforces a soft limit and a hard cap on concurrent upstream requests. Both are auto-sized from /v1/usage when UMANS_API_KEY is set.
  2. Circuit breaker: opens after BREAKER_THRESHOLD (default 5) HTTP 429 responses within BREAKER_WINDOW_MS (default 5 minutes), blocks traffic for BREAKER_COOLDOWN_MS (default 60 seconds), then half-opens to probe recovery.
  3. Intention-based reservations + queue: main and vision lanes hold reserved slots; excess requests enter a bounded queue (MAX_QUEUE_DEPTH, default 100) with a timeout (QUEUE_TIMEOUT_MS, default 180 seconds).

How rate limiting works

Requests are protected by two gates. The upstream snapshot gate is the authoritative one: it compares the live, unweighted usage.requests_in_window from /v1/usage against limits.requests.hard_cap - request_rate_margin (default margin 50). When the window count reaches that threshold it rejects locally with 503 rate_limit_exceeded + retry-after, so the request is never forwarded upstream and the wallet never trips the upstream hard cap. This gate is active regardless of the knobs below and cannot be disabled (the live snapshot is the single source of truth).

The optional local weighted limiter is a sliding-window weighted counter used as a fallback for bursts between /v1/usage polls. It is controlled by RATE_LIMIT_REQUESTS and NEVER_LIMIT_REQUESTS:

| RATE_LIMIT_REQUESTS | Behavior | |-----------------------|----------| | 0 (default) | Auto-derived from /v1/usage | | -1 | Disables the local weighted limiter (upstream gate stays active) | | N (positive integer) | Explicit weighted sliding window of N requests |

NEVER_LIMIT_REQUESTS disables the local weighted limiter only; it has no effect on the upstream snapshot gate. REQUEST_RATE_MARGIN (default 50) controls how far below the hard cap the proxy rejects.

Programmatic API

import { createProxyServer } from "umans-gate";

const server = createProxyServer({
  config: { port: 8080 },
});

// server.db    : CaptureDB instance
// server.ws    : WsBroadcaster instance
// server.queue : WriteQueue instance
// server.shutdown(): graceful shutdown

Development

bun run dev             # start proxy server
bun run typecheck       # TypeScript checking
bun run lint            # Biome lint
bun run lint:fix       # Biome lint + auto-fix
bun run test            # server tests
bun run test:dashboard  # dashboard tests (vitest + jsdom)
bun run test:all        # server + dashboard tests
bun run build           # build server (tsup) + dashboard (vite)

FAQ

Is umans-gate free?

Yes. umans-gate is MIT-licensed and free to use, modify, and distribute. The npm package (npm install -g umans-gate) and standalone binaries are free. No paid tier, no feature gating. Source code is public on GitHub.

Does umans-gate work with Claude Code?

Yes. umans-gate intercepts Anthropic API traffic, which is what Claude Code uses. Point ANTHROPIC_BASE_URL at the proxy (http://localhost:1945) and every request is captured. The stamp pipeline (STAMP_CLAUDE_CODE_ENABLED=true) applies TTL, top_k, temperature, max_tokens, thinking, output_config, and context_management stamps to Anthropic requests.

Does umans-gate work with OpenAI-compatible APIs?

Yes. The proxy intercepts OpenAI-compatible traffic on /v1/chat/completions. With STAMP_REASONING_EFFORT_ENABLED=true, it injects reasoning_effort, strips output_config and context_management, and forces temperature: 1.0. The thinking field is controlled by STAMP_MODEL_RULES (per-model rules, ADR-0029), not by reasoning_effort stamping.

What is the difference between umans-gate and a regular HTTP proxy?

⚠️ Experimental: enabled by stamp_claude_code_enabled (default: on)

A regular HTTP proxy forwards traffic. umans-gate captures every request/response pair to SQLite, stamps ttl onto cache_control ephemeral blocks, runs a vision handoff pipeline (image → text description), enforces concurrency limits with a circuit breaker, and serves a live React dashboard over WebSocket. It is purpose-built for LLM API traffic observation and optimization.

Does umans-gate modify my requests?

By default, the proxy applies minor body modifications: it strips oh-my-openagent's [Category+Skill Reminder] text blocks from Anthropic requests (EXPERIMENT_STRIP_OMO_REMINDER, default: on), and it always forces accept-encoding: identity and strips content-encoding for capture safety. Full stamping (STAMP_CLAUDE_CODE_ENABLED for Anthropic, STAMP_REASONING_EFFORT_ENABLED for OpenAI) is on by default — the proxy rewrites request bodies (TTL, thinking, max_tokens, etc.) before forwarding upstream, and the stamped body is what gets captured. Toggle any of these off in the Config tab for a clean passthrough.

What is the ring buffer and how many captures does it store?

The ring buffer is a SQLite table capped at MAX_CAPTURES (default 200). When the limit is reached, the oldest captures are evicted. Increase MAX_CAPTURES in config for longer history. Bodies are optionally compressed with zstd, and capture_body_max_bytes (default 10 MB) limits per-capture size.

Can I run umans-gate in production?

umans-gate is a personal-use project with no production support tier, no SLA, and no backward-compatibility commitment. It is designed for local development and debugging. Security vulnerabilities are the exception. See SECURITY.md for the 48-hour acknowledgment SLA.

How do I secure the dashboard?

Set DASHBOARD_TOKEN via env or config. When set, all /dashboard/api/* routes, /health, /metrics, and WebSocket connections require Authorization: Bearer <token> (or ?token=<token> for WS). Includes brute-force protection.

Does umans-gate support HTTP/2?

Yes, as an opt-in. Set UPSTREAM_PROTOCOL=http2 in config or env. HTTP/1.1 is the default because benchmarks show no measurable difference at typical LLM concurrency levels (4 concurrent SSE streams). See BENCHMARKS.md for details.

What is vision handoff and when should I use it?

Vision handoff replaces image blocks in requests with text descriptions generated by a vision model (default umans-flash). This reduces token cost and enables text-only models to process image-bearing requests. Descriptions are cached for 7 days. Vision handoff is currently disabled by default (VISION_STRATEGY=never) while umans.ai's subscription plan is unavailable; it will be reactivated when a new plan or a cheaper multimodal model is available. When enabled, use VISION_STRATEGY=always to intercept all images, catalog to intercept only when the target model lacks vision capability, or never to disable.

Documentation

Start here: Documentation Index: curated reading guide

Understand:

Operate:

Develop:

Design:

License

MIT. See LICENSE. This project provides llms.txt for LLM discoverability.