Gini Agent: a local-first personal agent runtime with memory and approval-gated tools
The agent that remembers and learns.
At a glance
- What is it?
- Gini Agent is a TypeScript monorepo from Open-Curiosity that puts a single Bun runtime at the centre of a personal agent: chat, runs, memory, skills and approvals all live in one gateway that every client talks to. This review covers what the documentation actually commits to, how to install it, and where the design leaves you on your own.
- Who is it for?
- Adopt Gini Agent if you want a personal agent whose state lives on a machine you control and you are willing to run a Bun process plus a Next.js control plane to get it. Skip it if you need a managed service, a stable plugin API, or a project with a long release history, since v0.3.0 is the third tagged release and the last push was on 2026-07-18.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 75 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Gini Agent is aimed at: an agent that keeps state between conversations
Most agent tooling treats a conversation as the unit of work. You open a chat, the model calls tools, you close the tab, and the transcript is all that survives. Gini Agent takes the opposite position. The README states that the runtime, not the chat, is the system of record, and it lists what that record covers: conversations, runs, tasks, approvals, memory, skills, jobs, tools, traces, audit events and runtime health. That is a long list, and the length is the point. If you have ever rebuilt context by hand at the start of every session, the project is aimed at you.
The intended user is a single person running an agent on their own hardware, not a platform team. The repository ships a Dockerfile and a docker-compose.yml, but the quick start path is a shell installer that sets up a per-user runtime on macOS. The topics list includes local-first and personal-agent, and the default embeddings, reranking and speech-to-text run locally according to the README. That combination points at someone who wants the agent on a laptop or a home server rather than in a vendor's tenancy.
There is a second, less obvious audience: people who want the agent to act in a browser. The Dockerfile comment is explicit that the container runs a headed Chromium under Xvfb, and calls that choice deliberate because a real Chrome presents fewer automation signals than headless mode. Gini Agent is not only a chat surface with memory. It is built to drive a browser on your behalf and to hand that browser back to you when a sign-in wall appears.
One Bun process as the gateway, and clients that are not allowed to own state
The architecture summary in the README is one sentence: the runtime is the gateway, a single Bun process per instance owns state and performs work, and the Next.js web app, CLI, Expo mobile app, MCP surfaces and messaging bridges are clients of the same authenticated /api/* contract. The ASCII diagram in the README shows the gateway at the top with the Next.js BFF, CLI and other clients below it.
The split between the Next.js BFF and the gateway is worth reading carefully. The diagram annotates the BFF with "no browser token", which means the browser talks to the Next.js layer and the Next.js layer talks to the gateway. The CLI, by contrast, uses a bearer token. So there are two client classes with different credential handling, and the web UI never holds the gateway token itself. That is a sensible arrangement for a localhost service, though it also means the web app is not optional in the browser path; you cannot point a browser directly at the gateway API and expect the control plane to work.
State isolation is per instance. The README claims parallel instances with isolated state, ports and logs, and the Docker compose file sets GINI_INSTANCE to default and publishes two ports, 7777 for the web control plane and 7778 for the runtime gateway API. The gateway documentation is named as the place where ports and disk layout are specified, so the exact allocation scheme is not in the README itself. If you plan to run more than one instance, that document is the one to read before you start, because the README only asserts that isolation exists.
Installing Gini Agent and getting to a first run
The README gives a single install command. It fetches scripts/install.sh from the main branch and pipes it to bash, which means you are executing whatever is on main at that moment rather than a pinned release.
curl -fsSL https://raw.githubusercontent.com/Open-Curiosity/gini-agent/main/scripts/install.sh | bashOn macOS the README says the installer enables autostart through per-user LaunchAgents for the runtime and the webapp, waits for the webapp to come up, and opens the /setup page in your browser. The setup form offers the full provider catalog, and the providers document lists OpenAI, Anthropic, Bedrock, Azure, OpenRouter, DeepSeek, Codex and Local. If you would rather not run the installer, the repository is a Bun workspaces monorepo and package.json exposes the entry points directly.
bun run gini
bun run serverThe first command runs packages/runtime/src/cli.ts and the second runs packages/runtime/src/server.ts. There is also a smoke target, which is the one to reach for when something starts but does not behave.
bun run smokeFor a container deployment the compose file is the documented path. It builds from the repository root, publishes 7777 and 7778, and defaults GINI_PROVIDER to echo, which the compose comments describe as a deterministic stub.
docker compose up --build
docker compose logs -fWith echo selected you get a working runtime without any model credential, which is a reasonable way to confirm the control plane renders and the gateway answers before you wire up a provider. The compose comments also note that state persists in a named volume, so chats, sign-ins, memory and downloaded models survive restarts. When you are ready for a real model, the environment block shows OPENAI_API_KEY and ANTHROPIC_API_KEY commented out, and GINI_MODEL for overriding the model. You can also leave the provider at echo and configure it after boot at http://localhost:7777/setup.
Approval gates, secrets and why the agent can be unblocked from your phone
The most opinionated part of Gini Agent is how it asks for things. The README describes four inline controls: a secure card for keys, passwords, OTPs and payment fields; a browser handoff when a task hits a sign-in wall; a choice prompt when more than one path is reasonable; and a confirm-before-send step before the agent sends, replies, posts or buys on your behalf.
The secrets card is the one with a concrete claim attached. The README says a value typed into it flows straight to the gateway and never reaches the model, the transcript or the audit trail. That is a design commitment about a data path, and it is the kind of claim you should verify against docs/adr/browser-fill-secret.md and docs/adr/chat-credential-provisioning.md rather than take on faith, because it determines whether pasting an API key into an agent is acceptable in your setup.
The handoff control is what makes the mobile client more than a viewer. The README states that the same cards render on the web app and the iOS app off one wire protocol, and that they reach the phone off-LAN through a runtime tunnel. The remote access document lists tunnel modes with a per-provider guide for Gini Relay, Tailscale, ngrok and Cloudflare, and notes that these are the same pages the app opens inline. So the answer to "can I approve an agent action from my phone" is yes, but only after you have configured a tunnel, and the documentation treats tunnel confirmation as part of that setup.
Approval-gated file, terminal and code tools are listed in the feature summary. The README does not enumerate the individual tools or their permission granularity, so treat the approval system as documented in outline only until you read docs/conversation-runs.md.
Skill learning, memory and the human gate
Two documents carry the parts of the design that are hardest to get right. The memory document is described as covering retain, recall, embeddings, reranking, review and storage. The skill learning document is described as covering how Gini improves its own skills from task outcomes, with a two-tier reward, attribution, a daily review and a human gate.
That last phrase, the human gate, is the interesting one. A system that rewrites its own skills based on outcomes needs a mechanism to stop bad lessons from sticking, and the documentation names the gate as the mechanism. The README does not describe how a skill is represented on disk or what the two tiers of reward actually are, so anyone evaluating this feature should read docs/skill-learning.md directly. The skills/ directory at the repository root suggests skills are files rather than database rows, but the README does not say so and I am not going to assert it.
Memory runs local by default. The README states that local embeddings, reranking and voice-message speech-to-text are on by default, and the package.json trustedDependencies list includes onnxruntime-node, which is consistent with local inference rather than a hosted embedding API. The Dockerfile installs libgomp1 specifically for onnxruntime-node's OpenMP runtime, which is a small but telling detail: the container image is built to make local inference work, not to fall back to a remote service. If your machine cannot spare the cycles for local embedding, the README does not present a documented switch to a hosted alternative.
Where Gini Agent is the wrong tool
The honest limitation is maturity. The releases list shows v0.1.0 on 2026-05-22, v0.2.0 on 2026-06-03 and v0.3.0 on 2026-06-08. The last push to the repository was on 2026-07-18. Three tagged releases and a single package version of 0.3.0 in package.json is a young project, and the README's own roadmap document is described as listing shipped surfaces and what is planned, which implies parts of the design are not built yet.
The install path deserves scrutiny too. Piping a script from the main branch to bash gives you the current state of main, not a release artifact, and the README does not document a rollback or an uninstall procedure. The operations document is named as covering install, start, stop, smoke, diagnostics and cleanup, so a teardown path likely exists there, but the README does not present one. If your environment requires pinned, auditable installs, this is friction you will feel immediately.
The provider matrix is broad but the README does not state which providers are first-class. It distinguishes Codex OAuth, several API-key providers, Amazon Bedrock through the model-agnostic Converse API with AWS SigV4, and any OpenAI-compatible local server. That last category is the escape hatch for anyone whose preferred model is not on the list, but "OpenAI-compatible" is a loose guarantee, and the per-provider guides are where the real prerequisites live.
Finally, this is a single-user personal agent by design. The README talks about instances and isolation, not about multi-tenant access control, roles or shared workspaces. If you need several people acting on one agent with different permissions, the documented model does not describe that.
The alternative: OpenClaw, and what actually differs
The repository documents a migration path from openclaw in docs/migration-from-openclaw.md, which makes openclaw the obvious comparison. The existence of that document is itself the useful fact: Gini Agent expects some users to arrive with an existing openclaw install and provides an import path rather than asking them to start over.
The difference the README draws is about where state lives. Gini Agent's stated position is that the runtime is the system of record, and that chat is only an interaction surface among several. The architecture diagram reinforces this by placing the gateway above the Next.js BFF, the CLI and other clients, all of which authenticate against the same /api/* contract. A tool that treats the conversation as the primary artifact would put the transcript first and the runtime second. Gini Agent inverts that ordering, and the inversion is what makes the mobile client, the MCP surfaces and the messaging bridges peers rather than add-ons.
The second difference is the control vocabulary. The README frames secrets, sign-in handoff, choice prompts and confirm-before-send as purpose-built controls that render inline where the work is, backed by architecture decision records in docs/adr/. That is a specific claim about interaction design, not a general one about capability, and it is the part of the project most worth comparing against whatever you use today. If your current agent asks you to paste a token into chat or to go complete a step elsewhere, the contrast is real.
What the README does not do is compare feature sets, performance or reliability against openclaw. There is no benchmark table and no compatibility matrix in the repository documentation. The migration document is the only place where the two are discussed together, and it is written for people leaving, not for people shopping.
Licence, maintenance and what an upgrade costs you
Gini Agent is MIT licensed, and package.json marks the root package private with the same licence identifier. MIT is permissive: you can use, modify and redistribute the code, including in closed products, provided the copyright notice and permission notice are retained. The repository does not appear to ship a separate licence for the packages/ workspaces, so the root LICENSE is the one that governs. That is a description of the licence text, not legal advice, and if you are embedding this in a commercial product you should read LICENSE and any third-party notices yourself.
The dependency surface is worth counting before you commit. package.json lists onnxruntime-node, protobufjs, sharp and unrs-resolver under trustedDependencies, which means those packages run install scripts and are trusted to do so. The same file pins a patched dependency: [email protected] is patched through patches/[email protected]. A patched upstream package is a maintenance liability, because the patch has to be rebased when playwright-core moves. The Dockerfile pins oven/bun:1.3.14-debian and notes that the base is Debian 13 trixie, which is why the Chromium runtime libraries use the t64-suffixed package names. Those two pins, Bun and the patched playwright-core, are the things most likely to break an upgrade.
On cadence: the last push was on 2026-07-18, and the most recent tag, v0.3.0, dates from 2026-06-08. The releases document is described as covering versioning, CHANGELOG conventions and the release process, so the project has a stated process even if the tag history is short. There is no published upgrade guide in the README, and no documented rollback. Before upgrading across a minor version, read CHANGELOG.md and docs/releases.md and confirm whether the named state volume in docker-compose.yml needs a migration step.
Editorial conclusion
Adopt Gini Agent if you want a personal agent whose state lives on a machine you control and you are willing to run a Bun process plus a Next.js control plane to get it. Skip it if you need a managed service, a stable plugin API, or a project with a long release history, since v0.3.0 is the third tagged release and the last push was on 2026-07-18. Before committing, read docs/gateway.md for the disk layout and port assignments, and check docs/providers/README.md to confirm your model provider is covered.
Frequently asked questions
What does Gini stand for?
The repository does not expand the name into an acronym. The README presents it as a product name for the personal agent, and package.json uses gini-agent as the package name.
What are genie agents?
That term does not appear anywhere in the Gini Agent repository, so the documentation cannot answer it. Gini Agent is described in its README as a personal agent that remembers, improves and runs without forcing you to read a log line.
What does Gini mean in a decision tree?
Nothing in this repository connects the name to decision-tree Gini impurity. The README uses Gini purely as the project's name, and the topics list describes it as an agent runtime rather than a statistics or machine-learning library.
What does Gini mean in English?
The repository does not give a meaning or expansion for the word. The README only states that Gini Agent is a personal agent that remembers and learns.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/open-curiosity-gini-agent)