MCP server exposing a local markdown knowledge base
Project description
MCP Knowledge Base Server
A local, text‑only knowledge base exposed as an MCP server with optional HTTP/SSE transports and a built‑in web UI. Supports creating, reading, updating, searching, and soft‑deleting UTF‑8 text files. Optionally mirrors content to Chroma for semantic search and 2D/3D vector visualization.
Highlights
- MCP tools for file lifecycle + search
- HTTP/SSE transports and a minimal built‑in UI
- Deterministic path validation and soft deletes
- Optional Chroma mirroring for semantic search and vector plotting
- No lock‑in: works with any Python toolchain (pip/pipx/Poetry/PDM/Rye/etc.)
Table of contents
- Quick start
- How it works
- CLI usage
- MCP tools
- Human UI
- UI HTTP API
- Optional: ChromaDB mirroring
- Reindexing CLI
- Persistent CLI defaults
- Path rules & safety
- Testing
- Integrating with LLM clients
- Troubleshooting
Quick start
Prereqs: Python 3.11+ is required. :contentReference[oaicite:1]{index=1}
Install (choose one):
-
From PyPI:
python -m pip install mcp-kb
Run the server (HTTP transport + UI):
mcp-kb-server --root /path/to/knowledgebase --transport http
# Alternative if entry points aren't on PATH:
python -m mcp_kb.cli.main --root /path/to/knowledgebase --transport http
On first launch, a documentation file is installed at .data/KNOWLEDBASE_DOC.md. The UI binds to port 8765 by default and increments until free, logging a URL like:
UI available at http://127.0.0.1:8765
Note: The server defaults to
stdioonly. Add--transport sseand/or--transport httpto enable network transports.
How it works
- KnowledgeBase: safe, validated file operations (create/read/append/regex/soft‑delete).
- MCP server: exposes the operations as MCP tools over chosen transports.
- Human UI: small web UI for browsing, editing, and searching files.
- Optional vector layer: if Chroma is configured, semantic search and a 3D scatter of embeddings appear in the UI.
CLI usage
The package exposes these entry points: mcp-kb / mcp-kb-server (run server) and mcp-kb-reindex (offline reindex).
Common flags (server):
--root <path>: KB root directory (relative paths are enforced internally)--transport {stdio|sse|http}(repeatable; default:stdio)--host <ip>/--port <int>: apply to HTTP/SSE transports--ui-port <int>: starting port for UI (default 8765; auto‑increments if busy)--no-ui: disable the UI even if HTTP/SSE is active
Examples:
# stdio only (default):
mcp-kb-server --root /path/to/kb
# HTTP + SSE + stdio:
mcp-kb-server --root /path/to/kb \
--transport stdio --transport sse --transport http \
--host 0.0.0.0 --port 9000
MCP tools
All tools operate on relative paths inside the KB root and respect soft‑deletes.
create_file(path, content) -> strread_file(path, start_line?, end_line?) -> {path, start_line, end_line, content}append_file(path, content) -> strregex_replace(path, pattern, replacement) -> {replacements}delete(path) -> str(soft delete; renames file with sentinel)search(query, limit=5) -> [FileSegment...](semantic first if Chroma is on; otherwise literal scan)overview() -> strdocumentation() -> str
read_file and search return FileSegment objects with start_line, end_line, and content. Line indices are 0‑based inclusive in the JSON the server emits.
Human UI
- Menu: Browse (always) and Vectors (when a vector store is available).
- Browse: left tree, right editor, Save/Cancel/Delete, and New File.
- Search: sidebar search filters the tree; clicking a result opens the file and highlights the matched lines. When vectors are available, the plot highlights results and the query point.
UI HTTP API
Base path is the UI origin.
-
GET /api/tree→ file tree (nested{name, path, type, children}) -
GET /api/file?path=<rel>→{path, start_line, end_line, content} -
PUT /api/file(JSON{path, content}) →204on success -
DELETE /api/file?path=<rel>→204on success -
GET /api/search?query=<text>&limit=<int>→{ "results": [ { "path": "notes/a.md", "start_line": 10, "end_line": 12, "content": "..." } ], "meta": { "query_embeddings": [ ... ], "query_embeddings_umap2d": [x, y], "query_embeddings_umap3d": [x, y, z] } }
(Meta fields appear when Chroma is enabled.)
Vector endpoints (visible when Chroma is configured):
GET /api/vector/status→{ "available": bool, "dimensions": int|null, "count": int|null }GET /api/vector/embeddings?limit=<int>&offset=<int>&path=<rel?>→[ { id, document_id, path, chunk, embedding, umap2d?, umap3d? } ]GET /api/vector/query_embedding?query=<text>→{ embedding: number[], used_model: string|null }POST /api/vector/reindex→{ status: "queued"|"running"|"unavailable"|"error" }POST /api/vector/refit→{ status: "queued"|"unavailable"|"error" }
Optional: ChromaDB mirroring
Install the vector extras (pick what you need):
# core vector support (Chroma, UMAP integration, splitters)
python -m pip install 'mcp-kb[vector]'
# add Sentence Transformers embedding support
python -m pip install 'mcp-kb[sentence-transformer]'
Enable via CLI flags (examples):
mcp-kb-server \
--root /path/to/kb \
--transport http \
--chroma-client ephemeral \
--chroma-collection local-kb \
--chroma-embedding default
Supported clients: off, ephemeral, persistent, http, cloud. All --chroma-* flags have MCP_KB_CHROMA_* env var equivalents (e.g., MCP_KB_CHROMA_CLIENT=http, MCP_KB_CHROMA_HOST=...). Chunking can be tuned with --chroma-chunk-size and --chroma-chunk-overlap.
Reindexing CLI
Rebuild the Chroma index from disk without running the MCP transports:
mcp-kb-reindex --root /path/to/kb \
--chroma-client persistent \
--chroma-data-dir /path/to/chroma \
--chroma-collection knowledge-base \
--chroma-embedding default
This processes all active text files and updates the collection; some tests assert the reindex path mirrors content exactly.
Persistent CLI defaults
Resolved CLI/environment settings are persisted per KB root at:
<root>/.data/cli-config.json
Future runs inherit these defaults unless overridden by new flags or env vars. Delete or edit the file to reset.
Path rules & safety
- Relative paths only. Absolute paths and
..traversal are rejected. .data/is read‑only for writes (reads allowed).- Soft delete: files renamed with a sentinel; hidden from listing/search.
- Writes are serialized with per‑file locks to avoid corruption.
These rules are enforced in the validation and filesystem helpers.
Testing
Install test deps and run:
python -m pip install pytest
pytest -q
Vector‑related tests are skipped if Chroma isn’t installed. To run them:
python -m pip install 'mcp-kb[vector]'
pytest -q
The suite exercises the real HTTP UI, vector endpoints, CLI config persistence, and FastMCP flows.
Integrating with LLM clients
Provide the server command your client can execute. Two portable options:
-
Executable (preferred if on PATH):
{ "command": "mcp-kb-server", "args": ["--root", "/absolute/path/.knowledgebase", "--transport", "stdio"] }
-
Python module (works even without entry points on PATH):
{ "command": "python", "args": [ "-m", "mcp_kb.cli.main", "--root", "/absolute/path/.knowledgebase", "--transport", "stdio" ] }
Examples:
-
Claude Desktop (
claude_desktop_config.json):{ "mcpServers": { "local-kb": { "command": "mcp-kb-server", "args": [ "--root", "/absolute/path/.knowledgebase", "--transport", "stdio" ] } } }
-
VS Code (Claude MCP Extension) (
settings.json):{ "claudeMcp.servers": { "local-kb": { "command": "mcp-kb-server", "args": [ "--root", "/absolute/path/.knowledgebase", "--transport", "stdio" ], "env": { "MCP_KB_ROOT": "/absolute/path/.knowledgebase" } } } }
Troubleshooting
- “Absolute paths are not permitted” → Use a relative path in tools and UI.
- “Writes are not allowed inside the protected folder '.data'” → Choose a different directory (e.g.,
docs/). - Vector endpoints missing → You didn’t install/enable the vector extras or a Chroma client.
- UI port in use → Set
--ui-portto another number; it auto‑increments if busy.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_kb-0.3.3.tar.gz.
File metadata
- Download URL: mcp_kb-0.3.3.tar.gz
- Upload date:
- Size: 53.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc36b271d69713de4d5163ad114e44e7d70c457cfba6c78d925563955076a4d6
|
|
| MD5 |
9165f08e39d039ab2b4f014db29278c8
|
|
| BLAKE2b-256 |
ca443a42543556dba34739950af49852165a2fc15383f838f1046f53e1091b27
|
Provenance
The following attestation bundles were made for mcp_kb-0.3.3.tar.gz:
Publisher:
version_publish_main.yml on JulianKimmig/local_knowledge_base
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_kb-0.3.3.tar.gz -
Subject digest:
fc36b271d69713de4d5163ad114e44e7d70c457cfba6c78d925563955076a4d6 - Sigstore transparency entry: 604705140
- Sigstore integration time:
-
Permalink:
JulianKimmig/local_knowledge_base@a9bb0782bd9544e50804be2cf6ffbb3549d269d6 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/JulianKimmig
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
version_publish_main.yml@a9bb0782bd9544e50804be2cf6ffbb3549d269d6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mcp_kb-0.3.3-py3-none-any.whl.
File metadata
- Download URL: mcp_kb-0.3.3-py3-none-any.whl
- Upload date:
- Size: 59.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46eaa1e727662e1ca92eadd6d761cc370338adc476d280454ab163850662fb09
|
|
| MD5 |
de31fa82776d7d8a41fe95ebe1e1be39
|
|
| BLAKE2b-256 |
e46e4bab0a7951f4074269d2e33bd9a409e502a3a214c350b736077dbd3b03fc
|
Provenance
The following attestation bundles were made for mcp_kb-0.3.3-py3-none-any.whl:
Publisher:
version_publish_main.yml on JulianKimmig/local_knowledge_base
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_kb-0.3.3-py3-none-any.whl -
Subject digest:
46eaa1e727662e1ca92eadd6d761cc370338adc476d280454ab163850662fb09 - Sigstore transparency entry: 604705142
- Sigstore integration time:
-
Permalink:
JulianKimmig/local_knowledge_base@a9bb0782bd9544e50804be2cf6ffbb3549d269d6 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/JulianKimmig
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
version_publish_main.yml@a9bb0782bd9544e50804be2cf6ffbb3549d269d6 -
Trigger Event:
push
-
Statement type: