octarq

command module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 9 Imported by: 0

README

Octarq — the self-hosted back office for one-person companies & AI-native teams

CI MCP Powered

English | 简体中文

Octarq is a single Go binary you extend with plugins — the self-hosted operations backend for indie hackers, one-person companies, and small AI-native teams.

Own a domain? Octarq already gives you the things you'd otherwise wire together from three SaaS bills: short links with analytics, inbound/outbound email, and DNS automation — each shipped as a first-class plugin, not a locked-in feature. Then you extend it the same way its own core is built: a small Go interface + a React page = a new tool in your back office. And because Octarq speaks MCP, every plugin you add is instantly drivable by your AI agent (Claude Code, Cursor, Claude Desktop).

One binary. No CGO. SQLite by default. go:embed'd dashboard. Extend without forking.


Why Octarq

Think of it as the intersection of three tools you already know:

  • PocketBase's single-binary, extend-in-an-afternoon developer experience —
  • applied to Dub-style links + real domain/email/DNS infrastructure —
  • with an n8n-style plugin ecosystem for connectors (Telegram, Webhooks, SMS, …) —
  • and every capability is agent-native over MCP.

Octarq isn't a URL shortener that also does email. It's a framework: links/email/DNS are the reference plugins that prove the model, and the ecosystem grows toward whatever a one-person company needs to self-host next.


Batteries included (the reference plugins)

These ship in the default build so Octarq is useful on minute one:

  • 🔗 Links — custom/random slugs, geo/device/OS/language routing, expiration & click limits, expired-URL fallbacks, time-series analytics with bot detection, UTM builder, QR codes, tags (optional MaxMind GeoIP).
  • ✉️ Mail — serverless inbound mail via Cloudflare Email Routing (no port 25, no spam daemons), catch-all auto-provisioning, a full client (read/reply/send over your SMTP relays, download raw .eml), on-demand AI summaries (BYO key).
  • 🌐 DNS — Cloudflare & DNSPod CRUD, subdomain presets for short-link + email auth (MX/SPF/DKIM), native comment/notes mapping.
  • 🏢 Workspaces & RBAC — isolated multi-tenant orgs, server-enforced roles, invite/onboarding, hashed Bearer API tokens.

Every one of these is a plugin.Plugin + UIPlugin — the exact same seam your own plugins use.


Agent-native: your plugin is an MCP tool

Octarq ships a built-in MCP server (octarq mcp, over stdio and SSE/stream) so assistants like Claude Code can read and query your instance — list_links, list_mailboxes, list_domains, export_data, plus a guarded read-only SQL tool (SELECT/WITH only, row-capped, secrets auto-redacted).

The point isn't "we added AI." The point is the framework wiring: a plugin that implements the optional MCPProvider interface exposes its own tools to every connected agent — no extra plumbing. Write a plugin, and your AI agent can drive it.

📬 New OTP email arrives ──▶ your 10-line plugin (OnEmail hook)
                              ├─ generates a short link (links service)
                              └─ exposes it as an MCP tool ──▶ Claude Code consumes it

Quick start

git clone https://github.com/octarq-org/octarq.git && cd octarq
cp .env.example .env          # set OCTARQ_SECRET_KEY and OCTARQ_ADMIN_PASSWORD
docker compose up -d

Open http://localhost:8080 and log in. That's the full stack — dashboard, API, redirector, MCP — in one container backed by SQLite.

Prefer a ~19MB scratch image or from-source build? See make release and deploy/.


Extend it (write a plugin)

A plugin is one repo with two mirror halves, composed at build time (like xcaddy — pick your plugins, build a binary):

// backend: implement a 3-method interface, get DB/auth/audit/DNS/mail/cache for free
func (Plugin) Name() string          { return "hello" }
func (Plugin) Models() []any         { return nil }
func (Plugin) Mount(mux plugin.Mux, ctx *plugin.Context) {
    mux.Handle("GET /api/hello/ping", ctx.Guard(http.HandlerFunc(pong)))
}
// frontend: a React page from the shared SDK — matches the app, a11y for free
export const helloPlugin: UIPlugin = {
  name: "hello",
  routes: [{ path: "/hello", Component: lazy(() => import("./Page")) }],
  menu:  [{ id: "hello", label: "Hello", path: "/hello", icon: "👋", category: "Workspace" }],
};
  • Never fork, never import internal/* — everything is on plugin.Context (DB, Guard, Encrypt, Audit, Notify, SendMail, OnEmail, DNS, cache, geo, webhooks, job queue…), evolved additive-only.
  • Routes auto-gate (404 when disabled), plugins talk via a service registry (no cross-imports), models auto-migrate.
  • Compose a custom binary without editing code — the xcaddy model:
    OCTARQ_PLUGINS='[{"go":"github.com/you/octarq-plugin-foo","npm":"@you/octarq-plugin-foo"}]' make plugin-build
    

Start from the templateoctarq-plugin-template · Guidedocs/PLUGINS.md

Octarq's own Pro edition is just another set of plugins built against this same public interface — nothing the community can't do.


Setup guides

  • Email via Cloudflare Worker — deploy deploy/cloudflare-email-worker.js, set a catch-all route, enable Accept email.
  • GeoIP analytics — set OCTARQ_MAXMIND_LICENSE_KEY (free) and Octarq auto-downloads + hot-loads GeoLite2. See deploy/GEOIP.md.
  • MCP in Claude Desktop — point claude_desktop_config.json at octarq mcp.
Claude Desktop MCP config
{ "mcpServers": { "octarq": {
  "command": "/path/to/octarq", "args": ["mcp"],
  "env": { "OCTARQ_DB_PATH": "/path/to/octarq.db" }
}}}

Development

OCTARQ_SECRET_KEY=dev OCTARQ_ADMIN_PASSWORD=dev go run .   # backend :8080
make dev                                                  # Vite frontend, proxies /api
go test ./... -race

Credits

Inspired by and built on ideas from

and the DX bar set by

License

MIT. The framework stays permissive; the commercial edition is a private set of plugins on top.

Documentation

Overview

Command octarq is a single-binary domain / short-link / email management service (link · email · domain). It serves an embedded React dashboard, a JSON API, and a short-link redirector from one process.

This is the open-core binary: it runs the app with no Pro plugins. The commercial build (private octarq-core module) reuses the same app package and registers additional plugins before Run — see the plugin package.

Subcommands:

octarq          run the HTTP server (default)
octarq mcp      run the Model Context Protocol server over stdio, exposing
             read-only short-link / email / domain tools (plus a guarded
             read-only SQL tool) to AI clients such as Claude Code, Claude
             Desktop and Cursor. See internal/mcp.

Directories

Path Synopsis
Package app is the public composition root for octarq.
Package app is the public composition root for octarq.
cmd
octarq-build command
Command octarq-build wires third-party plugins into a custom Octarq binary at build time — the xcaddy model: pick plugins, build a binary.
Command octarq-build wires third-party plugins into a custom Octarq binary at build time — the xcaddy model: pick plugins, build a binary.
openapi-gen command
Package config loads runtime configuration from environment variables.
Package config loads runtime configuration from environment variables.
examples
edition-nomail command
Command edition-nomail is a worked example of a trimmed octarq edition: it composes only the dns and links Core plugins (no mail) by building its own composition root instead of using plugins/builtin.Default().
Command edition-nomail is a worked example of a trimmed octarq edition: it composes only the dns and links Core plugins (no mail) by building its own composition root instead of using plugins/builtin.Default().
plugin-hello
Package hello is a minimal, copy-me example of a octarq plugin: the Go half of a full-stack feature.
Package hello is a minimal, copy-me example of a octarq plugin: the Go half of a full-stack feature.
internal
api
Package api implements octarq's JSON HTTP API.
Package api implements octarq's JSON HTTP API.
auth
Package auth implements session authentication using a DB-backed session token stored in a signed cookie.
Package auth implements session authentication using a DB-backed session token stored in a signed cookie.
cleanup
Package cleanup runs periodic maintenance: purging expired data based on the retention window.
Package cleanup runs periodic maintenance: purging expired data based on the retention window.
crypto
Package crypto provides AES-GCM encryption for secrets at rest and HMAC signing for session cookies.
Package crypto provides AES-GCM encryption for secrets at rest and HMAC signing for session cookies.
db
Package db opens the configured database (SQLite or Postgres) through GORM and runs migrations.
Package db opens the configured database (SQLite or Postgres) through GORM and runs migrations.
dnsprovider
Package dnsprovider abstracts DNS record management across providers.
Package dnsprovider abstracts DNS record management across providers.
geo
Package geo resolves a client IP into country/city (optional, via a MaxMind GeoLite2 mmdb) and parses a User-Agent into device/browser/os.
Package geo resolves a client IP into country/city (optional, via a MaxMind GeoLite2 mmdb) and parses a User-Agent into device/browser/os.
mail
Package mail parses inbound MIME messages and sends outbound mail via SMTP.
Package mail parses inbound MIME messages and sends outbound mail via SMTP.
mcp
Audit trail for AI database access through the MCP server.
Audit trail for AI database access through the MCP server.
models
Package models defines the GORM persistence schema for octarq.
Package models defines the GORM persistence schema for octarq.
notify
Package notify delivers best-effort notifications about octarq events.
Package notify delivers best-effort notifications about octarq events.
safehttp
Package safehttp provides an HTTP client hardened against SSRF for any server-side fetch or POST of a user-supplied URL (link previews, outbound webhooks, notification channels, SNS confirmations).
Package safehttp provides an HTTP client hardened against SSRF for any server-side fetch or POST of a user-supplied URL (link previews, outbound webhooks, notification channels, SNS confirmations).
server
Package server wires the API, short-link redirector, and embedded SPA behind a single http.Handler.
Package server wires the API, short-link redirector, and embedded SPA behind a single http.Handler.
Claude (Anthropic Messages API) backend for llmprovider.
Claude (Anthropic Messages API) backend for llmprovider.
Package plugin defines the public, importable contract that anyone implements to extend octarq without forking it.
Package plugin defines the public, importable contract that anyone implements to extend octarq without forking it.
plugins
builtin
Package builtin is the OSS edition's default Core feature set.
Package builtin is the OSS edition's default Core feature set.
dns
Package dns is a built-in Core plugin: domain management and DNS — the operator's zones, per-zone DNS-provider credentials (Cloudflare, …), live record CRUD through the provider, and the DNS-verification posture (SPF/DMARC/ DKIM for mail hosts, CNAME health for link hosts).
Package dns is a built-in Core plugin: domain management and DNS — the operator's zones, per-zone DNS-provider credentials (Cloudflare, …), live record CRUD through the provider, and the DNS-verification posture (SPF/DMARC/ DKIM for mail hosts, CNAME health for link hosts).
links
Package shortlink resolves slugs to targets, records click events asynchronously, and renders the password gate when a link is protected.
Package shortlink resolves slugs to targets, records click events asynchronously, and renders the password gate when a link is protected.
Package webembed embeds the built React dashboard into the binary.
Package webembed embeds the built React dashboard into the binary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL