Home Lab Part 4: MCP Servers — An AI Knowledge Base

April 4, 2026 — #home-lab #mcp #ai #docker #self-hosting

The most unconventional service in my home lab: Model Context Protocol (MCP) servers that give AI assistants — Claude, GPT, local models — read and write access to a shared knowledge base stored in OpenCloud.

Why

AI assistants are stateless. Every conversation starts from zero. I wanted a way to persist context across sessions and across different AI tools — setup notes, project context, writing drafts, and memory about ongoing work. MCP provides a standard protocol for this, and since I already had OpenCloud running, WebDAV was a natural storage backend.

Architecture

The MCP servers are a fork of LaubPlusCo/mcp-webdav-server with added authentication and multi-instance support. The image auto-builds on push via GitHub Actions.

Two instances run as Docker containers, each scoped to different access levels:

EndpointAccessWebDAV Scope
mcp.johannes-kling.de/opencloud/read/mcpRead-onlyAll files
mcp.johannes-kling.de/opencloud/write/mcpRead + Write/LLM/ only

Both are authenticated via Traefik BasicAuth. The write server is deliberately scoped to /LLM/ — it can’t touch other files.

The Knowledge Base Structure

/LLM/
├── knowledge/
│   ├── home-lab/       ← Per-service setup notes (what you're reading about)
│   ├── dev/            ← Development project docs
│   ├── writing/        ← Style guide and drafts
│   └── study/          ← Study notes
├── memory/             ← Cross-session persistent memory
├── prompts/            ← System prompts for different contexts
└── writing/
    └── drafts/         ← Blog post drafts

The idea is that any AI assistant — whether it’s Claude Code on my laptop, Claude on the web, or a local model — can read the same knowledge base and build on previous work.

Docker Compose

services:
  mcp_opencloud_read:
    image: ghcr.io/jochern/mcp-webdav-server:latest
    environment:
      WEBDAV_URL: "https://cloud.johannes-kling.de/remote.php/dav/files/Johannes/"
      WEBDAV_USERNAME: "Johannes"
      WEBDAV_PASSWORD: "${OPENCLOUD_PASSWORD}"
      READ_ONLY: "true"
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.mcp-read.rule=Host(`mcp.johannes-kling.de`) && PathPrefix(`/opencloud/read`)"

  mcp_opencloud_write:
    image: ghcr.io/jochern/mcp-webdav-server:latest
    environment:
      WEBDAV_URL: "https://cloud.johannes-kling.de/remote.php/dav/files/Johannes/LLM/"
      WEBDAV_USERNAME: "Johannes"
      WEBDAV_PASSWORD: "${OPENCLOUD_PASSWORD}"
      READ_ONLY: "false"
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.mcp-write.rule=Host(`mcp.johannes-kling.de`) && PathPrefix(`/opencloud/write`)"

Traefik routes by path prefix — all MCP traffic goes through mcp.johannes-kling.de, and each server gets its own path.

Client Configuration

In Claude Code, the MCP servers are configured in .mcp.json:

{
  "opencloud-read": {
    "type": "http",
    "url": "https://mcp.johannes-kling.de/opencloud/read/mcp",
    "headers": {
      "Authorization": "Basic <base64>"
    }
  },
  "opencloud-write": {
    "type": "http",
    "url": "https://mcp.johannes-kling.de/opencloud/write/mcp",
    "headers": {
      "Authorization": "Basic <base64>"
    }
  }
}

Once configured, the AI can list directories, read files, create files, and update content — all through the standard MCP tool interface. This blog post series, for example, was written with Claude Code reading the knowledge base for accurate setup details.

Scaling to New Services

Adding a new MCP-accessible service means:

  1. Add a new container to the compose file with different WebDAV credentials/scope
  2. Add a Traefik path-prefix label: /{newservice}/{access}/mcp
  3. No DNS or Cloudflare changes needed — mcp.johannes-kling.de already routes to Traefik

Gotchas

The write token is scoped. The write server can only access /LLM/ — it can’t read or modify files outside that directory. This is intentional. You don’t want an AI assistant accidentally overwriting your documents.

MCP sessions can expire. If the connection is idle for too long, the session ID becomes invalid. The fix is simple: reconnect the MCP client.

BasicAuth over HTTPS is fine. Since Cloudflare handles TLS, the credentials are encrypted in transit. The BasicAuth is just for authenticating the MCP client to the server.

Result

The knowledge base is live and actively used. Every home lab service has its setup documented in /LLM/knowledge/home-lab/, this portfolio site has its docs in /LLM/knowledge/dev/, and cross-session memory persists between conversations. It’s a small thing, but having AI assistants that actually remember context makes them significantly more useful.