ETW MCP early previewをMCPクライアントに登録したものの、「dnxが見つからない」「互換性のある.NET SDKを解決できない」と表示され、ETWサーバーが起動しないことがあります。
この問題は、ETWやETLファイルの解析処理ではなく、ETW MCPサーバーが起動する前の.NET実行環境で発生している可能性が高いです。最初に確認すべきポイントは、次の3つです。
- .NET 10の「ランタイム」ではなく「SDK」がインストールされているか
- MCPクライアントの起動ディレクトリで、古いSDKを固定する
global.jsonが適用されていないか - MCPクライアントが新しい
dnxとPATHを認識しているか
公式情報でも、ETW MCPは.NET 10 SDKに含まれるdnxを使って起動し、古いSDKを固定するglobal.jsonがある環境ではSDK解決に失敗する可能性が案内されています。基本的には、.NET 10 SDKの導入、global.jsonの見直し、または影響を受けない別ディレクトリからの起動で解決できます。(Microsoft for Developers)
ETW MCPが起動しない原因:dnx、.NET 10 SDK、global.json固定を切り分ける
ETW MCPは、Microsoft.Windows.EventTracing.MCPというNuGetパッケージとして提供されています。MCPクライアントは、概ね次の流れでETW MCPサーバーを起動します。
MCPクライアント
↓
dnxコマンドを実行
↓
使用する.NET SDKを決定
↓
NuGetからETW MCPパッケージを取得
↓
ETW MCPサーバーをstdioで起動
dnxは、.NETツールを永続的にインストールせず、その場でダウンロードして実行するためのコマンドです。.NET 10 SDK 10.0.100以降で利用でき、指定されたパッケージは必要に応じてNuGetキャッシュへダウンロードされます。(Microsoft Learn)
つまり、ETW MCPが起動しない場合は、いきなりETWの権限やETLファイルを調べるのではなく、まずdnxと.NET SDKの解決段階を確認する必要があります。
エラーメッセージから原因を絞り込む
表示されるメッセージによって、問題が起きている層をある程度判断できます。
| 症状・エラーの例 | 主な原因 | 最初に確認するもの |
|---|---|---|
dnxが見つからない | .NET 10 SDK未導入、PATH未反映 | dotnet --list-sdks、where.exe dnx |
| 互換性のある.NET SDKが見つからない | global.jsonのSDK固定 | dotnet --version、global.json |
NETSDK1141 | 指定SDKが未導入、バージョンやパスが不正 | global.jsonのversion |
Unrecognized command or argument 'execute' | 古いSDKでdnx処理が実行された | 選択中のSDKとdnxのバージョン |
| MCPサーバーがタイムアウトする | 起動直後にdnxが異常終了している | MCPクライアントのログ、手動実行 |
| ターミナルでは動くがクライアントでは動かない | PATHまたは作業ディレクトリが異なる | クライアント再起動、起動ディレクトリ |
Microsoftは、global.jsonによって.NET 10より前のSDKが選択された環境で、dnxがUnrecognized command or argument 'execute'を出して失敗するケースを説明しています。この状態は、MCPクライアント側では単なるタイムアウトやサーバー切断として見えることもあります。(Microsoft Learn)
最初に.NET 10 SDKの導入状況を確認する
PowerShellまたはコマンドプロンプトを開き、次のコマンドを実行します。
dotnet --list-sdks
正常な例は次のような出力です。
8.0.4xx [C:\Program Files\dotnet\sdk]
9.0.3xx [C:\Program Files\dotnet\sdk]
10.0.3xx [C:\Program Files\dotnet\sdk]
一覧に10.0.xxxが1つもない場合は、.NET 10 SDKがインストールされていません。
ここで注意したいのは、.NET 10 Runtimeだけでは不十分という点です。dnxは.NET 10 SDKに含まれるため、ダウンロード時には「Runtime」ではなく「SDK」を選択します。MicrosoftのMCPサーバー向けドキュメントでも、dnxが見つからない場合の対処として.NET 10 SDKのインストールが案内されています。(Microsoft Learn)
続いて、実際に呼び出されるコマンドの場所を確認します。
where.exe dotnet
where.exe dnx
期待される結果の例は次のとおりです。
C:\Program Files\dotnet\dotnet.exe
C:\Program Files\dotnet\dnx.cmd
.NET 10正式版では、Windows上のdnxは主にdnx.cmdとして提供されます。dnx.ps1を直接指定した設定は、正式版では動作しない可能性があるため、MCPクライアントには通常どおりdnxを指定してください。(Microsoft Learn)
.NET 10 SDKを入れたのにdnxが見つからない場合
.NET 10 SDKをインストールした直後は、すでに起動していたMCPクライアントが古いPATHを保持している場合があります。
次の順序で再確認します。
- MCPクライアントを完全に終了する
- タスクトレイやバックグラウンドプロセスにも残っていないことを確認する
- 新しいPowerShellを開く
where.exe dnxを実行する- MCPクライアントを起動し直す
ターミナルではdnxが見えるのにMCPクライアントだけが認識しない場合は、クライアントの再起動が特に重要です。
インストール済みSDKと選択中のSDKは別に確認する
dotnet --list-sdksに.NET 10が表示されても、そのディレクトリで.NET 10が選択されるとは限りません。
MCPクライアントが起動するワークスペースやプロジェクトのディレクトリへ移動し、次のコマンドを実行します。
dotnet --version
dotnet --info
確認ポイントは次のとおりです。
dotnet --list-sdksには10.0系がある- しかし
dotnet --versionは8.0系や9.0系になる - またはSDK解決エラーが表示される
この場合は、global.jsonによって古いSDKが選択されている可能性が高いです。
dotnet --list-sdksはインストール済みSDKの一覧を表示します。一方、dotnet --versionは、そのディレクトリで実際に選択されたSDKを確認するために使えます。
global.jsonが現在のディレクトリより上にないか確認する
.NET CLIは、現在の作業ディレクトリから親ディレクトリへ向かってglobal.jsonを検索します。プロジェクトフォルダーにファイルがなくても、その1つ上やユーザーフォルダーなどに置かれていれば影響を受けます。最初に見つかったglobal.jsonがSDK選択に使用されます。(Microsoft Learn)
PowerShellでは、次のスクリプトで現在地と親ディレクトリにあるglobal.jsonを確認できます。
$dir = Get-Item .
while ($null -ne $dir) {
$file = Join-Path $dir.FullName "global.json"
if (Test-Path $file) {
Write-Output $file
}
$dir = $dir.Parent
}
ファイルが見つかったら、内容を確認します。
Get-Content "C:\対象のパス\global.json"
問題になりやすい例は次のとおりです。
{
"sdk": {
"version": "8.0.100",
"rollForward": "disable"
}
}
この設定では、8.0.100との完全一致が求められ、.NET 10へは移行しません。
次のようにrollForwardが書かれていない場合も注意が必要です。
{
"sdk": {
"version": "8.0.100"
}
}
SDKバージョンが指定されていてrollForwardが省略されている場合、既定値はpatchです。同じ機能バンドのパッチまでは選択できますが、.NET 8から.NET 10のようにメジャーバージョンをまたぐことはありません。(Microsoft Learn)
global.jsonを修正する方法
global.jsonの扱いは、プロジェクトが本来どのSDKを必要としているかによって変わります。単純に削除するのではなく、用途に応じて選択してください。
プロジェクト自体を.NET 10へ移行できる場合
プロジェクトでも.NET 10を使用してよい場合は、次のように更新できます。
{
"sdk": {
"version": "10.0.100",
"rollForward": "latestFeature"
}
}
latestFeatureは、指定したメジャー・マイナーバージョンの範囲で、インストール済みの新しい機能バンドやパッチを選択します。この例では、10.0.100以上の10.0系SDKが対象になります。(Microsoft Learn)
バージョン欄は、次のように省略してはいけません。
{
"sdk": {
"version": "10.0"
}
}
versionには10.0.100のような完全なSDKバージョンが必要です。10、10.0、10.0.xなどの指定は無効です。(Microsoft Learn)
古いSDKを基準にしつつ.NET 10も許可する場合
技術的には、次のようにlatestMajorを使う方法があります。
{
"sdk": {
"version": "8.0.100",
"rollForward": "latestMajor"
}
}
latestMajorは、指定値以上でインストールされている最も新しいSDKを選択します。そのため、.NET 10 SDKがインストールされていれば、10.0系が選ばれる可能性があります。(Microsoft Learn)
ただし、この変更はETW MCPだけでなく、そのディレクトリで実行するdotnet build、dotnet test、dotnet runなどにも影響します。
共有リポジトリでSDKを固定している場合は、次の問題が起こり得ます。
- 開発者ごとに使用SDKが変わる
- CIとローカル環境でビルド結果が変わる
- 古いSDKを前提とした処理が動かなくなる
- 意図せず新しいコンパイラやMSBuildが使われる
ETW MCPのためだけに共有リポジトリのglobal.jsonを緩めるより、別ディレクトリから起動する方法のほうが安全な場合があります。
global.jsonを削除できる場合
個人用の検証フォルダーなど、SDK固定が不要な場所であれば、global.jsonを削除する方法もあります。
global.jsonが見つからない場合、.NET CLIは原則としてインストール済みの最新SDKを使用します。また、SDK解決エラーNETSDK1141の公式対処にも、必要なSDKの導入、バージョンの修正、またはglobal.jsonの削除が挙げられています。(Microsoft Learn)
削除前には、念のためバックアップします。
Copy-Item .\global.json .\global.json.backup
Remove-Item .\global.json
共有リポジトリに登録されたファイルは、チームの合意なしに削除しないでください。
global.jsonの影響を受けない別ディレクトリから起動する
プロジェクトが.NET 8や.NET 9に固定されており、global.jsonを変更できない場合は、ETW MCPを別のディレクトリから起動します。
例えば、次のような専用フォルダーを用意します。
New-Item -ItemType Directory -Force "$env:USERPROFILE\etw-mcp-runtime"
Set-Location "$env:USERPROFILE\etw-mcp-runtime"
その場所で、親ディレクトリを含めてglobal.jsonの影響がないことを確認します。
dotnet --version
10.0系が表示される場合は、そのディレクトリでETW MCPを手動起動します。
dnx Microsoft.Windows.EventTracing.MCP --yes
MCPクライアントが作業ディレクトリを指定できる場合は、この専用フォルダーを起動ディレクトリに設定します。指定できない場合は、ユーザー単位のMCP設定へ登録する、専用ワークスペースからクライアントを開くなど、クライアントごとの方法を使います。
重要なのは、設定ファイルが置かれている場所ではなく、プロセスの現在の作業ディレクトリがSDK選択に影響するという点です。(Microsoft Learn)
.NET 10 SDK 10.0.302以降ではdnxの動作が変わっている
比較的新しい.NET 10 SDKでは、dnxとglobal.jsonの関係が変更されています。
.NET 10 SDK 10.0.302以降のdnxおよびdnx.cmdは、インストール済みの最新SDKを直接見つけて呼び出すため、作業ディレクトリのglobal.jsonによるSDK固定をバイパスします。古いSDKへの固定によってdnxまで壊れる問題を避けるための変更です。(Microsoft Learn)
そのため、次の環境では.NET 10 SDKを新しいサービスリリースへ更新するだけで改善する可能性があります。
- .NET 10 SDK 10.0.100系や古い10.0.2xx系を使っている
- MCP設定のコマンドが
dnxになっている global.jsonで.NET 8または.NET 9を固定している
一方、次のように設定している場合は注意が必要です。
dotnet dnx Microsoft.Windows.EventTracing.MCP --yes
dotnet dnxを明示的に実行すると、従来どおり.NETマルチプレクサーとglobal.jsonがSDK選択を制御します。新しいdnxのバイパス動作を利用したい場合は、MCPクライアントのコマンドをdotnet dnxではなくdnxにします。(Microsoft Learn)
MCPクライアントの設定を確認する
ETW MCPの基本的な起動指定は次の形です。
{
"servers": {
"etw": {
"type": "stdio",
"command": "dnx",
"args": [
"Microsoft.Windows.EventTracing.MCP",
"--yes"
]
}
}
}
MCPクライアントによって、最上位のキーがservers、mcpServersなど異なる場合があります。既存の設定構造は変更せず、次の2点を確認してください。
command: dnx
args: Microsoft.Windows.EventTracing.MCP, --yes
ETW MCPはMicrosoft.Windows.EventTracing.MCPというNuGetパッケージとして提供され、公式の導入例でもdnxから起動する構成が使われています。(Microsoft for Developers)
dnxの絶対パスで一時的に診断する
ターミナルでは動くのにMCPクライアントではdnxが見つからない場合は、次のコマンドで表示されたパスを一時的に指定します。
where.exe dnx
例えば、結果が次のパスだったとします。
C:\Program Files\dotnet\dnx.cmd
診断用として、MCP設定を次のように変更します。
{
"command": "C:\\Program Files\\dotnet\\dnx.cmd",
"args": [
"Microsoft.Windows.EventTracing.MCP",
"--yes"
]
}
これで動く場合は、ETW MCPや.NET 10 SDKではなく、MCPクライアントから見えるPATHに問題があります。
絶対パスの固定は、インストール先やCPUアーキテクチャが異なる端末へ設定を共有しにくくなるため、恒久対応ではなく診断用として使うのが安全です。
同じディレクトリから手動起動して確認する
MCPクライアントのログだけでは原因が分からない場合は、クライアントが使用するのと同じディレクトリで手動実行します。
dnx Microsoft.Windows.EventTracing.MCP --yes
結果は次のように判断します。
| 手動実行の結果 | 判断 |
|---|---|
dnxが見つからない | .NET 10 SDKまたはPATHの問題 |
| SDK解決エラーになる | global.jsonまたはSDK導入状況の問題 |
| NuGet接続エラーになる | プロキシ、ファイアウォール、NuGetソースの問題 |
| プロセスが起動して待機する | dnxとETW MCPの起動段階は通過している可能性が高い |
| 手動では動くがクライアントでは失敗 | クライアントのPATH、作業ディレクトリ、設定の問題 |
dnxは初回実行時、対象パッケージがキャッシュにない場合はNuGetフィードからダウンロードします。そのため、SDK問題を解消した後に、社内プロキシやNuGet.orgへの接続制限が別のエラーとして現れることがあります。(Microsoft Learn)
手動起動で待機状態になった場合は、Ctrl+Cで終了できます。
よくある失敗と注意点
.NET 10 Runtimeだけをインストールする
dnxに必要なのは.NET 10 SDKです。ランタイム一覧に.NET 10があっても、SDK一覧に10.0系がなければ解決しません。
確認には次を使います。
dotnet --list-sdks
global.jsonをプロジェクト直下だけ探す
.NET CLIは現在の作業ディレクトリから上方向に検索します。プロジェクト直下にないからといって、影響を受けていないとは限りません。
dotnet –list-sdksだけで正常と判断する
.NET 10 SDKがインストールされていても、global.jsonによって.NET 8や.NET 9が選択される場合があります。
次の2つは役割が異なります。
dotnet --list-sdks
dotnet --version
前者はインストール済み一覧、後者は現在のディレクトリで選択されたSDKの確認に使います。
共有リポジトリのglobal.jsonを安易に削除する
global.jsonは、開発者やCIで使用するSDKをそろえるために置かれている場合があります。ETW MCPのためだけに削除すると、ビルド再現性を損なう可能性があります。
変更できない場合は、別ディレクトリからの起動や、新しい.NET 10 SDKのdnxを利用します。
dotnet dnxへ書き換える
新しいdnxがglobal.jsonをバイパスする環境でも、dotnet dnxを明示するとglobal.jsonの影響を再び受けます。ETW MCPの一般的な起動設定では、コマンドをdnxにします。(Microsoft Learn)
dnx.ps1を直接指定する
.NET 10正式版にはdnx.ps1が含まれず、dnx.cmdが使われます。古いプレビュー環境で作成した設定を引き継いでいる場合は、commandをdnxへ戻してください。(Microsoft Learn)
ETW MCPが起動しないときの確認順序
最短で切り分けるなら、次の順番で確認します。
dotnet --list-sdks
where.exe dnx
dotnet --version
dotnet --info
dnx Microsoft.Windows.EventTracing.MCP --yes
判断基準は次のとおりです。
- 10.0系SDKがない
→ .NET 10 SDKをインストールする - 10.0系SDKはあるが
dnxが見つからない
→ PATHを確認し、MCPクライアントを完全終了して再起動する dotnet --list-sdksには10.0系があるが、dotnet --versionが8.0系や9.0系になる
→ 起動ディレクトリと親ディレクトリのglobal.jsonを確認するglobal.jsonを変更できない
→ .NET 10を許可する設定へ見直すか、影響を受けない別ディレクトリから起動する- .NET 10 SDK 10.0.302以降を使っているのに失敗する
→ MCP設定がdotnet dnxになっていないか、古いdnxのパスを固定していないか確認する - 手動実行は成功するがMCPクライアントでは失敗する
→ クライアントのPATH、作業ディレクトリ、MCP設定を確認する
ETW MCPの起動問題では、「.NET 10 SDKが入っているか」と「そのSDKが実際に選ばれているか」を分けて確認することが重要です。まずdotnet --list-sdksとdotnet --versionを比較し、差がある場合はglobal.jsonを調べてください。そのうえで、同じディレクトリからETW MCPを手動起動すれば、SDK問題とMCPクライアント側の問題を明確に切り分けられます。

コメント