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

opencode-cliproxiapi-auth

v1.0.1

Published

OpenCode authentication plugin for CLIProxyAPI with /connect command and dynamic model fetching

Readme

opencode-cliproxiapi-auth

OpenCode authentication and model-provider plugin for CLIProxyAPI.

Connect OpenCode to a running CLIProxyAPI instance (local or remote), authenticate with an optional API key, dynamically load models from /v1/models, and enrich metadata from CLIProxyAPI models.json and models.dev.

Features

  • /connect cliproxy — interactive setup (base URL + optional API key)
  • Provider cliproxy — auto-registered with full model list
  • Dynamic models — fetched from CLIProxyAPI /v1/models with TTL cache
  • models.json enrichment — defaults to CLIProxyAPI registry URL; override with local path or custom URL
  • models.dev enrichment — fills missing metadata (graceful fallback)
  • Auth-aware base URL/connect cliproxy base URL used when opencode.json omits baseURL
  • Thinking / reasoning — maps CLIProxyAPI thinking.levels to OpenCode variants (low, medium, high, xhigh, max, …)
  • Optional API key — works when CLIProxyAPI runs without api-keys
  • Fallback models — sensible defaults when the server is unreachable
  • Safe logging — API keys, bearer tokens, and sk-* values are redacted from logs
  • Concurrent fetch dedup — parallel model requests share a single in-flight fetch

Requirements

  • OpenCode ≥ 1.14.49 recommended (provider hook for dynamic models)
  • Node.js ≥ 20
  • Running CLIProxyAPI (default port 8317)

Installation

From npm (after publish)

npm install opencode-cliproxiapi-auth

Add to opencode.json:

{
  "plugin": ["opencode-cliproxiapi-auth"]
}

Local development (before publish)

git clone <repo-url>
cd opencode-cliproxiapi-auth
npm install
npm run build

In your project's opencode.json:

{
  "plugin": ["file:///absolute/path/to/opencode-cliproxiapi-auth/dist/index.js"]
}

Or from inside the plugin repo (relative path):

{
  "plugin": ["file://./dist/index.js"]
}

Quick Start

1. Start CLIProxyAPI

Default endpoint: http://localhost:8317/v1

If api-keys is set in CLIProxyAPI config.yaml, use one of those keys. If omitted, no key is required.

2. Connect in OpenCode

/connect cliproxy

Prompts:

| Field | Default | Notes | |-------|---------|-------| | Base URL | http://localhost:8317/v1 | Include /v1 suffix | | API key | (empty) | Optional if CLIProxyAPI has no api-keys |

Credentials are stored in ~/.local/share/opencode/auth.json.

3. Verify models

opencode models cliproxy

Models appear as cliproxy/<model-id>, e.g. cliproxy/claude-sonnet-4-6.

4. Use a model

opencode run -m cliproxy/gpt-5.4-mini "Hello"

Configuration

Optional settings in opencode.json:

{
  "plugin": ["opencode-cliproxiapi-auth"],
  "provider": {
    "cliproxy": {
      "options": {
        "baseURL": "http://localhost:8317/v1",
        "apiKey": "your-key-from-config.yaml",
        "modelCacheTtl": 300000,
        "refreshOnList": true,
        "modelsDev": { "enabled": true }
      }
    }
  }
}

models.json enrichment

/v1/models often returns minimal metadata. By default, the plugin loads CLIProxyAPI's registry from GitHub (DEFAULT_MODELS_JSON_URL). No config is required for thinking levels and token limits in most setups.

Override with a local clone or custom URL:

{
  "provider": {
    "cliproxy": {
      "options": {
        "modelsJsonPath": "/path/to/CLIProxyAPI/internal/registry/models/models.json"
      }
    }
  }
}

Set "modelsJsonPath": "" to disable registry enrichment entirely.

Enrichment mapping:

| CLIProxyAPI models.json | OpenCode field | |---------------------------|----------------| | context_length / inputTokenLimit | contextWindow | | max_completion_tokens / outputTokenLimit | maxTokens | | thinking.levels | reasoning variants | | display_name | model name | | description | model description |

Options reference

| Option | Type | Default | Description | |--------|------|---------|-------------| | baseURL | string | http://localhost:8317/v1 | CLIProxyAPI base URL; falls back to /connect cliproxy stored URL | | apiKey | string | — | Key from config.yaml api-keys (optional) | | modelCacheTtl | number | 300000 | Model cache TTL (ms) | | refreshOnList | boolean | true | Refresh models when provider options reload | | modelsJsonPath | string | CLIProxyAPI GitHub models.json | Local path or URL; "" disables enrichment | | modelsDev.enabled | boolean | true | Enrich from models.dev | | modelsDev.url | string | https://models.dev/api.json | models.dev API URL | | modelsDev.cacheTtl | number | 86400000 | models.dev cache TTL (ms) | | modelsDev.timeoutMs | number | 5000 | models.dev fetch timeout (ms) | | modelsDev.providerAliases | object | — | Map owned_by → models.dev provider |

baseURL resolution

Effective base URL is chosen in order:

  1. provider.cliproxy.options.baseURL in opencode.json
  2. baseURL stored by /connect cliproxy in ~/.local/share/opencode/auth.json
  3. Default http://localhost:8317/v1

API key priority: options.apiKey → auth key → CLIPROXY_API_KEY env → none (no Authorization header).

Environment variables

| Variable | Description | |----------|-------------| | CLIPROXY_API_KEY | API key fallback (config/auth take precedence) | | CLIPROXY_DEBUG=1 | Enable debug logging to OpenCode log files | | CLIPROXY_BASE_URL | Integration tests only — live CLIProxyAPI base URL | | CLIPROXY_TEST_MODEL | Integration tests only — override model for chat-completion test |

Runtime API

For scripts and manual cache control:

import {
  fetchModels,
  clearModelCache,
  refreshModels,
  CLIPROXY_PROVIDER_ID,
  CLIPROXY_ENDPOINTS,
} from 'opencode-cliproxiapi-auth/runtime';

const config = {
  baseUrl: 'http://localhost:8317/v1',
  apiKey: 'optional-key',
  // modelsJsonPath omitted → uses CLIProxyAPI GitHub registry by default
};

const models = await fetchModels(config);
await refreshModels(config);
clearModelCache(config);

Exported helpers also include loadModelsJson, parseModelsJson, thinkingToVariants, normalizeRegistryModel, and models.dev utilities.

Architecture

index.ts          → CliproxyAuthPlugin (OpenCode entry)
runtime.ts        → programmatic exports
src/
  plugin.ts       → config / provider / auth hooks
  model-fetcher.ts→ /v1/models + cache + orchestration
  models-json.ts  → CLIProxyAPI models.json loader
  normalizer.ts   → field normalization + thinking variants
  models-dev.ts   → models.dev enrichment
  cache.ts        → TTL cache primitive
  logger.ts       → sanitized file logging
  constants.ts    → defaults and endpoints
  types.ts        → TypeScript interfaces

Inspired by opencode-omniroute-auth, simplified for CLIProxyAPI (no combo models, no Gemini schema sanitization).

Development

npm install
npm run build      # compile TypeScript → dist/
npm test           # unit tests (mocked)
npm run check:exports

Publishing to npm

Publishing uses npm trusted publishing (OIDC from GitHub Actions). No NPM_TOKEN secret is required.

Workflow: .github/workflows/publish.yml (triggers: tag v*, GitHub Release, manual dispatch).

One-time setup (npm trusted publisher)

  1. Log in to npmjs.com as gromr1.
  2. Open package settings for opencode-cliproxiapi-auth (after first publish) or account publishing settings before the first release.
  3. Section Trusted publishingGitHub Actions.
  4. Configure exactly (case-sensitive):

| Field | Value | |-------|-------| | Organization or user | GRomR1 (exact GitHub casing — npm is case-sensitive) | | Repository | opencode-cliproxiapi-auth | | Workflow filename | publish.yml | | Allowed actions | npm publish |

  1. Save. npm does not validate until the first publish attempt — double-check spelling.

package.jsonrepository.url must use the same casing as GitHub (git+https://github.com/GRomR1/opencode-cliproxiapi-auth.git).

Optional hardening after verified publish: package Settings → Publishing access → Require 2FA and disallow tokens, then revoke old automation tokens.

Release flow

# 1. Bump version in package.json (e.g. 1.0.1)
# 2. Commit, push, tag
git tag v1.0.0
git push origin v1.0.0

Or: Actions → Publish to npm → Run workflow (branch main).

The workflow runs npm test, then npm publish via OIDC. Provenance is added automatically for public repos. Requires npm CLI ≥ 11.5.1 (Node 24 in CI).

Local dry run (no upload)

npm pack
tar -tf opencode-cliproxiapi-auth-1.0.0.tgz

Integration tests (live CLIProxyAPI)

Credentials go in .env (never commit — see .env.example):

cp .env.example .env
# CLIPROXY_BASE_URL=https://your-cpa-host/v1
# CLIPROXY_API_KEY=          # optional if CLIProxyAPI has no api-keys
# CLIPROXY_TEST_MODEL=gpt-5.4-mini   # optional chat test model
npm run test:integration

Requires CLIPROXY_BASE_URL. CLIPROXY_API_KEY is optional. The chat-completion test uses CLIPROXY_TEST_MODEL when set, otherwise prefers gpt-5.4-mini, then the first model from /v1/models.

Integration suite verifies:

  • Live /v1/models fetch and enrichment
  • Reasoning metadata from models.json
  • opencode models cliproxy (plugin registration)
  • Direct /v1/chat/completions against CLIProxyAPI

Debug

CLIPROXY_DEBUG=1 opencode --print-logs models cliproxy

Logs: ~/.local/share/opencode/log/ (lines tagged service=cliproxy).

Troubleshooting

Provider not found: cliproxy

  • Ensure plugin is in opencode.json plugin array.
  • Run npm run build if using file://./dist/index.js.
  • Do not use opencode --pure (skips external plugins).
  • Unpublished package: use file:// path, not npm package name.

No models / connection failed

curl -H "Authorization: Bearer YOUR_KEY" https://your-host/v1/models
  • Match apiKey with CLIProxyAPI config.yaml api-keys.
  • Or leave key empty if CLIProxyAPI has no auth.

Models lack context limits or thinking levels

Registry enrichment is on by default (CLIProxyAPI GitHub models.json). If you disabled it with "modelsJsonPath": "", remove that or point to a local clone / custom URL.

Stale model list

import { clearModelCache } from 'opencode-cliproxiapi-auth/runtime';
clearModelCache();

Or keep refreshOnList: true (default).

OpenCode suggests cliapiproxy instead of cliproxy

You may have a manual cliapiproxy provider in global opencode.json. This plugin registers cliproxy — use cliproxy/<model-id>.

Related

License

MIT