Package search now prioritizes results in this order: 1. Exact pname match 2. Exact attr_path match 3. pname starts with query 4. attr_path starts with query 5. FTS ranking (bm25 for SQLite, ts_rank for PostgreSQL) This ensures searching for "git" returns the "git" package first, rather than packages that merely mention "git" in their description. Also update CLAUDE.md to clarify using `nix run` instead of `go build -o` for testing binaries. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
12 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.
All servers share the same 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 with 6 tools each
- PostgreSQL and SQLite backends with FTS
- 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
├── 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
├── nix/
│ ├── module.nix # NixOS module for nixos-options
│ ├── hm-options-module.nix # NixOS module for hm-options
│ └── 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 (by hash or channel name) |
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 |
list_revisions |
List all indexed revisions |
delete_revision |
Delete an indexed revision |
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-buildto evaluate options from any revision - File indexing downloads tarball and stores allowed extensions (.nix, .json, .md, etc.)
- File indexing enabled by default (use
--no-filesto skip) - Skips already-indexed revisions (use
--forceto 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()andfilepath.IsAbs() - NixOS module supports
connectionStringFilefor 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
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
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 runto run/test binaries (e.g.,nix run .#nixpkgs-search -- options serve)- Do NOT use
go build -o /tmp/...to test binaries - always usenix run - Remember: modified files must be tracked by git for
nix runto see them
- Do NOT use
- 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. Rules:
- 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
Version is defined in multiple places that must stay in sync:
cmd/nixpkgs-search/main.gocmd/nixos-options/main.gocmd/hm-options/main.gointernal/mcp/server.go(inDefaultNixOSConfig,DefaultHomeManagerConfig,DefaultNixpkgsPackagesConfig)nix/package.nix
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
# 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
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).