MCP-native tool architecture, Markdown-only skills registry, and pull progress reporting#3
Open
GVonB wants to merge 8 commits into
Open
MCP-native tool architecture, Markdown-only skills registry, and pull progress reporting#3GVonB wants to merge 8 commits into
GVonB wants to merge 8 commits into
Conversation
Add team/mcp package with MCPToolBus (background asyncio loop thread, single manager task owning the AsyncExitStack), MemberToolset (per-member enablement + output truncation), and ToolInfo. Bump to 0.18.0, Python 3.10, add mcp>=1.9,<2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
team/mcp/builtin/{code,web,workspace,memory,beliefs,decisions,federation,expert}.py
with BuiltinContext + BUILTIN_SERVERS registry. Typed keyword-arg signatures
replace the old string-body parsing; sandbox helpers move into code.py.
Schema regression test pins all 25 generated schemas. tools.py stays until the
Phase 4 cutover.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Config: MCPServerConfig + mcp_servers, extra_context (replaces Markdown skills), qualified server/tool pattern validation, config.expand_env(). Remove skills fields. Cutover: member.py drives both agentic loops through MemberToolset (text mode via team.mcp.textmode, native mode via toolset schemas) — fixes the native-mode dropped peers bug. orchestrator.py owns the bus lifecycle, builds per-member BuiltinContext, connects external mcp_servers (TEAM_WORKSPACE injected), and carries the moved host-Ollama sandbox security warning. personas.py renders the tool protocol from ToolInfo. Tests rewired to the bus (conftest fixtures + federation KV shim). tools.py/skills.py remain until Phase 5. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Delete team/tools.py, team/skills.py, tests/test_tools.py, tests/test_skills.py. Extension scaffolder (cli.py forge) and team/extension.py swap the skills/ slot + team.skills entry-point group for a servers/ slot + team.mcp_servers group (transport: entry_point). bridge_server capabilities advertise tools + mcp_servers instead of skills. Rewire test_plugin_system to _resolve_entry_point, update test_forge/test_extension. Federation tests route through a KV-body shim. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace repo skills/ with examples/mcp/team_helpers_server.py (the 4 helper skills as one stdio FastMCP server) and examples/context/*.md referenced via extra_context. Add examples/mcp_team.yaml. New tests: test_example_helpers_server (bus-driven) and test_mcp_external_stdio (real subprocess, reaps child on stop). Bump _version to 0.18.0. Rewrite README tool/skill chapters + AGENTS.md for the MCP-native architecture; add CHANGELOG.md with breaking changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… mode Code review follow-ups: - Built-in tools ran inline on the single bus event loop (FastMCP does not offload sync tool fns), so a slow tool (run_bash, or federation delegate_task waiting up to 600s) froze the loop and stalled every other member's concurrent tool calls — a regression of the per-member parallelism the old design had. Add an @offload decorator (anyio.to_thread) to all 25 built-in tools; functools.wraps preserves the FastMCP-generated schema. - render_system_prompt injected the text-mode fenced-block protocol even for native-mode members, telling native models to emit blocks that the native path never parses. Gate the section on tool_mode. - Bound external MCP server connects (asyncio.wait_for inside the manager task) so a server that never completes initialize/list_tools is marked dead instead of wedging startup and shutdown; snapshot _conns iteration to avoid a dict-mutation race with stop(); treat timeout=0 as a real (not falsy) bound. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`ensure_image()` blocked silently on `client.images.pull()` with no progress and no timeout, and `OllamaClient.ensure_model()` discarded the streamed pull events it already received — so a slow or genuinely large (multi-GB) first-run pull was indistinguishable from a hang. container.py now pulls via the low-level streaming API and aggregates layer progress; ollama_client.py forwards pull events instead of dropping them; member.py/orchestrator.py thread an optional on_progress callback through prepare()/up(); cli.py's `_up_with_progress` wires it into the existing status spinner for `up`, `run`, and `test`. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Prior investigation against the upstream cumbof/team repo and its published PyPI wheel confirmed the bundled skills/ examples never shipped in the package (only the loader did), and every one of upstream's own documented skills is already faithfully preserved under the new architecture (3 markdown files byte-identical in examples/context/, 4 python skills' tool names reproduced in examples/mcp/team_helpers_server.py). The one real gap: the team.skills entry-point registry that let a third-party package register a reusable, installable context bundle by name had no replacement - extra_context: only accepted local relative paths. team/skills.py is a new, much smaller module covering only that gap: a name -> Markdown file resolver via the team.skills entry-point group (a registered entry's module sets SKILL_FILE to its bundled .md path). Python tool-loading, remote-URL fetching, and checksum verification stay retired in favor of MCP servers. member.py's _load_extra_context() now falls back to this registry when an extra_context: entry isn't a local file. extension.py and cli.py's forge scaffold a matching skills/ slot alongside servers/, with a `skills` subcommand listing a package's registered Markdown bundles (mirroring `servers` for MCP). Also fixes a pre-existing cosmetic bug in the servers/skills CLI hints where an escaped \n printed literally instead of a newline. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
team/tools.py) into 8 in-process MCP servers underteam/mcp/builtin/(workspace, code, memory, beliefs, decisions, federation, expert, web), wired through a new MCP tool bus that both text-mode (fenced-block) and native-mode (LLM function-calling —tool_mode: nativealready existed pre-migration) agentic loops share.skills.py(arbitrary local/remote/entry-point-registered Python tool plugins, including itsexec()-based and remote-URL loader) in favor of MCP servers — either external (mcp_servers:, stdio/http) or in-process (team.mcp_serversentry-point group).team.skillsstill exists as an entry-point group, but now resolves only to Markdown context bundles (via aSKILL_FILE-pointing wrapper module), consumed throughextra_context:alongside plain relative paths.team forgescaffolds a matchingskills/slot next toservers/, and the generated extension CLI gets askillssubcommand mirroringservers.team-corePyPI wheel and this repo: the bundledskills/example directory never shipped in the package (only the loader module did), and every documented example skill is faithfully preserved under the new architecture — the 3 markdown files are byte-identical inexamples/context/, and the 4 Python skills' tool names all reappear inexamples/mcp/team_helpers_server.py.team up/run/test), replacing a silent blocking spinner that was indistinguishable from a hang on large first-time pulls.Test plan
pytest -q -m "not integration"— 912 passedteam checkpreflight against a real Docker Desktop instanceteam up/team runagainst real Ollama containers, confirming progress line updates during image/model pullstool_mode: nativeexecutes real tool calls (vs. text-mode's fenced-block parsing) againstllama3.2:3bvia a live smoke-test runteam forge, installed in a clean venv, ran its scaffold tests, confirmedteam <ext> skills/serversboth work)🤖 Generated with Claude Code