This repository has been archived on 2026-03-10. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
labmcp/CLAUDE.md
Torjus Håkestad 4276ffbda5 feat: add optional basic auth support for Loki client
Some Loki deployments (e.g., behind a reverse proxy or Grafana Cloud)
require HTTP Basic Authentication. This adds optional --loki-username
and --loki-password flags (and corresponding env vars) to the
lab-monitoring server, along with NixOS module options for secure
credential management via systemd LoadCredential.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 20:32:10 +01:00

19 KiB

CLAUDE.md - Project Context

This file provides context for Claude when working on this project.

Project Overview

LabMCP is a collection of Model Context Protocol (MCP) servers written in Go, designed to extend Claude's capabilities with custom tools. The repository is structured to be generic and extensible, allowing multiple MCP servers to be added over time.

MCP Servers

Nixpkgs Search (nixpkgs-search) - Primary

Combined search for NixOS options and Nix packages from nixpkgs. Provides two separate MCP servers:

  • Options server: Search NixOS configuration options (nixpkgs-search options serve)
  • Packages server: Search Nix packages (nixpkgs-search packages serve)

NixOS Options (nixos-options) - Legacy

Search and query NixOS configuration options. Uses nixpkgs as source. Note: Prefer using nixpkgs-search options instead.

Home Manager Options (hm-options)

Search and query Home Manager configuration options. Uses home-manager repository as source.

Lab Monitoring (lab-monitoring)

Query Prometheus metrics, Alertmanager alerts, and Loki logs. Unlike other servers, this queries live HTTP APIs — no database or indexing needed.

  • 8 core tools: list/get alerts, search metrics, get metadata, PromQL query, list targets, list/create silences
  • 3 optional Loki tools (when LOKI_URL is set): query_logs, list_labels, list_label_values
  • Configurable Prometheus, Alertmanager, and Loki URLs via flags or environment variables
  • Optional basic auth for Loki (LOKI_USERNAME/LOKI_PASSWORD)

Git Explorer (git-explorer)

Read-only access to git repository information. Designed for deployment verification.

  • 9 tools: resolve_ref, get_log, get_commit_info, get_diff_files, get_file_at_commit, is_ancestor, commits_between, list_branches, search_commits
  • Uses go-git library for pure Go implementation
  • All operations are read-only (never modifies repository)

The nixpkgs/options/hm servers share a database-backed architecture:

  • Full-text search across option/package names and descriptions
  • Query specific options/packages with full metadata
  • Index multiple revisions (by git hash or channel name)
  • Fetch module source files
  • PostgreSQL and SQLite backends

Technology Stack

  • Language: Go 1.24+
  • Build System: Nix flakes
  • Databases: PostgreSQL and SQLite (both fully supported)
  • Protocol: MCP (Model Context Protocol) - JSON-RPC over STDIO or HTTP/SSE
  • Module Path: git.t-juice.club/torjus/labmcp

Project Status

Complete and maintained - All core features implemented:

  • Full MCP servers (6 tools each for nixpkgs/options, 8-11 tools for monitoring)
  • PostgreSQL and SQLite backends with FTS (for nixpkgs/options servers)
  • Live API queries for Prometheus/Alertmanager/Loki (monitoring server)
  • NixOS modules for deployment
  • CLI for manual operations
  • Comprehensive test suite

Repository Structure

labmcp/
├── cmd/
│   ├── nixpkgs-search/
│   │   └── main.go             # Combined options+packages CLI (primary)
│   ├── nixos-options/
│   │   └── main.go             # NixOS options CLI (legacy)
│   ├── hm-options/
│   │   └── main.go             # Home Manager options CLI
│   ├── lab-monitoring/
│   │   └── main.go             # Prometheus/Alertmanager CLI
│   └── git-explorer/
│       └── main.go             # Git repository explorer CLI
├── internal/
│   ├── database/
│   │   ├── interface.go        # Store interface (options + packages)
│   │   ├── schema.go           # Schema versioning
│   │   ├── postgres.go         # PostgreSQL implementation
│   │   ├── sqlite.go           # SQLite implementation
│   │   └── *_test.go           # Database tests
│   ├── mcp/
│   │   ├── server.go           # MCP server core + ServerConfig + modes
│   │   ├── handlers.go         # Tool implementations (options + packages)
│   │   ├── types.go            # Protocol types
│   │   ├── transport.go        # Transport interface
│   │   ├── transport_stdio.go  # STDIO transport
│   │   ├── transport_http.go   # HTTP/SSE transport
│   │   ├── session.go          # HTTP session management
│   │   └── *_test.go           # MCP tests
│   ├── options/
│   │   └── indexer.go          # Shared Indexer interface
│   ├── nixos/
│   │   ├── indexer.go          # NixOS options indexing
│   │   ├── parser.go           # options.json parsing
│   │   ├── types.go            # Channel aliases, extensions
│   │   └── *_test.go           # Indexer tests
│   ├── homemanager/
│   │   ├── indexer.go          # Home Manager indexing
│   │   ├── types.go            # Channel aliases, extensions
│   │   └── *_test.go           # Indexer tests
│   ├── packages/
│   │   ├── indexer.go          # Nix packages indexing
│   │   ├── parser.go           # nix-env JSON parsing
│   │   ├── types.go            # Package types, channel aliases
│   │   └── *_test.go           # Parser tests
│   ├── monitoring/
│   │   ├── types.go            # Prometheus/Alertmanager/Loki API types
│   │   ├── prometheus.go       # Prometheus HTTP client
│   │   ├── alertmanager.go     # Alertmanager HTTP client
│   │   ├── loki.go             # Loki HTTP client
│   │   ├── handlers.go         # MCP tool definitions + handlers
│   │   ├── format.go           # Markdown formatting utilities
│   │   └── *_test.go           # Tests (httptest-based)
│   └── gitexplorer/
│       ├── client.go           # go-git repository wrapper
│       ├── types.go            # Type definitions
│       ├── handlers.go         # MCP tool definitions + handlers
│       ├── format.go           # Markdown formatters
│       ├── validation.go       # Path validation
│       └── *_test.go           # Tests
├── nix/
│   ├── module.nix                  # NixOS module for nixos-options
│   ├── hm-options-module.nix       # NixOS module for hm-options
│   ├── lab-monitoring-module.nix   # NixOS module for lab-monitoring
│   ├── git-explorer-module.nix     # NixOS module for git-explorer
│   └── package.nix                 # Parameterized Nix package
├── testdata/
│   └── options-sample.json     # Test fixture
├── flake.nix
├── go.mod
├── .mcp.json                   # MCP client configuration
├── CLAUDE.md                   # This file
├── README.md
└── TODO.md                     # Future improvements

MCP Tools

Options Servers (nixpkgs-search options, nixos-options, hm-options)

Tool Description
search_options Full-text search across option names and descriptions
get_option Get full details for a specific option with children
get_file Fetch source file contents from indexed repository
index_revision Index a revision (options, files, and packages for nixpkgs)
list_revisions List all indexed revisions
delete_revision Delete an indexed revision

Packages Server (nixpkgs-search packages)

Tool Description
search_packages Full-text search across package names and descriptions
get_package Get full details for a specific package by attr path
get_file Fetch source file contents from nixpkgs
index_revision Index a revision to make its packages searchable
list_revisions List all indexed revisions
delete_revision Delete an indexed revision

Monitoring Server (lab-monitoring)

Tool Description
list_alerts List alerts with optional filters (state, severity, receiver)
get_alert Get full details for a specific alert by fingerprint
search_metrics Search metric names with substring filter, enriched with metadata
get_metric_metadata Get type, help text, and unit for a specific metric
query Execute instant PromQL query
list_targets List scrape targets with health status
list_silences List active/pending silences
create_silence Create a silence (confirms with user first)
query_logs Execute a LogQL range query against Loki (requires LOKI_URL)
list_labels List available label names from Loki (requires LOKI_URL)
list_label_values List values for a specific label from Loki (requires LOKI_URL)

Git Explorer Server (git-explorer)

Tool Description
resolve_ref Resolve a git ref (branch, tag, commit) to its full commit hash
get_log Get commit log with optional filters (author, path, limit)
get_commit_info Get full details for a specific commit
get_diff_files Get list of files changed between two commits
get_file_at_commit Get file contents at a specific commit
is_ancestor Check if one commit is an ancestor of another
commits_between Get all commits between two refs
list_branches List all branches in the repository
search_commits Search commit messages for a pattern

Key Implementation Details

Database

  • Schema versioning with automatic recreation on version mismatch
  • Full-text search: SQLite FTS5, PostgreSQL tsvector/GIN
  • Path-based queries use LIKE for exact prefix matching
  • Batch operations for efficient indexing

Indexing

  • Uses nix-build to evaluate options from any revision
  • File indexing downloads tarball and stores allowed extensions (.nix, .json, .md, etc.)
  • File indexing enabled by default (use --no-files to skip)
  • Skips already-indexed revisions (use --force to re-index)

Transports

  • STDIO: Default transport, line-delimited JSON-RPC (for CLI/desktop MCP clients)
  • HTTP: Streamable HTTP transport with SSE (for web-based MCP clients)
    • Session management with cryptographically secure IDs
    • Configurable CORS (localhost-only by default)
    • Optional TLS support
    • SSE keepalive messages (15s default)

Security

  • Revision parameter validated against strict regex to prevent Nix injection
  • Path traversal protection using filepath.Clean() and filepath.IsAbs()
  • NixOS module supports connectionStringFile for PostgreSQL secrets
  • Systemd service runs with extensive hardening options
  • HTTP transport hardening:
    • Request body size limit (1MB default)
    • Server timeouts (read: 30s, write: 30s, idle: 120s, header: 10s)
    • Maximum session limit (10,000 default)
    • Origin validation for CORS

CLI Commands

nixpkgs-search (Primary)

# Options MCP Server
nixpkgs-search options serve           # Run options MCP server on STDIO
nixpkgs-search options search <query>  # Search options
nixpkgs-search options get <option>    # Get option details

# Packages MCP Server
nixpkgs-search packages serve          # Run packages MCP server on STDIO
nixpkgs-search packages search <query> # Search packages
nixpkgs-search packages get <attr>     # Get package details

# Combined Indexing
nixpkgs-search index <revision>        # Index options AND packages
nixpkgs-search index --no-packages <r> # Index options only (faster)
nixpkgs-search index --no-options <r>  # Index packages only
nixpkgs-search index --no-files <r>    # Skip file indexing
nixpkgs-search index --force <r>       # Force re-index

# Shared Commands
nixpkgs-search list                    # List indexed revisions
nixpkgs-search delete <revision>       # Delete indexed revision
nixpkgs-search --version               # Show version

nixos-options (Legacy)

nixos-options serve                    # Run MCP server on STDIO (default)
nixos-options serve --transport http   # Run MCP server on HTTP
nixos-options index <revision>         # Index a nixpkgs revision
nixos-options index --force <r>        # Force re-index existing revision
nixos-options index --no-files         # Skip file content indexing
nixos-options list                     # List indexed revisions
nixos-options search <query>           # Search options
nixos-options get <option>             # Get option details
nixos-options delete <revision>        # Delete indexed revision
nixos-options --version                # Show version

hm-options

hm-options serve                       # Run MCP server on STDIO (default)
hm-options serve --transport http      # Run MCP server on HTTP
hm-options index <revision>            # Index a home-manager revision
hm-options index --force <r>           # Force re-index existing revision
hm-options index --no-files            # Skip file content indexing
hm-options list                        # List indexed revisions
hm-options search <query>              # Search options
hm-options get <option>                # Get option details
hm-options delete <revision>           # Delete indexed revision
hm-options --version                   # Show version

lab-monitoring

lab-monitoring serve                          # Run MCP server on STDIO
lab-monitoring serve --transport http         # Run MCP server on HTTP
lab-monitoring alerts                         # List alerts
lab-monitoring alerts --state active          # Filter by state
lab-monitoring query 'up'                     # Instant PromQL query
lab-monitoring targets                        # List scrape targets
lab-monitoring metrics node                   # Search metric names
lab-monitoring logs '{job="varlogs"}'          # Query logs (requires LOKI_URL)
lab-monitoring logs '{job="nginx"} |= "error"' --start 2h --limit 50
lab-monitoring labels                         # List Loki labels
lab-monitoring labels --values job            # List values for a label

git-explorer

git-explorer serve                            # Run MCP server on STDIO
git-explorer serve --transport http           # Run MCP server on HTTP
git-explorer --repo /path resolve <ref>       # Resolve ref to commit hash
git-explorer --repo /path log --limit 10      # Show commit log
git-explorer --repo /path show <ref>          # Show commit details
git-explorer --repo /path diff <from> <to>    # Files changed between commits
git-explorer --repo /path cat <ref> <path>    # File contents at commit
git-explorer --repo /path branches            # List branches
git-explorer --repo /path search <query>      # Search commit messages
git-explorer --version                        # Show version

Channel Aliases

nixpkgs-search/nixos-options: nixos-unstable, nixos-stable, nixos-24.11, nixos-24.05, etc.

hm-options: hm-unstable, hm-stable, master, release-24.11, release-24.05, etc.

Notes for Claude

Planning

When creating implementation plans, the first step should usually be to checkout an appropriately named feature branch (e.g., git checkout -b feature/lab-monitoring). This keeps work isolated and makes PRs cleaner.

After implementing a plan, update the README.md to reflect any new or changed functionality (new servers, tools, CLI commands, configuration options, NixOS module options, etc.).

Development Workflow

  • Always run go fmt ./... before committing Go code
  • Run Go commands using nix develop -c (e.g., nix develop -c go test ./...)
  • Use nix run to run/test binaries (e.g., nix run .#nixpkgs-search -- options serve)
    • Do NOT use go build -o /tmp/... to test binaries - always use nix run
    • Remember: modified files must be tracked by git for nix run to see them
  • File paths in responses should use format path/to/file.go:123

Linting

Before completing work on a feature, run all linting tools to ensure code quality:

# Run all linters (should report 0 issues)
nix develop -c golangci-lint run ./...

# Check for known vulnerabilities in dependencies
nix develop -c govulncheck ./...

# Run go vet for additional static analysis
nix develop -c go vet ./...

All three tools should pass with no issues before merging a feature branch.

Nix Build Requirement

IMPORTANT: When running nix build, nix run, or similar commands, new files must be tracked by git first. Nix flakes only see git-tracked files. If you create new files, run git add <file> before attempting nix operations.

Version Bumping

Version bumps should be done once per feature branch, not per commit. Only bump versions for packages that were actually changed — different packages can have different version numbers.

Rules for determining bump type:

  • Patch bump (0.1.0 → 0.1.1): Changes to Go code within internal/ that affect a program
  • Minor bump (0.1.0 → 0.2.0): Changes to Go code outside internal/ (e.g., cmd/)
  • Major bump (0.1.0 → 1.0.0): Breaking changes to CLI usage or MCP protocol

Each package's version is defined in multiple places that must stay in sync for that package:

  • lab-monitoring: cmd/lab-monitoring/main.go + internal/mcp/server.go (DefaultMonitoringConfig)
  • nixpkgs-search: cmd/nixpkgs-search/main.go + internal/mcp/server.go (DefaultNixOSConfig, DefaultNixpkgsPackagesConfig)
  • nixos-options: cmd/nixos-options/main.go + internal/mcp/server.go (DefaultNixOSConfig)
  • hm-options: cmd/hm-options/main.go + internal/mcp/server.go (DefaultHomeManagerConfig)
  • git-explorer: cmd/git-explorer/main.go + internal/mcp/server.go (DefaultGitExplorerConfig)
  • nix/package.nix: Shared across all packages (bump to highest version when any package changes)

User Preferences

  • User prefers PostgreSQL over SQLite (has homelab infrastructure)
  • User values good test coverage and benchmarking
  • Project should remain generic to support future MCP servers

Testing

# Run all tests
nix develop -c go test ./... -short

# Run with verbose output
nix develop -c go test ./... -v

# Run benchmarks (requires nix-build)
nix develop -c go test -bench=. -benchtime=1x -timeout=30m ./internal/nixos/...
nix develop -c go test -bench=. -benchtime=1x -timeout=30m ./internal/homemanager/...

Building

# Build with nix
nix build .#nixpkgs-search
nix build .#nixos-options
nix build .#hm-options
nix build .#lab-monitoring
nix build .#git-explorer

# Run directly
nix run .#nixpkgs-search -- options serve
nix run .#nixpkgs-search -- packages serve
nix run .#nixpkgs-search -- index nixos-unstable
nix run .#hm-options -- serve
nix run .#hm-options -- index hm-unstable
nix run .#lab-monitoring -- serve
nix run .#git-explorer -- --repo . serve

Indexing Performance

Indexing operations are slow due to Nix evaluation and file downloads. When running index commands, use appropriate timeouts:

  • nixpkgs-search (full): ~15-20 minutes for nixos-unstable (options + packages + files)
  • nixpkgs-search (options only): ~5-6 minutes with --no-packages
  • nixpkgs-search (packages only): ~10-15 minutes with --no-options
  • hm-options: ~1-2 minutes for master (with files)

Use --no-files flag to skip file indexing for faster results. Use --no-packages to index only options (matches legacy behavior).