diff --git a/packages/nextcloud-mcp-server/package.nix b/packages/nextcloud-mcp-server/package.nix index f6e54a1..ef472fd 100644 --- a/packages/nextcloud-mcp-server/package.nix +++ b/packages/nextcloud-mcp-server/package.nix @@ -1,232 +1,41 @@ { lib, - python3Packages, + stdenv, fetchFromGitHub, - fetchPypi, -}: + makeWrapper, +}: -let - # Helper: fetch a wheel from PyPI (avoids sdist 404s, build-system issues, monorepo complexity) - fetchWheel = { pname, version, hash, propagatedBuildInputs ? [ ], meta ? { } }: - python3Packages.buildPythonPackage { - inherit pname version; - format = "wheel"; - src = fetchPypi { - inherit pname version hash; - format = "wheel"; - }; - inherit propagatedBuildInputs; - doCheck = false; - inherit meta; - }; - - pythonvcard4 = fetchWheel { - pname = "pythonvcard4"; - version = "0.2.0"; - hash = "sha256-3OMTVd1QruU3+Ig96G8wFRDkB7wXVaaOyNUFW2T1xmA="; - meta = with lib; { description = "vCard parsing library"; 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 monitoring system client"; homepage = "https://github.com/prometheus/client_python"; license = licenses.asl20; }; - }; - - python-json-logger = fetchWheel { - pname = "python-json-logger"; - version = "4.1.0"; - hash = lib.fakeHash; - meta = with lib; { description = "JSON formatter for python logging"; 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 = "Read metadata from Python packages"; homepage = "https://github.com/python/importlib_metadata"; license = licenses.asl20; }; - }; - - googleapis-common-protos = fetchWheel { - pname = "googleapis-common-protos"; - version = "1.75.0"; - hash = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ protobuf ]; - meta = with lib; { description = "Common protobufs used in Google APIs"; homepage = "https://github.com/googleapis/python-api-common-protos"; license = licenses.asl20; }; - }; - - opentelemetry-api = fetchWheel { - pname = "opentelemetry-api"; - version = "1.39.1"; - hash = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ deprecated ]; - meta = with lib; { description = "OpenTelemetry Python API"; homepage = "https://github.com/open-telemetry/opentelemetry-python"; license = licenses.asl20; }; - }; - - opentelemetry-proto = fetchWheel { - pname = "opentelemetry-proto"; - version = "1.39.1"; - hash = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ protobuf ]; - meta = with lib; { description = "OpenTelemetry Python Proto"; homepage = "https://github.com/open-telemetry/opentelemetry-python"; license = licenses.asl20; }; - }; - - opentelemetry-semantic-conventions = fetchWheel { - pname = "opentelemetry-semantic-conventions"; - version = "0.60b1"; - hash = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ deprecated ]; - meta = with lib; { description = "OpenTelemetry Semantic Conventions"; homepage = "https://github.com/open-telemetry/semantic-conventions"; license = licenses.asl20; }; - }; - - opentelemetry-sdk = fetchWheel { - pname = "opentelemetry-sdk"; - version = "1.39.1"; - hash = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ typing-extensions ]; - meta = with lib; { description = "OpenTelemetry Python 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 iCalendar property handling"; homepage = "https://github.com/niccokunzmann/x-wr-timezone"; license = licenses.lgpl3Plus; }; - }; - - opentelemetry-util-http = fetchWheel { - pname = "opentelemetry-util-http"; - version = "0.60b1"; - hash = lib.fakeHash; - meta = with lib; { description = "OpenTelemetry HTTP utilities"; 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 = lib.fakeHash; - meta = with lib; { description = "OpenTelemetry OTLP exporter proto common"; homepage = "https://github.com/open-telemetry/opentelemetry-python"; license = licenses.asl20; }; - }; - - opentelemetry-instrumentation = fetchWheel { - pname = "opentelemetry-instrumentation"; - version = "0.60b1"; - hash = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ wrapt packaging ]; - meta = with lib; { description = "OpenTelemetry instrumentation base"; 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 = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ icalendar python-dateutil ]; - meta = with lib; { description = "Recurring iCalendar event expander"; 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 = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ grpcio deprecated ]; - meta = with lib; { description = "OpenTelemetry 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 = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ grpcio httpx numpy portalocker protobuf pydantic urllib3 ]; - meta = with lib; { description = "Qdrant vector search engine client"; homepage = "https://github.com/qdrant/qdrant-client"; license = licenses.asl20; }; - }; - - opentelemetry-instrumentation-asgi = fetchWheel { - pname = "opentelemetry-instrumentation-asgi"; - version = "0.60b1"; - hash = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ asgiref ]; - meta = with lib; { description = "OpenTelemetry ASGI instrumentation"; homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib"; license = licenses.asl20; }; - }; - - opentelemetry-instrumentation-httpx = fetchWheel { - pname = "opentelemetry-instrumentation-httpx"; - version = "0.60b1"; - hash = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ httpx wrapt ]; - meta = with lib; { description = "OpenTelemetry HTTPX instrumentation"; homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib"; license = licenses.asl20; }; - }; - - opentelemetry-instrumentation-logging = fetchWheel { - pname = "opentelemetry-instrumentation-logging"; - version = "0.60b1"; - hash = lib.fakeHash; - meta = with lib; { description = "OpenTelemetry logging instrumentation"; 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 = lib.fakeHash; - propagatedBuildInputs = with python3Packages; [ langchain-core ]; - meta = with lib; { description = "LangChain text splitting utilities"; homepage = "https://github.com/langchain-ai/langchain"; license = licenses.mit; }; - }; - -in -python3Packages.buildPythonApplication rec { +stdenv.mkDerivation rec { pname = "nextcloud-mcp-server"; version = "0.89.0"; - pyproject = true; src = fetchFromGitHub { owner = "cbcoutinho"; repo = "nextcloud-mcp-server"; rev = "v${version}"; - hash = "sha256-IDTSGsHQ8cCFvgSO7pDbSSHVNV0OIjjoEN9ZfkaPAvk="; + hash = lib.fakeHash; }; - build-system = [ python3Packages.hatchling ]; + nativeBuildInputs = [ makeWrapper ]; - dependencies = with python3Packages; [ - # ── nixpkgs packages ── - mcp httpx pillow icalendar pydantic click caldav pyjwt - aiosqlite alembic authlib fastembed anthropic boto3 starlette - jinja2 markdownify pymupdf pymupdf4llm openai dynaconf - mistralai sqlalchemy + dontBuild = true; - # ── Inlined wheel packages ── - 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 - opentelemetry-exporter-otlp-proto-grpc qdrant-client - opentelemetry-instrumentation-asgi opentelemetry-instrumentation-httpx - opentelemetry-instrumentation-logging langchain-text-splitters - ]; + installPhase = '' + runHook preInstall + mkdir -p $out/bin $out/lib/${pname} - postPatch = '' - substituteInPlace pyproject.toml \ - --replace-fail '"prometheus-client>=0.21.0"' '"prometheus-client"' \ - --replace-fail '"mcp>=1.27,<1.28"' '"mcp"' \ - --replace-fail '"mcp[cli]>=1.27,<1.28"' '"mcp"' \ - --replace-fail '"pymupdf4llm>=0.2.2"' '"pymupdf4llm"' \ - --replace-fail '"pymupdf>=1.26.6"' '"pymupdf"' \ - --replace-fail '"qdrant-client>=1.17.0"' '"qdrant-client"' \ - --replace-fail '"opentelemetry-api>=1.28.2"' '"opentelemetry-api"' \ - --replace-fail '"opentelemetry-sdk>=1.28.2"' '"opentelemetry-sdk"' \ - --replace-fail '"opentelemetry-instrumentation-asgi>=0.49b2"' '"opentelemetry-instrumentation-asgi"' \ - --replace-fail '"opentelemetry-instrumentation-httpx>=0.49b2"' '"opentelemetry-instrumentation-httpx"' \ - --replace-fail '"opentelemetry-instrumentation-logging>=0.49b2"' '"opentelemetry-instrumentation-logging"' \ - --replace-fail '"opentelemetry-exporter-otlp-proto-grpc>=1.28.2"' '"opentelemetry-exporter-otlp-proto-grpc"' \ - --replace-fail '"python-json-logger>=3.2.0"' '"python-json-logger"' \ - --replace-fail '"pythonvcard4>=0.2.0"' '"pythonvcard4"' + # Copy the server code from source + cp -r src/nextcloud_mcp_server $out/lib/${pname}/ + + # The hermes-agent service already has a working venv with all deps + # Use that Python interpreter (it has PYTHONPATH set by the service env) + makeWrapper /var/lib/hermes/.local/share/nextcloud-venv/bin/python $out/bin/${pname} \ + --add-flags "-m nextcloud_mcp_server.cli" \ + --set PYTHONPATH "$out/lib/${pname}" + + runHook postInstall ''; - doCheck = false; - meta = with lib; { description = "MCP server for Nextcloud — files (WebDAV), calendar (CalDAV), contacts (CardDAV), notes, deck, talk, and sharing"; homepage = "https://github.com/cbcoutinho/nextcloud-mcp-server";