Shared taxonomies and decorator for MCP tools to self-declare ADR 0016 Layer-1 facts (risk, content trust, idempotency, lifecycle).
Project description
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 .
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_tool_contract-0.1.1.tar.gz.
File metadata
- Download URL: mcp_tool_contract-0.1.1.tar.gz
- Upload date:
- Size: 5.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a97241b260b834bf48f6b6818bc8bb77ee621c527de6c9e4b20743acee9b51c
|
|
| MD5 |
8798ae99ed2baaa06154d4752edeac4a
|
|
| BLAKE2b-256 |
bc90d4e04d9fb46586d215f76fd3fbae19d8a5a52f28f30da7f5e7cdb0b191d0
|
File details
Details for the file mcp_tool_contract-0.1.1-py3-none-any.whl.
File metadata
- Download URL: mcp_tool_contract-0.1.1-py3-none-any.whl
- Upload date:
- Size: 5.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df7222537faf8d52533ec55f375cd2f5b5bfa5e16a77f885c2dbe762aefcfb38
|
|
| MD5 |
6106f6801c93ce8916588c365c7e7c13
|
|
| BLAKE2b-256 |
4a41b262e4f334bbfa1c6a5c6b62f19e0cd5b6bf95cc7aeea023fed6183cba78
|