Observed since 20 Oct, 18:58 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Local-first LLM key manager and localhost gateway for safer AI apps and agents.
Never accidentally share your LLM API keys again.
21pins is a local-first CLI and localhost gateway for LLM apps, agents, and experiments. Store your provider keys once on your own machine, then give each app a scoped 21pins token instead of handing out real OpenAI, OpenRouter, Anthropic, DeepSeek, Venice, Hetzner, Maple, Gemini, or Ollama credentials.
It speaks the OpenAI-compatible /v1/chat/completions shape, so many tools can use it by changing only the base URL, API key, and model name.
127.0.0.1; provider keys stay in your local 21pins state file.proxy:chat,usage:read without exposing your upstream OpenRouter key.openrouter/openai/gpt-4o-mini, openai/gpt-4o-mini, or ollama/llama3.2 through one local gateway.npm install -g 21pins
Then initialize local state:
21pins init
Your local state is separate from the npm package. Upgrading or reinstalling the npm package does not delete your stored keys, tokens, grants, receipts, or usage rows.
Default state paths:
Linux: ~/.config/21pins/state.json
macOS: ~/Library/Application Support/21pins/state.json
Set PINS21_STATE_PATH if you want to store state somewhere else.
Add your OpenRouter key once:
21pins key set openrouter --value "$OPENROUTER_API_KEY"
Create a scoped token for Pi or another local app:
21pins token create pi --scopes proxy:chat,usage:read
Start the local gateway:
21pins serve --port 8787
Configure your OpenAI-compatible client:
Base URL: http://127.0.0.1:8787/v1
API key: the 21pins token, not your OpenRouter key
Model: openrouter/openai/gpt-4o-mini
21pins forwards the request with your stored OpenRouter key and records local usage/cost data when the upstream response includes usage.
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.PINS21_TOKEN,
baseURL: "http://127.0.0.1:8787/v1",
});
const response = await client.chat.completions.create({
model: "openrouter/openai/gpt-4o-mini",
messages: [{ role: "user", content: "Say pong." }],
});
console.log(response.choices[0].message.content);
Create your app token with usage:read, start the gateway, then open:
http://127.0.0.1:8787/ui
Or fetch JSON:
curl -H "Authorization: Bearer $PINS21_TOKEN" \
http://127.0.0.1:8787/v1/usage
/ui and /v1/usage are loopback-only. /v1/usage requires the usage:read scope.
21pins currently wires:
List providers:
21pins key providers
Sync model catalogs where supported:
21pins models sync
21pins models list --provider openrouter --search gpt
21pins models choose --provider openrouter --search gpt
21pins is intentionally boring:
127.0.0.1Still treat every 21pins token like a bearer credential. If you paste it somewhere unsafe, rotate it.
MIT
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.1Registry latest | 4 Sept 2026 | 4 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 18:58 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:b5114e0032722bbad368e673ba7df31024156f78b97c8f849da500d4aa2caba9