Documentation navigation
Docs/Install/Manual configuration

Manual configuration

Configure the Lore server and agent integrations by hand when you do not use the installer script.

Manual configuration is for installations where you do not want the installer to make every choice for you. Use it when you are deploying Lore on a remote host, connecting to an existing database, or installing only selected agent integrations.

You will configure four things:

LayerWhat you set upResult
ServerDatabase URL, optional auth token, cache, and file storageLore Web starts and exposes /setup and /api/mcp
Runtime settingsEmbedding, View LLM, boot memory, recall, Dream, and backup settingsLore can search, view, and maintain memory
Shared client configServer URL and token for local hooksLocal integrations know where Lore is
Agent runtimeNative plugin or MCP endpoint, environment variables, and runtime-specific hooksAgents can load boot memory and use recall

Keep server secrets on the server, and keep agent-specific configuration in the agent runtime. A client config should not contain DATABASE_URL; a server .env should not contain Claude, Codex, or OpenClaw hook settings.

Before you start

You need:

  • a machine that can run Lore Web;
  • PostgreSQL with pgvector available, either bundled through Docker Compose or managed by you;
  • optional Redis for shared cache;
  • an API token if the server should not be open on your network;
  • one or more agent runtimes to connect after setup.

Start the server with Docker Compose

For the standard Docker Compose deployment, create a .env next to docker-compose.yml:

*.txt
Plaintext
TZ=Asia/Shanghai

POSTGRES_DB=lore
POSTGRES_USER=lore
POSTGRES_PASSWORD=change-me
POSTGRES_PORT=55439
POSTGRES_DATA_DIR=./data/postgres

DATABASE_URL=postgresql://lore:change-me@postgres:5432/lore
WEB_PORT=18901
API_TOKEN=
LORE_DB_POOL_SIZE=10

REDIS_URL=redis://redis:6379/0
REDIS_DATA_DIR=./data/redis
CACHE_KEY_PREFIX=lore
CACHE_LOCAL_MAX_ITEMS=2000

SNAPSHOT_DATA_DIR=./data/snapshots

LORE_POSTGRES_IMAGE=fffattiger/pgvector-zhparser:pg16
LORE_REDIS_IMAGE=redis:7-alpine
LORE_FRONTEND_IMAGE=fffattiger/lore:latest

Start Lore:

*.bash
Shell
curl -fsSL https://raw.githubusercontent.com/FFatTiger/lore/main/docker-compose.yml -o docker-compose.yml
docker compose up -d
docker compose ps
curl -fsS http://127.0.0.1:18901/api/health

If you set API_TOKEN, use the same token when you open the Web Console and when you configure MCP or hooks.

Start the server without bundled PostgreSQL

Use this path when you already operate PostgreSQL yourself. Point Lore Web at that database:

*.txt
Plaintext
DATABASE_URL=postgresql://lore:change-me@db.example.com:5432/lore
API_TOKEN=YOUR_SERVER_TOKEN_IF_USED
REDIS_URL=redis://redis.example.com:6379/0
CACHE_KEY_PREFIX=lore
CACHE_LOCAL_MAX_ITEMS=2000
LORE_DB_POOL_SIZE=10

The database role should be allowed to create the schema and required extensions during first startup. If your production role is restricted, run the first startup with a migration-capable role, then switch to the restricted role after the schema exists.

Start Lore (still using Docker Compose for the Web and Redis containers, pointing at your external database):

*.bash
Shell
curl -fsSL https://raw.githubusercontent.com/FFatTiger/lore/main/docker-compose.yml -o docker-compose.yml
# Remove or comment out the postgres service block in docker-compose.yml,
# or leave your DATABASE_URL pointing at the external host.
docker compose up -d
docker compose ps
curl -fsS http://127.0.0.1:18901/api/health

Lore also needs writable storage for backups and review changesets. In Docker Compose this is provided by SNAPSHOT_DATA_DIR. In a custom deployment, mount persistent storage at the path used by the container image.

Complete /setup

After the server is healthy, open:

*.txt
Plaintext
http://127.0.0.1:18901/setup

Complete these steps in order:

  1. Embedding setup — choose an OpenAI-compatible embedding endpoint.
  2. View LLM setup — choose OpenAI-compatible chat, OpenAI Responses, or Anthropic Messages.
  3. Boot memory setup — review the startup memories that agents will receive.
  4. Final check — confirm setup is complete before connecting agents.

You can also save settings through the API:

*.bash
Shell
curl -fsS -X PUT http://127.0.0.1:18901/api/settings \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer YOUR_SERVER_TOKEN_IF_USED' \
  --data '{
    "patch": {
      "embedding.provider": "openai_compatible",
      "embedding.base_url": "http://host.docker.internal:8090/v1",
      "embedding.api_key": "YOUR_EMBEDDING_KEY",
      "embedding.model": "text-embedding-3-small",
      "view_llm.provider": "openai_compatible",
      "view_llm.base_url": "http://host.docker.internal:8090/v1",
      "view_llm.api_key": "YOUR_LLM_KEY",
      "view_llm.model": "deepseek-v4-flash"
    }
  }'

Skip the authorization header only when your server has no API_TOKEN.

Create shared client config

Local Lore integrations, including Claude Code, Codex, and OpenCode, can read the same client config. Create ~/.lore/config.json on the machine where the agents run:

*.json
JSON
{
  "base_url": "http://127.0.0.1:18901",
  "api_token": "YOUR_TOKEN_IF_USED",
  "docker_managed": false
}

Rules:

  • base_url is the Lore server origin without a trailing slash;
  • omit api_token when the server has no API_TOKEN;
  • keep docker_managed false when you manage the server yourself.

Connect Claude Code

Claude Code hooks read the shared ~/.lore/config.json. If you configure Claude MCP manually, register the HTTP endpoint with a bearer header when the server uses API_TOKEN:

*.bash
Shell
claude mcp remove lore || true
claude mcp add --transport http --scope user \
  --header "Authorization: Bearer YOUR_TOKEN_IF_USED" \
  lore "http://127.0.0.1:18901/api/mcp?client_type=claudecode"

For an unprotected local server, omit the --header option.

If you install the Claude Code plugin by hand, install the plugin files and hooks, then restart Claude Code. Do not copy local guidance into CLAUDE.md; the hooks forward lifecycle events to the Lore server and use the server-returned host output.

*.bash
Shell
git clone https://github.com/FFatTiger/lore.git /tmp/lore-plugin
# Copy or install the claudecode-plugin directory according to your Claude Code plugin setup.
# Ensure its hooks call /api/lifecycle/event and share ~/.lore/config.json.

The exact plugin path may differ by release. Check the Lore repository for the current plugin layout.

Restart Claude Code after changing settings, plugin files, or CLAUDE.md.

Connect Codex

Enable plugins and hooks in ~/.codex/config.toml:

*.toml
TOML
[plugins."lore@lore"]
enabled = true

[features]
hooks = true

Register MCP without server auth:

*.bash
Shell
codex mcp remove lore || true
codex mcp add lore --url "http://127.0.0.1:18901/api/mcp?client_type=codex"

Register MCP with server auth by keeping the URL plain and storing the bearer header in ~/.codex/config.toml:

*.toml
TOML
[mcp_servers.lore]
url = "http://127.0.0.1:18901/api/mcp?client_type=codex"
http_headers = { Authorization = "Bearer YOUR_TOKEN_IF_USED" }

Install Codex hooks from the plugin package when you need startup boot memory and per-prompt recall. Hooks read ~/.lore/config.json, so no extra token environment variable is required:

*.bash
Shell
bash /tmp/lore-plugin/packages/codex-plugin/scripts/install-hooks.sh

Restart Codex, open /hooks, and trust the Lore hooks if Codex asks for approval.

Connect OpenCode

The native OpenCode integration is a prerelease in v1.3.15-pre.4, tested with OpenCode 1.18.3. It reads the same ~/.lore/config.json shown above and installs one managed file:

*.txt
Plaintext
~/.config/opencode/plugins/lore-memory.js

The preferred path is the prerelease installer:

*.bash
Shell
npx @loremem/cli install --pre --channels opencode

To install lore-opencode.zip manually, preserve any unmarked file already at the target path:

*.bash
Shell
tmp_dir="$(mktemp -d)"
target="$HOME/.config/opencode/plugins/lore-memory.js"
curl -fL https://github.com/FFatTiger/lore/releases/download/v1.3.15-pre.4/lore-opencode.zip \
  -o "$tmp_dir/lore-opencode.zip"
unzip -q "$tmp_dir/lore-opencode.zip" -d "$tmp_dir/lore-opencode"
mkdir -p "$(dirname "$target")"
if [ -f "$target" ] && ! grep -q '@lore-managed-opencode-plugin' "$target"; then
  echo "Refusing to overwrite unmarked OpenCode plugin: $target" >&2
  exit 1
fi
install -m 0644 "$tmp_dir/lore-opencode/lore-memory.js" "$target"
rm -rf "$tmp_dir"

Restart OpenCode after installation. The plugin registers exactly these native tools:

  • lore_guidance
  • lore_status
  • lore_boot
  • lore_get_node
  • lore_search
  • lore_list_domains
  • lore_create_node
  • lore_update_node
  • lore_delete_node
  • lore_move_node

Boot is injected into system context with experimental.chat.system.transform; it is never inserted into the user message. Prompt Recall runs through chat.message and appends a separate current-turn text part. If Lore or the experimental system hook is unavailable, the plugin warns and fails open. Native tools remain available, and prompt Recall continues when only system injection is unavailable.

Standard OpenCode installation does not configure /api/mcp. If native plugin loading is impossible, generic MCP at /api/mcp?client_type=opencode is a manual fallback only and does not reproduce the native lifecycle behavior.

Manual ZIP installation does not apply this compatibility edit: if oh-my-openagent or legacy oh-my-opencode imports Claude Code plugins, add claude_code.plugins_override["lore@lore"] = false to the active user-level JSON/JSONC config before restarting OpenCode. This prevents duplicate Claude Lore lifecycle hooks; the native plugin still removes duplicate Lore MCP entries at runtime. Do not change Claude Code files. If you intentionally want the legacy fallback alongside native Lore, leave that override enabled and start OpenCode with LORE_OPENCODE_ALLOW_MCP=1.

To uninstall only the OpenCode integration, use the ownership-aware uninstaller. It removes lore-memory.js only when the file contains the Lore management marker and preserves unmarked plugins:

*.bash
Shell
npx @loremem/cli uninstall --channels opencode -y

Connect OpenClaw

OpenClaw uses a plugin entry in ~/.openclaw/openclaw.json:

*.json
JSON
{
  "plugins": {
    "entries": {
      "lore": {
        "enabled": true,
        "config": {
          "baseUrl": "http://127.0.0.1:18901",
          "apiToken": "YOUR_TOKEN_IF_USED",
          "timeoutMs": 30000,
          "defaultDomain": "core",
          "injectPromptGuidance": true,
          "startupHealthcheck": true,
          "recallEnabled": true,
          "minDisplayScore": 0.4,
          "maxDisplayItems": 3,
          "scorePrecision": 2,
          "excludeBootFromResults": true
        }
      }
    }
  }
}

Restart OpenClaw after editing the plugin entry.

Connect Pi

Install or symlink the Lore extension into the Pi extension directory. From the cloned Lore repository:

*.bash
Shell
PI_CODING_AGENT_DIR="$HOME/.pi/agent" bash /tmp/lore-plugin/packages/pi-extension/scripts/install-local.sh

Pi reads ~/.lore/config.json by default. If your Pi runtime supports extension config, use it only when you need a per-runtime override:

*.json
JSON
{
  "baseUrl": "http://127.0.0.1:18901",
  "apiToken": "YOUR_TOKEN_IF_USED",
  "timeoutMs": 30000,
  "defaultDomain": "core",
  "injectPromptGuidance": true,
  "startupHealthcheck": true,
  "recallEnabled": true
}

Run /reload inside Pi or restart the runtime.

Connect Hermes

Hermes reads the Lore server and token from ~/.lore/config.json:

*.json
JSON
{
  "base_url": "http://127.0.0.1:18901",
  "api_token": "YOUR_TOKEN_IF_USED"
}

LORE_BASE_URL and LORE_API_TOKEN remain fallback environment variables for older setups.

Then link the plugin package into the Hermes plugin directory. From the cloned Lore repository:

*.bash
Shell
mkdir -p ~/.hermes/skills
ln -s /tmp/lore-plugin/packages/hermes-plugin/lore_memory ~/.hermes/skills/lore_memory

Restart Hermes after linking the plugin.

Verify the result

Before moving real instructions into Lore, check these items:

  1. curl -fsS http://127.0.0.1:18901/api/health returns success.
  2. /setup shows embedding, View LLM, and boot memory complete.
  3. Every MCP-based agent URL includes the right client_type; OpenCode uses its native plugin instead.
  4. Protected servers receive the same bearer token from Web UI, MCP, hooks, and the OpenCode plugin.
  5. A new agent session includes boot context. For OpenCode, confirm core://agent/opencode through lore_boot.
  6. A realistic project prompt produces a recall block. In OpenCode this must still work when experimental system injection is unavailable.
  7. Opening a recalled node works in the Web Console.
Quick installUse the installer to start Lore with Docker or connect clients to an existing Lore server.Use your own PostgreSQLRun Lore against an existing PostgreSQL instance with pgvector and optional Chinese full-text search extensions.First-run setupOpen /setup, configure model endpoints, bootstrap memory, and restart connected runtimes.Essential settingsSet server auth, embedding, View LLM, Redis cache, and backup defaults used by daily operation.