Summary
The published PyPI wheels do not match what a clean checkout builds from the repository.
At current main (6eec2d20700566700d367d6576792e490c35a56e), the repo only tracks one bundled experience JSON and does not track toolshield/mcp_scan.py. However, the published wheels include many additional
bundled experience files, and the 0.1.1 wheel also included mcp_scan.py.
This causes two issues:
- a clean source build is missing most bundled safety experiences advertised in the README;
- the current PyPI release,
0.1.2, is missing toolshield/mcp_scan.py, so toolshield auto crashes.
Package contents mismatch
Current git main contains:
- Bundled experience JSON files: 1
- toolshield/mcp_scan.py: absent
PyPI toolshield==0.1.1 contains:
- Bundled experience JSON files: 30
- toolshield/mcp_scan.py: present
PyPI toolshield==0.1.2 contains:
- Bundled experience JSON files: 31
- toolshield/mcp_scan.py: absent
The only tracked bundled experience in git is: toolshield/experiences/claude-sonnet-4.5/gmail-mcp.json
But the published wheels include additional bundled experiences such as:
filesystem-mcp.json
terminal-mcp.json
postgres-mcp.json
playwright-mcp.json
notion-mcp.json
Reproduction
1. A clean source build is missing bundled files
git clone https://github.com/CHATS-Lab/ToolShield
cd ToolShield
git checkout 6eec2d20700566700d367d6576792e490c35a56e
uv build --wheel
python - <<'PY'
import glob
import zipfile
z = zipfile.ZipFile(glob.glob("dist/*.whl")[0])
names = z.namelist()
print("experiences:", sum(
x.startswith("toolshield/experiences/") and x.endswith(".json")
for x in names
))
print("mcp_scan.py:", sum(x.endswith("mcp_scan.py") for x in names))
PY
Observed:
experiences: 1
mcp_scan.py: 0
Git confirms this is what is tracked:
git ls-files toolshield/experiences
# toolshield/experiences/claude-sonnet-4.5/gmail-mcp.json
git ls-files toolshield/mcp_scan.py
# no output
git grep -n "mcp_scan"
# toolshield/cli.py:532 imports toolshield.mcp_scan
2. toolshield auto is broken in PyPI 0.1.2
pip install "toolshield>=0.1.1,<0.2" currently resolves to 0.1.2.
python -c "from toolshield.mcp_scan import main" -> ModuleNotFoundError: No module named 'toolshield.mcp_scan'
The CLI also fails:
toolshield auto --agent claude_code
Observed:
File ".../toolshield/cli.py", line 532, in auto_discover
from toolshield.mcp_scan import main as scan_main
ModuleNotFoundError: No module named 'toolshield.mcp_scan'
3. Clean source builds cannot run advertised bundled import examples
The README advertises commands such as:
toolshield import --exp-file terminal-mcp.json --agent claude_code
toolshield import --exp-file filesystem-mcp.json --agent claude_code
toolshield import --exp-file postgres-mcp.json --agent claude_code
But a wheel built from a clean checkout only includes gmail-mcp.json.
Example:
pip install dist/toolshield-0.1.1-py3-none-any.whl
toolshield import --exp-file terminal-mcp.json --agent claude_code
Observed:
Experience file not found: 'terminal-mcp.json'
Available bundled experiences for claude-sonnet-4.5: gmail-mcp.json
4. Version numbers are desynchronized
For PyPI 0.1.2:
python -c "import importlib.metadata as m; print(m.version('toolshield'))"
# 0.1.2
python -c "import toolshield; print(toolshield.__version__)"
# 0.1.0
At current main, pyproject.toml still says:
version = "0.1.1"
So there are three different version values:
PyPI metadata: 0.1.2
pyproject.toml on main: 0.1.1
toolshield.__version__: 0.1.0
CI gap
Current CI only runs:
ruff check toolshield/
pytest tests/ -v --tb=short
The pytest step is conditional and there is currently no tests/ directory, so it is skipped.
CI does not currently:
- build the wheel from a clean checkout;
- inspect wheel contents;
- install the built wheel;
- smoke-test the installed CLI.
Likely root cause
The release wheels appear to have been built from local working trees containing files that were not committed. Hatch includes package files that are present on disk at build time, so untracked local files can
end up in a wheel, while a clean checkout silently omits them.
That explains why:
- PyPI wheels contain many experience files not present in git;
- mcp_scan.py appeared in 0.1.1 but disappeared in 0.1.2;
- clean source builds differ from published wheels.
Suggested fixes
-
Commit the bundled experience JSON files and toolshield/mcp_scan.py, or generate them through a committed, reproducible build step.
-
Add CI that builds a wheel from a clean checkout and asserts expected contents.
-
Smoke-test installed-wheel commands in CI, for example:
- toolshield list
- toolshield import --all --agent claude_code --source_location
- toolshield auto --help
-
Single-source the package version, for example from package metadata or Hatch’s version configuration.
-
Add a release workflow that builds and publishes from a clean tag.
Impact
Users installing the current PyPI release cannot run toolshield auto.
Users building from source get a different wheel than PyPI and cannot use most README examples for bundled experiences.
This makes downstream integrations unreliable because package contents vary depending on how the wheel was produced.
Summary
The published PyPI wheels do not match what a clean checkout builds from the repository.
At current
main(6eec2d20700566700d367d6576792e490c35a56e), the repo only tracks one bundled experience JSON and does not tracktoolshield/mcp_scan.py. However, the published wheels include many additionalbundled experience files, and the 0.1.1 wheel also included
mcp_scan.py.This causes two issues:
0.1.2, is missingtoolshield/mcp_scan.py, sotoolshield autocrashes.Package contents mismatch
Current git
maincontains:PyPI toolshield==0.1.1 contains:
PyPI toolshield==0.1.2 contains:
The only tracked bundled experience in git is:
toolshield/experiences/claude-sonnet-4.5/gmail-mcp.jsonBut the published wheels include additional bundled experiences such as:
Reproduction
1. A clean source build is missing bundled files
Observed:
experiences: 1
mcp_scan.py: 0
Git confirms this is what is tracked:
2. toolshield auto is broken in PyPI 0.1.2
pip install "toolshield>=0.1.1,<0.2"currently resolves to 0.1.2.python -c "from toolshield.mcp_scan import main"->ModuleNotFoundError: No module named 'toolshield.mcp_scan'The CLI also fails:
Observed:
3. Clean source builds cannot run advertised bundled import examples
The README advertises commands such as:
But a wheel built from a clean checkout only includes gmail-mcp.json.
Example:
Observed:
4. Version numbers are desynchronized
For PyPI 0.1.2:
At current main, pyproject.toml still says:
version = "0.1.1"
So there are three different version values:
CI gap
Current CI only runs:
ruff check toolshield/
pytest tests/ -v --tb=short
The pytest step is conditional and there is currently no tests/ directory, so it is skipped.
CI does not currently:
Likely root cause
The release wheels appear to have been built from local working trees containing files that were not committed. Hatch includes package files that are present on disk at build time, so untracked local files can
end up in a wheel, while a clean checkout silently omits them.
That explains why:
Suggested fixes
Commit the bundled experience JSON files and toolshield/mcp_scan.py, or generate them through a committed, reproducible build step.
Add CI that builds a wheel from a clean checkout and asserts expected contents.
Smoke-test installed-wheel commands in CI, for example:
Single-source the package version, for example from package metadata or Hatch’s version configuration.
Add a release workflow that builds and publishes from a clean tag.
Impact
Users installing the current PyPI release cannot run toolshield auto.
Users building from source get a different wheel than PyPI and cannot use most README examples for bundled experiences.
This makes downstream integrations unreliable because package contents vary depending on how the wheel was produced.