Repository navigation
Coding Agents
ok-fine works with Claude Code, OpenAI Codex CLI, Gemini CLI, pi, and oh-my-pi (omp) on existing codebases
without changing a single file in them. There is no AGENTS.md, CLAUDE.md, GEMINI.md, .mcp.json, or
settings file to commit: knowledge and the repository-to-project binding both live in ok-fine. Each developer
installs one agent package and configures the ok-fine MCP server once per harness.
For non-coding chat users, desktop harnesses, or organization-wide rollout without git, see Organization rollout.
The agent package is built from agents/ and published to
ferrule-io/ok-fine-agents whenever a release changes it. It contains:
- three Agent Skills:
ok-fine(find the project, recall before work, record after),ok-fine-onboard(bind a repository and bootstrap knowledge, or interview a non-coding team to create and seed its project; see Organization rollout), andok-fine-review(lint, staleness, drift, verification); - a hook for Claude Code, Codex, and Gemini CLI and an extension for pi and omp that tell the agent which git
repository it is in and to look up its ok-fine project before planning or editing; the full reminder is injected
at session start, then a one-line reminder on each prompt until the session has called an ok-fine lookup tool
(
list_projects,search_concepts,read_concept,get_index,orient). Hooks run on SessionStart plus UserPromptSubmit (Claude Code, Codex) / BeforeAgent (Gemini CLI), and the pi/omp extension runs on each prompt (before_agent_start). They run locally and never call ok-fine, and the per-prompt line stops once the transcript/session shows an ok-fine lookup call whose tool name is bare or containsok-fine/ok_fine(so name the MCP serverok-fine).
| Stage | Who / when | Mechanism |
|---|---|---|
| 1. Org setup | Once per org | Deploy ok-fine and configure the identity provider (below). Single developer: skip and run ok-fine locally over stdio (below). |
| 2. Developer setup | Once per developer per harness | Install the package, add a user-scope MCP server named ok-fine, and log in with the harness's OAuth flow (HTTP only). |
| 3. Repository onboarding | Once per codebase, by anyone with okf:write
|
Ask the agent to "onboard this repository to ok-fine". The ok-fine-onboard skill creates or picks the project, adds the git remote to the overview's repositories, and bootstraps up to 30 concepts, each with sources[].commit and a stale_after 180 days out. The codebase is untouched. |
| 4. Every session | Automatic | The hook/extension tells the agent the repository URL and to call list_projects then search_concepts before planning or editing, repeating a one-line reminder each prompt until it does; server instructions and the ok-fine skill drive capture of durable knowledge after. On recall the agent checks each concept's code sources for drift since sources[].commit (treating a commit that is not an ancestor of HEAD as drifted, since <commit>..HEAD alone would miss unmerged branches); a stale or drifted concept is re-checked against the code and, without asking the user, corrected if needed, refreshed (commit → HEAD, stale_after + 180 days), and agent-verified. Work on unmerged branches is recorded as a proposal (proposal.ref, trust tier proposed) at the concept's usual id; proposals met during recall are resolved in place (landed → current truth, abandoned → deprecated) (see Proposals below). |
| 5. Maintenance | On demand | Ask the agent to "review ok-fine knowledge". The ok-fine-review skill runs lint, finds stale, unverified, drifted, and stale_after-less concepts, resolves landed and abandoned proposals, and refreshes and agent-verifies concepts without a human gate. Other deprecations and deletions wait for confirmation; human verification is an optional correction step recorded only on explicit confirmation. |
A project is bound to codebases through the repositories list in its overview frontmatter:
type: Project
title: Shop
repositories:
- git@github.com:acme/shop.gitlist_projects (and GET /api/v1/projects?repository=) normalizes remotes before comparing: scheme, userinfo,
port, and a trailing .git are dropped and the result is lowercased, so git@github.com:Acme/Shop.git,
https://github.com/acme/shop, and ssh://git@github.com:22/acme/shop all match github.com/acme/shop. Local
paths are rejected with bad_request. One repository may be bound to several projects (and one project to
several repositories) for monorepo splits and multi-repo products.
- Audience
<PUBLIC_BASE_URL>/mcp, JWT access tokens. Agent tokens need scopesokf:read okf:write;okf:adminis reserved for operators (e.g. project deletion, archive import, and manual sync). - The
issparameter in authorization responses (RFC 9207); Gemini CLI rejects responses without it. - Dynamic client registration or client ID metadata documents, or one public client with loopback redirect URIs that developers pass as the client ID below.
Without a shared server, each harness starts ok-fine itself from npm
(Running locally); knowledge lives in ~/.ok-fine.
Requires Node.js 24+ and git.
| Harness | Add server |
|---|---|
| Claude Code | claude mcp add --scope user ok-fine -- npx -y @ferrule-io/ok-fine |
| Codex CLI | codex mcp add ok-fine -- npx -y @ferrule-io/ok-fine |
| Gemini CLI |
~/.gemini/settings.json: {"mcpServers":{"ok-fine":{"command":"npx","args":["-y","@ferrule-io/ok-fine"]}}}
|
| pi |
~/.pi/agent/mcp.json: {"mcpServers":{"ok-fine":{"command":"npx","args":["-y","@ferrule-io/ok-fine"],"exposure":"direct"}}}
|
| omp |
~/.omp/agent/mcp.json: {"mcpServers":{"ok-fine":{"type":"stdio","command":"npx","args":["-y","@ferrule-io/ok-fine"]}}}
|
- Install the agent package as in the table below; there is no login step.
- Flags go after the package name, e.g.
npx -y @ferrule-io/ok-fine --remote git@github.com:acme/knowledge.git. Gemini CLI usessettings.jsonbecausegemini mcp addwould parse-yitself. - Any number of agent sessions can use this stdio setup at the same time on the same data directory. The first session hosts the knowledge base and additional sessions connect to it via an owner-only local socket (
DATA_DIR/ok-fine.sock), with automatic failover if the host exits (see Running locally).
Replace https://okf.example.com with your PUBLIC_BASE_URL.
| Harness | Install package | Add server | Log in |
|---|---|---|---|
| Claude Code |
claude plugin marketplace add ferrule-io/ok-fine-agents then claude plugin install ok-fine@ok-fine
|
claude mcp add --transport http --scope user ok-fine https://okf.example.com/mcp (pre-registered client: add --client-id <id> --callback-port <port>) |
/mcp |
| Codex CLI |
codex plugin marketplace add ferrule-io/ok-fine-agents, install ok-fine from /plugins, trust its hook in /hooks
|
codex mcp add ok-fine --url https://okf.example.com/mcp (pre-registered: --oauth-client-id <id>) |
codex mcp login ok-fine |
| Gemini CLI | gemini extensions install https://github.com/ferrule-io/ok-fine-agents --auto-update |
gemini mcp add -s user -t http ok-fine https://okf.example.com/mcp (pre-registered: oauth.clientId in ~/.gemini/settings.json) |
/mcp auth ok-fine |
| pi | pi install git:github.com/ferrule-io/ok-fine-agents |
~/.pi/agent/mcp.json: {"mcpServers":{"ok-fine":{"url":"https://okf.example.com/mcp","exposure":"direct"}}} (pre-registered: oauth.clientId/callbackPort) |
pi mcp login ok-fine |
| omp |
omp plugin marketplace add ferrule-io/ok-fine-agents then omp plugin install ok-fine@ok-fine
|
~/.omp/agent/mcp.json: {"mcpServers":{"ok-fine":{"type":"http","url":"https://okf.example.com/mcp"}}}
|
/mcp reauth ok-fine |
Headless use without OAuth: mint a token and pass it as a static header — Claude Code
--header "Authorization: Bearer ${OKF_TOKEN}", Codex --bearer-token-env-var OKF_TOKEN, pi/omp
"headers": {"Authorization": "Bearer ${OKF_TOKEN}"}.
Say "onboard this repository to ok-fine" once per codebase, then work normally: the agent recalls relevant knowledge before planning or editing and records durable decisions, conventions, and runbooks afterwards. Say "review ok-fine knowledge" to audit and refresh it. Nothing is ever written into the codebase.
Knowledge about work on an unmerged branch or PR is recorded as a proposal: a new concept at the id its type would get (usually decisions/<slug>, type: Decision, status: draft), never over an existing concept, with the extension frontmatter key proposal: { ref: <URI> }. Current-state concepts are never edited for unmerged work. The body captures the design, alternatives, and bundle-absolute links to the current-state concepts it would change.
-
Trust tier: the server derives trust tier
proposedfrom theproposalkey, ahead of anyverifiedentries;search_conceptsfilters on it withtrustTier: "proposed". Removing the key restores the tier derived from verifications. - Recall ordering: proposals are not current truth; they rank after current (fresh and stale/drifted) concepts and before deprecated ones. They are exempt from drift refresh while the branch is unmerged.
-
Resolving: agents resolve every proposal they encounter during recall, without asking the user. A proposal has landed once what it describes is grounded in the mainline (the branch the team integrates into, e.g. the remote's default branch): its source commits are ancestors of the mainline, or the code it describes is present there.
refis any URI (pull/merge request, branch, ticket, …) and only a hint that the agent may interpret with whatever tools its environment offers.-
Landed: the same concept is rewritten as current truth:
proposalkey dropped,status: stable, body describing what landed, sources at the mainline commit (not a feature branch's HEAD), then agent-verified; linked current-state concepts are refreshed against that commit. If another current concept already records the same decision, the proposal is deprecated with a successor link instead. -
Abandoned (nothing landed and the evidence shows the work was dropped): set
status: deprecated, keeping theproposalkey, with anAbandoned:line giving the evidence. - Otherwise: leave the proposal as-is.
-
Landed: the same concept is rewritten as current truth:
-
Legacy
proposals/concepts: at startup, after a sync that pulls changes, and on archive import, the server moves eachproposals/<path>concept carryingproposaltodecisions/<path>(ordecisions/<path>-proposal,-proposal-2, … when taken), byte for byte, logging aMoveentry; inbound links are not rewritten and concepts without the key stay.
Generated from wiki/ in ferrule-io/ok-fine on every release. Edit pages there; changes made in the wiki UI are overwritten.