mcp-tool-contract
Shared taxonomies and a @tool decorator that let an MCP tool self-declare
the facts about itself that only its author knows for certain: risk level,
content trustworthiness, idempotency, and lifecycle (version/deprecation).
This implements Layer 1 ("Facts") of
ADR 0016
in central-mcp-gateway. Every upstream MCP service the gateway aggregates is
owned by the same team, so instead of the gateway guessing these facts from a
tool's name/description (or requiring them to be re-declared by hand in a
separate catalog file), the tool's own definition is the single source of
truth and the gateway reads it from tools/list.
Install
pip install mcp-tool-contract
or with uv:
uv add mcp-tool-contract
Usage
from mcp_tool_contract import tool, tool_annotations
@tool(
risk="external-publication", # one of RISK_LEVELS
content_trust="trusted", # one of CONTENT_TRUST_LEVELS
idempotent=False,
version="2.1.0",
)
def post_update(...):
...
When your MCP server framework builds the tools/list response for a tool,
merge tool_annotations(post_update) into that tool's annotations dict
alongside its real inputSchema and description (which this package does
not touch — your framework already derives those from the function
signature/docstring).
tool_annotations() returns {} for an undeclared function, so adoption can
be incremental: undecorated tools simply fall back to the gateway's existing
name/description heuristic, exactly as before.
Taxonomies
RISK_LEVELS/RISK_LEVEL_ORDER—read-only<low-risk-write<high-risk-write<external-publication<paid-operation<destructive.CONTENT_TRUST_LEVELS—trusted,untrusted,sensitive,prompt-injection-prone. Orthogonal to risk: a read-only tool can still return untrusted or adversarial content.
An unrecognised value for either field raises ValueError at decoration
time — a typo in the upstream fails that upstream's own CI, instead of
silently falling back to the gateway's heuristic.
Trust boundary
The gateway remains the single point of control (ADR 0001). A declared fact is the default; the gateway's static catalog may still veto or override any tool's effective risk, content-trust, or schema (ADR 0016 Layer 3), and an anti-downgrade check flags any tool whose effective risk or content-trust weakens between discovery cycles without a recorded catalog override.
Release
Bump version in pyproject.toml, then tag and push:
git tag v0.2.0
git push origin v0.2.0
.github/workflows/publish.yml builds and publishes the tagged version to
PyPI.
Development
uv sync --extra dev
uv run pytest
uv run ruff check .
Metadata
Release files for mcp-tool-contract 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| mcp_tool_contract-0.1.1.tar.gz | 5.5 kB | Without provenance | Details for mcp_tool_contract-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mcp_tool_contract-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for mcp_tool_contract-0.1.1-py3-none-any.whl |
Total release size: 10.8 kB
Release files / mcp_tool_contract-0.1.1.tar.gz
| Download URL | mcp_tool_contract-0.1.1.tar.gz |
|---|---|
| Size | 5.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6a97241b260b834bf48f6b6818bc8bb77ee621c527de6c9e4b20743acee9b51c
|
|
BLAKE2b-256 checksum How to use checksums |
bc90d4e04d9fb46586d215f76fd3fbae19d8a5a52f28f30da7f5e7cdb0b191d0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / mcp_tool_contract-0.1.1-py3-none-any.whl
| Download URL | mcp_tool_contract-0.1.1-py3-none-any.whl |
|---|---|
| Size | 5.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
df7222537faf8d52533ec55f375cd2f5b5bfa5e16a77f885c2dbe762aefcfb38
|
|
BLAKE2b-256 checksum How to use checksums |
4a41b262e4f334bbfa1c6a5c6b62f19e0cd5b6bf95cc7aeea023fed6183cba78
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Security for mcp-tool-contract 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.