4 Commits

Author SHA1 Message Date
steve e39e00a2c0 Add MCP auth status to kb_status and update server instructions
- kb_status now returns authenticated: true/false so clients can verify auth
- Server instructions mention Bearer token auth requirement
- Add .env, .venv/, test_mcp_client.py to .gitignore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:04:12 +01:00
steve d078af9ad3 Split MCP docs into MCP.md with AI tool setup examples
Move MCP server documentation from README into dedicated MCP.md.
Add configuration examples for Claude Code, VS Code, Cursor,
Windsurf, and JetBrains IDEs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 22:03:41 +01:00
steve b3dce188e1 Fix version check failing on non-200 status responses
When the engine returns 401 (auth required) or other non-200 responses,
the version check was parsing the error body, getting an empty version
string, and fatally exiting. Now skips the check on non-200 responses
and lets the actual API call surface the real error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 21:52:24 +01:00
steve 0dc3065979 Update README for v3.0.0 — add MCP server docs, updatenote, fix version refs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 21:45:31 +01:00
5 changed files with 207 additions and 10 deletions
+3
View File
@@ -4,3 +4,6 @@ __pycache__/
engine/data/ engine/data/
TMP/ TMP/
.env
.venv/
test_mcp_client.py
+174
View File
@@ -0,0 +1,174 @@
# MCP Server (Agent Integration)
The MCP server exposes kb operations as native MCP tools, so agents can search, add notes, upload files, and manage documents without shelling out to the CLI.
## Start the MCP server
The compose files include a `kb-mcp` service alongside the engine. Set `KB_MCP_API_KEY` to require Bearer token auth from connecting agents:
```bash
KB_API_KEY=your-engine-key KB_MCP_API_KEY=your-agent-key \
docker compose -f engine/compose.nvidia.yaml up -d
```
Or run the MCP server standalone:
```bash
docker run -d --name kb-mcp \
-p 3000:3000 \
-e KB_ENGINE_URL=http://your-engine-host:8000 \
-e KB_API_KEY=your-engine-key \
-e KB_MCP_API_KEY=your-agent-key \
--restart unless-stopped \
docker.dcglab.co.uk/dcg/kb/mcp:latest
```
## MCP tools
| Tool | Description |
|---|---|
| `kb_search` | Hybrid search with optional collection/tag/type filters |
| `kb_addnote` | Add a text note (queued for async ingestion) |
| `kb_update_note` | Update an existing note in place |
| `kb_get` | Get document details by ID or source path |
| `kb_status` | Engine health and statistics |
| `kb_jobs` | Ingestion queue status |
| `kb_upload_start` | Start a chunked file upload |
| `kb_upload_chunk` | Upload a base64-encoded file chunk |
| `kb_upload_finish` | Finish upload and submit for ingestion |
## Collections
The MCP server supports **collections** — scoped document namespaces implemented via tag conventions. Use these to separate agent memory from user documents:
- `documents` (default) — user-facing documents
- `memory` — agent memory and preferences
- `workspace` — working context
Tools accept a `collection` parameter. The MCP server translates this to `collection:<name>` tags on the engine, and strips them from responses so agents see a clean `"collection": "memory"` field.
## MCP server configuration
| Variable | Default | Description |
|---|---|---|
| `KB_ENGINE_URL` | `http://localhost:8000` | Engine API URL |
| `KB_API_KEY` | (none) | Engine API key |
| `KB_MCP_API_KEY` | (none) | Bearer token required from agents (disabled if unset) |
| `KB_MCP_PORT` | `3000` | Port to listen on |
## Connecting AI coding tools
The kb MCP server uses **Streamable HTTP** transport at `http://your-host:3000/mcp`. Below are configuration examples for popular AI coding tools.
### Claude Code (CLI / Desktop / Web)
Add the server to your project or user settings:
```bash
claude mcp add kb-server --transport http http://localhost:3000/mcp
```
Or add it manually to `.claude/settings.json` (project) or `~/.claude/settings.json` (global):
```json
{
"mcpServers": {
"kb-server": {
"type": "http",
"url": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer your-agent-key"
}
}
}
}
```
### VS Code (GitHub Copilot)
Add to your `.vscode/settings.json` (workspace) or user settings:
```json
{
"mcp": {
"servers": {
"kb-server": {
"type": "http",
"url": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer your-agent-key"
}
}
}
}
}
```
Or add to `.vscode/mcp.json` in your workspace:
```json
{
"servers": {
"kb-server": {
"type": "http",
"url": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer your-agent-key"
}
}
}
}
```
### Cursor
Add to `.cursor/mcp.json` in your project root:
```json
{
"mcpServers": {
"kb-server": {
"type": "streamable-http",
"url": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer your-agent-key"
}
}
}
}
```
### Windsurf
Add to `~/.codeium/windsurf/mcp_config.json`:
```json
{
"mcpServers": {
"kb-server": {
"serverUrl": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer your-agent-key"
}
}
}
}
```
### JetBrains IDEs (IntelliJ, WebStorm, PyCharm, etc.)
Add to `.junie/mcp.json` in your project root, or configure via **Settings > Tools > AI Assistant > MCP Servers**:
```json
{
"servers": {
"kb-server": {
"type": "http",
"url": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer your-agent-key"
}
}
}
}
```
+17 -5
View File
@@ -2,16 +2,19 @@
Personal knowledge base with hybrid search (full-text + semantic vector search). Personal knowledge base with hybrid search (full-text + semantic vector search).
v2 uses a client-server architecture: a **FastAPI engine** running in Docker (with optional GPU acceleration) and a lightweight **Go CLI client** that talks to it over HTTP. Client-server architecture: a **FastAPI engine** running in Docker (with optional GPU acceleration), a lightweight **Go CLI client**, and an **MCP server** for native agent integration.
## Architecture ## Architecture
``` ```
Go CLI (kb) ──HTTP──▶ FastAPI Engine (Docker) ──▶ SQLite + GPU Go CLI (kb) ──HTTP──▶ FastAPI Engine (Docker) ──▶ SQLite + GPU
MCP Agents ──MCP/HTTP──▶ MCP Server (Docker) ──┘
``` ```
- **Engine**: Keeps the embedding model warm in memory. Handles search, ingestion, and document management via REST API. Runs in Docker with NVIDIA GPU, AMD GPU (ROCm), or CPU-only support. - **Engine**: Keeps the embedding model warm in memory. Handles search, ingestion, document management, and note mutation via REST API. Runs in Docker with NVIDIA GPU, AMD GPU (ROCm), or CPU-only support.
- **Client**: Single static Go binary. No Python, no ML dependencies, instant startup. Talks to the engine over HTTP. - **Client**: Single static Go binary. No Python, no ML dependencies, instant startup. Talks to the engine over HTTP.
- **MCP Server**: Exposes kb operations as native MCP tools over Streamable HTTP. Runs as a separate Docker container alongside the engine. Supports collections for scoping agent memory vs user documents.
- **Storage**: Single SQLite database with FTS5 (keyword search) and sqlite-vec (vector search). Portable via bind mount — just copy the data directory between hosts. - **Storage**: Single SQLite database with FTS5 (keyword search) and sqlite-vec (vector search). Portable via bind mount — just copy the data directory between hosts.
## Quick start ## Quick start
@@ -84,7 +87,7 @@ Check [releases](https://gitea.dcglab.co.uk/steve/kb/releases) for the latest cl
```bash ```bash
# Set the version tag # Set the version tag
TAG=client-v2.1.0 TAG=client-v3.0.0
# Linux (amd64) # Linux (amd64)
curl -L -o kb https://gitea.dcglab.co.uk/steve/kb/releases/download/${TAG}/kb-linux-amd64 curl -L -o kb https://gitea.dcglab.co.uk/steve/kb/releases/download/${TAG}/kb-linux-amd64
@@ -135,6 +138,9 @@ kb jobs
kb search "how to install git" kb search "how to install git"
kb search "deploy process" --tags ops --type pdf kb search "deploy process" --tags ops --type pdf
# Update a note in place
kb updatenote 42 "revised note content"
# Manage # Manage
kb list kb list
kb info 1 kb info 1
@@ -182,6 +188,12 @@ KB_DATA_PATH=~/kb-data docker compose -f compose.nvidia.yaml up -d
Data is device-agnostic — you can ingest on NVIDIA and serve from AMD or CPU (or any combination) with the same data directory. Data is device-agnostic — you can ingest on NVIDIA and serve from AMD or CPU (or any combination) with the same data directory.
## Claude Code skill ## MCP server (agent integration)
This tool is designed to be wrapped as a Claude Code skill. See `SKILL.md` for the skill definition. The MCP server exposes kb operations as native MCP tools over Streamable HTTP, so agents can search, add notes, upload files, and manage documents without shelling out to the CLI. Includes setup guides for Claude Code, VS Code, Cursor, Windsurf, and JetBrains IDEs.
See **[MCP.md](MCP.md)** for full details — server setup, available tools, collections, configuration, and client examples.
## Agent skill
If you are restricted from using MCP server, or you just prefer to utilise Agent SKILLS, please also see `SKILL.md` for the skill definition.
+4
View File
@@ -94,6 +94,10 @@ func (c *Client) checkEngineVersion() {
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return // auth error or other issue — let the actual request surface it
}
var status struct { var status struct {
Version string `json:"version"` Version string `json:"version"`
} }
+8 -4
View File
@@ -87,7 +87,12 @@ async def _ensure_exclusive_collection(doc_id: int, collection: str) -> None:
mcp = FastMCP( mcp = FastMCP(
"kb", "kb",
instructions="Knowledge base MCP server. Provides tools for searching, adding, and managing documents and notes.", instructions=(
"Knowledge base MCP server. Provides tools for searching, adding, and "
"managing documents and notes. This server requires Bearer token "
"authentication — all requests are authenticated via the Authorization "
"header at the HTTP transport layer."
),
) )
@@ -218,6 +223,7 @@ async def kb_status() -> str:
database size, and ingestion queue state. database size, and ingestion queue state.
""" """
result = engine.get_status() result = engine.get_status()
result["authenticated"] = bool(config.KB_MCP_API_KEY)
return json.dumps(result, indent=2) return json.dumps(result, indent=2)
@@ -323,9 +329,7 @@ class BearerAuthMiddleware(BaseHTTPMiddleware):
return await call_next(request) return await call_next(request)
auth_header = request.headers.get("authorization", "") auth_header = request.headers.get("authorization", "")
if auth_header.startswith("Bearer "): if auth_header.startswith("Bearer ") and auth_header[7:] == config.KB_MCP_API_KEY:
token = auth_header[7:]
if token == config.KB_MCP_API_KEY:
return await call_next(request) return await call_next(request)
return JSONResponse( return JSONResponse(