poker-mcp 1.4.0 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -4
- package/package.json +56 -55
- package/src/mcp/handlers/guiHandlers.js +156 -0
- package/src/mcp/handlers/index.js +4 -2
- package/src/mcp/handlers/resetHandlers.js +4 -6
- package/src/mcp/handlers/thinnedIndicesHandlers.js +48 -0
- package/src/mcp/tools/buildupFactorTools.js +5 -1
- package/src/mcp/tools/index.js +6 -3
- package/src/mcp/tools/resetTools.js +1 -5
- package/src/mcp/tools/thinnedIndicesTools.js +78 -0
- package/src/services/DataManager.js +36 -0
- package/src/services/TaskManager.js +191 -19
- package/src/utils/MaterialAlternatives.js +13 -3
- package/src/utils/MaterialCatalog.js +278 -16
- package/src/utils/pendingView.js +50 -0
- package/src/utils/summaryParser.js +152 -65
- package/src/validators/PhysicsValidator.js +15 -2
package/README.md
CHANGED
|
@@ -4,13 +4,118 @@ YAML-based input file management tool for radiation-shielding calculation code P
|
|
|
4
4
|
|
|
5
5
|
## 📋 クイック情報
|
|
6
6
|
|
|
7
|
-
- **バージョン**: 1.
|
|
7
|
+
- **バージョン**: 1.6.0
|
|
8
8
|
- **プロトコル**: MCP (Model Context Protocol) 1.0.0 完全準拠
|
|
9
9
|
- **メインサーバー**: `src/mcp_server_stdio_v4.js`
|
|
10
10
|
- **データ保存**: `~/.poker-mcp/`(`POKER_MCP_HOME`環境変数で変更可)
|
|
11
11
|
- **核種データ**: `${POKER_INSTALL_PATH}/LIB/ICRP-07.NDX` を直接参照
|
|
12
12
|
- **実行方式**: STDIO通信(MCPプロトコル標準)
|
|
13
13
|
|
|
14
|
+
## 🆕 バージョン1.7.0〜1.7.2の新機能
|
|
15
|
+
|
|
16
|
+
### 📉 サマリー出力量の制御(ThinnedIndices 操作系 3メソッド)
|
|
17
|
+
`thinnedindices` ノードを MCP から設定できます。`.paths` の生成では全ての
|
|
18
|
+
線源分割点と検出器評価点が必要ですが、既定では間引かれるため手で書き足す
|
|
19
|
+
必要がありました。
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
poker_updateThinnedIndices({ fit_for_paths: true })
|
|
23
|
+
// → 入力の分割定義と検出器グリッドから必要数を計算して設定
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
既定値は poker_mcp 側で持ちません。省略しても `.summary` には全 7 キーが
|
|
27
|
+
値付きで出力されるので、そちらを正とします。
|
|
28
|
+
|
|
29
|
+
### 🔄 保留中の変更が `get` で見えるように
|
|
30
|
+
`propose` の直後に `get` を呼ぶと変更が見えず、「反映されていない」と誤解する
|
|
31
|
+
余地がありました。確定値とは別に `pending` として示します。
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
poker_proposeThinnedIndices({ sourcepoint: 100 })
|
|
35
|
+
poker_getThinnedIndices()
|
|
36
|
+
// → { thinnedindices: null, pending: { sourcepoint: 100 }, pending_count: 1 }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 🛡️ `.paths` の座標照合
|
|
40
|
+
件数だけでなく座標も YAML と突き合わせます。検出器を動かして `.paths` を
|
|
41
|
+
再生成し忘れると、件数は変わらないため従来は通り抜け、**静かに誤った線量**が
|
|
42
|
+
出ていました。
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## 🆕 バージョン1.6.0の新機能
|
|
46
|
+
|
|
47
|
+
### 🧱 カスタム材料をライブラリ追加だけで使えるように
|
|
48
|
+
材料の一覧・密度範囲・ビルドアップ可用性をコード側に持たず、すべて
|
|
49
|
+
`%POKER_INSTALL_PATH%/LIB/` から読み込むようにしました。**カスタム材料を
|
|
50
|
+
`lib_material.dat` に追記すれば、コード変更なしにサーバ再起動だけで
|
|
51
|
+
ゾーン定義・密度検証・等価材料の自動選定すべてに反映されます。**
|
|
52
|
+
|
|
53
|
+
標準材料を追加する場合は `lib_material.dat` と `lib_setting.dat` の
|
|
54
|
+
`buildup_material` の両方に登録します(片方だけなら警告が出ます)。
|
|
55
|
+
|
|
56
|
+
### 🔀 ビルドアップ等価材料の選定を実データ方式へ
|
|
57
|
+
従来の光子実効Z最近傍は暫定実装でした。ビルドアップを支配するのは散乱と吸収の
|
|
58
|
+
競合であることから、POKER の減衰係数ファイルから
|
|
59
|
+
`μ_incoherent / (μ_total − μ_incoherent)` を求め、0.1〜3 MeV の11点で
|
|
60
|
+
最も一致する標準材料を選びます。
|
|
61
|
+
|
|
62
|
+
一致度スコアを応答に付けるようにしました。0.30 を超える場合は「標準材料に
|
|
63
|
+
近いものが無い」ことを意味し、候補上位3件とともに警告を出します。黙って粗い
|
|
64
|
+
代用材を当てるより、どの程度粗いかを見せる方が判断材料になります。
|
|
65
|
+
|
|
66
|
+
この変更で `Source_Dry` の等価材料は `Lead` から `Tungsten` に変わります。
|
|
67
|
+
|
|
68
|
+
### 🐛 `poker_updateBuildupFactor` が equivalent を更新できない問題を修正
|
|
69
|
+
ツールスキーマと `DataManager` の双方に `equivalent` が無く、`TaskManager`
|
|
70
|
+
だけが素通しする三層不整合でした。変更・解除(空文字指定)に対応し、
|
|
71
|
+
標準材料への指定や非標準材料の指定を拒否する検証も追加しています。
|
|
72
|
+
|
|
73
|
+
### 📡 CAD連携レイトレース
|
|
74
|
+
FreeCAD のソリッドモデルを、STEP のような中間フォーマットを介さず、CSG で
|
|
75
|
+
表現し直す作業も無しに遮蔽体系として扱えます。線源点→検出器の直線を FreeCAD 側で
|
|
76
|
+
追跡し、通過した材質と厚さを `.paths` ファイルで POKER に渡します。
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
poker_cui model.yaml -p -t # 分割点を出力
|
|
80
|
+
freecadcmd -c "... gen_paths.main('spec.json')" # CAD をトレース
|
|
81
|
+
poker_cui model.yaml --path-input model.paths -t # 計算
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
POKER 側の `--path-input` も実装され、CSG 経由と一致することを平板・円筒・球の
|
|
85
|
+
5 体系で確認済みです。フィレットや自由曲面のように CSG で表現できない形状も
|
|
86
|
+
扱えます。**複数線源・グリッド検出器・スラント補正に対応**。
|
|
87
|
+
|
|
88
|
+
他の CAD で作ったモデルも、STEP で FreeCAD に読み込めば同じパイプラインに
|
|
89
|
+
乗ります。副産物として、POKER の改造なしで使える**簡易化の監査ツール**
|
|
90
|
+
(ある形状を省略してよいかを定量化する)もあります。
|
|
91
|
+
|
|
92
|
+
詳細は [CAD_RAYTRACE.md](./docs/manuals/CAD_RAYTRACE.md)、フォーマットは
|
|
93
|
+
[PATHS_FORMAT.md](./docs/manuals/PATHS_FORMAT.md)。
|
|
94
|
+
|
|
95
|
+
詳細は [CHANGELOG.md](./CHANGELOG.md) を参照。
|
|
96
|
+
|
|
97
|
+
## 🆕 バージョン1.5.0の新機能
|
|
98
|
+
|
|
99
|
+
### 🖥️ POKER GUI を閉じずに表示を切り替え
|
|
100
|
+
`poker_openGui` で別の入力を指定すると、起動中の POKER ウィンドウの表示が
|
|
101
|
+
そのまま切り替わります。従来は先に POKER を閉じる必要がありました。
|
|
102
|
+
|
|
103
|
+
未保存の編集があるときは POKER 側で保存確認が出るため、編集内容が
|
|
104
|
+
黙って失われることはありません(キャンセルすると切り替わりません)。
|
|
105
|
+
|
|
106
|
+
> **POKER 2.1.1 以降が必要です。** 2.1.0 以前では従来どおり
|
|
107
|
+
> `POKER_ALREADY_RUNNING` を返すので、先に POKER を閉じてください。
|
|
108
|
+
|
|
109
|
+
### 🐛 `poker_openGui` の偽の成功報告を修正
|
|
110
|
+
`spawn` の成否のみで判定していたため、POKER が二重起動で弾かれて即座に
|
|
111
|
+
終了しても「起動しました」と PID 付きで成功を返していました。
|
|
112
|
+
起動後の生存確認を追加し、実際に表示されたことを確認してから報告します。
|
|
113
|
+
|
|
114
|
+
### 📖 ドキュメントの大幅整理
|
|
115
|
+
`ADMIN_GUIDE.md` を実運用に即した内容へ全面改訂しました(699行 → 248行)。
|
|
116
|
+
乱数で「正常」を出力する監視スクリプトなど、実態と乖離した記述を削除し、
|
|
117
|
+
検証可能な手順のみに整理しています。
|
|
118
|
+
|
|
14
119
|
## 🆕 バージョン1.4.0の新機能
|
|
15
120
|
|
|
16
121
|
### ☢️ 子孫核種の自動管理
|
|
@@ -231,7 +336,7 @@ Claude Desktopで以下のようにテストできます:
|
|
|
231
336
|
## 🏆 主要機能
|
|
232
337
|
|
|
233
338
|
### ✅ **MCP完全対応**
|
|
234
|
-
- **
|
|
339
|
+
- **33メソッド完全実装**: 全ての放射線遮蔽計算入力管理機能
|
|
235
340
|
- **JSON-RPC 2.0準拠**: 標準プロトコル完全対応
|
|
236
341
|
- **STDIO通信**: MCPクライアントとの標準通信方式
|
|
237
342
|
- **自動バックアップ・ロールバック**: 企業品質のデータ保護
|
|
@@ -250,7 +355,7 @@ Claude Desktopで以下のようにテストできます:
|
|
|
250
355
|
|
|
251
356
|
## 🎯 API構成
|
|
252
357
|
|
|
253
|
-
### 🔧 **
|
|
358
|
+
### 🔧 **33メソッド完全実装**
|
|
254
359
|
|
|
255
360
|
| **カテゴリ** | **メソッド数** | **機能** | **主要操作** |
|
|
256
361
|
|-------------|---------------|----------|-------------|
|
|
@@ -263,7 +368,7 @@ Claude Desktopで以下のようにテストできます:
|
|
|
263
368
|
| **📏 Unit** | 5個 | 単位設定管理 | propose・get・update・validateIntegrity・analyzeConversion |
|
|
264
369
|
| **⚙️ System** | 6個 | システム制御 | applyChanges・executeCalculation・resetYaml・confirmDaughterNuclides・openGui・各種検証 |
|
|
265
370
|
|
|
266
|
-
### 📋 **全
|
|
371
|
+
### 📋 **全33メソッド一覧**
|
|
267
372
|
```
|
|
268
373
|
Body系 (3): poker_proposeBody, poker_updateBody, poker_deleteBody
|
|
269
374
|
Zone系 (3): poker_proposeZone, poker_updateZone, poker_deleteZone
|
package/package.json
CHANGED
|
@@ -1,55 +1,56 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "poker-mcp",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "YAML-based input file management tool for radiation shielding calculation code POKER with MCP support - Enhanced with collision detection, daughter nuclide auto-completion, and environment variable support",
|
|
5
|
-
"main": "src/mcp_server_stdio_v4.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
"poker-mcp": "src/mcp_server_stdio_v4.js"
|
|
9
|
-
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"start": "node src/mcp_server_stdio_v4.js",
|
|
12
|
-
"dev": "nodemon src/mcp_server_stdio_v4.js",
|
|
13
|
-
"prepare": "echo 'NPX ready: npx poker-mcp'",
|
|
14
|
-
"check:manifest": "node scripts/check-manifest-sync.mjs"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
".
|
|
54
|
-
|
|
55
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "poker-mcp",
|
|
3
|
+
"version": "1.7.2",
|
|
4
|
+
"description": "YAML-based input file management tool for radiation shielding calculation code POKER with MCP support - Enhanced with collision detection, daughter nuclide auto-completion, and environment variable support",
|
|
5
|
+
"main": "src/mcp_server_stdio_v4.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"poker-mcp": "src/mcp_server_stdio_v4.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node src/mcp_server_stdio_v4.js",
|
|
12
|
+
"dev": "nodemon src/mcp_server_stdio_v4.js",
|
|
13
|
+
"prepare": "echo 'NPX ready: npx poker-mcp'",
|
|
14
|
+
"check:manifest": "node scripts/check-manifest-sync.mjs",
|
|
15
|
+
"test:pending": "node tests/pending-view.test.mjs"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"mcp",
|
|
19
|
+
"model-context-protocol",
|
|
20
|
+
"yaml",
|
|
21
|
+
"radiation",
|
|
22
|
+
"shielding",
|
|
23
|
+
"nuclear",
|
|
24
|
+
"radioisotope",
|
|
25
|
+
"medical",
|
|
26
|
+
"accelerator",
|
|
27
|
+
"POKER",
|
|
28
|
+
"physics",
|
|
29
|
+
"validation",
|
|
30
|
+
"npx",
|
|
31
|
+
"point-kernel",
|
|
32
|
+
"collision-detection",
|
|
33
|
+
"daughter-nuclide"
|
|
34
|
+
],
|
|
35
|
+
"author": "Yoshihiro Hirao <tora@pointkernel.com>",
|
|
36
|
+
"license": "ISC",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/Hirao-Y/poker_mcp.git"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/Hirao-Y/poker_mcp#readme",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18.0.0"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
47
|
+
"js-yaml": "^4.1.0",
|
|
48
|
+
"winston": "^3.17.0",
|
|
49
|
+
"zod": "^3.24.2"
|
|
50
|
+
},
|
|
51
|
+
"files": [
|
|
52
|
+
"src/",
|
|
53
|
+
"README.md",
|
|
54
|
+
".mcp.json"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
@@ -5,6 +5,86 @@ import path from 'path';
|
|
|
5
5
|
import { logger } from '../../utils/logger.js';
|
|
6
6
|
import { TASKS_DIR, YAML_FILE } from '../../utils/paths.js';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* POKER.exe のファイルバージョンを取得する(Windows専用)
|
|
10
|
+
*
|
|
11
|
+
* POKER 2.1.1 以降は二重起動時に入力ファイルパスを既存インスタンスへ
|
|
12
|
+
* 転送するため、起動中でもそのまま spawn してよい。
|
|
13
|
+
* 2.1.0 以前は転送機能がなく、メッセージボックスを出して終了する。
|
|
14
|
+
*
|
|
15
|
+
* @returns {Promise<string|null>} "2.1.1.1" 形式。取得できなければ null
|
|
16
|
+
*/
|
|
17
|
+
async function getPokerFileVersion(exePath) {
|
|
18
|
+
if (process.platform !== 'win32') return null;
|
|
19
|
+
|
|
20
|
+
return new Promise(resolve => {
|
|
21
|
+
try {
|
|
22
|
+
const ps = spawn('powershell', [
|
|
23
|
+
'-NoProfile', '-NonInteractive', '-Command',
|
|
24
|
+
`try { [System.Diagnostics.FileVersionInfo]::GetVersionInfo('${exePath.replace(/'/g, "''")}').FileVersion } catch { '' }`
|
|
25
|
+
], { windowsHide: true });
|
|
26
|
+
|
|
27
|
+
let out = '';
|
|
28
|
+
ps.stdout.on('data', d => { out += d.toString(); });
|
|
29
|
+
ps.on('error', () => resolve(null));
|
|
30
|
+
ps.on('close', () => {
|
|
31
|
+
const v = out.trim();
|
|
32
|
+
resolve(/^\d+(\.\d+)*$/.test(v) ? v : null);
|
|
33
|
+
});
|
|
34
|
+
setTimeout(() => resolve(null), 5000);
|
|
35
|
+
} catch {
|
|
36
|
+
resolve(null);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** "2.1.1.1" >= "2.1.1" を判定する */
|
|
42
|
+
function isVersionAtLeast(version, minimum) {
|
|
43
|
+
if (!version) return false;
|
|
44
|
+
const a = version.split('.').map(Number);
|
|
45
|
+
const b = minimum.split('.').map(Number);
|
|
46
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
47
|
+
const x = a[i] || 0, y = b[i] || 0;
|
|
48
|
+
if (x !== y) return x > y;
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** 入力転送に対応する最小バージョン */
|
|
54
|
+
const FORWARDING_MIN_VERSION = '2.1.1';
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* POKER.exe が既に起動しているかを調べる(Windows専用)
|
|
58
|
+
*
|
|
59
|
+
* @returns {Promise<{detected: boolean, pids: number[]}>}
|
|
60
|
+
*/
|
|
61
|
+
async function isPokerRunning() {
|
|
62
|
+
if (process.platform !== 'win32') return { detected: false, pids: [] };
|
|
63
|
+
|
|
64
|
+
return new Promise(resolve => {
|
|
65
|
+
try {
|
|
66
|
+
const p = spawn('tasklist', ['/FI', 'IMAGENAME eq POKER.exe', '/FO', 'CSV', '/NH'], {
|
|
67
|
+
windowsHide: true
|
|
68
|
+
});
|
|
69
|
+
let out = '';
|
|
70
|
+
p.stdout.on('data', d => { out += d.toString(); });
|
|
71
|
+
p.on('error', () => resolve({ detected: false, pids: [] }));
|
|
72
|
+
p.on('close', () => {
|
|
73
|
+
// 該当なしの場合 tasklist は「情報: ...」等を返す
|
|
74
|
+
const pids = [];
|
|
75
|
+
for (const line of out.split(/\r?\n/)) {
|
|
76
|
+
const m = line.match(/^"POKER\.exe","(\d+)"/i);
|
|
77
|
+
if (m) pids.push(Number(m[1]));
|
|
78
|
+
}
|
|
79
|
+
resolve({ detected: pids.length > 0, pids });
|
|
80
|
+
});
|
|
81
|
+
setTimeout(() => resolve({ detected: false, pids: [] }), 3000);
|
|
82
|
+
} catch {
|
|
83
|
+
resolve({ detected: false, pids: [] });
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
8
88
|
/**
|
|
9
89
|
* POKER.exe のパスを解決する
|
|
10
90
|
* POKER_INSTALL_PATH 環境変数(デフォルト: C:/Poker)配下の POKER.exe を参照
|
|
@@ -81,6 +161,34 @@ export function createGuiHandlers(taskManager) {
|
|
|
81
161
|
};
|
|
82
162
|
}
|
|
83
163
|
|
|
164
|
+
// ── Step 3.5: 多重起動の扱い ────────────────────────────────
|
|
165
|
+
//
|
|
166
|
+
// POKER 2.1.1 以降は、起動中に別の入力で spawn すると、2つ目の
|
|
167
|
+
// プロセスがパスを既存インスタンスへ転送して終了する(表示が切替わる)。
|
|
168
|
+
// 2.1.0 以前は転送機能がなく、メッセージボックスを出して終了するため、
|
|
169
|
+
// 呼び出し側には「成功したのに表示が変わらない」と見える。
|
|
170
|
+
// そこでバージョンで分岐する。
|
|
171
|
+
const pokerVersion = await getPokerFileVersion(pokerExePath);
|
|
172
|
+
const supportsForwarding = isVersionAtLeast(pokerVersion, FORWARDING_MIN_VERSION);
|
|
173
|
+
const running = await isPokerRunning();
|
|
174
|
+
|
|
175
|
+
if (running.detected && !supportsForwarding) {
|
|
176
|
+
logger.warn('poker_openGui: 起動中かつ転送非対応版', {
|
|
177
|
+
pids: running.pids, version: pokerVersion
|
|
178
|
+
});
|
|
179
|
+
return {
|
|
180
|
+
success: false,
|
|
181
|
+
error: 'POKER.exe は既に起動しています。この版は二重起動時の入力転送に対応していません。',
|
|
182
|
+
error_type: 'POKER_ALREADY_RUNNING',
|
|
183
|
+
running_pids: running.pids,
|
|
184
|
+
poker_version: pokerVersion ?? '(取得不可)',
|
|
185
|
+
suggestion: `別の入力を表示するには、先に起動中の POKER ウィンドウを閉じてください。`
|
|
186
|
+
+ `\nPOKER ${FORWARDING_MIN_VERSION} 以降に更新すると、閉じずに切り替えられます。`
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const forwarding = running.detected && supportsForwarding;
|
|
191
|
+
|
|
84
192
|
// ── Step 4: POKER.exe をデタッチ起動 ─────────────────────────
|
|
85
193
|
try {
|
|
86
194
|
const child = spawn(pokerExePath, [resolvedYaml], {
|
|
@@ -88,6 +196,54 @@ export function createGuiHandlers(taskManager) {
|
|
|
88
196
|
stdio: 'ignore', // MCPサーバーの stdio を汚染しない
|
|
89
197
|
shell: false
|
|
90
198
|
});
|
|
199
|
+
|
|
200
|
+
// 起動直後に終了していないかを確認してから成功を報告する。
|
|
201
|
+
// spawn の成功はプロセス生成の成功でしかなく、GUI が実際に
|
|
202
|
+
// 表示されたことを意味しない。
|
|
203
|
+
//
|
|
204
|
+
// ただし転送時(既存インスタンスあり・2.1.1以降)は、2つ目の
|
|
205
|
+
// プロセスがパスを送って即座に終了するのが正常動作である。
|
|
206
|
+
const died = await new Promise(resolve => {
|
|
207
|
+
const timer = setTimeout(() => resolve(null), 1500);
|
|
208
|
+
child.once('exit', code => { clearTimeout(timer); resolve(code ?? -1); });
|
|
209
|
+
child.once('error', () => { clearTimeout(timer); resolve(-1); });
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
if (died !== null && !(forwarding && died === 0)) {
|
|
213
|
+
logger.error('poker_openGui: POKER.exe が起動直後に終了', {
|
|
214
|
+
exitCode: died, executable: pokerExePath, inputFile: resolvedYaml, forwarding
|
|
215
|
+
});
|
|
216
|
+
return {
|
|
217
|
+
success: false,
|
|
218
|
+
error: `POKER.exe が起動直後に終了しました (exit=${died})`,
|
|
219
|
+
error_type: 'POKER_EXITED_IMMEDIATELY',
|
|
220
|
+
input_file: resolvedYaml,
|
|
221
|
+
suggestion: '入力ファイルが POKER で読める形式か確認してください。'
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (forwarding) {
|
|
226
|
+
logger.info('poker_openGui: 既存インスタンスへ入力を転送', {
|
|
227
|
+
executable: pokerExePath, inputFile: resolvedYaml,
|
|
228
|
+
targetPids: running.pids, version: pokerVersion
|
|
229
|
+
});
|
|
230
|
+
return {
|
|
231
|
+
success: true,
|
|
232
|
+
message: '起動中の POKER に入力を転送しました。',
|
|
233
|
+
forwarded: true,
|
|
234
|
+
launched: {
|
|
235
|
+
executable: pokerExePath,
|
|
236
|
+
input_file: resolvedYaml,
|
|
237
|
+
target_pids: running.pids
|
|
238
|
+
},
|
|
239
|
+
poker_version: pokerVersion,
|
|
240
|
+
note: '転送の送信までを確認しています。読み込みに失敗した場合は'
|
|
241
|
+
+ ' POKER のウィンドウにエラーが表示されます。'
|
|
242
|
+
+ '\n未保存の編集があるときは POKER 側で保存確認が出ます'
|
|
243
|
+
+ '(キャンセルすると切り替わりません)。'
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
91
247
|
child.unref(); // MCPサーバーが POKER.exe の終了を待たない
|
|
92
248
|
|
|
93
249
|
logger.info('poker_openGui: POKER.exe 起動成功', {
|
|
@@ -5,7 +5,8 @@ import { createTransformHandlers } from './transformHandlers.js';
|
|
|
5
5
|
import { createBuildupFactorHandlers } from './buildupFactorHandlers.js';
|
|
6
6
|
import { createSourceHandlers } from './sourceHandlers.js';
|
|
7
7
|
import { createDetectorHandlers } from './detectorHandlers.js';
|
|
8
|
-
import { createUnitHandlers } from './unitHandlers.js';
|
|
8
|
+
import { createUnitHandlers } from './unitHandlers.js';
|
|
9
|
+
import { createThinnedIndicesHandlers } from './thinnedIndicesHandlers.js';
|
|
9
10
|
import { createCalculationHandlers } from './calculationHandlers.js';
|
|
10
11
|
import { resetHandlers } from './resetHandlers.js';
|
|
11
12
|
import { createDaughterNuclideHandler } from './daughterNuclideHandler.js';
|
|
@@ -32,7 +33,8 @@ export function createAllHandlers(taskManager) {
|
|
|
32
33
|
...createDetectorHandlers(taskManager),
|
|
33
34
|
|
|
34
35
|
// 単位操作
|
|
35
|
-
...createUnitHandlers(taskManager),
|
|
36
|
+
...createUnitHandlers(taskManager),
|
|
37
|
+
...createThinnedIndicesHandlers(taskManager),
|
|
36
38
|
|
|
37
39
|
// 計算操作
|
|
38
40
|
...createCalculationHandlers(taskManager),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// handlers/resetHandlers.js - YAML初期化ハンドラー
|
|
2
2
|
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
|
3
3
|
import { logger } from '../../utils/logger.js';
|
|
4
|
+
import { MaterialCatalog } from '../../utils/MaterialCatalog.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* poker_resetYaml ハンドラー
|
|
@@ -49,12 +50,9 @@ export function createResetYamlHandler(taskManager) {
|
|
|
49
50
|
throw new McpError(ErrorCode.InvalidParams, `reset_level は ${validResetLevels.join(', ')} のいずれかである必要があります`);
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
];
|
|
56
|
-
if (!validMaterials.includes(atmosphere_material)) {
|
|
57
|
-
throw new McpError(ErrorCode.InvalidParams, `atmosphere_material は ${validMaterials.join(', ')} のいずれかである必要があります`);
|
|
53
|
+
if (!MaterialCatalog.has(atmosphere_material)) {
|
|
54
|
+
throw new McpError(ErrorCode.InvalidParams,
|
|
55
|
+
`atmosphere_material は ${MaterialCatalog.allMaterials().join(', ')} のいずれかである必要があります`);
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
// VOID材料の密度指定チェック
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// mcp/handlers/thinnedIndicesHandlers.js
|
|
2
|
+
//
|
|
3
|
+
// thinnedindices(サマリー出力量の制御)のハンドラ。
|
|
4
|
+
// 既定値は poker_mcp 側で持たず、POKER の .summary に出力される値を正とする。
|
|
5
|
+
|
|
6
|
+
import { logger } from '../../utils/logger.js';
|
|
7
|
+
|
|
8
|
+
export function createThinnedIndicesHandlers(taskManager) {
|
|
9
|
+
return {
|
|
10
|
+
async proposeThinnedIndices(args) {
|
|
11
|
+
const result = await taskManager.proposeThinnedIndices(args || {});
|
|
12
|
+
return {
|
|
13
|
+
content: [{
|
|
14
|
+
type: 'text',
|
|
15
|
+
text: JSON.stringify({
|
|
16
|
+
success: true,
|
|
17
|
+
message: 'thinnedindices を提案しました(applyChanges で確定)',
|
|
18
|
+
...result
|
|
19
|
+
}, null, 2)
|
|
20
|
+
}]
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
async getThinnedIndices() {
|
|
25
|
+
const result = await taskManager.getThinnedIndices();
|
|
26
|
+
return {
|
|
27
|
+
content: [{
|
|
28
|
+
type: 'text',
|
|
29
|
+
text: JSON.stringify(result, null, 2)
|
|
30
|
+
}]
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
async updateThinnedIndices(args) {
|
|
35
|
+
const result = await taskManager.updateThinnedIndices(args || {});
|
|
36
|
+
const msg = (args && args.fit_for_paths)
|
|
37
|
+
? 'thinnedindices を更新しました(入力の分割数・評価点数に合わせました)'
|
|
38
|
+
: 'thinnedindices を更新しました(applyChanges で確定)';
|
|
39
|
+
logger.info(msg, { indices: result.thinnedindices });
|
|
40
|
+
return {
|
|
41
|
+
content: [{
|
|
42
|
+
type: 'text',
|
|
43
|
+
text: JSON.stringify({ success: true, message: msg, ...result }, null, 2)
|
|
44
|
+
}]
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -12,7 +12,7 @@ export const buildupFactorTools = [
|
|
|
12
12
|
},
|
|
13
13
|
equivalent: {
|
|
14
14
|
type: 'string',
|
|
15
|
-
description: '
|
|
15
|
+
description: '非標準材料のビルドアップ等価材料(標準材料名)。省略時は組成の散乱/吸収比を実用エネルギー帯域で照合して自動選択'
|
|
16
16
|
},
|
|
17
17
|
use_slant_correction: {
|
|
18
18
|
type: 'boolean',
|
|
@@ -45,6 +45,10 @@ export const buildupFactorTools = [
|
|
|
45
45
|
use_finite_medium_correction: {
|
|
46
46
|
type: 'boolean',
|
|
47
47
|
description: '新しい有限媒体補正設定'
|
|
48
|
+
},
|
|
49
|
+
equivalent: {
|
|
50
|
+
type: 'string',
|
|
51
|
+
description: '非標準材料のビルドアップ等価材料(標準材料名)。空文字を指定すると等価材料の指定を解除します'
|
|
48
52
|
}
|
|
49
53
|
},
|
|
50
54
|
required: ['material']
|
package/src/mcp/tools/index.js
CHANGED
|
@@ -6,7 +6,8 @@ import { buildupFactorTools } from './buildupFactorTools.js';
|
|
|
6
6
|
import { sourceTools } from './sourceTools.js';
|
|
7
7
|
import { detectorTools } from './detectorTools.js';
|
|
8
8
|
import { commonTools } from './commonTools.js';
|
|
9
|
-
import { unitTools } from './unitTools.js';
|
|
9
|
+
import { unitTools } from './unitTools.js';
|
|
10
|
+
import { thinnedIndicesTools } from './thinnedIndicesTools.js';
|
|
10
11
|
import { calculationTools } from './calculationTools.js';
|
|
11
12
|
import { resetTools } from './resetTools.js';
|
|
12
13
|
import { daughterNuclideTools } from './daughterNuclideTools.js';
|
|
@@ -20,7 +21,8 @@ export const allTools = [
|
|
|
20
21
|
...sourceTools,
|
|
21
22
|
...detectorTools,
|
|
22
23
|
...commonTools,
|
|
23
|
-
...unitTools,
|
|
24
|
+
...unitTools,
|
|
25
|
+
...thinnedIndicesTools,
|
|
24
26
|
...calculationTools,
|
|
25
27
|
...resetTools,
|
|
26
28
|
...daughterNuclideTools,
|
|
@@ -35,7 +37,8 @@ export {
|
|
|
35
37
|
sourceTools,
|
|
36
38
|
detectorTools,
|
|
37
39
|
commonTools,
|
|
38
|
-
unitTools,
|
|
40
|
+
unitTools,
|
|
41
|
+
thinnedIndicesTools,
|
|
39
42
|
calculationTools,
|
|
40
43
|
resetTools,
|
|
41
44
|
daughterNuclideTools,
|
|
@@ -30,11 +30,7 @@ export const resetTools = [
|
|
|
30
30
|
},
|
|
31
31
|
atmosphere_material: {
|
|
32
32
|
type: 'string',
|
|
33
|
-
description: 'ATMOSPHERE
|
|
34
|
-
enum: [
|
|
35
|
-
'Carbon', 'Concrete', 'Iron', 'Lead', 'Aluminium', 'Copper', 'Tungsten',
|
|
36
|
-
'Air', 'Water', 'PyrexGlass', 'AcrylicResin', 'Polyethylene', 'Soil', 'VOID'
|
|
37
|
-
],
|
|
33
|
+
description: 'ATMOSPHEREゾーンに設定する材料。lib_material.dat に登録された材料名(カスタム材料を含む)または VOID',
|
|
38
34
|
default: 'VOID'
|
|
39
35
|
},
|
|
40
36
|
atmosphere_density: {
|