OpenAI-compatible proxy server for StepFun AI, providing access to StepFun LLM models through a unified API. Zero external dependencies — uses only Node.js built-in modules.
- OpenAI-Compatible API — Standard
/v1/chat/completionsand/v1/modelsendpoints - Streaming Support — SSE streaming for chat completions
- Tool Schema Normalization — Resolves
$refand$defsin tool schemas before forwarding - Dashboard UI — Liquid glass effects, model/key management, real-time plan & usage stats
- Auto-Config — Automatically configures opencode provider on startup
- Dynamic Model Fetch — Fetches available models from
https://api.stepfun.ai/step_plan/v1/models - Account Info — Real-time balance, cash balance, and voucher balance from StepFun API
- Step Plan Integration — Live plan name, 5h/weekly usage %, and reset timers from platform.stepfun.ai
- Response Caching — LRU cache for non-streaming responses
- Multi-Key Support — Rotate between multiple StepFun API keys
- Zero Dependencies — No npm packages required
| Model | Description |
|---|---|
step-3.5-flash |
StepFun 3.5 Flash |
step-3.5-flash-2603 |
StepFun 3.5 Flash (2603) |
step-3.7-flash |
StepFun 3.7 Flash (reasoning tiers: low/medium/high) |
step-tts-2 |
StepFun TTS v2 |
stepaudio-2.5-tts |
StepFun Audio 2.5 TTS |
stepaudio-2.5-asr |
StepFun Audio 2.5 ASR |
step-image-edit-2 |
StepFun Image Edit v2 |
Models are dynamically fetched from https://api.stepfun.ai/step_plan/v1/models on startup.
# Clone and start (zero deps — no npm install needed)
cd STEP-PROXY
node proxy.js
# Or use launcher (auto-detects Bun, falls back to Node)
start.cmd
# Open dashboard
open http://localhost:8080Get a StepFun API key from platform.stepfun.ai.
Add to .config/config.json:
{
"API_KEY": "your-stepfun-api-key"
}Or set environment variable:
set STEP_API_KEY=your-stepfun-api-key
node proxy.jsStepFun has two separate systems:
| Standard API | Step Plan | |
|---|---|---|
| Base URL | https://api.stepfun.ai/v1 |
https://api.stepfun.ai/step_plan/v1 |
| Billing | Prepaid balance | Subscription quota (5h/weekly limits) |
| Chat endpoint | /v1/chat/completions |
/step_plan/v1/chat/completions |
| Models | All models | step-3.5-flash, step-3.5-flash-2603, step-3.7-flash |
The proxy automatically routes chat completions to the Step Plan endpoint. Using the standard endpoint with a Step Plan subscription returns quota_exceeded errors.
Edit .config/config.json or set environment variables:
| Key | Description | Default |
|---|---|---|
LISTEN_ADDR |
Proxy listen address | 127.0.0.1:8080 |
UPSTREAM_BASE_URL |
StepFun API URL (for models/accounts) | https://api.stepfun.ai |
API_KEY |
StepFun API key | — |
REQUEST_TIMEOUT |
Upstream request timeout | 15m |
API_KEYS |
Client API keys for proxy auth | [] (open access) |
TOKENS |
Array of {name, token} for multi-key support |
auto-populated |
OASIS_TOKEN |
Oasis JWT token for platform.stepfun.ai API | — |
OASIS_WEBID |
Oasis web device ID | — |
CACHE_TTL |
Response cache TTL | 60s |
CACHE_MAX_SIZE |
Max cached responses | 100 |
CACHE_ENABLED |
Enable response caching | true |
The OASIS_TOKEN and OASIS_WEBID are browser session values from platform.stepfun.ai. They are required for the dashboard to display live plan name, 5h/weekly usage %, and reset timers.
- Open platform.stepfun.ai in your browser and log in
- Open DevTools (
F12) → Application tab → Cookies →https://platform.stepfun.ai - Find the
Oasis-Tokencookie → copy its full value (it's a long JWT string) - Find the
Oasis-WebIdcookie → copy its full value (a 40-character hex string)
Add to .config/config.json:
{
"OASIS_TOKEN": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"OASIS_WEBID": "bfe7df2615d72de9fb91c7be9abb5b9105127d5d"
}Note: The
OASIS_TOKENJWT expires (typically ~30 days). When it expires, the plan status will show an error — regenerate it from the browser. TheOASIS_WEBIDdoes not change between sessions.
You can also set per-key sessions in the TOKENS array or via the Dashboard → Manage Keys modal. Per-key sessions override the global OASIS_TOKEN for that key's plan status lookup.
The proxy supports multiple StepFun API keys. Set TOKENS in config:
{
"TOKENS": [
{ "name": "Key 1", "token": "your-key-1" },
{ "name": "Key 2", "token": "your-key-2" }
]
}Manage keys via the Dashboard → Manage Keys modal (inline add/edit/delete).
The proxy automatically rotates tokens across conversations using fingerprint-based session tracking. Each conversation is identified by an MD5 hash of the first user message (skipping auto title prompts). Follow-up requests (tool calls, continuations) in the same conversation are pinned to the same token automatically. A global session counter increments for each new conversation.
Conversation A (fingerprint: a1b2c3) → sess1 → Token 1
├── tool call follow-up → Token 1 (same fingerprint)
└── user follow-up → Token 1 (same fingerprint)
Conversation B (fingerprint: d4e5f6) → sess2 → Token 2 (next in pool)
Console logs show:
14:30:15 [Session#1>Key1]-[step-3.5-flash]-"user prompt"
14:30:15 [Session#1>Key1]-[step-3.5-flash]-done:3996ms
By default the proxy is open access. To restrict access, set API_KEYS:
{
"API_KEYS": ["my-secret-key-1", "my-secret-key-2"]
}Clients must include the key:
curl -H "x-api-key: my-secret-key-1" http://localhost:8080/v1/models
curl -H "Authorization: Bearer my-secret-key-1" http://localhost:8080/v1/modelsimport OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'http://localhost:8080/v1',
apiKey: 'not-needed'
});
const response = await client.chat.completions.create({
model: 'step-3.5-flash',
messages: [{ role: 'user', content: 'Hello!' }]
});The proxy auto-configures opencode on startup. Restart opencode after starting the proxy, then select the stepfun provider.
Access at http://localhost:8080:
- Plan & Usage Stats — Plan name, 5h/weekly usage % with reset timers (auto-refreshes every 30s)
- Cache Stats — Real-time cache hits and performance
- API Key Status — Online/Offline indicator
- SS Mode — Blur sensitive tokens for screenshots
- Liquid Glass Effects — Canvas-generated SVG displacement maps
- Model Management — Toggle models on/off
- Key Manager — Add/edit/delete API keys with inline editing
- Collapsible Sections — Models, API Key, Quick Actions, Environment, Proxy Configuration
| Method | Path | Description |
|---|---|---|
GET |
/healthz |
Health check with API key status, uptime, and account info |
GET |
/v1/models |
OpenAI models list |
POST |
/v1/chat/completions |
OpenAI chat completions (streaming supported) |
| Method | Path | Description |
|---|---|---|
GET / POST |
/api/config |
Read/write proxy configuration |
GET |
/api/validate |
Validate API key |
GET |
/api/models |
List available model IDs |
GET |
/api/bg |
Bing wallpaper image (cached daily) |
GET / POST |
/api/keys |
Multi-key CRUD (add/update/delete) |
GET |
/api/account |
StepFun account info (balance, cash, voucher) |
GET |
/api/step-plan-status |
Platform plan + usage rates (60s cache) |
GET / DELETE |
/api/cache |
View/clear response cache |
proxy.js
├── Config System — JSON + env vars + API key validation
├── UpstreamClient — HTTP client for StepFun API
│ ├── getUserInfo() — GET /v1/models (validate key)
│ ├── chatCompletions() — POST /step_plan/v1/chat/completions
│ ├── getAccountInfo() — GET /v1/accounts (balance info)
│ ├── getStepPlanStatus()— POST platform QueryStepPlanRateLimit (usage)
│ └── getPlanStatus() — POST platform GetStepPlanStatus (plan)
├── Tool Schema Norm. — $ref resolution and schema normalization
├── HTTP Handlers — OpenAI + management + plan status endpoints
├── Request Router — Pathname-based routing
├── Session Tracking — Fingerprint-based sticky sessions
├── Opencode Config — Auto-configures opencode provider
└── Server Startup — Validation, config write, listen
dashboard.html
├── Liquid Glass Engine — Canvas-based displacement/specular maps
├── Plan & Usage Cards — Plan name, 5h/weekly usage %, reset timers
├── Combined View — Aggregates plan names and usage from all data slides
├── Model Management — Toggle models on/off
├── Key Manager — Add/edit/delete API keys
├── Bing Wallpaper — Daily rotating background
├── Cache Stats — Real-time cache performance
└── Configuration Forms — Listen addr, upstream URL, timeout
No external npm dependencies — uses Node.js built-in modules only: fs, path, os, http, https, url, crypto, zlib.
MIT