@aizigao/pi-claude-code-headers-compat
Pi extension package for Claude-compatible header and request-path adaptation across multiple providers.
Package details
Install @aizigao/pi-claude-code-headers-compat from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@aizigao/pi-claude-code-headers-compat- Package
@aizigao/pi-claude-code-headers-compat- Version
0.4.0- Published
- Jun 1, 2026
- Downloads
- 909/mo · 614/wk
- Author
- aizigao
- License
- MIT
- Types
- extension
- Size
- 23.3 KB
- Dependencies
- 2 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-claude-code-headers-compat
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
403responses 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
providersis the provider name apiKeyfollows 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_KEYare 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.110 (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:
matchedProvidersis the current field name- legacy
matchedProvidersUrlis still supported for backward compatibility
modifyHeaders
Used to override default header values.
Currently supported:
USER_AGENTANTHROPIC_VERSIONACCEPTCONTENT_TYPEAUTHORIZATION
Notes:
- if a field is omitted, it falls back to the default value
AUTHORIZATIONdefaults toBearer ${API_KEY}${API_KEY}will be replaced with the final resolved key value for that providerapiKeyresolution follows Pi's latest rules:!commandexecutes 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:
- make sure the provider is already defined in
models.json - make sure that provider is enabled in
claude-code-headers-compat.json - start Pi
- when that provider sends requests, the plugin will automatically apply the compatibility handling
Notes
- provider names in
matchedProvidersmust stay consistent withmodels.json - legacy
matchedProvidersUrlis still accepted, but new configs should usematchedProviders apiKeyinmodels.jsonsupports 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-keyanthropic-dangerous-direct-browser-accessaccept-languagex-appx-pi-provider-markerx-stainless-*(prefix match)sec-fetch-*(prefix match)
Added headers
Added by default when missing:
authorization: Bearer ${API_KEY}user-agent: 2.1.110 (Claude Code)anthropic-version: 2023-06-01accept: application/jsoncontent-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):
authorizationuser-agentanthropic-versionacceptcontent-type
You can override the defaults through modifyHeaders (legacy style) or providers.<name>.setHeaders (new style).