toolbase 0.1.0__tar.gz → 0.2.0__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.
Files changed (122) hide show
  1. toolbase-0.2.0/CHANGELOG.md +94 -0
  2. toolbase-0.2.0/MANIFEST.in +4 -0
  3. {toolbase-0.1.0 → toolbase-0.2.0}/PKG-INFO +60 -34
  4. toolbase-0.1.0/toolbase.egg-info/PKG-INFO → toolbase-0.2.0/README.md +56 -71
  5. {toolbase-0.1.0 → toolbase-0.2.0}/pyproject.toml +9 -1
  6. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/_toolkit_host.py +109 -33
  7. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/cli.py +1899 -474
  8. toolbase-0.2.0/toolbase/connect/__init__.py +55 -0
  9. toolbase-0.2.0/toolbase/connect/base.py +102 -0
  10. toolbase-0.2.0/toolbase/connect/claude_code.py +180 -0
  11. toolbase-0.2.0/toolbase/connect/codex.py +199 -0
  12. toolbase-0.2.0/toolbase/connect/orchestral.py +207 -0
  13. toolbase-0.2.0/toolbase/envs/bundle_deps.py +96 -0
  14. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/envs/cache.py +43 -0
  15. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/envs/manifest.py +39 -4
  16. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/envs/paths.py +42 -0
  17. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/ingest.py +2 -2
  18. toolbase-0.1.0/toolbase/serve/tool_groups.py → toolbase-0.2.0/toolbase/serve/bundles.py +63 -63
  19. toolbase-0.2.0/toolbase/serve/config.py +188 -0
  20. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/serve/orchestrator.py +198 -133
  21. toolbase-0.2.0/toolbase/serve/profile_scaffold.py +301 -0
  22. toolbase-0.2.0/toolbase/serve/profiles.py +398 -0
  23. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/setup/declarative.py +63 -8
  24. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/setup/schema.py +62 -6
  25. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/setup/storage.py +13 -8
  26. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/skills.py +35 -2
  27. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/templates/skills/example_skill.md +1 -0
  28. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/validation.py +147 -80
  29. toolbase-0.2.0/toolbase.egg-info/SOURCES.txt +62 -0
  30. toolbase-0.1.0/README.md +0 -209
  31. toolbase-0.1.0/tests/test_auth.py +0 -491
  32. toolbase-0.1.0/tests/test_categories_api.py +0 -143
  33. toolbase-0.1.0/tests/test_config_command.py +0 -293
  34. toolbase-0.1.0/tests/test_create_command.py +0 -358
  35. toolbase-0.1.0/tests/test_envs_cache.py +0 -285
  36. toolbase-0.1.0/tests/test_envs_config.py +0 -157
  37. toolbase-0.1.0/tests/test_envs_discovery.py +0 -129
  38. toolbase-0.1.0/tests/test_envs_manifest.py +0 -172
  39. toolbase-0.1.0/tests/test_envs_paths.py +0 -107
  40. toolbase-0.1.0/tests/test_envs_phase3_wiring.py +0 -248
  41. toolbase-0.1.0/tests/test_envs_phase4_config.py +0 -547
  42. toolbase-0.1.0/tests/test_envs_phase5_list.py +0 -408
  43. toolbase-0.1.0/tests/test_envs_phase6_reset.py +0 -380
  44. toolbase-0.1.0/tests/test_envs_schema.py +0 -277
  45. toolbase-0.1.0/tests/test_expected_toolkits.py +0 -207
  46. toolbase-0.1.0/tests/test_host_stderr_capture.py +0 -85
  47. toolbase-0.1.0/tests/test_ingest_ast.py +0 -557
  48. toolbase-0.1.0/tests/test_ingest_command.py +0 -302
  49. toolbase-0.1.0/tests/test_ingest_merge.py +0 -356
  50. toolbase-0.1.0/tests/test_ingest_walker.py +0 -173
  51. toolbase-0.1.0/tests/test_ingest_yaml_emit.py +0 -216
  52. toolbase-0.1.0/tests/test_init_template.py +0 -269
  53. toolbase-0.1.0/tests/test_install_flags.py +0 -319
  54. toolbase-0.1.0/tests/test_interactive_flags.py +0 -209
  55. toolbase-0.1.0/tests/test_logger_serve_log_wiring.py +0 -107
  56. toolbase-0.1.0/tests/test_login_command.py +0 -532
  57. toolbase-0.1.0/tests/test_orchestrator_restart.py +0 -733
  58. toolbase-0.1.0/tests/test_orchestrator_tool_groups.py +0 -219
  59. toolbase-0.1.0/tests/test_per_toolkit_log_rotation.py +0 -71
  60. toolbase-0.1.0/tests/test_publish_auto_create.py +0 -322
  61. toolbase-0.1.0/tests/test_publish_version_check.py +0 -180
  62. toolbase-0.1.0/tests/test_serve_config.py +0 -439
  63. toolbase-0.1.0/tests/test_serve_state_config.py +0 -139
  64. toolbase-0.1.0/tests/test_setup_command.py +0 -280
  65. toolbase-0.1.0/tests/test_setup_context.py +0 -322
  66. toolbase-0.1.0/tests/test_setup_declarative.py +0 -291
  67. toolbase-0.1.0/tests/test_setup_downloads.py +0 -462
  68. toolbase-0.1.0/tests/test_setup_handlers.py +0 -313
  69. toolbase-0.1.0/tests/test_setup_host.py +0 -624
  70. toolbase-0.1.0/tests/test_setup_prompts.py +0 -238
  71. toolbase-0.1.0/tests/test_setup_rpc.py +0 -225
  72. toolbase-0.1.0/tests/test_setup_runner.py +0 -460
  73. toolbase-0.1.0/tests/test_setup_schema.py +0 -300
  74. toolbase-0.1.0/tests/test_setup_storage.py +0 -214
  75. toolbase-0.1.0/tests/test_setup_validate_cache.py +0 -174
  76. toolbase-0.1.0/tests/test_skills.py +0 -286
  77. toolbase-0.1.0/tests/test_tool_groups.py +0 -499
  78. toolbase-0.1.0/tests/test_toolkit_host_explicit_tools.py +0 -219
  79. toolbase-0.1.0/tests/test_validation_explicit_tools.py +0 -340
  80. toolbase-0.1.0/tests/test_versioning.py +0 -86
  81. toolbase-0.1.0/toolbase/serve/config.py +0 -436
  82. toolbase-0.1.0/toolbase.egg-info/SOURCES.txt +0 -108
  83. toolbase-0.1.0/toolbase.egg-info/dependency_links.txt +0 -1
  84. toolbase-0.1.0/toolbase.egg-info/entry_points.txt +0 -3
  85. toolbase-0.1.0/toolbase.egg-info/requires.txt +0 -15
  86. toolbase-0.1.0/toolbase.egg-info/top_level.txt +0 -1
  87. {toolbase-0.1.0 → toolbase-0.2.0}/LICENSE +0 -0
  88. {toolbase-0.1.0 → toolbase-0.2.0}/setup.cfg +0 -0
  89. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/__init__.py +0 -0
  90. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/_setup_host.py +0 -0
  91. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/astro.py +0 -0
  92. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/auth.py +0 -0
  93. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/config.py +0 -0
  94. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/envs/__init__.py +0 -0
  95. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/envs/config.py +0 -0
  96. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/envs/discovery.py +0 -0
  97. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/envs/schema.py +0 -0
  98. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/hep.py +0 -0
  99. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/logging/__init__.py +0 -0
  100. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/logging/logger.py +0 -0
  101. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/neutrino.py +0 -0
  102. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/quantum.py +0 -0
  103. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/serve/__init__.py +0 -0
  104. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/serve/proxy_tool.py +0 -0
  105. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/setup/__init__.py +0 -0
  106. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/setup/_rpc.py +0 -0
  107. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/setup/context.py +0 -0
  108. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/setup/downloads.py +0 -0
  109. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/setup/prompts.py +0 -0
  110. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/setup/runner.py +0 -0
  111. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/setup/validate_cache.py +0 -0
  112. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/templates/Dockerfile.template +0 -0
  113. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/templates/README.md.template +0 -0
  114. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/templates/__init__.py.template +0 -0
  115. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/templates/mcp/__init__.py.template +0 -0
  116. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/templates/mcp/server_stdio.py.template +0 -0
  117. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/templates/requirements.txt.template +0 -0
  118. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/templates/setup.py.template +0 -0
  119. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/templates/tool_example.py +0 -0
  120. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/templates/toolkit.yaml.template +0 -0
  121. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/toolkit.py +0 -0
  122. {toolbase-0.1.0 → toolbase-0.2.0}/toolbase/versioning.py +0 -0
@@ -0,0 +1,94 @@
1
+ # Changelog
2
+
3
+ All notable changes to `toolbase` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
6
+
7
+ ---
8
+
9
+ ## [Unreleased]
10
+
11
+ ## [0.2.0] — 2026-06-05
12
+
13
+ Serve/curation revamp. **Breaking** (v0, clean cutover — no compatibility aliases).
14
+
15
+ ### Added
16
+
17
+ - `toolbase connect <client>` / `disconnect <client>` — write (or remove) the toolbase MCP entry in an agent client's config, replacing the manual JSON copy-paste. Claude Code in v1 (`~/.claude.json` for user scope, `.mcp.json` for `-l` project scope), via a pluggable adapter so Codex / Orchestral can follow. `--list` shows where toolbase is wired; `--clients` lists targets; `--profile` also sets the active profile; `--abspath` writes an absolute binary path. Non-destructive merge, atomic write.
18
+ - `toolbase activate` / `deactivate <toolkit | toolkit/bundle | toolkit__tool>` — expose or hide tools in the active profile. The casual-tier surface; users never need to learn "profiles" to curate.
19
+ - **Profiles** — named curated tool sets, one file per profile under `<scope>/.toolbase/profiles/<name>.yaml`. `toolbase profile <list|show|create|edit|delete|set-default|path|tools>` manages them (replaces `toolbase groups`).
20
+ - `toolbase install -a/--activate` — install and activate in one step.
21
+ - `toolbase list -v` — per-tool served/hidden view with bundle + config-gating annotations; `tb list` now marks each toolkit active/inactive, and `--json` gains an `active` field.
22
+ - `toolbase config init <toolkit> [--user | --project] [--force]` — scaffold a commented YAML config file from a toolkit's `config:` schema. Defaults to the project layer (matches `config set` / `unset`); pass `--user` for the user layer. Required fields land as `<NEEDS VALUE>`; optional fields with defaults get their default; optional fields without defaults are commented out so the full schema is visible.
23
+ - **Workspace-aware schema defaults.** `path` and `string` fields in a toolkit's `config:` block may use `${CWD}` (the orchestrator's `os.getcwd()` at serve time — i.e. the harness's launch directory, where the agent is working) or `${PROJECT_ROOT}` (the discovered `.toolbase/` parent, or `${CWD}` if there is none). Composition works (`${CWD}/scratch`). Unknown templates are rejected at schema parse time. `tb config show` renders templates alongside their current expansion.
24
+ - **Multi-bundle tool membership.** A tool's `bundle:` field now accepts either a single name or a list (`bundle: [a, b]`); a multi-bundle tool is served if **any** of its bundles is available and counts as in-profile if any of its bundles is in the profile's allowlist.
25
+ - **Per-bundle dependencies.** A toolkit author can declare `deps: [pip-spec]` on each bundle alongside the existing `requires:` (config-key gate). The toolkit's `requirements.txt` stays the always-installed base; bundle `deps:` add on top when the user installs that bundle.
26
+ - **Install-time bundle selection: `tb install <toolkit>[a,b]` (pip-extras style) and `--bundle a` (flag form).** Pip-installs only the selected bundles' `deps:` on top of `requirements.txt` rather than every bundle's deps. Re-installing with new bundles is **additive** (pip-like): pip-installs the new bundles' deps into the existing venv without rebuilding. `--rebuild` forces destructive reinstall. Cache metadata (`.install_meta.yaml`) and project manifest entries record the installed bundle set; serve filters tools whose bundles are entirely outside the installed set, with a one-line summary at startup per toolkit.
27
+ - **Subset-install visibility in `tb list`.** Version rows now end with `[subset: a, b]` when only some bundles' deps are installed (`[subset: (base only)]` for an explicit empty subset). `--json` gains an `installed_bundles` field (`null` for a full install, list for a subset). `tb list -v` annotates per-tool why a tool is hidden when its bundle isn't in the install set: `(skipped: bundle X not installed)` — multi-bundle plural `(skipped: bundles a, b not installed)`. Install-scope wins over the existing config-gating annotation since install-scope strips the deps that config-gating would later check. When 6+ tools would be install-gated in a single toolkit (large toolkits with bundle subsets — heptapod's 50-tool/8-bundle case prompted this), they collapse into a single dim summary line `(+N tools in uninstalled bundles: a, b, … — add with tb install <name>[<bundle>])` to keep the verbose output scannable. Config-gated tools stay inline since they're one `tb config set` away rather than a reinstall.
28
+ - **Author-controlled tool display names.** A `tools[]` entry in `toolkit.yaml` may now carry an optional `display_name:` field that overrides the agent-visible name on the MCP wire (after the orchestrator's `<toolkit>__` prefix). When absent, the default is the Python class name with the trailing `Tool` suffix stripped, PascalCase preserved — so `InspireSearchTool` advertises as `heptapod__InspireSearch`. Explicit `display_name: search_papers` would advertise as `heptapod__search_papers`. Precedence: yaml `display_name:` > `@define_tool(display_name=...)` in code > derived default. The yaml layer wins because that's what the registry sees and what an author editing the file directly expects to take effect.
29
+
30
+ ### Changed
31
+
32
+ - **Nothing-active by default.** Installing a toolkit places it in the cache but serves nothing until you `activate` it (conda-style: install ≠ activate). `tb serve` resolves an active profile — there is no "serve everything" fallback.
33
+ - `serve.yaml` is now defaults-only: `default.profile` (the active profile) and `default.disabled` (absolute blocklists), with a two-layer user→project merge.
34
+ - **Vocabulary:** the author-side intra-toolkit grouping is now a **bundle** (was `tool_groups:` / per-tool `group:`); the user-side curated subset is now a **profile** (was the `groups:` block in `serve.yaml`). The developer unit stays a **toolkit**. `tb serve --enable-bundle` replaces `--enable-group`.
35
+ - **Resolved state-config is injected at tool construction time.** Tools declared with required `StateField`s (e.g. a `base_directory` the toolkit author marks `required: true`) no longer fail with a pydantic `ValidationError` on serve startup; values flow from `~/.toolbase/config/<toolkit>.yaml` (and project-layer overrides) into the tool constructor via `_import_explicit_tools`. Required fields with a schema default — literal or template — are now satisfied by the default; previously the default was ignored and the field was flagged missing.
36
+ - **Per-tool failures during import / construction now skip just that tool**, emitting a structured `tool_import_skipped` log line to the per-toolkit log. A single misconfigured tool no longer takes down its sibling tools or the whole toolkit host.
37
+ - **Agent-visible tool names are now PascalCase by default** (breaking on the wire — old: `heptapod__inspiresearch`, new: `heptapod__InspireSearch`). The toolkit host now sets each instance's `_mcp_display_name` to the class name with the `Tool` suffix stripped (PascalCase preserved), and calls `MCPServer(use_display_names=True)` so MCP advertises it. The previous default — `cls.__name__.removesuffix("Tool").lower()` from `BaseTool.get_name()` — collapsed word boundaries into a single lowercase blob that was both harder for the agent to read and impossible to customise per-tool short of subclassing. Agents that have hard-coded the old lowered form (logs, harness configs, scripts) need updating; agents that read the tool list each turn (Claude Code, Codex) adapt automatically.
38
+ - **CLI startup is faster.** `tb --help` / `tb list` and similar no-network commands dropped from ~290 ms to ~50 ms warm by lazy-importing `requests`, `rich.syntax`/`pygments`, `rich.panel` / `table` / `progress`, and dropping a dead `Syntax` import. Heavy modules load only when commands that need them run.
39
+ - `config_dir()` and `project_config_dir()` are pure path resolvers; they no longer `mkdir(parents=True, exist_ok=True)` as a side effect. Writers (`save_config` etc.) create parents lazily at write time, so a layered path lookup no longer leaves an empty `<project>/.toolbase/config/` dir behind that looks like a half-done install.
40
+
41
+ ### Fixed
42
+
43
+ - **Orchestrator's per-tool install-scope and config-gating filter actually fires.** `tb serve` reads each toolkit's `toolkit.yaml` to build a `name_to_bundles` lookup (which bundles each tool belongs to) and consults it for every tool the host advertises. The lookup was keyed by toolkit.yaml's `tools[].name` field — the PascalCase BaseTool subclass name (e.g. `InspireSearchTool`). But the toolkit host calls `orchestral.mcp.MCPServer(..., use_display_names=False)`, which registers each tool under `BaseTool.get_name() = cls.__name__.removesuffix("Tool").lower()` — so MCP advertises `inspiresearch`, not `InspireSearchTool`. Every `name_to_bundles.get(host_advertised_name)` missed → `tool_bundles` came back `[]` → both the install-scope gate and the config-gate short-circuited (they no-op on empty bundle membership). Result: a `tb install heptapod[inspire,pdg]` subset install still surfaced ~30 tools instead of the expected ~14, including tools from bundles whose pip deps weren't installed — those would just blow up at the host's import step with a `tool_import_skipped` log line, but the orchestrator continued to advertise the rest. Normalised `name_to_bundles` keys to match the MCP form so the filter works as documented.
44
+ - **`tb config init` scaffold no longer produces unparseable multi-document YAML.** Defaults with non-trivial values — `path` template defaults like `${CWD}`, string/integer/secret defaults — were being rendered via `yaml.safe_dump(scalar)` whose output appends a `\n...` document-end marker that the previous `.strip()` only partially trimmed (trailing newline only, not the marker). The resulting file looked like one document but parsed as two, so the orchestrator dropped the toolkit at serve startup with `config incomplete — invalid: <file> (failed to parse ...: expected a single document in the stream)` and the harness reported `Failed to reconnect to toolbase: -32000` with no obvious cause. Existing broken files don't auto-repair — delete the bare `...` line manually or re-run `tb config init --force` to regenerate.
45
+ - **Partial-install cache slots no longer wedge subsequent `tb install` invocations.** A Ctrl-C during a long pip install (heavy bundle deps can take minutes) used to leave the cache slot with source files but no `.install_meta.yaml`. The next install with a bundle subset (`tb install foo[a,b]`) matched the "already installed with all bundles" branch, printed a misleading message about needing `--rebuild`, and exited 0 without doing anything. Two-part fix: (1) the fresh-install pipeline (source → env setup → meta write) is now wrapped in `try/finally` keyed on a success flag, so any interrupt or exception before meta-write removes the slot; (2) the collision check explicitly detects a missing `.install_meta.yaml` and treats it as a corrupted slot — auto-clean and proceed as fresh install rather than no-op.
46
+
47
+ ### Removed
48
+
49
+ - `toolbase groups` and the `groups:` block in `serve.yaml` (replaced by profiles).
50
+ - `tb serve` positional toolkit names and the `--group` / `--enable-tool` / `--disable-tool` one-shot flags (curation now lives in profiles; `--profile` selects one).
51
+
52
+ ---
53
+
54
+ ## [0.1.0] — 2026-05-22
55
+
56
+ Initial Toolbase release. Toolbase is the community registry and CLI for AI agent toolkits — a **toolkit** is the publishable unit, and each toolkit bundles one or more **tools** that agents call over the [Model Context Protocol](https://modelcontextprotocol.io). You author and ship toolkits, install them into isolated environments, and serve them to coding agents (Claude Code, Codex) or any MCP client.
57
+
58
+ > Toolbase began as `scitoolkit`. The code is mature — it shipped across nine `scitoolkit` releases (0.1.0–0.6.1) over two weeks — but `toolbase` is a new, general-purpose package on PyPI, not a rename of the published `scitoolkit`. This entry is the cumulative feature set as of the first Toolbase release; the granular pre-rebrand release notes live with the `scitoolkit` project.
59
+
60
+ ### Authoring and publishing
61
+
62
+ - `toolbase init` — scaffold a toolkit from template (`--with-setup` for toolkits that need a `setup.py`).
63
+ - `toolbase ingest` — register tools from existing source. Re-running over a directory that already has a `toolkit.yaml` merges (new tools appended, hand-edited entries preserved byte-for-byte) rather than overwriting; `--prune` removes stale entries, `--force` rebuilds from scratch.
64
+ - `toolbase create` — reserve a toolkit name on the registry without uploading code (optional; `publish` auto-registers on first run).
65
+ - `toolbase validate` — Pydantic-based pre-publish structural checks.
66
+ - `toolbase login` — browser-flow auth that stores a per-user token good for any toolkit you own or collaborate on. Legacy per-toolkit tokens (`toolbase login <toolkit>`) are still accepted but deprecated. `whoami` / `logout` round out auth.
67
+ - `toolbase publish [--dry-run]` — package and upload to the registry; auto-registers the name on first run, and blocks "version already exists" / "version decrease" before upload.
68
+
69
+ ### Installing and managing
70
+
71
+ - `toolbase search` — find toolkits on the registry.
72
+ - `toolbase install <name|path>` — download (or build from a local path), extract, and set up an isolated environment (venv or conda, auto-detected). Scope flags: `-g` (global, the default), `-l` (pin into the current project's `.toolbase/manifest.yaml`), `-e <path>` (editable — symlink a local source into the cache so `serve` loads tools live, the `pip install -e .` parallel). Multiple versions of a toolkit coexist in the global cache; the binary lives once in the shared cache and the manifest scope is independent of file location.
73
+ - `toolbase list` / `toolbase uninstall <name>` — manage installed toolkits.
74
+
75
+ ### Serving
76
+
77
+ - `toolbase serve` — multi-toolkit MCP aggregator (stdio). Each installed toolkit runs in its own subprocess in its own Python environment; the orchestrator aggregates them and exposes the union as a single MCP server. A crashed toolkit auto-restarts with exponential backoff and doesn't take the orchestrator down. Supports positional toolkit names, `--group`, `--enable-tool`, `--disable-tool`, `--dry-run`, `--call-timeout`.
78
+ - `toolbase groups` — manage named tool subsets that span toolkits.
79
+ - `toolbase logs` — tail the serve log with Rich coloring.
80
+
81
+ ### Configuration and setup
82
+
83
+ - `toolbase config <show|edit|path|set|unset|validate>` — manage per-toolkit config at `~/.toolbase/config/<toolkit>.yaml`. Toolkits declare a `config:` block in `toolkit.yaml` (seven types: `string`, `secret`, `path`, `integer`, `float`, `boolean`, `choice`); the human-editable file is the canonical source, prompts are scaffolding.
84
+ - `toolbase setup <toolkit>` (`--reset`, `--check`) — run a toolkit's `setup.py` for involved setup: full prompts, resumable SHA256-verified downloads with auto-extraction (tar/zip, zip-slip defended), and derived-state writes via `ctx.set_config(...)`.
85
+
86
+ ### Platform
87
+
88
+ - **Multi-tier execution:** same-Python toolkits run in venv, different-Python toolkits run under conda (auto-detected). Docker mode is detected and refused with a clear "coming in Phase 3B" message.
89
+ - **HTTP-loopback architecture** between the orchestrator and per-toolkit subprocesses.
90
+ - **Per-tool selection** per serve session or persistently in `~/.toolbase/serve.yaml`.
91
+ - **Skills surfacing:** a toolkit's `skills/*.md` files are auto-mirrored to `~/.claude/skills/` (symlinked on POSIX for live edits, copied on Windows) so Claude Code discovers them.
92
+ - **Agent-friendly:** every state-modifying command supports `--yes`, `--no`, `--no-input`; non-TTY stdin auto-applies non-interactive behavior.
93
+ - **`tb` alias:** every command is available as `tb` as well as `toolbase`.
94
+ - Python 3.12+ required.
@@ -0,0 +1,4 @@
1
+ include CHANGELOG.md
2
+ prune tests
3
+ prune toolbase.egg-info
4
+ global-exclude __pycache__ *.py[cod] .DS_Store
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: toolbase
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: The community registry and CLI for AI agent toolkits - discover, share, and serve tools to AI agents over MCP
5
5
  Author-email: Alex Roman <toolbase.dev@gmail.com>
6
6
  License: MIT
@@ -29,11 +29,14 @@ Requires-Dist: pydantic>=2.0
29
29
  Requires-Dist: email-validator>=2.0
30
30
  Requires-Dist: orchestral-ai>=1.4
31
31
  Requires-Dist: mcp>=1.0
32
+ Requires-Dist: tomlkit>=0.12
32
33
  Provides-Extra: dev
33
34
  Requires-Dist: pytest>=7.0; extra == "dev"
34
35
  Requires-Dist: pytest-cov>=4.0; extra == "dev"
35
36
  Requires-Dist: black>=23.0; extra == "dev"
36
37
  Requires-Dist: ruff>=0.1.0; extra == "dev"
38
+ Provides-Extra: docs
39
+ Requires-Dist: mkdocs-material>=9.5; extra == "docs"
37
40
  Dynamic: license-file
38
41
 
39
42
  # toolbase
@@ -60,42 +63,54 @@ pip install toolbase
60
63
  # Install a toolkit from the registry (global by default)
61
64
  tb install arxiv-search
62
65
 
63
- # Or scope an install to the current project's manifest
64
- tb install -l arxiv-search
66
+ # Expose it to the agent (installing alone serves nothing)
67
+ tb activate arxiv-search
65
68
 
66
- # See what you have
67
- tb list
69
+ # Wire toolbase into Claude Code (writes its MCP config for you)
70
+ tb connect claude-code
68
71
 
69
- # Serve installed toolkits over MCP stdio
70
- tb serve
72
+ # See what's installed and what's active
73
+ tb list
71
74
  ```
72
75
 
73
76
  `tb` is a shorter alias for `toolbase`; both ship with the package
74
77
  and behave identically.
75
78
 
79
+ **Install, then activate.** Installing places a toolkit in the cache but
80
+ does not serve it — nothing reaches the agent until you `tb activate` it
81
+ (conda-style: install ≠ activate). `tb install -a arxiv-search` does both
82
+ in one step. Use `tb deactivate` to hide a toolkit, bundle, or tool again.
83
+
76
84
  Installs are global by default (`-g`). Use `-l` to pin a toolkit into
77
85
  the current project's `.toolbase/manifest.yaml` instead — the binary
78
86
  still lives in the shared global cache, only the pin is project-scoped,
79
87
  so a collaborator who clones the project and runs `tb install` (no
80
88
  args) gets the same toolkits at the same versions.
81
89
 
82
- To use the served toolkits in [Claude Code](https://claude.ai/code), add
83
- this to its MCP config:
84
-
85
- ```json
86
- {
87
- "mcpServers": {
88
- "toolbase": {
89
- "command": "toolbase",
90
- "args": ["serve"]
91
- }
92
- }
93
- }
90
+ **`tb connect` replaces hand-editing MCP config.** It writes the
91
+ `toolbase` server entry into [Claude Code](https://claude.ai/code)'s
92
+ config (`~/.claude.json` for user scope, `.mcp.json` for `-l` project
93
+ scope). Claude Code then spawns its own `toolbase serve` subprocess and
94
+ discovers the active profile's tools. To watch tool calls fire in real
95
+ time, run `tb logs` in another terminal. (If you'd rather wire it by
96
+ hand, the entry is `{"mcpServers": {"toolbase": {"command": "toolbase",
97
+ "args": ["serve"]}}}`.)
98
+
99
+ ### Curating what the agent sees
100
+
101
+ `tb activate` / `tb deactivate` edit the active **profile** — a named
102
+ curated set of tools. Three granularities:
103
+
104
+ ```bash
105
+ tb activate heptapod # the whole toolkit
106
+ tb activate heptapod/pythia # one bundle (a coherent group of tools)
107
+ tb activate heptapod__run_pythia # one specific tool
94
108
  ```
95
109
 
96
- Claude Code will spawn its own `toolbase serve` subprocess and
97
- discover all installed toolkits' tools. To watch tool calls fire in
98
- real time, run `tb logs` in another terminal.
110
+ Most users only ever touch the default profile via these commands. Power
111
+ users can keep several named profiles (`tb profile create paper`,
112
+ `tb connect claude-code --profile paper`) and switch between them. Run
113
+ `tb profile tools` to see the bundles and tools a toolkit offers.
99
114
 
100
115
  ---
101
116
 
@@ -127,20 +142,20 @@ publish→install round-trip on every change, install it editable:
127
142
 
128
143
  ```bash
129
144
  cd my-toolkit
130
- tb install -e . # live symlink to this source dir
131
- tb serve my-toolkit # serve it; edit tools/, restart, edits are live
145
+ tb install -e . -a # live symlink to this source dir, and activate it
146
+ # edit tools/, restart your agent session — edits are live
132
147
  ```
133
148
 
134
149
  An editable install symlinks your source into the cache and builds the
135
150
  environment there (your source tree stays clean — no `.venv` written
136
- into it). Edits to your tool source appear on the next `tb serve`. If
137
- you change dependencies, re-run `tb install -e .` to rebuild the env.
151
+ into it). Edits to your tool source appear on the next serve. If you
152
+ change dependencies, re-run `tb install -e .` to rebuild the env.
138
153
 
139
154
  For the agent-assisted authoring flow (recommended for first toolkits),
140
155
  see <https://toolbase-ai.com/docs/scaffold-with-an-agent>.
141
156
 
142
157
  For the full author guide — toolkit layout, tool conventions, skills,
143
- groups, expected_toolkits, configuration — see
158
+ bundles, expected_toolkits, configuration — see
144
159
  <https://toolbase-ai.com/docs/authoring> and
145
160
  <https://toolbase-ai.com/docs/configuration>.
146
161
 
@@ -154,15 +169,23 @@ groups, expected_toolkits, configuration — see
154
169
  `publish` — author and ship toolkits.
155
170
  - `search`, `install`, `uninstall`, `list` — manage installed toolkits.
156
171
  `install` takes `-g` (global, the default), `-l` (pin into this
157
- project), or `-e <path>` (editable, live symlink to a local source).
158
- - `serve` run installed toolkits as an MCP stdio server. Supports
159
- positional toolkit names, `--group`, `--enable-tool`,
160
- `--disable-tool`, `--dry-run`, `--call-timeout`.
172
+ project), `-e <path>` (editable, live symlink to a local source), or
173
+ `-a` (also activate). `list` takes `-v` for a per-tool served/hidden
174
+ view.
175
+ - `activate` / `deactivate` — expose or hide a toolkit, bundle
176
+ (`toolkit/bundle`), or tool (`toolkit__tool`) in the active profile.
177
+ - `connect <client>` / `disconnect <client>` — write (or remove)
178
+ toolbase in an agent client's MCP config (`claude-code` in v1).
179
+ `--list` shows where it's wired; `--clients` lists supported targets.
180
+ - `serve` — run the active profile's tools as an MCP stdio server
181
+ (`--profile`, `--dry-run`, `--call-timeout`). Normally spawned by the
182
+ client, not run by hand.
183
+ - `profile <list|show|create|edit|delete|set-default|path|tools>` —
184
+ manage named profiles (curated tool sets).
161
185
  - `setup <toolkit>` — run a toolkit's `setup.py` (`--reset`, `--check`).
162
186
  - `config <show|edit|path|set|unset|validate>` — manage per-toolkit
163
187
  config files at `~/.toolbase/config/<toolkit>.yaml`.
164
188
  - `logs` — tail the serve log with Rich coloring.
165
- - `groups` — manage named tool subsets that span toolkits.
166
189
 
167
190
  **Features:**
168
191
 
@@ -190,8 +213,11 @@ groups, expected_toolkits, configuration — see
190
213
  - **Multi-tier execution:** same-Python toolkits run in venv,
191
214
  different-Python toolkits run under conda (auto-detected). Docker
192
215
  mode coming in 3B.
193
- - **Per-tool selection:** enable or disable individual tools per
194
- serve session or persistently in `~/.toolbase/serve.yaml`.
216
+ - **Profiles:** curated tool sets assembled across toolkits at
217
+ toolkit / bundle / tool granularity, stored one-file-per-profile under
218
+ `.toolbase/profiles/`. Activate with `tb activate`; the active profile
219
+ is chosen by `default.profile` in `~/.toolbase/serve.yaml` (or a
220
+ project-level override).
195
221
  - **Skills surfacing:** a toolkit's `skills/*.md` files are
196
222
  auto-mirrored to `~/.claude/skills/` so Claude Code discovers
197
223
  them. Symlinked on POSIX for live edits, copied on Windows.
@@ -1,41 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: toolbase
3
- Version: 0.1.0
4
- Summary: The community registry and CLI for AI agent toolkits - discover, share, and serve tools to AI agents over MCP
5
- Author-email: Alex Roman <toolbase.dev@gmail.com>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/alexr314/toolbase
8
- Project-URL: Documentation, https://github.com/alexr314/toolbase#readme
9
- Project-URL: Repository, https://github.com/alexr314/toolbase
10
- Project-URL: Issues, https://github.com/alexr314/toolbase/issues
11
- Keywords: ai,agents,tools,toolkit,mcp,orchestral,registry,package-manager
12
- Classifier: Development Status :: 3 - Alpha
13
- Classifier: Intended Audience :: Developers
14
- Classifier: Intended Audience :: Science/Research
15
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
- Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
- Classifier: License :: OSI Approved :: MIT License
18
- Classifier: Programming Language :: Python :: 3
19
- Classifier: Programming Language :: Python :: 3.12
20
- Requires-Python: >=3.12
21
- Description-Content-Type: text/markdown
22
- License-File: LICENSE
23
- Requires-Dist: click>=8.0
24
- Requires-Dist: requests>=2.31
25
- Requires-Dist: pyyaml>=6.0
26
- Requires-Dist: ruamel.yaml>=0.18
27
- Requires-Dist: rich>=13.0
28
- Requires-Dist: pydantic>=2.0
29
- Requires-Dist: email-validator>=2.0
30
- Requires-Dist: orchestral-ai>=1.4
31
- Requires-Dist: mcp>=1.0
32
- Provides-Extra: dev
33
- Requires-Dist: pytest>=7.0; extra == "dev"
34
- Requires-Dist: pytest-cov>=4.0; extra == "dev"
35
- Requires-Dist: black>=23.0; extra == "dev"
36
- Requires-Dist: ruff>=0.1.0; extra == "dev"
37
- Dynamic: license-file
38
-
39
1
  # toolbase
40
2
 
41
3
  The package manager and runtime for AI agent tools. Publish toolkits to
@@ -60,42 +22,54 @@ pip install toolbase
60
22
  # Install a toolkit from the registry (global by default)
61
23
  tb install arxiv-search
62
24
 
63
- # Or scope an install to the current project's manifest
64
- tb install -l arxiv-search
25
+ # Expose it to the agent (installing alone serves nothing)
26
+ tb activate arxiv-search
65
27
 
66
- # See what you have
67
- tb list
28
+ # Wire toolbase into Claude Code (writes its MCP config for you)
29
+ tb connect claude-code
68
30
 
69
- # Serve installed toolkits over MCP stdio
70
- tb serve
31
+ # See what's installed and what's active
32
+ tb list
71
33
  ```
72
34
 
73
35
  `tb` is a shorter alias for `toolbase`; both ship with the package
74
36
  and behave identically.
75
37
 
38
+ **Install, then activate.** Installing places a toolkit in the cache but
39
+ does not serve it — nothing reaches the agent until you `tb activate` it
40
+ (conda-style: install ≠ activate). `tb install -a arxiv-search` does both
41
+ in one step. Use `tb deactivate` to hide a toolkit, bundle, or tool again.
42
+
76
43
  Installs are global by default (`-g`). Use `-l` to pin a toolkit into
77
44
  the current project's `.toolbase/manifest.yaml` instead — the binary
78
45
  still lives in the shared global cache, only the pin is project-scoped,
79
46
  so a collaborator who clones the project and runs `tb install` (no
80
47
  args) gets the same toolkits at the same versions.
81
48
 
82
- To use the served toolkits in [Claude Code](https://claude.ai/code), add
83
- this to its MCP config:
84
-
85
- ```json
86
- {
87
- "mcpServers": {
88
- "toolbase": {
89
- "command": "toolbase",
90
- "args": ["serve"]
91
- }
92
- }
93
- }
49
+ **`tb connect` replaces hand-editing MCP config.** It writes the
50
+ `toolbase` server entry into [Claude Code](https://claude.ai/code)'s
51
+ config (`~/.claude.json` for user scope, `.mcp.json` for `-l` project
52
+ scope). Claude Code then spawns its own `toolbase serve` subprocess and
53
+ discovers the active profile's tools. To watch tool calls fire in real
54
+ time, run `tb logs` in another terminal. (If you'd rather wire it by
55
+ hand, the entry is `{"mcpServers": {"toolbase": {"command": "toolbase",
56
+ "args": ["serve"]}}}`.)
57
+
58
+ ### Curating what the agent sees
59
+
60
+ `tb activate` / `tb deactivate` edit the active **profile** — a named
61
+ curated set of tools. Three granularities:
62
+
63
+ ```bash
64
+ tb activate heptapod # the whole toolkit
65
+ tb activate heptapod/pythia # one bundle (a coherent group of tools)
66
+ tb activate heptapod__run_pythia # one specific tool
94
67
  ```
95
68
 
96
- Claude Code will spawn its own `toolbase serve` subprocess and
97
- discover all installed toolkits' tools. To watch tool calls fire in
98
- real time, run `tb logs` in another terminal.
69
+ Most users only ever touch the default profile via these commands. Power
70
+ users can keep several named profiles (`tb profile create paper`,
71
+ `tb connect claude-code --profile paper`) and switch between them. Run
72
+ `tb profile tools` to see the bundles and tools a toolkit offers.
99
73
 
100
74
  ---
101
75
 
@@ -127,20 +101,20 @@ publish→install round-trip on every change, install it editable:
127
101
 
128
102
  ```bash
129
103
  cd my-toolkit
130
- tb install -e . # live symlink to this source dir
131
- tb serve my-toolkit # serve it; edit tools/, restart, edits are live
104
+ tb install -e . -a # live symlink to this source dir, and activate it
105
+ # edit tools/, restart your agent session — edits are live
132
106
  ```
133
107
 
134
108
  An editable install symlinks your source into the cache and builds the
135
109
  environment there (your source tree stays clean — no `.venv` written
136
- into it). Edits to your tool source appear on the next `tb serve`. If
137
- you change dependencies, re-run `tb install -e .` to rebuild the env.
110
+ into it). Edits to your tool source appear on the next serve. If you
111
+ change dependencies, re-run `tb install -e .` to rebuild the env.
138
112
 
139
113
  For the agent-assisted authoring flow (recommended for first toolkits),
140
114
  see <https://toolbase-ai.com/docs/scaffold-with-an-agent>.
141
115
 
142
116
  For the full author guide — toolkit layout, tool conventions, skills,
143
- groups, expected_toolkits, configuration — see
117
+ bundles, expected_toolkits, configuration — see
144
118
  <https://toolbase-ai.com/docs/authoring> and
145
119
  <https://toolbase-ai.com/docs/configuration>.
146
120
 
@@ -154,15 +128,23 @@ groups, expected_toolkits, configuration — see
154
128
  `publish` — author and ship toolkits.
155
129
  - `search`, `install`, `uninstall`, `list` — manage installed toolkits.
156
130
  `install` takes `-g` (global, the default), `-l` (pin into this
157
- project), or `-e <path>` (editable, live symlink to a local source).
158
- - `serve` run installed toolkits as an MCP stdio server. Supports
159
- positional toolkit names, `--group`, `--enable-tool`,
160
- `--disable-tool`, `--dry-run`, `--call-timeout`.
131
+ project), `-e <path>` (editable, live symlink to a local source), or
132
+ `-a` (also activate). `list` takes `-v` for a per-tool served/hidden
133
+ view.
134
+ - `activate` / `deactivate` — expose or hide a toolkit, bundle
135
+ (`toolkit/bundle`), or tool (`toolkit__tool`) in the active profile.
136
+ - `connect <client>` / `disconnect <client>` — write (or remove)
137
+ toolbase in an agent client's MCP config (`claude-code` in v1).
138
+ `--list` shows where it's wired; `--clients` lists supported targets.
139
+ - `serve` — run the active profile's tools as an MCP stdio server
140
+ (`--profile`, `--dry-run`, `--call-timeout`). Normally spawned by the
141
+ client, not run by hand.
142
+ - `profile <list|show|create|edit|delete|set-default|path|tools>` —
143
+ manage named profiles (curated tool sets).
161
144
  - `setup <toolkit>` — run a toolkit's `setup.py` (`--reset`, `--check`).
162
145
  - `config <show|edit|path|set|unset|validate>` — manage per-toolkit
163
146
  config files at `~/.toolbase/config/<toolkit>.yaml`.
164
147
  - `logs` — tail the serve log with Rich coloring.
165
- - `groups` — manage named tool subsets that span toolkits.
166
148
 
167
149
  **Features:**
168
150
 
@@ -190,8 +172,11 @@ groups, expected_toolkits, configuration — see
190
172
  - **Multi-tier execution:** same-Python toolkits run in venv,
191
173
  different-Python toolkits run under conda (auto-detected). Docker
192
174
  mode coming in 3B.
193
- - **Per-tool selection:** enable or disable individual tools per
194
- serve session or persistently in `~/.toolbase/serve.yaml`.
175
+ - **Profiles:** curated tool sets assembled across toolkits at
176
+ toolkit / bundle / tool granularity, stored one-file-per-profile under
177
+ `.toolbase/profiles/`. Activate with `tb activate`; the active profile
178
+ is chosen by `default.profile` in `~/.toolbase/serve.yaml` (or a
179
+ project-level override).
195
180
  - **Skills surfacing:** a toolkit's `skills/*.md` files are
196
181
  auto-mirrored to `~/.claude/skills/` so Claude Code discovers
197
182
  them. Symlinked on POSIX for live edits, copied on Windows.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "toolbase"
7
- version = "0.1.0"
7
+ version = "0.2.0"
8
8
  description = "The community registry and CLI for AI agent toolkits - discover, share, and serve tools to AI agents over MCP"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -40,6 +40,10 @@ dependencies = [
40
40
  # Phase 3C-1 setup system relies on for state-field declaration.
41
41
  "orchestral-ai>=1.4",
42
42
  "mcp>=1.0",
43
+ # Round-trips ~/.codex/config.toml for `tb connect codex` while preserving
44
+ # the user's comments + formatting. The stdlib only reads TOML (tomllib);
45
+ # tomlkit is the writer (same role ruamel.yaml plays for our YAML).
46
+ "tomlkit>=0.12",
43
47
  ]
44
48
 
45
49
  [project.urls]
@@ -62,10 +66,14 @@ dev = [
62
66
  "black>=23.0",
63
67
  "ruff>=0.1.0",
64
68
  ]
69
+ docs = [
70
+ "mkdocs-material>=9.5",
71
+ ]
65
72
 
66
73
  [tool.setuptools.packages.find]
67
74
  where = ["."]
68
75
  include = ["toolbase*"]
76
+ exclude = ["tests*"]
69
77
 
70
78
  [tool.setuptools.package-data]
71
79
  # Ship template files (non-.py) so `toolbase init` works on PyPI installs.