From 9250da767e2368cb538662b34fbc3c3b1a694276 Mon Sep 17 00:00:00 2001 From: huangzesen Date: Fri, 17 Jul 2026 16:08:14 -0700 Subject: [PATCH] docs(mcp): retire stale addon setup guidance --- src/lingtai/tools/mcp/manual/SKILL.md | 6 ++++ .../mcp/manual/reference/curated-addons.md | 2 +- tests/test_mcp_capability.py | 35 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/lingtai/tools/mcp/manual/SKILL.md b/src/lingtai/tools/mcp/manual/SKILL.md index 1295f8b70..082326ed4 100644 --- a/src/lingtai/tools/mcp/manual/SKILL.md +++ b/src/lingtai/tools/mcp/manual/SKILL.md @@ -49,6 +49,12 @@ The `mcp` capability is your interface to Model Context Protocol (MCP) servers This is the router. Detail lives in `reference/`. Load only what you need. +## TUI command boundary + +`/addon` is retired; never recommend it. `/mcp` is the only current TUI command for this surface, and it is read-only config/status inspection. It is **not** a guided setup or configuration screen; never describe it as one or redirect a human there for addon setup. + +For curated addon setup, load `reference/curated-addons.md` (the curated-addon setup contract) and the relevant provider docs before editing. Make exact configuration changes only within explicit human authorization, using that contract's four-step mechanism; do not redirect the human to a nonexistent or setup-like TUI screen. + ## Three states of an MCP For any MCP server, relative to this agent: diff --git a/src/lingtai/tools/mcp/manual/reference/curated-addons.md b/src/lingtai/tools/mcp/manual/reference/curated-addons.md index 070d84dd0..76b0ec7de 100644 --- a/src/lingtai/tools/mcp/manual/reference/curated-addons.md +++ b/src/lingtai/tools/mcp/manual/reference/curated-addons.md @@ -12,7 +12,7 @@ LingTai's first-party email and chat integrations. They now ship inside the `lin ## The four-step setup -1. **Read the curated setup docs before editing config.** The table below gives the registry/module/env/config-file names. If exact provider-specific fields are needed, inspect the shipped module resources or the catalog `homepage` for that addon. Field names like `email_password` (imap), `bot_token` (telegram), `app_id`/`app_secret` (feishu), and gewechat host (wechat) are addon-specific; do not guess them from memory. +1. **Read the curated setup docs before editing config.** The table below gives the registry/module/env/config-file names. If exact provider-specific fields are needed, inspect the shipped module resources or the catalog `homepage` for that addon. Field names like `email_password` (imap), `bot_token` (telegram), `app_id`/`app_secret` (feishu), and gewechat host (wechat) are addon-specific; do not guess them from memory. Make exact configuration changes only within explicit human authorization; this contract is the setup procedure, not a TUI setup screen. 2. **Add the addon to `init.json`.** Append the registry name to the top-level `addons:` list, then add an `mcp.` activation entry with the subprocess spec from this table or the addon docs: diff --git a/tests/test_mcp_capability.py b/tests/test_mcp_capability.py index 41b53007c..24ada1a85 100644 --- a/tests/test_mcp_capability.py +++ b/tests/test_mcp_capability.py @@ -8,6 +8,7 @@ from __future__ import annotations import json +import re import sys from pathlib import Path from unittest.mock import MagicMock @@ -295,6 +296,40 @@ def test_mcp_show_action_returns_health_snapshot(tmp_path): assert "mcp_manual" in manual and manual["mcp_manual"] # umbrella SKILL.md body +def test_mcp_manual_preserves_tui_command_boundary(): + """The shipped MCP router must not route setup to a retired TUI surface.""" + manual_root = Path(__file__).resolve().parents[1] / "src/lingtai/tools/mcp/manual" + router = (manual_root / "SKILL.md").read_text(encoding="utf-8") + curated = (manual_root / "reference/curated-addons.md").read_text(encoding="utf-8") + + assert re.search(r'/addon.{0,120}(?:retired|never recommended)', router, re.I | re.S) + assert not re.search(r'(?:use|open|run|launch|recommend)[ \t]+`?/addon', router, re.I) + assert re.search(r'/mcp.{0,140}only current TUI command', router, re.I | re.S) + assert re.search(r'/mcp.{0,180}read[- ]only', router, re.I | re.S) + assert re.search( + r"/mcp.{0,240}(?:not|isn't).{0,90}(?:guided[ \t]+)?(?:setup|configuration)", + router, + re.I | re.S, + ) + assert re.search( + r'curated addon setup.{0,220}(?:curated-addons.*contract|provider docs)', + router, + re.I | re.S, + ) + assert re.search(r'explicit human authorization', router, re.I) + + # Keep the existing four-step mechanism in the owning reference while the + # router adds only the TUI boundary and authorization rule. + assert re.search(r'## The four-step setup', curated) + for step in ( + r'1[.].*read.*setup docs', + r'2[.].*init[.]json', + r'3[.].*config file', + r"4[.].*system[(]action=.*refresh.*[)]", + ): + assert re.search(step, curated, re.I | re.S) + + def test_mcp_show_unknown_action_returns_error(tmp_path): agent, workdir = _mk_agent(tmp_path, addons=["imap"]) handler = agent._tool_handlers.get("mcp")