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

@aizigao/pi-claude-code-headers-compat

v0.4.1

Published

Pi extension package for Claude-compatible header and request-path adaptation across multiple providers.

Readme

pi-claude-code-headers-compat

简体中文 | English

npm version

The requests sent by Pi with "api": "anthropic-messages" use the SDK format, which is not exactly the same as the requests sent by Claude Code. The specific problem I am facing is that my proxy provider is currently blocked by Cloudflare as crawler traffic. The purpose of this package is to make the request headers look broadly closer to what Claude Code sends.

The goal of this plugin is not to change the structure of models.json, but to add an extra compatibility layer while keeping Pi's original provider configuration style.

Who this is for

This package is suitable for users who:

  • already configured custom providers in Pi
  • use Claude-compatible proxy/provider endpoints
  • run into incompatible headers, incompatible paths, or unexpected API responses
  • want to handle these compatibility rules through a standalone package
  • get 403 responses from the proxy provider

What it does

When enabled, the package will:

  • read configured providers from the official ~/.pi/agent/models.json
  • read compatibility settings from ~/.pi/agent/claude-code-headers-compat.json
  • only apply compatibility handling to matched provider requests
  • automatically rewrite request paths and adjust headers before sending the request

Installation

Install it in Pi with:

pi install npm:@aizigao/pi-claude-code-headers-compat

If you are developing this project locally, use:

npm install

Configuration

1. Configure the provider

Using my current proxy provider aicoding.sh as an example: when used in Pi, Cloudflare treats the request as crawler traffic because of the headers and returns 403. My configuration is:

File: ~/.pi/agent/models.json. Keep using Pi's default format for this file. No structure changes are needed.

{
  "providers": {
    "aicoding-sh-anthropic": {
      "baseUrl": "https://api.aicoding.sh",
      "api": "anthropic-messages",
      "apiKey": "$AI_CODING_SH_API_KEY",
      "models": [
        {
          "id": "claude-sonnet-4-6",
          "name": "azg-claude-sonnet-4-6",
          "reasoning": true,
          "input": ["text", "image"],
          "cost": {
            "input": 3,
            "output": 15,
            "cacheRead": 0.3,
            "cacheWrite": 3.75
          },
          "contextWindow": 1000000,
          "maxTokens": 128000
        },
        {
          "id": "claude-opus-4-7",
          "name": "azg-claude-opus-4-7",
          "reasoning": true,
          "input": ["text", "image"],
          "cost": {
            "input": 15,
            "output": 75,
            "cacheRead": 1.5,
            "cacheWrite": 18.75
          },
          "contextWindow": 1000000,
          "maxTokens": 128000
        },
        {
          "id": "gpt-5.5",
          "name": "azg-gpt-5.5",
          "reasoning": true,
          "input": ["text", "image"],
          "cost": {
            "input": 5,
            "output": 30,
            "cacheRead": 0.5,
            "cacheWrite": 6.25
          },
          "contextWindow": 1000000,
          "maxTokens": 128000
        },
        {
          "id": "gpt-5.4",
          "name": "azg-gpt-5.4",
          "reasoning": true,
          "input": ["text", "image"],
          "cost": {
            "input": 2.5,
            "output": 15,
            "cacheRead": 0.25,
            "cacheWrite": 3.125
          },
          "contextWindow": 1000000,
          "maxTokens": 128000
        },
        {
          "id": "gpt-5.3-codex",
          "name": "azg-gpt-5.3-codex",
          "reasoning": true,
          "input": ["text", "image"],
          "cost": {
            "input": 1.75,
            "output": 14,
            "cacheRead": 0.175,
            "cacheWrite": 2.1875
          },
          "contextWindow": 1000000,
          "maxTokens": 128000
        }
      ]
    }
  }
}

Notes:

  • the key under providers is the provider name
  • apiKey follows the latest official value-resolution rules: it supports !command, $ENV, ${ENV}, composite interpolation like ${KEY_PREFIX}_${KEY_SUFFIX}, escapes like $$ / $!, and literal values
  • legacy uppercase env-style values such as AI_CODING_SH_API_KEY are still treated as env var names for backward compatibility
  • the plugin matches compatibility logic using the provider name and baseUrl

2. Configure compatibility rules

File: ~/.pi/agent/claude-code-headers-compat.json

Your current configuration example:

{
  "enable": true,
  "matchedProviders": ["aicoding-sh-anthropic"],
  "modifyHeaders": {
    "USER_AGENT": "2.1.178 (Claude Code)",
    "ANTHROPIC_VERSION": "2023-06-01"
  }
}

Field reference:

enable

Whether to enable it.

matchedProviders

The list of provider names that should use compatibility handling. Configure it as needed.

Requirements:

  • the names must match the provider keys in models.json
  • only providers listed here will get compatibility handling

Compatibility note:

  • matchedProviders is the current field name
  • legacy matchedProvidersUrl is still supported for backward compatibility

modifyHeaders

Used to override default header values.

Currently supported:

  • USER_AGENT
  • ANTHROPIC_VERSION
  • ACCEPT
  • CONTENT_TYPE
  • AUTHORIZATION

Notes:

  • if a field is omitted, it falls back to the default value
  • AUTHORIZATION defaults to Bearer ${API_KEY}
  • ${API_KEY} will be replaced with the final resolved key value for that provider
  • apiKey resolution follows Pi's latest rules:
    • !command executes the command and uses stdout
    • $ENV / ${ENV} interpolates environment variables, including composite values like ${KEY_PREFIX}_${KEY_SUFFIX}
    • $$ emits a literal $, and $! emits a literal !
    • other values are treated as literals
  • for backward compatibility, legacy uppercase env-style values are still resolved as environment variable names when present

How it works

This package uses @aizigao/pi-fetch-pipeline to register a fetch middleware that intercepts outgoing requests. When a request matches a configured provider, the middleware rewrites the URL and adjusts headers before forwarding the request down the pipeline. This approach avoids directly patching globalThis.fetch, making it safer to coexist with other extensions that also modify fetch behavior.

Usage

After configuration:

  1. make sure the provider is already defined in models.json
  2. make sure that provider is enabled in claude-code-headers-compat.json
  3. start Pi
  4. when that provider sends requests, the plugin will automatically apply the compatibility handling

Notes

  • provider names in matchedProviders must stay consistent with models.json
  • legacy matchedProvidersUrl is still accepted, but new configs should use matchedProviders
  • apiKey in models.json supports the latest Pi value-resolution syntax, including !command, $ENV, ${ENV}, composite interpolation, escapes, and literals
  • this package is currently aimed at Claude-compatible provider scenarios
  • if a provider does not match, requests will not be rewritten

Request header change list (added/removed/modified)

Note: the following changes only apply when a provider matches the compatibility rules.

Removed headers

Removed by default:

  • x-api-key
  • anthropic-dangerous-direct-browser-access
  • accept-language
  • x-app
  • x-pi-provider-marker
  • x-stainless-* (prefix match)
  • sec-fetch-* (prefix match)

Added headers

Added by default when missing:

  • authorization: Bearer ${API_KEY}
  • user-agent: 2.1.178 (Claude Code)
  • anthropic-version: 2023-06-01
  • accept: application/json
  • content-type: application/json

In addition, the plugin injects a marker header during provider registration for request matching:

  • x-pi-provider-marker: <providerName>

Headers you can modify in config

These headers are force-overridden by default (if already present, values are rewritten):

  • authorization
  • user-agent
  • anthropic-version
  • accept
  • content-type

You can override the defaults through modifyHeaders (legacy style) or providers.<name>.setHeaders (new style).