feature/streamable-http-transport #1
248
CLAUDE.md
248
CLAUDE.md
@@ -12,176 +12,136 @@ The first MCP server provides search and query capabilities for NixOS configurat
|
||||
|
||||
## Technology Stack
|
||||
|
||||
- **Language**: Go 1.25.5
|
||||
- **Language**: Go 1.24+
|
||||
- **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
|
||||
- **Module Path**: `git.t-juice.club/torjus/labmcp`
|
||||
|
||||
## Key Architectural Decisions
|
||||
## Project Status
|
||||
|
||||
1. **Database Support**: Both PostgreSQL and SQLite
|
||||
- PostgreSQL is preferred for production use (user's preference)
|
||||
- SQLite provides lightweight alternative for simpler deployments
|
||||
- Use Go's `database/sql` interface for abstraction
|
||||
**Complete and maintained** - All core features implemented:
|
||||
- Full MCP server with 6 tools
|
||||
- PostgreSQL and SQLite backends with FTS
|
||||
- NixOS module for deployment
|
||||
- CLI for manual operations
|
||||
- Comprehensive test suite
|
||||
|
||||
2. **File Storage**: Store nixpkgs file contents in database during indexing
|
||||
- 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)
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
labmcp/
|
||||
├── cmd/
|
||||
│ └── nixos-options/ # MCP server binary
|
||||
│ └── main.go
|
||||
│ └── nixos-options/
|
||||
│ └── main.go # CLI entry point
|
||||
├── internal/
|
||||
│ ├── mcp/ # MCP protocol implementation
|
||||
│ │ ├── server.go
|
||||
│ │ └── types.go
|
||||
│ ├── database/ # Database abstraction
|
||||
│ │ ├── interface.go
|
||||
│ │ ├── postgres.go
|
||||
│ │ └── sqlite.go
|
||||
│ └── nixos/ # NixOS options specific logic
|
||||
│ ├── search.go
|
||||
│ └── types.go
|
||||
├── scripts/
|
||||
│ └── populate-db.go # Tool to populate database
|
||||
├── schema/
|
||||
│ └── schema.sql # Database schema
|
||||
├── flake.nix # Nix build configuration
|
||||
│ ├── database/
|
||||
│ │ ├── interface.go # Store interface
|
||||
│ │ ├── schema.go # Schema versioning
|
||||
│ │ ├── postgres.go # PostgreSQL implementation
|
||||
│ │ ├── sqlite.go # SQLite implementation
|
||||
│ │ └── *_test.go # Database tests
|
||||
│ ├── mcp/
|
||||
│ │ ├── server.go # MCP server loop
|
||||
│ │ ├── handlers.go # Tool implementations
|
||||
│ │ ├── types.go # Protocol types
|
||||
│ │ └── server_test.go # MCP tests
|
||||
│ └── nixos/
|
||||
│ ├── indexer.go # Nixpkgs indexing
|
||||
│ ├── parser.go # options.json parsing
|
||||
│ ├── 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
|
||||
├── TODO.md # Detailed task list
|
||||
├── .mcp.json # MCP client configuration
|
||||
├── 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
|
||||
- "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
|
||||
All tools are implemented and functional:
|
||||
|
||||
**Secondary Use Case**: Explore module implementations
|
||||
- If option description is unclear, fetch the actual module source
|
||||
- Understand how complex options are structured
|
||||
| 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 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
|
||||
- **Integration Tests**: Full indexing pipeline, MCP tool invocations
|
||||
- **Benchmarks**: Indexing time, query performance, memory usage
|
||||
- **Test Fixtures**: Sample options.json, mock repositories
|
||||
- **Coverage Goal**: >80% on core logic, 100% on database operations
|
||||
### 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
|
||||
|
||||
## 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)
|
||||
2. Should we auto-update channel aliases or manual only?
|
||||
### 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
|
||||
|
||||
## Current Status
|
||||
## CLI Commands
|
||||
|
||||
**Planning phase** - architecture and features defined, ready to begin implementation.
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Design and implement database schema
|
||||
2. Set up project structure (directories, Go modules)
|
||||
3. Implement database abstraction layer
|
||||
4. Implement MCP protocol basics
|
||||
5. Build indexing logic
|
||||
6. Implement MCP tools
|
||||
7. Create Nix package in flake.nix
|
||||
8. Write tests and benchmarks
|
||||
```bash
|
||||
nixos-options serve # Run MCP server on stdio
|
||||
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
|
||||
```
|
||||
|
||||
## 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 values good test coverage and benchmarking
|
||||
- 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
|
||||
- File paths in responses should use format `path/to/file.go:123`
|
||||
- **Always run `go fmt ./...` before committing Go code**
|
||||
- **Run Go commands using `nix develop -c`** (e.g., `nix develop -c go test ./...`) to ensure proper build environment with all dependencies
|
||||
- **Use `nix run` to run binaries** instead of `go build` followed by running the binary (e.g., `nix run .#nixos-options -- serve`)
|
||||
|
||||
### Testing
|
||||
```bash
|
||||
# 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/...
|
||||
```
|
||||
|
||||
### Building
|
||||
```bash
|
||||
# Build with nix
|
||||
nix build
|
||||
|
||||
# Run directly
|
||||
nix run . -- serve
|
||||
nix run . -- index nixos-unstable
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user