OpenLore
by aakarim
README.md
<div align="center">
# π OpenLore
[](https://github.com/aakarim/OpenLore/releases/latest)
[](https://pkg.go.dev/github.com/aakarim/go-openlore)
<a href="https://trendshift.io/repositories/85262?utm_source=trendshift-badge&utm_medium=badge&utm_campaign=badge-trendshift-85262" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/85262/daily?language=Go" alt="aakarim%2FOpenLore | Trendshift" width="250" height="55"/></a>
Sponsored by <a href="https://oiya.ai/?utm_source=github&utm_medium=referral&utm_campaign=openlore&utm_content=sponsor_logo"><img src="assets/oiya-logo.svg" alt="Oiya" height="24" align="absmiddle"></a>
**Give every AI agent on your team the same up-to-date knowledge.**
</div>
Point OpenLore at a folder of Markdown and every agent on your team reads the same files, whether it's Claude Code, Codex, Cursor or a CI job. Agents use the tools they already know, like `cat`, `grep` and `find`. You decide who can see and change what.
<p align="center">
<a href="https://render.com/deploy?repo=https://github.com/aakarim/OpenLore"><img src="https://render.com/images/deploy-to-render-button.svg" alt="Deploy to Render"></a>
<br>
<sub>One-click hosted server. See <a href="docs/how-to/deploy/render.md">Deploy OpenLore to Render</a>.</sub>
</p>
<p align="center">
<img src="assets/openlore-how-it-works.svg" alt="Claude Code, Codex and a CI job connect to one OpenLore server, which checks each identity's access and serves the same folder of Markdown" width="820">
</p>
## Quick start
Install and serve a folder:
```shell
brew install --cask aakarim/tap/lore
openlore ./docs
```
SSH runs on port `2222`. The web view and MCP share port `8080`. The contents of `./docs` appear at `/`.
Connect an agent:
```shell
# Claude Code
claude mcp add --transport http openlore http://localhost:8080/mcp
# Codex
codex mcp add openlore --url http://localhost:8080/mcp
# Anything with a shell
ssh -p 2222 localhost "grep -r 'retry' /"
```
Tell your agents when to use it:
```shell
ssh -p 2222 localhost agents >> AGENTS.md
```
Or let your agent do the whole setup:
```shell
ssh openlore.sh teach | claude
```
Not on Homebrew? See the [Quickstart](docs/start/quickstart.md#install) for Linux and Windows.
## Why not just keep Markdown in your repo?
For one agent in one repository, do that.
OpenLore is for when several agents, repositories or people need the same knowledge, and you need to say who can read, write or publish what. Update a file once and every agent sees the new version on its next read.
There's no vector database, ingestion pipeline or SDK. Your knowledge stays as ordinary Markdown.
## Guides
- [What is OpenLore](docs/introduction.md)
- [Claude Code](docs/start/agents/start-claude-code.md)
- [Codex](/docs/start/agents/codex.md)
- [Cursor](/docs/start/agents/cursor.md)
- [OpenCode](/docs/start/agents/opencode.md)
- [Meta Muse](/docs/start/agents/meta-muse.md)
- [OpenAI dots](/docs/start/agents/openai-dots.md)
- [Grok Bot](/docs/start/agents/grok-bot.md)
- [Claude Duet](/docs/start/agents/claude-duet.md)
- [Any agent over SSH](docs/start/agents/start-ssh.md)
- [Let an agent publish into an inbox](docs/how-to/publish-to-inbox.md)
- [Deploy to Render](docs/how-to/deploy/render.md)
- [Prune a knowledge repository from its analytics](docs/recipes/knowledge-cleanup.md)
- [Build an LLM wiki on OpenLore](docs/recipes/llm-wiki.md)
- [Share a coding style guide with every agent](docs/recipes/coding-style-guide.md)
- [All documentation](https://openlore.sh/docs/)
## Features
- **Agent-native retrieval** β Agents use the shell tools and composition
patterns they already understand instead of learning a bespoke retrieval API.
- **One knowledge surface, multiple transports** β Serve the same virtual
filesystem over SSH, SFTP/SSHFS (including direct VS Code browsing and
editing), MCP, and a human-friendly web view.
- **Live, governed knowledge** β Keep content read-only, allow scoped publishing,
or enable full writes per docset. Writes are atomic, conflict-aware and
validated before they commit.
- **Identity-scoped views** β Give each person or agent only the docsets it
needs, with role-based `ro`, `publish`, and `rw` grants, path aliases, and
private home directories.
- **Safe by construction** β The shell is an in-memory Go interpreter, not a
real operating-system shell. There is no shell escape, arbitrary process
execution, or ambient network access in a normal session.
- **Portable knowledge bundles** β Embed docs into a self-contained binary,
build cross-platform bundles with the GitHub Action, or package them as a
desktop MCP extension.
- **Structured knowledge without a new query language** β Inspect frontmatter
as NDJSON with `lore meta`, query it with `jq`, and validate Google's
[Open Knowledge Format (OKF)](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
bundles and Agent Skills close to the write path.
- **Extensible policy and processing** β Plugins can add validation, grants,
read/write middleware, metadata, and post-commit processing while preserving
the same filesystem interface.
## Use Cases
- **Continuous Learning repository** - store sessions and learnings in one shared server. Add metrics so you can optimise. Allow agents to share learnings with each other while maintaining user isolation.
- **Team Artifact Repository** - share markdown, HTML, JSON, Excel etc. documents you've created while maintaining access controls. Much more natural than git, more agent-native than Confluence/Notion.
- **Documentation for coding agents** β Put internal API docs, runbooks, product
context, and architecture notes behind a familiar, greppable interface.
- **A shared live memory for teams of agents** β Give agents separate or shared
docsets so they can publish findings, hand off work, and accumulate durable
context across sessions.
- **Public docs site** - add any files to your public docset, enable public access and it will be shown to any agent that stumbles across your site. Improves AEO/GEO with no need to edit your existing docs.
- **Skills sharing** β Publish Agent Skills into shared collections so every
authorised agent can discover and use the same governed procedures.
- **Agent Plugins repository** β Version-pin [Agent Plugins](https://agent-plugins.org) repos from GitHub and serve them to your team's agents. Skills packaged in the open standard stay current automatically.
- **Governed knowledge contribution** β Let contributors publish into inboxes
while reserving existing documents for maintainers and preventing accidental
overwrites.
- **Artifact repository** β Store and expose reports, logs, screenshots, and
generated files through the browser or SSH without building a custom artifact
viewer or granting access to the agent's machine.
- **Identity-specific workspaces** β Mount a private home for each agent plus
shared team knowledge, all through one server and one authorisation model.
- **Portable customer or project knowledge** β Ship a versioned executable with
the relevant docs embedded, or distribute the same knowledge as an MCPB
desktop extension.
- **Validated knowledge catalogues** β Enforce frontmatter and bundle conventions,
inspect metadata cheaply, and stop malformed knowledge at admission time.
## How It Works
OpenLore is built on [Wish](https://github.com/charmbracelet/wish) for SSH
transport. A connection is handled entirely against a virtual filesystem:
1. **Authenticate** β connect keylessly or resolve an SSH key, certificate,
passkey, or OAuth login to an identity.
2. **Compose a view** β mount only the docsets and paths granted to that identity.
3. **Explore** β run shell commands implemented as pure Go functions over that
view, or use the equivalent MCP `shell` tool.
4. **Contribute safely** β if writing is enabled, authorise and validate a
whole-file change before committing it atomically.
OAuth clients use delegated identities, so durable write provenance distinguishes
direct work by `adil` from work performed as `adil/claude@claude.ai`. Delegates
can inherit no more authority than their principal and can be narrowed by
docset and capability deny lists. CIMD clients can additionally authenticate
with vendor-hosted metadata and `private_key_jwt`; see
[Authenticated OAuth Clients](docs/reference/authenticated-oauth-clients.md).
The normal shell cannot invoke `bash`, `exec`, `curl`, or arbitrary host
processes. Embedded documentation is always read-only. Explicitly trusted
identities can be granted narrowly scoped asynchronous processing through the
`spawn` capability.
## Governed Writing
OpenLore is read-only by default. Writable deployments keep a single,
policy-controlled write path for redirects, append, `tee`, `patch`, `sed -i`,
file moves, publishing, and trusted external jobs.
```shell
echo "# Research" | publish /backend/findings.md
cat change.diff | patch /backend/api.md
sed -i 's/old/new/g' /backend/runbook.md
```
Writes are whole-object atomic swaps. Compare-and-swap protection rejects stale
edits by default, docset grants constrain the target, and plugins can validate
or defer a write before it commits.
See [Writing and publishing](docs/concepts/writing.md) for user-facing setup and
[Write system internals](docs/reference/write-system.md) for the implementation model.
## Installation
See the [Quickstart](docs/start/quickstart.md#install) for Homebrew, Linux and
Windows releases, and which installations include the dashboard. To build
OpenLore yourself, see [Building from source](docs/reference/building-from-source.md).
### Embed docs in a binary
Place documentation in `assets/lore/` and build. The resulting binary contains
the docs and serves them read-only at `/docs` when run with no directory
argument:
```shell
make dashboard-build # optional: include the web UI
go build -o my-docs ./cmd/openlore
```
### Build with the GitHub Action
Produce cross-platform binaries with your docs embedded:
```yaml
- uses: aakarim/openlore@v1
with:
docs-dir: ./docs
config: ./openlore.yml
```
See [Ways to use OpenLore](docs/how-to/usage.md) for direct VS Code editing, MCP stdio,
MCPB desktop packaging, SSHFS, and Go library usage.
### Create a customised deployment
Use the bundled `setup` skill to create `<team>-lore`, a small customer-owned
repository containing `openlore.yml`, a thin `Containerfile` pinned to an
official OpenLore release, and deployment artifacts. It builds a working local
server and verifies HTTP, MCP, authenticated SSH, writes, and persistence before
deployment:
```shell
ssh openlore.sh setup | amp
```
The generated repository keeps initial `lore.json` policy and SSH-visible files
under gitignored `.local/`. The first deployment initialises an empty persistent
volume from that state. Root `openlore.yml` remains the Git/IaC authority and is
deployed separately to `/var/lib/openlore/config/openlore.yml`; it is not baked
into the image. Later `lore.json` and filesystem edits on the server are
authoritative and are never overwritten by image updates.
Additional instruction commands support the full lifecycle:
- `onboarding` adds initial identities, roles, homes, and folders locally;
- `deploy` selects Fly.io, Railway, AWS, Google Cloud, Azure, DigitalOcean, or a
custom deployment and verifies a shared persistence/networking contract;
- `upgrade` prepares only the pinned base-image version change so existing CD
can deploy it.
Provider deployments require HTTPS/MCP, authenticated OpenLore SSH,
administrative shell access, and a persistent `/var/lib/openlore` volume. Where
the provider supports it, deployment configures public port 22 to forward to
OpenLore port 2222. Otherwise it reports the assigned port and recommends an
external TCP forwarding system.
The published container contains only OpenLore. It deliberately contains no
onboarding policy or server configuration. Before the service starts, the
deployment must put `openlore.yml` and `lore.json` in the persistent config
directory and run:
```shell
./out --config /var/lib/openlore/config/openlore.yml
```
This keeps configuration independently deployable: a simple deployment can
copy `openlore.yml` onto the volume, while Kubernetes can project the same file
from a ConfigMap. Use the `deploy` skill for Fly.io, Railway, AWS, Google Cloud,
Azure, DigitalOcean, or custom infrastructure. The repository's Railpack and
Fly files provide the image, persistent-volume, and port wiring; they do not
seed or mutate configuration at process startup.
For a quick hosted server without a customised repository, use the
[Deploy to Render](docs/how-to/deploy/render.md) button. Unlike the Railpack and Fly files,
its start script writes a starter `openlore.yml` and `lore.json` to an empty
disk on first boot. Render serves HTTPS, MCP and the web view only; it has no
public TCP ingress for OpenLore SSH.
Railway assigns its SSH TCP proxy a public hostname and port. Standard SSH port
22 requires an external raw TCP load balancer. Fly.io can map public port 22 to
OpenLore's internal port 2222 with a dedicated address. Raw SSH has no hostname
or SNI routing, so one listener cannot route multiple domains on port 22.
The container workflow publishes `latest` from `main`; releases also publish
`VERSION`, `vVERSION`, major, and minor image tags.
## Documentation
The same pages, in the same groups, are published at
[openlore.sh/docs](https://openlore.sh/docs/).
### Introduction
| Page | Contents |
|---|---|
| [What is OpenLore](docs/introduction.md) | Serve, connect, scope, govern and observe in one page |
| [Changelog](docs/changelog.md) | Current version, release notes, compatibility notes, and versioned docs |
### Start
| Page | Contents |
|---|---|
| [Quickstart](docs/start/quickstart.md) | Install OpenLore, serve a folder, and connect an agent |
| [Claude Code](docs/start/agents/start-claude-code.md) | Connect Claude Code over MCP and scope what it sees |
| [Codex](docs/start/agents/codex.md) | Connect Codex over MCP |
| [Cursor](docs/start/agents/cursor.md) | Connect Cursor over MCP |
| [OpenCode](docs/start/agents/opencode.md) | Connect OpenCode over MCP |
| [Meta Muse](docs/start/agents/meta-muse.md) | Connect Meta Muse over MCP |
| [OpenAI dots](docs/start/agents/openai-dots.md) | Connect OpenAI dots over MCP |
| [Grok Bot](docs/start/agents/grok-bot.md) | Connect Grok Bot over MCP |
| [Claude Duet](docs/start/agents/claude-duet.md) | Connect Claude Duet over MCP |
| [Any agent over SSH](docs/start/agents/start-ssh.md) | Connect a coding agent or CI job over SSH and give it an identity |
### Concepts
How OpenLore works: docsets, transports, identity, writes, rules, and observation.
| Page | Contents |
|---|---|
| [Docsets](docs/concepts/docsets.md) | What a docset is, why access is organised around them, and how nesting, grants, aliases and fail-closed validation work |
| [Transports](docs/concepts/transports.md) | How SSH, SFTP, MCP, the JSON API and the web share one filesystem, the MCP tools, command results, sessions, and instruction commands |
| [Auth](docs/concepts/auth.md) | Authentication posture, how SSH keys, certificates, passkeys, OAuth tokens and inbox credentials resolve to an identity, roles, docsets, aliases, homes, and workload identity federation |
| [Writing and publishing](docs/concepts/writing.md) | Write modes, inboxes, conflict handling, what a successful write does and does not check, and jobs |
| [Folder rules](docs/concepts/folder-rules.md) | `.lore/config.yaml` and `lore.json` rules, layering, permissions, rejection messages, and growth limits |
| [Plugins and formats](docs/concepts/plugins.md) | Provider interfaces, Open Knowledge Format validation, `lore validate`, `lore meta`, and the Agent Skills plugin |
| [Dashboard and metrics](docs/concepts/dashboard.md) | Dashboard authentication, facts versus activity, and the file viewer |
### How to
Task walkthroughs.
| Page | Contents |
|---|---|
| [Ways to use OpenLore](docs/how-to/usage.md) | Set up SSH, MCP over HTTP and stdio, the web view, SSHFS, embedded binaries, the GitHub Action, MCPB, and library usage |
| [Configure the server](docs/how-to/configure-the-server.md) | Create `openlore.yml`, precedence over embedded config and flags, HTTPS, analytics, and debug logging |
| [Production checklist](docs/how-to/production-checklist.md) | What a shared server needs before cloud agents can reach it: a host with HTTPS out of the box, a pinned image on a volume, a public origin, a token on `/mcp`, passkeys |
| [Let an agent publish into an inbox](docs/how-to/publish-to-inbox.md) | Accept contributions from an agent without letting it edit anything else |
| [Browse and edit from an editor](docs/how-to/editors.md) | Direct VS Code and SFTP editor setup without a local project mirror |
| [Run headlong / shellm](docs/how-to/shellm.md) | Use OpenLore over SSH from headlong's shellm engine, including its housekeeping skill |
| [Build from source](docs/reference/building-from-source.md) | Build the web UI and binary yourself, or build without the web UI |
| [Deploy OpenLore to Render](docs/how-to/deploy/render.md) | One-click Render deployment, first passkey sign-in, upgrades, and custom domains |
### Reference
Lookup material: commands, keys, endpoints, interfaces, and internals.
| Page | Contents |
|---|---|
| [Command reference](docs/reference/commands.md) | Complete shell, introspection, publishing, syntax, CLI command, and flag reference |
| [openlore.yml reference](docs/reference/openlore-yml.md) | Generated reference for every key `openlore.yml` accepts |
| [Rules standard library](docs/reference/rules-stdlib.md) | Generated reference for compiled-in rule members and their parameters |
| [HTTP inbox API](docs/reference/inbox.md) | `POST /inbox/{docset}` with bearer or HMAC credentials, and the token endpoints |
| [OAuth clients](docs/reference/authenticated-oauth-clients.md) | CIMD client identity, `private_key_jwt`, mTLS corroboration, and signing-key rotation |
| [Write system internals](docs/reference/write-system.md) | Filesystem layering, write seam, admission middleware, and async jobs |
| [Build the dashboard](docs/reference/dashboard-build.md) | Frontend build and backend-only Go builds |
| [Security evaluation](SECURITY.md) | Threat model and security properties |
## Security
- Commands run in a pure-Go interpreter, not through `os/exec`.
- The virtual filesystem cleans paths and enforces docset boundaries.
- Allowed file patterns and ignored directories keep secrets out of the view.
- RBAC controls reads, publishing, writes, approvals, and trusted capabilities.
- The web endpoint can publish the SSH host key over TLS to avoid blind trust on
first use; SSH user and host certificates are also supported.
See [SECURITY.md](SECURITY.md) for the full security evaluation.
## License
[Apache License 2.0](LICENSE) β Copyright Β© 2026 Adil Karim
OpenLore bundles third-party open-source components. Their licences and required
notices are listed in
[assets/legal/THIRD_PARTY_NOTICES.md](assets/legal/THIRD_PARTY_NOTICES.md), with
full licence texts in [assets/legal/licenses/](assets/legal/licenses/). These are
embedded in the binary and served by the running service at `/legal`.
This server cannot be deployed
Maintenance
ActivityActive
ResponsivenessWithin a week