Skip to content

Commit 993f30d

Browse files
committed
G3: 權限一致與成本量測
1 parent f2a35e8 commit 993f30d

25 files changed

Lines changed: 569 additions & 58 deletions

‎CHANGELOG.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ notes are recorded in `docs/updates/` (index: `docs/updates/README.md`).
66
The format follows Keep a Changelog. Until 1.0, breaking changes are permitted
77
only when documented here with a migration path.
88

9-
New entries go under `## Unreleased`. The version bump on `main` is automated
9+
New entries go under `## Unreleased
10+
11+
- MCP adds mode/profile/page-size stdio flags and measured disclosure costs. Readonly now rejects mutating custom-registry calls; concurrent workers preserve accepted client roots and capabilities after session termination.`. The version bump on `main` is automated
1012
and does not touch this file, so after a release tag appears, move the entries
1113
it shipped into a `## [x.y.z] - date` section of their own; the tag's
1214
`CHANGELOG.md` shows which ones those are (`git show vX.Y.Z:CHANGELOG.md`).

‎Progress.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
核准設計:[跨平台自動化與 GUI 改版](docs/superpowers/specs/2026-10-02-platform-gui-modernization-design.md)。
1010
實作計畫:[分階段交付計畫](docs/superpowers/plans/2026-10-02-modernization-index.md),已核准,依序實作。
1111
現有 `[Answer]` 決策沿用;後續交付包含 E–H 與完整整合驗收。
12-
從 G3 接續原有計畫;不額外新增付費型功能。既有 API 介面及相關修正繼續,
12+
從 H1 接續原有計畫;不額外新增付費型功能。既有 API 介面及相關修正繼續,
1313
目前以本機/離線測試驗證;缺少真實 API 條件的既有項目保留待驗證。
1414
正向實體裝置擷取、GNOME/KDE 授權與鍵態恢復仍列 H3;
1515
歷史 Qt 原生崩潰的後續追蹤仍保留在下列驗收項目。
1616
WDA 專用 endpoint、外部 client/別名競態、未知建立回覆及 SDK 擷取後的
1717
App session 接續/恢復仍列 H3;受控閒置檢查不能冒充原生互斥證據。
18-
G3 的 MCP 權限一致與成本量測及 H1–H3 的型別、文件與整合驗收繼續依序實作。
18+
H1–H3 的型別、文件與整合驗收繼續依序實作。
1919
H3 仍需自有錄製的原生輸出內容、實體鍵態恢復及外部輸入 client 競態證據;
2020
受控 GUI 所有權、重試、container 關閉與 widget 刪除不代表實體恢復或有效錄影。
2121

‎README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,3 +1078,5 @@ cursor or real session changes. GUI Tools adds mode/profile preview, enable/disa
10781078
comma-separated names and next page Actions. Static preview names share the name field.
10791079
Configure the real deployment with the environment settings above. More details:
10801080
[session contract](docs/MCP_DISCOVERY.md).
1081+
1082+
MCP stdio also accepts `--tool-mode full|progressive|static`, `--tool-profile ac_screenshot,ac_probe_capabilities` and `--tool-page-size 1..100`; explicit flags override corresponding deployment settings. `--list-tools` still prints the complete authorized catalog for inspection. Example: `python -m je_auto_control.utils.mcp_server --tool-mode static --tool-profile ac_screenshot`. Discovery changes availability only: execution still checks RBAC, schema, roots/env, rate limits and confirmation. Readonly rejects mutating calls from custom registries too. Concurrent workers retain accepted identity, roots and capabilities across session termination. [Measured local schema cost](benchmarks/results/mcp-discovery-g3/report.json): full747 /363544bytes versus core6 /2506bytes; local handshake/list medians37.91/9.56ms, search9.78/9.65ms (five samples, no network).

‎README/README_zh-CN.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,3 +900,5 @@ Tools → MCP 工具发现提供可取消的 Actions,在本机搜索或查看
900900
工具的完整结构,不保留 cursor、不修改真实 session。GUI Tools 增加模式/静态清单预览、
901901
逗号分隔名称的启用/停用及下一页 Actions;静态清单也使用名称字段。
902902
真正部署请使用上述环境设置。详见[session 契约](../docs/MCP_DISCOVERY.md)。
903+
904+
MCP stdio 支持 `--tool-mode full|progressive|static`、`--tool-profile ac_screenshot,ac_probe_capabilities` 和 `--tool-page-size 1..100`;参数覆盖对应部署设置。`--list-tools` 仍输出完整已授权目录供检查。例如:`python -m je_auto_control.utils.mcp_server --tool-mode static --tool-profile ac_screenshot`。披露只改变可见列表,执行仍检查 RBAC、schema、roots/env、限流与确认。只读也拒绝自定义 registry 的修改调用;后台任务在 session 终止后保留原请求身份、roots 与 capabilities。[本机测量](../benchmarks/results/mcp-discovery-g3/report.json):完整747个/363544bytes,核心6个/2506bytes;本机握手及列表中位数37.91/9.56ms,搜索9.78/9.65ms(五次样本,未含网络)。

‎README/README_zh-TW.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,3 +901,5 @@ Tools → MCP 工具探索提供可取消的 Actions,在本機搜尋或查看
901901
工具的完整結構,不保留 cursor、不修改真實 session。GUI Tools 增加模式/靜態清單預覽、
902902
以逗號分隔名稱的啟用/停用及下一頁 Actions;靜態清單也使用名稱欄位。
903903
真正部署請使用上述環境設定。詳見[session 契約](../docs/MCP_DISCOVERY.md)。
904+
905+
MCP stdio 支援 `--tool-mode full|progressive|static`、`--tool-profile ac_screenshot,ac_probe_capabilities` 與 `--tool-page-size 1..100`;旗標覆寫對應部署設定。`--list-tools` 仍輸出完整已授權目錄供檢查。例如:`python -m je_auto_control.utils.mcp_server --tool-mode static --tool-profile ac_screenshot`。揭露只改變可見清單,執行仍檢查 RBAC、schema、roots/env、限流與確認。唯讀也拒絕自訂 registry 的修改呼叫;背景工作在 session 終止後保留原請求身分、roots 與 capabilities。[本機量測](../benchmarks/results/mcp-discovery-g3/report.json):完整747個/363544bytes,核心6個/2506bytes;本機交握及清單中位數37.91/9.56ms,搜尋9.78/9.65ms(五次樣本,未含網路)。

‎architecture.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,3 +469,5 @@ its original default tools/list shape; progressive/static modes and explicit pag
469469
are deployment settings. Cursor signatures are per owner, stable snapshots have
470470
bounded lifetime/count, and standing HTTP notification writers are looked up from
471471
live session metadata. Preview surfaces never mutate real serving sessions.
472+
473+
G3 concurrent MCP workers retain accepted transport identity, capabilities and bounded roots even after session drop. ContextVar authorization/view leases remain intact. Readonly is checked at execution for custom registries; mode/profile/page-size flags preserve full defaults. Local cost artifacts use the same registry/policy.

‎architecture_explore.md‎

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ iOS(WebDriverAgent)。核心能力是滑鼠/鍵盤控制、影像辨識、
1919

2020
| 指標 | 數值 |
2121
| --- | ---: |
22-
| Python 模組總數(含周邊子專案) | 1,216 |
23-
| 程式碼總行數 | 177,148 |
22+
| Python 模組總數(含周邊子專案) | 1,218 |
23+
| 程式碼總行數 | 177,329 |
2424
| `je_auto_control/utils/` 子套件數 | 311 |
2525
| `AC_*` 動作指令數(`known_commands()` 實測) | 822 |
2626
| 套件門面 `__all__` 公開名稱數 | 1,403 |
2727
| GUI 分頁數(`main_widget` 註冊) | 50 |
2828
| MCP 工具數(`build_default_tool_registry()` 實測) | 747 |
29-
| `test_*.py` 測試檔/測試函式 | 771 / 8,010 |
29+
| `test_*.py` 測試檔/測試函式 | 772 / 8,016 |
3030
| 範例腳本 | 31 |
3131

3232
**技術基線**:Python ≥ 3.10、MIT 授權、必要相依只有 `je_open_cv`/`opencv-python`/`pillow`/`mss`/
@@ -537,7 +537,7 @@ socket server 有 8 MiB 讀取上限與 30 秒 handler timeout。
537537

538538
### 5.4.9 AI / Agent / LLM
539539

540-
> 13 個套件、約 25,014 行。
540+
> 13 個套件、約 25,088 行。
541541
542542
| 模組 | 行數 | 職責 |
543543
| --- | ---: | --- |
@@ -550,7 +550,7 @@ socket server 有 8 MiB 讀取上限與 30 秒 handler timeout。
550550
| `utils/cua_action/` | 204 | 標準化 computer-use 動作結構(Anthropic/OpenAI → `AC_*`) |
551551
| `utils/llm/` | 365 | 自然語言 → action list 規劃器 + Anthropic/null 後端 |
552552
| `utils/mcp_registry/` | 97 | MCP registry 資訊清單產生;預設 io.github.integration-automation/autocontrol,專案 Integration-Automation/AutoControlGUI |
553-
| `utils/mcp_server/` | 20,597 | **無頭 MCP 伺服器**(16K LOC,預設註冊 747 個工具=728 個 `ac_*` + 19 個別名):stdio + HTTP 傳輸、工具工廠與處理器、資源、prompt、稽核、限流、外掛熱重載 |
553+
| `utils/mcp_server/` | 20,671 | **無頭 MCP 伺服器**(16K LOC,預設註冊 747 個工具=728 個 `ac_*` + 19 個別名):stdio + HTTP 傳輸、工具工廠與處理器、資源、prompt、稽核、限流、外掛熱重載 |
554554
| `utils/tool_use_schema/` | 195 | 把 `AC_*` 指令匯出成 Claude/OpenAI 的 tool-use schema |
555555
| `utils/trajectory_eval/` | 132 | agent 軌跡評估:依評分規準為一次執行打分 |
556556
| `utils/vision/` | 550 | VLM 元素定位器(依描述找元素)+ Anthropic/OpenAI/null 後端 |
@@ -756,7 +756,7 @@ socket server 有 8 MiB 讀取上限與 30 秒 handler timeout。
756756
| `input_owner.py` | 133 | Qt-free panel input ownership; cancelled work only releases its own native holds. |
757757
| `cleanup_jobs.py` | 69 | Internal headless cleanup jobs retaining failed owned callbacks for retry. |
758758

759-
#### `utils/mcp_server/`(20,597 行,747 個工具)— 最大子系統
759+
#### `utils/mcp_server/`(20,671 行,747 個工具)— 最大子系統
760760

761761
| 檔案 | 行數 | 職責 |
762762
| --- | ---: | --- |
@@ -772,7 +772,8 @@ socket server 有 8 MiB 讀取上限與 30 秒 handler timeout。
772772
| `tools/_handlers_input.py` | 224 | 同一種 adapter,輸入主題:滑鼠、鍵盤、虛擬手把(ViGEm)。 |
773773
| `tools/_handlers_screen.py` | 331 | 同一種 adapter,螢幕主題:擷取、像素、影像與文字搜尋、螢幕錄影。 |
774774
| `tools/_handlers_system.py` | 575 | 同一種 adapter,桌面工作階段:視窗、行程與 shell、開檔、閒置與睡眠、音量、鎖定、輸入法狀態、欄位驗證與重試、色彩對比、變更排序、元件分類、剪貼簿。 |
775-
| `_tool_calls.py` | 131 | 授權後執行工具、取消與錯誤處理;每筆稽核攜帶 user_id。 |
775+
| `_worker_scope.py` | 45 | Bind accepted MCP transport identity and policy to concurrent tool workers. |
776+
| `_tool_calls.py` | 139 | 授權後執行工具、取消與錯誤處理;每筆稽核攜帶 user_id。 |
776777
| `_http_auth.py` | 50 | HTTP bearer 個人驗證、舊 token 相容、SSE session 擁有者檢查。 |
777778
| `tools/_factories_journal.py` | 24 | 三項動作日誌工具與路徑 metadata;預覽唯讀,錄製經 executor dispatch。 |
778779
| `tools/_factories_rbac.py` | 35 | 五個 admin-only 使用者管理工具;回傳資料不含 token 或 hash。 |
@@ -784,7 +785,7 @@ socket server 有 8 MiB 讀取上限與 30 秒 handler timeout。
784785
| `tools/_handlers_executor_bridge.py` | 1,429 | 252 個純委派(中位數 3 行,最長的 16 行全是參數簽章):每個都是 `from action_executor import _x` 再 `return _x(...)`,沒有分支邏輯。超過 750 行,理由記在 `Progress.md` 的豁免表(再切只能照 MCP 工廠領域分,會把同一種委派散進十幾個沒有語意邊界的檔)。 |
785786
| `tools/_handlers_locators.py` | 436 | 同一種 adapter,定位主題:無障礙樹、智慧等待、自我修復、螢幕觀察、座標空間、視覺與 OCR、影像去重、元件倉庫、A/B 定位。 |
786787
| `tools/_handlers_operations.py` | 629 | 同一種 adapter,營運主題:agent 與其記憶/追蹤、治理與合規、成本與遙測、失敗掛鉤、看門狗、速率限制、檢查點、核可、產物與資產、測試選擇與分片、佇列與 saga。 |
787-
| `server.py` | 730 | JSON-RPC 2.0 over stdio 的最小 MCP 伺服器:連線範圍狀態、行內/併發分派、工具與 resource/prompt 處理器;握手時代的方法表(`_run_method`),兩個協定時代的逐請求分派在 `_stateless.py`。 |
788+
| `server.py` | 720 | JSON-RPC 2.0 over stdio 的最小 MCP 伺服器:連線範圍狀態、行內/併發分派、工具與 resource/prompt 處理器;握手時代的方法表(`_run_method`),兩個協定時代的逐請求分派在 `_stateless.py`。 |
788789
| `http_transport.py` | 705 | MCP 的 HTTP 傳輸;宣告 2026-07-28 的請求走 `_http_stateless.py` 的標頭規則,不發 session。 |
789790
| `_http_stateless.py` | 185 | MCP 2026-07-28 在 Streamable HTTP 上的規則:`MCP-Protocol-Version`/`Mcp-Method`/`Mcp-Name` 必須與 body 相符(`=?base64?…?=` 先解碼),不符是 400+`HeaderMismatch`;版本與中繼資料錯誤 400、未知方法 404。純函式,由 `http_transport.py` 回覆。 |
790791
| `http_sessions.py` | 258 | MCP 的 HTTP 傳輸用的 session 身分:`Mcp-Session-Id` 註冊表,以及每個 session 那條常駐的 server→client SSE 串流。 |
@@ -802,10 +803,10 @@ socket server 有 8 MiB 讀取上限與 30 秒 handler timeout。
802803
| `tools/_validation.py` | 122 | MCP 工具用到的 JSON Schema 子集驗證器。 |
803804
| `tools/plugin_tools.py` | 89 | 把外掛載入的 `AC_*` callable 包成 `MCPTool`。 |
804805
| `log_bridge.py` | 118 | 把 Python logging 記錄橋接成 MCP `notifications/message`;2026-07-28 的請求只收到自己設了 `logLevel` 時產生的記錄。 |
805-
| `audit.py` | 97 | MCP 工具呼叫稽核記錄。 |
806+
| `audit.py` | 98 | MCP 工具呼叫稽核記錄。 |
806807
| `context.py` | 80 | 傳給 opt-in 工具處理器的每次呼叫上下文。 |
807808
| `rate_limit.py` | 48 | 工具呼叫的 token bucket 限流。 |
808-
| `__main__.py` | 92 | `je_auto_control_mcp` console script 進入點。 |
809+
| `__main__.py` | 122 | `je_auto_control_mcp` console script 進入點。 |
809810

810811
#### `utils/remote_desktop/`(13,884 行/60 檔)
811812

@@ -1123,7 +1124,7 @@ GUI 是**選用 extra**(`pip install je_auto_control[gui]`,PySide6 + qt-mate
11231124
| `ci_templates/.gitlab-ci.yml` | — | 供使用者專案複製的 GitLab CI 範本。 |
11241125
| `docs/` | Sphinx(`API`/`Eng`/`Zh`/`getting_started`) | Read the Docs 文件。 |
11251126
| `architecture_diagram/` | drawio + png | 既有的架構圖原始檔。 |
1126-
| `test/` | `unit_test/headless`(主要)、`unit_test/flow_control`、`integrated_test`、`gui_test`、`manual_test`、`verify`、`test_source` | 771 個 `test_*.py`/8,010 個測試函式。**注意**:`test/unit_test/` 下的 `*_test.py` 是會真的驅動滑鼠鍵盤的手動示範腳本,因此 `pyproject.toml` 把 `python_files` 釘成 `test_*.py`。`unit_test/headless/conftest.py` 有一個 autouse fixture,每個測試結束都沖掉 Qt 排隊中的 `deleteLater()`——不沖會讓殘留的 widget 在後面某個不相干的測試裡被銷毀,曾經整個直譯器 `__fastfail`。`test_doc_counts.py` 守住文件引用的指令/工具/子套件/範例數,`test_doc_line_counts.py` 守住所有行數(`--fix` 可一次重新產生)。 Folder Sync 正向案例等待實際 sender,防回送先等待實際輪詢處理,保留內容與次數斷言。 `verify/native_debugger.py` 以有時限的 gdb/lldb 包裝原有 coverage 命令,保留 target 退出碼與原生堆疊。 `verify/macos_verify.py` 是在真的 `macos-14` runner 上量測 TCC 到底允許什麼的探針(macOS 是唯一沒有容器可用的支援平台),不被 pytest 收集。 |
1127+
| `test/` | `unit_test/headless`(主要)、`unit_test/flow_control`、`integrated_test`、`gui_test`、`manual_test`、`verify`、`test_source` | 772 個 `test_*.py`/8,016 個測試函式。**注意**:`test/unit_test/` 下的 `*_test.py` 是會真的驅動滑鼠鍵盤的手動示範腳本,因此 `pyproject.toml` 把 `python_files` 釘成 `test_*.py`。`unit_test/headless/conftest.py` 有一個 autouse fixture,每個測試結束都沖掉 Qt 排隊中的 `deleteLater()`——不沖會讓殘留的 widget 在後面某個不相干的測試裡被銷毀,曾經整個直譯器 `__fastfail`。`test_doc_counts.py` 守住文件引用的指令/工具/子套件/範例數,`test_doc_line_counts.py` 守住所有行數(`--fix` 可一次重新產生)。 Folder Sync 正向案例等待實際 sender,防回送先等待實際輪詢處理,保留內容與次數斷言。 `verify/native_debugger.py` 以有時限的 gdb/lldb 包裝原有 coverage 命令,保留 target 退出碼與原生堆疊。 `verify/macos_verify.py` 是在真的 `macos-14` runner 上量測 TCC 到底允許什麼的探針(macOS 是唯一沒有容器可用的支援平台),不被 pytest 收集。 |
11271128

11281129
---
11291130

@@ -1228,7 +1229,7 @@ socket 預設綁 `127.0.0.1`;資源一律用 `with`。
12281229
| 層/子系統 | 檔案數 | 行數 |
12291230
| --- | ---: | ---: |
12301231
| `gui/` | 127 | 33,929 |
1231-
| `utils/mcp_server/` | 53 | 20,597 |
1232+
| `utils/mcp_server/` | 54 | 20,671 |
12321233
| `utils/remote_desktop/` | 60 | 13,884 |
12331234
| `utils/executor/` | 13 | 10,177 |
12341235
| `utils/usb/` | 17 | 4,666 |
@@ -1248,7 +1249,7 @@ socket 預設綁 `127.0.0.1`;資源一律用 `with`。
12481249
| `autocontrol-lsp/` | 8 | 744 |
12491250
| `utils/hotkey/` | 7 | 863 |
12501251
| 其餘模組(約 286 個 `utils/` 子套件 + `android/`/`ios/`/周邊小工具) | 737 | 62,819 |
1251-
| **總計** | **1,204** | **176,644** |
1252+
| **總計** | **1,205** | **176,718** |
12521253

12531254

12541255
Crypto optional-dependency failures use CryptoDependencyError from utils/exception:
@@ -1341,3 +1342,5 @@ unchanged; progressive/static and explicit paging are deployment settings. Sessi
13411342
enable/disable/state handlers use the current view; preview API/AC/Builder/MCP and
13421343
GUI manipulate isolated metadata only. _tool_calls.prepare_tool_call retains the
13431344
existing validation pipeline behind the server compatibility method.
1345+
1346+
G3 `_worker_scope` preserves accepted thread-local connection/capabilities/path policy alongside ContextVar authorization/view leases. Readonly call checks also cover custom registries; CLI flags retain default full behavior. Local benchmarks retain version/hash and raw samples.

0 commit comments

Comments
 (0)