anthropics / anthropics/claude-code
[BUG] Windows-MCP extension: concurrent comtypes code generation corrupts the UIAutomation cache and crashes server startup
- Ngôn ngữ chính
- Python
- Star
- 145k
- Fork
- 23.1k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
### 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)
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Hướng nghiên cứu
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.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Lĩnh vực
- desktop-dev
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Sôi nổi
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 55/100