●Product

Three primitives. One slice axis per layer.

Customer → Product → Tenant. The Customer is your workspace — billing, users, allowed domains. The Product is what your SDK authenticates as — its own apiKey, its own flag namespace, its own audit stream. The Tenant is the slice your flag value resolves for — a B2B customer organisation, a brand variant of one codebase, a region, a cohort. Same data shape, same override semantics, same audit boundary regardless of what you're slicing by. Every flag, every rule, every audit row is scoped at the storage layer — bypass is impossible because the row can't be written without all three.

●Architecture

The whole platform is built around three data layers.

MVP runs on Firebase. A custom data plane is a post-PMF decision, not day one.

Layer 04SDK
evaluate() subscribe() audit()
Layer 03Rules
flag tenant override rollout approval
Layer 02Tenant
tenant_id env scope region
Layer 01Storage
firestore onSnapshot · change log cloud functions
●SDK

Per-Product apiKey. Per-tenant evaluation.

Each Product has its own apiKey — the SDK uses it to identify which Product's flags to fetch. For multi-tenant Products, the evaluation API also requires a tenantId, enforced server-side. iOS, Android, and Web SDKs ship today, pushing flag changes in real time via Firestore listeners (~1s, no polling). Web ships as two packages — @argus/client for the browser (real-time) and @argus/node for server-side pull / SSR. Edge resolution lands in v1.5.

typescript · argus-sdk@v0
// scoped, deterministic, reversible
const flag = await argus.evaluate({
  key:     "new_billing_v2",
  tenant:  ctx.tenantId,      // required
  env:     "prod",
});

if (flag.on) renderNewBilling();

// → audit row written, scoped to tenant.
// → reversible from the dashboard in one click.
// → impossible to evaluate without a tenant.
●Web SDK

Drop Argus into the browser and the server.

The Web SDK ships as two packages that share one read-scoped apiKey. @argus/client runs in the browser: it seeds flag values with a single resolveFlags pull, then subscribes to a Firestore listener so changes land in real time (~1s, no polling). @argus/node runs on the server for SSR and request-scoped evaluation, and serialises resolved flags so the browser hydrates without a second round trip. Same shape as the iOS and Android SDKs — one apiKey per Product, an optional tenantId for multi-tenant resolution.

typescript · @argus/client
// browser · real-time via Firestore listener
import { init } from "@argus/client";

const argus = await init({
  apiKey:   import.meta.env.ARGUS_KEY,
  baseUrl:  "https://api.your-argus.cloud",
  tenantId: "acme_retail",   // optional
});

if (argus.getFlag("new_billing_v2", false))
  renderNewBilling();

// re-renders when a flag flips, live
argus.onChange((flags) => paint(flags));

// React: import { useFlag } from "@argus/client/react"
argus.close(); // detach the listener
typescript · @argus/node
// server · request-scoped pull + SSR hydration
import { createClient } from "@argus/node";

const argus = createClient({
  apiKey:  process.env.ARGUS_KEY,   // same key
  baseUrl: "https://api.your-argus.cloud",
});

const ctx = { userId: user.id, tenantId: "acme_retail" };
const on = await argus.getFlag("new_billing_v2", false, ctx);

// hand the resolved set to the browser, no re-fetch
res.locals.argusState = argus.serialize(ctx);
// → @argus/client picks it up to hydrate instantly.

baseUrl is your Cloud Functions origin. One read-scoped apiKey covers both packages — there is no public / secret split. The init and resolution API shown here is shipped today; the npm packages publish with v1 — until then a preview build is available from the SDK repository.

●MCP

Manage flags from your AI coding agent.

Argus ships a local MCP server (argus-mcp) so an AI coding agent — Claude Code, Cursor, and the like — can manage feature flags from inside a coding session: list, create, and publish flags, set per-environment values, and toggle them, without leaving the editor.

01 · Governed by default

New flags land as DRAFT — invisible to SDKs until published.

Changing a prod value requires explicit confirmation. The agent gets reach, not a blank cheque.

02 · Every mutation audited

The agent writes to the same audit log as a human.

Each change records actor, timestamp, env, tenant, flag, before, and after — tagged as the agent. Append-only, same as any other change.

03 · Founder / local today

Runs as a local stdio server, authenticated with a local service-account key.

No per-agent tokens yet. A productized, multi-tenant MCP with per-agent revocable tokens is on the roadmap.

●Tenant overrides

Resolution order, plainly stated.

Tenant override documents are first-class — not a special case of segments. They have their own audit stream and resolution lane.

→
Default
flag default value at evaluation time
→
Flag rule
global rule (env, segment, version target)
→
Tenant override
tenant-owned override document · audited
→
Rollout
per-tenant % · deterministic per-user bucket (seed + userId)
→
Resolved value
flag.on · with source metadata in response
→
Audit row
append-only · tenant-scoped · reconciled
●Approvals & RBAC

Two engineers approve prod. Roles scope to tenant.

01 · Two-engineer approval

Production-impacting changes require a second reviewer.

Approval is a flow, not a checkbox. Requested → assigned → approved → applied. Each step writes an audit row.

approval · requested · by shahin just now
awaiting 1 of 2 · reviewers marco, roberto —
02 · Tenant-scoped RBAC

Three roles, each a strict superset of the last.

A contributor changes dev and proposes everything higher. An approver approves changes and sets dev / staging directly. A super_user owns prod and user management.

Roledevstagingprodapproveusers
contributor●○○○○
approver●●○●○
super_user●●●●●
●Audit log

Append-only. Product- and tenant-scoped. Source metadata travels.

Every resolution response carries the source of the value (default · rule · override · rollout). Every change writes a row you can query by product and tenant.

argus / audit · tenant=98chimp streaming
flag=new_billing_v2 tenant=98chimp env=prod before=off after=50% actor=shahin just now
approval=applied flag=new_billing_v2 approvers=marco, shahin 2m
override=created flag=kyc_lite tenant=98chimp value=on 14m
rbac=grant role=approver scope=tenant:98chimp subject=roberto@98chimp.com 38m
4 rows · last 1h · exportable to your siem append-only
●Capability matrix

Multi-tenancy as the first row, not a checkbox.

Honest comparison against the alternatives most teams already run. We update this page as the tools ship changes.

Capability Argus LaunchDarkly Statsig Flagsmith DIY
Tenant as first-class primitive ● ○◐◐○
Scoped audit log per tenant ● ◐◐○○
Two-engineer prod approval ● ✓○○○
Deterministic per-tenant rollout (hash) ● ✓✓◐◐
Self-host parity (control + data plane) ● ○○✓✓
Pricing not coupled to end-customer MAU ● ○○◐✓
● built   ◐ partial   ✓ via add-on   ○ none   ·   source · manus apr 2026, vendor docs apr 2026
●Roadmap

Plain text. Honest horizons.

Shipping now

v0 · MVP on Firebase

  • Tenant-scoped evaluation API
  • Per-tenant override documents
  • iOS, Android + Web SDKs (real-time push)
  • Two-engineer prod approval
  • Tenant-scoped RBAC
  • Immutable audit rows
  • Reversible tenant-scoped rollback
Next 60 days

v1 · with design partners

  • Tenant feature matrix export (CSV + API)
  • Audit feed export to customer SIEM
  • Self-host helm chart (control + data parity)
On the roadmap

v1.5+ · with proof

  • Edge resolution
  • Code-reference scanning · dead flag detection
  • SOC 2 audit export packaging
  • Operational AI · tenant rollout suggestions from history
●What's next

Start free, or see the pricing.

Free is $0 with no card. Paid plans start at $199/month, with per-tenant pricing for multi-tenant portfolios. The full breakdown is on the pricing page.