# AGENTS.md - MCP Server Packages for Nix This repository provides Nix derivations for MCP (Model Context Protocol) servers not yet available in nixpkgs. ## Quick Reference | Command | Description | |----------------------------------|------------------------------------| | `nix build .#` | Build a specific package | | `nix build .#default` | Build all packages | | `nix flake show` | List available packages | | `nix flake check` | Validate flake syntax and outputs | | `nix develop` | Enter development shell | ## Build Commands ```bash nix build .#manim-mcp-server # Build specific package nix build .#default # Build all packages ./result/bin/ # Test built package nix flake check # Validate flake nix flake update # Update dependencies ``` ## Testing This repository has no unit tests. Validation is done via successful `nix build`. To verify a package works: 1. Build it: `nix build .#` 2. Run it: `./result/bin/` 3. Check the flake: `nix flake check` ## Project Structure ``` packages/ ├── default.nix # Package aggregator - registers all packages └── / └── package.nix # Package derivation overlays/ └── default.nix # Nix overlay that exports all MCP packages flake.nix # Main flake definition flake.lock # Locked dependency versions ``` ## Code Style Guidelines ### Nix Formatting - Use 2-space indentation - Place opening braces on the same line - Use `rec` only when self-references are needed - Prefer `let...in` blocks for local bindings - Use attribute sets with one attribute per line for readability ### Function Arguments Format function arguments with each parameter on its own line: ```nix { lib, stdenv, fetchFromGitHub, makeWrapper, python3, }: ``` ### Naming Conventions - **Package names**: lowercase with hyphens (e.g., `manim-mcp-server`) - **Variables**: camelCase for local variables (e.g., `mcpPackages`, `allMcpServers`) - **Attribute names**: lowercase with hyphens in package sets - **Version strings**: Use `x.x.x-unstable` for development versions pinned to commits ### Package Structure Each package lives in `packages//package.nix`. Register new packages in `packages/default.nix`: ```nix { pkgs }: { manim-mcp-server = pkgs.callPackage ./manim-mcp-server/package.nix { }; new-package = pkgs.callPackage ./new-package/package.nix { }; } ``` ### Hash Calculation When adding new packages, use `lib.fakeHash` initially: ```nix hash = lib.fakeHash; ``` Then run `nix build` and copy the correct hash from the error message. ### Meta Attributes Always include these meta attributes: ```nix meta = with lib; { description = "Short description of the MCP server"; homepage = "https://github.com/owner/repo"; license = licenses.mit; # Use actual license mainProgram = pname; platforms = platforms.all; # Or specific platforms }; ``` ### Comments - Use `#` for single-line comments - Place comments above the code they describe - Document non-obvious patches or workarounds (see manim-mcp-server for example) ## Adding New Packages ### 1. Create Package Directory ```bash mkdir -p packages/ ``` ### 2. Choose the Right Builder | Language | Builder | |----------|-------------------------------------------| | Python | `python3Packages.buildPythonApplication` | | Python | `stdenv.mkDerivation` with `makeWrapper` | | Go | `buildGoModule` | | Node.js | `buildNpmPackage` | | Rust | `rustPlatform.buildRustPackage` | ### 3. Create package.nix See `packages/manim-mcp-server/package.nix` for a reference implementation. ### 4. Register the Package Add to `packages/default.nix`: ```nix new-mcp-server = pkgs.callPackage ./new-mcp-server/package.nix { }; ``` ### 5. Build and Test ```bash nix build .# ./result/bin/ ``` ## Git Conventions ### Commit Messages - Use short, lowercase messages for simple changes: `fix`, `update`, `add` - Use sentence case for descriptive commits: `Add manim-mcp-server package` - Keep the first line under 72 characters ### What to Commit - Package derivations (`package.nix` files) - Updates to `packages/default.nix` - Updates to `flake.nix` and `flake.lock` - Documentation updates ### What NOT to Commit - `.envrc` (use `nix develop` instead) - `.direnv/` directory - Build artifacts (`result/`) ## Common Patterns ### Patching Source Files When upstream code has hardcoded paths, use `substitute`: ```nix substitute src/file.py $out/lib/${pname}/file.py \ --replace-fail 'old-string' 'new-string' ``` ### Python Wrapper Pattern For Python scripts without proper packaging: ```nix let python = python3.withPackages (ps: with ps; [ mcp fastmcp ]); in stdenv.mkDerivation { # ... installPhase = '' makeWrapper ${python}/bin/python $out/bin/${pname} \ --add-flags "$out/lib/${pname}/server.py" ''; } ``` ### Environment Variables Set environment variables in wrappers using `--set`: ```nix makeWrapper ${python}/bin/python $out/bin/${pname} \ --set SOME_VAR "value" ```