# Arkloop runs an agent platform as one Go process and a SQLite file

> Arkloop is a local-first desktop app and CLI for conversational AI agents, built as a single embedded Go process over a local SQLite database with no container to deploy. It suits one person or one team running agents on their own machine, and its licence stops short of letting you resell it as a multi-tenant service.

**qqqqqf-q/Arkloop** — 干净、强大、属于你的 AI Agent 平台  --AI agents, without the clutter.

- Repository: https://github.com/qqqqqf-q/Arkloop
- Website: https://arkloop.io
- Stars: 377 · Forks: 34
- Language: Go
- License: NOASSERTION
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/qqqqqf-q-arkloop

## One Go process is the API, the worker and the database

Arkloop's central design choice is that the backend is a library boundary rather than a deployment. The API and the worker are compiled into a single embedded process, storage is a local SQLite file migrated automatically on first start, and events move through an in-process bus. There is no Postgres, no Redis and no message queue to stand up. Above that sit four pieces: an Electron shell that embeds the Go runtime, the Go runtime itself, a React and TypeScript chat UI bundled into the desktop app and also served by the CLI, and the `ark` binary, which is a headless door into the same process.

What that buys is that the same conversation surface works whether you started it from a window or from an SSH session. What it costs is a ceiling. Everything in the process shares one machine's disk, one memory budget and one failure domain, so an unattended scheduled job and an interactive chat contend for the same resources.

Storage is configurable rather than hardcoded. `ARKLOOP_STORAGE_BACKEND` defaults to `filesystem` and `ARKLOOP_STORAGE_ROOT` to `/var/lib/arkloop/storage`, a combination the example configuration describes as suited to single-node self-hosting.

## The desktop build compiles out Redis, PostgreSQL and S3

The repository is larger than the desktop application, and the Makefile is where the difference becomes explicit. `build-desktop` runs `go build -tags desktop ./cmd/...` inside `src/services/worker` with a comment stating it excludes Redis, PostgreSQL and the S3 SDK. `SERVICES` in the same file still names `api`, `worker` and `sandbox`, and a `.dockerignore` sits at the repository root, so a cloud or container layout exists in the tree alongside the local one.

The test target mirrors the split. `test-desktop` runs its suites behind the same tag and covers only portable packages: `internal/agent`, `internal/consumer`, `internal/llm`, `internal/memory`, `internal/queue`, `internal/runtime`, `internal/tools` and `internal/webhook`, skipping anything that pulls in `pgx`, Redis or S3. Read that list as the honest scope of what a single-binary install is tested against.

For anyone forking this, the consequence is concrete. Changes to routing or memory behaviour land inside those tested packages, while reaching the container path means inheriting a build matrix the desktop target deliberately narrows.

## Secrets are AES-256-GCM, and the refresh token lives for 30 days

`.env.example` states the security model more precisely than the prose does. Secrets, API keys among them, are stored with AES-256-GCM under `ARKLOOP_ENCRYPTION_KEY`, which must be 64 hex characters or 32 bytes, generated with `openssl rand -hex 32`. The shipped value is a placeholder, `please_generate_with_openssl_rand_hex_32`, so an install that skips that step runs on a key that is already public in the repository.

Authentication is a JWT pair. `ARKLOOP_AUTH_JWT_SECRET` needs at least 32 characters, and its default pads the length by repeating `please_change_me`. `ARKLOOP_AUTH_ACCESS_TOKEN_TTL_SECONDS` sits at 900, which is fifteen minutes, while `ARKLOOP_AUTH_REFRESH_TOKEN_TTL_SECONDS` is 2592000, or thirty days. A refresh token taken from a machine therefore outlives a work session by a month, and the process holding it also holds your provider keys.

Two operational knobs matter. `ARKLOOP_LIMIT_CONCURRENT_RUNS` caps parallel runs per org at 10, and `ARKLOOP_LLM_DEBUG_EVENTS`, off by default, writes raw model input and output chunks into `run_events`, which the file marks as local development only. Its companion `ARKLOOP_DEBUG_SSE` is the flag to reach for when a stream ends in an unexpected EOF, correlated by `trace_id` and `run_id`.

## Four install doors, and only one of them gives you a window

The desktop app comes from GitHub Releases for macOS, Linux and Windows, bundles the whole runtime, and needs no Docker and no configuration to start, with automatic updates through the same release feed. On first launch the app can install the `ark` command-line tool, after which the same runtime runs without a window:

```bash
ark web
```

Homebrew installs the CLI only, so that route gives you the headless server and not the Electron shell:

```bash
brew install qqqqqf-q/arkloop/arkloop && ark web
```

Arch users choose between a prebuilt binary and a source build:

```bash
yay -S arkloop-bin    # prebuilt binary
yay -S arkloop-git    # build from source
```

For a machine with no package manager, the project publishes one command that resolves the architecture, refuses anything it has no build for, extracts the archive, and starts the server on all interfaces without opening a browser:

```bash
sh -c 'set -e; arch="$(uname -m)"; case "$arch" in x86_64|amd64) arch=amd64 ;; aarch64|arm64) arch=arm64 ;; *) echo "unsupported architecture: $arch" >&2; exit 1 ;; esac; name="ark-linux-${arch}"; rm -rf "$name"; curl -fsSL "https://github.com/qqqqqf-q/Arkloop/releases/latest/download/${name}.tar.gz" | tar -xz; cd "$name"; exec ./ark web --host 0.0.0.0 --no-open'
```

Those two flags, `--host 0.0.0.0` and `--no-open`, appear in no other install command, which is worth knowing before you copy that line onto a machine that already runs something on the port. The `19001` in `.env.example` is a host-mapped port for the development compose file, not a port the binary advertises.

## A persona bundles a prompt, a tool allowlist and a budget

The unit of configuration is the persona, and it carries four things at once: its own system prompt, its own tool allowlist, its own budget, and an executor type that decides how it runs. That combination is what keeps two agents inside one process from leaking tools to each other, and it is why the memory subsystem can be tuned per persona rather than globally.

Three extension points sit on top. Models route by priority across OpenAI, Anthropic, Gemini and any OpenAI-compatible endpoint, using keys you supply. Tools arrive through built-ins, MCP servers pointed at by `ARKLOOP_MCP_CONFIG_FILE`, and ClawHub skills. Runs are not only interactive, since sub-agent spawning and scheduled jobs are built in.

The channel layer puts that same pipeline behind Telegram, Discord, QQ, Feishu and WeChat bots, including scheduled heartbeat runs that fire with nobody watching. Memory has three positions rather than one: a plain-text notebook by default, Nowledge as an optional semantic layer, or the subsystem switched off entirely. The names are given without a description of the retrieval path behind Nowledge, so a plan that depends on semantic recall has to be built from the source.

## Apache 2.0 with a clause that forbids operating it as a service

The licence is a modified Apache License 2.0, named the Arkloop License, and the two modifications matter more than the base text. The first is a multi-tenant restriction: the source code may not be used to operate a multi-tenant SaaS without written authorization. The second is brand protection, requiring that the logo and copyright information in the frontend components not be removed or modified. The repository's licence field resolves to NOASSERTION rather than to Apache-2.0, which is why automated tooling will not classify it as a standard permissive licence.

The practical consequences for an evaluating team are plain. Self-hosting a fork for one organisation sits inside the terms. Packaging it as a hosted multi-tenant product needs a signature from the author, and shipping a white-labelled fork means leaving the logo where it is, which is a product decision as much as a legal one. Vulnerability reports go by email to a single address rather than a public issue, with the disclosure policy in `SECURITY.md`. None of this is legal advice, and a real deployment question deserves a full read of `LICENSE` and `NOTICE` rather than a summary of two clauses.

## No changelog, a pinned package manager, and subsystems named in one line

A few repository details are worth checking before you depend on them. Releases are numbered like `v26.5.21.2`, and the three most recent, `v26.5.19.2`, `v26.5.21.1` and `v26.5.21.2`, all landed in May 2026, with the last push to the default branch on 2026-08-27. Nothing explains what the scheme encodes, and there is no changelog at the top level to settle it, so a reader cannot tell from the repository whether a given number carries a breaking change.

Development needs `pnpm`, with `pnpm@10.29.3` pinned as the package manager. The root `package.json` is private and carries a `guard:no-org` script plus a build allowlist limited to `esbuild` and `electron`, with `electron-winstaller` and `sharp` marked as ignored. Local CI is one command:

```bash
pnpm install
cd src/apps/desktop && pnpm dev        # Desktop app (Electron + embedded runtime)

# Headless, from source:
cd src/apps/web && pnpm build
go run ./src/services/cli/cmd/ark web  # Serves the web UI and local API

bin/ci-local quick                     # Local CI
```

Then the honest limit. Several named subsystems, ClawHub skills among them, arrive as a single line with no link to their own documentation, while project space goes to a sponsor list and a request for stars. Arkloop rewards a reader who plans to modify it rather than one who installs it and leaves.

## Conclusion

Adopt Arkloop if you want agent infrastructure on your own machine, with model keys under your control and a runtime you can read in one process, and you accept that multi-tenant hosting and white-labelling are closed off by the licence. Do not adopt it if you need the container path, a changelog that tells you which release broke what, or documented behaviour for the Nowledge semantic memory layer. Verify three things before the first install: read LICENSE for the multi-tenant clause and the logo requirement, replace both placeholder secrets in `.env.example`, and confirm that a 2592000-second refresh token is acceptable for a runtime holding your provider credentials.

## FAQ

### Does Arkloop need Docker or a server to run?

No. The whole backend is one embedded Go process over a local SQLite database that auto-migrates on first start, with no Postgres, Redis or message queue. The desktop app bundles the full runtime, so it opens and runs without Docker or configuration.

### Which model providers can Arkloop route to?

OpenAI, Anthropic, Gemini and any OpenAI-compatible API, with priority-based routing and your own API keys. Secrets are stored with AES-256-GCM under an encryption key you generate, not one the project ships.

### Can I run Arkloop as a multi-tenant hosted service?

Not without written authorization. The Arkloop License, a modified Apache License 2.0, states that the source code may not be used to operate a multi-tenant SaaS without permission, and it also requires leaving the logo and copyright information in the frontend components intact.

### How does Arkloop store memory between conversations?

Memory is a plain-text notebook by default, with an optional Nowledge semantic memory layer, and the subsystem can be turned off entirely. Individual personas also carry their own budgets and tool allowlists.

### Can I reach the same Arkloop runtime without the desktop app?

Yes. The desktop app can install the command-line tool on first launch, and Homebrew and AUR both package it, after which the same runtime serves the web UI and local API headlessly. A headless Linux box can be set up with a single command that detects the architecture and starts the server without opening a browser.

## Sources

- [Issues](https://github.com/qqqqqf-q/Arkloop/issues)
- [Project website](https://arkloop.io)
- [qqqqqf-q/Arkloop on GitHub](https://github.com/qqqqqf-q/Arkloop)
- [README](https://github.com/qqqqqf-q/Arkloop/blob/main/README.md)
- [Releases](https://github.com/qqqqqf-q/Arkloop/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/qqqqqf-q-arkloop
