mcp-toolsmith 0.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_toolsmith-0.1.0a1/.github/workflows/ci.yml +31 -0
- mcp_toolsmith-0.1.0a1/.github/workflows/release.yml +51 -0
- mcp_toolsmith-0.1.0a1/.gitignore +10 -0
- mcp_toolsmith-0.1.0a1/CHANGELOG.md +12 -0
- mcp_toolsmith-0.1.0a1/LICENSE +22 -0
- mcp_toolsmith-0.1.0a1/PKG-INFO +208 -0
- mcp_toolsmith-0.1.0a1/README.md +174 -0
- mcp_toolsmith-0.1.0a1/docs/release.md +51 -0
- mcp_toolsmith-0.1.0a1/pyproject.toml +83 -0
- mcp_toolsmith-0.1.0a1/src/mcp_toolsmith/__init__.py +22 -0
- mcp_toolsmith-0.1.0a1/src/mcp_toolsmith/auditor.py +414 -0
- mcp_toolsmith-0.1.0a1/src/mcp_toolsmith/cli.py +73 -0
- mcp_toolsmith-0.1.0a1/src/mcp_toolsmith/compiler.py +117 -0
- mcp_toolsmith-0.1.0a1/src/mcp_toolsmith/introspection.py +258 -0
- mcp_toolsmith-0.1.0a1/src/mcp_toolsmith/models.py +170 -0
- mcp_toolsmith-0.1.0a1/tests/fixtures/dangerous_tools.py +13 -0
- mcp_toolsmith-0.1.0a1/tests/fixtures/good_tools.json +24 -0
- mcp_toolsmith-0.1.0a1/tests/test_auditor.py +152 -0
- mcp_toolsmith-0.1.0a1/tests/test_cli.py +87 -0
- mcp_toolsmith-0.1.0a1/tests/test_compiler.py +229 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
- master
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install package
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install --upgrade pip
|
|
24
|
+
python -m pip install -e ".[dev]"
|
|
25
|
+
|
|
26
|
+
- name: Run tests
|
|
27
|
+
run: pytest
|
|
28
|
+
|
|
29
|
+
- name: Run lint
|
|
30
|
+
run: ruff check .
|
|
31
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
|
|
19
|
+
- name: Install package
|
|
20
|
+
run: |
|
|
21
|
+
python -m pip install --upgrade pip
|
|
22
|
+
python -m pip install -e ".[dev]"
|
|
23
|
+
|
|
24
|
+
- name: Run tests
|
|
25
|
+
run: |
|
|
26
|
+
pytest
|
|
27
|
+
ruff check .
|
|
28
|
+
|
|
29
|
+
publish:
|
|
30
|
+
needs: test
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
environment: pypi
|
|
33
|
+
|
|
34
|
+
permissions:
|
|
35
|
+
id-token: write
|
|
36
|
+
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
|
|
40
|
+
- uses: actions/setup-python@v5
|
|
41
|
+
with:
|
|
42
|
+
python-version: "3.12"
|
|
43
|
+
|
|
44
|
+
- name: Build package
|
|
45
|
+
run: |
|
|
46
|
+
python -m pip install --upgrade build
|
|
47
|
+
python -m build
|
|
48
|
+
|
|
49
|
+
- name: Publish package distributions to PyPI
|
|
50
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
51
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0a1
|
|
4
|
+
|
|
5
|
+
- Add `mcp-toolsmith audit` for Python files and MCP JSON tool definitions.
|
|
6
|
+
- Add `mcp-toolsmith compile` for MCP and OpenAI-style tool output.
|
|
7
|
+
- Discover top-level Python functions and Pydantic v2 models.
|
|
8
|
+
- Report naming, description, schema-size, argument-description, overlap, and
|
|
9
|
+
tool-poisoning findings.
|
|
10
|
+
- Refuse Python file execution by default; use `--execute` only for trusted
|
|
11
|
+
Python files.
|
|
12
|
+
- Preserve user properties named like JSON Schema metadata during compilation.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shayan Mousavinia
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-toolsmith
|
|
3
|
+
Version: 0.1.0a1
|
|
4
|
+
Summary: Audit and compile Python tool schemas for LLM agents.
|
|
5
|
+
Project-URL: Repository, https://github.com/ShAmoNiA/mcp-toolsmith
|
|
6
|
+
Project-URL: Issues, https://github.com/ShAmoNiA/mcp-toolsmith/issues
|
|
7
|
+
Author: Shayan Mousavinia
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: agents,json-schema,llm,mcp,pydantic,tool-calling
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: jsonschema>=4.22
|
|
23
|
+
Requires-Dist: pydantic>=2.7
|
|
24
|
+
Requires-Dist: rich>=13.7
|
|
25
|
+
Requires-Dist: typer>=0.12
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
28
|
+
Requires-Dist: editables>=0.5; extra == 'dev'
|
|
29
|
+
Requires-Dist: mypy<1.19,>=1.10; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
32
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# mcp-toolsmith
|
|
36
|
+
|
|
37
|
+
Audit and compile Python tool schemas for LLM agents.
|
|
38
|
+
|
|
39
|
+
**Alpha:** JSON tool files are safe by default. Python files require `--execute`
|
|
40
|
+
and should only be used with trusted code. The public API may change before
|
|
41
|
+
`1.0.0`.
|
|
42
|
+
|
|
43
|
+
`mcp-toolsmith` is a small Python-first CLI and library for checking whether tool
|
|
44
|
+
metadata is usable by LLM agents, then compiling those tools into MCP or
|
|
45
|
+
OpenAI-style tool definitions.
|
|
46
|
+
|
|
47
|
+
It helps catch problems such as vague tool names, missing descriptions,
|
|
48
|
+
oversized schemas, overlapping tools, and prompt-injection-like language inside
|
|
49
|
+
tool metadata.
|
|
50
|
+
|
|
51
|
+
## Install
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install mcp-toolsmith==0.1.0a1
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For local development:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
python -m pip install -e ".[dev]"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Usage
|
|
64
|
+
|
|
65
|
+
### Audit JSON tool definitions
|
|
66
|
+
|
|
67
|
+
JSON tool definitions are safe by default:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
mcp-toolsmith audit tools.json
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Example JSON input:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"tools": [
|
|
78
|
+
{
|
|
79
|
+
"name": "search_docs",
|
|
80
|
+
"description": "Search project documentation by natural language query.",
|
|
81
|
+
"inputSchema": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"properties": {
|
|
84
|
+
"query": {
|
|
85
|
+
"type": "string",
|
|
86
|
+
"description": "Question or topic to search for."
|
|
87
|
+
},
|
|
88
|
+
"limit": {
|
|
89
|
+
"type": "integer",
|
|
90
|
+
"description": "Maximum number of results to return.",
|
|
91
|
+
"default": 5
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"required": ["query"]
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Example audit output:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
OK Audited 1 tool(s) from tools.json
|
|
105
|
+
Errors: 0 Warnings: 0
|
|
106
|
+
|
|
107
|
+
search_docs [mcp] ~55 schema tokens
|
|
108
|
+
No findings
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Compile tools
|
|
112
|
+
|
|
113
|
+
Compile to MCP-style tool definitions:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
mcp-toolsmith compile tools.json --target mcp
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Compile to OpenAI-style function definitions:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
mcp-toolsmith compile tools.json --target openai
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Audit trusted Python files
|
|
126
|
+
|
|
127
|
+
Python files are executable source code, so `mcp-toolsmith` refuses to import
|
|
128
|
+
them unless you opt in:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
mcp-toolsmith audit tools.py --execute
|
|
132
|
+
mcp-toolsmith compile tools.py --target mcp --execute
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Use `--execute` only for trusted files.
|
|
136
|
+
|
|
137
|
+
Trusted Python files can contain top-level functions and Pydantic v2 models:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
from pydantic import BaseModel, Field
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def get_weather(city: str, unit: str = "celsius") -> str:
|
|
144
|
+
"""Get current weather for a city.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
city: City and country, such as Madrid, Spain.
|
|
148
|
+
unit: Temperature unit to return.
|
|
149
|
+
"""
|
|
150
|
+
return "sunny"
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class SearchDocsInput(BaseModel):
|
|
154
|
+
"""Search project documentation by natural language query."""
|
|
155
|
+
|
|
156
|
+
query: str = Field(description="Question or topic to search for.")
|
|
157
|
+
limit: int = Field(default=5, description="Maximum number of results.")
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
In this alpha, trusted Python discovery includes every public top-level function
|
|
161
|
+
and every public Pydantic model in the file. Decorator-based discovery is planned
|
|
162
|
+
for a later release.
|
|
163
|
+
|
|
164
|
+
## Python API
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
from mcp_toolsmith import audit_file, compile_file
|
|
168
|
+
|
|
169
|
+
report = audit_file("tools.json")
|
|
170
|
+
report.print()
|
|
171
|
+
|
|
172
|
+
mcp_tools = compile_file("tools.json", target="mcp")
|
|
173
|
+
openai_tools = compile_file("tools.json", target="openai")
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
For trusted Python files:
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
report = audit_file("tools.py", execute=True)
|
|
180
|
+
mcp_tools = compile_file("tools.py", target="mcp", execute=True)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Checks
|
|
184
|
+
|
|
185
|
+
| Check | Why it matters |
|
|
186
|
+
| --- | --- |
|
|
187
|
+
| Vague tool names | Agents may pick the wrong tool when names are generic |
|
|
188
|
+
| Missing descriptions | Tool selection depends heavily on clear descriptions |
|
|
189
|
+
| Missing argument descriptions | Models need argument-level context |
|
|
190
|
+
| Oversized schemas | Large schemas cost tokens and can distract smaller models |
|
|
191
|
+
| Overlapping tools | Similar tools make tool choice unstable |
|
|
192
|
+
| Tool-poisoning language | Tool metadata is part of the prompt surface |
|
|
193
|
+
|
|
194
|
+
## Roadmap
|
|
195
|
+
|
|
196
|
+
| Version | Goal |
|
|
197
|
+
| --- | --- |
|
|
198
|
+
| `0.1.0a1` | Safe-by-default CLI, Python/Pydantic discovery behind `--execute`, audit report, MCP/OpenAI compile |
|
|
199
|
+
| `0.2.0` | Decorator-based Python tool discovery |
|
|
200
|
+
| `0.3.0` | OpenAPI input and richer JSON Schema validation |
|
|
201
|
+
| `0.4.0` | Provider compatibility profiles for Anthropic, Gemini, and OpenAI |
|
|
202
|
+
| `0.5.0` | Deterministic schema compaction and rewriting |
|
|
203
|
+
| `1.0.0` | Stable public API and compatibility matrix |
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
MIT
|
|
208
|
+
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# mcp-toolsmith
|
|
2
|
+
|
|
3
|
+
Audit and compile Python tool schemas for LLM agents.
|
|
4
|
+
|
|
5
|
+
**Alpha:** JSON tool files are safe by default. Python files require `--execute`
|
|
6
|
+
and should only be used with trusted code. The public API may change before
|
|
7
|
+
`1.0.0`.
|
|
8
|
+
|
|
9
|
+
`mcp-toolsmith` is a small Python-first CLI and library for checking whether tool
|
|
10
|
+
metadata is usable by LLM agents, then compiling those tools into MCP or
|
|
11
|
+
OpenAI-style tool definitions.
|
|
12
|
+
|
|
13
|
+
It helps catch problems such as vague tool names, missing descriptions,
|
|
14
|
+
oversized schemas, overlapping tools, and prompt-injection-like language inside
|
|
15
|
+
tool metadata.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install mcp-toolsmith==0.1.0a1
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For local development:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
python -m pip install -e ".[dev]"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Audit JSON tool definitions
|
|
32
|
+
|
|
33
|
+
JSON tool definitions are safe by default:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
mcp-toolsmith audit tools.json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Example JSON input:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"tools": [
|
|
44
|
+
{
|
|
45
|
+
"name": "search_docs",
|
|
46
|
+
"description": "Search project documentation by natural language query.",
|
|
47
|
+
"inputSchema": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"properties": {
|
|
50
|
+
"query": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"description": "Question or topic to search for."
|
|
53
|
+
},
|
|
54
|
+
"limit": {
|
|
55
|
+
"type": "integer",
|
|
56
|
+
"description": "Maximum number of results to return.",
|
|
57
|
+
"default": 5
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"required": ["query"]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Example audit output:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
OK Audited 1 tool(s) from tools.json
|
|
71
|
+
Errors: 0 Warnings: 0
|
|
72
|
+
|
|
73
|
+
search_docs [mcp] ~55 schema tokens
|
|
74
|
+
No findings
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Compile tools
|
|
78
|
+
|
|
79
|
+
Compile to MCP-style tool definitions:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
mcp-toolsmith compile tools.json --target mcp
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Compile to OpenAI-style function definitions:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
mcp-toolsmith compile tools.json --target openai
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Audit trusted Python files
|
|
92
|
+
|
|
93
|
+
Python files are executable source code, so `mcp-toolsmith` refuses to import
|
|
94
|
+
them unless you opt in:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
mcp-toolsmith audit tools.py --execute
|
|
98
|
+
mcp-toolsmith compile tools.py --target mcp --execute
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Use `--execute` only for trusted files.
|
|
102
|
+
|
|
103
|
+
Trusted Python files can contain top-level functions and Pydantic v2 models:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from pydantic import BaseModel, Field
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def get_weather(city: str, unit: str = "celsius") -> str:
|
|
110
|
+
"""Get current weather for a city.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
city: City and country, such as Madrid, Spain.
|
|
114
|
+
unit: Temperature unit to return.
|
|
115
|
+
"""
|
|
116
|
+
return "sunny"
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class SearchDocsInput(BaseModel):
|
|
120
|
+
"""Search project documentation by natural language query."""
|
|
121
|
+
|
|
122
|
+
query: str = Field(description="Question or topic to search for.")
|
|
123
|
+
limit: int = Field(default=5, description="Maximum number of results.")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
In this alpha, trusted Python discovery includes every public top-level function
|
|
127
|
+
and every public Pydantic model in the file. Decorator-based discovery is planned
|
|
128
|
+
for a later release.
|
|
129
|
+
|
|
130
|
+
## Python API
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from mcp_toolsmith import audit_file, compile_file
|
|
134
|
+
|
|
135
|
+
report = audit_file("tools.json")
|
|
136
|
+
report.print()
|
|
137
|
+
|
|
138
|
+
mcp_tools = compile_file("tools.json", target="mcp")
|
|
139
|
+
openai_tools = compile_file("tools.json", target="openai")
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
For trusted Python files:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
report = audit_file("tools.py", execute=True)
|
|
146
|
+
mcp_tools = compile_file("tools.py", target="mcp", execute=True)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Checks
|
|
150
|
+
|
|
151
|
+
| Check | Why it matters |
|
|
152
|
+
| --- | --- |
|
|
153
|
+
| Vague tool names | Agents may pick the wrong tool when names are generic |
|
|
154
|
+
| Missing descriptions | Tool selection depends heavily on clear descriptions |
|
|
155
|
+
| Missing argument descriptions | Models need argument-level context |
|
|
156
|
+
| Oversized schemas | Large schemas cost tokens and can distract smaller models |
|
|
157
|
+
| Overlapping tools | Similar tools make tool choice unstable |
|
|
158
|
+
| Tool-poisoning language | Tool metadata is part of the prompt surface |
|
|
159
|
+
|
|
160
|
+
## Roadmap
|
|
161
|
+
|
|
162
|
+
| Version | Goal |
|
|
163
|
+
| --- | --- |
|
|
164
|
+
| `0.1.0a1` | Safe-by-default CLI, Python/Pydantic discovery behind `--execute`, audit report, MCP/OpenAI compile |
|
|
165
|
+
| `0.2.0` | Decorator-based Python tool discovery |
|
|
166
|
+
| `0.3.0` | OpenAPI input and richer JSON Schema validation |
|
|
167
|
+
| `0.4.0` | Provider compatibility profiles for Anthropic, Gemini, and OpenAI |
|
|
168
|
+
| `0.5.0` | Deterministic schema compaction and rewriting |
|
|
169
|
+
| `1.0.0` | Stable public API and compatibility matrix |
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
MIT
|
|
174
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Release
|
|
2
|
+
|
|
3
|
+
Maintainer notes for publishing `mcp-toolsmith`.
|
|
4
|
+
|
|
5
|
+
## Checklist
|
|
6
|
+
|
|
7
|
+
Use a clean working tree:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git status --short
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Remove local build outputs:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
rm -rf dist build *.egg-info
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Run checks:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pytest
|
|
23
|
+
ruff check .
|
|
24
|
+
python -m build
|
|
25
|
+
twine check dist/*
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Publish to TestPyPI first:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
twine upload --repository testpypi dist/*
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Then test installation in a clean virtual environment:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
python -m venv .test-venv
|
|
38
|
+
.test-venv\Scripts\activate
|
|
39
|
+
python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple mcp-toolsmith==0.1.0a1
|
|
40
|
+
mcp-toolsmith --help
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If TestPyPI works, publish the same artifacts to PyPI:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
twine upload dist/*
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Do not commit `dist/`, `build/`, caches, virtual environments, or source
|
|
50
|
+
archives containing `.git/`.
|
|
51
|
+
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.25"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "mcp-toolsmith"
|
|
7
|
+
version = "0.1.0a1"
|
|
8
|
+
description = "Audit and compile Python tool schemas for LLM agents."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Shayan Mousavinia" }
|
|
14
|
+
]
|
|
15
|
+
keywords = [
|
|
16
|
+
"mcp",
|
|
17
|
+
"llm",
|
|
18
|
+
"agents",
|
|
19
|
+
"tool-calling",
|
|
20
|
+
"json-schema",
|
|
21
|
+
"pydantic"
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 3 - Alpha",
|
|
25
|
+
"Environment :: Console",
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"License :: OSI Approved :: MIT License",
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
29
|
+
"Programming Language :: Python :: 3.10",
|
|
30
|
+
"Programming Language :: Python :: 3.11",
|
|
31
|
+
"Programming Language :: Python :: 3.12",
|
|
32
|
+
"Programming Language :: Python :: 3.13",
|
|
33
|
+
"Topic :: Software Development :: Libraries :: Python Modules"
|
|
34
|
+
]
|
|
35
|
+
dependencies = [
|
|
36
|
+
"jsonschema>=4.22",
|
|
37
|
+
"pydantic>=2.7",
|
|
38
|
+
"rich>=13.7",
|
|
39
|
+
"typer>=0.12"
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.optional-dependencies]
|
|
43
|
+
dev = [
|
|
44
|
+
"build>=1.2",
|
|
45
|
+
"editables>=0.5",
|
|
46
|
+
"mypy>=1.10,<1.19",
|
|
47
|
+
"pytest>=8.0",
|
|
48
|
+
"ruff>=0.5",
|
|
49
|
+
"twine>=5.0"
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[project.urls]
|
|
53
|
+
Repository = "https://github.com/ShAmoNiA/mcp-toolsmith"
|
|
54
|
+
Issues = "https://github.com/ShAmoNiA/mcp-toolsmith/issues"
|
|
55
|
+
|
|
56
|
+
[project.scripts]
|
|
57
|
+
mcp-toolsmith = "mcp_toolsmith.cli:app"
|
|
58
|
+
|
|
59
|
+
[tool.hatch.build.targets.wheel]
|
|
60
|
+
packages = ["src/mcp_toolsmith"]
|
|
61
|
+
|
|
62
|
+
[tool.hatch.build]
|
|
63
|
+
exclude = [
|
|
64
|
+
"/.git",
|
|
65
|
+
"/.venv",
|
|
66
|
+
"/build",
|
|
67
|
+
"/dist",
|
|
68
|
+
"/dist_*",
|
|
69
|
+
"/__pycache__",
|
|
70
|
+
"/.pytest_cache",
|
|
71
|
+
"/.ruff_cache",
|
|
72
|
+
"/.mypy_cache"
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
[tool.pytest.ini_options]
|
|
76
|
+
testpaths = ["tests"]
|
|
77
|
+
|
|
78
|
+
[tool.ruff]
|
|
79
|
+
line-length = 120
|
|
80
|
+
target-version = "py310"
|
|
81
|
+
|
|
82
|
+
[tool.ruff.lint]
|
|
83
|
+
select = ["E", "F", "I", "UP", "B"]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Audit and compile Python tool schemas for LLM agents."""
|
|
2
|
+
|
|
3
|
+
from mcp_toolsmith.auditor import audit_file, audit_tool, audit_tools
|
|
4
|
+
from mcp_toolsmith.compiler import compile_file, compile_tool, compile_tools
|
|
5
|
+
from mcp_toolsmith.introspection import UnsafePythonExecutionError
|
|
6
|
+
from mcp_toolsmith.models import AuditReport, Finding, ToolAudit, ToolSchema
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"AuditReport",
|
|
10
|
+
"Finding",
|
|
11
|
+
"ToolAudit",
|
|
12
|
+
"ToolSchema",
|
|
13
|
+
"UnsafePythonExecutionError",
|
|
14
|
+
"audit_file",
|
|
15
|
+
"audit_tool",
|
|
16
|
+
"audit_tools",
|
|
17
|
+
"compile_file",
|
|
18
|
+
"compile_tool",
|
|
19
|
+
"compile_tools",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
__version__ = "0.1.0a1"
|