Skip to content

Get started

From nothing to a gateway

Five steps. Every block below is real output — the project's own rule is that a claim is a measurement or it is removed, and that applies to its documentation too.

  1. 01Install

    Python 3.10–3.13 and git. A GPU — a graphics processing unit — is needed only on the machine that serves; clients need neither.

    git clone https://github.com/warith-harchaoui/ai-bunker.git
    cd ai-bunker
    python3 -m venv .venv && source .venv/bin/activate
    pip install -e ".[api]"
  2. 02Find out what you need

    Before buying anything. The cheapest answer is often the machine you already own, which is in the catalogue at $0 so that "buy nothing" is a costed option rather than a shrug.

    $ ai-bunker recommend --team 2 --model qwen3-coder-next --vision qwen3-vl-8b
    
      LOAD MODEL
        each person decodes 25% of a session, 50% of the team is in session at peak
        → 95th percentile of Binomial(2, 0.125) = 2 concurrent sequences
        the machine must sustain 2 sequence(s) above 20 tok/s
    
      ✔ BUY
          Apple MacBook Pro M2 Max 96GB (existing)
          90 GiB · 400 GB/s · $0
          carries 5 sequences (needs 2) at 20 tok/s each, 27 tok/s alone

    Why the sizing works this way →

  3. 03Configure, and check the claims

    cp config/gateway.example.yaml config/gateway.yaml
    export AI_BUNKER_API_KEY="$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')"
    
    $ ai-bunker doctor
      [ok  ] charter carries operating rules
      [ok  ] 27 rules loaded
      [ok  ] 247 rule assertions pass
      [ok  ] 100% of rules carry evidence
      [WARN] upstream local answers at http://127.0.0.1:8001/v1   not reachable
      [ok  ] no route leaves this network
      12/14 checks pass

    doctor reports what the deployment actually does, including that a gateway without an API key — an application programming interface key — is open to anyone who can reach it. Open by accident and open on purpose look identical from outside; this is what tells them apart.

  4. 04Serve, and point a client at it

    ai-bunker serve                      # localhost:8000
    
    export OPENAI_BASE_URL="http://127.0.0.1:8000/v1"
    export OPENAI_API_KEY="$AI_BUNKER_API_KEY"

    That is the whole client configuration. Any client that speaks OpenAI now gets the charter, the rule engine and the budget without being configured for them.

    The dashboard is at /gui:

    The ai-bunker dashboard in its light theme. A status bar across the top carries chips reading 'sovereign', 'open to anyone who can reach it', '10 output rules', '12 command rules' and '3 tool rules', and a sun button that switches to the dark theme. Below, a thin bar shows the session floor as a sliver of orange against a nearly empty window, labelled 'floor 595 — under 1% of the window' and '193,120 left to work with'. A second, wider bar breaks that floor into its two components, charter at 448 tokens (75%) and knowledge index at 147 (25%), both owned by ai-bunker, and a table repeats them with their shares. A panel on the right reports 262,144 tokens served by the engine, 209,715 declared to clients, a 16,000-token compaction margin and 193,120 of conversation space, and says the count was made by the server's own tokenizer rather than estimated.
    Two bars rather than one: a 300:1 ratio and a composition are two different questions, and one bar cannot carry both.
  5. 05Equip a repository

    $ ai-bunker adopt /path/to/project --list
    Adopting ai-bunker into /path/to/project:
      + charter/AGENTS.md   (how to work here, injected every request)
      + charter/packs   (the standards pages, read on demand)
      + charter/rules   (the rules, with their own evidence)
      + opencode.json   (points at the gateway)
      + .opencode/plugins/bounded-reads.js   (the one thing the gateway cannot do)
      + .claude/settings.ai-bunker.json   (merge into .claude/settings.json)
      + CLAUDE.md   (what the gateway does to a session)

    Nothing is overwritten without --force. The client kit is deliberately one config and one plugin: everything the gateway can see, the gateway enforces, so a kit carries only what happens before a request exists — bounded reads, no skill injection, compaction thresholds.

Before you depend on it

This is 0.2.0-alpha: a green continuous-integration (CI) gate, next to projects with years of production use. Command screening applies to streamed completions as well as atomic ones — a tool call asked for in fragments is assembled, judged by the same code path, and refused the same way — and /health reports which guarantees are live rather than implying all of them are.

And what is still open

  • Counting is serialised, by a lock and on purpose. The tokenizer probe and the counts are synchronous calls. They used to run inside asynchronous handlers, and /health took 9.73 seconds against a silent engine; the inbound pipeline now runs in a worker thread and the same stall costs it 0.01 seconds. Two requests still do not count at once — the gateway's shared state has never needed a lock because nothing was ever concurrent, and an availability fix paid for with a data race is not a fix.
  • The audit log grows without bound. Appended to, never rotated: rotation belongs to whatever already rotates logs on that host, and nothing here will tell you the file is large. In-memory state is bounded, oldest sessions evicted first.
  • A request above thirty-two characters per token of served context is refused unread. Screening costs time linearly in what arrives, and a worker thread does not change that — pattern matching holds the interpreter lock. This ceiling is what bounds it, so it applies to every surface that carries a body. About four mebibytes on a 131,072-token engine: roughly thirteen times the largest request that could ever fit, because refusing one that would have fitted is the worse failure.
  • Personal data is not screened. The rules cover credentials, prompt injection, dangerous shell commands and tool descriptions — not names, addresses, national identifiers or payment cards. A deployment with an obligation about personal data needs a content inspector; this is a gateway, and the landscape says which tools do that properly.
  • The shell-tool vocabulary is a default, not a claim to completeness. A gateway cannot know every client's tool names, so SHELL_TOOLS is overridable — and a tool it does not recognise is a command it does not screen.

A limitation nobody published is one somebody discovers. The exact bounds are quoted once, where they can be checked against the code: stated limitations, in full →

Every command, with its real output →