Add configurable MaxSessions limit (default: 10000) to SessionStore.
When the limit is reached, new session creation returns ErrTooManySessions
and HTTP transport responds with 503 Service Unavailable.
This prevents attackers from exhausting server memory by creating
unlimited sessions through repeated initialize requests.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Configure HTTP server with sensible timeouts:
- ReadTimeout: 30s (time to read entire request)
- WriteTimeout: 30s (time to write response)
- IdleTimeout: 120s (keep-alive connection timeout)
- ReadHeaderTimeout: 10s (time to read request headers)
For SSE connections, use http.ResponseController to extend write
deadlines before each write, preventing timeout on long-lived streams
while still protecting against slow clients.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
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>
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>
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>
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>
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>
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>
- 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>
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>
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>
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>
- 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>
- 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>
- 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>
- 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>