Posted on
Artificial Intelligence

MCP for Documentation

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

MCP for Documentation: Turn Your Docs Into Actionable CLI Knowledge

Ever tried to update a README at 2 a.m. only to discover three conflicting versions, a stale API reference, and a broken site build? Documentation sprawl is real. The Model Context Protocol (MCP) offers a pragmatic way to make your documentation “live” and toolable: expose your docs, searches, transforms, and checks as first‑class, callable operations an AI or you can reliably run from the terminal.

This post shows how to use MCP for documentation in a Linux- and Bash-friendly way: what it is, why it’s useful, and how to wire up a small toolbox that plugs cleanly into any MCP-aware workflow. You’ll get actionable steps, real commands, and distro-specific installation instructions.

What is MCP (and why docs folks should care)

MCP (Model Context Protocol) is an open protocol that lets AI assistants and other clients talk to “servers” that expose:

  • Resources (files, databases, APIs)

  • Tools (commands with defined inputs/outputs)

  • Prompts and context

For documentation, MCP helps by:

  • Making your docs verifiable: searches, style checks, and builds become explicit tools with consistent outputs.

  • Reducing context chaos: the assistant (or you) can query the exact docs tree and run conversions or checks on demand.

  • Unifying workflows: the same Bash commands you run locally can be exposed via MCP as structured tools.

You don’t need to rewrite your stack. MCP layers on top of solid CLI tools you already use.

TL;DR: What you’ll set up

  • A minimal CLI “docs toolbox” powered by ripgrep, pandoc, markdownlint, and optional site builders (MkDocs or Sphinx).

  • Watchers to auto-lint/build on changes.

  • A simple way to map these commands as MCP tools in whichever MCP client/server you use.

1) Install the essentials

We’ll use:

  • ripgrep: fast code/docs search

  • pandoc: convert between formats (e.g., docx ⇄ md, md ⇄ html/pdf)

  • jq: JSON plumbing for scripts

  • inotify-tools: file change detection

  • graphviz: render diagrams from dot (optional)

  • Node.js + markdownlint-cli: Markdown style checks

  • A static docs site builder: MkDocs or Sphinx (optional but useful)

Choose your distro and run:

Debian/Ubuntu (apt):

sudo apt update
sudo apt install -y ripgrep pandoc jq inotify-tools graphviz nodejs npm mkdocs python3-sphinx
sudo npm install -g markdownlint-cli

Fedora/RHEL/CentOS Stream (dnf):

sudo dnf install -y ripgrep pandoc jq inotify-tools graphviz nodejs npm mkdocs python3-sphinx
sudo npm install -g markdownlint-cli

openSUSE (zypper):

sudo zypper install -y ripgrep pandoc jq inotify-tools graphviz nodejs npm mkdocs python3-sphinx
sudo npm install -g markdownlint-cli

Notes:

  • If your repo doesn’t include a site generator yet, you can skip MkDocs/Sphinx for now.

  • If MkDocs isn’t found on your distro, try package search (apt-cache, dnf search, zypper search) or use a Python toolchain (pipx install mkdocs). The OS packages above work on most recent distros.

2) Create a Bash docs toolbox

Add a lightweight script that wraps common ops in consistent commands. Keep it in your repo, e.g., tools/docs.sh.

#!/usr/bin/env bash
set -euo pipefail

DOCS_DIR="${DOCS_DIR:-docs}"

usage() {
  cat <<EOF
Usage: $0 <command> [args...]

Commands:
  search <pattern>        Search docs for a regex (ripgrep)
  convert <in> <out>      Convert between formats via pandoc (auto-detected)
  lint                    Lint Markdown via markdownlint
  build [mkdocs|sphinx]   Build site using mkdocs or sphinx (auto if not given)
  changed                 List changed files since main (git required)
EOF
}

cmd_search() {
  local pattern="${1:-}"
  test -n "$pattern" || { echo "Missing pattern"; exit 2; }
  rg -n --hidden --glob "!.git" "$pattern" "$DOCS_DIR"
}

cmd_convert() {
  local in="${1:-}" out="${2:-}"
  test -f "$in" && test -n "$out" || { echo "Usage: $0 convert <in> <out>"; exit 2; }
  pandoc "$in" -o "$out"
}

cmd_lint() {
  # Lint across the docs tree; adjust glob as needed
  markdownlint "$DOCS_DIR" --ignore "$DOCS_DIR/vendor"
}

cmd_build() {
  local which="${1:-auto}"
  if [[ "$which" == "mkdocs" || ( "$which" == "auto" && -f mkdocs.yml ) ]]; then
    mkdocs build
  elif [[ "$which" == "sphinx" || ( "$which" == "auto" && -f docs/conf.py ) ]]; then
    sphinx-build -b html "$DOCS_DIR" "$DOCS_DIR/_build/html"
  else
    echo "No site builder detected. Provide 'mkdocs' or 'sphinx', or add mkdocs.yml/docs/conf.py."
    exit 1
  fi
}

cmd_changed() {
  # Useful for targeted checks in CI or MCP tools
  git fetch -q origin main || true
  git diff --name-only origin/main...HEAD -- "$DOCS_DIR" || true
}

main() {
  local cmd="${1:-}"; shift || true
  case "$cmd" in
    search)  cmd_search "$@";;
    convert) cmd_convert "$@";;
    lint)    cmd_lint "$@";;
    build)   cmd_build "$@";;
    changed) cmd_changed "$@";;
    *)       usage; exit 2;;
  esac
}
main "$@"

Make it executable:

chmod +x tools/docs.sh

Why this matters for MCP: these predictable, idempotent commands are exactly what you want to expose as MCP tools. They do one thing, accept clear args, and return clear output that a client (or human) can interpret.

3) Add a watcher to keep docs fresh

Auto-run lint/build whenever you edit files. This helps humans and doubles as a simple loop an MCP client could trigger when needed.

#!/usr/bin/env bash
set -euo pipefail

# Watch only markdown and config files to avoid rebuild storms
inotifywait -m -r -e modify,create,delete,move docs mkdocs.yml docs/conf.py 2>/dev/null | \
while read -r _; do
  echo "[watch] Changes detected. Linting and building..."
  if tools/docs.sh lint; then
    tools/docs.sh build auto || true
  else
    echo "[watch] Lint failed; fix issues and save again."
  fi
done

Run it in a second terminal:

./tools/watch-docs.sh

Installation reminder (if you skipped earlier):

  • apt: sudo apt install -y inotify-tools

  • dnf: sudo dnf install -y inotify-tools

  • zypper: sudo zypper install -y inotify-tools

4) Expose your toolbox as MCP tools

Every MCP client/server has its own way to declare tools. The idea is the same: map an action name and input schema to a command.

Here’s a conceptual example of a tool mapping file some clients use (adjust to your client’s config format):

# ~/.config/your-mcp-client/tools.docs.json
{
  "tools": [
    {
      "name": "docs.search",
      "description": "Search docs for a regex pattern",
      "command": "/absolute/path/to/repo/tools/docs.sh",
      "args": ["search", "${pattern}"],
      "input_schema": { "pattern": "string" }
    },
    {
      "name": "docs.convert",
      "description": "Convert docs via pandoc",
      "command": "/absolute/path/to/repo/tools/docs.sh",
      "args": ["convert", "${input}", "${output}"],
      "input_schema": { "input": "string", "output": "string" }
    },
    {
      "name": "docs.lint",
      "description": "Markdown lint",
      "command": "/absolute/path/to/repo/tools/docs.sh",
      "args": ["lint"]
    },
    {
      "name": "docs.build",
      "description": "Build docs site (mkdocs or sphinx)",
      "command": "/absolute/path/to/repo/tools/docs.sh",
      "args": ["build", "${which}"],
      "input_schema": { "which": "string?" }
    }
  ]
}

Tips:

  • Use absolute paths so the MCP runtime can find your script.

  • Start small: search and lint are great first tools.

  • Prefer plain-text or JSON outputs. Where helpful, wrap results as JSON the client can parse. For example:

tools/docs.sh search "TODO:" | jq -R -s 'split("\n") | map(select(length>0)) | {matches: .}'

5) Real-world examples

  • Find outdated API paths:
tools/docs.sh search '/v1/'
  • Convert a legacy Word doc to Markdown:
tools/docs.sh convert docs/legacy/guide.docx docs/guide.md
  • Lint everything and fail fast (great for CI and MCP):
tools/docs.sh lint
  • Build your site:
tools/docs.sh build mkdocs
# or
tools/docs.sh build sphinx
  • Only process changed files since main:
tools/docs.sh changed | xargs -r markdownlint

Optional: Add diagrams with Graphviz in Markdown:

dot -Tsvg docs/diagrams/arch.dot -o docs/diagrams/arch.svg

Graphviz install if missing:

  • apt: sudo apt install -y graphviz

  • dnf: sudo dnf install -y graphviz

  • zypper: sudo zypper install -y graphviz

Why this approach works

  • It’s incremental. You can keep your current docs stack. MCP simply formalizes access to it.

  • It’s observable. Outputs are deterministic and CLI-first, which MCP clients and CI love.

  • It’s portable. The same scripts run on any Linux distro and within containers.

  • It’s auditable. Tool invocations and results can be logged, reviewed, and repeated.

Troubleshooting quick hits

  • markdownlint not found? Install Node and the CLI:

    • apt: sudo apt install -y nodejs npm && sudo npm install -g markdownlint-cli
    • dnf: sudo dnf install -y nodejs npm && sudo npm install -g markdownlint-cli
    • zypper: sudo zypper install -y nodejs npm && sudo npm install -g markdownlint-cli
  • mkdocs not found? Try your distro package first, then:

    python3 -m pip install --user mkdocs
    
  • ripgrep too noisy? Narrow with globs:

    rg -n --glob '*.md' 'pattern' docs/
    

Conclusion and next steps

Documentation shouldn’t be a guessing game. With MCP and a small, reliable Bash toolbox, your docs become queryable, convertible, lintable, and buildable—by you and by any MCP-aware assistant—using the same commands.

Your next steps: 1) Install the CLI tools (see the apt/dnf/zypper commands above). 2) Drop the tools/docs.sh script into your repo and try the search/lint/build commands. 3) Map one or two of these commands as MCP tools in your client of choice and test a round trip. 4) Gradually add more actions (diagram generation, link checking, PDF exports) as your needs grow.

If you want a follow-up, I can provide:

  • A sample MCP tool schema tailored to your specific client

  • A Makefile and CI workflow (GitHub Actions/GitLab CI) that mirrors these tools

  • A minimal MkDocs or Sphinx starter pre-wired to the toolbox

Make your docs run like code—because they are.