weysabi-server
v0.16.0
Published
OpenAI-compatible HTTP server for weysabi
Readme
weysabi-server
OpenAI-compatible HTTP server for weysabi. It exposes OpenAI-style endpoints while routing requests through Weysabi's provider failover, circuit breaker, and retry logic.
Usage
import { createWeysabi } from "weysabi";
import { createServer } from "weysabi-server";
const weysabi = createWeysabi({
groq: { apiKey: process.env.WEYSABI_GROQ_API_KEY },
});
const server = await createServer(weysabi, {
port: 3000,
hostname: "127.0.0.1",
});
console.log(`Server on http://${server.hostname}:${server.port}`);Or via CLI:
weysabi server --host 127.0.0.1 --port 3000Endpoints
| Method | Path | Description |
| ------ | ---------------------- | ---------------------- |
| POST | /v1/chat/completions | Chat completion |
| GET | /v1/models | List configured models |
| GET | /health | Health check |
| GET | /v1/admin/stats | Aggregate usage stats |
| GET | /v1/admin/usage | Paginated usage data |
Configuration
| Env Var | Default | Description |
| --------------------------- | --------- | ------------------------------------- |
| WEYSABI_PORT | 3000 | HTTP server port |
| WEYSABI_HOST | 0.0.0.0 | HTTP server bind address |
| WEYSABI_API_KEY | — | Bearer token auth (disabled if unset) |
| WEYSABI_ADMIN_API_KEY | — | Dedicated key enabling admin routes |
| WEYSABI_CORS_ORIGINS | * | Comma-separated CORS origins |
| WEYSABI_RATE_LIMIT_RPM | 300 | Per-IP rate limit (requests/minute) |
| WEYSABI_MAX_BODY_BYTES | 1048576 | Maximum request body size |
| WEYSABI_TRUSTED_PROXIES | empty | Comma-separated direct proxy IPs |
| WEYSABI_GROQ_API_KEY | — | Groq provider key |
| WEYSABI_OPENAI_API_KEY | — | OpenAI provider key |
| WEYSABI_ANTHROPIC_API_KEY | — | Anthropic provider key |
| WEYSABI_GOOGLE_API_KEY | — | Google Gemini provider key |
| WEYSABI_MISTRAL_API_KEY | — | Mistral provider key |
For multi-instance deployments, inject shared rate-limit and idempotency stores. Redis adapters are re-exported by weysabi-server:
import {
createServer,
fromIORedis,
RedisIdempotencyStore,
RedisRateLimitStore,
} from "weysabi-server";
const redisClient = fromIORedis(redis);
const server = await createServer(weysabi, {
rateLimitStore: new RedisRateLimitStore(redisClient),
idempotencyStore: new RedisIdempotencyStore(redisClient),
});Control-plane store
The server package includes a project-scoped SQLite control-plane store for local development and single-instance self-hosting:
import { createSqliteControlPlaneStore } from "weysabi-server";
const control = createSqliteControlPlaneStore(".weysabi/control.db");
const project = await control.projects.create({
name: "Support",
slug: "support",
});
const createdKey = await control.apiKeys.create({
projectId: project.id,
name: "runtime",
scopes: ["chat:write"],
});
console.log(createdKey.secret); // returned only at creation
await control.close();The store persists only an Argon2id hash and SHA-256 fingerprint for project API keys. Project deletion cascades to managed child resources. Prompt version allocation and publishing use SQLite transactions.
Control-plane databases use versioned migrations. Databases created by the earlier preview schema must be backed up and recreated rather than being opened with the hardened store.
Injected stores remain caller-owned and are not disposed by server.stop().
Deployment
Docker
docker build -t weysabi-server -f packages/server/Dockerfile .
docker run -p 3000:3000 \
-e WEYSABI_GROQ_API_KEY=gsk-... \
-e WEYSABI_API_KEY=sk-weysabi-secret \
weysabi-serverRailway
- Connect your repo
- Set build command:
bun install - Set start command:
bun run packages/server/src/start.ts - Add env vars:
WEYSABI_GROQ_API_KEY,WEYSABI_API_KEY, etc. - Deploy — Railway detects the Bun runtime automatically
Fly.io
# Use the included Dockerfile
fly launch --dockerfile packages/server/Dockerfile
fly secrets set WEYSABI_GROQ_API_KEY=gsk-... WEYSABI_API_KEY=sk-...
fly deployRender
- Create a new Web Service
- Build command:
bun install - Start command:
bun run packages/server/src/start.ts - Set env vars in the dashboard
- Render auto-detects Bun from the lockfile
Security
- Auth: Set
WEYSABI_API_KEYto requireAuthorization: Bearer <key>on all endpoints except/health - Rate limiting: Per-IP fixed-window limiting (configurable via
WEYSABI_RATE_LIMIT_RPM, default 300/min) - Distributed state: Shared rate-limit and idempotency stores can be injected for multi-instance deployments
- Idempotency safety: Reusing a key with a different request returns
409instead of stale data - Proxy safety: Forwarded IP headers are ignored unless the direct peer appears in
WEYSABI_TRUSTED_PROXIES - Body limits: Completion requests are capped by
WEYSABI_MAX_BODY_BYTES - Disconnect handling: Client cancellation aborts the upstream provider stream
- CORS: Configurable origins via
WEYSABI_CORS_ORIGINS(comma-separated, default*) - No data leakage: Provider API keys never appear in responses
