Skip to content

fix(packaging): publish a README on PyPI and modernise project metadata - #52

Merged
blackaxgit merged 1 commit into
mainfrom
fix/pypi-metadata
Jul 27, 2026
Merged

fix(packaging): publish a README on PyPI and modernise project metadata#52
blackaxgit merged 1 commit into
mainfrom
fix/pypi-metadata

Conversation

@blackaxgit

Copy link
Copy Markdown
Owner

The problem

https://pypi.org/project/blc-ssh-mcp/ renders an empty body — just the name and a one-line summary. pyproject.toml declared no readme, so the built wheel carried a zero-length long description:

Description-Content-Type: (absent)
long_description: 0 chars          <- 0.6.1 as published

Package metadata cannot be edited on PyPI and published files are immutable, so correcting this requires a release. That is the only reason 0.6.2 exists.

Changes

readme = "README.md" — long description goes from 0 to 26,936 chars.

All 7 relative README links made absolute. PyPI resolves relative Markdown links against pypi.org, not the repo, so every one of these would have 404'd for users reading the project page:

[LICENSE](LICENSE) · [CHANGELOG.md](CHANGELOG.md) ×2 · [SECURITY.md](SECURITY.md) · [CONTRIBUTING.md](CONTRIBUTING.md) · [compose.yaml](compose.yaml) · config/servers.example.toml

An 8th was caught only by re-checking the built artifact: the license badge's link target (](LICENSE) at the end of an image link), which the plain-text replacement pass missed.

Summary rewritten. Old: "SSH MCP server for managing infrastructure via Claude Code" — names a single MCP client and never says what the server does. New: "MCP server giving AI assistants SSH access to run commands, transfer files, and manage server fleets".

license migrated to the PEP 639 SPDX expression. license = "MPL-2.0" + license-files = ["LICENSE"] replaces the deprecated {text = "..."} table, and the correspondingly deprecated License :: OSI Approved :: classifier is dropped. Published metadata now carries License-Expression: MPL-2.0; License-File: LICENSE is unchanged.

More discoverable on PyPI: Changelog, Documentation, Security Policy and Container Image links; the System Administrators audience; sftp, devops, automation keywords.

Verification

twine check — the tool that specifically validates long-description rendering for PyPI:

Checking blc_ssh_mcp-0.6.2-py3-none-any.whl: PASSED
Checking blc_ssh_mcp-0.6.2.tar.gz: PASSED

Read back from the built wheel's METADATA:

Summary: MCP server giving AI assistants SSH access to run commands, transfer files, and manage server fleets
License-Expression: MPL-2.0
Description-Content-Type: text/markdown
long_description: 26936 chars
relative links remaining: 0
  • pytest718 passed
  • ruff format --check / ruff check src/ tests/ / mypy src/ / bandit -r src/ -q / pip-audit — clean
  • gitleaks scoped to origin/main..HEAD — no leaks

Note

No code changes — src/ssh_mcp/ is touched only by the version bump. The trusted publisher is already configured, so tagging v0.6.2 after merge publishes without further setup.

Not done here (flagging, not fixing)

Provides-Extra: dev is published in the metadata, so pip install blc-ssh-mcp[dev] advertises pytest/ruff/bandit to end users. Moving dev dependencies to PEP 735 [dependency-groups] would keep them out of the distribution entirely, but it changes uv sync --extra dev across both workflows and the determinism tests that assert on it — worth its own PR.

0.6.1's PyPI page rendered an empty body. pyproject.toml declared no `readme`,
so the wheel carried a zero-length long description. Package metadata cannot be
edited on PyPI and published files are immutable, so fixing it requires a
release — that is the only reason 0.6.2 exists.

- readme = "README.md": long description goes from 0 to ~27 KB
- make all 7 relative README links absolute. PyPI resolves relative links
  against pypi.org, so [LICENSE](LICENSE), [CHANGELOG.md](CHANGELOG.md) and
  friends would have 404'd. Includes the license badge's link target, which
  the plain-text pass missed.
- rewrite the summary: the old one named a single MCP client and did not say
  what the server does
- migrate `license` to the PEP 639 SPDX expression, dropping the legacy
  {text = "..."} table and the deprecated License :: OSI Approved :: classifier
- add Changelog, Documentation, Security Policy and Container Image links,
  the System Administrators audience, and sftp/devops/automation keywords

Verified with `twine check` (PASSED on both artifacts) and by reading the built
wheel's METADATA: License-Expression: MPL-2.0, 26936-char description, zero
relative links remaining.
@blackaxgit
blackaxgit merged commit eec650b into main Jul 27, 2026
7 checks passed
@blackaxgit
blackaxgit deleted the fix/pypi-metadata branch July 27, 2026 01:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant