anthropics / anthropics/claude-code
[BUG] Windows-MCP extension: concurrent comtypes code generation corrupts the UIAutomation cache and crashes server startup
- 主要言語
- Python
- スター
- 145k
- フォーク
- 23.1k
- PR マージ指標
- PR 指標を取得中
説明
### Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version
### What's Wrong?
The bundled Windows-MCP extension (`ant.dir.cursortouch.windows-mcp`) fails to start intermittently, because multiple `windows-mcp` processes race each other while generating the `comtypes` COM wrapper modules.
At import time, `windows_mcp/uia/core.py` calls `comtypes.client.GetModule("UIAutomationCore.dll")`. That call does not just *load* a module — it **generates and writes** Python wrapper modules into the extension venv at `.venv\Lib\site-packages\comtypes\gen\`. The desktop app launches one `windows-mcp` process per consumer (main app, Cowork, Code sessions) within seconds of each other, and this generation is not serialized across processes.
The result is that one process imports `comtypes.gen.UIAutomationClient` while another is still writing it, and dies during startup with one of two errors — both symptoms of importing a half-written module.
On 2026-09-09 at 21:33 JST, four processes started within 18 seconds; the first two crashed and only the last two came up. The app then reported that Windows-MCP tools were unavailable for Cowork and Code sessions.
### What Should Happen?
`GetModule()` should not be called concurrently from multiple processes against a shared `comtypes/gen` directory. Any of:
- Guard the call with a cross-process lock (e.g. a lock file beside `comtypes\gen\`), so the second and third processes wait rather than importing a partial module.
- Pre-generate the wrappers at extension install time and treat `comtypes\gen\` as read-only at runtime. This seems like the cleanest fix, since the generated output only depends on `UIAutomationCore.dll`.
- At minimum, catch `ImportError`/`AttributeError` around this import, regenerate once, and retry — rather than letting the exception kill the server process.
Right now a single unlucky startup takes the whole MCP server down for that session with no recovery.
### Error Messages/Logs
Three starts within 18 seconds — the first two crash, the third succeeds:
```
2026-09-09T12:33:05.018Z [Windows-MCP] [info] Initializing server... -> crash (AttributeError, below)
2026-09-09T12:33:10.304Z [Windows-MCP] [info] Initializing server... -> crash (ImportError, below)
[09/09/26 21:33:18] INFO Starting MCP server 'windows-mcp' with transport 'stdio' -> OK
[09/09/26 21:33:23] INFO Starting MCP server 'windows-mcp' with transport 'stdio' -> OK
```
Crash A — the generated module exists but is missing its top-level interface:
```
Server exiting due to unhandled exception
Traceback (most recent call last):
File "\src\windows_mcp\__main__.py", line 260, in main
_run_local_mode(transport=transport, host=host, port=port)
File "\src\windows_mcp\__main__.py", line 172, in _run_local_mode
local_mcp = _build_local_mcp()
File "\src\windows_mcp\__main__.py", line 99, in _build_local_mcp
from windows_mcp.watchdog.service import WatchDog
File "\src\windows_mcp\watchdog\service.py", line 13, in
from .event_handlers import (
File "\src\windows_mcp\watchdog\event_handlers.py", line 7, in
uia_client = _AutomationClient.instance()
File "\src\windows_mcp\uia\core.py", line 57, in instance
cls._instance = cls()
File "\src\windows_mcp\uia\core.py", line 71, in __init__
interface=self.UIAutomationCore.IUIAutomation,
AttributeError: module 'comtypes.gen.UIAutomationClient' has no attribute 'IUIAutomation'
```
Crash B — the same call site, this time failing one level deeper, inside the generated module's own import:
```
File "\src\windows_mcp\uia\core.py", line 68, in __init__
self.UIAutomationCore = comtypes.client.GetModule("UIAutomationCore.dll")
File "\.venv\Lib\site-packages\comtypes\client\_generate.py", line 240, in generate
return [_create_module(name, code) for (name, code) in codebases][-1]
File "\.venv\Lib\site-packages\comtypes\client\_generate.py", line 26, in _my_import
return importlib.import_module(fullname)
File "\.venv\Lib\site-packages\comtypes\gen\UIAutomationClient.py", line 4, in
from comtypes.gen._944DE083_8FB8_45CF_BCB7_C477ACB2F897_0_1_0 import (
ImportError: cannot import name 'IUIAutomationExpandCollapsePattern' from 'comtypes.gen._944DE083_8FB8_45CF_BCB7_C477ACB2F897_0_1_0'
```
Downstream effect:
```
2026-09-09T12:33:17.440Z [Windows-MCP] [info] Server transport closed
2026-09-09T12:33:17.484Z [Windows-MCP] [error] Couldn't start for Cowork and Code sessions. Error: Connection closed { metadata: { context: 'shared-pool', stack: undefined } }
```
Evidence that this is specifically a **write race**: both generated files carry an mtime of `21:33:17` — i.e. they were being rewritten at exactly the moment the two imports failed.
```
Name Length LastWriteTime
_944DE083_8FB8_45CF_BCB7_C477ACB2F897_0_1_0.py 315829 2026-09-09 21:33:17
UIAutomationClient.py 46305 2026-09-09 21:33:17
```
Once the third process finished generating, both files were valid again (`class IUIAutomationExpandCollapsePattern` and `IUIAutomation` both present) and the server has worked since — which is exactly why this presents as an intermittent, self-healing failure and is easy to miss.
### Steps to Reproduce
1. Install the Windows-MCP extension.
2. Force regeneration by deleting the generated cache while the app is closed:
```
%APPDATA%\Claude\Claude Extensions\ant.dir.cursortouch.windows-mcp\.venv\Lib\site-packages\comtypes\gen\
_944DE083_*.py
UIAutomationClient.py
__pycache__\
```
3. Start the desktop app in a way that spawns several `windows-mcp` processes at once (main app + Cowork + a Code session).
4. Check `%LOCALAPPDATA%\Claude\Logs\mcp-server-Windows-MCP.log`. One or more processes crash at startup with crash A or crash B.
The race window is only as long as one code generation, so this reproduces probabilistically. In my logs it hit on 2026-08-22 (1 crash, variant A) and 2026-09-09 (2 crashes, one of each variant) — roughly once every 2-3 weeks, always immediately after the gen cache needed rebuilding.
Workaround for anyone hitting this: close the app, delete the three paths above, and start the app once so a single process regenerates the cache.
### Is this a regression?
I don't know.
### Additional Information
- Claude desktop for Windows **1.49585.0.0**
- Claude Code **2.1.216**
- Windows 11 Pro build 26220
- Extension venv Python: CPython 3.13.6 (uv-managed)
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
調査の方向性
Start with windows_mcp/uia/core.py, especially the GetModule call during UIAutomationClient initialization. Reproduce the race by deleting the named comtypes\gen files and launching several Windows-MCP processes, then check the MCP server log. Done means concurrent startup no longer imports partial generated modules or crashes the server.
索引モデルが issue の本文から書いたものです。
評価
- 領域
- desktop-dev
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 活発
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 55/100