Commit Graph

31 Commits

Author SHA1 Message Date
149832e4e5 security: add request body size limit to prevent DoS
Add MaxRequestSize configuration to HTTPConfig with a default of 1MB.
Use http.MaxBytesReader to enforce the limit, returning 413 Request
Entity Too Large when exceeded.

This prevents memory exhaustion attacks where an attacker sends
arbitrarily large request bodies.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:04:11 +01:00
cbe55d6456 feat: add Streamable HTTP transport support
Add support for running the MCP server over HTTP with Server-Sent Events
(SSE) using the MCP Streamable HTTP specification, alongside the existing
STDIO transport.

New features:
- Transport abstraction with Transport interface
- HTTP transport with session management
- SSE support for server-initiated notifications
- CORS security with configurable allowed origins
- Optional TLS support
- CLI flags for HTTP configuration (--transport, --http-address, etc.)
- NixOS module options for HTTP transport

The HTTP transport implements:
- POST /mcp: JSON-RPC requests with session management
- GET /mcp: SSE stream for server notifications
- DELETE /mcp: Session termination
- Origin validation (localhost-only by default)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:02:40 +01:00
0b7333844a 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>
2026-02-03 21:40:59 +01:00
5e043e724e chore: add MCP configuration file
Example configuration for running the nixos-options MCP server
via Claude Code or other MCP clients.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 19:14:36 +01:00
cc369e6385 security: add connectionStringFile option for PostgreSQL secrets
The connectionString option stores credentials in the world-readable
Nix store. This adds connectionStringFile as an alternative that reads
the connection string from a file at runtime, compatible with secret
management tools like agenix or sops-nix.

Changes:
- Add database.connectionStringFile option (mutually exclusive with connectionString)
- Read connection string from file at service start when configured
- Add warning to connectionString documentation about Nix store visibility
- Update README with examples for both approaches

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 19:13:20 +01:00
f0adc9efbe security: improve path validation in get_file handler
The previous check only looked for ".." substring, which missed:
- Absolute paths (/etc/passwd)
- URL-encoded traversal patterns
- Paths that clean to traversal (./../../etc)

Now uses filepath.Clean() and filepath.IsAbs() for robust validation:
- Rejects absolute paths
- Cleans paths before checking for traversal
- Uses cleaned path for database lookup

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 19:12:25 +01:00
be1ff4839b security: validate revision parameter to prevent Nix injection
The revision parameter was interpolated directly into a Nix expression,
allowing potential injection of arbitrary Nix code. An attacker could
craft a revision string like:
  "; builtins.readFile /etc/passwd; "

This adds ValidateRevision() which ensures revisions only contain safe
characters (alphanumeric, hyphens, underscores, dots) and are at most
64 characters long.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 19:10:31 +01:00
5f0445e749 docs: add nix develop note to CLAUDE.md
Go commands should be run via nix develop -c to ensure the proper
build environment with all dependencies (like gcc for cgo).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 19:01:52 +01:00
730f2d7610 feat: skip already-indexed revisions, add --force flag
When indexing a revision that already exists, the indexer now returns
early with information about the existing revision instead of re-indexing.
Use the --force flag to re-index an existing revision.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:59:44 +01:00
ae6a4d6cf9 feat: add --version flag to CLI
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:55:44 +01:00
11c300c4e7 docs: update TODO.md with future improvements
Replace completed planning document with actionable improvement ideas.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:53:55 +01:00
8627bfbe0a feat: add MCP server instructions for flake.lock indexing
Provides guidance to AI assistants on how to index the nixpkgs
revision from a project's flake.lock file, ensuring option
documentation matches the project's actual nixpkgs version.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:50:51 +01:00
452b0fda86 feat: enable file indexing by default
File indexing only adds ~3 seconds to the indexing process, so enable
it by default to make the get_file tool work out of the box.

- MCP index_revision tool now indexes files automatically
- CLI flag changed from --files to --no-files (opt-out)
- Update README examples

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:45:50 +01:00
3ba85691a8 test: improve file indexing benchmarks
- BenchmarkIndexRevisionWithFiles now reports separate timing for
  options indexing (options_ms) and file indexing (files_ms)
- Add BenchmarkIndexFilesOnly to measure file indexing in isolation

Run with:
  go test -bench=BenchmarkIndexFilesOnly -benchtime=1x -timeout=60m ./internal/nixos/...

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:42:02 +01:00
23076fa112 refactor: move package definition to nix/package.nix
Keeps flake.nix cleaner by extracting the package definition.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:29:37 +01:00
e2c006cb9f docs: add NixOS module documentation to README
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:27:11 +01:00
43ffc234ac feat: add NixOS module for nixos-options-mcp service
Module provides:
- services.nixos-options-mcp.enable - Enable the service
- services.nixos-options-mcp.package - Package to use
- services.nixos-options-mcp.database.type - sqlite or postgres
- services.nixos-options-mcp.database.name - SQLite filename
- services.nixos-options-mcp.database.connectionString - PostgreSQL URL
- services.nixos-options-mcp.indexOnStart - Revisions to index on start
- services.nixos-options-mcp.user/group - Service user/group
- services.nixos-options-mcp.dataDir - Data directory

Includes systemd hardening options.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:26:29 +01:00
88e8a55347 fix: improve search to prioritize path-based matching
When searching for option paths like "services.nginx", use name-based
LIKE matching instead of full-text search. This ensures the results
are options that start with the query, not random options that mention
the term somewhere in their description.

- Path queries (containing dots): use LIKE for name prefix matching
- Text queries (no dots): use FTS for full-text search on name+description

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:23:50 +01:00
ec0eba4bef fix: escape FTS5 queries to handle special characters
Wrap search queries in double quotes for FTS5 literal matching.
This prevents dots, colons, and other special characters from
being interpreted as FTS5 operators.

Fixes: "fts5: syntax error near '.'" when searching for option
paths like "services.nginx".

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:09:32 +01:00
d82990fbfa test: add test for search with special characters
Tests searching with dots, colons, hyphens, and parentheses.
Currently fails on SQLite due to FTS5 syntax interpretation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:08:55 +01:00
9352fd1f6e docs: update README with usage instructions
- Add installation instructions (nix flakes, go install)
- Add MCP server configuration example
- Add CLI examples for all commands
- Document environment variables and database connection strings
- List available MCP tools

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:58:02 +01:00
849ff38597 feat: wrap nixos-options binary with nix in PATH
The indexer requires nix-build to evaluate NixOS options.
Use makeWrapper to add nix to the binary's PATH.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:55:34 +01:00
f18a7e2626 test: add indexer benchmark and integration test
- BenchmarkIndexRevision: benchmark full nixpkgs indexing
- BenchmarkIndexRevisionWithFiles: benchmark with file content storage
- TestIndexRevision: integration test for indexer
- Uses nixpkgs revision from flake.lock (e6eae2ee...)
- Skips if nix-build not available or in short mode

Run with: go test -bench=BenchmarkIndexRevision -benchtime=1x -timeout=30m ./internal/nixos/...

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:55:34 +01:00
610dc7bd61 chore: add CLAUDE.md and gitignore
- Add project context file for Claude
- Ignore nix result symlink

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:55:34 +01:00
939abc8d8e test: MCP server tests, benchmarks, and nix build fix
- Add MCP server protocol tests (initialize, tools/list, errors)
- Add database benchmarks (batch inserts, search, children)
- Add sample options.json test fixture
- Fix flake.nix vendor hash for nix build

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:54:42 +01:00
f7112d4459 feat: CLI integration with database and MCP server
- Wire up all CLI commands to database operations
- Add 'get' command for single option details
- Add '--files' flag to 'index' for file content indexing
- Support postgres:// and sqlite:// connection strings
- Default to SQLite database file

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:54:42 +01:00
0b0ada3ccd feat: MCP tools and nixpkgs indexer
- Add options.json parser with mdDoc support
- Add nixpkgs indexer using nix-build
- Implement all MCP tool handlers:
  - search_options: Full-text search with filters
  - get_option: Option details with children
  - get_file: Fetch file contents
  - index_revision: Build and index options
  - list_revisions: Show indexed versions
  - delete_revision: Remove indexed data
- Add parser tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:54:42 +01:00
93245c1439 test: database layer tests
- Add comprehensive test suite for Store interface
- Test schema initialization, revisions, options, search, declarations, files
- SQLite tests use in-memory database for speed
- PostgreSQL tests require TEST_POSTGRES_CONN environment variable

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:54:42 +01:00
6326b3a3c1 feat: project structure and nix build setup
- Add CLI entry point with urfave/cli/v2 (serve, index, list, search commands)
- Add database interface and implementations for PostgreSQL and SQLite
- Add schema versioning with automatic recreation on version mismatch
- Add MCP protocol types and server scaffold
- Add NixOS option types
- Configure flake.nix with devShell and buildGoModule package

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:54:42 +01:00
740b846f0c docs: Add README 2026-02-03 07:34:40 +01:00
42d7ce78ba chore: initial commit 2026-02-03 07:32:27 +01:00