feat(mcp): extension activation, prompt section, lifecycle and /mcp

Spec: /mcp shows no pid (the SDK doesn't expose it) and never shows env values; the prompt section follows the server's own tools; the built-in collision check covers inactive built-ins.
This commit is contained in:
EugeneTes
2026-09-26 20:49:21 +02:00
parent 83ad683bd1
commit 2c5d5dfcb4
5 changed files with 597 additions and 5 deletions

View File

@@ -172,8 +172,9 @@ callTimeoutSeconds: 120, startupTimeoutSeconds: 120 (the first npx run downloads
process environment hook, which keeps `PLAYWRIGHT_BROWSERS_PATH`, so it applies. In the container that's `/opt/ms-playwright`, set in the image. A missing browser
shows up as an error result from the first `browser_*` call (the MCP server itself starts fine), and the model
reports it.
- `PromptSection` (added through `BeforeAgentStartEvent` → `SystemPromptOptions.Sections["browser"]` while any
`browser_*` tool is active):
- `PromptSection` (added through `BeforeAgentStartEvent` → `SystemPromptOptions.Sections["browser"]` while any of
the server's registered tools is active (for the preset, the `browser_*` tools); a server's `promptSection` works
the same way under its own name):
```
## Browser
@@ -221,7 +222,8 @@ provider's aliasing:
- The MCP server is always called with the original `mcpName`.
- Collisions with other tools follow the existing `ToolRegistry` rules. An MCP tool named like a built-in
(`read`, `bash`, ...) would **replace** it, so `McpExtension` refuses to register an exposed name that
`api.GetAllTools()` already reports with source `built-in`. It logs a warning suggesting a `toolPrefix`. A clash
`api.GetAllTools()` already reports with source `built-in`. It logs a warning suggesting a `toolPrefix`. The
built-in check runs against `GetAllTools()` at activation, so it covers every built-in, active or not. A clash
with another extension's tool is already ignored and recorded by the runner. Between two MCP servers, the first
configured wins, and a warning names both.
- Through the Claude Code provider these tools reach the model as `mcp__volcanic__<exposedName>`. Nothing else is
@@ -302,8 +304,11 @@ One per server per extension instance (that is, per session):
### 9. The command — `/mcp`
Lists each configured server for this session: state (`not started` / `running pid N` / `failed: <reason>` /
`disabled`), number of tools, last error, and the stderr tail with `/mcp <name>`. It costs no model call.
Lists each configured server for this session with its state and number of tools. It costs no model call. States:
`not started` / `running` / `failed: <reason>` / `disabled` (the preset adds `(set PLAYWRIGHT_ENABLED=true)`). The SDK
doesn't expose a live server's pid, so `/mcp` shows none. `/mcp <name>` shows the unexpanded command, the names (never
the values) of its `env` entries, server info, tools, the last error and the stderr tail. With a UI the output is a
notification; without one it is a `mcp` custom message appended without a turn.
`/mcp restart <name>` disposes the session process so the next call starts fresh (clears a wedged browser).
### 10. Host wiring (Telegram)