From 7dcdafcf67ae2377795f88af94e87a5eef70368c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CBeeRad=E2=80=9D?= Date: Sat, 2 May 2026 13:55:01 +1000 Subject: [PATCH 1/2] Clarify MCP database configuration --- README.md | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/README.md b/README.md index 5da3af2..ba85e0e 100644 --- a/README.md +++ b/README.md @@ -314,6 +314,83 @@ npx -y ra-h-mcp-server@latest setup --client claude-code,codex --yes --db "$HOME --- +## Point MCP At The Right Database + +The MCP server reads and writes whichever SQLite file is set as `RAH_DB_PATH`. + +Use the same database path for the app and for MCP. If these paths do not match, the browser UI and your coding agent will be looking at different graphs. + +### Default Database + +If you used the default app-data database, install MCP without `--db`: + +```bash +npx -y ra-h-mcp-server@latest setup --client claude-code,codex --yes +``` + +That points MCP at the default platform path: + +```text +~/Library/Application Support/RA-H/db/rah.sqlite # macOS +~/.local/share/RA-H/db/rah.sqlite # Linux +%APPDATA%/RA-H/db/rah.sqlite # Windows +``` + +### Custom Or Repo-Local Database + +If you set `SQLITE_DB_PATH` during app setup, pass that exact same path to the MCP installer with `--db`. + +Example repo-local app setup: + +```bash +SQLITE_DB_PATH="$PWD/.ra-h/db/rah.sqlite" npm run setup:local -- --profile qwen-local +``` + +Matching MCP setup: + +```bash +npx -y ra-h-mcp-server@latest setup \ + --client claude-code,codex \ + --yes \ + --db "$PWD/.ra-h/db/rah.sqlite" +``` + +### Project-Scoped Claude Code MCP + +If you want Claude Code to use a repo-local database only inside this repo, create a project `.mcp.json`: + +```json +{ + "mcpServers": { + "ra-h": { + "command": "npx", + "args": ["-y", "ra-h-mcp-server@latest"], + "env": { + "RAH_DB_PATH": "/absolute/path/to/ra-h_os/.ra-h/db/rah.sqlite" + } + } + } +} +``` + +Use the server name `ra-h` in project config if you want the project database to override a user-level `ra-h` server while Claude is opened in that repo. + +Keep `.mcp.json` out of git if it contains a machine-specific path. + +### Verify The Active MCP Database + +After configuring MCP, fully restart the client. + +Then run: + +```bash +npx -y ra-h-mcp-server@latest doctor --db "/path/to/rah.sqlite" +``` + +Inside your agent, ask it to use the RA-H MCP server and report the database path it is using before it creates or updates nodes. + +--- + ## Demo-safe isolated install If you need a clean demo without touching your normal RA-H database: @@ -341,6 +418,8 @@ The recommended path is the CLI installer: npx -y ra-h-mcp-server@latest setup --client claude-code --yes ``` +If your app uses a custom database path, include `--db` with that exact path. See [Point MCP At The Right Database](#point-mcp-at-the-right-database). + Manual config is still useful for troubleshooting or unsupported clients. Add this to your MCP client config and restart the client fully: From 0481435ca6693241c27d5330ba0be7a599a01eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CBeeRad=E2=80=9D?= Date: Sat, 2 May 2026 13:59:15 +1000 Subject: [PATCH 2/2] Add llama.cpp setup profile --- .env.example | 10 +++++ LLAMA-CPP-LOCAL-PROFILE.md | 6 +++ LOCAL-MODELS.md | 15 +++++++ README.md | 73 ++++++++++++++++++++++++++++----- docs/README.md | 30 ++++++++++++-- scripts/dev/bootstrap-local.mjs | 28 ++++++++++--- 6 files changed, 143 insertions(+), 19 deletions(-) diff --git a/.env.example b/.env.example index e6ebddb..15206ea 100644 --- a/.env.example +++ b/.env.example @@ -11,6 +11,7 @@ OPENAI_API_KEY= # # npm run setup:local -- --profile openai # npm run setup:local -- --profile qwen-local +# npm run setup:local -- --profile llama-cpp # # OpenAI profile: # LLM_PROFILE=openai @@ -30,6 +31,15 @@ OPENAI_API_KEY= # EMBEDDING_MODEL=qwen3-embedding:0.6b # EMBEDDING_DIMENSIONS=1024 # +# Example llama.cpp: +# LLM_PROFILE=openai-compatible +# LLM_BASE_URL=http://127.0.0.1:8080/v1 +# LLM_MODEL=qwen3-4b +# EMBEDDING_PROFILE=openai-compatible +# EMBEDDING_BASE_URL=http://127.0.0.1:8081/v1 +# EMBEDDING_MODEL=qwen3-embedding-0.6b +# EMBEDDING_DIMENSIONS=1024 +# # Example Qdrant sidecar, only needed when sqlite-vec is unavailable or unreliable: # VECTOR_BACKEND=qdrant # QDRANT_URL=http://localhost:6333 diff --git a/LLAMA-CPP-LOCAL-PROFILE.md b/LLAMA-CPP-LOCAL-PROFILE.md index 4b306b8..c68e6f6 100644 --- a/LLAMA-CPP-LOCAL-PROFILE.md +++ b/LLAMA-CPP-LOCAL-PROFILE.md @@ -11,6 +11,12 @@ llama-server -m /models/qwen3-embedding-0.6b.gguf --embedding --port 8081 Configure RA-H: +```bash +npm run setup:local -- --profile llama-cpp +``` + +That writes this profile to `.env.local`: + ```bash LLM_PROFILE=openai-compatible LLM_BASE_URL=http://127.0.0.1:8080/v1 diff --git a/LOCAL-MODELS.md b/LOCAL-MODELS.md index bee8794..d098afd 100644 --- a/LOCAL-MODELS.md +++ b/LOCAL-MODELS.md @@ -13,6 +13,8 @@ OpenAI remains the default supported path. Local mode is for users who are comfo ## Core Env +Ollama: + ```bash LLM_PROFILE=openai-compatible LLM_BASE_URL=http://127.0.0.1:11434/v1 @@ -24,6 +26,19 @@ EMBEDDING_MODEL=qwen3-embedding:0.6b EMBEDDING_DIMENSIONS=1024 ``` +llama.cpp: + +```bash +LLM_PROFILE=openai-compatible +LLM_BASE_URL=http://127.0.0.1:8080/v1 +LLM_MODEL=qwen3-4b + +EMBEDDING_PROFILE=openai-compatible +EMBEDDING_BASE_URL=http://127.0.0.1:8081/v1 +EMBEDDING_MODEL=qwen3-embedding-0.6b +EMBEDDING_DIMENSIONS=1024 +``` + Run: ```bash diff --git a/README.md b/README.md index ba85e0e..778d3b6 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ 2. **Provides a UI** — Browse, search, and organize your nodes at `localhost:3000` 3. **Exposes an MCP server** — Claude Code and other MCP clients can query and add to your knowledge base -Your database stays on your machine. With the `openai` profile, model requests go to OpenAI after you add an API key. With the `qwen-local` profile, model requests go to your local Ollama/OpenAI-compatible endpoint. +Your database stays on your machine. With the `openai` profile, model requests go to OpenAI after you add an API key. With `qwen-local` or `llama-cpp`, model requests go to your local OpenAI-compatible endpoints. Current contract: - no runtime `dimensions` @@ -54,7 +54,8 @@ Current contract: |-------------|---------------| | Your AI coding agent can read/write your RA-H graph | **Option A: MCP-only quick install** | | A browser UI at `localhost:3000` with OpenAI models | **Option B1: Full local app with OpenAI** | -| A browser UI at `localhost:3000` with local Qwen models | **Option B2: Full local app with local Qwen** | +| A browser UI at `localhost:3000` with local Qwen models through Ollama | **Option B2: Full local app with local Qwen/Ollama** | +| A browser UI at `localhost:3000` with local Qwen models through llama.cpp | **Option B3: Full local app with local Qwen/llama.cpp** | | A clean demo that does not touch your real graph | **Demo-safe isolated install** | ### Option A: MCP-only quick install @@ -120,7 +121,7 @@ npm run dev Open [localhost:3000](http://localhost:3000). Add your OpenAI API key when the app prompts you, or later in Settings -> API Keys. -### Option B2: Full local app with local Qwen +### Option B2: Full local app with local Qwen/Ollama Use this if you want the browser UI at `localhost:3000` and want RA-H to call local OpenAI-compatible Ollama endpoints instead of OpenAI. @@ -140,6 +141,34 @@ npm run dev Open [localhost:3000](http://localhost:3000). Settings -> API Keys will show the active local model profile and disable OpenAI key entry. +### Option B3: Full local app with local Qwen/llama.cpp + +Use this if you want local model calls but prefer managing GGUF files and llama.cpp server processes yourself. + +Prerequisites: +- llama.cpp is installed. +- You have compatible Qwen chat and embedding GGUF files. +- You start separate OpenAI-compatible servers before running RA-H setup. + +Example llama.cpp servers: + +```bash +llama-server -m /models/qwen3-4b.gguf --port 8080 +llama-server -m /models/qwen3-embedding-0.6b.gguf --embedding --port 8081 +``` + +Then set up RA-H: + +```bash +git clone https://github.com/bradwmorris/ra-h_os.git +cd ra-h_os +npm install +npm run setup:local -- --profile llama-cpp +npm run dev +``` + +Open [localhost:3000](http://localhost:3000). Settings -> API Keys will show the active local model profile and disable OpenAI key entry. + If you also want your coding agent connected to the same default database, run Option A after the app setup. If you override `SQLITE_DB_PATH`, pass the same path to the MCP installer with `--db`. Full install details: @@ -161,6 +190,7 @@ This is not cosmetic. The readable `nodes` and `chunks` tables are normal SQLite |---------------|---------------|-----------------|--------------| | `openai` | `gpt-4o-mini` | `text-embedding-3-small` | `1536` | | `qwen-local` | `qwen3:4b` through Ollama | `qwen3-embedding:0.6b` through Ollama | `1024` | +| `llama-cpp` | `qwen3-4b` through llama.cpp | `qwen3-embedding-0.6b` through llama.cpp | `1024` | Setup requires one of these commands on a fresh install. @@ -182,7 +212,15 @@ npm run setup:local -- --profile qwen-local npm run dev ``` -If you run setup without a profile and `.env.local` does not already select one, setup stops before creating vector tables and prints the two supported commands. +Local Qwen with llama.cpp: + +```bash +npm install +npm run setup:local -- --profile llama-cpp +npm run dev +``` + +If you run setup without a profile and `.env.local` does not already select one, setup stops before creating vector tables and prints the supported commands. If you change embedding provider, model, dimensions, or vector backend after data exists, your source data stays intact but derived embeddings must be rebuilt: @@ -209,17 +247,17 @@ With a key, you get: Get a key at [platform.openai.com/api-keys](https://platform.openai.com/api-keys) -If you selected `qwen-local`, do not add an OpenAI key in the UI. Settings -> API Keys shows the active local model profile and disables OpenAI key entry so the install stays aligned with the setup profile. +If you selected `qwen-local` or `llama-cpp`, do not add an OpenAI key in the UI. Settings -> API Keys shows the active local model profile and disables OpenAI key entry so the install stays aligned with the setup profile. --- ## Local Model Profile -Use the `qwen-local` setup profile if you want local utility LLM calls and local embeddings. +Use `qwen-local` or `llama-cpp` if you want local utility LLM calls and local embeddings. -RA-H does not bundle model weights. It calls a local OpenAI-compatible HTTP endpoint. The tested local path is Ollama with Qwen. +RA-H does not bundle model weights. It calls local OpenAI-compatible HTTP endpoints. The tested local paths are Ollama with Qwen and llama.cpp with compatible Qwen GGUF files. -Supported local contract: +Supported Ollama contract: ```bash LLM_PROFILE=openai-compatible @@ -232,6 +270,19 @@ EMBEDDING_MODEL=qwen3-embedding:0.6b EMBEDDING_DIMENSIONS=1024 ``` +Supported llama.cpp contract: + +```bash +LLM_PROFILE=openai-compatible +LLM_BASE_URL=http://127.0.0.1:8080/v1 +LLM_MODEL=qwen3-4b + +EMBEDDING_PROFILE=openai-compatible +EMBEDDING_BASE_URL=http://127.0.0.1:8081/v1 +EMBEDDING_MODEL=qwen3-embedding-0.6b +EMBEDDING_DIMENSIONS=1024 +``` + Runtime guides: - [Ollama local profile](./OLLAMA-LOCAL-PROFILE.md) @@ -249,7 +300,7 @@ If you change embedding provider, model, dimensions, or vector backend after dat npm run rebuild:embeddings ``` -Custom model/provider overrides are advanced and not a broad support guarantee. They may work, but the tested product surface is OpenAI plus the narrow local Qwen profile. +Custom model/provider overrides are advanced and not a broad support guarantee. They may work, but the tested product surface is OpenAI plus the narrow local Qwen profiles. --- @@ -285,9 +336,10 @@ By default, setup creates and seeds the SQLite database in your operating system %APPDATA%/RA-H/db/rah.sqlite # Windows ``` -This default applies to both app profiles: +This default applies to all app profiles: - `npm run setup:local -- --profile openai` - `npm run setup:local -- --profile qwen-local` +- `npm run setup:local -- --profile llama-cpp` This is a standard SQLite file. You can: - Back it up by copying the file @@ -536,6 +588,7 @@ See [docs/2_schema.md](./docs/2_schema.md) and [docs/8_mcp.md](./docs/8_mcp.md) |---------|--------------| | `npm run setup:local -- --profile openai` | Rebuild native modules, create `.env.local`, create the SQLite DB, and seed OpenAI-width vector tables | | `npm run setup:local -- --profile qwen-local` | Rebuild native modules, create `.env.local`, create the SQLite DB, and seed Qwen-width vector tables | +| `npm run setup:local -- --profile llama-cpp` | Rebuild native modules, create `.env.local`, create the SQLite DB, and seed Qwen-width vector tables for llama.cpp endpoints | | `npm run setup:local` | Only valid if `.env.local` already selects an embedding profile; otherwise it stops before DB/vector setup | | `npm run bootstrap:local` | Lower-level helper used by `setup:local`; most users should not run this directly | | `npm run rebuild:embeddings` | Recreate derived embeddings after changing embedding provider, model, dimensions, or vector backend | diff --git a/docs/README.md b/docs/README.md index 5dd2c4f..a6ca5a3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -30,7 +30,8 @@ If you just want RA-H OS working: 1. Use the MCP quick install below if you mainly want agent access. 2. Use the OpenAI local app quick start if you want the browser UI with OpenAI models. -3. Use the local Qwen quick start if you want the browser UI with local Ollama models. +3. Use the local Qwen/Ollama quick start if you want the browser UI with local Ollama models. +4. Use the local Qwen/llama.cpp quick start if you want to manage GGUF files and llama.cpp servers yourself. ## MCP Quick Install @@ -56,7 +57,7 @@ npm run dev Open http://localhost:3000 and add your OpenAI API key when prompted, or later in Settings -> API Keys. -## Local App Quick Start: Local Qwen +## Local App Quick Start: Local Qwen/Ollama Requires Ollama to be installed and running. @@ -72,7 +73,30 @@ npm run dev Open http://localhost:3000. Settings -> API Keys shows the active local model profile and disables OpenAI key entry. -Fresh app setup must choose `--profile openai` or `--profile qwen-local` before vector tables are created. OpenAI embeddings use width `1536`; the supported Qwen embedding profile uses width `1024`. +## Local App Quick Start: Local Qwen/llama.cpp + +Requires llama.cpp to be installed, compatible Qwen GGUF files to exist on disk, and separate OpenAI-compatible servers to be running. + +Example servers: + +```bash +llama-server -m /models/qwen3-4b.gguf --port 8080 +llama-server -m /models/qwen3-embedding-0.6b.gguf --embedding --port 8081 +``` + +Then set up RA-H: + +```bash +git clone https://github.com/bradwmorris/ra-h_os.git +cd ra-h_os +npm install +npm run setup:local -- --profile llama-cpp +npm run dev +``` + +Open http://localhost:3000. Settings -> API Keys shows the active local model profile and disables OpenAI key entry. + +Fresh app setup must choose `--profile openai`, `--profile qwen-local`, or `--profile llama-cpp` before vector tables are created. OpenAI embeddings use width `1536`; the supported Qwen embedding profiles use width `1024`. ## MCP Integration diff --git a/scripts/dev/bootstrap-local.mjs b/scripts/dev/bootstrap-local.mjs index 64f13a2..c1f9f17 100644 --- a/scripts/dev/bootstrap-local.mjs +++ b/scripts/dev/bootstrap-local.mjs @@ -8,7 +8,7 @@ import Database from 'better-sqlite3'; const repoDir = process.cwd(); const envTemplate = path.join(repoDir, '.env.example'); const targetEnv = path.join(repoDir, '.env.local'); -const supportedProfiles = new Set(['openai', 'qwen-local']); +const supportedProfiles = new Set(['openai', 'qwen-local', 'llama-cpp']); function log(message) { console.log(`[bootstrap-local] ${message}`); @@ -132,13 +132,16 @@ function normalizeSetupProfile(rawProfile) { if (rawProfile === 'qwen' || rawProfile === 'local' || rawProfile === 'ollama') { return 'qwen-local'; } + if (rawProfile === 'llama' || rawProfile === 'llamacpp' || rawProfile === 'cpp') { + return 'llama-cpp'; + } return rawProfile; } function applySetupProfile(profile) { if (!profile) return; if (!supportedProfiles.has(profile)) { - throw new Error(`Unsupported setup profile "${profile}". Use "openai" or "qwen-local".`); + throw new Error(`Unsupported setup profile "${profile}". Use "openai", "qwen-local", or "llama-cpp".`); } if (profile === 'openai') { @@ -150,12 +153,24 @@ function applySetupProfile(profile) { return; } + if (profile === 'qwen-local') { + ensureEnvValue('LLM_PROFILE', 'openai-compatible'); + ensureEnvValue('LLM_BASE_URL', 'http://127.0.0.1:11434/v1'); + ensureEnvValue('LLM_MODEL', 'qwen3:4b'); + ensureEnvValue('EMBEDDING_PROFILE', 'openai-compatible'); + ensureEnvValue('EMBEDDING_BASE_URL', 'http://127.0.0.1:11434/v1'); + ensureEnvValue('EMBEDDING_MODEL', 'qwen3-embedding:0.6b'); + ensureEnvValue('EMBEDDING_DIMENSIONS', '1024'); + ensureEnvValue('VECTOR_BACKEND', 'sqlite-vec'); + return; + } + ensureEnvValue('LLM_PROFILE', 'openai-compatible'); - ensureEnvValue('LLM_BASE_URL', 'http://127.0.0.1:11434/v1'); - ensureEnvValue('LLM_MODEL', 'qwen3:4b'); + ensureEnvValue('LLM_BASE_URL', 'http://127.0.0.1:8080/v1'); + ensureEnvValue('LLM_MODEL', 'qwen3-4b'); ensureEnvValue('EMBEDDING_PROFILE', 'openai-compatible'); - ensureEnvValue('EMBEDDING_BASE_URL', 'http://127.0.0.1:11434/v1'); - ensureEnvValue('EMBEDDING_MODEL', 'qwen3-embedding:0.6b'); + ensureEnvValue('EMBEDDING_BASE_URL', 'http://127.0.0.1:8081/v1'); + ensureEnvValue('EMBEDDING_MODEL', 'qwen3-embedding-0.6b'); ensureEnvValue('EMBEDDING_DIMENSIONS', '1024'); ensureEnvValue('VECTOR_BACKEND', 'sqlite-vec'); } @@ -175,6 +190,7 @@ function assertEmbeddingProfileSelected(env) { 'Run one of:', ' npm run setup:local -- --profile openai', ' npm run setup:local -- --profile qwen-local', + ' npm run setup:local -- --profile llama-cpp', '', 'If you change embedding provider later, run:', ' npm run rebuild:embeddings',