OpenKBS CLI
curl -fsSL https://openkbs.com/install.sh | bashZero to deployed in three commands
openkbs loginAuthenticateopenkbs create myapp -r us-east-1Scaffold projectopenkbs deployDeploy everythingEverything you need, nothing you don't
Each service is one flag in openkbs.json. Enable it, deploy, done.
Functions
Node.js 24 on Lambda. Deploy in seconds, scale to zero.
$ openkbs fn deploy apiPostgres
Managed Neon database. Connection string auto-injected.
$ openkbs postgres connectionStorage + CDN
S3 + CloudFront. Upload, serve, presign — all built in.
$ openkbs storage upload ./img.pngMQTT Realtime
Pub/sub over WebSocket via AWS IoT Core. Presence included.
$ openkbs mqtt publish chat -d '{"msg":"hi"}'AI Proxy
Route to OpenAI, Anthropic, Google. One key, pay-per-token.
$ curl proxy.openkbs.com/v1/modelsStatic Sites
Deploy HTML/CSS/JS to S3 + CloudFront with one command.
$ openkbs site deployTransactional email via Amazon SES. Custom sender domains.
$ openkbs email send hi@co.com -s "Welcome"Custom Domains
Auto-provisioned SSL certificates and CloudFront CDN.
$ openkbs domain add example.comOne config file. That's the whole infra.
{
"region": "us-east-1",
"postgres": true,
"storage": { "cloudfront": "media" },
"mqtt": true,
"email": true,
"functions": [
{ "name": "auth", "runtime": "nodejs24.x", "memory": 512 },
{ "name": "posts", "runtime": "nodejs24.x", "memory": 512 }
],
"site": "./site"
}AI Proxy — three vendors, one endpoint
Route to GPT, Claude, or Gemini. Pay with project credits. No vendor API keys.
/v1/openai/*/v1/anthropic/*/v1/google/*What you can build
A single openkbs deploy ships a complete app. Here's what one project looks like.
Auth & Sessions
User registration, login, and sessions — all backed by Postgres.
Media Uploads
S3 presigned URLs for direct browser uploads. CDN delivery via CloudFront.
Real-time Feed
Publish events from Lambda, receive instantly in the browser via MQTT.
Live Presence
See who's online. MQTT Last Will auto-removes disconnected users.
Private Messaging
Secure channels using cryptographic random IDs. Only the recipient knows the address.
AI Features
Call GPT, Claude, or Gemini from your functions. One API key, pay-per-token.
CLI Reference
Authentication
openkbs login # Browser-based login
openkbs auth <token> # Authenticate with project JWT (containers)
openkbs logout # Clear stored credentials
Projects
openkbs list # List all projects (alias: ls)
openkbs create [name] -r <region> # Create + scaffold project
openkbs deploy # Deploy all elastic services declared in openkbs.json
openkbs update # Update CLI + download latest skill
Functions (Lambda)
openkbs fn list # List deployed functions (alias: ls)
openkbs fn deploy <name> # Zip ./functions/<name>/ and deploy to Lambda
openkbs fn logs <name> # Tail recent CloudWatch logs
openkbs fn invoke <name> -d '{"action":"hello"}' # Invoke with JSON payload
openkbs fn destroy <name> # Delete function and its Lambda URL
Deploy options
| Flag | Description |
|---|---|
-s, --schedule <expr> | Schedule expression, e.g. "rate(1 hour)" or "cron(0 9 * * ? *)" |
-m, --memory <mb> | Memory in MB (default from openkbs.json) |
-t, --timeout <sec> | Timeout in seconds |
--no-http | Disable HTTP access (function URL) |
Handler pattern
Each function lives in ./functions/<name>/ with an index.mjs entry point. Environment variables auto-injected: DATABASE_URL, STORAGE_BUCKET, OPENKBS_PROJECT_ID, OPENKBS_API_KEY.
export async function handler(event) {
const method = event.requestContext?.http?.method || 'GET';
if (method === 'OPTIONS') return { statusCode: 204, headers: CORS, body: '' };
const body = event.body ? JSON.parse(event.body) : {};
return { statusCode: 200, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ok: true }) };
}
Static Site
openkbs site deploy # Deploy ./site/ to S3 + CloudFront
Storage (S3)
openkbs storage list [prefix] # List objects (alias: ls)
openkbs storage upload <local> [remote] # Upload a file
openkbs storage download <remote> [local] # Download a file
openkbs storage rm <keys...> # Delete objects
Presigned upload URLs
// From a Lambda function — using the Project API (no AWS SDK needed)
const res = await fetch(
\`https://project.openkbs.com/projects/\${process.env.OPENKBS_PROJECT_ID}/storage/upload-url\`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: \`Bearer \${process.env.OPENKBS_API_KEY}\` },
body: JSON.stringify({ key: 'media/uploads/photo.jpg', contentType: 'image/jpeg' }),
}
);
const { uploadUrl, publicUrl } = await res.json();
PostgreSQL (Neon)
openkbs postgres info # Show host, database, user
openkbs postgres connection # Output full connection string
Connection pooling in Lambda
import pg from 'pg';
let pool;
function getPool() {
if (!pool) pool = new pg.Pool({
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: true },
max: 3
});
return pool;
}
const result = await getPool().query('SELECT * FROM items LIMIT 50');
MQTT (Real-time Messaging)
openkbs mqtt info # Show MQTT status and endpoint
openkbs mqtt enable # Enable MQTT for this project
openkbs mqtt disable # Disable MQTT
openkbs mqtt token [-u userId] # Generate temporary client credentials
openkbs mqtt publish <channel> -d '<json>' # Publish event to channel
Architecture
Pub/sub via AWS IoT Core MQTT over WebSocket. Clients get temporary STS credentials, then connect directly to IoT Core. Supports channels, presence, and auto-reconnect.
Server-side publish
await fetch(\`https://project.openkbs.com/projects/\${projectId}/mqtt/publish\`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: \`Bearer \${apiKey}\` },
body: JSON.stringify({ channel: 'posts', event: 'new_post', data: { id: 1, title: 'Hello' } }),
});
Client SDK
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script src="https://openkbs.com/sdk/mqtt.js"></script>
const realtime = new MQTT.Realtime({
credentials: mqttData.credentials,
iotEndpoint: mqttData.iotEndpoint,
region: mqttData.region,
topicPrefix: mqttData.topicPrefix,
clientIdPrefix: mqttData.clientIdPrefix,
clientId: 'user-123',
});
// Channels
const channel = realtime.channels.get('posts');
channel.subscribe((msg) => console.log(msg.name, msg.data));
channel.publish('greeting', { text: 'Hello!' });
// Presence
channel.presence.enter({ name: 'Alice' });
channel.presence.subscribe((members) => console.log(members));
Security
- Credentials are scoped to the project's IoT topics only
- Any user with credentials can subscribe to all channels — for private channels, use unpredictable names
- For sensitive data, publish only from server via
/mqtt/publish
openkbs email enable # Enable email sending
openkbs email info # Show email status and usage
openkbs email send <to> -s <subject> -b <body> # Send email
openkbs email disable # Disable email
openkbs email verify-domain <domain> # Start domain verification
openkbs email verify-status # Check verification status
Send from Lambda
await fetch(\`https://project.openkbs.com/projects/\${projectId}/email/send\`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: \`Bearer \${apiKey}\` },
body: JSON.stringify({ to: 'user@example.com', subject: 'Hello', html: '<h1>Hi!</h1>' }),
});
Custom Domains
openkbs domain add <domain> # Register custom domain
openkbs domain verify # Check DNS records and certificate status
openkbs domain provision # Create CloudFront distribution
openkbs domain info # Show current domain configuration
openkbs domain remove # Remove custom domain
AI Proxy
Routes to OpenAI, Anthropic, and Google. Uses OPENKBS_API_KEY for auth. No vendor API keys needed.
| Route | Vendor |
|---|---|
/v1/openai/* | OpenAI |
/v1/anthropic/* | Anthropic |
/v1/google/* |
With Vercel AI SDK
import { createOpenAI } from '@ai-sdk/openai';
import { createAnthropic } from '@ai-sdk/anthropic';
import { createGoogleGenerativeAI } from '@ai-sdk/google';
import { generateText } from 'ai';
const apiKey = process.env.OPENKBS_API_KEY;
const openai = createOpenAI({ baseURL: 'https://proxy.openkbs.com/v1/openai', apiKey });
const anthropic = createAnthropic({
baseURL: 'https://proxy.openkbs.com/v1/anthropic/v1',
apiKey, headers: { Authorization: \`Bearer \${apiKey}\` },
});
const google = createGoogleGenerativeAI({
baseURL: 'https://proxy.openkbs.com/v1/google',
apiKey, headers: { Authorization: \`Bearer \${apiKey}\` },
});
const { text } = await generateText({ model: openai('gpt-5.4-mini'), prompt: 'Hello!' });
Direct SDK
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://proxy.openkbs.com/v1/openai',
apiKey: process.env.OPENKBS_API_KEY,
});
const res = await client.chat.completions.create({
model: 'gpt-5.4-mini',
messages: [{ role: 'user', content: 'Hello!' }],
});
Available models
Fetch current models and pricing dynamically:
openkbs models # human-readable table
openkbs models --json # machine-readable
# Or programmatically:
GET https://proxy.openkbs.com/v1/models
GET https://project.openkbs.com/ai/models
100,000 credits = 1 EUR. Prices are per 1K tokens.
openkbs.json Reference
| Field | Description |
|---|---|
projectId | Project short ID (auto-set) |
region | AWS region: eu-central-1, us-east-1, or ap-southeast-1 |
postgres | true to provision Neon Postgres |
storage | Object with cloudfront prefix for CDN |
mqtt | true to enable real-time WebSocket messaging |
email | true to enable email sending (SES) |
functions | Array of function definitions to deploy |
site | Path to static site directory |
spa | SPA fallback path (all 404s redirect here) |
Image Generation
openkbs image "A sunset over mountains" -o site/hero.png
openkbs image "Banner with this logo" --ref site/logo.png -o site/banner.png
openkbs image "Quick sketch" --fast -o site/sketch.png
| Flag | Description |
|---|---|
-o <file> | Output file path |
--ref <file> | Reference image (repeatable, up to 10) |
--aspect-ratio | e.g. 16:9 |
--count | Number of images to generate |
--fast | Faster, lighter quality |
Board (Task Management)
Trello-like kanban board built into every project.
openkbs board context # Compact digest of what's in flight
openkbs board show --column "In Progress" # Filter by column
openkbs board show --priority high --label urgent # Filter by priority/label
openkbs board search "auth flow" # Search title, description, comments
openkbs board create <title> [-c <column>] [-t <type>] [-p <priority>] [-d <desc>]
openkbs board update <cardId> [--title <t>] [--description <d>] [--priority <p>]
openkbs board move <cardId> <columnName>
openkbs board comment <cardId> <message>
openkbs board assign <cardId> <email>
openkbs board archive <cardId>
openkbs board delete <cardId>
# Card links
openkbs board link <fromId> <toId> --type blocks
openkbs board unlink <fromId> <toId>
openkbs board links <cardId>
# Editing large descriptions
openkbs board edit <cardId> # Check out to local file
openkbs board save <cardId> # Push edits back
openkbs board discard <cardId> # Discard local edits
# Discovery
openkbs board labels | types | columns | members
Card types: task, bug, feature, expert-request, spec. Priorities: low, medium, high, critical.