onetool-mcp 1.0.0b1__py3-none-any.whl
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.
- bench/__init__.py +5 -0
- bench/cli.py +69 -0
- bench/harness/__init__.py +66 -0
- bench/harness/client.py +692 -0
- bench/harness/config.py +397 -0
- bench/harness/csv_writer.py +109 -0
- bench/harness/evaluate.py +512 -0
- bench/harness/metrics.py +283 -0
- bench/harness/runner.py +899 -0
- bench/py.typed +0 -0
- bench/reporter.py +629 -0
- bench/run.py +487 -0
- bench/secrets.py +101 -0
- bench/utils.py +16 -0
- onetool/__init__.py +4 -0
- onetool/cli.py +391 -0
- onetool/py.typed +0 -0
- onetool_mcp-1.0.0b1.dist-info/METADATA +163 -0
- onetool_mcp-1.0.0b1.dist-info/RECORD +132 -0
- onetool_mcp-1.0.0b1.dist-info/WHEEL +4 -0
- onetool_mcp-1.0.0b1.dist-info/entry_points.txt +3 -0
- onetool_mcp-1.0.0b1.dist-info/licenses/LICENSE.txt +687 -0
- onetool_mcp-1.0.0b1.dist-info/licenses/NOTICE.txt +64 -0
- ot/__init__.py +37 -0
- ot/__main__.py +6 -0
- ot/_cli.py +107 -0
- ot/_tui.py +53 -0
- ot/config/__init__.py +46 -0
- ot/config/defaults/bench.yaml +4 -0
- ot/config/defaults/diagram-templates/api-flow.mmd +33 -0
- ot/config/defaults/diagram-templates/c4-context.puml +30 -0
- ot/config/defaults/diagram-templates/class-diagram.mmd +87 -0
- ot/config/defaults/diagram-templates/feature-mindmap.mmd +70 -0
- ot/config/defaults/diagram-templates/microservices.d2 +81 -0
- ot/config/defaults/diagram-templates/project-gantt.mmd +37 -0
- ot/config/defaults/diagram-templates/state-machine.mmd +42 -0
- ot/config/defaults/onetool.yaml +25 -0
- ot/config/defaults/prompts.yaml +97 -0
- ot/config/defaults/servers.yaml +7 -0
- ot/config/defaults/snippets.yaml +4 -0
- ot/config/defaults/tool_templates/__init__.py +7 -0
- ot/config/defaults/tool_templates/extension.py +52 -0
- ot/config/defaults/tool_templates/isolated.py +61 -0
- ot/config/dynamic.py +121 -0
- ot/config/global_templates/__init__.py +2 -0
- ot/config/global_templates/bench-secrets-template.yaml +6 -0
- ot/config/global_templates/bench.yaml +9 -0
- ot/config/global_templates/onetool.yaml +27 -0
- ot/config/global_templates/secrets-template.yaml +44 -0
- ot/config/global_templates/servers.yaml +18 -0
- ot/config/global_templates/snippets.yaml +235 -0
- ot/config/loader.py +1087 -0
- ot/config/mcp.py +145 -0
- ot/config/secrets.py +190 -0
- ot/config/tool_config.py +125 -0
- ot/decorators.py +116 -0
- ot/executor/__init__.py +35 -0
- ot/executor/base.py +16 -0
- ot/executor/fence_processor.py +83 -0
- ot/executor/linter.py +142 -0
- ot/executor/pack_proxy.py +260 -0
- ot/executor/param_resolver.py +140 -0
- ot/executor/pep723.py +288 -0
- ot/executor/result_store.py +369 -0
- ot/executor/runner.py +496 -0
- ot/executor/simple.py +163 -0
- ot/executor/tool_loader.py +396 -0
- ot/executor/validator.py +398 -0
- ot/executor/worker_pool.py +388 -0
- ot/executor/worker_proxy.py +189 -0
- ot/http_client.py +145 -0
- ot/logging/__init__.py +37 -0
- ot/logging/config.py +315 -0
- ot/logging/entry.py +213 -0
- ot/logging/format.py +188 -0
- ot/logging/span.py +349 -0
- ot/meta.py +1555 -0
- ot/paths.py +453 -0
- ot/prompts.py +218 -0
- ot/proxy/__init__.py +21 -0
- ot/proxy/manager.py +396 -0
- ot/py.typed +0 -0
- ot/registry/__init__.py +189 -0
- ot/registry/models.py +57 -0
- ot/registry/parser.py +269 -0
- ot/registry/registry.py +413 -0
- ot/server.py +315 -0
- ot/shortcuts/__init__.py +15 -0
- ot/shortcuts/aliases.py +87 -0
- ot/shortcuts/snippets.py +258 -0
- ot/stats/__init__.py +35 -0
- ot/stats/html.py +250 -0
- ot/stats/jsonl_writer.py +283 -0
- ot/stats/reader.py +354 -0
- ot/stats/timing.py +57 -0
- ot/support.py +63 -0
- ot/tools.py +114 -0
- ot/utils/__init__.py +81 -0
- ot/utils/batch.py +161 -0
- ot/utils/cache.py +120 -0
- ot/utils/deps.py +403 -0
- ot/utils/exceptions.py +23 -0
- ot/utils/factory.py +179 -0
- ot/utils/format.py +65 -0
- ot/utils/http.py +202 -0
- ot/utils/platform.py +45 -0
- ot/utils/sanitize.py +130 -0
- ot/utils/truncate.py +69 -0
- ot_tools/__init__.py +4 -0
- ot_tools/_convert/__init__.py +12 -0
- ot_tools/_convert/excel.py +279 -0
- ot_tools/_convert/pdf.py +254 -0
- ot_tools/_convert/powerpoint.py +268 -0
- ot_tools/_convert/utils.py +358 -0
- ot_tools/_convert/word.py +283 -0
- ot_tools/brave_search.py +604 -0
- ot_tools/code_search.py +736 -0
- ot_tools/context7.py +495 -0
- ot_tools/convert.py +614 -0
- ot_tools/db.py +415 -0
- ot_tools/diagram.py +1604 -0
- ot_tools/diagram.yaml +167 -0
- ot_tools/excel.py +1372 -0
- ot_tools/file.py +1348 -0
- ot_tools/firecrawl.py +732 -0
- ot_tools/grounding_search.py +646 -0
- ot_tools/package.py +604 -0
- ot_tools/py.typed +0 -0
- ot_tools/ripgrep.py +544 -0
- ot_tools/scaffold.py +471 -0
- ot_tools/transform.py +213 -0
- ot_tools/web_fetch.py +384 -0
onetool/cli.py
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
"""Serve CLI entry point for OneTool MCP server."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import atexit
|
|
6
|
+
import os
|
|
7
|
+
import signal
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
import typer
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _suppress_shutdown_warnings() -> None:
|
|
14
|
+
"""Suppress pymupdf SWIG warnings at exit.
|
|
15
|
+
|
|
16
|
+
pymupdf emits a DeprecationWarning about swigvarlink during Python's
|
|
17
|
+
interpreter shutdown. This warning is emitted at the C level during
|
|
18
|
+
garbage collection. Redirecting stderr at the fd level suppresses it.
|
|
19
|
+
"""
|
|
20
|
+
try:
|
|
21
|
+
# Redirect stderr at the OS level to suppress C-level warnings
|
|
22
|
+
devnull_fd = os.open(os.devnull, os.O_WRONLY)
|
|
23
|
+
os.dup2(devnull_fd, 2)
|
|
24
|
+
os.close(devnull_fd)
|
|
25
|
+
except Exception:
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
atexit.register(_suppress_shutdown_warnings)
|
|
30
|
+
from rich.console import Console
|
|
31
|
+
|
|
32
|
+
import ot
|
|
33
|
+
from ot._cli import create_cli, version_callback
|
|
34
|
+
from ot.support import get_support_banner, get_version
|
|
35
|
+
|
|
36
|
+
# Console for CLI output - no auto-highlighting, output to stderr
|
|
37
|
+
console = Console(stderr=True, highlight=False)
|
|
38
|
+
|
|
39
|
+
app = create_cli(
|
|
40
|
+
"onetool",
|
|
41
|
+
"OneTool MCP server - exposes a single 'run' tool for LLM code generation.",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _print_startup_banner() -> None:
|
|
46
|
+
"""Print startup message to stderr."""
|
|
47
|
+
version = get_version()
|
|
48
|
+
console.print(f"[bold cyan]OneTool MCP Server[/bold cyan] [dim]v{version}[/dim]")
|
|
49
|
+
console.print(get_support_banner())
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _setup_signal_handlers() -> None:
|
|
53
|
+
"""Set up signal handlers for clean exit."""
|
|
54
|
+
|
|
55
|
+
def handle_signal(signum: int, _frame: object) -> None:
|
|
56
|
+
"""Handle termination signals gracefully."""
|
|
57
|
+
sig_name = signal.Signals(signum).name
|
|
58
|
+
console.print(f"\nReceived {sig_name}, shutting down...")
|
|
59
|
+
# Use os._exit() for immediate termination - sys.exit() doesn't work
|
|
60
|
+
# well with asyncio event loops and can require multiple Ctrl+C presses
|
|
61
|
+
os._exit(0)
|
|
62
|
+
|
|
63
|
+
# Handle SIGINT (Ctrl+C) and SIGTERM
|
|
64
|
+
signal.signal(signal.SIGINT, handle_signal)
|
|
65
|
+
signal.signal(signal.SIGTERM, handle_signal)
|
|
66
|
+
|
|
67
|
+
# Init subcommand group - manage global configuration
|
|
68
|
+
init_app = typer.Typer(
|
|
69
|
+
name="init",
|
|
70
|
+
help="Initialize and manage global configuration in ~/.onetool/config/",
|
|
71
|
+
invoke_without_command=True,
|
|
72
|
+
)
|
|
73
|
+
app.add_typer(init_app)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@init_app.callback()
|
|
77
|
+
def init_callback(ctx: typer.Context) -> None:
|
|
78
|
+
"""Initialize and manage global configuration in ~/.onetool/config/.
|
|
79
|
+
|
|
80
|
+
Run without subcommand to initialize global config directory.
|
|
81
|
+
"""
|
|
82
|
+
if ctx.invoked_subcommand is None:
|
|
83
|
+
# No subcommand = run init
|
|
84
|
+
init_create()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@init_app.command("create", hidden=True)
|
|
88
|
+
def init_create() -> None:
|
|
89
|
+
"""Initialize global config directory (~/.onetool/).
|
|
90
|
+
|
|
91
|
+
Creates the global config directory and copies template files if they
|
|
92
|
+
don't already exist. Existing files are preserved.
|
|
93
|
+
|
|
94
|
+
This is the default action when running 'onetool init' without a subcommand.
|
|
95
|
+
"""
|
|
96
|
+
from ot.paths import ensure_global_dir, get_global_dir
|
|
97
|
+
|
|
98
|
+
global_dir = get_global_dir()
|
|
99
|
+
if global_dir.exists():
|
|
100
|
+
console.print(f"Global config already exists at {global_dir}/")
|
|
101
|
+
console.print("Use 'onetool init reset' to reinstall templates.")
|
|
102
|
+
return
|
|
103
|
+
|
|
104
|
+
ensure_global_dir(quiet=False, force=False)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@init_app.command("reset")
|
|
108
|
+
def init_reset() -> None:
|
|
109
|
+
"""Reset global config to default templates.
|
|
110
|
+
|
|
111
|
+
Prompts for each file before overwriting. For existing files, offers to
|
|
112
|
+
create a backup first. Backups are named file.bak, file.bak.1, etc.
|
|
113
|
+
"""
|
|
114
|
+
import shutil
|
|
115
|
+
|
|
116
|
+
from ot.paths import (
|
|
117
|
+
CONFIG_SUBDIR,
|
|
118
|
+
create_backup,
|
|
119
|
+
get_global_dir,
|
|
120
|
+
get_template_files,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
global_dir = get_global_dir()
|
|
124
|
+
config_dir = global_dir / CONFIG_SUBDIR
|
|
125
|
+
|
|
126
|
+
# Ensure directories exist
|
|
127
|
+
global_dir.mkdir(parents=True, exist_ok=True)
|
|
128
|
+
config_dir.mkdir(exist_ok=True)
|
|
129
|
+
|
|
130
|
+
template_files = get_template_files()
|
|
131
|
+
if not template_files:
|
|
132
|
+
console.print("No template files found.")
|
|
133
|
+
return
|
|
134
|
+
|
|
135
|
+
copied_files: list[str] = []
|
|
136
|
+
backed_up_files: list[tuple[str, Path]] = []
|
|
137
|
+
skipped_files: list[str] = []
|
|
138
|
+
|
|
139
|
+
for source_path, dest_name in template_files:
|
|
140
|
+
dest_path = config_dir / dest_name
|
|
141
|
+
exists = dest_path.exists()
|
|
142
|
+
|
|
143
|
+
if exists:
|
|
144
|
+
# Prompt for overwrite
|
|
145
|
+
console.print(f"\nconfig/{dest_name} already exists.")
|
|
146
|
+
do_overwrite = typer.confirm("Overwrite?", default=True)
|
|
147
|
+
|
|
148
|
+
if not do_overwrite:
|
|
149
|
+
skipped_files.append(dest_name)
|
|
150
|
+
continue
|
|
151
|
+
|
|
152
|
+
# Prompt for backup
|
|
153
|
+
do_backup = typer.confirm(f"Create backup of config/{dest_name}?", default=True)
|
|
154
|
+
|
|
155
|
+
if do_backup:
|
|
156
|
+
backup_path = create_backup(dest_path)
|
|
157
|
+
backed_up_files.append((dest_name, backup_path))
|
|
158
|
+
|
|
159
|
+
shutil.copy(source_path, dest_path)
|
|
160
|
+
copied_files.append(dest_name)
|
|
161
|
+
|
|
162
|
+
# Summary
|
|
163
|
+
console.print()
|
|
164
|
+
if copied_files:
|
|
165
|
+
console.print(f"Reset files in {config_dir}/:")
|
|
166
|
+
for name in copied_files:
|
|
167
|
+
console.print(f" + {name}")
|
|
168
|
+
|
|
169
|
+
if backed_up_files:
|
|
170
|
+
console.print("\nBackups created:")
|
|
171
|
+
for name, backup_path in backed_up_files:
|
|
172
|
+
console.print(f" config/{name} -> {backup_path.name}")
|
|
173
|
+
|
|
174
|
+
if skipped_files:
|
|
175
|
+
console.print("\nSkipped:")
|
|
176
|
+
for name in skipped_files:
|
|
177
|
+
console.print(f" - config/{name}")
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
@init_app.command("validate")
|
|
181
|
+
def init_validate() -> None:
|
|
182
|
+
"""Validate configuration and show status.
|
|
183
|
+
|
|
184
|
+
Checks config files for errors, then displays packs, secrets (names only),
|
|
185
|
+
snippets, aliases, and MCP servers.
|
|
186
|
+
"""
|
|
187
|
+
from loguru import logger
|
|
188
|
+
|
|
189
|
+
from ot.config.loader import get_config, load_config
|
|
190
|
+
from ot.config.secrets import load_secrets
|
|
191
|
+
from ot.executor.tool_loader import load_tool_registry
|
|
192
|
+
from ot.paths import CONFIG_SUBDIR, get_global_dir, get_project_dir
|
|
193
|
+
|
|
194
|
+
# Suppress DEBUG logs from config loader
|
|
195
|
+
logger.remove()
|
|
196
|
+
|
|
197
|
+
errors: list[str] = []
|
|
198
|
+
validated: list[str] = []
|
|
199
|
+
|
|
200
|
+
# Check global config
|
|
201
|
+
global_dir = get_global_dir()
|
|
202
|
+
global_config = global_dir / CONFIG_SUBDIR / "onetool.yaml"
|
|
203
|
+
if global_config.exists():
|
|
204
|
+
try:
|
|
205
|
+
load_config(global_config)
|
|
206
|
+
validated.append(str(global_config))
|
|
207
|
+
except Exception as e:
|
|
208
|
+
errors.append(f"{global_config}: {e}")
|
|
209
|
+
|
|
210
|
+
# Check project config
|
|
211
|
+
project_dir = get_project_dir()
|
|
212
|
+
if project_dir:
|
|
213
|
+
project_config = project_dir / CONFIG_SUBDIR / "onetool.yaml"
|
|
214
|
+
if project_config.exists():
|
|
215
|
+
try:
|
|
216
|
+
load_config(project_config)
|
|
217
|
+
validated.append(str(project_config))
|
|
218
|
+
except Exception as e:
|
|
219
|
+
errors.append(f"{project_config}: {e}")
|
|
220
|
+
|
|
221
|
+
# Report validation results
|
|
222
|
+
console.print("Configuration\n")
|
|
223
|
+
|
|
224
|
+
console.print("Directories:")
|
|
225
|
+
global_exists = global_dir.exists()
|
|
226
|
+
if global_exists:
|
|
227
|
+
console.print(f" Global: {global_dir}/ - [green]OK[/green]")
|
|
228
|
+
else:
|
|
229
|
+
console.print(f" Global: {global_dir}/ - [red]missing[/red]")
|
|
230
|
+
if project_dir:
|
|
231
|
+
console.print(f" Project: {project_dir}/ - [green]OK[/green]")
|
|
232
|
+
else:
|
|
233
|
+
console.print(" Project: (none)")
|
|
234
|
+
|
|
235
|
+
if validated:
|
|
236
|
+
console.print("\nConfig files:")
|
|
237
|
+
for path in validated:
|
|
238
|
+
console.print(f" + {path}")
|
|
239
|
+
|
|
240
|
+
if errors:
|
|
241
|
+
console.print("\n[red]Validation errors:[/red]")
|
|
242
|
+
for error in errors:
|
|
243
|
+
console.print(f" ! {error}")
|
|
244
|
+
raise typer.Exit(1)
|
|
245
|
+
|
|
246
|
+
if not validated and not errors:
|
|
247
|
+
console.print("\nNo configuration files found.")
|
|
248
|
+
console.print(f"Checked: {global_config}, .onetool/config/onetool.yaml")
|
|
249
|
+
return
|
|
250
|
+
|
|
251
|
+
# Load merged config for status display
|
|
252
|
+
try:
|
|
253
|
+
config = get_config()
|
|
254
|
+
except Exception as e:
|
|
255
|
+
console.print(f"\n[red]Config error:[/red] {e}")
|
|
256
|
+
return
|
|
257
|
+
|
|
258
|
+
# Packs and tools
|
|
259
|
+
try:
|
|
260
|
+
registry = load_tool_registry()
|
|
261
|
+
if registry.packs:
|
|
262
|
+
total_tools = 0
|
|
263
|
+
pack_list = []
|
|
264
|
+
for pack_name, pack_funcs in sorted(registry.packs.items()):
|
|
265
|
+
from ot.executor.worker_proxy import WorkerPackProxy
|
|
266
|
+
|
|
267
|
+
if isinstance(pack_funcs, WorkerPackProxy):
|
|
268
|
+
func_count = len(pack_funcs.functions)
|
|
269
|
+
else:
|
|
270
|
+
func_count = len(pack_funcs)
|
|
271
|
+
total_tools += func_count
|
|
272
|
+
pack_list.append((pack_name, func_count))
|
|
273
|
+
|
|
274
|
+
console.print(f"\nPacks ({len(pack_list)}, {total_tools} tools):")
|
|
275
|
+
for pack_name, func_count in pack_list:
|
|
276
|
+
console.print(f" {pack_name} ({func_count})")
|
|
277
|
+
else:
|
|
278
|
+
console.print("\nPacks:")
|
|
279
|
+
console.print(" (none)")
|
|
280
|
+
except Exception as e:
|
|
281
|
+
console.print("\nPacks:")
|
|
282
|
+
console.print(f" [red]Error loading tools:[/red] {e}")
|
|
283
|
+
|
|
284
|
+
# Secrets (names only) - use config's secrets_file path
|
|
285
|
+
try:
|
|
286
|
+
secrets_path = config.get_secrets_file_path() if config else None
|
|
287
|
+
secrets = load_secrets(secrets_path)
|
|
288
|
+
if secrets:
|
|
289
|
+
sorted_keys = sorted(secrets.keys())
|
|
290
|
+
console.print(f"\nSecrets ({len(sorted_keys)}):")
|
|
291
|
+
for key in sorted_keys:
|
|
292
|
+
console.print(f" {key} - [green]set[/green]")
|
|
293
|
+
else:
|
|
294
|
+
console.print("\nSecrets:")
|
|
295
|
+
console.print(" (none configured)")
|
|
296
|
+
except Exception as e:
|
|
297
|
+
console.print("\nSecrets:")
|
|
298
|
+
console.print(f" [red]Error:[/red] {e}")
|
|
299
|
+
|
|
300
|
+
# Snippets
|
|
301
|
+
if config and config.snippets:
|
|
302
|
+
sorted_snippets = sorted(config.snippets.keys())
|
|
303
|
+
console.print(f"\nSnippets ({len(sorted_snippets)}):")
|
|
304
|
+
console.print(f" {', '.join(sorted_snippets)}")
|
|
305
|
+
else:
|
|
306
|
+
console.print("\nSnippets:")
|
|
307
|
+
console.print(" (none)")
|
|
308
|
+
|
|
309
|
+
# Aliases
|
|
310
|
+
if config and config.alias:
|
|
311
|
+
sorted_aliases = sorted(config.alias.items())
|
|
312
|
+
console.print(f"\nAliases ({len(sorted_aliases)}):")
|
|
313
|
+
alias_items = [f"{name} -> {target}" for name, target in sorted_aliases]
|
|
314
|
+
console.print(f" {', '.join(alias_items)}")
|
|
315
|
+
else:
|
|
316
|
+
console.print("\nAliases:")
|
|
317
|
+
console.print(" (none)")
|
|
318
|
+
|
|
319
|
+
# Servers
|
|
320
|
+
if config and config.servers:
|
|
321
|
+
sorted_servers = sorted(config.servers.keys())
|
|
322
|
+
console.print(f"\nMCP Servers ({len(sorted_servers)}):")
|
|
323
|
+
console.print(f" {', '.join(sorted_servers)}")
|
|
324
|
+
else:
|
|
325
|
+
console.print("\nMCP Servers:")
|
|
326
|
+
console.print(" (none)")
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
@app.callback(invoke_without_command=True)
|
|
330
|
+
def serve(
|
|
331
|
+
ctx: typer.Context,
|
|
332
|
+
_version: bool | None = typer.Option(
|
|
333
|
+
None,
|
|
334
|
+
"--version",
|
|
335
|
+
"-v",
|
|
336
|
+
callback=version_callback("onetool", ot.__version__),
|
|
337
|
+
is_eager=True,
|
|
338
|
+
help="Show version and exit.",
|
|
339
|
+
),
|
|
340
|
+
config: Path | None = typer.Option(
|
|
341
|
+
None,
|
|
342
|
+
"--config",
|
|
343
|
+
"-c",
|
|
344
|
+
help="Path to onetool.yaml configuration file.",
|
|
345
|
+
exists=True,
|
|
346
|
+
readable=True,
|
|
347
|
+
),
|
|
348
|
+
) -> None:
|
|
349
|
+
"""Run the OneTool MCP server over stdio transport.
|
|
350
|
+
|
|
351
|
+
This starts the MCP server that exposes the 'run' tool for LLM integrations.
|
|
352
|
+
The server communicates via stdio and is typically invoked by MCP clients.
|
|
353
|
+
|
|
354
|
+
Examples:
|
|
355
|
+
onetool
|
|
356
|
+
onetool --config config/onetool.yaml
|
|
357
|
+
"""
|
|
358
|
+
# Bootstrap global config directory on first run
|
|
359
|
+
from ot.paths import ensure_global_dir
|
|
360
|
+
|
|
361
|
+
ensure_global_dir(quiet=True)
|
|
362
|
+
|
|
363
|
+
# Only run if no subcommand was invoked (handles --help automatically)
|
|
364
|
+
if ctx.invoked_subcommand is not None:
|
|
365
|
+
return
|
|
366
|
+
|
|
367
|
+
# Load config if specified
|
|
368
|
+
if config:
|
|
369
|
+
from ot.config.loader import get_config
|
|
370
|
+
|
|
371
|
+
get_config(config)
|
|
372
|
+
|
|
373
|
+
# Set up signal handlers for clean exit (before starting server)
|
|
374
|
+
_setup_signal_handlers()
|
|
375
|
+
|
|
376
|
+
# Print startup banner to stderr (stdout is for MCP JSON-RPC)
|
|
377
|
+
_print_startup_banner()
|
|
378
|
+
|
|
379
|
+
# Import here to avoid circular imports and only load when needed
|
|
380
|
+
from ot.server import main as server_main
|
|
381
|
+
|
|
382
|
+
server_main()
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def cli() -> None:
|
|
386
|
+
"""Run the CLI application."""
|
|
387
|
+
app()
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
if __name__ == "__main__":
|
|
391
|
+
cli()
|
onetool/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: onetool-mcp
|
|
3
|
+
Version: 1.0.0b1
|
|
4
|
+
Summary: One MCP, unlimited tools.
|
|
5
|
+
Project-URL: Homepage, https://github.com/beycom/onetool
|
|
6
|
+
Project-URL: Repository, https://github.com/beycom/onetool
|
|
7
|
+
Project-URL: Documentation, https://onetool.beycom.online
|
|
8
|
+
Project-URL: Issues, https://github.com/beycom/onetool/issues
|
|
9
|
+
Author-email: Gavin Las <beycom99@gmail.com>
|
|
10
|
+
License: GPL-3.0
|
|
11
|
+
License-File: LICENSE.txt
|
|
12
|
+
License-File: NOTICE.txt
|
|
13
|
+
Keywords: agents,code-execution,context-rot,llm,mcp,mcp-server,model-context-protocol,token-efficiency,tools
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: aiofiles>=25.1.0
|
|
24
|
+
Requires-Dist: docstring-parser>=0.17
|
|
25
|
+
Requires-Dist: duckdb>=1.4.3
|
|
26
|
+
Requires-Dist: fastmcp>=2.14.4
|
|
27
|
+
Requires-Dist: firecrawl>=4.13.4
|
|
28
|
+
Requires-Dist: google-genai>=1.60.0
|
|
29
|
+
Requires-Dist: httpx>=0.28.1
|
|
30
|
+
Requires-Dist: jinja2>=3.1.6
|
|
31
|
+
Requires-Dist: loguru>=0.7.3
|
|
32
|
+
Requires-Dist: mcp>=1.26.0
|
|
33
|
+
Requires-Dist: openai>=2.15.0
|
|
34
|
+
Requires-Dist: openpyxl>=3.1.5
|
|
35
|
+
Requires-Dist: pillow>=12.1.0
|
|
36
|
+
Requires-Dist: pydantic-settings>=2.12.0
|
|
37
|
+
Requires-Dist: pydantic>=2.12.5
|
|
38
|
+
Requires-Dist: pymupdf>=1.26.7
|
|
39
|
+
Requires-Dist: python-docx>=1.2.0
|
|
40
|
+
Requires-Dist: python-pptx>=1.0.2
|
|
41
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
42
|
+
Requires-Dist: questionary>=2.1.1
|
|
43
|
+
Requires-Dist: rich>=14.3.1
|
|
44
|
+
Requires-Dist: sqlalchemy>=2.0.46
|
|
45
|
+
Requires-Dist: trafilatura>=2.0.0
|
|
46
|
+
Requires-Dist: typer>=0.21.1
|
|
47
|
+
Provides-Extra: file
|
|
48
|
+
Requires-Dist: send2trash>=2.1.0; extra == 'file'
|
|
49
|
+
Description-Content-Type: text/markdown
|
|
50
|
+
|
|
51
|
+
<p align="center">
|
|
52
|
+
<img src="docs/assets/onetool-logo.png" alt="OneTool" width="400">
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
<p align="center">
|
|
56
|
+
<em>One tool to rule them all, one tool to find them, one tool to bring them all, and in the development bind them.</em>
|
|
57
|
+
</p>
|
|
58
|
+
|
|
59
|
+
<p align="center">
|
|
60
|
+
<a href="https://pypi.org/project/onetool-mcp/"><img alt="PyPI" src="https://img.shields.io/pypi/v/onetool-mcp"></a>
|
|
61
|
+
<a href="https://github.com/beycom/onetool-mcp/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/badge/license-GPLv3-blue"></a>
|
|
62
|
+
<a href="https://www.python.org/"><img alt="Python" src="https://img.shields.io/badge/python-3.11%2B-blue"></a>
|
|
63
|
+
</p>
|
|
64
|
+
|
|
65
|
+
> **v1.0.0 Pre-Release** - API stable, actively tested.
|
|
66
|
+
|
|
67
|
+
OneTool is a local-first MCP server that exposes a single `run` tool for code execution, giving your AI assistant access to unlimited capabilities through one interface.
|
|
68
|
+
|
|
69
|
+
## The Problem
|
|
70
|
+
|
|
71
|
+
Connect 5 MCP servers and you've burned 55K tokens before the conversation starts. Connect 10+ and you're at 100K tokens. Your AI gets worse as you add more tools - that's not a bug, it's how context windows work.
|
|
72
|
+
|
|
73
|
+
## The Solution
|
|
74
|
+
|
|
75
|
+
**98.7% fewer tokens. Same accuracy. 10x lower cost.**
|
|
76
|
+
|
|
77
|
+
Instead of loading 50 separate tool schemas, you write Python directly:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
__ot brave.search(query="AI trends 2026")
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
No JSON schema parsing. No tool selection loops. No hoping the model guesses correctly. You write explicit code to call APIs - deterministic, visible, no hidden magic.
|
|
84
|
+
|
|
85
|
+
Based on [Anthropic's research](https://www.anthropic.com/engineering/code-execution-with-mcp), which found token usage dropped from 150,000 to 2,000 when presenting tools as code APIs.
|
|
86
|
+
|
|
87
|
+
## Core Capabilities
|
|
88
|
+
|
|
89
|
+
- **30-second setup** - Install with uv or pip
|
|
90
|
+
- **Drop-in extensibility** - Add a Python file, get a new pack
|
|
91
|
+
- **AST security** - All code validated before execution
|
|
92
|
+
- **Benchmark harness** - Test LLM + MCP combinations with `bench`
|
|
93
|
+
|
|
94
|
+
## Batteries Included with 100+ Tools
|
|
95
|
+
|
|
96
|
+
See [Tool Reference](docs/tool-reference.md) for the complete list of packs and tools.
|
|
97
|
+
|
|
98
|
+
## Installation
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
uv tool install onetool-mcp
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Or with pip: `pip install onetool-mcp`
|
|
105
|
+
|
|
106
|
+
**With optional dependencies** (for convert, excel, code search):
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
uv tool install onetool-mcp \
|
|
110
|
+
--with pymupdf --with python-docx --with python-pptx \
|
|
111
|
+
--with openpyxl --with Pillow --with duckdb --with openai
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Add to Claude Code (`~/.claude/settings.json`):
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"mcpServers": {
|
|
119
|
+
"onetool": {
|
|
120
|
+
"command": "onetool"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Extending
|
|
127
|
+
|
|
128
|
+
Drop a Python file, get a pack. No registration, no config:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
# tools/mytool.py
|
|
132
|
+
pack = "mytool"
|
|
133
|
+
|
|
134
|
+
def search(*, query: str) -> str:
|
|
135
|
+
"""Search for something."""
|
|
136
|
+
return f"Results for: {query}"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Why this approach
|
|
140
|
+
|
|
141
|
+
LLMs write Python instead of parsing JSON schemas. You see what's being called. 2K tokens instead of 150K. Adding your own packs is just dropping in a file.
|
|
142
|
+
|
|
143
|
+
## Documentation
|
|
144
|
+
|
|
145
|
+
- [Why OneTool](docs/intro/index.md) - The problem and our solution
|
|
146
|
+
- [Getting Started](docs/getting-started/quickstart.md) - 2-minute setup
|
|
147
|
+
- [Tools Reference](docs/reference/tools/index.md) - All built-in tools
|
|
148
|
+
- [Extending](docs/extending/index.md) - Create your own tools
|
|
149
|
+
|
|
150
|
+
## References
|
|
151
|
+
|
|
152
|
+
- [Code Execution with MCP](https://www.anthropic.com/engineering/code-execution-with-mcp) - Anthropic Engineering
|
|
153
|
+
- [Context Rot](https://research.trychroma.com/context-rot) - Chroma Research
|
|
154
|
+
|
|
155
|
+
## Licensing
|
|
156
|
+
|
|
157
|
+
**GPLv3** - Will transition to **MIT** at v2.0. Contribute via PRs to help us get there.
|
|
158
|
+
|
|
159
|
+
## Support
|
|
160
|
+
|
|
161
|
+
If you use or like this project, please consider buying me a coffee:
|
|
162
|
+
|
|
163
|
+
[](https://ko-fi.com/beycom)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
bench/__init__.py,sha256=y388vnV0atWMmhJA4RzbIGGHrWNifzidcXkIgjSQR2Q,133
|
|
2
|
+
bench/cli.py,sha256=8QjzxnTkMFvJ-c_bQ0YZkr-MtN9sdZDau_Vo62DFSTQ,1664
|
|
3
|
+
bench/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
bench/reporter.py,sha256=peV3xaDiasQR5UAMCC1oRDuOWG_IAMC6HqQ8XjdXgC8,23602
|
|
5
|
+
bench/run.py,sha256=9s1z_Q4vEE5rdct9aKOpo2A6JLLl8vD0bwQ-jAWB2Ec,16456
|
|
6
|
+
bench/secrets.py,sha256=ho1susoPnJbmdhhMubhdCueQnybMm2ykBapR_nkpTZ0,2676
|
|
7
|
+
bench/utils.py,sha256=Kr3ZHb9cBFaM1HRNBFCUH3JKHk4-fNAiBpr2I95eR0c,386
|
|
8
|
+
bench/harness/__init__.py,sha256=e9qbt4m_7I6j1wlLd_HCI2kQSXNs_vdluFpOLULD25A,1511
|
|
9
|
+
bench/harness/client.py,sha256=qBW1Y49QFEt-NElybRKu1bA1YbuXKv2cPYr58hCSLjw,25303
|
|
10
|
+
bench/harness/config.py,sha256=k6jqvQeumS91ka_QBV8pXtpwQUZhgutbbNiL5n68gxI,12581
|
|
11
|
+
bench/harness/csv_writer.py,sha256=iwy3ixo9KlzoXmJVAYTHYt2Nm8s5vQsxVAaykgsvHEY,3305
|
|
12
|
+
bench/harness/evaluate.py,sha256=Mv6I63aBXwEZHoarUOYu3UIG3-rRcInLtBULlqcqeDk,17262
|
|
13
|
+
bench/harness/metrics.py,sha256=5Zy0x3IG-CeXUk-nxGm8-w2YCds1B2oxNGQMKNkgjGE,9690
|
|
14
|
+
bench/harness/runner.py,sha256=Gx9_IXVBhmogaWCf5e-YNuuyDNeJVJpSPKtbp7PyxaI,38332
|
|
15
|
+
onetool/__init__.py,sha256=NH91OBFDKBASlyorvmrLjckwXblgcToPkdqtZOIya7o,110
|
|
16
|
+
onetool/cli.py,sha256=9TR0BMcUw05O2yt0kcS-3MrCfWPbxavVCtNpsIscxtg,12159
|
|
17
|
+
onetool/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
ot/__init__.py,sha256=WI1BaMpZr1Xag5DLy8710K19v4EEiU0plLsgbCWWgz0,983
|
|
19
|
+
ot/__main__.py,sha256=Lj60MDYULRpq5qUSW2zQF-7eaG7R90v_vB_vl1dv2Fg,123
|
|
20
|
+
ot/_cli.py,sha256=cJ6mazEkl1cseHTUmtPFrsJfjZZ5IFkfFqh0c5s7xuY,2700
|
|
21
|
+
ot/_tui.py,sha256=fbF_iwK58EBPhxWmEEQozneHlSRr7MRop7aRugVQ688,1437
|
|
22
|
+
ot/decorators.py,sha256=8VRje2gT-9C3cpSITKkOSadZF6MBusbqTlRvkafqbAs,3223
|
|
23
|
+
ot/http_client.py,sha256=lwmAISFK9qGwMvWVX4mltZcttt2NUVKaxEnadYzuYy8,4163
|
|
24
|
+
ot/meta.py,sha256=cEaI-3Aul2OcSteY9g7XOheXDswwPo577IqIrFF-qeM,50052
|
|
25
|
+
ot/paths.py,sha256=0R13bHR-8TYBVcMNIepY7O0LXy5xlIZ-1-KRZCJRpJA,14410
|
|
26
|
+
ot/prompts.py,sha256=UdFjOhdhVtgFGJnNWL-I7Mv_KtVBA5Dc9MAG8cwPCOI,6593
|
|
27
|
+
ot/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
+
ot/server.py,sha256=YzVeXrm7wml623CZFTQSFJFyMlL0oD_hKHWN1h_vOJA,9603
|
|
29
|
+
ot/support.py,sha256=u6OQonVDktmQyMxm8GGPSzWmwTuts6a8vNmSjRpuBuU,1639
|
|
30
|
+
ot/tools.py,sha256=MeZx-5sXJ8go7tn_yqs-QYAbhzve-QliL7ZMVO6ilxU,3591
|
|
31
|
+
ot/config/__init__.py,sha256=xa0QbmATFJb01EXZi5kD5j4BgEcfEZZMt2AdKRihxis,1054
|
|
32
|
+
ot/config/dynamic.py,sha256=alaJUnDL2KRIWeCNN-garmPmJ3qFoOirkwh0hSFcMuc,3711
|
|
33
|
+
ot/config/loader.py,sha256=sWjvaaXraQVs45HFGxMrC6P21LPQ2qtbSdBus67JC4U,36016
|
|
34
|
+
ot/config/mcp.py,sha256=iQdDrc3o8UpmW9T-IeMGu_Qyl1lw1lS2vjoTamW4J5k,5072
|
|
35
|
+
ot/config/secrets.py,sha256=zrQZZwRNgnoxyC84WtJgtkcPY7AnB1J22kFDjKI-mxg,6009
|
|
36
|
+
ot/config/tool_config.py,sha256=BisTtEj9Ws8NnWxvSbW9kskkygO8F-RO4Mgm9KIuPm0,3651
|
|
37
|
+
ot/config/defaults/bench.yaml,sha256=roIxVP2QqksP3DS01_DsU87DjyHbQKKjPSVm4h6Lijc,114
|
|
38
|
+
ot/config/defaults/onetool.yaml,sha256=XZRfMsuF91vu9-Z1Ogp51bC5EN3lILtACr6StClirN8,750
|
|
39
|
+
ot/config/defaults/prompts.yaml,sha256=1viP1ELp3uq7U9-xrhlkgNrWWqB5gXtZ-NSOT3zShao,4443
|
|
40
|
+
ot/config/defaults/servers.yaml,sha256=YmrNEhfESEmWTBjK5BTohXw-E1R7SYhJn7RwzRDS-RQ,216
|
|
41
|
+
ot/config/defaults/snippets.yaml,sha256=G7cGnHrX_jUYQqQJi5vPqB4_FaYMdpGDXiFA3ykuK1A,107
|
|
42
|
+
ot/config/defaults/diagram-templates/api-flow.mmd,sha256=YizXla-1o85KyUJqMoT2rOJqFa6wUqhZNf8ZnZtvjyI,696
|
|
43
|
+
ot/config/defaults/diagram-templates/c4-context.puml,sha256=v6KPHcZ2Q_0QY9h80oLTb_xzJUB1Qq5XyeuzNckVh9c,916
|
|
44
|
+
ot/config/defaults/diagram-templates/class-diagram.mmd,sha256=T1VfDg6UK-tKxgT3qZF45JOlMiCdl4Nsa3tmrQhoaLU,1717
|
|
45
|
+
ot/config/defaults/diagram-templates/feature-mindmap.mmd,sha256=mjpih6ehYH5Z8cMquAN7U-8BR8UshC7ggeMOkDQWaF8,1357
|
|
46
|
+
ot/config/defaults/diagram-templates/microservices.d2,sha256=vzW_HJs0-XiOzOjxLZngcqZzjnJGdgPwutqgkXVyaZw,1448
|
|
47
|
+
ot/config/defaults/diagram-templates/project-gantt.mmd,sha256=TNNHDund_OaUM_G1ByGJAPIz95TLBPgtuNMB8rEYu5s,1277
|
|
48
|
+
ot/config/defaults/diagram-templates/state-machine.mmd,sha256=fO36UWr0inb979kyHB1PnLx7RYLzOWd4_ZCBXNmRdDw,971
|
|
49
|
+
ot/config/defaults/tool_templates/__init__.py,sha256=RwRpiQf_iQ5S7uGsfWM92cE8JN_Y1KDqaPfo24h-A5w,214
|
|
50
|
+
ot/config/defaults/tool_templates/extension.py,sha256=VfHxAjiIZ2BdbFMWEkdxGZT4OUxSAUb9ng9p-HH2lCM,1371
|
|
51
|
+
ot/config/defaults/tool_templates/isolated.py,sha256=aTl7_hG1ALHCGqyHMPjKa6fNBXoTBPjsLtbFgq76LAg,1556
|
|
52
|
+
ot/config/global_templates/__init__.py,sha256=aHmytPELRNraAZf2cMf5c9-4yZQUd5m5Z9wg0-dMRKY,109
|
|
53
|
+
ot/config/global_templates/bench-secrets-template.yaml,sha256=srZcnOM8Af2gQTpmo7g16sE9-zj0Tlguv54V-WE3hCs,224
|
|
54
|
+
ot/config/global_templates/bench.yaml,sha256=h2Ac5-unilwx5TPvDsp02y4I0WiPI7y9CyRh7FIBuL8,223
|
|
55
|
+
ot/config/global_templates/onetool.yaml,sha256=hj22T9SkiX5qNao8DisLmV950nAILvUFMX-HoHhVJdI,813
|
|
56
|
+
ot/config/global_templates/secrets-template.yaml,sha256=sUb2uExdrx_07bH2UVKtp-tqCSpcW-PenH_UFDxPF2k,1541
|
|
57
|
+
ot/config/global_templates/servers.yaml,sha256=tDDYHNovK7WuANaH3YepXwhNl9ky35GpAszWKNPmZyw,657
|
|
58
|
+
ot/config/global_templates/snippets.yaml,sha256=r92kjjs21C0gVGsEl7NpnvcjPbmtA1bsPeU8YfoOjs8,9762
|
|
59
|
+
ot/executor/__init__.py,sha256=JGGWInQwvhV1ttr7seATxHbsoL3jwTAUeT0GfeG-56M,836
|
|
60
|
+
ot/executor/base.py,sha256=Z_Sm0Jyf77ffduJG7IS5UCDRX9JquQ6pWm3ek8lEl4o,317
|
|
61
|
+
ot/executor/fence_processor.py,sha256=4GQ0MccQmsuRVSWHRtpv4X1jvL8c2P68gYxjnZl_yj8,2744
|
|
62
|
+
ot/executor/linter.py,sha256=oxXvd-HtWPxHkqUT3d1713xMN5MpxWjuKFQWTLH458U,3704
|
|
63
|
+
ot/executor/pack_proxy.py,sha256=S0d3VsHaXvoraoJdgySAkk4Jc_ExzjGkPbKeCDstUEc,8793
|
|
64
|
+
ot/executor/param_resolver.py,sha256=lQR73bB_aJ1zgXGiI_JmzOiCeUYnW-jiEPHRdquSY00,4361
|
|
65
|
+
ot/executor/pep723.py,sha256=j53wwEtUDWqNe0DMRq0usbySnWEUUeCe4Gd0pMf7qyA,8474
|
|
66
|
+
ot/executor/result_store.py,sha256=BwTd4Gk0JPVmysGB0bC1vtc3M-5q4ZMsfkBle7e-jRE,11104
|
|
67
|
+
ot/executor/runner.py,sha256=Xr-V9k07T773-IN5NJFJmoEH78sj2e3ONsYR5UU4DS0,16432
|
|
68
|
+
ot/executor/simple.py,sha256=Ps181W5FfHOp7CkxF2m5kCe6YZz0qlp4sXSxsysSK6Q,5029
|
|
69
|
+
ot/executor/tool_loader.py,sha256=vdu5pAL1NvGGu1H7tE3lqBafzWHWP3MfFXMZgzgFyIw,13377
|
|
70
|
+
ot/executor/validator.py,sha256=i7xS5EvHVjFFlwX2NKPQJQUK-75gp-XzVGQXs6UCuMY,14241
|
|
71
|
+
ot/executor/worker_pool.py,sha256=HJOu3P9E5MKgBZsddmeElctPUhF5kwx5Hfd9IezwJo8,12635
|
|
72
|
+
ot/executor/worker_proxy.py,sha256=NUxOI2VZFkNbH5IMulvokHEe5cZQtViOSpb4DEHBf4I,5651
|
|
73
|
+
ot/logging/__init__.py,sha256=cEvgp-lB9SNgwIWBoATp0dXroBaaBt4SxYri6AHiBgY,943
|
|
74
|
+
ot/logging/config.py,sha256=PwvQDzcfrcDiUBJhRLyCc07GaMHzn9hu6rFq5wFQCyo,9919
|
|
75
|
+
ot/logging/entry.py,sha256=9kaR2DuxJFUrNUZl6z0IXSjmCmxJS970v8uNykc8L0s,6169
|
|
76
|
+
ot/logging/format.py,sha256=MMpdrvGJqnW2lFOClfhZyzm36rIU7MAq6BUaXOhjFn8,5388
|
|
77
|
+
ot/logging/span.py,sha256=cP2t06AGMWaqFCXRbKyZX0W7gyYyjvIQfFijupLd2ik,11373
|
|
78
|
+
ot/proxy/__init__.py,sha256=N4shk9gsZ76BBe8tUftXL83ELB42zlbTXtF05lTUqUc,435
|
|
79
|
+
ot/proxy/manager.py,sha256=ZhivveB9MthYv5oeI_vj61uYxkN82wMAPzPOdjTaGkg,13442
|
|
80
|
+
ot/registry/__init__.py,sha256=VAvn1JAL8dZrsTh_Y7NilIrLo9blbhWt38TN-FcTapM,5149
|
|
81
|
+
ot/registry/models.py,sha256=Z-lsRRN3pDyL2nUalZA9QoD1IG_e7aSPUoE6TvRspCk,2160
|
|
82
|
+
ot/registry/parser.py,sha256=NXLFXYIMjFfEb4ztTLZqz4GxYZw-uEWAdxDuMMT_iVI,8416
|
|
83
|
+
ot/registry/registry.py,sha256=HFPPIGWop2szXRQeQeFs5axK4iS17dEOHV8qf9Jm5nE,13458
|
|
84
|
+
ot/shortcuts/__init__.py,sha256=n-yQvYHoEIg-7Ydm_P7bA86AJk5iq9o38pLiAj_zGGY,461
|
|
85
|
+
ot/shortcuts/aliases.py,sha256=0oCgkvTQcPS2TqNYa6uGwLYunA8-1L-FfrHCVynZ4-Q,2705
|
|
86
|
+
ot/shortcuts/snippets.py,sha256=rCbyFdQ4_1HY4AhxeLRMUfDXDcVN3FZpEUp_8ACRIiY,7956
|
|
87
|
+
ot/stats/__init__.py,sha256=5IP7bkfeXZm_B-WS9kNnQDCoggwF0Mit3dFtBe5CvKU,933
|
|
88
|
+
ot/stats/html.py,sha256=vlMCxfyjm6gipNyPYP5O8Nicmhq8tsP0l6Ifpc1-dnY,9079
|
|
89
|
+
ot/stats/jsonl_writer.py,sha256=ym-Wfy0gv90M59ipCQsxapTKNQBO28btKDe6kgFdxck,8169
|
|
90
|
+
ot/stats/reader.py,sha256=zKNegWFSbEBekBDmbgzVTv1Lj3UckRZKkiGkfqPN3XY,11883
|
|
91
|
+
ot/stats/timing.py,sha256=ZAzigZwmAdyRKdUBjtkIuAi_KJXyrsygwSxm0_NM7aE,1500
|
|
92
|
+
ot/utils/__init__.py,sha256=k54kcSGmKl8zrnKXw9svCyXej7FrVZvshMSK1f_6de4,2108
|
|
93
|
+
ot/utils/batch.py,sha256=0oi0wx2kn0XlbB03Utn9lJho_Fmdomasl1_F5AauSdU,4939
|
|
94
|
+
ot/utils/cache.py,sha256=s3z7R_xv-hWxB_q76L7eFPbwnc_KFYRoZllnRloQswg,3506
|
|
95
|
+
ot/utils/deps.py,sha256=5U_bnAEfd_Ivt9ZZitn9emt8T7Ehm99_xb1_okbURfA,11654
|
|
96
|
+
ot/utils/exceptions.py,sha256=_kYtWpnxkBPF2TXkXksPeX2MfJLrCJ2VU-1CckPjZoU,613
|
|
97
|
+
ot/utils/factory.py,sha256=UhKV6Wa2FOZHh4SKWmfeps1ThboS0rQnBUL38-eMljE,5106
|
|
98
|
+
ot/utils/format.py,sha256=4bUvYnsUD9Wz2czPsSoxQOIqxrFIlx-n3Y5HdtZpfxc,2065
|
|
99
|
+
ot/utils/http.py,sha256=IaRTxn--2TJYGpAquywsuHm_xJQxOcMvtFDfuaJUJIU,5653
|
|
100
|
+
ot/utils/platform.py,sha256=dBnxrLN-H2W0onc_LM9BML5WXmKahdpdkW2pVdauup4,1512
|
|
101
|
+
ot/utils/sanitize.py,sha256=5zDKpDwE6oo-74Bwv-yhovOJ6zk03vO2-gsCiEDA2kk,3815
|
|
102
|
+
ot/utils/truncate.py,sha256=03ObrMxElh3CM5lhwThA00oLgPzzFSOPR9Y8BmzAwis,1771
|
|
103
|
+
ot_tools/__init__.py,sha256=uUxp9V0E1lqzeT3wOx10JHzAFu3esn7M6FJrwBn_8Z0,95
|
|
104
|
+
ot_tools/brave_search.py,sha256=JPVR_S2J1NLL7ad4AudIkgMsvnqggibjZ5FRXPt5ZA0,17746
|
|
105
|
+
ot_tools/code_search.py,sha256=P3-oReY7n_3nrlEiYzFv5ompcU-cuVRTeEK4fSQKuew,25191
|
|
106
|
+
ot_tools/context7.py,sha256=sn75QMEeOeSQSYZeVwT4UjYEXo3QXa8KC61mwIUix3U,16088
|
|
107
|
+
ot_tools/convert.py,sha256=mCmDFLWgLiEJhYyd6Ex9s7qfyPOWj7FKaqtIFKG_Ig4,20488
|
|
108
|
+
ot_tools/db.py,sha256=RH_OOUJYqYVw14O8QYGB9QKg9IGNPQAM33HDa71D3v4,13142
|
|
109
|
+
ot_tools/diagram.py,sha256=tGNyd3PYdpi3Qs7Gs8pbcZVWMBVmyNbJG_wxiZ8682M,50478
|
|
110
|
+
ot_tools/diagram.yaml,sha256=Q4twP0rH-1zPWFbgBhl_RZbUg5dkmldX5E6Lp49Ugp4,5439
|
|
111
|
+
ot_tools/excel.py,sha256=yZGgKzDzPvZAE7b9vjC25FY7lJkw7PCBFMYOGcU1UyE,43067
|
|
112
|
+
ot_tools/file.py,sha256=9o_A1m7GCxpnIKIwAiahvGaQrfxXcfkVQicPH1_ztW0,46689
|
|
113
|
+
ot_tools/firecrawl.py,sha256=PtWtiKSUGl0VUdZfMhfHOmQSJ__UN2xcJ-BBuVaXmgo,23433
|
|
114
|
+
ot_tools/grounding_search.py,sha256=ak0wZzBQMPR5VYVrATOIzldZj_n8UxYeCxrmpTZrykA,20182
|
|
115
|
+
ot_tools/package.py,sha256=5MtsPW9ieolQAnaw60Yb4TyODSlowW56HAZj-j_QSkU,19148
|
|
116
|
+
ot_tools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
117
|
+
ot_tools/ripgrep.py,sha256=_dKHo5TTlYlzoRQV8-7kFw3yuYk7I5r_9FYJvnGFECc,17105
|
|
118
|
+
ot_tools/scaffold.py,sha256=92pjn0kqncK-2XrzEUn058HRkp1iJpAvWInaCKVdbGI,17374
|
|
119
|
+
ot_tools/transform.py,sha256=IQ6bBZ4mDS7c-8FzpUSQB1EwseYgq3kVGr5LFxLBcwA,6747
|
|
120
|
+
ot_tools/web_fetch.py,sha256=l9taGigHIW8QMaFRObjQuoUNdv9MzYMIyZgtdaTO3DA,13483
|
|
121
|
+
ot_tools/_convert/__init__.py,sha256=Cwo87GiP8JUWpGFSpbkCEyt_q4PUKauFpbqzyOIFOy0,465
|
|
122
|
+
ot_tools/_convert/excel.py,sha256=mVCgolocTKd7ZCpVd2hANaYnhJrneNtGYEZafrCeYqE,8679
|
|
123
|
+
ot_tools/_convert/pdf.py,sha256=6ATY_8NGrc5877Hhw-z5Gxo4Nxsw7MBhVLaHwAmvBXE,7323
|
|
124
|
+
ot_tools/_convert/powerpoint.py,sha256=M8lwkTV7x4wafR7eXrVojCBKgcXVxO1tT-Z2Ml5wwxo,7855
|
|
125
|
+
ot_tools/_convert/utils.py,sha256=AfId8ulTx_kKq0zVbhvuY3KGXqQjEk8Y7o8BXjP8WgA,10192
|
|
126
|
+
ot_tools/_convert/word.py,sha256=XfjqQRhEYS_433LprmF6vqyosytXVdNWzsCXo42WNcA,8710
|
|
127
|
+
onetool_mcp-1.0.0b1.dist-info/METADATA,sha256=S4eE3OnUcKTZpd8MK0COy_vlI9kzMV1ZrCatCbQ1E0w,5584
|
|
128
|
+
onetool_mcp-1.0.0b1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
129
|
+
onetool_mcp-1.0.0b1.dist-info/entry_points.txt,sha256=UUr3FvhGxnRdyJSxRG5YeqCGUi8nQ3oMCoueM35sF04,66
|
|
130
|
+
onetool_mcp-1.0.0b1.dist-info/licenses/LICENSE.txt,sha256=EAAF-2Agl1ewXnFl4KFpREq8Jh1YFRiogyBIzfGyImM,35561
|
|
131
|
+
onetool_mcp-1.0.0b1.dist-info/licenses/NOTICE.txt,sha256=GTNDiQ3_2O_AcngYY3t41ZQ7S_E7r0EcflmdZGjGFxM,2470
|
|
132
|
+
onetool_mcp-1.0.0b1.dist-info/RECORD,,
|