Skip to main content

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)

Source distribution for mcp-tool-contract 0.1.1
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)

Table of built distributions (wheels) for mcp-tool-contract 0.1.1
File Interpreter ABI Platform Actions
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.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page