14 Commits

Author SHA1 Message Date
hermes-agent 15906893c0 Add audiobookshelf-mcp package
Go binary from michaeldvinci/audiobookshelf-mcp (v0.0.5).
Covers libraries, audiobooks, podcasts, authors, collections,
playlists, and users. Uses buildGoModule with fakeHash placeholders
to be filled on first nix build.
2026-07-04 22:24:46 +00:00
hermes-agent dc23a30013 Add pinchflat-mcp package
NixOS Configuration CI / Nix Flake Check (pull_request) Successful in 26s
Python MCP server (fastmcp + httpx) that exposes the Pinchflat REST API
as MCP tools. Covers sources, media items, media profiles, tasks, and
settings endpoints.

Tested against live Pinchflat instance — 28 sources, search, app info
all working via stdio transport.
2026-07-04 22:05:12 +00:00
hermes-agent ac60ea8712 fix: correct SRI hash for applemusic-mcp source
NixOS Configuration CI / Nix Flake Check (push) Successful in 17s
2026-06-25 16:12:48 +02:00
hermes-agent 87e2b844e8 fix: use fetchFromGitHub instead of fetchPypi for applemusic-mcp
NixOS Configuration CI / Nix Flake Check (push) Failing after 17s
fetchPypi with pyproject format was causing "Unsupported format pyproject"
error. Switched to fetchFromGitHub to match the pattern used by other
packages in this repo (e.g. zotero-mcp).

Note: the SRI hash is a placeholder — run `nix build .#applemusic-mcp`
and replace with the correct hash from the error output on first build.
2026-06-25 16:11:06 +02:00
hermes-agent c86bd93348 docs: add applemusic-mcp to README
NixOS Configuration CI / Nix Flake Check (push) Failing after 7s
2026-06-25 16:07:16 +02:00
hermes-agent 4d88ebc184 feat: register applemusic-mcp in default.nix
NixOS Configuration CI / Nix Flake Check (push) Failing after 9s
2026-06-25 16:06:44 +02:00
hermes-agent 8a362abe52 feat: add applemusic-mcp package
NixOS Configuration CI / Nix Flake Check (push) Successful in 18s
Cross-platform Apple Music MCP server supporting playlist management,
library search, and catalog access via media-user-token (no Apple
Developer account required).

https://github.com/epheterson/applemusic-mcp
2026-06-25 16:06:32 +02:00
hermes-agent 28997eb625 zotero-mcp: add semantic search dependencies (chromadb, sentence-transformers, openai, google-genai, tiktoken)
NixOS Configuration CI / Nix Flake Check (push) Successful in 43s
2026-06-22 11:42:13 +02:00
hermes-agent 90c942e4bb update: bump 6 MCP packages + nixpkgs flake
NixOS Configuration CI / Nix Flake Check (push) Successful in 1m23s
- flake.lock: nixpkgs 2026-05-31 → 2026-06-16
- zotero-mcp: v0.2.2 → v0.5.0
- duckduckgo-mcp-server: 0.1.1-unstable → v0.4.0
- kindly-web-search-mcp-server: bump to latest commit + add trafilatura dep
- sabnzbd-mcp: pin to specific commit instead of refs/heads/main
- jellyfin-mcp: v2026.318.7 → v2026.604.2 (remove go.mod patch)
- nextcloud-mcp-server: v0.89.0 → v0.121.3

n8n-mcp, mcp-arr-server, pdf-reader-mcp held back:
upstream npm packages require @modelcontextprotocol/sdk versions
not yet published to npm registry
2026-06-20 13:55:06 +02:00
luis 6d1df19b13 mcp server
NixOS Configuration CI / Nix Flake Check (push) Successful in 44s
2026-06-14 23:16:03 +02:00
luis f4b66744ad fixes
NixOS Configuration CI / Nix Flake Check (push) Successful in 52s
2026-06-03 23:54:11 +02:00
hermes-agent b17a484806 nextcloud-mcp-server: add missing icalendar-searcher dependency
CI / Flake Check (push) Successful in 46s
CI / Build Individual Packages (academic-search-mcp-server) (push) Successful in 59s
CI / Build Individual Packages (duckduckgo-mcp-server) (push) Successful in 52s
CI / Build Individual Packages (kindly-web-search-mcp-server) (push) Successful in 1m35s
CI / Build Individual Packages (manim-mcp-server) (push) Successful in 1m7s
CI / Build Individual Packages (rust-research-mcp) (push) Failing after 52s
CI / Build Individual Packages (pdf-reader-mcp) (push) Successful in 1m7s
CI / Build Individual Packages (zotero-mcp) (push) Successful in 1m35s
2026-05-28 20:40:20 +02:00
luis 55344ed9ef Merge pull request 'fix: unset PYTHONPATH to prevent Python 3.12 ABI contamination' (#3) from hermes-agent/mcp-servers:main into main
CI / Flake Check (push) Successful in 42s
CI / Build Individual Packages (academic-search-mcp-server) (push) Successful in 56s
CI / Build Individual Packages (duckduckgo-mcp-server) (push) Successful in 50s
CI / Build Individual Packages (kindly-web-search-mcp-server) (push) Successful in 1m30s
CI / Build Individual Packages (manim-mcp-server) (push) Successful in 1m2s
CI / Build Individual Packages (rust-research-mcp) (push) Failing after 48s
CI / Build Individual Packages (pdf-reader-mcp) (push) Successful in 1m3s
CI / Build Individual Packages (zotero-mcp) (push) Successful in 1m36s
Reviewed-on: #3
2026-05-28 09:34:02 +02:00
hermes-agent 9c01a07231 fix: unset PYTHONPATH in nextcloud-mcp-server wrapper
CI / Flake Check (pull_request) Has been cancelled
CI / Build Individual Packages (academic-search-mcp-server) (pull_request) Has been cancelled
CI / Build Individual Packages (duckduckgo-mcp-server) (pull_request) Has been cancelled
CI / Build Individual Packages (kindly-web-search-mcp-server) (pull_request) Has been cancelled
CI / Build Individual Packages (manim-mcp-server) (pull_request) Has been cancelled
CI / Build Individual Packages (pdf-reader-mcp) (pull_request) Has been cancelled
CI / Build Individual Packages (rust-research-mcp) (pull_request) Has been cancelled
CI / Build Individual Packages (zotero-mcp) (pull_request) Has been cancelled
Prevents Python 3.12 site-packages (from host env like mautrix bridge) from contaminating the Python 3.13 wrapper, causing C extension ABI mismatches (e.g. PIL._imaging).
2026-05-28 09:15:30 +02:00
19 changed files with 560 additions and 222 deletions
+13 -54
View File
@@ -1,63 +1,22 @@
name: CI
name: NixOS Configuration CI
on:
push:
branches: [ main, master ]
branches:
- main
- master
pull_request:
branches: [ main, master ]
branches:
- main
- master
jobs:
flake-check:
name: Flake Check
runs-on: ubuntu-latest
check:
name: Nix Flake Check
runs-on: nixos
steps:
- name: Checkout code
- name: Checkout Repository
uses: actions/checkout@v4
- name: Install Nix
uses: https://github.com/cachix/install-nix-action@v26
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
- name: Validate flake
run: nix flake check --print-build-logs
build-individual:
name: Build Individual Packages
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package:
- academic-search-mcp-server
- duckduckgo-mcp-server
- kindly-web-search-mcp-server
- manim-mcp-server
- pdf-reader-mcp
- rust-research-mcp
- zotero-mcp
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Nix
uses: https://github.com/cachix/install-nix-action@v26
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
- name: Build ${{ matrix.package }}
run: nix build .#${{ matrix.package }} --print-build-logs
- name: Test executable exists
run: |
if [ -e "./result/bin/${{ matrix.package }}" ]; then
echo "✓ Executable found: ${{ matrix.package }}"
./result/bin/${{ matrix.package }} --help || true
else
echo "⚠ No executable found at ./result/bin/${{ matrix.package }}"
ls -la ./result/bin/ || echo "No bin directory"
fi
- name: Run nix flake check
run: nix flake check --show-trace
+23 -17
View File
@@ -6,21 +6,27 @@ This repository provides Nix derivations for MCP (Model Context Protocol) server
## Available Packages
| Package | Description | Language |
|------------------------------|---------------------------------------------------------------|------------|
| academic-search-mcp-server | Search academic papers via Semantic Scholar and Crossref | Python |
| duckduckgo-mcp-server | Web search and content fetching via DuckDuckGo | Python |
| kindly-web-search-mcp-server | Web search + content retrieval via Serper, Tavily, or SearXNG | Python |
| manim-mcp-server | Execute Manim animation code and return videos | Python |
| n8n-mcp | AI access to n8n node docs and workflow management | TypeScript |
| pdf-reader-mcp | Productionready PDF processing with parallel processing | TypeScript |
| rust-research-mcp | Accumulate and organize academic knowledge | Rust |
| simple-web-search-mcp | Zero-config web search and page reading for LLMs | TypeScript |
| mcp-arr-server | MCP server for *arr suite — Sonarr, Radarr, Lidarr, Prowlarr | TypeScript |
| transmission-mcp | MCP server for the Transmission BitTorrent client | Python |
| sabnzbd-mcp | MCP server for SABnzbd download management | Python |
| jellyfin-mcp | MCP server for Jellyfin — search, playback, metadata, admin | Go |
| zotero-mcp | Connect Zotero research library with AI assistants | Python |
| Package | Description | Language |
| -------------------------------- | -------------------------------------------------------------------- | ---------- |
| academic-search-mcp-server | Search academic papers via Semantic Scholar and Crossref | Python |
| annas-mcp | Anna's Archive MCP server | Python |
| applemusic-mcp | Apple Music — manage playlists, search catalog, browse library | Python |
| duckduckgo-mcp-server | Web search and content fetching via DuckDuckGo | Python |
| jellyfin-mcp | MCP server for Jellyfin media server | Python |
| kindly-web-search-mcp-server | Web search + content retrieval via SearxNG, Tavily, or SearXNG | Python |
| manim-mcp-server | Execute Manim animation code and return videos | Python |
| mcp-arr-server | MCP server for *arr suite — Sonarr, Radarr, Lidarr, Prowlarr | TypeScript |
| mcp-score | AI-driven music score generation and MuseScore live control | Python |
| n8n-mcp | AI access to n8n node docs and workflow management | TypeScript |
| nextcloud-mcp-server | Nextcloud MCP server (files, calendar, contacts, deck, etc.) | Python |
| pdf-reader-mcp | Productionready PDF processing with parallel processing | TypeScript |
| rust-research-mcp | Accumulate and organize academic knowledge | Rust |
| simple-web-search-mcp | Zero-config web search and page reading for LLMs | TypeScript |
| transmission-mcp | MCP server for the Transmission BitTorrent client | Python |
| sabnzbd-mcp | MCP server for SABnzbd download management | Python |
| jellyfin-mcp | MCP server for Jellyfin — search, playback, metadata, admin | Go |
| zotero-mcp | Connect Zotero research library with AI assistants | Python |
| mcp-score | AI-driven music score generation and MuseScore live control | Python |
## Usage
@@ -35,7 +41,7 @@ Add this flake to your inputs and apply the overlay:
mcp-servers.url = "git+ssh://gitea@gitea.bueso.eu/luis/mcp-servers";
};
outputs = { nixpkgs, mcp-servers, ... }: {
outputs = { self, nixpkgs, ... }: {
# Apply the overlay to get packages in pkgs
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
@@ -66,4 +72,4 @@ Access packages without the overlay:
```
## License
Each packaged MCP server retains its original license. The Nix expressions in this repository are provided asis.
Each packaged MCP server retains its original license. The Nix expressions in this repository are provided as-is.
Generated
+3 -37
View File
@@ -1,30 +1,12 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1770181073,
"narHash": "sha256-ksTL7P9QC1WfZasNlaAdLOzqD8x5EPyods69YBqxSfk=",
"lastModified": 1781577229,
"narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "bf922a59c5c9998a6584645f7d0de689512e444c",
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
"type": "github"
},
"original": {
@@ -36,24 +18,8 @@
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
+43 -36
View File
@@ -12,52 +12,59 @@
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs =
{ self, nixpkgs, ... }:
let
supportedSystems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
in
{
self,
nixpkgs,
flake-utils,
...
}:
{
# Overlay that adds all MCP packages to nixpkgs
overlays.default = import ./overlays/default.nix;
}
// flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ self.overlays.default ];
};
# Import all MCP packages
mcpPackages = import ./packages { inherit pkgs; };
# List of all MCP server packages (for devShell)
allMcpServers = builtins.attrValues mcpPackages ++ [ pkgs.mcp-nixos ];
in
{
# Export all packages
packages = mcpPackages // {
// {
packages = forAllSystems (
system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ self.overlays.default ];
};
mcpPackages = import ./packages { inherit pkgs; };
in
mcpPackages // {
default = pkgs.symlinkJoin {
name = "mcp-servers";
paths = builtins.attrValues mcpPackages;
};
};
}
);
devShells.default = pkgs.mkShell {
packages = allMcpServers ++ [
pkgs.git
];
devShells = forAllSystems (
system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ self.overlays.default ];
};
mcpPackages = import ./packages { inherit pkgs; };
in
{
default = pkgs.mkShell {
packages = builtins.attrValues mcpPackages ++ [ pkgs.mcp-nixos pkgs.git ];
shellHook = ''
export SEARXNG_BASE_URL="https://search.bueso.eu"
'';
};
}
);
shellHook = ''
export SEARXNG_BASE_URL="https://search.bueso.eu"
'';
};
}
);
checks.x86_64-linux = builtins.removeAttrs self.packages.x86_64-linux [ "default" ];
};
}
+5
View File
@@ -91,6 +91,11 @@
"JELLYFIN_URL": "PLACEHOLDER",
"JELLYFIN_API_KEY": "PLACEHOLDER"
}
},
"mcp-score": {
"type": "local",
"command": ["mcp-score", "serve"],
"enabled": true
}
}
}
+29
View File
@@ -0,0 +1,29 @@
{
lib,
buildGoModule,
fetchFromGitHub,
}:
buildGoModule rec {
pname = "annas-mcp";
version = "0.0.5";
src = fetchFromGitHub {
owner = "iosifache";
repo = "annas-mcp";
rev = "v${version}";
hash = "sha256-XicM7tU5jD8B8n7JJDQ/84koBiLb8XF4+WBQ4LCUoRU=";
};
vendorHash = "sha256-2NdG5p2XfrhVgi388dRDBUSGwg6ybnzfn9495TWNGsA=";
subPackages = [ "cmd/annas-mcp" ];
meta = with lib; {
description = "MCP server and CLI for searching and downloading documents from Anna's Archive";
homepage = "https://github.com/iosifache/annas-mcp";
license = licenses.mit;
mainProgram = "annas-mcp";
platforms = platforms.all;
};
}
+40
View File
@@ -0,0 +1,40 @@
{
lib,
python3Packages,
fetchFromGitHub,
}:
python3Packages.buildPythonApplication rec {
pname = "applemusic-mcp";
version = "0.15.1";
pyproject = true;
src = fetchFromGitHub {
owner = "epheterson";
repo = "applemusic-mcp";
rev = "v${version}";
hash = "sha256-N97bZyT8TWOrt1WS7W31OJaICwoUxFfcDDuRs+TweTQ=";
};
build-system = with python3Packages; [
hatchling
];
dependencies = with python3Packages; [
mcp
pyjwt
requests
cryptography
playwright
];
pythonImportsCheck = [ "applemusic_mcp" ];
meta = with lib; {
description = "MCP server for Apple Music manage playlists, search catalog, browse library";
homepage = "https://github.com/epheterson/applemusic-mcp";
license = licenses.mit;
mainProgram = "applemusic-mcp";
platforms = platforms.all;
};
}
+27
View File
@@ -0,0 +1,27 @@
{
lib,
buildGoModule,
fetchFromGitHub,
}:
buildGoModule rec {
pname = "audiobookshelf-mcp";
version = "unstable-2026-06-27";
src = fetchFromGitHub {
owner = "michaeldvinci";
repo = "audiobookshelf-mcp";
rev = "e790d9c75085772180c95f2ec1376acc98e9282c";
hash = lib.fakeHash;
};
vendorHash = lib.fakeHash;
meta = with lib; {
description = "MCP server for Audiobookshelf libraries, audiobooks, podcasts, authors, collections, playlists";
homepage = "https://github.com/michaeldvinci/audiobookshelf-mcp";
license = licenses.gpl3Only;
mainProgram = "abs-mcp";
platforms = platforms.all;
};
}
+5 -9
View File
@@ -1,11 +1,3 @@
# MCP Server Packages
#
# This file aggregates all MCP server packages in this repository.
# To add a new package:
# 1. Create a directory: packages/<package-name>/
# 2. Create package.nix in that directory
# 3. Add an entry below using callPackage
#
{ pkgs }:
{
@@ -16,7 +8,6 @@
zotero-mcp = pkgs.callPackage ./zotero-mcp/package.nix { };
pdf-reader-mcp = pkgs.callPackage ./pdf-reader-mcp/package.nix { };
kindly-web-search-mcp-server = pkgs.callPackage ./kindly-web-search-mcp-server/package.nix { };
rust-research-mcp = pkgs.callPackage ./rust-research-mcp/package.nix { };
duckduckgo-mcp-server = pkgs.callPackage ./duckduckgo-mcp-server/package.nix { };
n8n-mcp = pkgs.callPackage ./n8n-mcp/package.nix { };
simple-web-search-mcp = pkgs.callPackage ./simple-web-search-mcp/package.nix { };
@@ -25,5 +16,10 @@
sabnzbd-mcp = pkgs.callPackage ./sabnzbd-mcp/package.nix { };
jellyfin-mcp = pkgs.callPackage ./jellyfin-mcp/package.nix { };
nextcloud-mcp-server = pkgs.callPackage ./nextcloud-mcp-server/package.nix { };
annas-mcp = pkgs.callPackage ./annas-mcp/package.nix { };
mcp-score = pkgs.callPackage ./mcp-score/package.nix { };
applemusic-mcp = pkgs.callPackage ./applemusic-mcp/package.nix { };
pinchflat-mcp = pkgs.callPackage ./pinchflat-mcp/package.nix { };
audiobookshelf-mcp = pkgs.callPackage ./audiobookshelf-mcp/package.nix { };
# example-mcp-server = pkgs.callPackage ./example-mcp-server/package.nix { };
}
+3 -3
View File
@@ -6,14 +6,14 @@
python3Packages.buildPythonApplication rec {
pname = "duckduckgo-mcp-server";
version = "0.1.1-unstable";
version = "0.4.0";
pyproject = true;
src = fetchFromGitHub {
owner = "nickclyde";
repo = "duckduckgo-mcp-server";
rev = "d198a2f0e8bd7c862d87d8517e1518aa295f8348";
hash = "sha256-aoWU5AVErAt73V+BgveEmVnjNh/cteS+A9AIFLylOsw=";
rev = "v${version}";
hash = "sha256-g1mpBrhuCt3g/XnUfHoY8lJDMizINypikj8Lqk2LVuE=";
};
build-system = [ python3Packages.hatchling ];
+3 -8
View File
@@ -6,21 +6,16 @@
buildGoModule rec {
pname = "jellyfin-mcp";
version = "2026.318.7";
version = "2026.604.2";
src = fetchFromGitHub {
owner = "jaredtrent";
repo = "jellyfin-mcp";
tag = "v${version}";
hash = "sha256-/6Sy8C5+/x90ZTo74qX0agTHybsWw+Vg416GBM1PS7k=";
hash = "sha256-Ks54txfOAkNEWfhl5ZXEIaFzAbmCnwhHtN1+FIa7dgo=";
};
# go.mod requires 1.25.6 but nixpkgs has 1.25.5; patch to relax
postPatch = ''
substituteInPlace go.mod --replace-fail "go 1.25.6" "go 1.25.5"
'';
vendorHash = "sha256-WYb+BpnKUUrgcJ0zChdTb1oB99R8bTgpSXUtjPKhL6M=";
vendorHash = "sha256-cDy+PpZM6xL7ur/xq81y4vlyaDnSOpGkyVV2hh8qI7o=";
meta = with lib; {
description = "MCP server for Jellyfin media server search, playback, metadata, admin";
@@ -77,8 +77,8 @@ python313Packages.buildPythonApplication rec {
src = fetchFromGitHub {
owner = "Shelpuk-AI-Technology-Consulting";
repo = "kindly-web-search-mcp-server";
rev = "2fd83d28710cce335f610e3d5ed0b403250ab1ba";
hash = "sha256-sOLx87p+w51wuBOItDdzrsrgItNZ92WivZAv3Zzp16o=";
rev = "2b76afb37bf311facbde6750d0a0c0cbdfb8fec2";
hash = "sha256-90QHr2FPiMSwKXmjlZ2W9NIQvj3LDXzYIq6m/Z+sJMw=";
};
build-system = with python313Packages; [
@@ -94,6 +94,7 @@ python313Packages.buildPythonApplication rec {
nodriver
pymupdf
fastmcp
trafilatura
];
nativeBuildInputs = [ makeWrapper ];
+76
View File
@@ -0,0 +1,76 @@
{
lib,
python313Packages,
fetchFromGitHub,
fetchPypi,
}:
let
# music21 is not in nixpkgs; vendor it (upstream mcp-score pins >=9.0,<10)
music21 = python313Packages.buildPythonPackage rec {
pname = "music21";
version = "9.9.2";
format = "wheel";
src = fetchPypi {
inherit pname version;
format = "wheel";
dist = "py3";
python = "py3";
hash = "sha256-ZIAQq40TKNCxB0bO8UV+hLEidM0xYkgifpbSHielGMo=";
};
propagatedBuildInputs = with python313Packages; [
chardet
joblib
jsonpickle
matplotlib
more-itertools
numpy
requests
webcolors
];
doCheck = false;
pythonImportsCheck = [ "music21" ];
meta = with lib; {
description = "Toolkit for computer-aided musicology";
homepage = "https://github.com/cuthbertLab/music21";
license = licenses.bsd3;
};
};
in
python313Packages.buildPythonApplication rec {
pname = "mcp-score";
version = "0.1.0-unstable";
pyproject = true;
src = fetchFromGitHub {
owner = "tskovlund";
repo = "mcp-score";
rev = "3ff9d4b6504fcee5032c44fdcf7dc1d7a21a4b5d";
hash = "sha256-zrpvzxi8AbF5/etuvMZLni4HSFBYGRe55rpKJJEAg60=";
};
build-system = with python313Packages; [
hatchling
];
dependencies = with python313Packages; [
mcp
music21
websockets
];
pythonImportsCheck = [ "mcp_score" ];
meta = with lib; {
description = "MCP server for AI-driven music score generation and manipulation via MusicXML and MuseScore";
homepage = "https://github.com/tskovlund/mcp-score";
license = licenses.mit;
mainProgram = "mcp-score";
platforms = platforms.all;
};
}
+10 -3
View File
@@ -20,6 +20,7 @@ let
};
inherit propagatedBuildInputs;
doCheck = false;
dontCheckRuntimeDeps = true;
inherit meta;
};
@@ -131,14 +132,14 @@ let
in
python3Packages.buildPythonApplication rec {
pname = "nextcloud-mcp-server";
version = "0.89.0";
version = "0.121.3";
pyproject = true;
src = fetchFromGitHub {
owner = "cbcoutinho";
repo = "nextcloud-mcp-server";
rev = "v${version}";
hash = "sha256-IDTSGsHQ8cCFvgSO7pDbSSHVNV0OIjjoEN9ZfkaPAvk=";
hash = "sha256-U6BG5anTEllNnJzta4VV6QOfn86+N15q6v/SfLGM7mc=";
};
build-system = [ python3Packages.uv-build ];
@@ -152,7 +153,7 @@ python3Packages.buildPythonApplication rec {
googleapis-common-protos opentelemetry-api opentelemetry-proto
opentelemetry-semantic-conventions opentelemetry-sdk
x-wr-timezone opentelemetry-util-http opentelemetry-exporter-otlp-proto-common
opentelemetry-instrumentation recurring-ical-events
opentelemetry-instrumentation recurring-ical-events icalendar-searcher
opentelemetry-exporter-otlp-proto-grpc qdrant-client
opentelemetry-instrumentation-asgi opentelemetry-instrumentation-httpx
opentelemetry-instrumentation-logging langchain-text-splitters mistralai caldav
@@ -178,6 +179,12 @@ python3Packages.buildPythonApplication rec {
--replace-quiet '">=2.4.5"' '""'
'';
# PYTHONPATH from the host environment (e.g., mautrix bridge injecting
# Python 3.12 site-packages) causes C extension ABI mismatches on NixOS.
# The wrapper's own sys.path has the correct closure packages, so we
# unset the external PYTHONPATH to prevent contamination.
makeWrapperArgs = [ "--unset" "PYTHONPATH" ];
dontCheckRuntimeDeps = true;
catchConflicts = false;
+42
View File
@@ -0,0 +1,42 @@
{
lib,
stdenv,
makeWrapper,
python3,
}:
let
python = python3.withPackages (
ps: with ps; [
fastmcp
httpx
]
);
in
stdenv.mkDerivation {
pname = "pinchflat-mcp";
version = "0.1.0";
src = ./server.py;
nativeBuildInputs = [ makeWrapper ];
dontUnpack = true;
installPhase = ''
mkdir -p $out/lib/pinchflat-mcp $out/bin
cp $src $out/lib/pinchflat-mcp/server.py
makeWrapper ${python}/bin/python $out/bin/pinchflat-mcp \
--add-flags "$out/lib/pinchflat-mcp/server.py" \
--set-default PINCHFLAT_MCP_TRANSPORT stdio
'';
meta = with lib; {
description = "MCP server for Pinchflat media downloader";
homepage = "https://gitea.bueso.eu/hermes-agent/pinchflat";
license = licenses.mit;
mainProgram = "pinchflat-mcp";
platforms = platforms.all;
};
}
+226
View File
@@ -0,0 +1,226 @@
#!/usr/bin/env python3
"""Pinchflat MCP server — exposes the Pinchflat REST API as MCP tools."""
import os
import sys
from typing import Any, Optional
import httpx
from fastmcp import FastMCP
PINCHFLAT_URL = os.environ.get("PINCHFLAT_URL", "http://localhost:8945")
PINCHFLAT_TOKEN = os.environ.get("PINCHFLAT_API_TOKEN", "")
if not PINCHFLAT_TOKEN:
print("PINCHFLAT_API_TOKEN environment variable is required", file=sys.stderr)
sys.exit(1)
BASE = f"{PINCHFLAT_URL.rstrip('/')}/api/v1"
HEADERS = {"Authorization": f"Bearer {PINCHFLAT_TOKEN}", "Content-Type": "application/json"}
mcp = FastMCP("pinchflat")
def _get(path: str, params: Optional[dict] = None) -> Any:
"""Make a GET request to the Pinchflat API."""
with httpx.Client(timeout=30) as client:
r = client.get(f"{BASE}{path}", headers=HEADERS, params=params)
r.raise_for_status()
return r.json()
def _post(path: str, json: Optional[dict] = None) -> Any:
"""Make a POST request to the Pinchflat API."""
with httpx.Client(timeout=30) as client:
r = client.post(f"{BASE}{path}", headers=HEADERS, json=json)
r.raise_for_status()
return r.json()
def _put(path: str, json: dict) -> Any:
"""Make a PUT request to the Pinchflat API."""
with httpx.Client(timeout=30) as client:
r = client.put(f"{BASE}{path}", headers=HEADERS, json=json)
r.raise_for_status()
return r.json()
def _delete(path: str) -> Any:
"""Make a DELETE request to the Pinchflat API."""
with httpx.Client(timeout=30) as client:
r = client.delete(f"{BASE}{path}", headers=HEADERS)
r.raise_for_status()
return r.json()
# --- Sources ---
@mcp.tool()
def list_sources() -> dict:
"""List all configured media sources (YouTube channels, playlists, etc.)."""
return _get("/sources")
@mcp.tool()
def get_source(source_id: int) -> dict:
"""Get details of a specific source by ID, including its pending tasks."""
return _get(f"/sources/{source_id}")
@mcp.tool()
def create_source(
original_url: str,
media_profile_id: int,
collection_type: str = "channel",
custom_name: Optional[str] = None,
download_cutoff_date: Optional[str] = None,
) -> dict:
"""Create a new media source (e.g. add a YouTube channel to monitor).
Args:
original_url: URL of the channel/playlist to monitor
media_profile_id: ID of the media profile to use for downloads
collection_type: 'channel', 'playlist', or 'video'
custom_name: Optional custom name for the source
download_cutoff_date: Only download media after this date (YYYY-MM-DD)
"""
source = {
"media_profile_id": media_profile_id,
"collection_type": collection_type,
"original_url": original_url,
}
if custom_name:
source["custom_name"] = custom_name
if download_cutoff_date:
source["download_cutoff_date"] = download_cutoff_date
return _post("/sources", json={"source": source})
@mcp.tool()
def update_source(
source_id: int,
custom_name: Optional[str] = None,
download_cutoff_date: Optional[str] = None,
enabled: Optional[bool] = None,
index_frequency_minutes: Optional[int] = None,
) -> dict:
"""Update an existing source. Only provided fields will be changed."""
updates = {}
if custom_name is not None:
updates["custom_name"] = custom_name
if download_cutoff_date is not None:
updates["download_cutoff_date"] = download_cutoff_date
if enabled is not None:
updates["enabled"] = enabled
if index_frequency_minutes is not None:
updates["index_frequency_minutes"] = index_frequency_minutes
return _put(f"/sources/{source_id}", json={"source": updates})
@mcp.tool()
def delete_source(source_id: int) -> dict:
"""Delete a source (marks it for deletion)."""
return _delete(f"/sources/{source_id}")
@mcp.tool()
def force_download_pending(source_id: int) -> dict:
"""Force download of all pending media items for a source."""
return _post(f"/sources/{source_id}/force_download_pending")
@mcp.tool()
def force_redownload(source_id: int) -> dict:
"""Force re-download of all existing media for a source."""
return _post(f"/sources/{source_id}/force_redownload")
@mcp.tool()
def force_index(source_id: int) -> dict:
"""Force re-index of a source."""
return _post(f"/sources/{source_id}/force_index")
@mcp.tool()
def force_metadata_refresh(source_id: int) -> dict:
"""Force metadata refresh for a source."""
return _post(f"/sources/{source_id}/force_metadata_refresh")
# --- Media Items ---
@mcp.tool()
def list_media(source_id: Optional[int] = None, limit: int = 50) -> dict:
"""List media items. Optionally filter by source_id."""
params = {}
if source_id:
params["source_id"] = source_id
return _get("/media", params=params)
@mcp.tool()
def search_media(query: str) -> dict:
"""Search media items by title or description."""
return _get("/media/search", params={"q": query})
@mcp.tool()
def get_media(media_id: int) -> dict:
"""Get details of a specific media item."""
return _get(f"/media/{media_id}")
@mcp.tool()
def force_download_media(media_id: int) -> dict:
"""Force download of a specific media item."""
return _post(f"/media/{media_id}/force_download")
# --- Media Profiles ---
@mcp.tool()
def list_media_profiles() -> dict:
"""List all media profiles (download quality/container settings)."""
return _get("/media_profiles")
@mcp.tool()
def get_media_profile(profile_id: int) -> dict:
"""Get details of a specific media profile."""
return _get(f"/media_profiles/{profile_id}")
# --- Tasks ---
@mcp.tool()
def list_tasks(source_id: Optional[int] = None) -> dict:
"""List all tasks. Optionally filter by source_id."""
params = {}
if source_id:
params["source_id"] = source_id
return _get("/tasks", params=params)
@mcp.tool()
def get_task(task_id: int) -> dict:
"""Get details of a specific task."""
return _get(f"/tasks/{task_id}")
# --- Settings & Info ---
@mcp.tool()
def get_settings() -> dict:
"""Get current Pinchflat settings."""
return _get("/settings")
@mcp.tool()
def get_app_info() -> dict:
"""Get Pinchflat app info (version, environment, etc.)."""
return _get("/app_info")
if __name__ == "__main__":
transport = os.environ.get("PINCHFLAT_MCP_TRANSPORT", "stdio")
mcp.run(transport=transport if transport in ("stdio", "http") else "stdio")
-50
View File
@@ -1,50 +0,0 @@
{
lib,
rustPlatform,
fetchFromGitHub,
pkg-config,
openssl,
}:
rustPlatform.buildRustPackage rec {
pname = "rust-research-mcp";
version = "0.6.7-unstable";
src = fetchFromGitHub {
owner = "Ladvien";
repo = "research_hub_mcp";
rev = "3335c118da9e7a9e9e7f2e608989fbe35557f3c5";
hash = "sha256-KkIVeFQ8hEL82ZtC+Tie+8T/eZcEoWyq5cRVgdinQEc=";
};
cargoHash = "sha256-zwhQ2ksFbedeuzTaJI+9t9of6es7RJa6JwRHQRznqBY=";
nativeBuildInputs = [
pkg-config
];
buildInputs = [
openssl
];
doCheck = false;
# The build.rs uses vergen to embed git info, which fails without a git repo.
# Set environment variables to satisfy vergen during build.
env = {
VERGEN_GIT_BRANCH = "main";
VERGEN_GIT_COMMIT_DATE = "2025-09-25";
VERGEN_GIT_COMMIT_TIMESTAMP = "2025-09-25T19:35:10Z";
VERGEN_GIT_SHA = "3335c118da9e7a9e9e7f2e608989fbe35557f3c5";
VERGEN_BUILD_DATE = "2025-09-25";
VERGEN_BUILD_TIMESTAMP = "2025-09-25T19:35:10Z";
};
meta = with lib; {
description = "MCP server for accumulating and organizing academic knowledge";
homepage = "https://github.com/Ladvien/research_hub_mcp";
license = licenses.gpl3Only;
mainProgram = pname;
platforms = platforms.all;
};
}
+1 -1
View File
@@ -23,7 +23,7 @@ stdenv.mkDerivation {
src = fetchFromGitHub {
owner = "jmagar";
repo = "sabnzbd-mcp";
rev = "refs/heads/main";
rev = "9d691ed70b72397fddec03ca4ec68c81b30c79c3";
hash = "sha256-1sEnHH40cDVT5oiZD2Xywl7S9vJThii/ce+6r+XmpSw=";
};
+8 -2
View File
@@ -39,14 +39,14 @@ let
in
python3Packages.buildPythonApplication rec {
pname = "zotero-mcp";
version = "0.2.2";
version = "0.5.0";
pyproject = true;
src = fetchFromGitHub {
owner = "54yyyu";
repo = "zotero-mcp";
rev = "v${version}";
hash = "sha256-GZkzABsUh6qua66K4URPq0InLgs6cqLgKEXm7wzT+s8=";
hash = "sha256-ioy6bdP+jFioUGBKiiYtD4nbdFe6v2E3nCi6s9+dTT0=";
};
build-system = with python3Packages; [
@@ -67,6 +67,12 @@ python3Packages.buildPythonApplication rec {
pymupdf
ebooklib
pdfplumber
# Semantic search
chromadb
sentence-transformers
openai
google-genai
tiktoken
];
# Optional: semantic search dependencies