docs: rewrite README in a plainer, dev-oriented tone

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
bernatsampera
2026-07-24 02:03:29 +02:00
co-authored by Claude Opus 4.7
parent 63a38fb08e
commit 57a8cd0f3c
+56 -57
View File
@@ -1,65 +1,65 @@
# gcontext
**Your agent's state lives in a folder. It's served at a URL. Any runtime becomes your agent.**
gcontext stores an AI agent's state (instructions, service connections, secrets, knowledge, work in progress) in a plain directory and serves it over MCP from a local HTTP server. MCP clients like Claude Code, Codex, Cursor, or Claude Desktop connect to that server and work against the shared state.
Claude Code, Codex, Cursor, Claude Desktop: these are runtimes. They read, reason, and act, but they forget everything between sessions. gcontext is the part that persists: the context your agent has learned, the services it can operate, the secrets it can use, the multi-step work in progress. All of it in a plain directory you can version with git.
The point: runtimes forget everything between sessions. If the state lives in a folder instead, it persists, you can version it with git, and you can switch runtimes without losing anything. gcontext only manages that state. It has no chat loop, no LLM client, and no orchestration; the runtime you attach does the actual work.
gcontext is not a runtime. It has no chat loop, no LLM client, no orchestration engine. It serves your agent's state over MCP, and any MCP client that attaches becomes your agent.
## Install
```bash
uv tool install gcontext-ai # or: uv tool install git+https://github.com/bleak-ai/gcontext
gcontext init my-agent # scaffold the state folder
gcontext up my-agent # serve it at http://127.0.0.1:4242/mcp
uv tool install gcontext-ai
```
Connect a harness by pasting the URL, once, from any directory:
## Quickstart
```bash
gcontext init my-agent # create the state folder
gcontext up my-agent # serve it at http://127.0.0.1:4242/mcp
```
Then connect a client (once, from any directory):
```bash
claude mcp add --transport http my-agent http://127.0.0.1:4242/mcp
```
The server prints every harness as it attaches. `Ctrl+C` and every harness cleanly loses access. That's the whole model: a server running, and harnesses that connect to it.
`gcontext connect claude|desktop|codex|cursor` prints the exact steps per client. The server logs each client as it connects. Stopping the server (Ctrl+C) disconnects everything; there is no other cleanup.
## What's in the folder
## The folder
```
my-agent/
gcontext.yaml # identity: name, description, optional port
gcontext.yaml # name, description, optional port
instructions.md # standing instructions for whatever runtime attaches
secrets.env # secret VALUES, gitignored, never leave your machine
secrets.env # secret values, gitignored
connections/ # services the agent can operate
connections/ # services the agent can use
stripe/
connection.yaml # declares secret NAMEs and Python deps
index.md # how to use the API, patterns that work
connection.yaml # secret names + Python deps
index.md # API notes, usage patterns
modules/ # knowledge the agent accumulates
modules/ # accumulated knowledge
flows/ # multi-step work, tracked as files (see below)
archive/ # anything moved here is out of context, still readable
archive/ # excluded from scanning, still readable
```
Markdown is the context. YAML is the config. The folder is the agent.
Markdown holds the context, YAML holds the config. Edit any of it with a text editor; the server reads the files on demand, so changes apply immediately.
## The three ideas
Connected clients get six tools: `overview`, `read_context`, `write_context`, `run_script`, `list_connections`, `flows`.
### 1. Nothing reaches the agent invisibly
## Context ledger
The **context ledger** enumerates every pipe that inserts context into the agent, each marked `loaded`, `on demand`, `skipped`, or `UNCONTROLLED` (runtime-owned). See it anytime:
`gcontext context` lists every channel through which context reaches the agent, marked as `loaded` (pushed at start), `on demand` (agent pulls it via a visible tool call), `skipped` (closed by a launch flag), or `uncontrolled` (owned by the runtime, outside gcontext's view). gcontext only inserts context through the channels on that list. If you want to know what the agent is seeing, this is the answer.
```bash
gcontext context my-agent
```
## Secrets
If gcontext feeds something to the agent, it's on that list. No hidden injection, ever.
`connection.yaml` declares secret names; `secrets.env` holds the values. When the agent calls `run_script`, the values are injected as environment variables and scrubbed from the script's output. The agent can know that `STRIPE_API_KEY` exists and use it in a script, but never reads the value. `secrets.env` is gitignored by `init` and the `write_context` tool refuses to touch it.
### 2. Secrets: names visible, values never
`run_script` executes Python in a per-project venv with each connection's declared deps preinstalled (via uv).
The agent sees secret NAMEs only. Values live in `secrets.env`, get injected as environment variables when a script runs (`run_script` tool, deps preinstalled via uv), and are scrubbed from all output. This never changes.
## Flows
### 3. Flows: workflows as files, not engines
A flow declares which files each step needs and produces:
A flow is a YAML file describing multi-step work as file dependencies:
```yaml
steps:
@@ -69,41 +69,40 @@ steps:
instructions: Read the brief, write the draft.
```
Step status is computed purely from the filesystem, make-style: `blocked` (a need is missing), `ready` (needs exist, produces don't), `stale` (a need changed after the produces), `done`. A runtime completes a step by writing the declared files. There is no executor, no checkpointer, no stored run state: change an upstream file and downstream steps light up as stale. Progress is git-diffable because progress is files.
Step status is derived from the filesystem, like make targets:
- `blocked`: a needed file doesn't exist
- `ready`: needs exist, produces don't
- `stale`: a needed file was modified after the produced files
- `done`: everything exists and is up to date
There is no engine and no stored run state. A step is completed by writing the files it declares, whether that's done by an attached runtime, a script, or you in an editor. If an upstream file changes, downstream steps become stale on the next read. `gcontext flows` prints the board; attached clients get the same via the `flows()` tool, which includes step instructions only for steps that are currently actionable.
## Archiving
When old modules or connections start cluttering the context, move them:
```bash
gcontext flows my-agent # the board, per step
```
Attached runtimes get the same board via the `flows()` tool, with step instructions surfacing only when a step is actionable.
## Commands
| Command | What it does |
|---|---|
| `gcontext init <dir>` | Scaffold a new agent state folder |
| `gcontext up [dir]` | Serve the folder over MCP at a local URL |
| `gcontext status [dir]` | Server up? Who is connected? State overview |
| `gcontext connect [client]` | Attach instructions for claude, desktop, codex, cursor |
| `gcontext context [dir]` | The context ledger |
| `gcontext flows [dir]` | The flow boards |
| `gcontext chat [dir]` | A dedicated, fully controlled claude session |
The tools an attached runtime gets: `overview`, `read_context`, `write_context`, `run_script`, `list_connections`, `flows`.
## Housekeeping without magic
When accumulated state starts polluting context, move folders into `archive/`:
```
mv my-agent/modules/old-onboarding my-agent/archive/modules/
```
Archived items are never scanned into overviews or counts, stay readable by path, and every summary reports that they exist. The folder move is the entire mechanism. gcontext never archives, deletes, or reorganizes anything by itself.
Anything under `archive/` is skipped when scanning, but stays readable by path, and summaries mention what's archived so it doesn't silently vanish. That's the entire mechanism. gcontext never moves, archives, or deletes anything on its own.
## Commands
| Command | Description |
|---|---|
| `gcontext init <dir>` | Scaffold a new state folder |
| `gcontext up [dir]` | Serve the folder over MCP |
| `gcontext status [dir]` | Server state, connected clients, state overview |
| `gcontext connect [client]` | Connection steps for claude, desktop, codex, cursor |
| `gcontext context [dir]` | Print the context ledger |
| `gcontext flows [dir]` | Print the flow boards |
| `gcontext chat [dir]` | Launch a dedicated claude session against the folder |
## Scope
Local-first, by design. The server binds `127.0.0.1` with no auth: everything on your machine, nothing exposed. A remote/deployed story (same shape, a URL with a token) is planned but deliberately not in this release.
Local only. The server binds `127.0.0.1` without auth, so it is not reachable from outside your machine and should stay that way. A remote variant (same model, URL plus token) is planned but not part of this release.
## License