From 15906893c0e2045d89ca1ec58549825e965b1188 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sat, 4 Jul 2026 22:24:46 +0000 Subject: [PATCH 1/5] 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. --- packages/audiobookshelf-mcp/package.nix | 27 +++++++++++++++++++++++++ packages/default.nix | 1 + 2 files changed, 28 insertions(+) create mode 100644 packages/audiobookshelf-mcp/package.nix diff --git a/packages/audiobookshelf-mcp/package.nix b/packages/audiobookshelf-mcp/package.nix new file mode 100644 index 0000000..9a4c88a --- /dev/null +++ b/packages/audiobookshelf-mcp/package.nix @@ -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; + }; +} \ No newline at end of file diff --git a/packages/default.nix b/packages/default.nix index 6f189ac..d51cddd 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -20,5 +20,6 @@ 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 { }; } From 617bb9cab59a8ad7e33881af914067bc57e1845c Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 12 Jul 2026 11:09:19 +0000 Subject: [PATCH 2/5] pinchflat-mcp: add pagination, downloaded filter, and delete_media tool - list_media: add offset and downloaded params for API pagination - delete_media: new tool to delete downloaded files (with prevent_download option) - Bump timeout on delete to 120s --- packages/pinchflat-mcp/server.py | 37 +++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/pinchflat-mcp/server.py b/packages/pinchflat-mcp/server.py index 439a55b..4d5f669 100644 --- a/packages/pinchflat-mcp/server.py +++ b/packages/pinchflat-mcp/server.py @@ -150,11 +150,25 @@ def force_metadata_refresh(source_id: int) -> dict: # --- 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 = {} +def list_media( + source_id: Optional[int] = None, + limit: int = 50, + offset: int = 0, + downloaded: Optional[bool] = None, +) -> dict: + """List media items with pagination. Optionally filter by source_id or download status. + + Args: + source_id: Filter to a specific source + limit: Max items to return (default 50) + offset: Skip first N items for pagination (default 0) + downloaded: If True, only return downloaded media; if False, only undownloaded + """ + params = {"limit": limit, "offset": offset} if source_id: params["source_id"] = source_id + if downloaded is not None: + params["downloaded"] = "true" if downloaded else "false" return _get("/media", params=params) @@ -176,6 +190,23 @@ def force_download_media(media_id: int) -> dict: return _post(f"/media/{media_id}/force_download") +@mcp.tool() +def delete_media(media_id: int, prevent_download: bool = False) -> dict: + """Delete a media item's downloaded files from disk. + + Args: + media_id: The media item ID to delete + prevent_download: If True, prevent the item from being re-downloaded in the future + """ + params = {} + if prevent_download: + params["prevent_download"] = "true" + with httpx.Client(timeout=120) as client: + r = client.delete(f"{BASE}/media/{media_id}", headers=HEADERS, params=params) + r.raise_for_status() + return r.json() + + # --- Media Profiles --- @mcp.tool() From d009717854423bae7e2c03463f3a21fe2c8f2504 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 12 Jul 2026 11:14:43 +0000 Subject: [PATCH 3/5] audiobookshelf-mcp: fix src hash (from CI), still need vendorHash --- packages/audiobookshelf-mcp/package.nix | 2 +- .../__pycache__/server.cpython-312.pyc | Bin 0 -> 10428 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 packages/pinchflat-mcp/__pycache__/server.cpython-312.pyc diff --git a/packages/audiobookshelf-mcp/package.nix b/packages/audiobookshelf-mcp/package.nix index 9a4c88a..102c164 100644 --- a/packages/audiobookshelf-mcp/package.nix +++ b/packages/audiobookshelf-mcp/package.nix @@ -12,7 +12,7 @@ buildGoModule rec { owner = "michaeldvinci"; repo = "audiobookshelf-mcp"; rev = "e790d9c75085772180c95f2ec1376acc98e9282c"; - hash = lib.fakeHash; + hash = "sha256-vQR+Ej3Qtg8ehIUWnXkSayNYpqnOZPWV0TpTVPYh+io="; }; vendorHash = lib.fakeHash; diff --git a/packages/pinchflat-mcp/__pycache__/server.cpython-312.pyc b/packages/pinchflat-mcp/__pycache__/server.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e94f3f9065f478668eaead1ca85e0afd3bfaabfa GIT binary patch literal 10428 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 dV0pp7@uITh#LNTb4enQ2{6DZVut Date: Sun, 12 Jul 2026 11:14:52 +0000 Subject: [PATCH 4/5] fix: remove committed pyc, add to gitignore --- .gitignore | 1 + .../__pycache__/server.cpython-312.pyc | Bin 10428 -> 0 bytes 2 files changed, 1 insertion(+) delete mode 100644 packages/pinchflat-mcp/__pycache__/server.cpython-312.pyc diff --git a/.gitignore b/.gitignore index 6d4ce14..4dd2233 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ result-* # Local environment overrides .envrc.local /.dir-locals.el +__pycache__/ diff --git a/packages/pinchflat-mcp/__pycache__/server.cpython-312.pyc b/packages/pinchflat-mcp/__pycache__/server.cpython-312.pyc deleted file mode 100644 index e94f3f9065f478668eaead1ca85e0afd3bfaabfa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10428 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 dV0pp7@uITh#LNTb4enQ2{6DZVut Date: Sun, 12 Jul 2026 11:16:46 +0000 Subject: [PATCH 5/5] audiobookshelf-mcp: fix vendorHash (from CI) --- packages/audiobookshelf-mcp/package.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/audiobookshelf-mcp/package.nix b/packages/audiobookshelf-mcp/package.nix index 102c164..6d6978a 100644 --- a/packages/audiobookshelf-mcp/package.nix +++ b/packages/audiobookshelf-mcp/package.nix @@ -15,7 +15,7 @@ buildGoModule rec { hash = "sha256-vQR+Ej3Qtg8ehIUWnXkSayNYpqnOZPWV0TpTVPYh+io="; }; - vendorHash = lib.fakeHash; + vendorHash = "sha256-W8hlCGf4QdFbKc3QFc9pa4MWBhnp5A5GvWFNzg0BEhw="; meta = with lib; { description = "MCP server for Audiobookshelf — libraries, audiobooks, podcasts, authors, collections, playlists";