OpenLore serves a folder of Markdown over SSH, MCP and a web view, with grants instead of a retrieval API
A minimal, extensible, agent-native knowledge repository that keeps shared context current and inspectable
At a glance
- What is it?
- OpenLore is a Go server that exposes one virtual filesystem to agents over SSH on port 2222 and over MCP and a web view on port 8080, with role based ro, publish and rw grants. It deliberately has no vector database, no ingestion pipeline and no SDK, and its shell is an in-memory interpreter rather than a real operating system shell.
- Who is it for?
- Run OpenLore when several agents, repositories or people need one set of shared files with different levels of write access, and you want them to reach it with cat, grep and find rather than a new client library. Do not run it for the single agent in the single repository case, because the README's own advice there is to keep Markdown in the repo, and do not expect retrieval quality from a chunking pipeline since none exists.
- Can I use it commercially?
- Yes. Apache-2.0 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 received new commits within the last day.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The premise: the same Markdown, reached with the tools agents already have
OpenLore's argument starts with a refusal. It serves a folder of Markdown to agents, and the agents read it with the shell tools they already know, such as cat, grep and find, whether the client is Claude Code, Codex, Cursor or a CI job. The README is explicit that there is no vector database, no ingestion pipeline and no SDK, and that your knowledge stays as ordinary Markdown.
That constraint is the design. The retrieval model is the filesystem, which means an agent's competence at searching files transfers directly, and a human can read the same source with the same tools without a viewer.
The README also answers the obvious objection, under the heading asking why not just keep Markdown in your repo. For one agent in one repository, do that. OpenLore is for the case where 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.
Two further claims describe the shape of the product. 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. And writes are described as atomic, conflict aware and validated before they commit, which is the part that distinguishes it from an agent editing a file over SSH directly.
Two ports, four transports, one virtual filesystem
The install is a Homebrew cask and one command, and the network surface is small enough to state exactly:
brew install --cask aakarim/tap/lore
openlore ./docsThe README then fixes the ports. SSH runs on port 2222, the web view and MCP share port 8080, and the contents of the directory you passed appear at the root path. That last point is worth internalising: the path an agent sees is the same path space, so a command that works against a local checkout works unchanged against the server.
The transports are more numerous than the ports suggest. One knowledge surface is served over SSH, over SFTP and SSHFS including direct browsing and editing from VS Code, over MCP, and through a human friendly web view. SFTP and SSHFS are the quiet one: because it is a real file server, an editor can mount it and a reviewer can browse it without any OpenLore specific client.
Connecting an agent is one command per client:
# 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' /"The third line is the important demonstration. The grep recurses from the root of the mounted knowledge, and an agent that has never heard of OpenLore can still use it. Guides are also provided for Cursor, OpenCode, and any agent over SSH.
The shell is an in-memory Go interpreter, not /bin/sh
The safety claim is specific and unusual enough to quote closely. The README states the shell is an in-memory Go interpreter rather than a real operating-system shell, and that there is no shell escape, no arbitrary process execution and no ambient network access in a normal session.
That claim only makes sense against the alternative. If an agent reached a knowledge server by running a real shell, every prompt it read from a document would be a step away from running something on the host. An in-memory interpreter removes that category of risk, because there is no process table to escape into and no inherited environment to read.
The cost is that the shell is not POSIX. Whatever commands it understands are the ones the interpreter implements, and an agent that assumes a full shell may find gaps. The README does not enumerate the supported command set or the semantics of each one, so the honest position is that the guarantee covers the escape risk while leaving the command surface undocumented.
The second half of the statement is the one to watch. No ambient network access in a normal session implies there are non-normal sessions, or at least configuration that adds it. Nothing in the README explains what those are, and that is a question to answer before pointing production agents at the server.
Grants, docsets and the inbox pattern for contributions
Access control is the reason to run a server instead of sharing a folder, so it is worth reading the vocabulary precisely.
Content is organised into docsets. A docset can be kept read only, or allow scoped publishing, or enable full writes, and those three settings map onto the three role grants: ro, publish and rw. Identity scoped views then give each person or agent only the docsets it needs, with path aliases so the same virtual path can resolve differently per identity, and a private home directory per agent so scratch space does not land in shared knowledge.
The publish grant exists for a specific workflow. The use case list describes governed knowledge contribution: contributors publish into inboxes while existing documents stay reserved for maintainers, which prevents an accidental overwrite of a document somebody else owns. The guide for letting an agent publish into an inbox is linked separately, and it is the pattern most worth adopting first, because a mistake by an agent then lands in a review queue rather than in the canonical file.
The write path has guarantees attached. Writes are atomic, conflict aware and validated before they commit, and validation is extensible: plugins can add validation, grants, read and write middleware, metadata and post-commit processing while preserving the same filesystem interface.
The team-facing consequence is that an identity can be added or removed without moving files, which is the operational difference between this and a shared directory.
Metadata you can read with jq, and validation against OKF
Structured knowledge usually arrives with a query language attached. OpenLore takes the opposite position, described as structured knowledge without a new query language.
The mechanism is lore meta, which inspects frontmatter and outputs NDJSON, which means standard tools apply. You query it with jq. There is no retrieval DSL to learn and no API surface to integrate, and a pipeline that wants to index or filter frontmatter can do it with the same tools it already uses.
Validation runs close to the write path rather than as a separate CI step. The README names Google's Open Knowledge Format, linking the OKF specification in the GoogleCloudPlatform knowledge-catalog repository, and says bundles and Agent Skills are validated against it. Validating before commit is the right side of the boundary: a document that fails a convention is rejected at the moment the agent tries to write it, rather than later when a person reads it.
Plugins extend the same surface rather than replacing it, covering validation, grants, middleware, metadata and post-commit processing. Combined with the grant model, that is what makes a self-hosted knowledge server extensible without becoming a platform.
For distribution there are three more paths. Docs can be embedded into a self contained binary, cross-platform bundles can be built with the GitHub Action declared in action.yml, and the same knowledge can be packaged as a desktop MCP extension.
The build splits Go from a Node dashboard, and deployment targets are declared in the repo
The Makefile is short and makes one important promise in a comment: normal Go builds intentionally do not require Node or generated dashboard assets, and distribution builds embed the generated frontend. In practice there are two build paths.
The plain build is `go build./...`. The distribution path runs the dashboard build first, which uses `npm ci` and `npm run build` inside the dashboard directory, and then produces a single binary with -trimpath from./cmd/openlore. A CI target named dashboard-ci additionally runs the dashboard's check and test steps. Anyone shipping a binary therefore has to run the Node toolchain, and anyone running from source does not.
The module is github.com/aakarim/go-openlore and requires Go 1.26.2, which is a high floor and the single most likely thing to block a build. The dependency list describes the server precisely: charmbracelet ssh and wish with bubbletea and lipgloss for the terminal side, pkg/sftp for file transfer, the modelcontextprotocol go-sdk for MCP, go-jwt-middleware and golang-jwt for authentication, go-webauthn for passkeys, goldmark for Markdown, modernc sqlite for storage, and yaml.v3 for configuration.
Deployment is declared rather than described. fly.toml, render.yaml, railpack.json and railpack-plan.json are all in the root, along with a render deploy button in the README and a deploy/ directory. The example directories cover caddy-multi-port and caddy-reverse-proxy, which suggests the port model above was designed with a reverse proxy in mind from the start.
Where OpenLore is the wrong tool, and the honest alternative
The project states its own boundary, and it is a real one. If you have one agent working in one repository, a server with identity, grants and two ports is infrastructure you do not need, and the README says so.
Beyond scope, there are cases where the design actively does not help. There is no semantic retrieval, so an agent that needs to answer a question spanning many documents by meaning rather than by keyword has to grep, and no chunking or embedding exists to fix that. Grading and relevance across a large corpus is out of reach by construction.
The access model has a cost too. Every identity that can write needs a grant, and every docset needs a decision, and that administration is real work for a small team whose knowledge fits in a repository.
The alternative is not a single competitor but two shapes of decision. Keep Markdown in the repository and rely on version control for history and access control, which is correct until you have more than one place writing. Or consider a hosted workspace such as Confluence or Notion, which the README names in its use-case comparison.
OpenLore sits between the two, and the decision is whether greppability by an unmodified agent is worth running a server to get it.
Cadence, licence and the pre-1.0 signals
The release history is fast and the version line is pre-1.0. v0.7.1 was published on 2026-09-19, v0.7.3 on 2026-10-01 described as a verified v0.7 reliability release, and v0.7.4 on 2026-10-12 covering shell correctness, dashboard finder and analytics reliability. The last push was on 2026-10-15 and the repository is not archived.
Those three release notes are unusually informative for a project this young, and they cut both ways. The release notes point to ongoing changes in shell correctness, release verification and the dashboard. A verified reliability release and a dashboard finder say the same about a project that is still finding its edges. Either way, a 0.7 line means the CLI surface, the configuration file names and the grant semantics may still move between minor versions, and the README does not publish a deprecation policy to soften that.
The licence is Apache-2.0 with a LICENSE file at the root, and SECURITY.md is present, so there is a published path for reporting a problem. Configuration is example driven, with lore.json.example and openlore.yml.example in the root, which is the right way to ship a config format that is still moving.
One oddity to expect if you build from source: the repository is OpenLore and the command is openlore, while the Go module path is github.com/aakarim/go-openlore and the Homebrew cask is aakarim/tap/lore. Three names for one project is a small thing, but it is the kind of small thing that wastes an afternoon when a dependency path does not resolve.
Editorial conclusion
Run OpenLore when several agents, repositories or people need one set of shared files with different levels of write access, and you want them to reach it with cat, grep and find rather than a new client library. Do not run it for the single agent in the single repository case, because the README's own advice there is to keep Markdown in the repo, and do not expect retrieval quality from a chunking pipeline since none exists. Verify first the port choice, since SSH and the web view want 2222 and 8080, and confirm that the dashboard frontend build is a separate Node step your distribution pipeline has to run.
Frequently asked questions
How do I install and start OpenLore?
Install the Homebrew cask with `brew install --cask aakarim/tap/lore` and then run `openlore ./docs` to serve a folder. The README points to the quickstart document for Linux and Windows, and it contains no apt, cargo or binary download instructions.
Which ports does OpenLore use?
SSH runs on port 2222, and the web view and MCP share port 8080. A plain shell client reaches it with something like `ssh -p 2222 localhost "grep -r 'retry' /"`, where the served folder is mounted at the root.
Does OpenLore use a vector database or embeddings?
No. The README states there is no vector database, no ingestion pipeline and no SDK, and that your knowledge stays as ordinary Markdown retrieved with shell tools such as cat, grep and find.
How does OpenLore control who can write?
By docset, with role based ro, publish and rw grants, identity scoped views, path aliases and a private home directory per agent. Writes are described as atomic, conflict aware and validated before commit, and a publish grant lets contributors write into an inbox without overwriting maintained documents.
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/aakarim-openlore)Was this useful?