Install
$ agentstack add skill-osouthgate-agent-plus-skills-openrouter-remote ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
openrouter-remote
Stdlib-only Python 3 CLI wrapping three OpenRouter surfaces:
- Balance —
GET /api/v1/credits(needs user key) - Models —
GET /api/v1/models(no auth) with rich client-side filtering - Keys —
/api/v1/keys*(needs provisioning key, a distinct credential)
Lives at ${CLAUDE_SKILL_DIR}/../../bin/openrouter-remote; the plugin auto-adds bin/ to PATH.
Every JSON payload carries a top-level tool: {name, version} field. Check it with openrouter-remote --version, or inspect live output via openrouter-remote balance --json | jq .tool — useful when debugging whether an agent is hitting a stale plugin install.
Pipe JSON through jq for any non-trivial slicing — e.g. models list --json --supports tools | jq '.[] | select(.context_length >= 200000) | .id', or usage --json | jq '.totals.monthly'. The CLI's built-in filters cover the common cases; jq is the escape hatch for everything else without re-fetching.
When to reach for this
- User asks about balance, remaining credits, or current spend.
- User wants to know which model to use for a task (cheapest with tools, biggest context, etc.).
- User wants to create / disable / delete API keys or change their limits.
- You're configuring a Hermes cron that needs to alert when credits get low — use
balance --alert-below.
Do NOT use this for making chat completions — that's what an OpenAI-compatible SDK pointed at https://openrouter.ai/api/v1 is for. This plugin is management-plane only.
When NOT to use this — fall back to direct OpenRouter API calls
This wrapper is management-plane only. It covers balance, aggregated usage, model catalogue (list/cheap/show/endpoints), and user-key CRUD (list/show/create/disable/enable/rename/set-limit/delete). Everything else on OpenRouter is unwrapped — reach for curl https://openrouter.ai/api/v1/... with Authorization: Bearer $OPENROUTER_API_KEY directly. OpenRouter has no first-party CLI, so raw HTTP is the official escape hatch.
Specific cases where you should skip openrouter-remote and hit the API directly:
- Actual chat completions / generations. →
POST /api/v1/chat/completionsorPOST /api/v1/completions(OpenAI-compatible). Use an SDK pointed athttps://openrouter.ai/api/v1, orcurlfor a one-shot. This wrapper will never implement completions. - Streaming responses (SSE). → Same endpoints with
"stream": true. The wrapper's_http()is request/response only and buffers the whole body. - Generation metadata for a specific call (cost, tokens, native finish reason, provider chosen). →
GET /api/v1/generation?id=after a completion. Not exposed here. - Model / app rankings and provider-level analytics. →
GET /api/v1/analytics/*and the/frontend/*endpoints the web dashboard uses. No wrapper surface. - BYOK provider-key management (your own Anthropic/OpenAI/Groq keys plugged into OpenRouter). → Web UI only at . There is no REST endpoint;
openrouter-remote integrationsdeliberately just prints the URL and exits 2. - Team / organization / billing / invoice endpoints. → Not publicly documented and not wrapped. Use the web dashboard, or inspect the network tab for the
/frontend/*calls if you really need to script it.
Don't get stuck in a loop. If a subcommand returns "no such endpoint", a 404, or the BYOK "web-UI-only" pointer, immediately switch to direct curl (or an OpenAI-compatible SDK for completions) instead of retrying the wrapper with different flags. The wrapper's purpose is to make the handful of read-heavy management flows faster — not to shadow the full REST API.
Configure
Layered config, highest precedence first:
--env-file.env.local/.env(walked up from cwd)- Shell environment (including Claude Code settings)
Project .env files override the shell. Only OPENROUTER_* keys are picked up.
Two distinct credentials — don't confuse them:
# .env
OPENROUTER_API_KEY=sk-or-... # user key, for completions + balance
OPENROUTER_PROVISIONING_KEY=sk-or-v1-... # management key, for /keys endpoints
The provisioning key is generated separately at and cannot be used to make completions — it's management-plane only. Each command documents which key it needs.
Balance
openrouter-remote balance
# total_credits: $10.0000
# total_usage: $9.8848
# remaining: $0.1152
openrouter-remote balance --json # for jq
openrouter-remote balance --alert-below 2.00 # exits 1 if remaining
- (scoped to `/api/v1/keys` user-key CRUD only)
Manage BYOK providers at .
The CLI keeps an `openrouter-remote integrations` subcommand that just prints the URL and exits non-zero — so old invocations in scripts or skills get a clear pointer instead of a silent 404 chasing a non-existent endpoint.
## Key management
All `keys` subcommands require `OPENROUTER_PROVISIONING_KEY`.
```bash
openrouter-remote keys list [--all] # paginate with --all
openrouter-remote keys show
openrouter-remote keys create --name hermes-prod --limit 20 --limit-reset monthly
openrouter-remote keys disable # PATCH disabled=true
openrouter-remote keys enable
openrouter-remote keys set-limit 50.00 [--reset monthly]
openrouter-remote keys rename
openrouter-remote keys delete -y
Keys can be referenced by full hash, hash prefix (if unambiguous), or name/label. You don't need to copy full hashes around.
create shows the new sk-or-... string ONCE on stderr. Save it immediately — OpenRouter won't show it again. After that, you only have the hash to identify the key by.
disable vs delete: disable is reversible, delete is not. Prefer disable for temporary revocation (e.g. a key that leaked briefly).
Quirks
- Two credential types.
OPENROUTER_API_KEY= user key for completions + balance.OPENROUTER_PROVISIONING_KEY= management-only. The error messages steer you to the right one. - POST to
/keys/needs the trailing slash — some clients 307 without it. include_byok_in_limitandlimit_resetonly kick in after a PATCH; on first create they may be silently defaulted.- The
keystring is returned only on creation — never again. Thehashis what you use to identify it afterwards. - Free models can silently return errors when overloaded; if a
:freemodel starts 500ing, swap in the paid variant.
Troubleshooting
HTTP 401on/credits:OPENROUTER_API_KEYwrong. Check openrouter.ai/keys.HTTP 401on/keys*: you're using the user key instead of the provisioning key. Generate one at openrouter.ai/settings/provisioning-keys.HTTP 403 disabledon completions elsewhere: one of your keys was auto-disabled (usually rate-limit abuse).openrouter-remote keys listwill show[x]next to it.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: osouthgate
- Source: osouthgate/agent-plus-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.