Metadata-Version: 2.4
Name: mcp-toolsmith
Version: 0.2.0
Summary: Audit and compile Python tool schemas for LLM agents.
Project-URL: Repository, https://github.com/ShAmoNiA/mcp-toolsmith
Project-URL: Issues, https://github.com/ShAmoNiA/mcp-toolsmith/issues
Author: Shayan Mousavinia
License-Expression: MIT
License-File: LICENSE
Keywords: agents,json-schema,llm,mcp,pydantic,tool-calling
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: jsonschema>=4.22
Requires-Dist: pydantic>=2.7
Requires-Dist: rich>=13.7
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: editables>=0.5; extra == 'dev'
Requires-Dist: mypy<1.19,>=1.10; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Requires-Dist: twine>=5.0; extra == 'dev'
Description-Content-Type: text/markdown

# mcp-toolsmith

Audit and compile Python tool schemas for LLM agents.

**Pre-1.0:** JSON tool files are safe by default. Python files require
`--execute` and should only be used with trusted code. The public API may change
before `1.0.0`.

`mcp-toolsmith` is a small Python-first CLI and library for checking whether tool
metadata is usable by LLM agents, then compiling those tools into MCP or
OpenAI-style tool definitions.

It helps catch problems such as vague tool names, missing descriptions,
oversized schemas, overlapping tools, and prompt-injection-like language inside
tool metadata.

## Install

```bash
pip install mcp-toolsmith
```

For local development:

```bash
python -m pip install -e ".[dev]"
```

## Usage

### Audit JSON tool definitions

JSON tool definitions are safe by default:

```bash
mcp-toolsmith audit tools.json
```

Example JSON input:

```json
{
  "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:

```text
OK Audited 1 tool(s) from tools.json
Errors: 0  Warnings: 0

search_docs [mcp] ~55 schema tokens
  No findings
```

### Compile tools

Compile to MCP-style tool definitions:

```bash
mcp-toolsmith compile tools.json --target mcp
```

Compile to OpenAI-style function definitions:

```bash
mcp-toolsmith compile tools.json --target openai
```

### Audit trusted Python files

Python files are executable source code, so `mcp-toolsmith` refuses to import
them unless you opt in:

```bash
mcp-toolsmith audit tools.py --execute
mcp-toolsmith compile tools.py --target mcp --execute
```

Use `--execute` only for trusted files.

By default, Python discovery only includes functions decorated with `@tool`:

```python
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 []
```

Use decorator arguments to override the generated tool name or description:

```python
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:

```bash
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`.

## Python API

```python
from mcp_toolsmith import audit_file, compile_file

report = audit_file("tools.json")
report.print()

mcp_tools = compile_file("tools.json", target="mcp")
openai_tools = compile_file("tools.json", target="openai")
```

For trusted Python files:

```python
report = audit_file("tools.py", execute=True)
mcp_tools = compile_file("tools.py", target="mcp", execute=True)
```

To opt into broad Python discovery:

```python
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` | OpenAPI input and richer JSON Schema validation |
| `0.4.0` | Provider compatibility profiles for Anthropic, Gemini, and OpenAI |
| `0.5.0` | Deterministic schema compaction and rewriting |
| `1.0.0` | Stable public API and compatibility matrix |

## License

MIT

