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

claude-cli-proxy

v1.3.0

Published

Run a local Anthropic- and OpenAI-compatible API server on top of your Claude Code subscription. No API key required.

Downloads

909

Readme

claude-cli-proxy

Turn your Claude Code subscription into a local API server.

Run one command and you get an HTTP endpoint on http://127.0.0.1:7274 that speaks both the Anthropic Messages API and the OpenAI Chat Completions API. Point any existing tool, SDK or agent framework at it and it works — no API key, no per-token billing. Requests are served by the Claude Code CLI you already have installed and logged in.

npx claude-cli-proxy
  claude-cli-proxy v1.0.0  · Claude Code 2.1.226

  Endpoint      http://127.0.0.1:7274
  Anthropic     http://127.0.0.1:7274/v1/messages
  OpenAI        http://127.0.0.1:7274/v1/chat/completions

  API key       not required — send "not-needed" where your SDK insists on one
  Model         claude-sonnet-5

  ✓ claude-sonnet-5 responded in 3.7s

  Ready to go. Point your client at http://127.0.0.1:7274

Then see it work:

claude-cli-proxy test            # a real query, with the request that produced it
claude-cli-proxy test --stream   # streaming, with time to first token
claude-cli-proxy examples        # copy-paste client code for your language

Requirements

  • Node.js 20 or newer
  • Claude Code installed and signed in. Run claude once in a terminal and complete /login if you haven't.

That's it. This package has zero dependencies.

Install

npm install -g claude-cli-proxy

Then start it:

claude-cli-proxy

Or run it without installing:

npx claude-cli-proxy

On startup it picks a working model, makes one real test call, and tells you when it's ready. If something is wrong — not logged in, quota exhausted, CLI missing — it says so and tells you how to fix it.

About the API key

You don't need one. The server runs on your machine against a Claude CLI that is already signed in, so there is no credential to check.

Most SDKs refuse to start without something in the key field. Pass the string not-needed — it works, and it documents itself when someone reads your config later:

client = OpenAI(api_key="not-needed", base_url="http://127.0.0.1:7274/v1")

If you do want a key enforced — sharing the port with another user, say — start with --api-key and one is generated and stored for you.

Use it

Every snippet below is also available live, with your actual URL filled in:

claude-cli-proxy examples python

curl

curl http://127.0.0.1:7274/v1/messages \
  -H "x-api-key: not-needed" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 256,
    "messages": [{"role": "user", "content": "Explain HTTP caching in two sentences."}]
  }'

Anthropic SDK

from anthropic import Anthropic

client = Anthropic(api_key="not-needed", base_url="http://127.0.0.1:7274")

message = client.messages.create(
    model="claude-sonnet-5",
    max_tokens=256,
    messages=[{"role": "user", "content": "Hello!"}],
)
print(message.content[0].text)

OpenAI SDK

from openai import OpenAI

client = OpenAI(api_key="not-needed", base_url="http://127.0.0.1:7274/v1")

completion = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(completion.choices[0].message.content)

JavaScript

import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'not-needed',
  baseURL: 'http://127.0.0.1:7274/v1',
});

const completion = await client.chat.completions.create({
  model: 'claude-sonnet-5',
  messages: [{ role: 'user', content: 'Hello!' }],
});

LangChain

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="claude-sonnet-5",
    api_key="not-needed",
    base_url="http://127.0.0.1:7274/v1",
)
print(llm.invoke("Hello!").content)

Anything else

Most tools accept a custom base URL. Set these and many will just work:

export ANTHROPIC_BASE_URL=http://127.0.0.1:7274
export ANTHROPIC_API_KEY=not-needed

export OPENAI_BASE_URL=http://127.0.0.1:7274/v1
export OPENAI_API_KEY=not-needed

Streaming

Both endpoints stream. Set "stream": true and you get standard server-sent events in the format each API defines, so SDK streaming helpers work unchanged.

There is also a plain-text mode that skips the event envelope entirely and streams raw text — useful for piping into a terminal:

curl -N http://127.0.0.1:7274/v1/messages \
  -H "x-api-key: not-needed" \
  -H "accept: text/plain" \
  -H "content-type: application/json" \
  -d '{"model":"claude-sonnet-5","max_tokens":512,"stream":true,
       "messages":[{"role":"user","content":"Write a haiku about ports."}]}'

Models

| Model | Use --model value | Context in | Max out | |---|---|---|---| | Claude Opus 5 | claude-opus-5 or opus | 1,000,000 | 64,000 | | Claude Sonnet 5 | claude-sonnet-5 or sonnet | 1,000,000 | 64,000 | | Claude Haiku 4.5 | claude-haiku-4-5 or haiku | 200,000 | 32,000 |

Sonnet 5 is the default. Which models you can actually reach depends on your Claude plan — check with:

claude-cli-proxy models --probe

If your client hardcodes a model name you can't change (many OpenAI tools send gpt-4o), map it onto a real model instead of getting a 404:

CLAUDE_API_OPENAI_MODEL_FALLBACK=claude-sonnet-5 claude-cli-proxy

Responses always report the model that actually ran.

Commands

claude-cli-proxy               Start the server
claude-cli-proxy test          Send a real query and show the request used
claude-cli-proxy examples      Copy-paste client code, URL already filled in
claude-cli-proxy api           Every parameter, and whether it has any effect
claude-cli-proxy doctor        Check your environment and report problems
claude-cli-proxy models        List models (--probe tests each with a real call)
claude-cli-proxy key           Show the API key (--rotate to replace it)
claude-cli-proxy update        Update to the latest version
claude-cli-proxy uninstall     Remove it (--purge also deletes local state)
claude-cli-proxy reinstall     Remove and install again

ccproxy is a shorter alias. Every command has a detailed page:

claude-cli-proxy help test

Try it before you integrate

test runs a real query and prints the exact request that produced it, so you can copy the shape into your own client:

claude-cli-proxy test                      # single response
claude-cli-proxy test --stream             # streaming, reports time to first token
claude-cli-proxy test --openai --stream    # against the chat completions route
claude-cli-proxy test "your own prompt"
claude-cli-proxy test --url http://127.0.0.1:7274   # use a server already running

Which parameters actually do anything

claude-cli-proxy api

Lists every parameter both endpoints accept, marked honoured (passed to the model), emulated (applied by this server, so approximate), or ignored (accepted so your request doesn't fail, but has no effect) — plus response headers and error codes.

For agents

Everything is available as JSON, and a running server describes itself over HTTP:

claude-cli-proxy api --json          # the full request reference
claude-cli-proxy examples --json     # every integration snippet
claude-cli-proxy test --json         # request, response, timings
claude-cli-proxy doctor --json       # environment state, exit code 1 if broken
claude-cli-proxy models --json       # available models
claude-cli-proxy --json              # connection details, then keep serving
curl http://127.0.0.1:7274/          # index: endpoints and auth status
curl http://127.0.0.1:7274/v1/help   # the full reference, same as `api --json`

/ and /v1/help never require a key — an agent has to be able to learn the surface before it knows whether one is needed.

Options

| Flag | Default | Description | |---|---|---| | --port <n> | 7274 | Port to listen on | | --strict-port | off | Fail instead of moving to a free port | | --host <addr> | 127.0.0.1 | Interface to bind | | --model <id> | claude-sonnet-5 | Default model | | --api-key [key] | off | Require a key. With no value, one is generated and stored | | --allow-insecure | off | Permit a non-loopback bind without a key | | --no-selfcheck | off | Skip the startup test call | | --cors-origin <o> | off | Allow a browser origin | | --timeout <s> | 900 | Per-request timeout | | --concurrency <n> | 4 | Requests handled in parallel | | --json | off | Machine-readable output | | --quiet | off | Suppress logging |

If port 7274 is busy, the server moves to the next free port and tells you which one it picked. Use --strict-port if you'd rather it fail.

Every flag has an environment variable equivalent: CLAUDE_API_PORT, CLAUDE_API_HOST, CLAUDE_API_KEY, CLAUDE_API_DEFAULT_MODEL, CLAUDE_API_TIMEOUT, CLAUDE_API_CONCURRENCY, CLAUDE_API_MAX_OUTPUT_TOKENS, CLAUDE_API_MAX_INPUT_TOKENS, CLAUDE_API_CORS_ORIGIN, CLAUDE_API_SYSTEM_PROMPT, CLAUDE_API_SELFCHECK.

Endpoints

| Method | Path | Purpose | |---|---|---| | POST | /v1/messages | Anthropic Messages API | | POST | /v1/chat/completions | OpenAI Chat Completions API | | POST | /v1/messages/count_tokens | Estimate prompt size | | GET | /v1/models | List models (both SDK formats) | | GET | /v1/models/{id} | Model details | | GET | /v1/limits | What this server supports | | GET | /v1/help | Full request reference as JSON | | GET | / | Index of endpoints and auth status | | GET | /health | Status, no key required |

Use as a library

import { start } from 'claude-cli-proxy';

const server = await start({ port: 7274 });
console.log(server.url);

const check = await server.verify();
console.log(check.ok ? `ready on ${check.model}` : check.fatal.message);

await server.close();

Good to know

It uses your subscription. Every request draws on your Claude plan's usage allowance, the same as using Claude Code directly. There is no per-token charge, but there is a quota — and when you hit it you get a 429 telling you so.

Keep it local. The default binding is 127.0.0.1, so only your machine can reach it. Anything that can reach the port can spend your quota, so binding to a wider interface is refused unless you add --api-key (or --allow-insecure to override). Browser requests from other origins are refused unless you allow them with --cors-origin.

Some parameters are accepted but ignored. temperature, top_p, tools, response_format and similar options aren't available through this backend. Requests using them succeed rather than failing; the x-claude-cli-ignored-params response header lists exactly what was dropped. GET /v1/limits documents the full picture.

max_tokens and stop_sequences are applied by this server, not by the model, so they're approximate rather than exact. Token counts from count_tokens are estimates; the usage figures in responses are the real ones.

Long prompts are fine. There's no input cap by default — send a whole document and the model decides what fits.

First request is slower. Expect roughly 3 seconds of fixed overhead per request. Repeated prompts with a shared prefix are cached automatically, which makes large-context work much faster after the first call.

Troubleshooting

Run this first:

claude-cli-proxy doctor

"Claude Code CLI not found" — install it with npm install -g @anthropic-ai/claude-code, or point CLAUDE_BIN at the executable.

"not signed in" — run claude auth login. Installing Claude Code does not sign you in, so this is the most common gap. doctor checks it without spending any quota.

401 on every request — same cause: the CLI isn't signed in. This is never about the API key; the server doesn't require one.

429 — your Claude plan's usage limit is exhausted. This is a plan quota, not a key problem. Wait for the reset.

404 on a model name — the model isn't available through this server. Run claude-cli-proxy models, or set CLAUDE_API_OPENAI_MODEL_FALLBACK.

Client times out on long requests — raise the client's own timeout. The server keeps the connection alive while the model works, but many HTTP clients default to 30 or 60 seconds.

Uninstall

claude-cli-proxy uninstall

Add --purge to also delete the local state directory at ~/.claude-cli-proxy.

License

Proprietary. You may install and run this software for personal use or inside your organisation. Copying, modifying, redistributing or reusing its source is not permitted. See LICENSE for the full terms.

Versions 1.0.0 and 1.0.1 were released under MIT; that grant still stands for those versions.