fix: 2nd-pass audit Major — protocol contract test, wheel fallback coverage, dead modular example, clone-vs-starter boundary#33
Merged
Conversation
…verage, dead modular example, clone-vs-starter boundary Resolves all 4 Major findings from the second-pass audit on PR #32. [M1] tests/test_tools.py: add `test_greet_registered_on_server` - Parallels test_server_info.py and test_code_review.py, both of which had an equivalent registration assertion already. - Calls `mcp.list_tools()` and verifies the greet tool is wired in AND that the generated JSON Schema actually reflects the Annotated[..., Field( min_length, max_length)] constraints. Without this, FastMCP's schema generation was an unverified link in the protocol contract. [M2] tests/test_server_info.py: cover wheel-install fallback path - The existing tests all walk the source tree and find pyproject.toml. That's the dev/editable-install path. When a user does `pip install my-mcp-server` from a wheel, pyproject.toml is NOT shipped — _read_pyproject returns None and _server_metadata must fall back to importlib.metadata.version(). That branch (server_info.py:51-56) was previously 0% covered. - Three new tests via monkeypatch: · `_read_pyproject` returns None → version comes from importlib.metadata. · `_read_pyproject` returns None AND importlib.metadata raises PackageNotFoundError → returns "0.0.0" fallback. · pyproject.toml exists but has no [project] table → covers the server_info.py:42 exit. - server_info.py coverage: 79% → 96%. [M3] src/my_mcp_server/tools/greet.py: delete dead modular example - The file defined `greet_formal` + a `register()` function, but server.py never called `from my_mcp_server.tools.greet import register` to wire it in. 100% dead code with 0% test coverage. - Updated server.py:71-74 comment to describe the modular pattern in prose without referencing the deleted file. [M4] SECURITY.md: distinguish code-level vs runtime GitHub settings - Previous text "Repo-side toggles enabled — Secret scanning + push protection + Dependabot security updates + branch protection on main" was misleading for clones: GitHub does NOT copy these settings when a template is cloned into a new repo. Clones inherited the false belief that "I'm safe because the starter is." - Added a new section "What clones inherit vs. what they don't" with the exact `gh api` invocations clones can run to replicate the toggles on their own fork. Coverage moved 70.64% → 84.69% (also benefits from M3 deletion of the 0%-covered dead module). 21 tests pass (was 17).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves all 4 Major findings from the second-pass audit. Companion to PR #32 (which fixed the 2 Critical findings).
[M1]
tests/test_tools.py— addtest_greet_registered_on_serverParallels
test_server_info.pyandtest_code_review.py(both already had this). Callsmcp.list_tools()and verifies the greet tool is wired in and that the generated JSON Schema actually reflectsAnnotated[..., Field(min_length, max_length)]constraints. Without this, FastMCP's schema generation was an unverified link in the MCP protocol contract.[M2]
tests/test_server_info.py— cover wheel-install fallback pathExisting tests walk the source tree and find
pyproject.toml. That's the dev/editable-install path. When a user doespip install my-mcp-serverfrom a wheel, pyproject.toml is NOT shipped —_read_pyprojectreturns None and_server_metadatafalls back toimportlib.metadata.version(). That branch (server_info.py:51-56) was previously 0% covered.Three new tests via
monkeypatch:_read_pyprojectreturns None → version comes fromimportlib.metadata._read_pyprojectreturns None ANDimportlib.metadataraisesPackageNotFoundError→ returns"0.0.0"fallback.[project]table → coversserver_info.py:42exit.server_info.pycoverage: 79% → 96%.[M3]
src/my_mcp_server/tools/greet.py— delete dead modular exampleThe file defined
greet_formal+ aregister()function, butserver.pynever calledfrom my_mcp_server.tools.greet import registerto wire it in. 100% dead code, 0% test coverage. Updatedserver.py:71-74comment to describe the modular pattern in prose without referencing the deleted file.[M4]
SECURITY.md— distinguish code-level vs runtime GitHub settingsPrevious text was misleading for clones: GitHub does NOT copy
secret_scanning/push_protection/dependabot_security_updates/ branch protection when a template is cloned. Clones inherited the false belief "I'm safe because the starter is."Added a new section "What clones inherit vs. what they don't" with the exact
gh apiinvocations clones can run to replicate the toggles on their own fork.Coverage delta
server_info.pytools/greet.pyTest plan
ruff check ./ruff format --check ./mypy src/all cleananalyze (python)+analyze (actions)green