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:
248
CLAUDE.md
248
CLAUDE.md
@@ -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
|
||||||
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user