[build-system] requires = ["setuptools>=68", "wheel"] build-backend = "setuptools.build_meta" [project] name = "vaultbeat-apple-health" # ⚠️ RELEASES GO OUT FROM THE PUBLIC REPO (Fino-wind/vaultbeat-apple-health), never from # the monorepo's copy of this file. Only the public README carries the # `mcp-name` marker the official MCP Registry validates; the monorepo's README # is developer-facing and does not, so a wheel built there reaches PyPI with no # marker and the Registry 403s it — the package installs fine via uvx and is # invisible to every directory that ingests the Registry. # Flow: sync src (excluding README) → bump BOTH pyprojects → build and publish # from the public repo. # # 🔴 This warning has sat directly above the version line since 2026-08-07, # when 0.3.1 was burned this way. It half-worked, and the two halves fail # differently — verified per-version against PyPI on 2026-08-18, not recalled: # 0.3.11 · 0.4.0 · 0.4.1 · 0.4.2 built from the public repo, marker PRESENT, # publishable to the Registry — and nobody ever ran `mcp-publisher publish`. # 0.4.3 · 0.4.4 built from the monorepo, marker ABSENT, # so the Registry 403s them and the version numbers are spent. # Net effect for five releases: every directory that ingests the Registry # (Glama, PulseMCP, mcp.so) kept handing installers 0.3.11 — the last build # WITHOUT headless key storage, i.e. the one that loses its private key on a # server. The worst possible version to be pinned to. # A comment cannot enforce this. `scripts/ci/check_mcp_registry_current.py` # now does, with one rule per failure above; if that guard is ever deleted, # this paragraph is what comes back. version = "0.8.1" description = "Local MCP server for Vaultbeat — AI Health Sync: your AI agent reads your end-to-end-encrypted Apple Health data (sleep, cycle, weight, water), decrypted only on your machine" readme = "README.md" requires-python = ">=3.11" dependencies = [ # Lower bounds are SECURITY floors, not "oldest version that imports". Directory # listings run dependency scanners against this range and publish the verdict next # to the product name — mcp-marketplace showed "Use Caution / High Risk, 8 known # CVEs" on 2026-07-31, which for an E2EE health product is the worst possible # badge to wear. Both floors below were raised that day after confirming each # advisory against osv.dev directly (the scanner's claim was accurate). # # cryptography: the old ceiling was <47.0.0, which excluded 48.0.1 — the fix for # the vulnerable OpenSSL shipped inside the wheels. The range could not resolve to # a clean version at all, so raising the floor REQUIRED raising the ceiling too. "cryptography>=48.0.1,<50.0.0", "httpx>=0.28.0,<1.0.0", "keyring>=24", # mcp: 1.27.2 fixes "HTTP transports serve session requests without validation" # and 1.28.1 the WebSocket transport. Not academic here — `serve --transport http` # is a supported mode of this very server. Ceiling stays <2.0.0 (2.x is a major). "mcp>=1.28.1,<2.0.0", # Not optional, and it used to be. `bind` prints a QR for the phone to scan — # that scan IS the first mile of this product, and without qrcode the command # printed a raw JSON blob plus "install the qr extra and run me again". The # owner hit it on 2026-08-11 while walking the first-time-bind path as a user: # he had a payload on screen, a phone in his hand, and nothing to point it at. # Anyone who reaches `bind` from `--help` rather than from the website's # copy-paste command lands in the same gap. # # Pure Python, no build step, ~90 KB. Making the single unavoidable action of # onboarding opt-in was the design error, not the dependency. "qrcode>=8.0.0,<9.0.0", ] [project.optional-dependencies] dev = [ "pytest>=8.3.0,<9.0.0", "ruff>=0.11.0,<1.0.0", "mypy>=1.13.0,<2.0.0", # The streamable-HTTP transport tests reach uvicorn through `mcp`'s server # stack. It was never declared: this checkout's venv happened to carry it, so # `pytest` was green here while a clean clone (the public repo, and therefore # anyone running the suite from scratch) failed on ModuleNotFoundError. # Found 2026-07-26 while preparing the 0.2.3 release from the public repo. # httpx needs no entry — it is already a runtime dependency above. "uvicorn>=0.30.0", ] # Kept as an empty-but-valid extra so `uvx --from 'vaultbeat-mcp[qr]' …` — the # command printed on the website, in the README and in every older doc — keeps # resolving instead of erroring on an unknown extra. qrcode is a hard dependency # now, so this asks for nothing; it exists purely so already-published # instructions do not break. qr = [] # Without these, PyPI shows no link back to the source — which a directory scanner # flags outright ("PyPI package has no GitHub URL", mcp-marketplace 2026-07-31). # For a server whose entire pitch is "audit the crypto yourself", a listing with no # route to the code undercuts the claim. [project.urls] Homepage = "https://vaultbeat.app" Repository = "https://github.com/Fino-wind/vaultbeat-apple-health" Issues = "https://github.com/Fino-wind/vaultbeat-community/issues" Documentation = "https://vaultbeat.app/mcp" [project.scripts] # Primary name, deliberately identical to the PyPI distribution name so that # `uvx vaultbeat-apple-health ` resolves without --from (2026-08-31 rename). vaultbeat-apple-health = "vaultbeat_mcp_local.cli:main" # Back-compat: the name this package shipped under until 0.6.1. vaultbeat-mcp = "vaultbeat_mcp_local.cli:main" # Back-compat alias: pre-rename installs and docs invoke vaultbeat-mcp-local. vaultbeat-mcp-local = "vaultbeat_mcp_local.cli:main" [tool.pytest.ini_options] # src-layout: make vaultbeat_mcp_local importable for the test run without depending # on an editable install being present. The editable .pth can silently drop out # when the venv is rebuilt (e.g. via `uv sync`), which otherwise breaks collection. pythonpath = ["src"] [tool.ruff] line-length = 100 target-version = "py311" [tool.mypy] python_version = "3.11" check_untyped_defs = true warn_unused_ignores = true warn_return_any = true [tool.setuptools.packages.find] where = ["src"]