Skip to content

Grounded

Metadata

Field Value
Service grounded
Purpose One curated documentation index shared by MCP-capable coding clients
Criticality TIER_3
Owner arnaud
Cluster / namespace local / grounded
Exposure Web UI through Authelia; MCP through a local Kubernetes tunnel
Stateful yes
Backup class Not configured; host-local local-path PVC
RPO / RTO Undefined until an off-cluster backup and restore drill succeeds
Last reviewed 2026-08-27

1. Service Overview

What “universal memory” means

Grounded gives Codex, Claude Code, VS Code, and ZCode the same searchable set of documentation. Add or refresh a library once and every connected client sees that index.

It is a documentation memory, not an agent-memory system:

Grounded keeps Grounded does not keep
Library names and versions Chat transcripts
Source URLs and page metadata Personal preferences
Scraped page content and chunks Task progress or plans
Full-text index and vector embeddings Decisions that were never documented
Scrape-job state Automatic memory of what an agent did

Use this division of responsibility:

  • AGENTS.md, CLAUDE.md, and repository docs: project rules, decisions, conventions, and operational context.
  • Grounded: versioned vendor docs, API references, manuals, and other stable sources that agents should search before answering.
  • Git history or an issue tracker: work history and outstanding tasks.

1. Open the tunnel

Run this on the same machine as the editor or CLI client and keep it open:

kubectl -n grounded port-forward service/grounded-mcp 6280:6280

All clients then use:

http://127.0.0.1:6280/mcp

The tunnel is the supported production access path for now. Kubernetes controls who may open it, and the MCP service is exposed only on the local loopback interface. The public https://mcp-docs.mutana.fr/mcp route remains behind Authelia browser forward auth and should not be configured in headless clients.

2. Configure each client

Prefer user-level configuration when you want Grounded in every project. Workspace configuration is useful when a team should discover the server from the repository, but it still requires each user to have a working tunnel.

Codex

Codex CLI and the VS Code Codex extension share ~/.codex/config.toml. Add:

[mcp_servers.grounded]
url = "http://127.0.0.1:6280/mcp"
startup_timeout_sec = 20
tool_timeout_sec = 120

Verify with codex mcp list; inside Codex, use /mcp to inspect the server and its tools. If native OAuth is enabled later, change the URL to the HTTPS MCP endpoint and run codex mcp login grounded.

Claude Code

claude mcp add --transport http --scope user \
  grounded http://127.0.0.1:6280/mcp
claude mcp list

Use /mcp inside Claude Code to inspect connection status. HTTP is the current transport; do not configure the deprecated SSE endpoint.

VS Code

Run MCP: Open User Configuration, then add this server to the user mcp.json (or use .vscode/mcp.json for workspace scope):

{
  "servers": {
    "grounded": {
      "type": "http",
      "url": "http://127.0.0.1:6280/mcp"
    }
  }
}

Run MCP: List Servers to start or inspect it. In Chat's Agent mode, use Configure Tools to confirm the Grounded tools are enabled.

ZCode

The simplest path is to reuse the Codex entry:

  1. Open ZCode SettingsMCP ServersImport.
  2. Select Codex CLI and import grounded.
  3. Confirm the HTTP URL is http://127.0.0.1:6280/mcp and enable the server.

Alternatively, create a new HTTP MCP server in the same settings page and enter that URL manually.

3. Ask agents to use Grounded explicitly

Good prompts make the evidence boundary unambiguous:

Use Grounded to list the indexed libraries before answering.
Search the Grounded library kubernetes, version 1.34, for StatefulSet update
semantics. Base the answer on the returned pages and cite their source URLs.
Use Grounded first. If the relevant version is missing, tell me what is missing
instead of presenting model memory as Grounded evidence.

The main MCP tools are:

Need Tool
Discover indexed knowledge list_libraries
Search a specific library/version search_docs
Fetch one source directly fetch_url
Resolve available versions find_version
Add or refresh documentation scrape_docs
Inspect or control scraping get_job_info, list_jobs, cancel_job, clear_completed_jobs
Delete indexed documentation remove_docs

Treat scrape_docs and remove_docs as shared administrative operations: their effects are visible to every client. Prefer the web UI for deliberate curation and ask before deleting a library or version.

2. Architecture Diagram

How the memory is managed

Data flow

public documentation URL
  -> single worker scrape job
  -> clean and split page content
  -> send chunks to the configured embedding provider
  -> SQLite full-text rows + vector embeddings on /data
  -> MCP search from every connected client

The worker owns the job queue and the SQLite store. The MCP and web processes are stateless gateways. Never scale the worker above one replica against the same PVC.

The persistent store is /data/documents.db on data-grounded-worker-0. SQLite uses write-ahead logging (WAL), so a live copy of only documents.db is not a valid backup. The store includes libraries, versions, pages, chunks, embeddings, metadata about the embedding model and dimension, and scrape-job state.

The configured OpenAI-compatible provider receives document chunks during indexing and query text during vector search. Choose a provider whose privacy and retention terms are acceptable for every indexed source and query. Private or secret material should not be indexed by default.

Curation lifecycle

  1. Sign in to https://grounded.mutana.fr through Authelia.
  2. Add a stable library name, an explicit version, and its canonical public documentation URL.
  3. Set crawl depth/page limits intentionally; start small and review the pages.
  4. Wait for the scrape job to complete, then test a narrow search in the UI or through MCP.
  5. Add a new version alongside the old one. Remove the old version only when no project still relies on it.
  6. Refresh after important upstream documentation releases and remove broken or irrelevant sources deliberately.

Names and versions are part of the retrieval contract. Prefer identifiers such as kubernetes / 1.34 over labels such as k8s-current / latest, which become misleading over time.

Changing the embedding model or its vector dimension invalidates existing vectors. Plan a complete re-scrape after such a change; keyword/full-text search can remain available while vectors are rebuilt.

3. Deployment Specifications

Item Value
Source grounded/base, grounded/overlays/local
Delivery Plain Kustomize through Fleet
Image ghcr.io/arabold/docs-mcp-server:v2.4.5
Workloads One worker StatefulSet; MCP and web Deployments
Persistent volume data-grounded-worker-0, 20Gi, local-path

Architecture and security

[Codex / Claude Code / VS Code / ZCode]
  -> localhost:6280 (kubectl port-forward)
  -> grounded-mcp:6280
  -> grounded-worker:8080/api (NetworkPolicy restricted)
  -> /data local-path PVC (SQLite + embeddings)

[Browser] -> Traefik -> Authelia -> grounded-web:6281 -> worker API
Component Replicas Request / limit Secret access
worker 1 250m CPU, 1Gi / 2Gi memory embedding provider credentials
MCP gateway 1 100m CPU, 256Mi / 512Mi memory none
web UI 1 100m CPU, 256Mi / 512Mi memory none

All pods run as UID/GID 1000, drop Linux capabilities, disable privilege escalation, use a read-only root filesystem, and do not mount service-account tokens. The scraper permits public-network fetching while rejecting private and special-use destinations, invalid TLS, and local-file access. This blocks a documentation URL from becoming a path into cluster services or node files.

Native MCP OAuth/OIDC is the target for direct public client access. Authelia does not currently have the required provider configuration in this repository, so the issuer, audience, and client-registration policy remain a deployment decision. Do not weaken the IngressRoute to unauthenticated access as a shortcut.

4. Configuration Guide

Setting Source Purpose
app.storePath: /data grounded-config ConfigMap Persistent SQLite location
app.telemetryEnabled: false ConfigMap Disable application telemetry
app.embeddingModel: openai:BAAI/bge-m3 ConfigMap Explicit OpenAI-compatible provider and model
OPENAI_API_KEY grounded-secrets Provider credential; worker only
OPENAI_API_BASE grounded-secrets OpenAI-compatible endpoint; worker only

The Secret is created out of band from grounded/overlays/local/grounded-secrets.env.example. After rotation, restart only the worker:

kubectl -n grounded rollout restart statefulset/grounded-worker

5. Access Protocols

Path Endpoint Audience Authentication
MCP tunnel http://127.0.0.1:6280/mcp Coding clients Kubernetes access plus local loopback
Web UI https://grounded.mutana.fr Operator Authelia forward auth
Public MCP https://mcp-docs.mutana.fr/mcp Reserved Not client-ready; native OAuth/OIDC pending
Worker API grounded-worker.grounded.svc:8080/api MCP/web pods only NetworkPolicy

6. Operations and Observability

The primary health signals are three Ready workloads, a Bound worker PVC, no restart loop, successful list_libraries/search_docs calls, and completed scrape jobs. There are no service-specific dashboards or alerts yet. Use kubectl -n grounded get all,pvc and worker logs for initial diagnosis, then follow the linked runbook.

7. Backup and Recovery Notes

The manifests are a production candidate, but the service was not present in the local cluster when reviewed on 2026-08-27. Production deployment remains gated on:

  • the real provider Secret;
  • an off-cluster backup destination, retention policy, and successful restore drill;
  • a decision that the tunnel is the accepted client access method, or a native MCP OAuth/OIDC design;
  • reconciliation of the tracked Fleet bootstrap and the live split GitRepo topology so Grounded has one authoritative deployment path.

local-path is host-local storage and no Grounded VolumeSnapshot mechanism is configured. Until backup is implemented, loss of the PVC means re-scraping the source documentation; RPO and RTO are undefined. See the Grounded runbook for preflight, incident, offline backup, restore, and rollback procedures.

8. Release and Change Notes

  • Current pinned release: v2.4.5.
  • Delivery uses Kustomize; there is no Helm chart version.
  • The 2026-08-27 production-readiness pass corrected the provider endpoint key, reduced credential exposure, hardened scraping, added memory limits, and replaced the assumed snapshot procedure with explicit deployment gates.

Source documentation