Skip to content

MauricioPerera/syntra

Repository files navigation

Syntra

Self-hosted Backend-as-a-Service platform. Authentication, database, storage, realtime, serverless functions, AI, scheduled jobs and more — through a single unified API.

Stack

Layer Technology
Runtime Bun
HTTP Framework Hono
Database PostgreSQL 15 + Kysely
Realtime Bun WebSockets + PostgreSQL LISTEN/NOTIFY
Functions Deno (isolated container)
Validation Zod
Auth JWT (Jose) + Argon2
AI OpenRouter
Storage Local filesystem or AWS S3 + CloudFront
Testing Vitest
Linting Biome

Project Structure

syntra/
├── packages/
│   ├── backend/            # Main API server (Bun + Hono)
│   └── shared/             # Shared types, Zod schemas, constants
├── functions/              # Deno serverless functions runtime
├── deploy/
│   └── docker-init/db/     # PostgreSQL init scripts
├── docker-compose.yml      # postgres + syntra + deno
└── .env.example

Installation

Prerequisites

Dependency Version Required
Bun >= 1.0 Yes
Docker + Docker Compose Latest Yes (for PostgreSQL)
PostgreSQL 15+ with pgvector Only if not using Docker

Option A: Docker Compose (recommended)

Everything runs in containers. Only Docker is required.

# 1. Clone the repository
git clone https://github.com/MauricioPerera/syntra.git
cd syntra

# 2. Create your environment file
cp .env.example .env

Generate security keys and edit .env:

# Linux/macOS:
openssl rand -base64 32   # copy → JWT_SECRET
openssl rand -base64 32   # copy → ENCRYPTION_KEY

# Windows (PowerShell):
[Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Max 256 }) -as [byte[]])

Fill in the required values in .env:

JWT_SECRET=<generated-key>
ENCRYPTION_KEY=<generated-key>
ADMIN_EMAIL=[email protected]
ADMIN_PASSWORD=your-secure-password
POSTGRES_PASSWORD=your-db-password
# 3. Start all services
docker compose up -d

# 4. Verify
curl http://localhost:7130/api/health
# → {"success":true,"statusCode":200,"data":{"status":"ok",...}}

This starts three containers:

Service Port Image Description
postgres 5432 pgvector/pgvector:pg15 PostgreSQL 15 + pgvector
syntra 7130 oven/bun:1-alpine API server (auto-installs deps + hot reload)
deno 7133 denoland/deno:alpine-2.0.6 Serverless functions runtime

The database is automatically initialized with schemas, extensions (pgcrypto, uuid-ossp, vector), roles (anon, authenticated), and all migrations run on first startup.

Option B: Local development (Bun + Docker PostgreSQL)

Run Syntra locally with Bun for faster iteration. Docker only for PostgreSQL.

# 1. Clone and install
git clone https://github.com/MauricioPerera/syntra.git
cd syntra
bun install

# 2. Configure environment
cp .env.example .env
# Edit .env — fill in JWT_SECRET, ENCRYPTION_KEY, ADMIN_EMAIL, ADMIN_PASSWORD, POSTGRES_PASSWORD

# 3. Start PostgreSQL
docker compose up postgres -d

# 4. Wait for PostgreSQL to be ready
docker compose ps   # should show "healthy"

# 5. Start Syntra with hot reload
bun run dev

The server starts at http://localhost:7130. Migrations run automatically.

Option C: Manual PostgreSQL (no Docker)

For existing PostgreSQL 15+ instances:

# 1. Create database and run init script
psql -U postgres -c "CREATE DATABASE syntra;"
psql -U postgres -d syntra -f deploy/docker-init/db/00-init.sql

# 2. Install pgvector extension (required for AI vector features)
#    Ubuntu/Debian:
sudo apt install postgresql-15-pgvector
#    macOS:
brew install pgvector

# 3. Clone and install
git clone https://github.com/MauricioPerera/syntra.git
cd syntra
bun install
cp .env.example .env

# 4. Edit .env — point to your PostgreSQL instance
#    POSTGRES_HOST=localhost
#    POSTGRES_PORT=5432
#    POSTGRES_DB=syntra
#    POSTGRES_USER=postgres
#    POSTGRES_PASSWORD=your-password
#    + JWT_SECRET, ENCRYPTION_KEY, ADMIN_EMAIL, ADMIN_PASSWORD

# 5. Start
bun run dev

Option D: Production (Linux server)

# 1. Install Bun
curl -fsSL https://bun.sh/install | bash
source ~/.bashrc

# 2. Clone and install
git clone https://github.com/MauricioPerera/syntra.git /opt/syntra
cd /opt/syntra
bun install --production

# 3. Configure environment
cp .env.example .env
# Edit .env:
#   NODE_ENV=production
#   JWT_SECRET=<openssl rand -base64 32>
#   ENCRYPTION_KEY=<openssl rand -base64 32>
#   [email protected]
#   ADMIN_PASSWORD=<strong-password>
#   POSTGRES_HOST=<your-db-host>
#   POSTGRES_PASSWORD=<your-db-password>
#   CORS_ORIGINS=https://yourdomain.com

# 4. Start PostgreSQL (Docker or system service)
docker compose up postgres -d

# 5. Start Syntra
bun run start

systemd service (optional)

cat > /etc/systemd/system/syntra.service << 'EOF'
[Unit]
Description=Syntra BaaS
After=network.target postgresql.service

[Service]
Type=simple
WorkingDirectory=/opt/syntra
ExecStart=/root/.bun/bin/bun run start
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable syntra
systemctl start syntra

Post-installation

1. Verify the server

curl http://localhost:7130/api/health

2. Get an API key (for MCP / programmatic access)

# Login as admin
TOKEN=$(curl -s -X POST http://localhost:7130/api/auth/admin/sessions \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"your-password"}' \
  | jq -r '.data.accessToken')

# Generate API key
curl -X POST http://localhost:7130/api/secrets/rotate-api-key \
  -H "Authorization: Bearer $TOKEN" \
  | jq '.data.apiKey'

3. Connect an AI agent

Add to your MCP client config:

{
  "mcpServers": {
    "syntra": {
      "type": "streamable-http",
      "url": "http://localhost:7130/api/mcp",
      "headers": { "X-API-Key": "ik_your_api_key" }
    }
  }
}
Client Config file
Claude Code ~/.claude.json
Claude Desktop ~/Library/Application Support/Claude/claude_desktop_config.json
Cursor .cursor/mcp.json in your project

4. Explore

  • API docs: http://localhost:7130/api/docs
  • Health check: http://localhost:7130/api/health
  • All 105 MCP tools are auto-discovered by connected AI agents

Environment Variables

Required

Variable Validation Description
JWT_SECRET min 32 chars Token signing key
ADMIN_EMAIL valid email Initial admin user email
ADMIN_PASSWORD min 8 chars Initial admin password
POSTGRES_PASSWORD non-empty Database password

Optional (with defaults)

Variable Default Description
PORT 7130 Server port
NODE_ENV development development, production, or test
ENCRYPTION_KEY AES-256-GCM key for secrets (min 32 chars)
POSTGRES_HOST localhost Database host
POSTGRES_PORT 5432 Database port
POSTGRES_DB syntra Database name
POSTGRES_USER postgres Database user
CORS_ORIGINS http://localhost:7131 Comma-separated allowed origins
STORAGE_PROVIDER local local or s3
LOCAL_STORAGE_PATH ./data/storage Path for local file storage
DENO_RUNTIME_URL http://localhost:7133 Deno functions runtime URL
LOGS_DIR ./data/logs Log files directory

Optional integrations

Variable Description
S3_BUCKET S3-compatible bucket name
S3_REGION S3 region
S3_ACCESS_KEY S3 access key
S3_SECRET_KEY S3 secret key
S3_ENDPOINT Custom endpoint (MinIO, Cloudflare R2, etc.)
OPENROUTER_API_KEY AI features (chat, embeddings, images)
VERCEL_TOKEN Vercel deployment integration
VERCEL_TEAM_ID Vercel team ID
VERCEL_PROJECT_ID Vercel project ID
DENO_SUBHOSTING_TOKEN Deno Deploy subhosting
DENO_SUBHOSTING_ORG_ID Deno Deploy organization
EMAIL_FROM Sender address for emails
SMTP_HOST SMTP server host
SMTP_PORT SMTP port (default: 587)
SMTP_USER SMTP username
SMTP_PASS SMTP password

All variables are validated with Zod on startup. Missing or invalid required variables produce clear error messages and prevent the server from starting.

API Reference

Base URL: http://localhost:7130/api

Auth /api/auth

Method Endpoint Auth Description
POST /users Register user
POST /sessions Login
POST /admin/sessions Admin login
POST /refresh Refresh token Refresh access token
POST /logout User Logout
GET /sessions/current User Get current session
POST /tokens/anon Admin Generate anonymous token
PATCH /profiles/current User Update own profile
GET /profiles/:userId User Get public profile
GET /users Admin List all users
GET /users/:userId Admin Get user by ID
DELETE /users Admin Delete users
GET /config Admin Get auth config
PUT /config Admin Update auth config
GET /public-config Public auth settings

Email Verification & Password Reset

Method Endpoint Description
POST /email/send-verification Send verification email
POST /email/verify Verify email with OTP
POST /email/send-reset-password Send password reset email
POST /email/reset-password Reset password with token

OAuth (PKCE)

Method Endpoint Description
GET /oauth/providers List enabled OAuth providers
GET /oauth/:provider Start OAuth flow
GET /oauth/:provider/callback OAuth callback
POST /oauth/exchange Exchange code for tokens
GET /oauth/configs List OAuth configs (admin)
POST /oauth/configs Create/update OAuth config (admin)
DELETE /oauth/configs/:provider Delete OAuth config (admin)

Supported providers: Google, GitHub, Discord, Microsoft, LinkedIn, Apple, X (Twitter), Facebook, Instagram, TikTok, Spotify.

Database /api/database

Tables

Method Endpoint Auth Description
GET /tables Admin List all tables
POST /tables Admin Create table
GET /tables/:name/schema Admin Get table schema
PATCH /tables/:name/schema Admin Alter table
DELETE /tables/:name Admin Drop table

Records (PostgREST-style)

Method Endpoint Auth Description
GET /records/:table User Query records
POST /records/:table User Insert records
PATCH /records/:table User Update records
DELETE /records/:table User Delete records

Query parameters:

?select=id,name,email               # Column selection
?status=eq.active                    # Equality
?age=gt.18                           # Greater than (also: gte, lt, lte)
?name=like.%John%                    # Pattern matching
?role=in.(admin,editor)              # In list
?order=created_at.desc              # Sorting
?limit=10&offset=20                 # Pagination

RPC & Metadata

Method Endpoint Description
POST /rpc/:functionName Execute PostgreSQL function
GET /functions List database functions
GET /indexes List indexes
GET /policies List RLS policies
GET /triggers List triggers

Storage /api/storage

Method Endpoint Auth Description
GET /buckets Admin List buckets
POST /buckets Admin Create bucket
GET /buckets/:id Admin Get bucket
PATCH /buckets/:id Admin Update bucket
DELETE /buckets/:id Admin Delete bucket
GET /objects/:bucket User List objects
POST /objects/:bucket/:key User Upload object
GET /objects/:bucket/:key User Download object
DELETE /objects/:bucket/:key User Delete object
POST /signed/upload User Get signed upload URL
POST /signed/download User Get signed download URL
POST /copy User Copy object

Realtime /api/realtime

HTTP

Method Endpoint Auth Description
GET /channels Admin List channels
POST /channels Admin Create channel
GET /channels/:id Admin Get channel
PATCH /channels/:id Admin Update channel
DELETE /channels/:id Admin Delete channel
GET /channels/:id/messages Admin Message history
GET /channels/:id/stats Admin Channel stats
POST /publish User Publish message
GET /stats Admin Live connection stats

WebSocket

Connect to ws://localhost:7130/api/realtime?token={jwt}

// Subscribe
{ "type": "subscribe", "channel": "room:123" }

// Publish
{ "type": "publish", "channel": "room:123", "event": "message", "payload": { "text": "hello" } }

// Unsubscribe
{ "type": "unsubscribe", "channel": "room:123" }

// Heartbeat
{ "type": "ping" }  →  { "type": "pong" }

AI /api/ai

Method Endpoint Auth Description
POST /chat User Chat completion (supports streaming)
POST /images User Generate images
POST /embeddings User Generate embeddings
GET /configs Admin List AI configs
POST /configs Admin Create AI config
GET /configs/:id Admin Get config
PATCH /configs/:id Admin Update config
DELETE /configs/:id Admin Delete config
GET /usage Admin Usage stats
GET /usage/list Admin Usage records

Functions /api/functions

Method Endpoint Auth Description
GET / Admin List functions
POST / Admin Create function
GET /:id Admin Get function
PATCH /:id Admin Update function
DELETE /:id Admin Delete function
POST /:id/deploy Admin Deploy to Deno runtime
GET /:id/deployments Admin List deployments
POST /:slug/invoke User Invoke function by slug

Schedules /api/schedules

Method Endpoint Auth Description
GET / Admin List scheduled jobs
POST / Admin Create job
GET /:id Admin Get job
PATCH /:id Admin Update job
DELETE /:id Admin Delete job
POST /:id/toggle Admin Toggle active/inactive
GET /:id/logs Admin Execution logs

MCP (Model Context Protocol) /api/mcp

Syntra exposes all its capabilities as an MCP server, allowing AI agents (Claude Code, Cursor, etc.) to manage your entire backend through natural language.

Transport: Streamable HTTP (stateless, JSON-RPC over POST)

Configuration:

{
  "mcpServers": {
    "syntra": {
      "type": "streamable-http",
      "url": "http://localhost:7130/api/mcp",
      "headers": { "X-API-Key": "ik_your_api_key" }
    }
  }
}

105 tools across 10 modules:

Module Tools Examples
auth 18 auth_register, auth_login, auth_list_users, auth_get_config
database 17 database_create_table, database_select_records, database_execute_sql
storage 12 storage_create_bucket, storage_upload_object, storage_get_signed_url
ai 16 ai_chat_completion, ai_generate_embedding, ai_vector_search
realtime 8 realtime_create_channel, realtime_publish_message
functions 9 functions_create, functions_deploy, functions_invoke
schedules 7 schedules_create_job, schedules_toggle_active
secrets 4 secrets_create, secrets_list, secrets_rotate_api_key
system 11 system_get_metadata, system_list_modules, system_send_email
usage 3 usage_get_stats, usage_list_records

Uses a pre-warmed server pool (10 instances) for low-latency responses (~4ms overhead over direct HTTP).

Other Endpoints

Endpoint Description
/api/secrets Encrypted environment variables management
/api/email Send transactional emails via SMTP
/api/webhooks Webhook management and delivery
/api/logs Application log retrieval
/api/deployments Vercel deployment integration
/api/metadata Project metadata
/api/usage Usage metrics
/api/docs API documentation
/api/health Health check

Database Schema

Seven PostgreSQL schemas for logical separation:

auth          →  users, user_providers, configs, oauth_configs, email_otps
system        →  secrets, audit_logs, deployments, mcp_usage
ai            →  configs, usage
storage       →  buckets, objects
functions     →  definitions, deployments
realtime      →  channels, messages
schedules     →  jobs, job_logs

Key features:

  • Row Level Security on auth.users with helper functions auth.uid(), auth.role(), auth.email()
  • Auto-updating updated_at via triggers
  • pg_notify('realtime_message') for realtime integration
  • Migrations auto-run on server startup

Authentication Flow

JWT Token Types

Token Lifetime Delivery
Access token 15 minutes Response body
Refresh token 7 days httpOnly cookie (web) or response body (mobile)
CSRF token Tied to refresh Response body
Anonymous token 24 hours Response body
API key 365 days Response body

OAuth PKCE Flow

  1. Client generates code_verifier and code_challenge
  2. GET /api/auth/oauth/:provider returns authorization URL
  3. User authorizes with provider
  4. Provider redirects with authorization code
  5. POST /api/auth/oauth/exchange exchanges code + verifier for tokens

Security

  • Passwords — Argon2id (memory-hard)
  • Secrets — AES-256-GCM encryption at rest
  • JWT — HMAC-SHA256 signing
  • SQL Injection — Parameterized queries via Kysely
  • Rate Limiting — Per-endpoint limits on auth and email
  • CSRF — Token derived from refresh token hash
  • RLS — PostgreSQL row-level security policies
  • Table Names — Regex whitelist validation
  • Storage — Signed URLs for temporary access, public/private bucket separation

Scripts

bun run dev              # Start backend with hot reload
bun run build            # Build all packages
bun run test             # Run tests (Vitest)
bun run typecheck        # TypeScript type checking
bun run lint             # Biome lint check
bun run lint:fix         # Biome lint auto-fix
bun run bench            # Run all benchmarks
bun run bench:http       # HTTP endpoint benchmarks
bun run bench:mcp        # MCP protocol benchmarks
bun run bench:internals  # In-process crypto/JWT/Zod benchmarks
bun run bench:stress     # Progressive load / stress test

Agent Skills

Syntra ships with Claude Code Skills — structured guides that help AI agents work with your backend more effectively. Skills are in .claude/skills/ and auto-load when connected via MCP.

Skill Description
syntra-setup Initialize and configure a Syntra backend, verify connection, bootstrap a project
syntra-db Database workflows: schema design, CRUD, filters, raw SQL, migrations
syntra-auth Authentication: users, OAuth providers, OTP, email verification, password policies
syntra-storage File storage: buckets, uploads, downloads, signed URLs, S3 compatibility
syntra-ai AI features: chat completions, image generation, embeddings, vector search (RAG)
syntra-functions Edge functions on Deno runtime + scheduled cron jobs
syntra-status System diagnostics: health checks, audit logs, usage stats, troubleshooting

Install skills in your project

Copy the .claude/skills/ directory into your project:

# From the Syntra repo
cp -r .claude/skills/syntra-* /path/to/your-project/.claude/skills/

Or install individual skills:

cp -r .claude/skills/syntra-db /path/to/your-project/.claude/skills/

Skills work with Claude Code, Cursor, and any MCP-compatible agent.

License

Apache-2.0

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors