Commit Graph

69 Commits

Author SHA1 Message Date
b491a60105 Merge pull request 'feature/lab-monitoring' (#6) from feature/lab-monitoring into master
Reviewed-on: #6
2026-02-04 22:48:23 +00:00
52f50a1a06 chore: enable silences in lab-monitoring MCP config
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:46:15 +01:00
d31a93d3b6 docs: add Loki log query support to lab-monitoring TODO
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:36:00 +01:00
5b9eda48f8 chore: update monitoring URLs to production endpoints
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:33:44 +01:00
741f02d856 docs: add list_rules and get_rule_group to lab-monitoring TODO
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:33:30 +01:00
06e62eb6ad feat: gate create_silence behind --enable-silences flag
The create_silence tool is a write operation that can suppress alerts.
Disable it by default and require explicit opt-in via --enable-silences
CLI flag (or enableSilences NixOS option) as a safety measure.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:23:46 +01:00
2a08cdaf2e feat: include active alert count in MCP server instructions
Add InstructionsFunc callback to ServerConfig, called during each
initialize handshake to generate dynamic instructions. The lab-monitoring
server uses this to query Alertmanager and include a count of active
non-silenced alerts, so the LLM can proactively inform the user.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:16:52 +01:00
1755364bba feat: add lab-monitoring MCP server for Prometheus and Alertmanager
New MCP server that queries live Prometheus and Alertmanager HTTP APIs
with 8 tools: list_alerts, get_alert, search_metrics, get_metric_metadata,
query (PromQL), list_targets, list_silences, and create_silence.

Extends the MCP core with ModeCustom and NewGenericServer for servers
that don't require a database. Includes CLI with direct commands
(alerts, query, targets, metrics), NixOS module, and comprehensive
httptest-based tests.

Bumps existing binaries to 0.2.1 due to shared internal/mcp change.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:11:53 +01:00
0bd4ed778a Merge pull request 'feature/nixpkgs-search' (#5) from feature/nixpkgs-search into master
Reviewed-on: #5
2026-02-04 17:07:30 +00:00
d1285d1f80 fix: improve package search relevance with exact match priority
Package search now prioritizes results in this order:
1. Exact pname match
2. Exact attr_path match
3. pname starts with query
4. attr_path starts with query
5. FTS ranking (bm25 for SQLite, ts_rank for PostgreSQL)

This ensures searching for "git" returns the "git" package first,
rather than packages that merely mention "git" in their description.

Also update CLAUDE.md to clarify using `nix run` instead of
`go build -o` for testing binaries.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 18:04:06 +01:00
66145fab6c docs: mark nixpkgs-packages as completed in TODO
The nixpkgs-packages feature has been implemented in nixpkgs-search.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:31:09 +01:00
d7ee6048e1 chore: update dev config for nixpkgs-search
- Update .mcp.json to use nixpkgs-search options/packages servers
- Update CLAUDE.md example to use nixpkgs-search

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:31:05 +01:00
75addb5a28 docs: update README for nixpkgs-search as primary server
- Document nixpkgs-search as the primary MCP server
- Add package search CLI examples and MCP tools
- Update installation and usage examples
- Add nixpkgs-search-mcp NixOS module documentation
- Mark nixos-options as legacy
- Update environment variable documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:30:25 +01:00
3625a8dfc3 feat(nix): add nixpkgs-search-mcp NixOS module
Add NixOS module for deploying nixpkgs-search as systemd services:
- Runs separate MCP servers for options (port 8082) and packages (port 8083)
- Shared database configuration (SQLite or PostgreSQL)
- Separate indexing service that runs before servers start
- options.enable and packages.enable flags (both default to true)
- indexFlags option for customizing index command (--no-packages, etc.)

Also update flake.nix:
- Register new module as nixpkgs-search-mcp
- Set as default nixosModule

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:30:19 +01:00
ea4c69bc23 feat: add nixpkgs-search binary with package search support
Add a new nixpkgs-search CLI that combines NixOS options search with
Nix package search functionality. This provides two MCP servers from
a single binary:
- `nixpkgs-search options serve` for NixOS options
- `nixpkgs-search packages serve` for Nix packages

Key changes:
- Add packages table to database schema (version 3)
- Add Package type and search methods to database layer
- Create internal/packages/ with indexer and parser for nix-env JSON
- Add MCP server mode (options/packages) with separate tool sets
- Add package handlers: search_packages, get_package
- Create cmd/nixpkgs-search with combined indexing support
- Update flake.nix with nixpkgs-search package (now default)
- Bump version to 0.2.0

The index command can index both options and packages together, or
use --no-packages/--no-options flags for partial indexing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:12:41 +01:00
9efcca217c Merge pull request 'feature/add-linting-tools' (#4) from feature/add-linting-tools into master
Reviewed-on: #4
2026-02-04 00:55:15 +00:00
d6e99161a9 docs: add linting instructions to CLAUDE.md
Document the requirement to run golangci-lint, govulncheck, and go vet
before completing work on a feature branch.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:53:28 +01:00
ea11dd5e14 fix: add nolint:errcheck comments for intentionally unchecked errors
Add //nolint:errcheck comments to intentionally unchecked error returns:

- defer X.Close() calls: errors from closing read-only resources, rows
  after iteration, files, response bodies, and gzip readers are not
  actionable and don't affect correctness

- defer tx.Rollback(): standard Go pattern where rollback after
  successful commit returns an error, which is expected behavior

- defer stmt.Close(): statements are closed with their transactions

- Cleanup operations: DeleteRevision on failure and os.RemoveAll for
  temp directories are best-effort cleanup

- HTTP response encoding: if JSON encoding fails at response time,
  there's nothing useful we can do

- Test/benchmark code: unchecked errors in test setup/cleanup where
  failures will surface through test assertions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:51:20 +01:00
097b661aed fix: resolve ineffassign warnings in postgres SearchOptions
The argNum variable tracks parameter positions but the final value is
unused. Added explicit acknowledgment to silence the linter.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:45:21 +01:00
6596ac56a5 fix: resolve staticcheck nil pointer dereference warning
Use t.Fatal instead of t.Error when retrieved session is nil to prevent
subsequent nil pointer dereference on retrieved.ID.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:45:16 +01:00
ad819a3c2c chore: add govulncheck to devshell
Add govulncheck for vulnerability scanning of Go dependencies.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:39:38 +01:00
df9a2f30a9 Merge pull request 'feature/file-metadata-and-range' (#3) from feature/file-metadata-and-range into master
Reviewed-on: #3
2026-02-04 00:37:05 +00:00
c829dd28a9 chore: bump version to 0.1.2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:30:53 +01:00
9252ddcfae test: add tests for file metadata and range parameters
- testFileRange: test GetFileWithRange with various offset/limit values
- testDeclarationsWithMetadata: test file metadata in declarations
- Verify byte_size and line_count are computed correctly
- Test edge cases: offset beyond EOF, non-indexed files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:30:49 +01:00
b188ca5088 feat(mcp): add offset/limit params and show file metadata in declarations
- Add offset and limit parameters to get_file tool schema
- Default limit is 250 lines, offset is 0
- Show "Showing lines X-Y of Z total" header when range is applied
- Update handleGetOption to use GetDeclarationsWithMetadata
- Display file size metadata (bytes, lines) in declarations output

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:30:45 +01:00
d9aab773c6 feat(database): add file size metadata and range parameters
- Add byte_size and line_count columns to files table
- Increment SchemaVersion to 2 (requires re-indexing)
- Add DeclarationWithMetadata, FileRange, FileResult types
- Add GetDeclarationsWithMetadata method for file metadata lookup
- Add GetFileWithRange method for paginated file retrieval
- Implement countLines and applyLineRange helpers

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:30:39 +01:00
128cc313dc docs: add TODO items for large file handling and nixpkgs-packages MCP
- Add file size metadata to get_option declarations
- Add range parameters to get_file with sensible defaults
- New MCP server idea for indexing nixpkgs packages

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:14:10 +01:00
1fc9f71c48 Merge pull request 'feature/hm-options' (#2) from feature/hm-options into master
Reviewed-on: #2
2026-02-03 22:40:08 +00:00
3d704dfaf5 docs: add indexing performance notes to CLAUDE.md
Document expected indexing times so appropriate timeouts are used:
- nixos-options: ~5-6 minutes for nixos-unstable
- hm-options: ~1-2 minutes for master

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 23:37:31 +01:00
6073575233 fix: support Home Manager declarations format in parser
The options.json parser expected declarations as []string (NixOS format),
but Home Manager uses [{name, url}] objects. This caused most HM options
to be silently skipped during parsing (27 vs 4880 options).

Changes:
- Parse declarations as json.RawMessage and try both formats
- Handle HM path format <home-manager/modules/...> in normalizeDeclarationPath
- Add /modules/ marker for HM store paths

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 23:33:13 +01:00
11935db702 docs: update README and CLAUDE.md for hm-options, bump version to 0.1.1
- Add hm-options documentation to README.md
- Update CLAUDE.md with hm-options info, repository structure
- Add note about git-tracking new files before nix build/run
- Add version bump rules documentation
- Bump version from 0.1.0 to 0.1.1 (patch bump for internal/ changes)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 23:03:36 +01:00
ea2d73d746 feat: add hm-options package for Home Manager options
Add a new MCP server for Home Manager options, mirroring the
functionality of nixos-options but targeting the home-manager
repository.

Changes:
- Add shared options.Indexer interface for both implementations
- Add internal/homemanager package with indexer and channel aliases
- Add cmd/hm-options CLI entry point
- Parameterize MCP server with ServerConfig for name/instructions
- Parameterize nix/package.nix for building both packages
- Add hm-options package and NixOS module to flake.nix
- Add nix/hm-options-module.nix for systemd deployment

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:51:30 +01:00
6b6be83e50 Merge pull request 'feature/streamable-http-transport' (#1) from feature/streamable-http-transport into master
Reviewed-on: #1
2026-02-03 21:23:38 +00:00
e6315eb94b docs: fix flake URL and add nix run MCP example
- Update flake URL from github:torjus/labmcp to the correct
  git+https://git.t-juice.club/torjus/labmcp
- Add alternative MCP client configuration using nix run with
  the flake URL directly (no installation required)
- Fix NixOS module example to use correct flake URL

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:21:50 +01:00
921005179e docs: add HTTP transport documentation
Update README.md:
- Add HTTP transport usage section with examples
- Document HTTP endpoints (POST/GET/DELETE)
- Add HTTP-related NixOS module options to the table

Update CLAUDE.md:
- Update protocol description to include HTTP/SSE
- Add new transport files to repository structure
- Add Transports section explaining STDIO vs HTTP
- Add HTTP security hardening details
- Update CLI commands with HTTP transport examples

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:16:46 +01:00
08f8b2cd83 feat: add SSE keepalive messages for connection health
Add configurable SSEKeepAlive interval (default: 15s) that sends SSE
comment lines (`:keepalive`) to maintain connection health.

Benefits:
- Keeps connections alive through proxies/load balancers that timeout
  idle connections
- Detects stale connections earlier (write failures terminate the
  handler)
- Standard SSE pattern - comments are ignored by compliant clients

Configuration:
- SSEKeepAlive > 0: send keepalives at specified interval
- SSEKeepAlive = 0: use default (15s)
- SSEKeepAlive < 0: disable keepalives

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:10:58 +01:00
684baf63da security: add maximum session limit to prevent memory exhaustion
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>
2026-02-03 22:07:51 +01:00
1565cb5e1b security: add HTTP server timeouts to prevent slowloris attacks
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>
2026-02-03 22:05:33 +01:00
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