Conversation
…ment runs, not a piece an application installs
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Plugin activation can leave stale servers and skip lifecycle startup, while CLI shutdown omits extension cleanup.
Review effort: Balanced
Findings: None
What changed in this PR
Moves the MCP server from plugins/ to apps/, reflecting its role as a deployable host while preserving package metadata.
Changes:
- Relocates MCP server implementation, tests, and documentation.
- Updates CI, release, and version-bump paths.
- Documents the new
apps/directory purpose.
| File | Description |
|---|---|
RELEASE.md |
Updates release package path. |
dev/bump_version.py |
Updates MCP version-file paths. |
apps/README.md |
Defines the applications directory. |
apps/mcp-server/.gitignore |
Ignores package build metadata. |
apps/mcp-server/README.md |
Documents MCP server usage. |
apps/mcp-server/pyproject.toml |
Defines package metadata and dependencies. |
apps/mcp-server/reactor_mcp_server/__init__.py |
Exposes the public API. |
apps/mcp-server/reactor_mcp_server/__main__.py |
Provides the server CLI. |
apps/mcp-server/reactor_mcp_server/app.py |
Implements HTTP routing and lifespans. |
apps/mcp-server/reactor_mcp_server/extension.py |
Defines MCP extensions and discovery. |
apps/mcp-server/reactor_mcp_server/points.py |
Defines contribution points and events. |
apps/mcp-server/reactor_mcp_server/server.py |
Builds and caches MCP servers. |
apps/mcp-server/reactor_mcp_server/tools.py |
Defines tool contributions and extensions. |
apps/mcp-server/reactor_mcp_server/toolsets.py |
Parses and resolves toolset selections. |
apps/mcp-server/tests/test_activation_by_url.py |
Tests URL-based activation. |
apps/mcp-server/tests/test_review_follow_ups.py |
Covers prior review regressions. |
apps/mcp-server/tests/test_served_over_http.py |
Tests served HTTP behavior. |
apps/mcp-server/tests/test_tools_are_contributions.py |
Tests contribution composition. |
.github/workflows/ci.yaml |
Installs tests from the new path. |
.github/workflows/release.yaml |
Builds and releases from the new path. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…ment's default selection and own query keys, host.active_for, stdio and --toolsets on the CLI; math and geo example toolsets
…servers when a URL wakes an extension; stop the host on CLI exit; list_server_toolsets, never shadowing an extension's tool
|
Addressed the review overview's three points in a21227c:
Also renamed the optional tool to Tests: 239 passed and 1 skipped at the root; with the example installed, its 12 pass, stdio included. |
…cp_toolsets_example)
Move
plugins/mcp-server→apps/mcp-server. The MCP server is a host a deployment runs, not a plugin an application installs.PY_PACKAGES),dev/bump_version.pyandRELEASE.mdfollow the new path.apps/README.mdsays what the folder is for.Toolsets, first class
The generic parts of what the private Datalayer gateway needed, moved into the foundation:
Toolset.titleandToolset.instructions. A toolset's instructions go into the server's instructions only when it is active (host.instructions_for).list_toolsetstool (build_host(..., list_toolsets_tool=True)). It gives the same answer as/toolsets, for a model already in a session or a stdio client. Read-only, and off by default in code.default_selectiononcreate_mcp_app/ToolsetRouter: what a URL naming no toolset gets.ignore_query_keys: query keys the deployment reads itself (e.g.scopes=), which are no longer taken for unknown toolset names.parse_selectionandselection_from_scopetakeignore=.host.active_for(selection): what a request is about to get, without building. It answers correctly foronly=, defaults andwithout=, where checking the named flags does not.host.describe(selection): the one payload behind/toolsetsandlist_toolsets. It now includes each toolset'stitle.--transport stdio,--toolsets(the default selection, and over stdio the whole selection),--ignore-query-key, and--list-toolsets-tool(on by default).The gateway's in-session enable/disable was not ported on purpose: toolsets are read once per connection, as the docs explain.
Example
examples/toolsetsis one installable distribution with two extensions:math(add,multiply) is on by default and has instructions.geo(get_capital_of_country,get_country_of_capital) is opt-in with anonToolset:geoactivation event.It is tested in process, over HTTP with a real client, and over stdio through the entry points. CI installs it.
Docs
toolsets.md: instructions,list_toolsets, what a deployment decides, andactive_for.serving.md: the new CLI options and stdio.host.mdandindex.mdare updated.example-toolsets.md.Tests: 231 passed from the root (80 in the app, 12 in the example).