44 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
luis 88a3976b5e Merge pull request 'feat: add nextcloud-mcp-server with 20 inlined Python deps' (#1) from hermes-agent/mcp-servers:main into main
CI / Flake Check (push) Successful in 48s
CI / Build Individual Packages (academic-search-mcp-server) (push) Successful in 58s
CI / Build Individual Packages (duckduckgo-mcp-server) (push) Successful in 49s
CI / Build Individual Packages (kindly-web-search-mcp-server) (push) Successful in 1m28s
CI / Build Individual Packages (manim-mcp-server) (push) Successful in 1m5s
CI / Build Individual Packages (rust-research-mcp) (push) Failing after 49s
CI / Build Individual Packages (pdf-reader-mcp) (push) Successful in 1m5s
CI / Build Individual Packages (zotero-mcp) (push) Successful in 2m49s
Reviewed-on: #1
2026-05-28 08:55:25 +02:00
hermes-agent fdfdc63883 fix caldav hash
CI / Build Individual Packages (rust-research-mcp) (pull_request) Failing after 52s
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 (zotero-mcp) (pull_request) Has been cancelled
2026-05-28 01:12:44 +02:00
hermes-agent 56e8414d1b inline caldav v3.2.0 to fix module not found 2026-05-28 01:12:29 +02:00
hermes-agent e614c3802b fix mistralai hash 2026-05-28 01:11:05 +02:00
hermes-agent 21da64300d add inlined mistralai to avoid opentelemetry conflict 2026-05-28 01:10:38 +02:00
hermes-agent e26984fd03 disable catchConflicts hook 2026-05-28 01:09:21 +02:00
hermes-agent 555765f4c4 disable runtime dep checks 2026-05-28 01:08:58 +02:00
hermes-agent 17dc826d7b relax all version constraints in postPatch 2026-05-28 01:08:29 +02:00
hermes-agent d39928e0e3 fix uv_build pattern to match actual pyproject.toml format 2026-05-28 01:07:49 +02:00
hermes-agent c22f65865a fix uv-build version constraint 2026-05-28 01:06:23 +02:00
hermes-agent 8f38158c61 fix build backend to uv-build 2026-05-28 01:05:48 +02:00
hermes-agent febfeb61f4 fix postPatch remove --replace-fail 2026-05-28 01:04:50 +02:00
hermes-agent bf3fb5a3a3 apply all 20 wheel hashes 2026-05-28 01:03:32 +02:00
hermes-agent adad2860f7 try underscore pnames for PyPI wheel filenames 2026-05-28 01:01:17 +02:00
hermes-agent b027fd26cd fetchurl with underscore pnames, fetchPypi format=wheel 2026-05-28 00:59:27 +02:00
hermes-agent 8d9d05c308 test: commit pins for last 2 packages 2026-05-28 00:56:30 +02:00
hermes-agent 7369b10b6f apply 8 GitHub source hashes, 2 remaining 2026-05-28 00:44:11 +02:00
hermes-agent 87e2fa8483 fix mkPy to pass extra args 2026-05-27 20:28:37 +02:00
hermes-agent a08806da9a hybrid: 4 pypi wheels + 16 github sources 2026-05-27 20:28:19 +02:00
hermes-agent b73ef032a4 restore dist/py3 hints on wheels 2026-05-27 20:20:48 +02:00
hermes-agent af28a83009 back to format=wheel without dist/python hints 2026-05-27 20:17:17 +02:00
hermes-agent ef7969273d fix source path (no src/ prefix) 2026-05-27 20:08:19 +02:00
hermes-agent 50e7ffca92 fix source hash 2026-05-27 20:07:44 +02:00
hermes-agent 572c9d6481 use wrapper pattern referencing working venv 2026-05-27 20:06:28 +02:00
hermes-agent 5afdbe50fb remove dist/python constraints on fetchWheel 2026-05-27 19:46:54 +02:00
hermes-agent 5b30010e3d fix 4 wheel hashes + source hash 2026-05-27 19:32:09 +02:00
hermes-agent 256a9b025c switch all inlined deps to format=wheel (avoid monorepo/build-system/tag issues) 2026-05-27 19:29:43 +02:00
hermes-agent ad923c5777 apply 6 more hashes from build 2 2026-05-27 19:26:13 +02:00
hermes-agent d4c0be5034 fix known hashes, switch to GitHub sources for wheel-only packages 2026-05-27 19:19:59 +02:00
hermes-agent 384467a43b add nextcloud-mcp-server package (0.89.0) with 20 inlined deps 2026-05-27 17:11:56 +02:00
19 changed files with 749 additions and 219 deletions
+13 -54
View File
@@ -1,63 +1,22 @@
name: CI name: NixOS Configuration CI
on: on:
push: push:
branches: [ main, master ] branches:
- main
- master
pull_request: pull_request:
branches: [ main, master ] branches:
- main
- master
jobs: jobs:
flake-check: check:
name: Flake Check name: Nix Flake Check
runs-on: ubuntu-latest runs-on: nixos
steps: steps:
- name: Checkout code - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Install Nix - name: Run nix flake check
uses: https://github.com/cachix/install-nix-action@v26 run: nix flake check --show-trace
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
+11 -5
View File
@@ -7,20 +7,26 @@ This repository provides Nix derivations for MCP (Model Context Protocol) server
## Available Packages ## Available Packages
| Package | Description | Language | | Package | Description | Language |
|------------------------------|---------------------------------------------------------------|------------| | -------------------------------- | -------------------------------------------------------------------- | ---------- |
| academic-search-mcp-server | Search academic papers via Semantic Scholar and Crossref | Python | | 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 | | 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 | | 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 | | 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 | | 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 | | pdf-reader-mcp | Productionready PDF processing with parallel processing | TypeScript |
| rust-research-mcp | Accumulate and organize academic knowledge | Rust | | rust-research-mcp | Accumulate and organize academic knowledge | Rust |
| simple-web-search-mcp | Zero-config web search and page reading for LLMs | TypeScript | | 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 | | transmission-mcp | MCP server for the Transmission BitTorrent client | Python |
| sabnzbd-mcp | MCP server for SABnzbd download management | Python | | sabnzbd-mcp | MCP server for SABnzbd download management | Python |
| jellyfin-mcp | MCP server for Jellyfin — search, playback, metadata, admin | Go | | jellyfin-mcp | MCP server for Jellyfin — search, playback, metadata, admin | Go |
| zotero-mcp | Connect Zotero research library with AI assistants | Python | | zotero-mcp | Connect Zotero research library with AI assistants | Python |
| mcp-score | AI-driven music score generation and MuseScore live control | Python |
## Usage ## 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"; 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 # Apply the overlay to get packages in pkgs
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem { nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
@@ -66,4 +72,4 @@ Access packages without the overlay:
``` ```
## License ## 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": { "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": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1770181073, "lastModified": 1781577229,
"narHash": "sha256-ksTL7P9QC1WfZasNlaAdLOzqD8x5EPyods69YBqxSfk=", "narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "bf922a59c5c9998a6584645f7d0de689512e444c", "rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -36,24 +18,8 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs" "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", "root": "root",
+30 -23
View File
@@ -12,52 +12,59 @@
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
}; };
outputs = 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; overlays.default = import ./overlays/default.nix;
} }
// flake-utils.lib.eachDefaultSystem ( // {
packages = forAllSystems (
system: system:
let let
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system; inherit system;
overlays = [ self.overlays.default ]; overlays = [ self.overlays.default ];
}; };
# Import all MCP packages
mcpPackages = import ./packages { inherit pkgs; }; mcpPackages = import ./packages { inherit pkgs; };
# List of all MCP server packages (for devShell)
allMcpServers = builtins.attrValues mcpPackages ++ [ pkgs.mcp-nixos ];
in in
{ mcpPackages // {
# Export all packages
packages = mcpPackages // {
default = pkgs.symlinkJoin { default = pkgs.symlinkJoin {
name = "mcp-servers"; name = "mcp-servers";
paths = builtins.attrValues mcpPackages; paths = builtins.attrValues mcpPackages;
}; };
}
);
devShells = forAllSystems (
system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ self.overlays.default ];
}; };
mcpPackages = import ./packages { inherit pkgs; };
devShells.default = pkgs.mkShell { in
packages = allMcpServers ++ [ {
pkgs.git default = pkgs.mkShell {
]; packages = builtins.attrValues mcpPackages ++ [ pkgs.mcp-nixos pkgs.git ];
shellHook = '' shellHook = ''
export SEARXNG_BASE_URL="https://search.bueso.eu" 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_URL": "PLACEHOLDER",
"JELLYFIN_API_KEY": "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;
};
}
+6 -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 }: { pkgs }:
{ {
@@ -16,7 +8,6 @@
zotero-mcp = pkgs.callPackage ./zotero-mcp/package.nix { }; zotero-mcp = pkgs.callPackage ./zotero-mcp/package.nix { };
pdf-reader-mcp = pkgs.callPackage ./pdf-reader-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 { }; 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 { }; duckduckgo-mcp-server = pkgs.callPackage ./duckduckgo-mcp-server/package.nix { };
n8n-mcp = pkgs.callPackage ./n8n-mcp/package.nix { }; n8n-mcp = pkgs.callPackage ./n8n-mcp/package.nix { };
simple-web-search-mcp = pkgs.callPackage ./simple-web-search-mcp/package.nix { }; simple-web-search-mcp = pkgs.callPackage ./simple-web-search-mcp/package.nix { };
@@ -24,5 +15,11 @@
transmission-mcp = pkgs.callPackage ./transmission-mcp/package.nix { }; transmission-mcp = pkgs.callPackage ./transmission-mcp/package.nix { };
sabnzbd-mcp = pkgs.callPackage ./sabnzbd-mcp/package.nix { }; sabnzbd-mcp = pkgs.callPackage ./sabnzbd-mcp/package.nix { };
jellyfin-mcp = pkgs.callPackage ./jellyfin-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 { }; # example-mcp-server = pkgs.callPackage ./example-mcp-server/package.nix { };
} }
+3 -3
View File
@@ -6,14 +6,14 @@
python3Packages.buildPythonApplication rec { python3Packages.buildPythonApplication rec {
pname = "duckduckgo-mcp-server"; pname = "duckduckgo-mcp-server";
version = "0.1.1-unstable"; version = "0.4.0";
pyproject = true; pyproject = true;
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "nickclyde"; owner = "nickclyde";
repo = "duckduckgo-mcp-server"; repo = "duckduckgo-mcp-server";
rev = "d198a2f0e8bd7c862d87d8517e1518aa295f8348"; rev = "v${version}";
hash = "sha256-aoWU5AVErAt73V+BgveEmVnjNh/cteS+A9AIFLylOsw="; hash = "sha256-g1mpBrhuCt3g/XnUfHoY8lJDMizINypikj8Lqk2LVuE=";
}; };
build-system = [ python3Packages.hatchling ]; build-system = [ python3Packages.hatchling ];
+3 -8
View File
@@ -6,21 +6,16 @@
buildGoModule rec { buildGoModule rec {
pname = "jellyfin-mcp"; pname = "jellyfin-mcp";
version = "2026.318.7"; version = "2026.604.2";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "jaredtrent"; owner = "jaredtrent";
repo = "jellyfin-mcp"; repo = "jellyfin-mcp";
tag = "v${version}"; 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 vendorHash = "sha256-cDy+PpZM6xL7ur/xq81y4vlyaDnSOpGkyVV2hh8qI7o=";
postPatch = ''
substituteInPlace go.mod --replace-fail "go 1.25.6" "go 1.25.5"
'';
vendorHash = "sha256-WYb+BpnKUUrgcJ0zChdTb1oB99R8bTgpSXUtjPKhL6M=";
meta = with lib; { meta = with lib; {
description = "MCP server for Jellyfin media server search, playback, metadata, admin"; description = "MCP server for Jellyfin media server search, playback, metadata, admin";
@@ -77,8 +77,8 @@ python313Packages.buildPythonApplication rec {
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "Shelpuk-AI-Technology-Consulting"; owner = "Shelpuk-AI-Technology-Consulting";
repo = "kindly-web-search-mcp-server"; repo = "kindly-web-search-mcp-server";
rev = "2fd83d28710cce335f610e3d5ed0b403250ab1ba"; rev = "2b76afb37bf311facbde6750d0a0c0cbdfb8fec2";
hash = "sha256-sOLx87p+w51wuBOItDdzrsrgItNZ92WivZAv3Zzp16o="; hash = "sha256-90QHr2FPiMSwKXmjlZ2W9NIQvj3LDXzYIq6m/Z+sJMw=";
}; };
build-system = with python313Packages; [ build-system = with python313Packages; [
@@ -94,6 +94,7 @@ python313Packages.buildPythonApplication rec {
nodriver nodriver
pymupdf pymupdf
fastmcp fastmcp
trafilatura
]; ];
nativeBuildInputs = [ makeWrapper ]; 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;
};
}
+198
View File
@@ -0,0 +1,198 @@
{
lib,
python3Packages,
fetchFromGitHub,
fetchPypi,
}:
let
# Helper: buildPythonPackage for a wheel fetched from PyPI
# CRITICAL: pname MUST use underscores, not hyphens, for PyPI wheel filenames
fetchWheel = { pname, version, hash, propagatedBuildInputs ? [ ], meta ? { } }:
python3Packages.buildPythonPackage {
inherit pname version;
format = "wheel";
src = fetchPypi {
inherit pname version hash;
format = "wheel";
dist = "py3";
python = "py3";
};
inherit propagatedBuildInputs;
doCheck = false;
dontCheckRuntimeDeps = true;
inherit meta;
};
pythonvcard4 = fetchWheel {
pname = "pythonvcard4"; version = "0.2.0"; hash = "sha256-3OMTVd1QruU3+Ig96G8wFRDkB7wXVaaOyNUFW2T1xmA=";
meta = with lib; { description = "vCard parsing"; homepage = "https://github.com/GNOME/python-vcard4"; license = licenses.gpl3Plus; };
};
prometheus-client = fetchWheel {
pname = "prometheus_client"; version = "0.25.0"; hash = "sha256-1a7InjSabsIwgF0N+ILzgH90/WwaL6hoZOPCJ5BZ/tE=";
meta = with lib; { description = "Prometheus client"; homepage = "https://github.com/prometheus/client_python"; license = licenses.asl20; };
};
python-json-logger = fetchWheel {
pname = "python_json_logger"; version = "4.1.0"; hash = "sha256-EymUdlz3W/RFVL6apJsG7yNF0jZhqWcgJicWQ4FBtrI=";
meta = with lib; { description = "JSON logger"; homepage = "https://github.com/nhairs/python-json-logger"; license = licenses.bsd2; };
};
importlib-metadata = fetchWheel {
pname = "importlib_metadata"; version = "8.7.1"; hash = "sha256-Wh+Avx2qSJSVBx77sJXXWmNM8oqLwplYEkQGO1MXYVE=";
propagatedBuildInputs = with python3Packages; [ zipp ];
meta = with lib; { description = "Importlib metadata"; homepage = "https://github.com/python/importlib_metadata"; license = licenses.asl20; };
};
googleapis-common-protos = fetchWheel {
pname = "googleapis_common_protos"; version = "1.75.0"; hash = "sha256-lh7WA5nEV86w7o8oWoTIcKq8nGqDK503uygbW+veQ+0=";
propagatedBuildInputs = with python3Packages; [ protobuf ];
meta = with lib; { description = "Common protos"; homepage = "https://github.com/googleapis/python-api-common-protos"; license = licenses.asl20; };
};
opentelemetry-api = fetchWheel {
pname = "opentelemetry_api"; version = "1.39.1"; hash = "sha256-Lt2EY0Mqf4RD7c6QlyFpsZXn1qBVAM0p5tE4mBh8mVA=";
propagatedBuildInputs = with python3Packages; [ deprecated ];
meta = with lib; { description = "OpenTelemetry API"; homepage = "https://github.com/open-telemetry/opentelemetry-python"; license = licenses.asl20; };
};
opentelemetry-proto = fetchWheel {
pname = "opentelemetry_proto"; version = "1.39.1"; hash = "sha256-Is3Hjv07N2XQnmi/vQENT8JUyYGK/QtrQjOH2d7kYAc=";
propagatedBuildInputs = with python3Packages; [ protobuf ];
meta = with lib; { description = "OpenTelemetry Proto"; homepage = "https://github.com/open-telemetry/opentelemetry-python"; license = licenses.asl20; };
};
opentelemetry-semantic-conventions = fetchWheel {
pname = "opentelemetry_semantic_conventions"; version = "0.60b1"; hash = "sha256-n6jIsMEQ2iiYCSkrBZEiDTp7U8FSaiMCHpd9aFl4k/s=";
propagatedBuildInputs = with python3Packages; [ deprecated ];
meta = with lib; { description = "OTel semconv"; homepage = "https://github.com/open-telemetry/semantic-conventions"; license = licenses.asl20; };
};
opentelemetry-sdk = fetchWheel {
pname = "opentelemetry_sdk"; version = "1.39.1"; hash = "sha256-TVSCxHhRPssKXZONzGE5TmRwZuDMJna+6fOvPz9F8Bw=";
propagatedBuildInputs = with python3Packages; [ typing-extensions ];
meta = with lib; { description = "OpenTelemetry SDK"; homepage = "https://github.com/open-telemetry/opentelemetry-python"; license = licenses.asl20; };
};
x-wr-timezone = fetchWheel {
pname = "x_wr_timezone"; version = "2.0.1"; hash = "sha256-50pTufT33vgThFXCQOZeR8Ikd4vOPAJPzW2iy+kcoDg=";
propagatedBuildInputs = with python3Packages; [ icalendar click ];
meta = with lib; { description = "X-WR-TIMEZONE"; homepage = "https://github.com/niccokunzmann/x-wr-timezone"; license = licenses.lgpl3Plus; };
};
opentelemetry-util-http = fetchWheel {
pname = "opentelemetry_util_http"; version = "0.60b1"; hash = "sha256-ZjgbooVQyRvuFNy6iXms5ENESvHtYJImY0WWtLD68Zk=";
meta = with lib; { description = "OTel HTTP utils"; homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib"; license = licenses.asl20; };
};
opentelemetry-exporter-otlp-proto-common = fetchWheel {
pname = "opentelemetry_exporter_otlp_proto_common"; version = "1.39.1"; hash = "sha256-CPilhi1kzDQ1EFaG0CFsE2XcVwH4aESozVZZfQx2T94=";
meta = with lib; { description = "OTLP proto common"; homepage = "https://github.com/open-telemetry/opentelemetry-python"; license = licenses.asl20; };
};
opentelemetry-instrumentation = fetchWheel {
pname = "opentelemetry_instrumentation"; version = "0.60b1"; hash = "sha256-BEgNuVK0j7HtAHP4IvDuJgEre+fD6sGjeTEic3x4Yy0=";
propagatedBuildInputs = with python3Packages; [ wrapt packaging ];
meta = with lib; { description = "OTel instrumentation"; homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib"; license = licenses.asl20; };
};
recurring-ical-events = fetchWheel {
pname = "recurring_ical_events"; version = "3.8.2"; hash = "sha256-mtYF4ntPvrcO4cZiBa3jJVC+FaV87cV5YGUi8cZ6720=";
propagatedBuildInputs = with python3Packages; [ icalendar python-dateutil ];
meta = with lib; { description = "Recurring iCal events"; homepage = "https://github.com/niccokunzmann/python-recurring-ical-events"; license = licenses.lgpl3Plus; };
};
opentelemetry-exporter-otlp-proto-grpc = fetchWheel {
pname = "opentelemetry_exporter_otlp_proto_grpc"; version = "1.39.1"; hash = "sha256-+hwTagXH6bTAn3OUacvbkn6iCzQIirHZWahJtcxYnBg=";
propagatedBuildInputs = with python3Packages; [ grpcio deprecated ];
meta = with lib; { description = "OTLP gRPC exporter"; homepage = "https://github.com/open-telemetry/opentelemetry-python"; license = licenses.asl20; };
};
qdrant-client = fetchWheel {
pname = "qdrant_client"; version = "1.18.0"; hash = "sha256-CTqoz4pCDuOtKmiwB+E3jXmSsmAOC1PBk/wXJnT2Wc0=";
propagatedBuildInputs = with python3Packages; [ grpcio httpx numpy portalocker protobuf pydantic urllib3 ];
meta = with lib; { description = "Qdrant client"; homepage = "https://github.com/qdrant/qdrant-client"; license = licenses.asl20; };
};
opentelemetry-instrumentation-asgi = fetchWheel {
pname = "opentelemetry_instrumentation_asgi"; version = "0.60b1"; hash = "sha256-1I3vLb7RApTJnPz0HrvQxBTTkKEXc6QfRy0gAA/N3CU=";
propagatedBuildInputs = with python3Packages; [ asgiref ];
meta = with lib; { description = "OTel ASGI"; homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib"; license = licenses.asl20; };
};
opentelemetry-instrumentation-httpx = fetchWheel {
pname = "opentelemetry_instrumentation_httpx"; version = "0.60b1"; hash = "sha256-83Y23XQq0q+D2Ja6aWAe0o2lH6TiXRq2L96JzkE+J1s=";
propagatedBuildInputs = with python3Packages; [ httpx wrapt ];
meta = with lib; { description = "OTel HTTPX"; homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib"; license = licenses.asl20; };
};
opentelemetry-instrumentation-logging = fetchWheel {
pname = "opentelemetry_instrumentation_logging"; version = "0.60b1"; hash = "sha256-8uGMvH4d02KMgOMNJDiX/ck8W34MiuYKvSubapn4I0M=";
meta = with lib; { description = "OTel logging"; homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib"; license = licenses.asl20; };
};
langchain-text-splitters = fetchWheel {
pname = "langchain_text_splitters"; version = "1.1.2"; hash = "sha256-ot4NeZ/zGIZCn9bi4AMt8nW2DsgXwZBZp7RhgcwcLxA=";
propagatedBuildInputs = with python3Packages; [ langchain-core ];
meta = with lib; { description = "LangChain text splitters"; homepage = "https://github.com/langchain-ai/langchain"; license = licenses.mit; };
};
mistralai = fetchWheel {
pname = "mistralai"; version = "2.4.7"; hash = "sha256-FjnL0tjxjHIqfm2Fl4PCAdUkC668MUkdJxWza8o9gK8=";
propagatedBuildInputs = with python3Packages; [ httpx pydantic python-dateutil ];
meta = with lib; { description = "Mistral AI API client"; homepage = "https://github.com/mistralai/client-python"; license = licenses.asl20; };
};
caldav = fetchWheel {
pname = "caldav"; version = "3.2.0"; hash = "sha256-OTYfRgqWWZuOTvu91xE4Ktsbvo/CeOrEZQ8jy2FV7KU=";
propagatedBuildInputs = with python3Packages; [ httpx icalendar python-dateutil ];
meta = with lib; { description = "CalDAV client"; homepage = "https://github.com/python-caldav/caldav"; license = licenses.asl20; };
};
in
python3Packages.buildPythonApplication rec {
pname = "nextcloud-mcp-server";
version = "0.121.3";
pyproject = true;
src = fetchFromGitHub {
owner = "cbcoutinho";
repo = "nextcloud-mcp-server";
rev = "v${version}";
hash = "sha256-U6BG5anTEllNnJzta4VV6QOfn86+N15q6v/SfLGM7mc=";
};
build-system = [ python3Packages.uv-build ];
dependencies = with python3Packages; [
mcp httpx pillow icalendar pydantic click pyjwt
aiosqlite alembic authlib fastembed anthropic boto3 starlette
jinja2 markdownify pymupdf pymupdf4llm openai dynaconf sqlalchemy
pythonvcard4 prometheus-client python-json-logger importlib-metadata
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 icalendar-searcher
opentelemetry-exporter-otlp-proto-grpc qdrant-client
opentelemetry-instrumentation-asgi opentelemetry-instrumentation-httpx
opentelemetry-instrumentation-logging langchain-text-splitters mistralai caldav
];
postPatch = ''
substituteInPlace pyproject.toml \
--replace-quiet '"uv_build>=0.11.5,<0.12.0"' '"uv_build"' \
--replace-quiet '" (>=1.27,<1.28)"' '""' \
--replace-quiet '" (>=0.28.1,<0.29.0)"' '""' \
--replace-quiet '" (>=10.3.0,<12.0.0)"' '""' \
--replace-quiet '" (>=7.1.0,<7.2.0)"' '""' \
--replace-quiet '" (>=3.0.1,<4.0)"' '""' \
--replace-quiet '" (>=1.28.2,<2.0.0)"' '""' \
--replace-quiet '" (>=2.0.0,<3.0.0)"' '""' \
--replace-quiet '">=3.0.1,<4.0"' '""' \
--replace-quiet '">=3.8.0,<4.0"' '""' \
--replace-quiet '">=3.2.13,<4.0"' '""' \
--replace-quiet '">=1.28.2"' '""' \
--replace-quiet '">=0.21.0"' '""' \
--replace-quiet '">=3.2.0"' '""' \
--replace-quiet '">=0.2.0"' '""' \
--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;
meta = with lib; {
description = "MCP server for Nextcloud files, calendar, contacts, notes, deck, talk, sharing";
homepage = "https://github.com/cbcoutinho/nextcloud-mcp-server";
license = licenses.agpl3Only;
mainProgram = "nextcloud-mcp-server";
platforms = platforms.all;
};
}
+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 { src = fetchFromGitHub {
owner = "jmagar"; owner = "jmagar";
repo = "sabnzbd-mcp"; repo = "sabnzbd-mcp";
rev = "refs/heads/main"; rev = "9d691ed70b72397fddec03ca4ec68c81b30c79c3";
hash = "sha256-1sEnHH40cDVT5oiZD2Xywl7S9vJThii/ce+6r+XmpSw="; hash = "sha256-1sEnHH40cDVT5oiZD2Xywl7S9vJThii/ce+6r+XmpSw=";
}; };
+8 -2
View File
@@ -39,14 +39,14 @@ let
in in
python3Packages.buildPythonApplication rec { python3Packages.buildPythonApplication rec {
pname = "zotero-mcp"; pname = "zotero-mcp";
version = "0.2.2"; version = "0.5.0";
pyproject = true; pyproject = true;
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "54yyyu"; owner = "54yyyu";
repo = "zotero-mcp"; repo = "zotero-mcp";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-GZkzABsUh6qua66K4URPq0InLgs6cqLgKEXm7wzT+s8="; hash = "sha256-ioy6bdP+jFioUGBKiiYtD4nbdFe6v2E3nCi6s9+dTT0=";
}; };
build-system = with python3Packages; [ build-system = with python3Packages; [
@@ -67,6 +67,12 @@ python3Packages.buildPythonApplication rec {
pymupdf pymupdf
ebooklib ebooklib
pdfplumber pdfplumber
# Semantic search
chromadb
sentence-transformers
openai
google-genai
tiktoken
]; ];
# Optional: semantic search dependencies # Optional: semantic search dependencies