Every mode serves the same virtual filesystem. Choose the transport and packaging that fit the client.
Serve a directory over SSH, web, and MCP
openlore ./docs
This starts SSH on port 2222 and HTTP on port 8080. The HTTP server includes the
human-facing front page and the default MCP endpoint at /mcp.
ssh -p 2222 localhost
ssh -p 2222 localhost "find / -name '*.md' | head -20"
ssh -p 2222 localhost "cat /docs/api-reference.md"
Use --allowed '*.md,*.txt' and --ignore '.git,node_modules' to constrain the
served tree from the command line, or configure these rules in openlore.yml.
An explicitly loaded --config file replaces (rather than merges with) an
embedded openlore.yml; otherwise the embedded config takes precedence over
built-in defaults. Command-line flags always win.
Connect an agent
Add a directory listing or the built-in agent instructions to AGENTS.md:
ssh -p 2222 localhost "tree -L 2 /" >> AGENTS.md
ssh -p 2222 localhost agents >> AGENTS.md
You can also give the agent a direct tool instruction:
## Documentation Access
Connect to the docs server for project documentation:
ssh -p 2222 docs.internal "cat /api/endpoints.md"
Use `ls`, `cat`, `grep`, `find`, and pipes to explore. Run `help` for the full
command list.
OpenLore skills output instructions to stdout rather than appearing in the
filesystem. setup creates and locally verifies a team deployment project;
onboarding adds initial identities and folders; deploy provisions and
verifies one authoritative server; and upgrade prepares a pinned image
version change. Provider deployment guides cover Fly.io, Railway, AWS, Google
Cloud, Azure, and DigitalOcean. teach covers general OpenLore setup and
agents emits an AGENTS.md snippet. Commands named agents-<type> emit
instructions for specific agent types: openlore-skill emits a portable
Agent Skills SKILL.md for installation into any harness’s skills directory
(Amp, Claude Code, headlong, …), while agents-shellm and
agents-shellm-housekeeping emit
headlong/shellm-format
SKILL.md files for accessing and maintaining the server (install with
ssh <server> agents-shellm > .skills/openlore/SKILL.md;
see shellm.md for Docker caveats and trajectory sharing).
Run skills for Agent Skills management
instructions and a list of built-in and configured runtime instruction
commands.
Pipe an instruction command from a public OpenLore server into your coding agent, for example:
ssh openlore.sh setup | amp
The generated <team>-lore repository tracks openlore.yml, a thin
Containerfile based on a stable OpenLore release, and provider artifacts under
deploy/. Initial policy and filesystem state live in gitignored .local/
until the first verified deployment initializes its persistent volume. The
deployment copies tracked openlore.yml separately into the volume (or projects
it through a facility such as a Kubernetes ConfigMap); it is not baked into the
container image.
Embed docs in a binary
Place docs in assets/lore/ and build:
go build -o my-docs ./cmd/openlore
The resulting binary contains the docs and serves them at /docs when run with
no directory argument. Embedded docs are always read-only.
Extract embedded docs when needed:
openlore export -o ./extracted-docs
Build with the GitHub Action
- uses: aakarim/openlore@v1
with:
docs-dir: ./docs
config: ./openlore.yml
The action produces cross-platform binaries containing the selected docs. It also builds and embeds the dashboard using the repository’s Nix-pinned Node toolchain. The resulting binary does not require Node at runtime.
MCP over HTTP
The Streamable HTTP MCP endpoint shares the HTTP server and its TLS or reverse proxy configuration:
openlore ./docs
# SSH: ssh -p 2222 localhost
# Web: http://localhost:8080
# MCP: http://localhost:8080/mcp
Configure it in openlore.yml:
mcp:
enabled: true
path: /mcp
require_auth: true
require_auth: true forces OAuth login for both MCP-over-HTTP and the JSON API
while retaining the separately configured SSH posture. false permits
anonymous access to both HTTP transports. If omitted, both inherit the keyless
posture. When the posture requires a token but no tokens block is configured,
both transports fail closed and answer every request with 401 (the server logs
a warning at startup); configure tokens or set require_auth: false.
--mcp-path /custom changes the MCP path; MCP over HTTP requires the HTTP
server to remain enabled.
The MCP server exposes:
| Tool | Description |
|---|---|
shell | Execute a command against the virtual filesystem |
list_commands | List commands supported by that server |
The shell tool returns completed command invocations as normal MCP results,
including when the command exits non-zero. Its structured content keeps
stdout, stderr, and exit_code separate. The existing output field and
text content contain stdout followed by stderr for compatibility, without a
synthetic exit-code line. MCP isError is reserved for failures of the tool
invocation itself rather than command exit status.
For Streamable HTTP connections, the shell’s OPENLORE_SESSION_ID environment
variable is the MCP server session ID. It remains stable across tool calls, so
session-scoped files or command logs can be addressed from the shell, for
example with cat /sessions/$OPENLORE_SESSION_ID/history when such a history
mount is configured.
The plain JSON POST /api/shell endpoint and persistent-session
POST /api/sessions/{id}/shell endpoint use the same result contract and
return HTTP 200 for completed commands:
{
"output": "...",
"stdout": "...",
"stderr": "...",
"is_error": false,
"exit_code": 1
}
MCP over stdio
Use stdio for clients that launch a local process, including Claude Desktop:
openlore mcp
openlore mcp ./docs
openlore mcp --allowed '*.md,*.txt' --ignore '.git,node_modules' ./docs
Example MCP client configuration:
{
"mcpServers": {
"openlore": {
"command": "openlore",
"args": ["mcp", "./docs"]
}
}
}
Package a desktop extension
Package an embedded binary as an MCPB extension for one-click installation:
go build -o openlore ./cmd/openlore
./openlore mcpb -o openlore.mcpb
If the binary does not contain embedded docs, installation prompts for a docs
directory. Pass --docs-dir ./docs to bundle one during packaging.
Browse and edit with VS Code
An SFTP filesystem extension can open OpenLore’s directory tree directly in VS Code without cloning, mounting, or synchronizing it into a local project folder. Saving an editor writes the individual file back through OpenLore’s governed write path. See Editing OpenLore Files for VS Code setup, other compatible editors, save behavior, and limitations.
Mount with SSHFS
SFTP also lets local tools mount a read-only view of the virtual filesystem:
mkdir -p /mnt/docs
sshfs -p 2222 localhost:/ /mnt/docs -o ro
grep -r "API" /mnt/docs/
code /mnt/docs/
fusermount -u /mnt/docs # Linux
umount /mnt/docs # macOS
Human-facing web view
The front page is enabled on port 8080 by default:
openlore ./docs
openlore --http-port 3000 ./docs
openlore --http-port 0 ./docs
In addition to browsing content, the page displays the SSH host key and provides
it at GET /host-key. Serve this endpoint over TLS when using it as the trust
anchor for an SSH connection.
Use OpenLore as a Go library
package main
import (
"log"
openlore "github.com/aakarim/go-openlore/pkg/openlore"
)
func main() {
srv, err := openlore.NewServer("./docs",
openlore.WithPort(2222),
openlore.WithHTTPPort(8080),
openlore.WithAllowedPatterns([]string{"*.md", "*.txt"}),
)
if err != nil {
log.Fatal(err)
}
if err := srv.ListenAndServe(); err != nil {
log.Fatal(err)
}
}
An MCP-only server can be built against any OpenLore filesystem:
fs := openlore.NewDirFS("./docs", openlore.FilesConfig{
Allowed: []string{"*.md", "*.txt"},
})
srv := openlore.NewMCPServer(fs,
openlore.WithMCPServerName("Company Knowledge Base"),
openlore.WithMCPInstructions("Use grep and cat to explore the docs."),
)