anthropics / anthropics/claude-code

[BUG] Windows-MCP extension: concurrent comtypes code generation corrupts the UIAutomation cache and crashes server startup

オープン
#93,082 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
area:mcp bug has repro platform:windows
主要言語
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

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。