# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a **monorepo** demonstrating the integration of MkDocs Material documentation with a Model Context Protocol (MCP) server. The project uses **uv** for dependency management and follows a workspace architecture with two main components.
## Architecture
### Workspace Structure
- **Root**: uv workspace configuration (`pyproject.toml`) with shared development tools (ruff, mypy, pytest, pre-commit)
- **mkdocs-site/**: MkDocs Material configuration (`mkdocs.yml`) and theme customization
- **mcp-server/**: Python MCP server implementation providing AI access to documentation
- **docs/**: Shared documentation source files consumed by both components
### Core Components
**MCP Server** (`mcp-server/src/mkdocs_mcp/`):
- `server.py`: Main MCP server using STDIO transport, handles protocol implementation
- `resources.py`: DocumentationResourceManager - converts Markdown files to MCP resources with frontmatter parsing
- `tools.py`: DocumentationToolManager - provides 5 AI tools: search_docs, find_by_title, list_pages, get_page_outline, search_code_blocks
**MkDocs Configuration** (`mkdocs-site/mkdocs.yml`):
- Material theme with dark/light mode, navigation features, and search
- Plugins: search, minify, git-revision-date-localized, mkdocstrings (for API docs)
- Markdown extensions: admonitions, code highlighting, Mermaid diagrams, tabbed content
- `docs_dir: ../docs` points to shared documentation source
**Key Architectural Decision**: The MCP server reads directly from the `docs/` directory to serve real-time documentation content to AI assistants via the Model Context Protocol. MkDocs builds from the same `docs/` directory, ensuring both systems stay synchronized.
## Common Development Commands
### Essential Setup
```bash
# Initial setup (runs uv sync --dev + pre-commit install)
make setup
# Start both documentation and MCP server simultaneously
make dev
```
### Documentation Development
```bash
# Start MkDocs dev server (auto-reload on file changes)
make docs-serve
# Build static documentation
make docs-build
# Clean build artifacts
make docs-clean
```
### MCP Server Development
```bash
# Start MCP server (STDIO transport)
make mcp-server
# Run only MCP server tests
make mcp-test
cd mcp-server && uv run pytest
```
### Testing & Quality
```bash
# Run specific test files
uv run pytest mcp-server/tests/test_server.py
uv run pytest tests/test_integration.py
# Test categories
make test-unit # Unit tests only (exclude integration)
make test-integration # Integration tests only
make test-cov # Full coverage report → htmlcov/
# Quality checks
make format # uv run ruff format .
make lint # uv run ruff check . --fix
make typecheck # uv run mypy .
make quality # All three above
make ci-check # Full CI pipeline (quality + tests)
```
### uv Workspace Commands
```bash
# Add dependencies to specific workspace member
cd mcp-server && uv add requests
cd mkdocs-site && uv add mkdocs-plugin-name
# Sync all workspace dependencies
uv sync --dev
# Run commands in workspace context
uv run pytest # Runs from root
cd mcp-server && uv run pytest # Runs MCP server tests only
```
## Development Environment
**DevContainer**: Configured for rootless Podman with uv pre-installed. The container is set up to:
- Use Python 3.12-slim base image
- Run as `vscode` user (UID/GID 1000) with sudo access
- Mount workspace with proper ownership using Podman's `:U` flag (automatically adjusts mount ownership)
- Forward ports 8000 (MkDocs) and 8001 (MCP server)
- Auto-install recommended VSCode extensions: Python, Ruff, MyPy, pytest, Markdown, YAML, Makefile Tools, GitLens
- Configure Python settings: strict type checking, format on save, auto-organize imports
- Set `UV_LINK_MODE=copy` to prevent hardlink warnings on bind mounts
- Auto-setup on container creation is handled manually via `make setup` inside the container
**Windows + WSL Setup**: The devcontainer.json uses explicit `workspaceMount` configuration to avoid UNC path issues with Wayland socket mounts that can cause "unsupported UNC path" errors on Windows with WSL + Podman.
**Alternative Development**: If DevContainer setup fails, use `scripts/dev-container.sh`:
```bash
./scripts/dev-container.sh build # Build container image
./scripts/dev-container.sh start # Start interactive container
./scripts/dev-container.sh setup # Setup environment inside container
```
**Key Files**:
- `.devcontainer/devcontainer.json`: Container config with explicit workspace mount and port forwarding
- `.devcontainer/Dockerfile`: Python 3.12 base with vscode user and uv installation
- `scripts/dev-container.sh`: Direct Podman wrapper bypassing VSCode DevContainer issues
## Important Implementation Details
### MCP Server Constraints
- **MUST log to stderr only** (never stdout) due to STDIO transport protocol
- Uses async/await throughout for file I/O operations
- Documentation path defaults to `../docs` relative to server location
- Resource URIs follow format: `docs://path/to/file.md`
### Testing Architecture
- **Unit tests**: `mcp-server/tests/` with comprehensive fixtures in `conftest.py`
- **Integration tests**: `tests/` for cross-component functionality
- Uses pytest markers: `@pytest.mark.integration`, `@pytest.mark.slow`
- Test fixtures create temporary documentation directories with realistic content
### Code Quality Configuration
- **Ruff**: Line length 88, targets Python 3.11+, includes isort/flake8-bugbear/pyupgrade rules
- **MyPy**: Strict mode with `disallow_untyped_defs = true`, `check_untyped_defs = true`
- **Pre-commit**: Comprehensive hooks including:
- Ruff formatting and linting (auto-fix enabled)
- MyPy type checking
- Standard checks (trailing whitespace, end-of-file-fixer, YAML/TOML/JSON validation)
- Security scanning with Bandit
- Markdown linting with markdownlint
- Custom hooks: MkDocs config validation, MCP imports check, documentation link validation
- **Note**: Direct commits to main/master branches are blocked by pre-commit
### Dependency Management
- All commands use `uv run` prefix instead of direct tool execution
- Workspace members have separate `pyproject.toml` files but share root configuration
- `uv.lock` file handles cross-workspace dependency resolution
## File Organization Logic
**Documentation Flow**:
1. Write content in `docs/` (shared)
2. MkDocs builds from `docs/` → `mkdocs-site/site/`
3. MCP server reads directly from `docs/` for live AI access
4. Both components stay synchronized to same source content
**Testing Strategy**:
- Unit tests focus on individual component logic
- Integration tests verify MkDocs + MCP server interaction
- Fixtures in `conftest.py` create realistic documentation structures for testing
## Additional Development Commands
### Validation and Configuration Checks
```bash
# Validate MkDocs configuration (strict mode)
make validate-mkdocs
# Validate all config files (pyproject.toml, JSON)
make validate-config
# Run pre-commit hooks on all files
make pre-commit
# Complete release check (quality + tests + validation)
make check-release
```
### Container Development
```bash
# Build development container manually
make container-build
# Run development container manually
make container-run
```
### Project Information and Maintenance
```bash
# Show project information and structure
make info
# Check for outdated dependencies
make check-deps
# Update all dependencies (use with caution)
make update-deps
# Reset development environment completely
make reset
```
## Working with MkDocs Material
When modifying documentation structure:
- Update `mkdocs-site/mkdocs.yml` `nav:` section for navigation changes
- Place documentation files in `docs/` (NOT `mkdocs-site/docs/`)
- Place custom CSS in `docs/stylesheets/` and custom JS in `docs/javascripts/`
- MkDocs will auto-reload during development (`make docs-serve`)
- MkDocs Material navigation features: tabs, sections, instant loading, path breadcrumbs
- Use frontmatter in Markdown files for metadata (title, description, tags)
## Working with MCP Server
When modifying the MCP server:
- All server code must use async/await for I/O operations
- Logging must go to stderr only (stdout is reserved for STDIO protocol)
- Resource URIs follow pattern: `docs://relative/path/to/file.md`
- Tools return structured responses (not raw text)
- Server defaults to `../docs` path relative to server location
- Dependencies: mcp, pydantic, anyio, aiofiles, python-frontmatter, markdown, watchfiles