Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

297 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LLMWikiNG (OKF Edition)

A complete pattern for building and maintaining a personal knowledge base (wiki) following the standardized Open Knowledge Format (OKF) v0.1 (developed by Google Cloud), using local LLMs and agents. Inspired by Andrej Karpathy's LLM-Wiki pattern.

Author: ZeroDot1

A big thank you to tevsa for the great idea and support!


💛 Support this project

I invest a lot of time, money, and passion into the development of LLMWikiNG. Since this project is completely open-source, local, and ad-free, any support — no matter how small — helps me tremendously to continue development and implement new features! If you would like to support my work, feel free to take a look at my Amazon wishlist. Every contribution is greatly appreciated! Thank you!


Instead of searching documents ad-hoc via RAG (Retrieval-Augmented Generation) on every query and regenerating knowledge from scratch each time, this system compiles information once into a structured, cross-linked Markdown wiki. When new sources arrive, the LLM updates existing pages, adds cross-references, and documents contradictions. Knowledge grows and refines continuously.


🏗️ Architecture

The project is built on three layers:

  1. Raw sources (raw/): Immutable original documents (articles, PDFs, notes) that serve as the information base.
  2. The Wiki (wiki/): A collection of LLM-maintained, interlinked Markdown files with a central index (index.md) and a chronological log (log.md).
  3. The CLI & configuration: The control script wiki.sh and the agent configuration .agy.yaml define the workflow and rules for the LLM agent.

🛠️ Features & Commands (wiki.sh)

The CLI script wiki.sh bundles all operations for managing the wiki:

  • ./wiki.sh init – Initializes the folder structure, creates index.md and log.md, and builds the Matrix search index.
  • ./wiki.sh ingest <source-file> – Reads a new source, archives it in raw/, generates an AI summary, creates/updates the wiki page, links it in the index, and records it in the log.
  • ./wiki.sh search "<search-term>" – Performs a token-saving Matrix full-text search (FTS5, JSON output for agents).
  • ./wiki.sh lint – Runs a health check (finds orphaned pages, missing links, incomplete pages).
  • ./wiki.sh sync – Updates the search embeddings for local search and rebuilds the index.
  • ./wiki.sh export <page> – Exports a page for sharing to output_docs/.
  • ./wiki.sh export <page> --pdf – Exports a page as PDF (via weasyprint, optional).
  • ./wiki.sh list – Lists all current wiki pages.
  • ./wiki.sh status – Shows statistics about the wiki, raw sources, and the LLM backend.
  • ./wiki.sh config – Shows the current configuration.
  • ./wiki.sh watcher – Starts the background file watcher (watchdog) for auto-sync on file changes.
  • ./wiki.sh history <page> – Shows the version history of a wiki page (date-based, no Git required).
  • ./wiki.sh update – Performs a self-update via GitHub (git fetch origin && git reset --hard origin/main).
  • ./wiki.sh reset [--yes] – Resets the entire wiki to factory state, deleting all pages, raw data, and exports. Use --yes for non-interactive execution.
  • ./wiki.sh reindex – Rebuilds the BM25 search index.
  • ./wiki.sh --wiki <slug> – Run any command against a specific wiki slug.
  • ./wiki.sh help – Shows the help page with all commands.
  • ./wiki.sh --version – Outputs the current version number.

🌐 Web Interface (run.py / FastAPI)

In addition to the CLI, the project offers a full-featured, extremely performant web interface in a modern Tokyo-Night/Newsroom design:

  • 🏠 Dashboard & Navigation: Overview of all current wiki pages, statistics, and system state.
  • ✍️ Universal Editor (WYSIWYG & Markdown): Integrated dual-mode editor for creating and editing wiki pages and raw sources directly in the browser — with WYSIWYG formatting (bold, italic, lists, quotes, code, links, images) and raw Markdown source mode including YAML frontmatter.
  • 🕸️ Interactive Knowledge Graph: Visualizes all relationships of your pages in a color-coded, dynamic 2D network (fully offline — custom dependency-free Canvas engine, no external libraries). Optimized for large wikis: Lazy Loading (first 200 nodes appear instantly, remaining pages load in the background), Barnes-Hut O(n log n) physics, Viewport Culling, and Level-of-Detail rendering keep the graph smooth even with 1,000+ pages. The graph page features a node search, tag filter bar, node detail panel (connections count + direct page link), stats overlay, zoom buttons, fullscreen mode, and a wiki switcher directly in the toolbar. Fully optimized with a dedicated, lightweight stylesheet (graph.css) resolving layout glitches and size constraints for icon/emoji assets. Contradictions/conflicts are shown in red dashed lines.
  • 📰 Weekly Reports & Email Briefings: Aggregate weekly changes, generate new briefing files in the wiki, and send them securely via the integrated SMTP client to your recipients. Configuration is done via the web interface (saved in config.json) with integrated quick presets for Gmail, ProtonMail Bridge, and Mail.ru.
  • ⏳ Pending Ingest: Shows un-ingested files in raw/ and allows ingesting them individually or as a batch ("Ingest All") via the web interface.
  • 📥 Network & Web Ingest:
    • Web Interface: Convenient upload, URL import, text paste, or URL bookmarking in ingestlater.md.
    • Direct Network Ingest (API): Enables fully automated uploading and immediate processing of source texts, URLs, or files remotely over the network. You can submit documents via curl or client scripts, which then immediately receive AI summaries and are integrated OKF-compliant into the desired wiki.
  • 📤 Export Management: View all exported documents in the browser, read them rendered, or download them directly.
  • 🏷️ Tag Cloud & Wikipedia-Style Tags: Each wiki page displays its tags in a clean, Wikipedia-style category/tags box at the bottom of the article. All tags and inline #hashtags in body content are clickable links leading to the Tag Cloud page (/tags). Tags are automatically generated during ingest and sync if missing, and centrally persisted in data/tags.json. The search page supports tag:name and #name syntax with score boosting.
  • 🔍 Search with Term Highlighting & Tag Syntax: Lightning-fast BM25 search with Cross-Wiki-Search (wiki=all). Supports tag:name and #name inline syntax with tag pills rendered on search results. Tag autocomplete dropdown appears when typing tag:. Shows colored highlights, wiki labels, and supports arrow key navigation.
  • ⬇️ Self-Update: Integrated update function — checks for new GitHub versions and updates itself with one click. Safely backs up all files, wiki pages, raw sources, database registers, and configurations into /tmp beforehand, auto-restoring user data post-update.
  • ⚙️ Settings & Keys Management: Central configuration page with tabs for language selection, Appearance (Dark/Light), AI-Integration (Ollama Endpoint configuration and dynamic AI tool paths opencode, hermes, agy), Wiki Management (create, edit, delete wikis with responsive table view showing page count, file count, total size, and last modified date per wiki), User Management (create, edit, delete users; change name, password, role, active status with self/last-admin lockout protection), API-Key & Per-User MCP-Key Management (with interactive permission editing for tool groups, allowed tools, active status, user assignments, and secure password-based recovery), 🦈 Tailscale & Funnel Integration (same-container One-Click Tailscale setup, Tailnet private access via serve, public HTTPS ingress via funnel, and automated/manual SSL/TLS certificate fetching via tailscale cert for remote MCP/API access by Claude, Grok, Cursor, or AGY), Server-Side Backups (create .tar.xz server backups, restore, download, delete), Interactive MCP Client Configurator (build customized config snippets for Antigravity agy/IDE, OpenCode, and Hermes Agent), SMTP email configuration, health check, and update function.
  • 🛡️ Audit Logging & Data Export: SQLite-based, per-category toggleable logging system recording all security actions (search, ingest, logins, API-keys, MCP-keys, Tailscale operations, backups, pages, wikis). Captures timestamps, usernames, IPs. Admins can search, filter by category/action, and export logs to JSON or CSV. Replaces logbuch entirely.
  • 🔄 Background File Watcher: Optional watchdog-based file watcher (enable_watcher in config.json) that monitors wiki directories for .md changes and triggers incremental sync automatically — no manual intervention needed.
  • 📜 Page Version History: Date-based versioning without Git. Every page save creates a version snapshot (up to 30 per page). Accessible via ./wiki.sh history <page> or through the history service.
  • 📄 PDF Export: Export wiki pages as PDF via ./wiki.sh export <page> --pdf (requires weasyprint). Falls back gracefully if the library is not installed.
  • 🌗 Appearance: The theme (Dark/Light) is changed exclusively in the settings (/settings?tab=theme) and persisted in config.json. Dark mode is the default and is loaded server-side — without a toggle in the sidebar.

Starting the Web Interface:

The web server runs by default on a modern Uvicorn ASGI server (standard post-2026 for maximum performance and competitiveness).

Start the server simply via the starter script:

./start.sh
  • Development mode with live reload: ./start.sh -d
  • Specific port: ./start.sh 9090
  • Set start language: ./start.sh --lang en

Then open http://localhost:8081 (or the assigned port) in your browser.

Server Parameters

The web server (run.py, FastAPI/uvicorn) can be started directly or via start.sh with the following parameters:

Parameter Via start.sh Description
--port, -p PORT ./start.sh 9090 Port (default: 8080). start.sh automatically searches for the next free port.
--host, -H HOST — (always 0.0.0.0) Bind address (default: 0.0.0.0)
--debug, -d ./start.sh -d Debug mode (Uvicorn with live reload)
--lang, -l CODE ./start.sh --lang en Start language (e.g. de, en). Overrides the value from config.json.
--reset ./start.sh --reset Reset server: Irreversibly deletes all wiki pages, raw sources, and exports. Resets the wiki to factory state.
--reset -y ./start.sh --reset -y Perform reset non-interactively (without prompt).

All parameters can also be passed directly to run.py:

python3 run.py --port 9090 --lang en -d

The default language is stored in config.json under the key "language":

{
  "language": "de"
}

If no --lang parameter is passed, the server uses the value from config.json. If that is also missing, German (de) is used as a fallback.

🌐 Web Endpoints (Routes)

All web routes are under the configurable base path /LLMWikiNG (bypassable via LLMWIKI_BASE_PATH, e.g. for example.com/LLMWikiNG/wiki/<Name>/). Multiple wikis are managed under wikis/<name>/; the original wiki/ is automatically moved to wikis/main/ on first start.

  • / – Dashboard: Overview of all wikis + activity.
  • /login, /logout – Login (username + password, signed cookie).
  • /register – User registration (called on first start for setup).
  • /users, /users/<id>/edit, /users/<id>/delete – User management (admin only).
  • /api-keys, /api-keys/<id>/delete – API-key management (admin only).
  • /api-keys/revealAPI-Key Recovery: After password entry, securely decrypts and displays existing keys in the web interface.
  • /wikis/new – Create a new wiki via the web UI.
  • /wiki/<name>/ – Wiki home page (index.md of the wiki).
  • /wiki/<name>/<page> – Rendered Markdown view of a wiki page with backlinks/trail.
  • /wiki/<name>/<page>/export – Copies the page to output_docs/.
  • /wiki/<name>/<page>/delete – Deletes the page.
  • /raw, /raw/<filename> – Raw source management.
  • /pending, /pending/ingest/<filename>, /pending/ingest-all – Pending ingest.
  • /export, /export/<filename> – Export management.
  • /graph – Interactive knowledge graph (custom Canvas engine, no external libs).
  • /graph/data?wiki=<name> – Complete graph data as JSON (cached in-memory).
  • /graph/data/paginated?wiki=<name>&page=0&page_size=200&tag= – Paginated graph data for lazy loading (frontend uses this for wikis of any size).
  • /ingest (GET/POST) – Ingest center (upload, URL notes, batch).
  • /search?q= – BM25 full-text search with match highlighting.
  • /lang/<code> – Language switch (cookie).
  • /about – About page.
  • /admin/status, /admin/sync, /admin/update, /admin/clear-log – Admin tools (sync now with persistent per-wiki SyncStatus JSON).
  • /api/v1/system/health – System health endpoint with SyncStatus data per wiki.
  • /status, /lint, /config, /settings, /briefings – Statistics, linter, SMTP, settings, weekly reports.
  • /edit, /edit/preview, /edit/save – ✍️ Universal editor (WYSIWYG & Markdown).

🔐 Authentication & API

The web interface is password-protected (Argon2 hashes, signed sessions). On first start (when the user database is empty), every request is automatically redirected to /register to create the first user as administrator. Upon registration, a default API key is automatically generated for the user. Although warned that keys are only displayed once, administrators can securely decrypt and view their API keys again at any time under Settings -> API-Keys by verifying their password. After initial setup, self-registration is automatically disabled to protect the system. The administrator can re-enable or disable registration at any time in the Settings (/settings -> checkbox "Allow registration of new users"). Additional users and API keys can be managed directly in the administration.

All functions are also accessible via a JSON API under /LLMWikiNG/api/v1, protected by API keys (X-API-Key header) or session cookies (automatic fallback for the web browser). A key can optionally require that an additional password (X-API-Password) is sent:

Direct Network Ingest via curl:

To ingest a document remotely into the main wiki and sync it with the vector index:

# Upload a Markdown file without requiring a password:
curl -X POST \
  -H "X-API-Key: llmw_dein_api_key_hier" \
  -F "file=@/path/to/document.md" \
  "http://192.168.2.170:8082/LLMWikiNG/wiki/main/api/ingest"
Method Path Protection
GET /api/v1/wikis API key
POST /api/v1/wikis API key (admin)
PUT /api/v1/wikis/<slug> API key (admin)
DELETE /api/v1/wikis/<slug> API key (admin)
GET /api/v1/wikis/<wiki>/pages API key
GET /api/v1/wikis/<wiki>/pages/<slug> API key
GET /api/v1/wikis/<wiki>/tags API key
POST /api/v1/wikis/<wiki>/pages API key (+ scope write)
POST /api/v1/wikis/<wiki>/pages/<slug>/export API key
POST /api/v1/wikis/<wiki>/ingest API key (file upload)
GET /api/v1/wikis/<wiki>/pending API key
POST /api/v1/wikis/<wiki>/ingest/process API key
GET /api/v1/graph?wiki= API key
GET /api/v1/search?q=&wiki= API key
GET /api/v1/stats?wiki= API key
GET /api/v1/lint?wiki= API key
GET /api/v1/status API key
GET /api/v1/system/status API key (admin)
POST /api/v1/system/sync API key (admin)
GET /api/v1/system/audit API key (admin)
GET /audit/export?fmt=json|csv Session / API key (admin log export)
GET /api/v1/system/backups API key (admin)
POST /api/v1/system/backups API key (admin backup create)
POST /api/v1/system/backups/<filename>/restore API key (admin backup restore)
DELETE /api/v1/system/backups/<filename> API key (admin backup delete)
GET /api/v1/system/update/check API key (admin)
POST /api/v1/system/update/run API key (admin)
GET /api/v1/users API key (admin)
POST /api/v1/users API key (admin)
DELETE /api/v1/users/<id> API key (admin)
GET /api/v1/api-keys API key (admin)
POST /api/v1/api-keys API key (admin)
DELETE /api/v1/api-keys/<id> API key (admin)
GET /api/v1/mcp-keys API key (admin)
POST /api/v1/mcp-keys API key (admin create per-user MCP key)
PUT /api/v1/mcp-keys/<id> API key (admin edit per-user MCP key)
DELETE /api/v1/mcp-keys/<id> API key (admin revoke per-user MCP key)
POST /wiki/<wiki>/api/ingest API key (direct ingest for a specific wiki)
POST /wiki/<wiki>/api/sync API key (direct sync for a specific wiki)
GET /mcp/sse MCP API key (SSE channel for AI agents)
POST /mcp/messages MCP API key (JSON-RPC SSE message channel)
POST /mcp MCP API key (Streamable HTTP JSON-RPC channel)

Example:

curl -H "X-API-Key: llmw_xxx" http://localhost:8080/LLMWikiNG/api/v1/wikis

✍️ Integrated Editor

The web server has an integrated, split editor:

  • WYSIWYG mode: Enables comfortable writing with direct visual formatting (bold, italic, lists, quotes, horizontal rules, links, images, inline code) completely without external JS libraries (pure HTML5 ContentEditable).
  • Markdown mode: Offers the ability to edit the Markdown source including YAML frontmatter directly.
  • Folder switch: The editor automatically loads and saves files in the appropriate directory (either wiki/ for active pages or raw/ for drafts), based on the current mode.

🌗 Appearance (Theme)

The appearance (Dark/Light) is controlled exclusively in the settings and persisted in config.json ("theme": "dark" or "light"). Dark mode is the default and is loaded server-side from config.json — there is deliberately no toggle button in the sidebar or header (no flash/FOUC).

  • Change theme: Settings → Appearance (tab theme) → choose Dark/Light.
  • Directly via API: POST /LLMWikiNG/theme/set (form field value=dark|light, login required).
  • Restore default: Set the "theme" entry in config.json to dark.

🦈 Tailscale & Funnel Integration

LLMWikiNG includes a same-container Tailscale daemon integration for One-Click setup of private VPN connections (Tailscale Serve) and public HTTPS access (Tailscale Funnel). This allows remote AI agents (Claude, Grok, Cursor, AGY) and mobile users to access LLMWikiNG & MCP endpoints from anywhere without port forwarding, NGINX, or CGNAT issues.

🌟 Key Capabilities

  • Same-Container Architecture: Runs tailscaled daemon directly inside the LLMWikiNG Docker container (no sidecar container required).
  • One-Click Setup: Go to Settings ➜ Tailscale, enter your Auth-Key (tskey-auth-...), set your preferred hostname (default: zerodot1sllmwiking), check Funnel, and click "Setup Everything".
  • Tailnet Serve (Private): Securely proxies HTTPS traffic within your private Tailnet to local port 8080.
  • Tailscale Funnel (Public): Exposes your LLMWikiNG instance to the public internet under https://<hostname>.<tailnet>.ts.net with valid Tailscale HTTPS certificates. Access control remains enforced via session login, API Keys, and per-user MCP Keys.
  • Encrypted Storage & Security: Auth keys are encrypted with system secrets in data/tailscale.json (chmod 0o600). Key reveal requires admin password authentication.
  • Audit Logging: Every Tailscale operation (tailscale_setup, tailscale_save, tailscale_up, tailscale_down, tailscale_apply, tailscale_reset, tailscale_reveal) is logged under the tailscale category.

🐳 Docker & Docker Compose Setup

Ensure your docker-compose.yml mounts /dev/net/tun and grants networking capabilities:

services:
  llmwiking:
    build: .
    container_name: llmwiking_app
    hostname: zerodot1sllmwiking
    ports:
      - "8082:8080"
    environment:
      - PORT=8080
      - HOST=0.0.0.0
      - TS_STATE_DIR=/var/lib/tailscale
      - TS_SERVE_CONFIG=/config/tailscale/serve.json
      - TS_HOSTNAME=zerodot1sllmwiking
    volumes:
      - ./data:/app/data
      - ./wikis:/app/wikis
      - ./ts-data:/var/lib/tailscale
      - ./ts-config:/config/tailscale
      - /dev/net/tun:/dev/net/tun
    cap_add:
      - NET_ADMIN
      - NET_RAW
    devices:
      - /dev/net/tun:/dev/net/tun

🤖 Remote Agent Access Snippet (Claude / Cursor / AGY)

Once Funnel is active, configure your AI agent with your public Tailscale URL:

{
  "mcpServers": {
    "llmwiking": {
      "url": "https://zerodot1sllmwiking.<your-tailnet>.ts.net/LLMWikiNG/mcp",
      "headers": {
        "X-MCP-Key": "mcp_...",
        "X-API-Key": "llmw_..."
      }
    }
  }
}

🤖 Model Context Protocol (MCP) & Open Knowledge Format (OKF)

LLMWikiNG natively implements the Open Knowledge Format (OKF v0.1) for AI-assisted knowledge allocation. All pages are saved as open, portable Markdown files with standardized YAML frontmatter. This ensures complete human readability and prevents proprietary vendor lock-in.

📘 Full MCP integration guide: See the in-wiki page LLMWikiNG MCP Server — Integration & Tool Reference for a complete per-tool reference (47 tools) and copy-paste client setups for Cursor, OpenCode, Claude Desktop, and Antigravity agy.

🔌 Enable & Configure MCP Server

The MCP server is enabled by default. You can configure it in two ways:

  1. Via Web UI (Recommended): Go to Settings ➜ MCP in the Web interface, toggle the server activation state, and define your API Key. This persists settings in config.json.
  2. Via Environment Variables: Set the following variables in your environment before startup:
# Enable MCP (Default: true)
ENABLE_MCP_SERVER=true

# Set API Key for AI Agents
LLMWIKING_MCP_KEY=your_secure_mcp_key_2026

Restart the application. The server now exposes two endpoints:

  • SSE Channel: http://localhost:8080/LLMWikiNG/mcp/sse
  • Streamable HTTP Endpoint: http://localhost:8080/LLMWikiNG/mcp
  • Message Channel: http://localhost:8080/LLMWikiNG/mcp/messages

💻 Client Integration (Cursor, OpenCode & Antigravity agy)

The LLMWikiNG MCP server can be used by any standard MCP client. Here are the configuration details for supported environments:

1. Cursor

Add a new server in Cursor under Settings → Features → MCP:

Field Value
Name LLMWikiNG-OKF
Type SSE
URL http://localhost:8080/LLMWikiNG/mcp/sse
Headers {"X-MCP-Key": "your_secure_mcp_key_2026", "X-API-Key": "your_database_api_key"}

2. OpenCode

Add the MCP server under the "mcp" key in your global (~/.config/opencode/opencode.json) or project-level (opencode.json in project root) configuration file:

{
  "mcp": {
    "llmwiking-okf": {
      "type": "remote",
      "url": "http://localhost:8080/LLMWikiNG/mcp/sse",
      "enabled": true,
      "environment": {
        "X-MCP-Key": "your_secure_mcp_key_2026",
        "X-API-Key": "your_database_api_key"
      }
    }
  }
}

Alternatively, add the server interactively via the terminal:

opencode mcp add
🎯 OpenCode Slash Commands (.opencode/command/)

For / autocomplete in OpenCode's chat, copy the .opencode/command/ directory from this project into your project:

# In deinem Projekt mit OpenCode:
cp -r pfad/zu/LLMWikiNG/.opencode/command/ .opencode/command/

After restarting OpenCode, type / in chat to see all 44 LLMWikiNG commands:

Command Description
/wikis Alle Wikis auflisten
/read Wiki-Seite lesen
/write Wiki-Seite erstellen
/search Volltextsuche
/status Systemstatus anzeigen
/update / /update-lwk System-Update ausführen
/user-edit Benutzer bearbeiten
/tailscale-status Tailscale-Status anzeigen
… und 35 weitere

Note: OpenCode loads MCP Prompts (via list_prompts) as AI hints, but does not show them in the / chat autocomplete by default. Use the .opencode/command/ files above for native /-support.

3. Antigravity CLI (agy) & Antigravity IDE

Both the agy CLI tool and the Antigravity IDE can consume global or local MCP servers.

Add the configuration to your global MCP configuration file ~/.gemini/config/mcp_config.json (or workspace-specific under .agents/mcp_config.json):

{
  "mcpServers": {
    "llmwiking-okf": {
      "type": "http",
      "url": "http://localhost:8080/LLMWikiNG/mcp",
      "headers": {
        "X-MCP-Key": "your_secure_mcp_key_2026",
        "X-API-Key": "your_database_api_key"
      }
    }
  }
}

The configured tools will then be automatically available to the agent inside agy.

Important

Security Recommendation: It is highly recommended to create a dedicated, low-privilege user account and a specific API key for each AI agent/client (in the WebUI under Settings ➜ Users / Keys) instead of sharing main administrator credentials or using the global config key. Additionally, you can create per-user MCP keys with fine-grained tool permissions under Settings ➜ Keys ➜ MCP Keys. Each MCP key is tied to a specific user and can be restricted to a subset of tools (e.g., read-only access). This ensures clean, isolated audit logs and sensible permission boundaries for each agent.

💬 Copy-Paste AI Configuration Prompt

You can copy and paste the following instruction directly into your AI assistant (e.g., Cursor Chat, Claude Code, OpenCode, or agy) to tell it to configure itself:

Please configure yourself to connect to the LLMWikiNG MCP server. The server uses Streamable HTTP at URL: http://localhost:8080/LLMWikiNG/mcp (or SSE at http://localhost:8080/LLMWikiNG/mcp/sse). You must include the headers 'X-MCP-Key' set to '<YOUR_MCP_SERVER_KEY>' and 'X-API-Key' set to '<YOUR_AGENT_API_KEY>'. In OpenCode, add it under the 'mcp' section in your config file. In Antigravity (agy), add it under the 'mcpServers' object in your ~/.gemini/config/mcp_config.json file with type 'http' and URL 'http://localhost:8080/LLMWikiNG/mcp'.

📋 Available MCP Tools (47 Tools)

Tool Description
okf_list_wikis Lists all wikis with metadata
okf_create_wiki Creates a new wiki (updates metadata if slug exists)
okf_update_wiki Edits name/description/slug of a wiki
okf_delete_wiki Deletes a wiki (except main)
okf_list_pages Lists all pages in a wiki (supports type filtering and pagination)
okf_read_concept Reads an OKF concept (frontmatter + markdown)
okf_write_concept Creates/updates an OKF concept
okf_delete_page Deletes a wiki page
okf_export_page Exports a page to output_docs/
okf_list_pending Lists raw sources waiting for ingest
okf_process_pending Processes all pending raw sources
okf_ingest_text Ingests raw text into a wiki
okf_search Full-text search across wiki pages
okf_wiki_stats Shows wiki statistics
okf_graph Visualizes the knowledge graph
okf_lint Runs a wiki health check (orphans, tag checks, word count, and cross-linking suggestions)
okf_read_raw Reads a raw source from raw/
okf_list_raw Lists all raw source files
okf_system_status Shows system status
okf_system_sync Synchronizes wikis
okf_audit_logs Shows system audit logs (supports pagination via limit/offset)
okf_cache_stats Shows cache statistics
okf_cache_clear Clears the cache
okf_list_users Lists all users
okf_create_user Creates a user
okf_update_user Edits a user (name, password, role, active status)
okf_delete_user Deletes a user
okf_list_api_keys Lists all API keys
okf_create_api_key Creates an API key
okf_delete_api_key Deletes an API key
okf_list_mcp_keys Lists all per-user MCP keys
okf_create_mcp_key Creates a per-user MCP key with tool permissions
okf_delete_mcp_key Deletes a per-user MCP key
okf_list_backups Lists available server backups
okf_create_backup Creates a new server backup
okf_restore_backup Restores a server backup
okf_check_update Checks for update via Git
okf_run_update Runs the system update
okf_tailscale_status Shows Tailscale status & configuration
okf_tailscale_save Saves the Tailscale configuration
okf_tailscale_setup Runs the Tailscale one-click setup (up + serve/funnel)
okf_tailscale_apply Applies the Tailscale serve/funnel configuration
okf_tailscale_cert Requests the HTTPS certificate via tailscale cert
okf_tailscale_reset Resets Tailscale funnel & serve

⚡ MCP Prompts — Slash Commands (46 Total)

MCP Prompts enable slash-command autocomplete in supporting clients (AGY, OpenCode, Cursor, Claude Code). Every MCP tool has its own slash command — 46 in total.

Client support:

  • AGY / Claude Code: Support list_prompts natively — slash commands appear in autocomplete.
  • OpenCode: Uses .opencode/command/ files for / autocomplete. Copy the command/ folder from this project (see section above) or the MCP tools are still available for the AI to call directly.
  • Cursor: Does not support slash commands via MCP prompts. Use MCP tools directly.
  • Other clients: Call the underlying MCP tools directly (e.g. okf_run_update() instead of /update).

📚 Wiki Management

Slash Command Arguments Maps to
/wikis okf_list_wikis()
/wiki-create <name> [slug] [desc] okf_create_wiki()
/wiki-update <wiki> [name] [desc] [new_slug] okf_update_wiki()
/wiki-delete <wiki> okf_delete_wiki()

📄 Page Management

Slash Command Arguments Maps to
/pages [wiki] [type_filter] okf_list_pages()
/read <slug> [wiki] okf_read_concept()
/write <slug> <title> <content> [wiki] okf_write_concept()
/page-delete <slug> [wiki] okf_delete_page()
/export <slug> [wiki] okf_export_page()
/pending [wiki] okf_list_pending()
/ingest [wiki] okf_process_pending()
/ingest-text <text> [wiki] [title] okf_ingest_text()

🔍 Search & Analysis

Slash Command Arguments Maps to
/search <query> [wiki] okf_search()
/stats [wiki] okf_wiki_stats()
/graph [wiki] okf_graph()
/lint [wiki] okf_lint()

📦 Raw Sources

Slash Command Arguments Maps to
/raw-list okf_list_raw()
/raw-read <filename> okf_read_raw()

⚙️ System

Slash Command Arguments Maps to
/status okf_system_status() + okf_cache_stats() + okf_check_update()
/sync [wiki] okf_system_sync()
/audit [limit] [action] [username] okf_audit_logs()
/cache okf_cache_stats()
/cache-clear okf_cache_clear()

👥 Users

Slash Command Arguments Maps to
/users okf_list_users()
/user-create <username> <password> [role] okf_create_user()
/user-delete <username> okf_delete_user()

🔑 API & MCP Keys

Slash Command Arguments Maps to
/api-keys okf_list_api_keys()
/api-key-create <name> okf_create_api_key()
/api-key-delete <key_id> okf_delete_api_key()
/mcp-keys okf_list_mcp_keys()
/mcp-key-create <name> [allowed_tools] okf_create_mcp_key()
/mcp-key-delete <key_id> okf_delete_mcp_key()

📦 Backups

Slash Command Arguments Maps to
/backups okf_list_backups()
/backup okf_create_backup()
/restore <filename> okf_restore_backup()

⬇️ Update

Slash Command Arguments Maps to
/check-update okf_check_update()
/update, /update-lwk, /updatelwk okf_check_update() + okf_run_update()

📄 OKF v0.1 Document Format

Every wiki page follows the Open Knowledge Format:

---
type: Concept
title: MCP Architecture 2026
description: Technical specification of the SSE-based protocol
tags: [backend, mcp, security]
timestamp: 2026-07-18T16:43:00Z
updated: 2026-07-29T12:40:00Z
updated_by: web
content_hash: a3f2c1d4e5b6f789
author: Agent (Cursor-Dev)
status: AI-Generated
---

# MCP Architektur 2026

Hier beginnt der freie, menschenlesbare Markdown-Textkörper.

content_hash – SHA-256 of the page body (first 16 hex chars), updated on every save by all write paths (Web Editor, MCP okf_write_concept, API). Enables conflict detection: if the stored hash differs from the incoming content, the write is rejected with an error prompt.

updated_by – Records the write source: web (browser editor), mcp (AI agent), cli (wiki.sh).


🚀 Getting Started

1. Install Prerequisites

Make sure the following tools are installed on your system:

  • bash, ripgrep (rg), jq
  • Python 3.11+ with aiosqlite (Matrix full-text search, no external search binary required)
  • Ollama (for local summaries, by default with llama3.2:3b)

2. Initialize the Wiki

Run the following command in the project directory:

chmod +x wiki.sh
./wiki.sh init

3. Add a Source (Ingest)

./wiki.sh ingest path/to/your/note.md

4. Reset Server & Workspace (Factory State)

To reset the entire wiki to its shipped state and irreversibly delete all personal pages, raw data, and exports:

Via CLI (wiki.sh):

./wiki.sh reset              # Requires manually typing 'RESET' to confirm
./wiki.sh reset --yes        # Performs the reset non-interactively (without prompt)

Via server starter (start.sh):

./start.sh --reset           # Requires manually typing 'RESET' to confirm
./start.sh --reset -y        # Performs the reset non-interactively (without prompt)

The reset deletes all files in wiki/, raw/, and output_docs/ and recreates index.md and log.md OKF-compliant. The Matrix search index (data/matrix/) is also reset.


🚀 FastAPI Backend (full port of llmWiki.py)

The entire application runs completely on FastAPI (no more Flask). The original Flask web server llmWiki.py has been removed; all routes, services, and template helpers have been ported 1:1 to FastAPI. The existing Jinja2 templates are still used.

Starting

pip install -r requirements.txt
./start.sh                 # or: python3 run.py --port 8080

Structure

run.py                      # Entry point (adds backend/ to path, calls main.main)
backend/
├── main.py                 # create_app() + main() (argparse, uvicorn), mounts all routers + MCP
├── web.py                  # Jinja2Templates, render(), abort/redirect, base_context()
├── core/
│   ├── config.py           # BASE_PATH, paths, multi-wiki, i18n, MCP-Config
│   ├── security.py         # Argon2 hashing, signed sessions, API-key management
│   └── storage.py          # JSON store for users & API keys (data/)
├── api/
│   ├── deps.py             # get_current_user, require_login, require_admin, get_api_user
│   └── routes/
│       ├── pages.py        # ALL HTML routes (under BASE_PATH)
│       ├── auth.py         # /login, /logout, /users, /api-keys
│       ├── api.py          # /api/v1/* (JSON, key-protected)
│       └── mcp.py          # MCP-Server (OKF v0.1, SSE-Transport, 47 Tools)
└── services/               # wiki, markdown, search, sync, graph, lint,
                            #   analytics, editor, email_sender (all multi-wiki capable)
templates/                  # Jinja2 templates (Tailwind v4, responsive, dark mode)
static/                     # static assets (css/tailwind-build.css, js/*, graph engine)
wikis/<name>/               # multi-wiki storage (wiki/ → wikis/main/ on migration)
data/                       # users.json, api_keys.json, mcp_keys.json

Frontend (Tailwind CSS v4)

The CSS is built via a CSS-first pipeline (Tailwind v4, @theme with oklch design tokens, dark mode, container-capable):

cd frontend && npm install && npm run build   # produces static/css/tailwind-build.css

base.html includes exclusively static/css/tailwind-build.css; all JS is located as ES modules under static/js/ (app.js, navigation.js, auth.js, editor.js, graph.js …).

🐋 Docker & UGreen NAS Deployment

The project provides direct support for Docker and is explicitly optimized for UGreen NAS (UGOS) to ensure out-of-the-box compatibility.

UGreen NAS (UGOS) Setup

When importing the exported image into the UGreen Container Manager, the system automatically detects the pre-defined volumes from the Dockerfile and maps them correctly under volume1/docker/llmwiking:

  • /app/data -> /volume1/docker/llmwiking/data (user & API-key databases)
  • /app/wikis -> /volume1/docker/llmwiking/wikis (all wiki directories)
  • /app/raw -> /volume1/docker/llmwiking/raw (unprocessed sources)
  • /app/output_docs -> /volume1/docker/llmwiking/output_docs (exported documents)

To run it via Docker Compose on your UGreen NAS, the default paths in docker-compose.yml are pre-configured to point directly to these directories.

Local Development / Alternative Host Setup

If you want to build and run the Docker container locally on another host system, you can use the configurable environment variable DOCKER_VOLUME_BASE in the docker-compose.yml.

  1. Create a local .env file in the project root:
    DOCKER_VOLUME_BASE=.
  2. Run your compose setup:
    docker compose up --build

This will mount the files and folders relative to the current project directory (preventing directory-over-file mount issues with config.json on local hosts).

⚙️ Configuration

The settings of the LLM backend can be controlled via environment variables or stored directly in the configuration .agy.yaml:

# Example: use a different model or backend
LLM_BACKEND=ollama OLLAMA_MODEL=llama3.2:3b ./wiki.sh ingest file.md
  • LLM_BACKEND: ollama, agy, or opencode (default: ollama)
  • OLLAMA_MODEL: The model to use (default: llama3.2:3b)

🔑 The Cryptographic Secret (secret_key in config.json)

The system uses a central password (the secret) to secure your login sessions (session cookies) and to store your API keys encrypted in the database.

The secret is automatically generated upon the first administrator creation and saved persistently in the config.json file (under the key secret_key). It is loaded exclusively from config.json, ensuring consistency across container rebuilds and server restarts.

To view or rotate this secret, log in as an administrator, navigate to Settings -> Backup & Restore, enter your password, and select either:

  • Reveal: To display the active secret in plain text.
  • Regenerate: To securely generate and persist a new random system secret.

Warning

If you rotate the secret, already generated API keys can no longer be decrypted and active user sessions are terminated.

📋 Steps to follow after changing the secret:

  1. Re-Login: All active sessions are immediately invalidated. You will be redirected to the login page. Log back in with your username and password.
  2. Recreate API Keys: Go to Settings -> API-Keys. Your old keys will show decryption errors since they were encrypted with the old secret. Click "🗑️ Alle API-Keys löschen" or "🗑️ Alle MCP-Schlüssel löschen" (confirming with your password) and create new ones.
  3. Update Client Scripts: Update any scripts, cron jobs, or curl integrations that query the API with the newly generated API keys.
  4. Restore Existing Installations: If you updated a running installation that used a different secret in docker-compose.yml, copy the old secret string and paste it into config.json under "secret_key" (or reveal the new secret in the WebUI and recreate your API keys).

📦 Self-Update

The project contains an integrated update function:

./update.sh            # Full self-update from GitHub
./update.sh --check    # Only check if an update is available
./wiki.sh update       # Update via CLI

The update script (Git-based):

  • Creates an automatic backup before the update
  • Runs git fetch origin and resets to origin/main (git reset --hard)
  • Automatically stashes local changes (if needed: git stash pop)
  • Protects wiki pages (wiki/), raw sources (raw/), exports (output_docs/), SMTP configuration (config.json), and LLM settings (.agy.yaml)
  • Shows the entire update history in the log

⚡ Projekt Matrix – Persistente Volltextsuche

Since v3.0.0 LLMWikiNG ships a persistent full-text index built on SQLite shards (FTS5) as its primary search engine (no external search binary required). Documents are distributed over 256 shards (<wiki>_shard_NNN.db) under data/matrix/, tracked centrally in data/matrix/registry.db. All writes run sequentially through an asyncio worker with NAS-safe PRAGMAs (WAL, synchronous=FULL, busy_timeout=5000) so the index stays intact on network shares (e.g. a UGreen NAS).

Activation

Add the feature flag to config.json (the matrix block is optional, values shown are the defaults):

{
  "enable_matrix": true,
  "matrix": {
    "shards": 256,
    "max_concurrent_reads": 32,
    "write_batch_size": 16,
    "sqlite_journal_mode": "WAL",
    "sqlite_synchronous": "FULL",
    "sqlite_mmap_size": 0,
    "sqlite_busy_timeout": 5000
  }
}

The index lives under data/matrix/ and therefore persists across container recreations. Environment overrides: MATRIX_DATA_ROOT, MATRIX_SHARDS, MATRIX_MAX_CONCURRENT_READS.

Bootstrap

Build the index for all wikis (or a single wiki):

./wiki.sh matrix-rebuild            # all wikis
./wiki.sh --wiki main matrix-rebuild
python3 scripts/bootstrap_matrix.py [--wiki <slug>]

Once enabled, file watchers index changes incrementally and /search (UI + API + MCP) serves results from the matrix index, falling back to the legacy local search.

API endpoints (under ${BASE}/api/v1/matrix)

Method Path Description
GET / POST /search?q=...&wikis=main&limit=30 Full-text search with FTS5 ranking, optional tag filter
POST /ingest Queue a document for indexing (202)
POST /ingest/bulk Queue multiple documents
DELETE /document/{wiki_id}/{doc_id} Remove a document (admin)
GET /stats Shard count, index size, queue, rebuild progress
GET /health Registry + shard readability probe
POST /rebuild?wiki_id=all Full background re-index (admin)
POST /prune Remove registry entries whose files are gone (admin)

MCP tools: okf_matrix_search (wiki_read) and okf_matrix_ingest (wiki_write).


⚖️ License

This project was created by ZeroDot1 and is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). You may copy, modify, and distribute the code, but must ensure that when provided over a network (Software as a Service), the modified source code is made available to users free of charge.

Special thanks to tevsa for the great idea and support in realizing this project. See the LICENSE file for more details.

About

LLMWikiNG is a local, privacy-friendly wiki platform developed by ZeroDot1 and based on the Karpathy LLM Wiki Pattern. The wiki is maintained and expanded by AI assistants—and you can easily read, search, and manage it right in your browser.

Topics

Resources

Stars

19 stars

Watchers

0 watching

Forks

Contributors

Languages