%global pypi_name nninteractive-agent %global import_name nninteractive_agent # Upstream has no release or tag yet: package a git snapshot. %global commit 57b06cb4bac0aedaf4946b8f4a65247d998eff6e %global shortcommit %(c=%{commit}; echo ${c:0:7}) %global snapdate 20261023 Name: python-%{pypi_name} Version: 0.1.0^%{snapdate}git%{shortcommit} Release: 1%{?dist} Summary: nnInteractive as a tool for AI agents (MCP server and skill) # Apache-2.0 covers everything shipped. The web demo (and its bundled marked, # DOMPurify and NiiVue JavaScript) is removed in %%prep, see there. The # nnInteractive model weights are CC-BY-NC-SA-4.0 and are never packaged; they # are fetched per user at run time. License: Apache-2.0 URL: https://github.com/MIC-DKFZ/nninteractive-agent Source0: %{url}/archive/%{commit}/%{pypi_name}-%{shortcommit}.tar.gz # scikit-image < 0.26 has area_threshold=, not max_size= (Fedora 43-45 ship 0.25) Patch0: python-nninteractive-agent-skimage-0.25-remove-small-holes.patch # Test-only: the MCP stdio client drops PYTHONPATH, so the server subprocess # could not import the package from the buildroot Patch1: python-nninteractive-agent-mcp-test-pass-environment.patch # Fedora ships mcp 1.x; upstream targets the mcp 2.x low-level Server API Patch2: python-nninteractive-agent-mcp-1x-compat.patch BuildArch: noarch BuildRequires: python3-devel BuildRequires: pyproject-rpm-macros BuildRequires: python3-pytest %global _description %{expand: nninteractive-agent lets an AI coding agent (Claude Code, Codex or any MCP client) segment 3D images with nnInteractive from a plain-language request such as "segment and count all liver lesions". The agent loads the image, places point, box and scribble prompts, renders and inspects its own masks, corrects them and saves the result. It provides an MCP server (nninteractive-agent-mcp), a skill that teaches the agent the segmentation and correction workflow, and a verifier subagent. Nothing is installed into an agent's configuration until the user runs "nninteractive-agent setup claude" (or "setup codex"). Inference runs either on a remote nninteractive-server (no PyTorch needed on this machine) or locally with python3-nninteractive. The model weights are licensed CC-BY-NC-SA-4.0 (non-commercial) and are downloaded per user; they are not part of this package. The upstream browser demo is not included: it needs the Claude Agent SDK, whose Python package bundles the proprietary Claude Code CLI.} %description %_description %package -n python3-%{pypi_name} Summary: %{summary} Recommends: python3-nninteractive %description -n python3-%{pypi_name} %_description %prep %autosetup -p1 -n %{pypi_name}-%{commit} # Drop the web demo: claude-agent-sdk (its only LLM backend besides Codex) # bundles the proprietary Claude Code CLI, and the demo carries minified # third-party JavaScript. The MCP server, skill and CLI do not import it. rm -r src/%{import_name}/web sed -i -e '/^nninteractive-agent-web = /d' \ -e 's|, "web/static/\*\*/\*"||' \ -e 's|, plus a web demo||' pyproject.toml if grep -q 'web\.server\|web/static' pyproject.toml; then exit 1; fi if grep -rq 'from \.web\|nninteractive_agent\.web\|from \.\+web import' src/%{import_name}; then exit 1; fi # Upstream asks for mcp>=2.3; Fedora has 1.26 (f43, f44) and 1.27 (rawhide). # Patch2 lets the server run on both APIs. %%check runs real stdio MCP sessions # (initialize, tools, prompts, resources and a tool call) against Fedora's mcp. sed -i 's/"mcp>=2\.3"/"mcp>=1.26"/' pyproject.toml if ! grep -q '"mcp>=1.26"' pyproject.toml; then exit 1; fi %generate_buildrequires %pyproject_buildrequires %build %pyproject_wheel %install %pyproject_install %pyproject_save_files %{import_name} %check %pyproject_check_import # No GPU, network or weights here: the tests drive the workspace with a fake # nnInteractive session. Deselected: the web demo (removed), the Codex host # (needs the codex CLI and imports the web package) and one test that loads # web examples. %pytest -v tests \ --ignore=tests/test_web.py \ --ignore=tests/test_codex.py \ --ignore=tests/test_viewer_coords.py \ --deselect=tests/test_release.py::test_examples_from_a_directory_and_a_json_file # Upstream's MCP test lists tools, prompts and resources but never calls a # tool. Call one over stdio so Patch2's call path (CallToolResult) is exercised. cat > mcp_call_check.py <<'EOF' import os, sys, tempfile import anyio from mcp.client.session import ClientSession from mcp.client.stdio import StdioServerParameters, stdio_client async def main(): params = StdioServerParameters(command=sys.executable, env=dict(os.environ), args=[ "-m", "nninteractive_agent.mcp_server", "--server", "local", "--python", "off", "--workdir", tempfile.mkdtemp()]) async with stdio_client(params) as (r, w), ClientSession(r, w) as s: await s.initialize() res = await s.call_tool("save", {}) text = res.content[0].text print("save without an image ->", repr(text[:80]), "isError =", res.isError) assert res.isError and text, res anyio.run(main) print("MCP tool call OK") EOF %{py3_test_envvars} %{python3} mcp_call_check.py %files -n python3-%{pypi_name} -f %{pyproject_files} %license LICENSE %doc README.md %{_bindir}/nninteractive-agent %{_bindir}/nninteractive-agent-mcp %changelog * Mon Oct 26 2026 Morgan Hough - 0.1.0^20261023git57b06cb-1 - Initial package: MCP server, skill and verifier subagent for text-prompted nnInteractive segmentation from Claude Code, Codex or any MCP client. - Web demo removed (claude-agent-sdk bundles the proprietary Claude Code CLI). - mcp requirement relaxed to Fedora's 1.x; %%check runs a stdio MCP session. - Patch0: scikit-image 0.25 compatibility (area_threshold vs max_size). - Patch1: pass the environment to the MCP test's server subprocess. - Patch2: run on Fedora's mcp 1.x as well as upstream's mcp 2.x.