mcp-toolsmith
mcp-toolsmith audits and compiles Python tool schemas for LLM agents, catching
vague names, missing argument descriptions, oversized schemas, overlapping
tools, and prompt-injection-like metadata before your agent uses them.
Pre-1.0: JSON tool files and static Python audits are safe by default.
Python execution requires --execute and should only be used with trusted code.
The public API may change before 1.0.0.
Tool schemas are not just documentation. In MCP, OpenAI-style tool calling, and agent frameworks, names, descriptions, and input schemas shape whether the model chooses the right tool and fills arguments correctly.
Install
pip install mcp-toolsmith
For local development:
python -m pip install -e ".[dev]"
Why?
LLM agents often fail because tool metadata is ambiguous.
Bad tool:
def run(query: str):
"""Run operation."""
return query
Audit:
mcp-toolsmith audit tools.py --execute --all-public --fail-on warning
Output:
WARNING name.vague: Tool name is too generic for reliable tool selection.
WARNING description.too_short: Tool description is too short to guide model selection.
WARNING schema.arg_description_missing: Argument descriptions are missing for: query.
Usage
Audit a project
Recursively audit supported Python and MCP JSON files:
mcp-toolsmith audit .
mcp-toolsmith audit src/
mcp-toolsmith audit src/tools/
Generated output, virtual environments, dependency directories, and common caches are excluded by default. Add explicit globs when needed:
mcp-toolsmith audit . --exclude "tests/**" --exclude "examples/**"
Store repeatable CI settings in pyproject.toml:
[tool.mcp-toolsmith]
profile = "openai"
fail-on = "warning"
include = ["src/**/*.py"]
exclude = ["tests/**", "examples/**", "src/generated/**"]
ignore = ["schema.description_too_short"]
max-schema-depth = 5
[[tool.mcp-toolsmith.per-file-ignores]]
path = "examples/**"
rules = ["schema.arg_description_missing"]
CLI values override project configuration, which overrides built-in defaults. Suppressions require specific rule codes. Inspect the settings used by the current project with:
mcp-toolsmith config show
Audit JSON tool definitions
JSON tool definitions are safe by default:
mcp-toolsmith audit tools.json
Example JSON input:
{
"tools": [
{
"name": "search_docs",
"description": "Search project documentation by natural language query.",
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Question or topic to search for."
},
"limit": {
"type": "integer",
"description": "Maximum number of results to return.",
"default": 5
}
},
"required": ["query"]
}
}
]
}
Example audit output:
OK Audited 1 tool(s) from tools.json
Mode: json
Profile: generic
Errors: 0 Warnings: 0
search_docs [mcp] ~55 schema tokens
No findings
Compile tools
Compile to MCP-style tool definitions:
mcp-toolsmith compile tools.json --target mcp
Compile to OpenAI-style function definitions:
mcp-toolsmith compile tools.json --target openai
Audit trusted Python files
Python files are parsed statically by default:
mcp-toolsmith audit tools.py
This discovers @tool-decorated functions without executing the file:
from mcp_toolsmith import tool
@tool
def search_docs(query: str, limit: int = 5) -> list[str]:
"""Search project documentation by natural language query.
Args:
query: Question or topic to search for.
limit: Maximum number of results to return.
"""
return []
Static mode maps common annotations such as str, int, float, bool,
dict, and list[str]. Use runtime execution only for trusted files when you
need full Pydantic/runtime schema generation:
mcp-toolsmith audit tools.py --execute
mcp-toolsmith compile tools.py --target mcp --execute
Use --execute only for trusted files. In both static and execution modes,
default Python discovery only includes functions decorated with @tool.
Use decorator arguments to override the generated tool name or description:
from mcp_toolsmith import tool
@tool(
name="search_project_docs",
description="Search project docs and return matching document IDs.",
)
def search_docs(query: str, limit: int = 5) -> list[str]:
"""Search project documentation by natural language query."""
return []
Use --all-public to include every public top-level function and Pydantic model:
mcp-toolsmith audit tools.py --execute --all-public
mcp-toolsmith compile tools.py --target mcp --execute --all-public
--all-public is mainly a compatibility path for early alpha behavior. For new
Python tool files, prefer @tool.
Use --fail-on to tune CI behavior:
mcp-toolsmith audit tools.py --fail-on error
mcp-toolsmith audit tools.py --fail-on warning
mcp-toolsmith audit tools.py --fail-on never
The default is error.
Provider compatibility profiles
Audit a tool schema for OpenAI-style tool calling:
mcp-toolsmith audit tools.py --profile openai
Audit a tool schema for MCP compatibility:
mcp-toolsmith audit tools.py --profile mcp
Use this in CI:
mcp-toolsmith audit tools.py --profile openai --fail-on warning
The default profile is generic, which keeps the provider-neutral audit
behavior from earlier releases.
More copy-pasteable examples live in examples.
Python API
from mcp_toolsmith import audit_file, compile_file
report = audit_file("tools.json")
openai_report = audit_file("tools.json", profile="openai")
report.print()
openai_report.print()
mcp_tools = compile_file("tools.json", target="mcp")
openai_tools = compile_file("tools.json", target="openai")
For trusted Python files:
report = audit_file("tools.py")
report = audit_file("tools.py", execute=True)
mcp_tools = compile_file("tools.py", target="mcp", execute=True)
To opt into broad Python discovery:
report = audit_file("tools.py", execute=True, all_public=True)
mcp_tools = compile_file("tools.py", target="mcp", execute=True, all_public=True)
Checks
| Check | Why it matters |
|---|---|
| Vague tool names | Agents may pick the wrong tool when names are generic |
| Missing descriptions | Tool selection depends heavily on clear descriptions |
| Missing argument descriptions | Models need argument-level context |
| Oversized schemas | Large schemas cost tokens and can distract smaller models |
| Overlapping tools | Similar tools make tool choice unstable |
| Tool-poisoning language | Tool metadata is part of the prompt surface |
Roadmap
| Version | Goal |
|---|---|
0.2.0 |
Decorator-based Python tool discovery |
0.3.0 |
Safe static audit for @tool-decorated Python functions |
0.4.0 |
Provider compatibility profiles for OpenAI and MCP tool schemas |
0.5.0 |
Deterministic schema compaction and rewriting |
1.0.0 |
Stable public API and compatibility matrix |
License
MIT
Metadata
Release files for mcp-toolsmith 0.5.0
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 | |
|---|---|---|---|---|
| mcp_toolsmith-0.5.0.tar.gz | 28.7 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_toolsmith-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.9 kB
Release files / mcp_toolsmith-0.5.0.tar.gz
| Download URL | mcp_toolsmith-0.5.0.tar.gz |
|---|---|
| Size | 28.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4fdb97d4650dbbf7e1ef9cc55b55f6a7a31e2dda1404e267bb67cd83e914b903
|
|
BLAKE2b-256 checksum How to use checksums |
fd85831b09e85d4876c350f8805aceb2550d1d10a58df1f0a0d6071e2acf3e1b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 11, 2026.
Transparency logRelease files / mcp_toolsmith-0.5.0-py3-none-any.whl
| Download URL | mcp_toolsmith-0.5.0-py3-none-any.whl |
|---|---|
| Size | 27.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b73dd91c00a28a64bd4496ea37495221dbbf1c0b3feaa2b1a58e65c28cf55057
|
|
BLAKE2b-256 checksum How to use checksums |
59c93ba93cf2cd545ec2b4a1a3024f62696fb466323813fdb26faaa16e680ef0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 11, 2026.
Transparency logSecurity for mcp-toolsmith 0.5.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for mcp_toolsmith-0.5.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 11, 2026.
Transparency logA 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.