diff --git a/README.md b/README.md new file mode 100644 index 0000000..f6fa59d --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# MCP Server Packages for Nix + +## Overview + +This repository provides Nix derivations for MCP (Model Context Protocol) servers that are not yet available in nixpkgs. + +## Available Packages + +| Package | Description | Language | +|----------------------------|----------------------------------------------------------|------------| +| academic-search-mcp-server | Search academic papers via Semantic Scholar and Crossref | Python | +| manim-mcp-server | Execute Manim animation code and return videos | Python | +| pdf-reader-mcp | Production‑ready PDF processing with parallel processing | TypeScript | +| zotero-mcp | Connect Zotero research library with AI assistants | Python | + +## Usage + +### Using the Overlay (Recommended) + +Add this flake to your inputs and apply the overlay: + +```nix +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + mcp.url = "github:YOUR-USERNAME/mcp"; # Update with your repo + }; + + outputs = { nixpkgs, mcp, ... }: { + # Apply the overlay to get packages in pkgs + nixosConfigurations.myhost = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + { + nixpkgs.overlays = [ mcp.overlays.default ]; + } + # Now you can use pkgs.manim-mcp-server + ]; + }; + }; +} +``` + +### Using Packages Directly + +Access packages without the overlay: + +```nix +{ + inputs.mcp.url = "github:YOUR-USERNAME/mcp"; + + outputs = { mcp, ... }: { + # Access directly + myPackage = mcp.packages.x86_64-linux.manim-mcp-server; + }; +} +``` + +## License +Each packaged MCP server retains its original license. The Nix expressions in this repository are provided as‑is. diff --git a/README.org b/README.org deleted file mode 100644 index 0681f4a..0000000 --- a/README.org +++ /dev/null @@ -1,343 +0,0 @@ -#+TITLE: MCP Server Packages for Nix -#+AUTHOR: -#+DESCRIPTION: Nix derivations for Model Context Protocol (MCP) servers - -* Overview - -This repository provides Nix derivations for MCP (Model Context Protocol) servers that are not yet available in nixpkgs. - -* Available Packages - -| Package | Description | Language | -|----------------------------+----------------------------------------------------------+------------| -| academic-search-mcp-server | Search academic papers via Semantic Scholar and Crossref | Python | -| manim-mcp-server | Execute Manim animation code and return videos | Python | -| pdf-reader-mcp | Production-ready PDF processing with parallel processing | TypeScript | -| zotero-mcp | Connect Zotero research library with AI assistants | Python | - -* Usage - -** Using the Overlay (Recommended) - -Add this flake to your inputs and apply the overlay: - -#+begin_src nix -{ - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - mcp.url = "github:YOUR-USERNAME/mcp"; # Update with your repo - }; - - outputs = { nixpkgs, mcp, ... }: { - # Apply the overlay to get packages in pkgs - nixosConfigurations.myhost = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [ - { - nixpkgs.overlays = [ mcp.overlays.default ]; - } - # Now you can use pkgs.manim-mcp-server - ]; - }; - }; -} -#+end_src - -** Using Packages Directly - -Access packages without the overlay: - -#+begin_src nix -{ - inputs.mcp.url = "github:YOUR-USERNAME/mcp"; - - outputs = { mcp, ... }: { - # Access directly - myPackage = mcp.packages.x86_64-linux.manim-mcp-server; - }; -} -#+end_src - -** In a Development Shell - -#+begin_src nix -{ - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - mcp.url = "github:YOUR-USERNAME/mcp"; - }; - - outputs = { nixpkgs, mcp, ... }: - let - system = "x86_64-linux"; - pkgs = import nixpkgs { - inherit system; - overlays = [ mcp.overlays.default ]; - }; - in { - devShells.${system}.default = pkgs.mkShell { - packages = [ - pkgs.manim-mcp-server - ]; - }; - }; -} -#+end_src - -* Adding New Packages - -** Directory Structure - -#+begin_example -packages/ -├── default.nix # Package aggregator -└── / - └── package.nix # Package derivation -#+end_example - -** Step-by-Step Guide - -1. *Create the package directory* - #+begin_src bash - mkdir -p packages/ - #+end_src - -2. *Create =package.nix=* using the appropriate builder for the language: - - - Python (with pyproject.toml): =python3Packages.buildPythonApplication= - - Python (script only): wrapper approach with =stdenv.mkDerivation= - - Go: =buildGoModule= - - Node.js: =buildNpmPackage= - - Rust: =rustPlatform.buildRustPackage= - -3. *Register in =packages/default.nix=* - #+begin_src nix - { pkgs }: - { - manim-mcp-server = pkgs.callPackage ./manim-mcp-server/package.nix { }; - # Add your new package here: - new-mcp-server = pkgs.callPackage ./new-mcp-server/package.nix { }; - } - #+end_src - -4. *Build and test* - #+begin_src bash - nix build .# - ./result/bin/ - #+end_src - -** Package Templates - -*** Python (with pyproject.toml) - -#+begin_src nix -{ lib, python3Packages, fetchFromGitHub }: - -python3Packages.buildPythonApplication rec { - pname = "example-mcp-server"; - version = "1.0.0"; - pyproject = true; - - src = fetchFromGitHub { - owner = "owner"; - repo = "repo"; - rev = "v${version}"; - hash = "sha256-AAAA..."; # Use lib.fakeHash first, then update - }; - - build-system = [ python3Packages.hatchling ]; - - dependencies = with python3Packages; [ - mcp - fastmcp - ]; - - meta = with lib; { - description = "Description of the MCP server"; - homepage = "https://github.com/owner/repo"; - license = licenses.mit; - mainProgram = "example-mcp-server"; - }; -} -#+end_src - -*** Python (script only, like manim-mcp-server) - -#+begin_src nix -{ lib, stdenv, fetchFromGitHub, makeWrapper, python3 }: - -let - python = python3.withPackages (ps: with ps; [ - mcp - fastmcp - # other dependencies - ]); -in -stdenv.mkDerivation rec { - pname = "example-mcp-server"; - version = "0.0.1-unstable"; - - src = fetchFromGitHub { - owner = "owner"; - repo = "repo"; - rev = "commit-hash"; - hash = "sha256-AAAA..."; - }; - - nativeBuildInputs = [ makeWrapper ]; - dontBuild = true; - - installPhase = '' - runHook preInstall - mkdir -p $out/bin $out/lib/${pname} - cp src/server.py $out/lib/${pname}/ - makeWrapper ${python}/bin/python $out/bin/${pname} \ - --add-flags "$out/lib/${pname}/server.py" - runHook postInstall - ''; - - meta = with lib; { - description = "Description"; - homepage = "https://github.com/owner/repo"; - license = licenses.mit; - mainProgram = pname; - }; -} -#+end_src - -*** Go - -#+begin_src nix -{ lib, buildGoModule, fetchFromGitHub }: - -buildGoModule rec { - pname = "example-mcp-server"; - version = "1.0.0"; - - src = fetchFromGitHub { - owner = "owner"; - repo = "repo"; - rev = "v${version}"; - hash = "sha256-AAAA..."; - }; - - vendorHash = "sha256-BBBB..."; # Use lib.fakeHash first - - ldflags = [ - "-s" "-w" - "-X main.version=${version}" - ]; - - meta = with lib; { - description = "Description"; - homepage = "https://github.com/owner/repo"; - license = licenses.mit; - mainProgram = pname; - }; -} -#+end_src - -*** Node.js (with package-lock.json) - -#+begin_src nix -{ lib, buildNpmPackage, fetchFromGitHub }: - -buildNpmPackage rec { - pname = "example-mcp-server"; - version = "1.0.0"; - - src = fetchFromGitHub { - owner = "owner"; - repo = "repo"; - rev = "v${version}"; - hash = "sha256-AAAA..."; - }; - - npmDepsHash = "sha256-BBBB..."; # Use lib.fakeHash first - - dontNpmBuild = true; # If pre-built or no build step needed - - meta = with lib; { - description = "Description"; - homepage = "https://github.com/owner/repo"; - license = licenses.mit; - mainProgram = pname; - }; -} -#+end_src - -*** Node.js (wrapper for npm packages without package-lock.json) - -Use this approach when the upstream project uses bun.lock or yarn.lock instead of package-lock.json: - -#+begin_src nix -{ lib, stdenvNoCC, nodejs_22, makeWrapper }: - -stdenvNoCC.mkDerivation rec { - pname = "example-mcp-server"; - version = "1.0.0"; - - # No source needed - npx fetches the package - dontUnpack = true; - - nativeBuildInputs = [ makeWrapper ]; - - installPhase = '' - runHook preInstall - mkdir -p $out/bin - makeWrapper ${nodejs_22}/bin/npx $out/bin/${pname} \ - --add-flags "--yes" \ - --add-flags "@scope/package-name@${version}" - runHook postInstall - ''; - - meta = with lib; { - description = "Description"; - homepage = "https://github.com/owner/repo"; - license = licenses.mit; - mainProgram = pname; - }; -} -#+end_src - -Note: This approach requires network access on first run as npx downloads the package. - -** Calculating Hashes - -When adding a new package, use =lib.fakeHash= initially: - -#+begin_src nix -hash = lib.fakeHash; -#+end_src - -Then run =nix build= and copy the correct hash from the error message. - -* Development - -** Enter Development Shell - -#+begin_src bash -nix develop -#+end_src - -** Build a Specific Package - -#+begin_src bash -nix build .#manim-mcp-server -#+end_src - -** Build All Packages - -#+begin_src bash -nix build .#default -#+end_src - -** List Available Packages - -#+begin_src bash -nix flake show -#+end_src - -* License - -Each packaged MCP server retains its original license. The Nix expressions in this repository are provided as-is. diff --git a/docs/adding-new-packages.md b/docs/adding-new-packages.md new file mode 100644 index 0000000..38edca4 --- /dev/null +++ b/docs/adding-new-packages.md @@ -0,0 +1,225 @@ +# Adding New Packages + +## Directory Structure + +```text +packages/ +├── default.nix # Package aggregator +└── / + └── package.nix # Package derivation +``` + +## Step‑by‑Step Guide + +1. **Create the package directory** + + ```bash + mkdir -p packages/ + ``` + +2. **Create `package.nix`** using the appropriate builder for the language: + * Python (with pyproject.toml): `python3Packages.buildPythonApplication` + * Python (script only): wrapper approach with `stdenv.mkDerivation` + * Go: `buildGoModule` + * Node.js: `buildNpmPackage` + * Rust: `rustPlatform.buildRustPackage` + +3. **Register** in `packages/default.nix`: + + ```nix + { pkgs }: + { + manim-mcp-server = pkgs.callPackage ./manim-mcp-server/package.nix { }; + # Add your new package here: + new-mcp-server = pkgs.callPackage ./new-mcp-server/package.nix { }; + } + ``` + +4. **Build and test**: + + ```bash + nix build .# + ./result/bin/ + ``` + +## Package Templates + +### Python (with `pyproject.toml`) + +```nix +{ lib, python3Packages, fetchFromGitHub }: + +python3Packages.buildPythonApplication rec { + pname = "example-mcp-server"; + version = "1.0.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "owner"; + repo = "repo"; + rev = "v${version}"; + hash = "sha256-AAAA..."; # Use lib.fakeHash first, then update + }; + + build-system = [ python3Packages.hatchling ]; + + dependencies = with python3Packages; [ + mcp + fastmcp + ]; + + meta = with lib; { + description = "Description of the MCP server"; + homepage = "https://github.com/owner/repo"; + license = licenses.mit; + mainProgram = "example-mcp-server"; + }; +} +``` + +### Python (script only, like `manim-mcp-server`) + +```nix +{ lib, stdenv, fetchFromGitHub, makeWrapper, python3 }: + +let + python = python3.withPackages (ps: with ps; [ + mcp + fastmcp + # other dependencies + ]); +in +stdenv.mkDerivation rec { + pname = "example-mcp-server"; + version = "0.0.1-unstable"; + + src = fetchFromGitHub { + owner = "owner"; + repo = "repo"; + rev = "commit-hash"; + hash = "sha256-AAAA..."; + }; + + nativeBuildInputs = [ makeWrapper ]; + dontBuild = true; + + installPhase = '' + runHook preInstall + mkdir -p $out/bin $out/lib/${pname} + cp src/server.py $out/lib/${pname}/ + makeWrapper ${python}/bin/python $out/bin/${pname} \ + --add-flags "$out/lib/${pname}/server.py" + runHook postInstall + ''; + + meta = with lib; { + description = "Description"; + homepage = "https://github.com/owner/repo"; + license = licenses.mit; + mainProgram = pname; + }; +} +``` + +### Go + +```nix +{ lib, buildGoModule, fetchFromGitHub }: + +buildGoModule rec { + pname = "example-mcp-server"; + version = "1.0.0"; + + src = fetchFromGitHub { + owner = "owner"; + repo = "repo"; + rev = "v${version}"; + hash = "sha256-AAAA..."; + }; + + vendorHash = "sha256-BBBB..."; # Use lib.fakeHash first + + ldflags = [ + "-s" "-w" + "-X main.version=${version}" + ]; + + meta = with lib; { + description = "Description"; + homepage = "https://github.com/owner/repo"; + license = licenses.mit; + mainProgram = pname; + }; +} +``` + +### Node.js (with `package-lock.json`) + +```nix +{ lib, buildNpmPackage, fetchFromGitHub }: + +buildNpmPackage rec { + pname = "example-mcp-server"; + version = "1.0.0"; + + src = fetchFromGitHub { + owner = "owner"; + repo = "repo"; + rev = "v${version}"; + hash = "sha256-AAAA..."; + }; + + npmDepsHash = "sha256-BBBB..."; # Use lib.fakeHash first + + dontNpmBuild = true; # If pre-built or no build step needed + + meta = with lib; { + description = "Description"; + homepage = "https://github.com/owner/repo"; + license = licenses.mit; + mainProgram = pname; + }; +} +``` + +### Node.js (wrapper for npm packages without `package-lock.json`) + +```nix +{ lib, stdenvNoCC, nodejs_22, makeWrapper }: + +stdenvNoCC.mkDerivation rec { + pname = "example-mcp-server"; + version = "1.0.0"; + + # No source needed - npx fetches the package + dontUnpack = true; + + nativeBuildInputs = [ makeWrapper ]; + + installPhase = '' + runHook preInstall + mkdir -p $out/bin + makeWrapper ${nodejs_22}/bin/npx $out/bin/${pname} \ + --add-flags "--yes" \ + --add-flags "@scope/package-name@${version}" + runHook postInstall + ''; + + meta = with lib; { + description = "Description"; + homepage = "https://github.com/owner/repo"; + license = licenses.mit; + mainProgram = pname; + }; +} +``` + +## Calculating Hashes + +When adding a new package, use `lib.fakeHash` initially: + +```nix +hash = lib.fakeHash; +``` + +Then run `nix build` and copy the correct hash from the error message. diff --git a/docs/dev.md b/docs/dev.md new file mode 100644 index 0000000..3301108 --- /dev/null +++ b/docs/dev.md @@ -0,0 +1,25 @@ +# Development + +## Enter Development Shell + +```bash +nix develop +``` + +## Build a Specific Package + +```bash +nix build .#manim-mcp-server +``` + +## Build All Packages + +```bash +nix build .#default +``` + +## List Available Packages + +```bash +nix flake show +``` diff --git a/docs/overview.md b/docs/overview.md new file mode 100644 index 0000000..db34acc --- /dev/null +++ b/docs/overview.md @@ -0,0 +1,5 @@ +# MCP Server Packages for Nix + +## Description + +Nix derivations for Model Context Protocol (MCP) servers that are not yet available in nixpkgs.