toolright 0.0.1__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Toolright contributors
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.
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.4
2
+ Name: toolright
3
+ Version: 0.0.1
4
+ Summary: Does your agent pick the right tool? Test MCP tool descriptions against real models. Python launcher for the Toolright Node.js CLI.
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/ab-rar-6024/toolright
7
+ Project-URL: Repository, https://github.com/ab-rar-6024/toolright
8
+ Project-URL: Issues, https://github.com/ab-rar-6024/toolright/issues
9
+ Project-URL: npm, https://www.npmjs.com/package/toolright
10
+ Keywords: mcp,model-context-protocol,llm,evaluation,tool-calling,agents
11
+ Classifier: Development Status :: 2 - Pre-Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: JavaScript
16
+ Classifier: Topic :: Software Development :: Testing
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Dynamic: license-file
21
+
22
+ # toolright (Python launcher)
23
+
24
+ **Does your agent pick the right tool?** Test your MCP server's tool descriptions against real models, then keep only the rewrites that measurably help.
25
+
26
+ This package is a thin Python launcher for [Toolright](https://github.com/ab-rar-6024/toolright), which is a **Node.js** tool. It does not reimplement anything: `pip install toolright` gives you a `toolright` command that runs the npm package of the **same version** through `npx`.
27
+
28
+ **You need Node.js 20+** on your PATH (it provides `npx`).
29
+
30
+ ```bash
31
+ pip install toolright
32
+
33
+ toolright lint -- python my_mcp_server.py # Tier 1: no model, no API key
34
+ toolright eval -m ollama:qwen2.5:3b --prompts prompts.json -- python my_mcp_server.py
35
+ ```
36
+
37
+ The first run downloads the pinned npm package once; later runs use npm's cache.
38
+
39
+ Full documentation, the three tiers, security model and limits: <https://github.com/ab-rar-6024/toolright>
40
+
41
+ Prefer Node directly? `npx toolright ...` or `npm install -g toolright`.
42
+
43
+ > Pre-release (0.0.1). Model-facing code has not yet been run against live provider APIs. See the main README for the honest status.
@@ -0,0 +1,22 @@
1
+ # toolright (Python launcher)
2
+
3
+ **Does your agent pick the right tool?** Test your MCP server's tool descriptions against real models, then keep only the rewrites that measurably help.
4
+
5
+ This package is a thin Python launcher for [Toolright](https://github.com/ab-rar-6024/toolright), which is a **Node.js** tool. It does not reimplement anything: `pip install toolright` gives you a `toolright` command that runs the npm package of the **same version** through `npx`.
6
+
7
+ **You need Node.js 20+** on your PATH (it provides `npx`).
8
+
9
+ ```bash
10
+ pip install toolright
11
+
12
+ toolright lint -- python my_mcp_server.py # Tier 1: no model, no API key
13
+ toolright eval -m ollama:qwen2.5:3b --prompts prompts.json -- python my_mcp_server.py
14
+ ```
15
+
16
+ The first run downloads the pinned npm package once; later runs use npm's cache.
17
+
18
+ Full documentation, the three tiers, security model and limits: <https://github.com/ab-rar-6024/toolright>
19
+
20
+ Prefer Node directly? `npx toolright ...` or `npm install -g toolright`.
21
+
22
+ > Pre-release (0.0.1). Model-facing code has not yet been run against live provider APIs. See the main README for the honest status.
@@ -0,0 +1,33 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "toolright"
7
+ version = "0.0.1"
8
+ description = "Does your agent pick the right tool? Test MCP tool descriptions against real models. Python launcher for the Toolright Node.js CLI."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ keywords = ["mcp", "model-context-protocol", "llm", "evaluation", "tool-calling", "agents"]
14
+ classifiers = [
15
+ "Development Status :: 2 - Pre-Alpha",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: JavaScript",
20
+ "Topic :: Software Development :: Testing",
21
+ ]
22
+
23
+ [project.urls]
24
+ Homepage = "https://github.com/ab-rar-6024/toolright"
25
+ Repository = "https://github.com/ab-rar-6024/toolright"
26
+ Issues = "https://github.com/ab-rar-6024/toolright/issues"
27
+ npm = "https://www.npmjs.com/package/toolright"
28
+
29
+ [project.scripts]
30
+ toolright = "toolright:main"
31
+
32
+ [tool.setuptools.packages.find]
33
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,57 @@
1
+ """Python launcher for the Toolright CLI.
2
+
3
+ Toolright is a Node.js tool (https://www.npmjs.com/package/toolright). This package
4
+ exists so that ``pip install toolright`` gives you a ``toolright`` command. It does not
5
+ reimplement anything: it runs the npm package of the SAME version through ``npx``.
6
+
7
+ Requirements: Node.js 20+ (which provides ``npx``) on your PATH.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import os
13
+ import shutil
14
+ import subprocess
15
+ import sys
16
+ from typing import List, Optional, Sequence
17
+
18
+ __version__ = "0.0.1"
19
+
20
+ NPM_PACKAGE = "toolright"
21
+ _GUARD = "TOOLRIGHT_PY_LAUNCHER"
22
+
23
+
24
+ def build_command(npx: str, args: Sequence[str]) -> List[str]:
25
+ """The exact command we run. The npm version is pinned to this package's version."""
26
+ return [npx, "--yes", f"{NPM_PACKAGE}@{__version__}", *args]
27
+
28
+
29
+ def main(argv: Optional[Sequence[str]] = None) -> int:
30
+ args = list(sys.argv[1:] if argv is None else argv)
31
+
32
+ if os.environ.get(_GUARD):
33
+ sys.stderr.write("toolright: launcher recursion detected; refusing to continue.\n")
34
+ return 1
35
+
36
+ npx = shutil.which("npx")
37
+ if shutil.which("node") is None or npx is None:
38
+ sys.stderr.write(
39
+ "toolright needs Node.js 20+ (it provides `npx`), and it was not found on your PATH.\n"
40
+ "Install Node.js from https://nodejs.org, then run this command again.\n"
41
+ )
42
+ return 127
43
+
44
+ env = dict(os.environ)
45
+ env[_GUARD] = "1"
46
+ try:
47
+ # A list, never a shell string: arguments are passed through untouched.
48
+ return subprocess.call(build_command(npx, args), env=env)
49
+ except KeyboardInterrupt:
50
+ return 130
51
+ except OSError as exc:
52
+ sys.stderr.write(f"toolright: could not start npx: {exc}\n")
53
+ return 1
54
+
55
+
56
+ if __name__ == "__main__": # pragma: no cover
57
+ raise SystemExit(main())
@@ -0,0 +1,3 @@
1
+ from . import main
2
+
3
+ raise SystemExit(main())
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.4
2
+ Name: toolright
3
+ Version: 0.0.1
4
+ Summary: Does your agent pick the right tool? Test MCP tool descriptions against real models. Python launcher for the Toolright Node.js CLI.
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/ab-rar-6024/toolright
7
+ Project-URL: Repository, https://github.com/ab-rar-6024/toolright
8
+ Project-URL: Issues, https://github.com/ab-rar-6024/toolright/issues
9
+ Project-URL: npm, https://www.npmjs.com/package/toolright
10
+ Keywords: mcp,model-context-protocol,llm,evaluation,tool-calling,agents
11
+ Classifier: Development Status :: 2 - Pre-Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: JavaScript
16
+ Classifier: Topic :: Software Development :: Testing
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Dynamic: license-file
21
+
22
+ # toolright (Python launcher)
23
+
24
+ **Does your agent pick the right tool?** Test your MCP server's tool descriptions against real models, then keep only the rewrites that measurably help.
25
+
26
+ This package is a thin Python launcher for [Toolright](https://github.com/ab-rar-6024/toolright), which is a **Node.js** tool. It does not reimplement anything: `pip install toolright` gives you a `toolright` command that runs the npm package of the **same version** through `npx`.
27
+
28
+ **You need Node.js 20+** on your PATH (it provides `npx`).
29
+
30
+ ```bash
31
+ pip install toolright
32
+
33
+ toolright lint -- python my_mcp_server.py # Tier 1: no model, no API key
34
+ toolright eval -m ollama:qwen2.5:3b --prompts prompts.json -- python my_mcp_server.py
35
+ ```
36
+
37
+ The first run downloads the pinned npm package once; later runs use npm's cache.
38
+
39
+ Full documentation, the three tiers, security model and limits: <https://github.com/ab-rar-6024/toolright>
40
+
41
+ Prefer Node directly? `npx toolright ...` or `npm install -g toolright`.
42
+
43
+ > Pre-release (0.0.1). Model-facing code has not yet been run against live provider APIs. See the main README for the honest status.
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/toolright/__init__.py
5
+ src/toolright/__main__.py
6
+ src/toolright.egg-info/PKG-INFO
7
+ src/toolright.egg-info/SOURCES.txt
8
+ src/toolright.egg-info/dependency_links.txt
9
+ src/toolright.egg-info/entry_points.txt
10
+ src/toolright.egg-info/top_level.txt
11
+ tests/test_launcher.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ toolright = toolright:main
@@ -0,0 +1 @@
1
+ toolright
@@ -0,0 +1,55 @@
1
+ import os
2
+ import sys
3
+ import unittest
4
+ from unittest import mock
5
+
6
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
7
+
8
+ import toolright # noqa: E402
9
+
10
+
11
+ class LauncherTests(unittest.TestCase):
12
+ def test_version_matches_pyproject(self):
13
+ here = os.path.dirname(__file__)
14
+ with open(os.path.join(here, "..", "pyproject.toml"), encoding="utf8") as f:
15
+ text = f.read()
16
+ self.assertIn(f'version = "{toolright.__version__}"', text)
17
+
18
+ def test_command_pins_the_npm_version_and_passes_args_untouched(self):
19
+ cmd = toolright.build_command("/x/npx", ["lint", "--", "node", "a b.js", "&calc", "$(x)"])
20
+ self.assertEqual(cmd[:3], ["/x/npx", "--yes", f"toolright@{toolright.__version__}"])
21
+ self.assertEqual(cmd[3:], ["lint", "--", "node", "a b.js", "&calc", "$(x)"])
22
+
23
+ def test_missing_node_gives_a_clear_message_and_exit_127(self):
24
+ with mock.patch("shutil.which", return_value=None), mock.patch("sys.stderr") as err:
25
+ self.assertEqual(toolright.main(["--version"]), 127)
26
+ self.assertIn("Node.js", "".join(c.args[0] for c in err.write.call_args_list))
27
+
28
+ def test_exit_code_is_passed_through(self):
29
+ with mock.patch("shutil.which", side_effect=lambda n: "/bin/" + n), \
30
+ mock.patch("subprocess.call", return_value=3) as call:
31
+ self.assertEqual(toolright.main(["lint"]), 3)
32
+ args, kwargs = call.call_args
33
+ self.assertIsInstance(args[0], list) # never a shell string
34
+ self.assertNotIn("shell", kwargs)
35
+
36
+ def test_refuses_to_recurse(self):
37
+ with mock.patch.dict(os.environ, {"TOOLRIGHT_PY_LAUNCHER": "1"}), \
38
+ mock.patch("subprocess.call") as call, mock.patch("sys.stderr"):
39
+ self.assertEqual(toolright.main(["x"]), 1)
40
+ call.assert_not_called()
41
+
42
+ def test_child_gets_the_guard_variable(self):
43
+ with mock.patch("shutil.which", side_effect=lambda n: "/bin/" + n), \
44
+ mock.patch("subprocess.call", return_value=0) as call:
45
+ toolright.main(["list"])
46
+ self.assertEqual(call.call_args.kwargs["env"]["TOOLRIGHT_PY_LAUNCHER"], "1")
47
+
48
+ def test_ctrl_c_returns_130(self):
49
+ with mock.patch("shutil.which", side_effect=lambda n: "/bin/" + n), \
50
+ mock.patch("subprocess.call", side_effect=KeyboardInterrupt):
51
+ self.assertEqual(toolright.main(["eval"]), 130)
52
+
53
+
54
+ if __name__ == "__main__":
55
+ unittest.main()