Create and manage InsForge projects using the CLI. Handles authentication, project setup, database management, edge functions, storage, deployments, and secr...
---
name: insforge-cli
description: Create and manage InsForge projects using the CLI. Handles authentication, project setup, database management, edge functions, storage, deployments, and secrets. For writing application code with the InsForge SDK, use the insforge (SDK) skill instead.
license: Apache-2.0
metadata:
author: insforge
version: "1.0.0"
organization: InsForge
date: February 2026
---
# InsForge CLI
Command-line tool for managing InsForge Backend-as-a-Service projects.
## Critical: Session Start Checks
```bash
insforge whoami # verify authentication
insforge current # verify linked project
```
If not authenticated: `insforge login`
If no project linked: `insforge create` (new) or `insforge link` (existing)
## Global Options
| Flag | Description |
|------|-------------|
| `--json` | Structured JSON output (for scripts and agents) |
| `-y, --yes` | Skip confirmation prompts |
## Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Success |
| 2 | Not authenticated |
| 3 | Project not linked |
| 4 | Resource not found |
| 5 | Permission denied |
## Environment Variables
| Variable | Description |
|----------|-------------|
| `INSFORGE_ACCESS_TOKEN` | Override stored access token |
| `INSFORGE_PROJECT_ID` | Override linked project ID |
| `INSFORGE_EMAIL` | Email for non-interactive login |
| `INSFORGE_PASSWORD` | Password for non-interactive login |
---
## Commands
### Authentication
- `insforge login` — OAuth (browser) or `--email` for password login. See [references/login.md](references/login.md)
- `insforge logout` — clear stored credentials
- `insforge whoami` — show current user
### Project Management
- `insforge create` — create new project. See [references/create.md](references/create.md)
- `insforge link` — link directory to existing project
- `insforge current` — show current user + linked project
- `insforge list` — list all orgs and projects
### Database — `insforge db`
- `insforge db query <sql>` — execute raw SQL. See [references/db-query.md](references/db-query.md)
- `insforge db tables / indexes / policies / triggers / functions` — inspect schema
- `insforge db rpc <fn> [--data <json>]` — call database function (GET if no data, POST if data)
- `insforge db export` — export schema/data. See [references/db-export.md](references/db-export.md)
- `insforge db import <file>` — import from SQL file. See [references/db-import.md](references/db-import.md)
### Edge Functions — `insforge functions`
- `insforge functions list` — list deployed functions
- `insforge functions code <slug>` — view function source
- `insforge functions deploy <slug>` — deploy or update. See [references/functions-deploy.md](references/functions-deploy.md)
- `insforge functions invoke <slug> [--data <json>] [--method GET|POST]` — invoke function
### Storage — `insforge storage`
- `insforge storage buckets` — list buckets
- `insforge storage create-bucket <name> [--private]` — create bucket (default: public)
- `insforge storage delete-bucket <name>` — delete bucket and **all its objects** (destructive)
- `insforge storage list-objects <bucket> [--prefix] [--search] [--limit] [--sort]` — list objects
- `insforge storage upload <file> --bucket <name> [--key <objectKey>]` — upload file
- `insforge storage download <objectKey> --bucket <name> [--output <path>]` — download file
### Deployments — `insforge deployments`
- `insforge deployments deploy [dir]` — deploy frontend app. See [references/deployments-deploy.md](references/deployments-deploy.md)
- `insforge deployments list` — list deployments
- `insforge deployments status <id> [--sync]` — get deployment status (--sync fetches from Vercel)
- `insforge deployments cancel <id>` — cancel running deployment
### Secrets — `insforge secrets`
- `insforge secrets list [--all]` — list secrets (values hidden; `--all` includes deleted)
- `insforge secrets get <key>` — get decrypted value
- `insforge secrets add <key> <value> [--reserved] [--expires <ISO date>]` — create secret
- `insforge secrets update <key> [--value] [--active] [--reserved] [--expires]` — update secret
- `insforge secrets delete <key>` — **soft delete** (marks inactive; restore with `--active true`)
### Schedules — `insforge schedules`
- `insforge schedules list` — list all scheduled tasks (shows ID, name, cron, URL, method, active, next run)
- `insforge schedules get <id>` — get schedule details
- `insforge schedules create --name --cron --url --method [--headers <json>] [--body <json>]` — create a cron job (5-field cron format only)
- `insforge schedules update <id> [--name] [--cron] [--url] [--method] [--headers] [--body] [--active]` — update schedule
- `insforge schedules delete <id>` — delete schedule (with confirmation)
- `insforge schedules logs <id> [--limit] [--offset]` — view execution logs
### Logs — `insforge logs`
- `insforge logs <source> [--limit <n>]` — fetch backend container logs (default: 20 entries)
| Source | Description |
|--------|-------------|
| `insforge.logs` | Main backend logs |
| `postgREST.logs` | PostgREST API layer logs |
| `postgres.logs` | PostgreSQL database logs |
| `function.logs` | Edge function execution logs |
> Source names are case-insensitive: `postgrest.logs` works the same as `postgREST.logs`.
### Documentation — `insforge docs`
- `insforge docs` — list all topics
- `insforge docs instructions` — setup guide
- `insforge docs <feature> <language>` — feature docs (`db / storage / functions / auth / ai / realtime` × `typescript / swift / kotlin / rest-api`)
> For writing application code with the InsForge SDK, use the insforge (SDK) skill instead, and use the `insforge docs <feature> <language>` to get specific SDK documentation.
---
## Non-Obvious Behaviors
**Functions invoke URL**: invoked at `{oss_host}/functions/{slug}` — NOT `/api/functions/{slug}`. Exits with code 1 on HTTP 400+.
**Secrets delete is soft**: marks the secret inactive, not destroyed. Restore with `insforge secrets update KEY --active true`. Use `--all` with `secrets list` to see inactive ones.
**Storage delete-bucket is hard**: deletes the bucket and every object inside it permanently.
**db rpc uses GET or POST**: no `--data` → GET; with `--data` → POST.
**Schedules use 5-field cron only**: `minute hour day month day-of-week`. 6-field (with seconds) is NOT supported. Headers can reference secrets with `${{secrets.KEY_NAME}}`.
---
## Common Workflows
### Set up database schema
```bash
insforge db query "CREATE TABLE posts (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
title TEXT NOT NULL,
content TEXT,
author_id UUID REFERENCES auth.users(id),
created_at TIMESTAMPTZ DEFAULT now()
)"
insforge db query "ALTER TABLE posts ENABLE ROW LEVEL SECURITY"
insforge db query "CREATE POLICY \"public_read\" ON posts FOR SELECT USING (true)"
insforge db query "CREATE POLICY \"owner_write\" ON posts FOR INSERT WITH CHECK (auth.uid() = author_id)"
```
> FK to users: always `auth.users(id)`. RLS current user: `auth.uid()`.
### Deploy an edge function
```bash
# Default source path: insforge/functions/{slug}/index.ts
insforge functions deploy my-handler
insforge functions invoke my-handler --data '{"action": "test"}'
```
### Deploy frontend
**Always verify the local build succeeds before deploying.** Local builds are faster to debug and don't waste server resources.
```bash
# 1. Build locally first
npm run build
# 2. Deploy
insforge deployments deploy ./dist --env '{"VITE_API_URL": "https://my-app.us-east.insforge.app"}'
```
**Environment variable prefix by framework:**
| Framework | Prefix | Example |
|-----------|--------|---------|
| Vite | `VITE_` | `VITE_INSFORGE_URL` |
| Next.js | `NEXT_PUBLIC_` | `NEXT_PUBLIC_INSFORGE_URL` |
| Create React App | `REACT_APP_` | `REACT_APP_INSFORGE_URL` |
| Astro | `PUBLIC_` | `PUBLIC_INSFORGE_URL` |
| SvelteKit | `PUBLIC_` | `PUBLIC_INSFORGE_URL` |
**Pre-deploy checklist:**
- [ ] `npm run build` succeeds locally
- [ ] All required env vars configured with correct framework prefix
- [ ] Edge function directories excluded from frontend build (if applicable)
- [ ] Never include `node_modules`, `.git`, `.env`, `.insforge`, or build output in the zip
- [ ] Build output directory matches framework's expected output (`dist/`, `build/`, `.next/`, etc.)
### Backup and restore database
```bash
insforge db export --output backup.sql
insforge db import backup.sql
```
### Schedule a cron job
```bash
# Create a schedule that calls a function every 5 minutes
insforge schedules create \
--name "Cleanup Expired" \
--cron "*/5 * * * *" \
--url "https://my-app.us-east.insforge.app/functions/cleanup" \
--method POST \
--headers '{"Authorization": "Bearer ${{secrets.API_TOKEN}}"}'
# Check execution history
insforge schedules logs <id>
```
#### Cron Expression Format
InsForge uses **5-field cron expressions** (pg_cron format). 6-field expressions with seconds are NOT supported.
```
┌─────────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌─────────── day of month (1-31)
│ │ │ ┌───────── month (1-12)
│ │ │ │ ┌─────── day of week (0-6, Sunday=0)
│ │ │ │ │
* * * * *
```
| Expression | Description |
|------------|-------------|
| `* * * * *` | Every minute |
| `*/5 * * * *` | Every 5 minutes |
| `0 * * * *` | Every hour (at minute 0) |
| `0 9 * * *` | Daily at 9:00 AM |
| `0 9 * * 1` | Every Monday at 9:00 AM |
| `0 0 1 * *` | First day of every month at midnight |
| `30 14 * * 1-5` | Weekdays at 2:30 PM |
#### Secret References in Headers
Headers can reference secrets stored in InsForge using the syntax `${{secrets.KEY_NAME}}`.
```json
{
"headers": {
"Authorization": "Bearer ${{secrets.API_TOKEN}}",
"X-API-Key": "${{secrets.EXTERNAL_API_KEY}}"
}
}
```
Secrets are resolved at schedule creation/update time. If a referenced secret doesn't exist, the operation fails with a 404 error.
#### Best Practices
1. **Use 5-field cron expressions only**
- pg_cron does not support seconds (6-field format)
- Example: `*/5 * * * *` for every 5 minutes
2. **Store sensitive values as secrets**
- Use `${{secrets.KEY_NAME}}` in headers for API keys and tokens
- Create secrets first via the secrets API before referencing them
3. **Target InsForge functions for serverless tasks**
- Use the function URL format: `https://your-project.region.insforge.app/functions/{slug}`
- Ensure the target function exists and has `status: "active"`
4. **Monitor execution logs**
- Check logs regularly to ensure schedules are running successfully
- Look for non-200 status codes and failed executions
#### Common Mistakes
| Mistake | Solution |
|---------|----------|
| Using 6-field cron (with seconds) | Use 5-field format only: `minute hour day month day-of-week` |
| Referencing non-existent secret | Create the secret first via secrets API |
| Targeting non-existent function | Verify function exists and is `active` before scheduling |
| Schedule not running | Check `isActive` is `true` and cron expression is valid |
#### Recommended Workflow
```
1. Create secrets if needed -> `insforge secrets add KEY VALUE`
2. Create/verify target function -> `insforge functions list`
3. Create schedule -> `insforge schedules create`
4. Verify schedule is active -> `insforge schedules get <id>`
5. Monitor execution logs -> `insforge schedules logs <id>`
```
### Debug with logs
```bash
insforge logs function.logs # function execution issues
insforge logs postgres.logs # database query problems
insforge logs insforge.logs # API / auth errors
insforge logs postgrest.logs --limit 50
```
#### Best Practices
1. **Start with function.logs for function issues**
- Check execution errors, timeouts, and runtime exceptions
2. **Use postgres.logs for query problems**
- Debug slow queries, constraint violations, connection issues
3. **Check insforge.logs for API errors**
- Authentication failures, request validation, general backend errors
#### Common Debugging Scenarios
| Problem | Check |
|---------|-------|
| Function not working | `function.logs` |
| Database query failing | `postgres.logs`, `postgREST.logs` |
| Auth issues | `insforge.logs` |
| API returning 500 errors | `insforge.logs`, `postgREST.logs` |
### Non-interactive CI/CD
```bash
INSFORGE_EMAIL=$EMAIL INSFORGE_PASSWORD=$PASSWORD insforge login --email -y
insforge link --project-id $PROJECT_ID --org-id $ORG_ID -y
insforge db query "SELECT count(*) FROM users" --json
```
---
## Project Configuration
After `create` or `link`, `.insforge/project.json` is created:
```json
{
"project_id": "...",
"appkey": "...",
"region": "us-east",
"api_key": "ik_...",
"oss_host": "https://{appkey}.{region}.insforge.app"
}
```
`oss_host` is the base URL for all SDK and API operations. `api_key` is the admin key for backend API calls.
> **Never commit this file to version control or share it publicly**.
> Do not edit this file manually. Use `insforge link` to switch projects.
don't have the plugin yet? install it then click "run inline in claude" again.
manage insforge backend-as-a-service projects entirely from the command line. covers auth, project setup, database operations, edge function deployment, file storage, frontend deployments, scheduled tasks, and secret management. use this skill for cli-driven workflows and ci/cd automation. for writing application code that calls insforge services, use the insforge (SDK) skill instead.
cli tool: insforge CLI installed (npm install -g insforge or local binary)
authentication (one required):
INSFORGE_ACCESS_TOKEN env var: pre-existing access token (skips login flow)insforge login opens browser for interactive authINSFORGE_EMAIL and INSFORGE_PASSWORD env vars, or insforge login --email flagproject context (one required):
.insforge/project.json file in working directory (auto-created by create or link)INSFORGE_PROJECT_ID env var: override linked projectINSFORGE_ORG_ID env var (needed for list and multi-project workflows)external api dependencies (optional, context-specific):
api_key in project.json for admin operationsdatabase connection: automatic post-project setup (managed by insforge)
inputs: local filesystem, insforge cli
steps:
insforge whoami to check current userinsforge current to check linked project and orgoutputs:
decision point: if exit code 2, user not authenticated. if exit code 3, project not linked. see procedure 2 or 3.
inputs: browser access (for oauth) or email/password credentials (env vars or flags)
steps:
INSFORGE_ACCESS_TOKEN not set, run insforge login--email flag with INSFORGE_EMAIL and INSFORGE_PASSWORD env vars for non-interactive ci/cd~/.insforge/credentials.jsonoutputs:
edge cases:
inputs: existing project id and org id (for link), or none (for create)
steps for create:
insforge create --name <project-name> [--org <org-id>].insforge/project.json written to working directorysteps for link:
insforge link [--project-id <id>] [--org-id <id>].insforge/project.json written with project configoutputs:
.insforge/project.json containing: project_id, appkey, region, api_key, oss_hostedge cases:
insforge link --project-id X to switchinputs: .insforge/project.json, sql statements or sql files
steps for query:
insforge db query "SELECT * FROM posts" for read operationsinsforge db query "CREATE TABLE posts (...)" for ddlsteps for inspection:
insforge db tables to list all tablesinsforge db indexes to list indexesinsforge db policies to list rls policiesinsforge db triggers to list triggersinsforge db functions to list plpgsql functionssteps for rpc calls:
insforge db rpc function_name for parameterless calls (uses get)insforge db rpc function_name --data '{"key":"value"}' for calls with params (uses post)steps for export:
insforge db export --output backup.sql to dump schema and datasteps for import:
insforge db import backup.sql to restore schema and dataoutputs:
--json for structured output.sql file on diskedge cases:
inputs: function source code in insforge/functions/{slug}/index.ts, node/typescript runtime
steps for deploy:
insforge/functions/{slug}/index.tsinsforge functions deploy slug to package and uploadhttps://{appkey}.{region}.insforge.app/functions/{slug}steps for list:
insforge functions list to show all deployed functions with statussteps for view source:
insforge functions code slug to print function sourcesteps for invoke:
insforge functions invoke slug for parameterless calls (uses get)insforge functions invoke slug --data '{"action":"test"}' for calls with body (uses post)insforge functions invoke slug --method DELETE to override http methodoutputs:
edge cases:
inputs: .insforge/project.json, local files (for upload)
steps for list buckets:
insforge storage buckets to show all buckets with region and access levelsteps for create bucket:
insforge storage create-bucket name [--private] (default: public)steps for list objects:
insforge storage list-objects bucket-name to list all objects--prefix path/ to filter by prefix--search term to search object keys (substring match)--limit 100 to cap results--sort name|size|modified to order resultssteps for upload:
insforge storage upload ./file.pdf --bucket my-bucket to upload with auto keyinsforge storage upload ./file.pdf --bucket my-bucket --key docs/file.pdf to specify keysteps for download:
insforge storage download path/to/object --bucket my-bucket to download to cwdinsforge storage download path/to/object --bucket my-bucket --output ./local-file.pdf to save as different namesteps for delete bucket:
insforge storage delete-bucket bucket-name to delete bucket and all contents permanently-y flag usedoutputs:
edge cases:
inputs: built frontend code in directory (e.g., ./dist, ./build, ./.next), .insforge/project.json
steps:
npm run build locally to verify build succeeds (do not skip this)insforge deployments deploy ./dist --env '{"VITE_API_URL":"https://..."}' to upload and build on insforgehttps://{appkey}-{hash}.{region}.vercel.appsteps for list:
insforge deployments list to show all past deployments with statussteps for status:
insforge deployments status deployment-id to check current build state--sync flag to fetch latest status from vercel (bypasses cache)steps for cancel:
insforge deployments cancel deployment-id to abort running build (confirmation required unless -y)outputs:
environment variables by framework:
VITE_ (e.g., VITE_INSFORGE_URL)NEXT_PUBLIC_ (e.g., NEXT_PUBLIC_INSFORGE_URL)REACT_APP_ (e.g., REACT_APP_INSFORGE_URL)PUBLIC_ (e.g., PUBLIC_INSFORGE_URL)PUBLIC_ (e.g., PUBLIC_INSFORGE_URL)edge cases:
inputs: .insforge/project.json, target function url or external api url, 5-field cron expression, optional headers with secret references
steps for list:
insforge schedules list to show all schedules with id, name, cron, url, method, active status, next_run_timesteps for get:
insforge schedules get schedule-id to show full schedule details including headers and bodysteps for create:
insforge schedules create --name "Task Name" --cron "*/5 * * * *" --url "https://..." --method POST [--headers '{}'] [--body '{}']${{secrets.KEY_NAME}}steps for update:
insforge schedules update schedule-id --cron "0 9 * * *" [--active true|false] [--url ...] [--method ...] [--headers ...] [--body ...]steps for delete:
insforge schedules delete schedule-id (confirmation required unless -y)steps for view logs:
insforge schedules logs schedule-id to show execution history (last 20 by default)--limit 50 to show more entries--offset 10 to paginate resultsoutputs:
--json formatcron expression examples:
* * * * * every minute*/5 * * * * every 5 minutes0 * * * * every hour at minute 00 9 * * * daily at 9:00 am0 9 * * 1 every monday at 9:00 am0 0 1 * * first day of month at midnight30 14 * * 1-5 weekdays at 2:30 pmsecret references:
${{secrets.KEY_NAME}}--headers '{"Authorization":"Bearer ${{secrets.API_TOKEN}}"}'edge cases:
isActive is true and cron expression valid via getinputs: .insforge/project.json, secret key and value (string)
steps for list:
insforge secrets list to show all active secrets (values hidden)--all to include deleted/inactive secretssteps for get:
insforge secrets get KEY to retrieve decrypted value (stdout, no masking)steps for add:
insforge secrets add KEY VALUE to create new secret--reserved flag to mark as reserved (cannot be updated, can be deleted and re-created)--expires "2025-12-31T23:59:59Z" (iso 8601) to set expiry (warning shown when near expiry)steps for update:
insforge secrets update KEY --value NEW_VALUE to change valueinsforge secrets update KEY --active false to deactivate (soft delete)insforge secrets update KEY --active true to restore deleted secret--value (delete and re-create instead)steps for delete:
insforge secrets delete KEY to soft delete (marks inactive)--all in list to see deleted secretsinsforge secrets update KEY --active true to restoreoutputs:
edge cases:
inputs: .insforge/project.json, log source name
steps:
insforge logs function.logs to view edge function execution logsinsforge logs postgres.logs to view database query logsinsforge logs insforge.logs to view main backend api logsinsforge logs postgrest.logs to view postgrest gateway logs--limit 50 to show more than default 20 entries (max 1000)outputs:
edge cases:
inputs: .insforge/project.json (read-only)
steps for view current:
insforge current to display linked project, org, user, and regioninsforge list to show all projects and orgs the user has access tosteps for logout:
insforge logout to delete stored credentialsoutputs:
never edit .insforge/project.json manually: use insforge link to switch projects.
edge cases:
if authentication fails (exit code 2):
INSFORGE_EMAIL and INSFORGE_PASSWORD set, issue is credential mismatch. re-check values or retry with insforge login in browser.insforge login interactively (requires browser and network access).INSFORGE_ACCESS_TOKEN set, token may be expired. run insforge logout and re-authenticate.if project not linked (exit code 3):
insforge create --name X to initialize.insforge link --project-id X --org-id Y with existing ids.insforge list to discover available projects in orgs.if resource not found (exit code 4):
list command for relevant resource type to confirm existence.if permission denied (exit code 5):
if 6-field cron expression used for schedule:
0 */5 * * * * becomes 5-field */5 * * * *.if schedule references non-existent secret:
insforge secrets add KEY VALUE.insforge schedules create or update with correct secret reference syntax ${{secrets.KEY_NAME}}.if frontend deploy fails locally:
npm run build).if storage bucket not empty and delete is required:
insforge storage delete-bucket name deletes bucket and all objects atomically. this is permanent.list-objects first to inspect contents.if db query returns permission denied:
insforge db policies to understand allow conditions.auth.uid()) matches required column.if schedule execution logged as timeout in logs:
if export operation times out:
insforge db query to export specific tables instead of full schema.successful authentication:
~/.insforge/credentials.json (unix/mac) or %APPDATA%\insforge\credentials.json (windows)logoutsuccessful project link/create:
.insforge/project.json created in current working directory with schema:{
"project_id": "uuid",
"appkey": "alphanumeric string",
"region": "us-east | eu-west | ap-southeast",
"api_key": "ik_alphanumeric",
"oss_host": "https://{appkey}.{region}.insforge.app"
}
database operations:
--json flag)edge function deployment:
https://{appkey}.{region}.insforge.app/functions/{slug}file storage:
docs/2024/report.pdf)https://{appkey}.{region}.insforge.app/storage/v1/object/public/{bucket}/{key} (public bucket)deployments:
https://{appkey}-{hash}.{region}.vercel.appdeployments deploy with previous sourceschedules:
secrets:
logs:
user knows authentication succeeded:
insforge whoami prints email address and exit code is 0insforge current prints org id and project id (or project id empty if not linked)user knows project is linked:
.insforge/project.json exists in working directoryinsforge current prints project id and regionuser knows database operation succeeded:
insforge db query returns result set or "0 rows" (for no results)user knows edge function deployed:
insforge functions list shows function with status activeinsforge logs function.logsuser knows file uploaded:
insforge storage upload prints "uploaded to {key}"insforge storage list-objects shows object in bucketinsforge storage downloaduser knows frontend deployed:
insforge deployments list shows new deployment with status successuser knows schedule is active:
insforge schedules get shows isActive: trueinsforge schedules logs shows execution attempts at next cron interval (within 1 minute of scheduled time)user knows secret is stored: