kiwiki
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@kiwikisearch my notes for meeting agenda"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
kiwiki
kiwiki is a self-hosted Agent Harness and Markdown knowledge base for humans and AI agents. Notes stay as regular files on disk, the web UI gives you a searchable wiki, and the built-in MCP server lets tools such as Claude Code, Codex, OpenCode, Cursor, ChatGPT, OpenClaw, Hermes, and any MCP client read and write the same knowledge base in parallel.
No hosted account is required. Your Markdown files are the source of truth.
Visit kiwiki.xyz for the project website, FAQ, agent integration guides, and hosting options.
Screenshots



Related MCP server: Bruin
Features
Multi-Agent Harness — Central knowledge base for Claude Code, Codex, OpenCode, Cursor, ChatGPT, OpenClaw, Hermes, and any MCP-compatible agent. All agents read and write the same wiki in parallel.
Markdown files with YAML frontmatter — Your file system is the source of truth. No proprietary database, no vendor lock-in, simple to back up.
100 % privacy — Self-hosted on your infrastructure. No cloud, no telemetry, no vendor lock-in.
Per-user isolated wiki folders under
/data/<username>/with role-based access (read/write/admin).SQLite FTS5 full-text search — Search thousands of Markdown files in milliseconds, including via MCP from your AI. Special prefix
tag:<value>filters by tag.Responsive web UI — FastAPI with Jinja2, HTMX, and Toast UI Editor. Works from 4K desktop to mobile, with WCAG 2.2 AA-oriented accessibility (see docs/ui-accessibility.md).
Streamable HTTP MCP endpoint at
/mcp(legacy HTTP/SSE at/mcp/sse) with OAuth 2.1 authorization-code flow for ChatGPT-style connectors.Docker Compose and Helm — One command to start. Kubernetes-ready.
Highlights in v3.0
Hardened authentication and sessions: API keys are compared in constant time and are never persisted in browser sessions; stored session tokens are hashed and revoked after user or role changes.
Conflict-safe storage: Atomic writes, revision checks, protected internal paths and per-user file/byte quotas protect Markdown data under concurrent agent access.
Hardened MCP and OAuth: PKCE-bound signed tokens, authenticated SSE sessions, bounded queues/uploads/batches, redacted audit logs and safe Git operations.
Accessible responsive UI: Native navigation semantics, stable note deep links and titles, inert mobile sidebar, visible keyboard focus, pinch zoom and a non-overlapping mobile editor.
Self-hosted frontend: HTMX, Toast UI Editor and fonts are vendored with the application; pages no longer depend on third-party CDNs.
Production diagnostics:
/livezand dependency-aware/readyz, request IDs, latency logs and version reporting are wired into Docker, Compose and Helm.
Quick Start
git clone https://github.com/natorus87/kiwiki.git
cd kiwiki
cp .env.example .env
# Replace every <...> placeholder in .env with a random secret first.
docker compose up -dOpen the web UI:
http://localhost:8082Use the API key configured in KIWIKI_USERS.
Configuration
All runtime configuration is done through environment variables.
Variable | Default | Description |
|
| Data directory for all wiki files |
| required | Built-in users in |
| request URL | Public base URL used in MCP and OAuth metadata; derived from the request when empty |
|
| Python log level |
|
| Trust forwarding headers and use secure cookies behind a TLS reverse proxy |
| empty | Trusted proxy networks allowed to supply |
| empty | Comma-separated list of allowed CORS origins; empty disables cross-origin access |
|
| Enables login, read, and write rate limits |
|
| Login/OAuth write attempts per minute and client IP |
|
| Authenticated write requests per minute and client IP |
|
| Authenticated read requests per minute and client IP |
|
| Web-session lifetime; sessions are stored hashed and revoked after user/role changes |
|
| Maximum Markdown files per user workspace |
|
| Maximum total Markdown bytes per user workspace |
|
| Maximum entries returned by one directory listing |
|
| Maximum entries returned by recursive listings |
| derived by app | Stable OAuth signing secret; explicitly required by the bundled Compose and Helm deployments |
|
| OAuth access-token lifetime |
|
| OAuth refresh-token lifetime |
| ChatGPT hosts | Additional comma-separated OAuth redirect hosts; HTTPS or loopback only |
|
| Maximum pending OAuth authorization codes per process |
|
| Maximum dynamically registered OAuth clients per process |
|
| Inactive dynamic-client lifetime |
|
| Maximum redirect URIs per dynamic client |
|
| Maximum simultaneous legacy SSE sessions |
|
| Maximum queued messages per legacy SSE session |
|
| Lifetime of incomplete staged uploads |
|
| Maximum assembled bytes per staged upload |
|
| Maximum chunks per staged upload |
|
| Maximum staged chunked uploads per process |
|
| Maximum aggregate bytes held by staged uploads |
Example:
KIWIKI_DATA_DIR=/data
KIWIKI_USERS=admin:<admin-api-key>:admin,writer:<writer-api-key>:write,reader:<reader-api-key>:read
KIWIKI_BASE_URL=https://kiwiki.example.com
KIWIKI_TRUST_PROXY=true
KIWIKI_TRUSTED_PROXY_CIDRS=172.16.0.0/12
KIWIKI_CORS_ORIGINS=https://kiwiki.example.com
KIWIKI_OAUTH_TOKEN_SECRET=<random-token-signing-secret>Generate strong keys with:
openssl rand -hex 24Do not commit real API keys, OAuth secrets, .env files, or local wiki data.
User Model
Each user gets a separate wiki root:
/data/admin/
/data/alice/
/data/bob/Users cannot read or search another user's files. Web UI requests, REST API calls, search, and MCP tools all run in the authenticated user's namespace.
Roles:
Role | Permissions |
| Read files and search |
| Read plus create, edit, move, and reindex |
| Full access, including delete and user management |
ChatGPT and MCP
kiwiki exposes MCP over Streamable HTTP:
https://kiwiki.example.com/mcpFor ChatGPT custom connectors, configure the MCP endpoint as the connector URL. If OAuth is enabled, ChatGPT discovers:
/.well-known/oauth-protected-resource/mcp
/.well-known/oauth-authorization-server/mcpThe OAuth flow uses:
Authorization code with PKCE
Signed access tokens
Refresh tokens
The
resourceparameter expected by MCP clientsClient ID Metadata Document style client IDs used by ChatGPT
For public deployments, set a stable KIWIKI_OAUTH_TOKEN_SECRET. This keeps connector tokens valid across container restarts while still allowing API-key rotation to revoke access.
Direct bearer-token access is also supported:
curl https://kiwiki.example.com/mcp \
-H "Authorization: Bearer <api-key>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'Usage as AI Memory
Configure your AI tools to use kiwiki as persistent memory. The following instruction works for ChatGPT (Custom Instructions → Personalization), Claude (Personalization), and coding agents:
Use kiwiki as my persistent memory. When asked about projects, decisions, recurring topics, personal preferences, or work context, first briefly check kiwiki. Use existing notes as context.
Save new important information in kiwiki when it might be useful later: preferences, decisions, project knowledge, workflows, important facts, and open items. Prefer to update existing files rather than creating new ones. Organize according to the existing structure:
/projects,/decisions,/notes,/sharedand/user. Write short Markdown notes with frontmatter. Do not delete anything without explicit instruction. Also ask in longer chats whether you should save something.
For coding agents (Claude Code, Codex, OpenCode, Cursor), add this instruction to your project's AGENTS.md, CLAUDE.md, or equivalent configuration file.
Agent Harness Setup
When using kiwiki as the Agent Harness for your project, instruct coding agents to connect to kiwiki via MCP. Add the following block to your project's AGENTS.md or CLAUDE.md:
This project uses kiwiki as its Agent Harness and persistent memory.
MCP connection — Connect to the kiwiki MCP server using the appropriate command for your tool:
Claude Code:
claude mcp add kiwiki http://localhost:8082/mcp --header "Authorization: Bearer <api-key>"Codex:
codex mcp add kiwiki http://localhost:8082/mcp --header "Authorization: Bearer <api-key>"OpenCode: configure MCP server in opencode.json
Cursor: configure MCP server in
.cursor/mcp.jsonOnce connected, use kiwiki as persistent memory (see usage instruction above).
This ensures every coding agent working on the project automatically connects to the shared knowledge base.
MCP Tools
The MCP server exposes tools for common wiki workflows, grouped by required role:
Read (any role)
read_index · list_files · read_file · fetch · search · read_many · list_all_files · grep · find · file_info · read_lines · recent_files · backlinks · preview_edit · validate_wiki · related_files · tag_index · search_status · whoami · file_history · diff · statistics · validate_links · link_graph · export · duplicate_check · ai_summarize · search_history · dead_link_check · grep_status
Write (write role or admin)
write_file · append_file · write_many · chunked_write · create_note · move_file · edit · update_frontmatter · build_index · sort · move_folder · replace_many · upsert_note · reindex_all · git_commit · template · rename · batch_tag
For autonomous agents, prefer write_many when updating several files and chunked_write when a large file or flaky client payload limit makes a single write_file / append_file call unreliable. Ordinary create, update, append, and index-refresh operations do not require confirmation; clients should ask before deleting files or running destructive reorganizations. chunked_write keeps temporary chunks in process memory for KIWIKI_MCP_UPLOAD_TTL_SECONDS (default 3600) and limits each upload with KIWIKI_MCP_MAX_UPLOAD_BYTES (default 10485760) and KIWIKI_MCP_MAX_UPLOAD_CHUNKS (default 1000); aggregate staging is additionally capped by KIWIKI_MCP_MAX_STAGED_UPLOADS and KIWIKI_MCP_MAX_STAGED_BYTES.
Admin (admin role only)
delete_file
The server exposes 49 tools. JSON-RPC batches are limited to 25 requests, list-valued tool arguments to 50 entries, and OAuth authorization codes expire after five minutes.
Keyboard Shortcuts
Shortcut | Action | Notes |
| First focus reveals the Skip-Link, then header → sidebar → content | Available on every page |
| Close mobile sidebar, search dropdown, account menu, modal, or context menu | Auto-detects open layer |
| Save current note in Editor | Also works from the FAB on mobile |
| Delete active file (admin) / folder | Pressed consecutively within 600 ms |
| Move active item | Works on files and folders |
| Edit active file in editor | Requires |
| Rename active item (inline) | Works on files and folders |
| Open context menu for focused navigation item | Alternative to the |
| Toggle folder or open file | Same as click |
See docs/ui-accessibility.md for the full accessibility model.
Architecture
The kiwiki frontend is intentionally framework-free — server-rendered Jinja2 templates plus HTMX for partial swaps, plus a small vanilla-JS layer (app/static/kiwiki.js) for interactive widgets. Application styles live in app/static/kiwiki.css with one :root token source; fonts and editor dependencies are vendored under app/static/. See docs/architecture.md for the layout, request flow, namespaces, and helper conventions before contributing frontend changes.
Local Development
Create a virtual environment and install dependencies:
python3.12 -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements-dev.txt
npm ciRun the app:
KIWIKI_DATA_DIR=./data \
KIWIKI_USERS="admin:dev-key:admin" \
KIWIKI_BASE_URL="http://127.0.0.1:8080" \
KIWIKI_TRUST_PROXY=false \
uvicorn app.main:app --host 127.0.0.1 --port 8080 --reloadBuild the frontend motion bundle:
npm run build:motionRun checks:
ruff check app tests
pytest -q
npm audit --audit-level=high
docker build -t kiwiki:test .Docker
The default Compose file builds the local image and serves the app on port 8082:
docker compose up -d
docker compose logs -f kiwikiPersistent data is mounted at:
./data:/dataFor public deployments, move real secrets into .env or your secret manager.
Helm
A Helm chart is available under charts/kiwiki.
Create a local file named kiwiki-secrets.env containing only
KIWIKI_USERS and KIWIKI_OAUTH_TOKEN_SECRET, then install with a
pre-created Secret:
kubectl create secret generic kiwiki-runtime-secrets \
--from-env-file=kiwiki-secrets.env \
--dry-run=client -o yaml | kubectl apply -f -
helm upgrade --install kiwiki ./charts/kiwiki \
--set existingSecret=kiwiki-runtime-secrets \
--set-string env.KIWIKI_BASE_URL="https://kiwiki.example.com"The Secret must contain KIWIKI_USERS and KIWIKI_OAUTH_TOKEN_SECRET.
secretEnv remains available for development, but its values are stored in
Helm release metadata. An existing PVC can be reused with
--set persistence.existingClaim=kiwiki-data. Review charts/kiwiki/values.yaml
before deploying.
Upgrading to v3.0
Existing data, user names and API keys do not need conversion. The Helm values
schema does change: KIWIKI_USERS and KIWIKI_OAUTH_TOKEN_SECRET must no
longer come from the ConfigMap-backed env block. Preserve the existing users,
API keys and explicit OAuth signing secret, then create a Kubernetes Secret
before the upgrade:
kubectl create secret generic kiwiki-runtime-secrets \
--from-env-file=kiwiki-secrets.env \
--dry-run=client -o yaml | kubectl apply -f -
helm upgrade --install kiwiki ./charts/kiwiki \
--set existingSecret=kiwiki-runtime-secrets \
--set persistence.existingClaim=kiwiki-dataRemove the old sensitive env.KIWIKI_USERS and
env.KIWIKI_OAUTH_TOKEN_SECRET values from the values file used for the
upgrade, and avoid --reuse-values until they have been removed. Do not pass
secrets through --set in production because Helm stores release values. If
the old deployment had no explicit OAuth secret, create a stable one now;
existing OAuth access and refresh tokens will be invalidated once during that
change. Existing pods keep working until replaced, but the v3 chart will reject
an upgrade that supplies neither existingSecret nor secretEnv. Previous
Helm release revisions may still contain the former ConfigMap values and should
be handled according to your cluster's secret-retention policy.
Repository Hygiene
The repository includes:
GitHub Actions CI for Ruff, branch coverage (minimum 60%), dependency audits, Chromium smoke tests and a container readiness check
Dependabot configuration for Python, npm, and GitHub Actions
Issue and pull request templates
Security policy
MIT license
Ignored local artifacts include .venv/, node_modules/, data/, Python caches, test caches, and local agent configuration.
Security
See SECURITY.md.
Important operational rules:
Use strong random API keys.
Set
KIWIKI_TRUST_PROXY=truebehind HTTPS.Configure
KIWIKI_TRUSTED_PROXY_CIDRS; forwarding headers from all other peers are ignored.Restrict
KIWIKI_CORS_ORIGINSin production.Set
KIWIKI_OAUTH_TOKEN_SECRETfor public MCP/OAuth deployments.Do not publish local wiki data or deployment secrets.
License
MIT. See LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/natorus87/kiwiki'
If you have feedback or need assistance with the MCP directory API, please join our Discord server