docs: update CLAUDE.md to reflect current project state

The file was still showing "Planning phase" with outdated next steps.
Updated to reflect the complete implementation:

- Changed status to "Complete and maintained"
- Updated repository structure to match actual layout
- Documented all 6 MCP tools as implemented
- Added key implementation details (database, indexing, security)
- Added CLI command reference
- Consolidated development notes
- Removed obsolete planning sections

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-03 21:40:59 +01:00
parent 5e043e724e
commit 0b7333844a

248
CLAUDE.md
View File

@@ -12,176 +12,136 @@ The first MCP server provides search and query capabilities for NixOS configurat
## Technology Stack ## Technology Stack
- **Language**: Go 1.25.5 - **Language**: Go 1.24+
- **Build System**: Nix flakes - **Build System**: Nix flakes
- **Databases**: PostgreSQL (primary) and SQLite (lightweight alternative) - **Databases**: PostgreSQL and SQLite (both fully supported)
- **Protocol**: MCP (Model Context Protocol) - JSON-RPC over stdio - **Protocol**: MCP (Model Context Protocol) - JSON-RPC over stdio
- **Module Path**: `git.t-juice.club/torjus/labmcp` - **Module Path**: `git.t-juice.club/torjus/labmcp`
## Key Architectural Decisions ## Project Status
1. **Database Support**: Both PostgreSQL and SQLite **Complete and maintained** - All core features implemented:
- PostgreSQL is preferred for production use (user's preference) - Full MCP server with 6 tools
- SQLite provides lightweight alternative for simpler deployments - PostgreSQL and SQLite backends with FTS
- Use Go's `database/sql` interface for abstraction - NixOS module for deployment
- CLI for manual operations
- Comprehensive test suite
2. **File Storage**: Store nixpkgs file contents in database during indexing ## Repository Structure
- Better performance for the `get_file` tool
- PostgreSQL handles large text storage well
3. **Revision Management**: Support multiple indexed nixpkgs revisions
- Store git hash, date, channel name, option count
- Allow querying specific revisions or use defaults
- Default revision: nixos-stable (configurable)
4. **Indexing Approach**: Part of MCP server, blocking operation (initially)
- Allows Claude to read flake.lock and request indexing
- Can optimize to async later if needed
5. **Testing**: Aim for >80% test coverage
- Unit tests for all components
- Integration tests for full workflows
- Benchmarks for indexing and query performance
## MCP Tools to Implement
### Core Search & Query
1. **`search_options`** - Fuzzy/partial matching search
- Parameters: revision, query, optional filters (type, namespace, hasDefault)
- Returns: matching options with basic metadata
2. **`get_option`** - Get full details for specific option
- Parameters: revision, option_path, optional depth
- Returns: name, type, default, example, description, file paths
- Default: direct children only (one level deep)
- Includes related/nearby options in same namespace
3. **`get_file`** - Fetch nixpkgs source file contents
- Parameters: revision, file_path
- Returns: file contents
- Security: validate paths, no traversal, nixpkgs-only
### Revision Management
4. **`index_revision`** - Index a specific nixpkgs revision
- Parameters: git_hash (full or short)
- Process: fetch nixpkgs, extract options.json, populate DB
- Returns: summary (option count, duration, etc.)
5. **`list_revisions`** - List indexed revisions
- Returns: git hash, date, channel name, option count
6. **`delete_revision`** - Prune old/unused revisions
- Parameters: revision identifier
- Returns: confirmation of deletion
### Channel Support
- Support friendly aliases: `nixos-unstable`, `nixos-24.05`, `nixos-23.11`, etc.
- Can be used in place of git hashes in all tools
## Database Schema
**Tables:**
1. `revisions` - Indexed nixpkgs versions
- id, git_hash (unique), channel_name, commit_date, indexed_at, option_count
2. `options` - NixOS options with hierarchy support
- id, revision_id (FK), name, parent_path, type, default_value (JSON text), example (JSON text), description, read_only
- parent_path enables efficient "list children" queries (derived from name)
3. `declarations` - File paths where options are declared
- id, option_id (FK), file_path, line_number
4. `files` - Cached file contents
- id, revision_id (FK), file_path, extension, content
- Configurable whitelist of extensions (default: .nix, .json, .md, .txt, .toml, .yaml, .yml)
**Indexes:**
- Full-text search: PostgreSQL (tsvector/GIN), SQLite (FTS5)
- B-tree on (revision_id, name) and (revision_id, parent_path)
- B-tree on (revision_id, file_path) for file lookups
**Cross-DB Compatibility:**
- JSON stored as TEXT (not JSONB) for SQLite compatibility
- Separate FTS implementations per database engine
## Repository Structure (Planned)
``` ```
labmcp/ labmcp/
├── cmd/ ├── cmd/
│ └── nixos-options/ # MCP server binary │ └── nixos-options/
│ └── main.go │ └── main.go # CLI entry point
├── internal/ ├── internal/
│ ├── mcp/ # MCP protocol implementation │ ├── database/
│ │ ├── server.go │ │ ├── interface.go # Store interface
│ │ ── types.go │ │ ── schema.go # Schema versioning
│ ├── database/ # Database abstraction │ ├── postgres.go # PostgreSQL implementation
│ │ ├── interface.go │ │ ├── sqlite.go # SQLite implementation
│ │ ── postgres.go │ │ ── *_test.go # Database tests
│ └── sqlite.go ├── mcp/
└── nixos/ # NixOS options specific logic │ ├── server.go # MCP server loop
├── search.go ├── handlers.go # Tool implementations
── types.go ── types.go # Protocol types
├── scripts/ │ │ └── server_test.go # MCP tests
│ └── populate-db.go # Tool to populate database │ └── nixos/
├── schema/ │ ├── indexer.go # Nixpkgs indexing
└── schema.sql # Database schema ├── parser.go # options.json parsing
├── flake.nix # Nix build configuration │ ├── types.go # Channel aliases, extensions
│ └── *_test.go # Indexer tests
├── nix/
│ ├── module.nix # NixOS module
│ └── package.nix # Nix package definition
├── testdata/
│ └── options-sample.json # Test fixture
├── flake.nix
├── go.mod ├── go.mod
├── TODO.md # Detailed task list ├── .mcp.json # MCP client configuration
├── CLAUDE.md # This file ├── CLAUDE.md # This file
── README.md ── README.md
└── TODO.md # Future improvements
``` ```
## Use Cases ## MCP Tools
**Primary Use Case**: Claude can help users find and understand NixOS options All tools are implemented and functional:
- "What options are available for nginx?"
- "Show me the services.caddy.* options"
- "What's the default value for services.postgresql.enable?"
- User shares a flake.lock → Claude indexes that nixpkgs version → answers questions about options in that specific version
**Secondary Use Case**: Explore module implementations | Tool | Description |
- If option description is unclear, fetch the actual module source |------|-------------|
- Understand how complex options are structured | `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 nixpkgs |
| `index_revision` | Index a nixpkgs revision (by hash or channel name) |
| `list_revisions` | List all indexed revisions |
| `delete_revision` | Delete an indexed revision |
## Testing Strategy ## Key Implementation Details
- **Unit Tests**: All components with mocks where appropriate ### Database
- **Integration Tests**: Full indexing pipeline, MCP tool invocations - Schema versioning with automatic recreation on version mismatch
- **Benchmarks**: Indexing time, query performance, memory usage - Full-text search: SQLite FTS5, PostgreSQL tsvector/GIN
- **Test Fixtures**: Sample options.json, mock repositories - Path-based queries use LIKE for exact prefix matching
- **Coverage Goal**: >80% on core logic, 100% on database operations - Batch operations for efficient indexing
## Open Questions ### Indexing
- Uses `nix-build` to evaluate NixOS options from any nixpkgs 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)
1. Should `index_revision` be blocking or async? (Currently: blocking, optimize later) ### Security
2. Should we auto-update channel aliases or manual only? - 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
## Current Status ## CLI Commands
**Planning phase** - architecture and features defined, ready to begin implementation. ```bash
nixos-options serve # Run MCP server on stdio
## Next Steps nixos-options index <revision> # Index a nixpkgs revision
nixos-options index --force <r> # Force re-index existing revision
1. Design and implement database schema nixos-options index --no-files # Skip file content indexing
2. Set up project structure (directories, Go modules) nixos-options list # List indexed revisions
3. Implement database abstraction layer nixos-options search <query> # Search options
4. Implement MCP protocol basics nixos-options get <option> # Get option details
5. Build indexing logic nixos-options delete <revision> # Delete indexed revision
6. Implement MCP tools nixos-options --version # Show version
7. Create Nix package in flake.nix ```
8. Write tests and benchmarks
## Notes for Claude ## 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 run` to run binaries** (e.g., `nix run .#nixos-options -- serve`)
- File paths in responses should use format `path/to/file.go:123`
### User Preferences
- User prefers PostgreSQL over SQLite (has homelab infrastructure) - User prefers PostgreSQL over SQLite (has homelab infrastructure)
- User values good test coverage and benchmarking - User values good test coverage and benchmarking
- Project should remain generic to support future MCP servers - Project should remain generic to support future MCP servers
- Nix flake must provide importable packages for other repos
- Use `database/sql` interface for database abstraction ### Testing
- File paths in responses should use format `path/to/file.go:123` ```bash
- **Always run `go fmt ./...` before committing Go code** # Run all tests
- **Run Go commands using `nix develop -c`** (e.g., `nix develop -c go test ./...`) to ensure proper build environment with all dependencies nix develop -c go test ./... -short
- **Use `nix run` to run binaries** instead of `go build` followed by running the binary (e.g., `nix run .#nixos-options -- serve`)
# 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/...
```
### Building
```bash
# Build with nix
nix build
# Run directly
nix run . -- serve
nix run . -- index nixos-unstable
```