poker-mcp 1.0.0
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 +241 -0
- package/config/mcp-manifest.json +1713 -0
- package/config/package-lock.json +1335 -0
- package/config/poker_mcp.code-workspace +8 -0
- package/package.json +51 -0
- package/src/config/ConfigManager.js +120 -0
- package/src/config/default.json +62 -0
- package/src/mcp/handlers/bodyHandlers.js +63 -0
- package/src/mcp/handlers/buildupFactorHandlers.js +43 -0
- package/src/mcp/handlers/calculationHandlers.js +265 -0
- package/src/mcp/handlers/detectorHandlers.js +201 -0
- package/src/mcp/handlers/index.js +43 -0
- package/src/mcp/handlers/sourceHandlers.js +25 -0
- package/src/mcp/handlers/transformHandlers.js +26 -0
- package/src/mcp/handlers/unitHandlers.js +305 -0
- package/src/mcp/handlers/zoneHandlers.js +83 -0
- package/src/mcp/middleware/errorHandler.js +49 -0
- package/src/mcp/middleware/requestValidator.js +129 -0
- package/src/mcp/server.js +76 -0
- package/src/mcp/tools/bodyTools.js +185 -0
- package/src/mcp/tools/buildupFactorTools.js +82 -0
- package/src/mcp/tools/calculationTools.js +58 -0
- package/src/mcp/tools/commonTools.js +22 -0
- package/src/mcp/tools/detectorTools.js +131 -0
- package/src/mcp/tools/index.js +34 -0
- package/src/mcp/tools/sourceTools.js +726 -0
- package/src/mcp/tools/sourceTools_fixed_part2.js +41 -0
- package/src/mcp/tools/transformTools.js +73 -0
- package/src/mcp/tools/unitTools.js +137 -0
- package/src/mcp/tools/zoneTools.js +65 -0
- package/src/mcp_server_stdio_v4.js +45 -0
- package/src/routes/restApi.js +184 -0
- package/src/services/CalculationService.js +525 -0
- package/src/services/DataManager.js +738 -0
- package/src/services/TaskManager.js +1622 -0
- package/src/utils/MaterialAlternatives.js +189 -0
- package/src/utils/errorHandler.js +68 -0
- package/src/utils/errors.js +37 -0
- package/src/utils/logger.js +24 -0
- package/src/utils/logger_no_color.js +28 -0
- package/src/utils/mcpErrors.js +225 -0
- package/src/validators/CMBValidator.js +191 -0
- package/src/validators/DetectorValidator.js +512 -0
- package/src/validators/ManifestValidator.js +249 -0
- package/src/validators/NuclideValidator.js +171 -0
- package/src/validators/PhysicsValidator.js +401 -0
- package/src/validators/PhysicsValidatorSimple.js +87 -0
- package/src/validators/SourceValidator.js +515 -0
- package/src/validators/TransformValidator.js +472 -0
- package/src/validators/UnitValidator.js +562 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// utils/MaterialAlternatives.js - 材料代替マッピング機能
|
|
2
|
+
import { PokerMcpError } from './mcpErrors.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 材料代替マッピング管理クラス
|
|
6
|
+
* マニフェストで定義された材料代替情報を活用
|
|
7
|
+
*/
|
|
8
|
+
export class MaterialAlternatives {
|
|
9
|
+
// マニフェストに対応する材料代替マッピング
|
|
10
|
+
static ALTERNATIVES = {
|
|
11
|
+
'STEEL': { substitute: 'Iron', note: '一般的な構造用鋼はIronで代替' },
|
|
12
|
+
'STAINLESS_STEEL': { substitute: 'Iron', note: 'ステンレス鋼もIronで代替可能' },
|
|
13
|
+
'BRASS': { substitute: 'Copper', note: '真鍮はCopperで代替' },
|
|
14
|
+
'BRONZE': { substitute: 'Copper', note: '青銅はCopperで代替' },
|
|
15
|
+
'GLASS': { substitute: 'PyrexGlass', note: '一般ガラスはPyrexGlassで代替' },
|
|
16
|
+
'PLASTIC': { substitute: 'AcrylicResin', note: '一般プラスチックはAcrylicResinで代替' },
|
|
17
|
+
'EARTH': { substitute: 'Soil', note: '土壌はSoilで代替' },
|
|
18
|
+
'VOID_SPACE': { substitute: 'VOID', note: '真空空間はVOIDで代替' },
|
|
19
|
+
'ATMOSPHERE': { substitute: 'Air', note: '大気はAirで代替' }
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// サポートされる材料一覧(マニフェストと同期)
|
|
23
|
+
static SUPPORTED_MATERIALS = [
|
|
24
|
+
'Carbon', 'Concrete', 'Iron', 'Lead', 'Aluminum',
|
|
25
|
+
'Copper', 'Tungsten', 'Air', 'Water', 'PyrexGlass',
|
|
26
|
+
'AcrylicResin', 'Polyethylene', 'Soil', 'VOID'
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 材料名の代替提案を取得
|
|
31
|
+
* @param {string} material - 入力された材料名
|
|
32
|
+
* @returns {Object|null} 代替情報またはnull
|
|
33
|
+
*/
|
|
34
|
+
static getAlternative(material) {
|
|
35
|
+
if (!material) return null;
|
|
36
|
+
|
|
37
|
+
// 大文字小文字を正規化
|
|
38
|
+
const normalizedMaterial = material.toUpperCase();
|
|
39
|
+
|
|
40
|
+
return this.ALTERNATIVES[normalizedMaterial] || null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 材料名のファジーマッチングによる提案
|
|
45
|
+
* @param {string} material - 入力された材料名
|
|
46
|
+
* @returns {string|null} 最も類似する材料名
|
|
47
|
+
*/
|
|
48
|
+
static findSimilarMaterial(material) {
|
|
49
|
+
if (!material) return null;
|
|
50
|
+
|
|
51
|
+
const input = material.toLowerCase();
|
|
52
|
+
|
|
53
|
+
// 部分一致による検索
|
|
54
|
+
for (const supported of this.SUPPORTED_MATERIALS) {
|
|
55
|
+
if (supported.toLowerCase().includes(input) ||
|
|
56
|
+
input.includes(supported.toLowerCase())) {
|
|
57
|
+
return supported;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 代替材料名での検索
|
|
62
|
+
for (const [alt, info] of Object.entries(this.ALTERNATIVES)) {
|
|
63
|
+
if (alt.toLowerCase().includes(input) ||
|
|
64
|
+
input.includes(alt.toLowerCase())) {
|
|
65
|
+
return info.substitute;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 包括的な材料チェックとエラー生成
|
|
74
|
+
* @param {string} material - チェック対象材料名
|
|
75
|
+
* @param {string} fieldName - フィールド名(エラー用)
|
|
76
|
+
* @throws {PokerMcpError} サポートされていない材料の場合
|
|
77
|
+
*/
|
|
78
|
+
static validateMaterialWithSuggestion(material, fieldName = 'material') {
|
|
79
|
+
if (!material) {
|
|
80
|
+
throw PokerMcpError.validationError('Material name is required', fieldName, material);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// サポートされている材料かチェック
|
|
84
|
+
if (this.SUPPORTED_MATERIALS.includes(material)) {
|
|
85
|
+
return true; // 正常
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 代替材料の提案
|
|
89
|
+
const alternative = this.getAlternative(material);
|
|
90
|
+
if (alternative) {
|
|
91
|
+
throw PokerMcpError.unsupportedMaterialWithSuggestion(
|
|
92
|
+
material,
|
|
93
|
+
alternative.substitute,
|
|
94
|
+
this.SUPPORTED_MATERIALS
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ファジーマッチングによる提案
|
|
99
|
+
const similar = this.findSimilarMaterial(material);
|
|
100
|
+
if (similar) {
|
|
101
|
+
throw PokerMcpError.unsupportedMaterialWithSuggestion(
|
|
102
|
+
material,
|
|
103
|
+
similar,
|
|
104
|
+
this.SUPPORTED_MATERIALS
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 一般的なエラー(提案なし)
|
|
109
|
+
throw PokerMcpError.validationError(
|
|
110
|
+
`Unsupported material: ${material}. Supported materials: ${this.SUPPORTED_MATERIALS.join(', ')}`,
|
|
111
|
+
fieldName,
|
|
112
|
+
material
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 材料特性情報の取得
|
|
118
|
+
* @param {string} material - 材料名
|
|
119
|
+
* @returns {Object|null} 材料特性情報
|
|
120
|
+
*/
|
|
121
|
+
static getMaterialInfo(material) {
|
|
122
|
+
if (!this.SUPPORTED_MATERIALS.includes(material)) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// マニフェストの material_constraints に対応
|
|
127
|
+
const materialInfo = {
|
|
128
|
+
'Carbon': {
|
|
129
|
+
typical_use: 'グラファイト、炭素繊維構造材',
|
|
130
|
+
shielding_properties: '軽量遮蔽材'
|
|
131
|
+
},
|
|
132
|
+
'Concrete': {
|
|
133
|
+
typical_use: '建築構造、放射線遮蔽壁',
|
|
134
|
+
shielding_properties: '汎用遮蔽材、経済的'
|
|
135
|
+
},
|
|
136
|
+
'Iron': {
|
|
137
|
+
typical_use: '鉄鋼構造、STEEL代替',
|
|
138
|
+
shielding_properties: '中重量遮蔽材、構造材兼用'
|
|
139
|
+
},
|
|
140
|
+
'Lead': {
|
|
141
|
+
typical_use: '高効率遮蔽材',
|
|
142
|
+
shielding_properties: '高密度γ線遮蔽材'
|
|
143
|
+
},
|
|
144
|
+
'Aluminum': {
|
|
145
|
+
typical_use: '軽量構造材',
|
|
146
|
+
shielding_properties: '軽量遮蔽材、耐食性'
|
|
147
|
+
},
|
|
148
|
+
'Copper': {
|
|
149
|
+
typical_use: 'BRASS/BRONZE代替',
|
|
150
|
+
shielding_properties: '中重量遮蔽材、導電性'
|
|
151
|
+
},
|
|
152
|
+
'Tungsten': {
|
|
153
|
+
typical_use: '超高密度遮蔽材',
|
|
154
|
+
shielding_properties: '最高密度遮蔽材'
|
|
155
|
+
},
|
|
156
|
+
'Air': {
|
|
157
|
+
typical_use: '大気、ATMOSPHERE代替',
|
|
158
|
+
shielding_properties: '透明媒体'
|
|
159
|
+
},
|
|
160
|
+
'Water': {
|
|
161
|
+
typical_use: '中性子減速材、冷却材',
|
|
162
|
+
shielding_properties: '中性子遮蔽材'
|
|
163
|
+
},
|
|
164
|
+
'PyrexGlass': {
|
|
165
|
+
typical_use: 'GLASS代替、耐熱ガラス',
|
|
166
|
+
shielding_properties: '透明遮蔽材'
|
|
167
|
+
},
|
|
168
|
+
'AcrylicResin': {
|
|
169
|
+
typical_use: 'PLASTIC代替、透明樹脂',
|
|
170
|
+
shielding_properties: '軽量透明遮蔽材'
|
|
171
|
+
},
|
|
172
|
+
'Polyethylene': {
|
|
173
|
+
typical_use: '中性子遮蔽樹脂',
|
|
174
|
+
shielding_properties: '中性子減速・遮蔽材'
|
|
175
|
+
},
|
|
176
|
+
'Soil': {
|
|
177
|
+
typical_use: 'EARTH代替、土壌遮蔽',
|
|
178
|
+
shielding_properties: '天然遮蔽材'
|
|
179
|
+
},
|
|
180
|
+
'VOID': {
|
|
181
|
+
density_specification: 'prohibited',
|
|
182
|
+
typical_use: '真空、VOID_SPACE代替',
|
|
183
|
+
shielding_properties: '非遮蔽領域'
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
return materialInfo[material] || null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// utils/errorHandler.js
|
|
2
|
+
import { logger } from './logger.js';
|
|
3
|
+
import { ValidationError, PhysicsError, DataError } from './errors.js';
|
|
4
|
+
|
|
5
|
+
export function handleError(error, req, res, next) {
|
|
6
|
+
const { id } = req.body || {};
|
|
7
|
+
|
|
8
|
+
logger.error('エラーが発生しました', {
|
|
9
|
+
error: error.message,
|
|
10
|
+
stack: error.stack,
|
|
11
|
+
request: {
|
|
12
|
+
method: req.method,
|
|
13
|
+
url: req.url,
|
|
14
|
+
body: req.body
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// エラータイプ別の処理
|
|
19
|
+
if (error instanceof ValidationError) {
|
|
20
|
+
return res.json({
|
|
21
|
+
jsonrpc: '2.0',
|
|
22
|
+
id: id,
|
|
23
|
+
error: {
|
|
24
|
+
code: -32602,
|
|
25
|
+
message: `入力値エラー: ${error.message}`,
|
|
26
|
+
data: {
|
|
27
|
+
field: error.field,
|
|
28
|
+
value: error.value
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (error instanceof PhysicsError) {
|
|
35
|
+
return res.json({
|
|
36
|
+
jsonrpc: '2.0',
|
|
37
|
+
id: id,
|
|
38
|
+
error: {
|
|
39
|
+
code: -32000,
|
|
40
|
+
message: `物理的制約エラー: ${error.message}`,
|
|
41
|
+
data: { type: error.code }
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (error instanceof DataError) {
|
|
47
|
+
return res.json({
|
|
48
|
+
jsonrpc: '2.0',
|
|
49
|
+
id: id,
|
|
50
|
+
error: {
|
|
51
|
+
code: -32001,
|
|
52
|
+
message: `データエラー: ${error.message}`,
|
|
53
|
+
data: { operation: error.operation }
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 予期しないエラー
|
|
59
|
+
return res.json({
|
|
60
|
+
jsonrpc: '2.0',
|
|
61
|
+
id: id,
|
|
62
|
+
error: {
|
|
63
|
+
code: -32603,
|
|
64
|
+
message: 'サーバー内部エラーが発生しました',
|
|
65
|
+
data: { timestamp: new Date().toISOString() }
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// utils/errors.js
|
|
2
|
+
export class ValidationError extends Error {
|
|
3
|
+
constructor(message, field = null, value = null) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = 'ValidationError';
|
|
6
|
+
this.field = field;
|
|
7
|
+
this.value = value;
|
|
8
|
+
this.code = 'VALIDATION_ERROR';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class PhysicsError extends Error {
|
|
13
|
+
constructor(message, type = 'PHYSICS_VIOLATION') {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'PhysicsError';
|
|
16
|
+
this.code = type;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class DataError extends Error {
|
|
21
|
+
constructor(message, operation = null) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = 'DataError';
|
|
24
|
+
this.operation = operation;
|
|
25
|
+
this.code = 'DATA_ERROR';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class CalculationError extends Error {
|
|
30
|
+
constructor(message, type = 'CALCULATION_ERROR', context = {}, mcpErrorCode = null) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.name = 'CalculationError';
|
|
33
|
+
this.code = type;
|
|
34
|
+
this.context = context;
|
|
35
|
+
this.mcpErrorCode = mcpErrorCode;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// utils/logger.js - MCP専用版(stdout汚染防止)
|
|
2
|
+
import winston from 'winston';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
const logger = winston.createLogger({
|
|
6
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
7
|
+
format: winston.format.combine(
|
|
8
|
+
winston.format.timestamp(),
|
|
9
|
+
winston.format.errors({ stack: true }),
|
|
10
|
+
winston.format.json()
|
|
11
|
+
),
|
|
12
|
+
transports: [
|
|
13
|
+
new winston.transports.File({
|
|
14
|
+
filename: path.join('logs', 'error.log'),
|
|
15
|
+
level: 'error'
|
|
16
|
+
}),
|
|
17
|
+
new winston.transports.File({
|
|
18
|
+
filename: path.join('logs', 'combined.log')
|
|
19
|
+
})
|
|
20
|
+
// Console transportは削除(MCPサーバーではstdout汚染禁止)
|
|
21
|
+
]
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export { logger };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// utils/logger.js - カラーコード無効化版
|
|
2
|
+
import winston from 'winston';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
const logger = winston.createLogger({
|
|
6
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
7
|
+
format: winston.format.combine(
|
|
8
|
+
winston.format.timestamp(),
|
|
9
|
+
winston.format.errors({ stack: true }),
|
|
10
|
+
winston.format.json()
|
|
11
|
+
),
|
|
12
|
+
transports: [
|
|
13
|
+
new winston.transports.File({
|
|
14
|
+
filename: path.join('logs', 'error.log'),
|
|
15
|
+
level: 'error'
|
|
16
|
+
}),
|
|
17
|
+
new winston.transports.File({
|
|
18
|
+
filename: path.join('logs', 'combined.log')
|
|
19
|
+
}),
|
|
20
|
+
new winston.transports.Console({
|
|
21
|
+
format: winston.format.combine(
|
|
22
|
+
winston.format.simple()
|
|
23
|
+
)
|
|
24
|
+
})
|
|
25
|
+
]
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export { logger };
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// utils/mcpErrors.js
|
|
2
|
+
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Poker MCP専用エラークラス
|
|
6
|
+
* マニフェストで定義された22個のカスタムエラーコードを実装
|
|
7
|
+
*/
|
|
8
|
+
export class PokerMcpError extends McpError {
|
|
9
|
+
// エラーコード定数
|
|
10
|
+
static BODY_NOT_FOUND = -32001;
|
|
11
|
+
static ZONE_NOT_FOUND = -32002;
|
|
12
|
+
static DUPLICATE_NAME = -32003;
|
|
13
|
+
static INVALID_BODY_TYPE = -32004;
|
|
14
|
+
static DEPENDENCY_EXISTS = -32005;
|
|
15
|
+
static FILE_ACCESS_ERROR = -32006;
|
|
16
|
+
static VALIDATION_ERROR = -32007;
|
|
17
|
+
static BACKUP_ERROR = -32008;
|
|
18
|
+
static UNIT_ALREADY_EXISTS = -32009;
|
|
19
|
+
static UNIT_NOT_FOUND = -32010;
|
|
20
|
+
static UNIT_INCOMPLETE = -32011;
|
|
21
|
+
static UNIT_KEY_MISSING = -32012;
|
|
22
|
+
static UNIT_INVALID_VALUE = -32013;
|
|
23
|
+
static UNIT_DELETE_FORBIDDEN = -32014;
|
|
24
|
+
static UNIT_REPAIR_FAILED = -32015;
|
|
25
|
+
static UNIT_VALIDATION_FAILED = -32016;
|
|
26
|
+
static TRANSFORM_NOT_FOUND = -32017;
|
|
27
|
+
static INVALID_TRANSFORM_REFERENCE = -32018;
|
|
28
|
+
static INVALID_NAME_FORMAT_HYPHENS = -32019;
|
|
29
|
+
static NAME_FORBIDDEN_CHARACTERS = -32020;
|
|
30
|
+
static INVALID_NUCLIDE_FORMAT = -32021;
|
|
31
|
+
static NUCLIDE_FORBIDDEN_HYPHEN = -32022;
|
|
32
|
+
static ATMOSPHERE_RESERVED = -32023;
|
|
33
|
+
static ATMOSPHERE_ZONE_MANDATORY = -32024;
|
|
34
|
+
static ATMOSPHERE_ZONE_DELETE_FORBIDDEN = -32025;
|
|
35
|
+
static ATMOSPHERE_ZONE_MUST_EXIST = -32026;
|
|
36
|
+
static ATMOSPHERE_MATERIAL_REQUIRED = -32027;
|
|
37
|
+
static VOID_DENSITY_PROHIBITED = -32028;
|
|
38
|
+
static NON_VOID_DENSITY_REQUIRED = -32029;
|
|
39
|
+
static MISSING_DENSITY_PARAMETER = -32030;
|
|
40
|
+
|
|
41
|
+
// 新しい必須パラメータエラーコード(Phase 1追加)
|
|
42
|
+
static CUTOFF_RATE_REQUIRED = -32050;
|
|
43
|
+
static SHOW_PATH_TRACE_REQUIRED = -32051;
|
|
44
|
+
static USE_SLANT_CORRECTION_REQUIRED = -32052;
|
|
45
|
+
static USE_FINITE_MEDIUM_CORRECTION_REQUIRED = -32053;
|
|
46
|
+
|
|
47
|
+
// 材料制約強化エラーコード
|
|
48
|
+
static UNSUPPORTED_MATERIAL_WITH_SUGGESTION = -32054;
|
|
49
|
+
|
|
50
|
+
constructor(code, message, field = null, value = null) {
|
|
51
|
+
super(code, message);
|
|
52
|
+
this.field = field;
|
|
53
|
+
this.value = value;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 便利メソッド:エラーコードから適切なエラーを生成
|
|
57
|
+
static bodyNotFound(name) {
|
|
58
|
+
return new PokerMcpError(this.BODY_NOT_FOUND, `Body not found: ${name}`, 'name', name);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static zoneNotFound(bodyName) {
|
|
62
|
+
return new PokerMcpError(this.ZONE_NOT_FOUND, `Zone not found: ${bodyName}`, 'body_name', bodyName);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static duplicateName(name, type = 'object') {
|
|
66
|
+
return new PokerMcpError(this.DUPLICATE_NAME, `Duplicate ${type} name: ${name}`, 'name', name);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static invalidBodyType(type) {
|
|
70
|
+
return new PokerMcpError(this.INVALID_BODY_TYPE, `Invalid body type: ${type}`, 'type', type);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static dependencyExists(name, dependencies) {
|
|
74
|
+
return new PokerMcpError(this.DEPENDENCY_EXISTS, `Cannot delete ${name} - dependencies exist: ${dependencies.join(', ')}`, 'name', name);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static fileAccessError(filename, operation) {
|
|
78
|
+
return new PokerMcpError(this.FILE_ACCESS_ERROR, `File access error: ${operation} failed for ${filename}`, 'filename', filename);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static validationError(message, field, value) {
|
|
82
|
+
return new PokerMcpError(this.VALIDATION_ERROR, message, field, value);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static backupError(message) {
|
|
86
|
+
return new PokerMcpError(this.BACKUP_ERROR, `Backup error: ${message}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
static unitAlreadyExists() {
|
|
90
|
+
return new PokerMcpError(this.UNIT_ALREADY_EXISTS, 'Unit section already exists');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
static unitNotFound() {
|
|
94
|
+
return new PokerMcpError(this.UNIT_NOT_FOUND, 'Unit section not found');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static unitIncomplete(missingKeys) {
|
|
98
|
+
return new PokerMcpError(this.UNIT_INCOMPLETE, `Unit section incomplete - missing keys: ${missingKeys.join(', ')}`, 'keys', missingKeys);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static unitKeyMissing(key) {
|
|
102
|
+
return new PokerMcpError(this.UNIT_KEY_MISSING, `Unit key missing: ${key}`, 'key', key);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static unitInvalidValue(key, value, validValues) {
|
|
106
|
+
return new PokerMcpError(this.UNIT_INVALID_VALUE, `Unit invalid value for ${key}: ${value}. Valid values: ${validValues.join(', ')}`, key, value);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
static unitDeleteForbidden() {
|
|
110
|
+
return new PokerMcpError(this.UNIT_DELETE_FORBIDDEN, 'Unit section cannot be deleted - use update instead');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static unitRepairFailed(reason) {
|
|
114
|
+
return new PokerMcpError(this.UNIT_REPAIR_FAILED, `Unit repair failed: ${reason}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static unitValidationFailed(details) {
|
|
118
|
+
return new PokerMcpError(this.UNIT_VALIDATION_FAILED, `Unit validation failed: ${details}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static transformNotFound(name) {
|
|
122
|
+
return new PokerMcpError(this.TRANSFORM_NOT_FOUND, `Transform not found: ${name}`, 'transform', name);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
static invalidTransformReference(name) {
|
|
126
|
+
return new PokerMcpError(this.INVALID_TRANSFORM_REFERENCE, `Invalid transform reference: ${name} does not exist in YAML transform section`, 'transform', name);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
static invalidNameFormatHyphens(name) {
|
|
130
|
+
return new PokerMcpError(this.INVALID_NAME_FORMAT_HYPHENS, `Invalid name format - hyphens not allowed: ${name}`, 'name', name);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static nameForbiddenCharacters(name, invalidChars) {
|
|
134
|
+
return new PokerMcpError(this.NAME_FORBIDDEN_CHARACTERS, `Name contains forbidden characters: ${name} (invalid: ${invalidChars.join(', ')})`, 'name', name);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static invalidNuclideFormat(nuclide) {
|
|
138
|
+
return new PokerMcpError(this.INVALID_NUCLIDE_FORMAT, `Invalid nuclide format - use concatenated format (e.g., Cs137): ${nuclide}`, 'nuclide', nuclide);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
static nuclideForbiddenHyphen(nuclide) {
|
|
142
|
+
return new PokerMcpError(this.NUCLIDE_FORBIDDEN_HYPHEN, `Nuclide contains forbidden hyphen: ${nuclide}`, 'nuclide', nuclide);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static atmosphereReserved(name) {
|
|
146
|
+
return new PokerMcpError(this.ATMOSPHERE_RESERVED, `ATMOSPHERE is reserved - cannot be used as body name: ${name}`, 'name', name);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static atmosphereZoneDeleteForbidden() {
|
|
150
|
+
return new PokerMcpError(this.ATMOSPHERE_ZONE_DELETE_FORBIDDEN, 'ATMOSPHERE zone is mandatory and cannot be deleted');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static voidDensityProhibited(density) {
|
|
154
|
+
return new PokerMcpError(this.VOID_DENSITY_PROHIBITED, `Density cannot be specified for VOID material: ${density}`, 'density', density);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
static nonVoidDensityRequired(material) {
|
|
158
|
+
return new PokerMcpError(this.NON_VOID_DENSITY_REQUIRED, `Density must be specified for non-VOID materials: ${material}`, 'material', material);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static missingDensityParameter(material) {
|
|
162
|
+
return new PokerMcpError(this.MISSING_DENSITY_PARAMETER, `Missing required density parameter for physical material: ${material}`, 'density', undefined);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 新しい必須パラメータエラー用便利メソッド
|
|
166
|
+
static cutoffRateRequired() {
|
|
167
|
+
return new PokerMcpError(this.CUTOFF_RATE_REQUIRED, 'cutoff_rate parameter is required for radiation shielding calculation accuracy', 'cutoff_rate', undefined);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
static showPathTraceRequired() {
|
|
171
|
+
return new PokerMcpError(this.SHOW_PATH_TRACE_REQUIRED, 'show_path_trace parameter is required for radiation path analysis', 'show_path_trace', undefined);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
static useSlantCorrectionRequired() {
|
|
175
|
+
return new PokerMcpError(this.USE_SLANT_CORRECTION_REQUIRED, 'use_slant_correction parameter is required for high-precision radiation shielding calculation', 'use_slant_correction', undefined);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
static useFiniteMediumCorrectionRequired() {
|
|
179
|
+
return new PokerMcpError(this.USE_FINITE_MEDIUM_CORRECTION_REQUIRED, 'use_finite_medium_correction parameter is required for accurate boundary effect analysis', 'use_finite_medium_correction', undefined);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
static unsupportedMaterialWithSuggestion(material, suggestedSubstitute, supportedList = []) {
|
|
183
|
+
const message = `Unsupported material '${material}'. Did you mean '${suggestedSubstitute}'? Supported materials: ${supportedList.join(', ')}`;
|
|
184
|
+
return new PokerMcpError(this.UNSUPPORTED_MATERIAL_WITH_SUGGESTION, message, 'material', material);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// エラーコードマッピング(逆引き用)
|
|
189
|
+
export const ERROR_CODE_MAP = {
|
|
190
|
+
[-32001]: 'Body not found',
|
|
191
|
+
[-32002]: 'Zone not found',
|
|
192
|
+
[-32003]: 'Duplicate name',
|
|
193
|
+
[-32004]: 'Invalid body type',
|
|
194
|
+
[-32005]: 'Dependency exists',
|
|
195
|
+
[-32006]: 'File access error',
|
|
196
|
+
[-32007]: 'Validation error',
|
|
197
|
+
[-32008]: 'Backup error',
|
|
198
|
+
[-32009]: 'Unit already exists',
|
|
199
|
+
[-32010]: 'Unit not found',
|
|
200
|
+
[-32011]: 'Unit incomplete',
|
|
201
|
+
[-32012]: 'Unit key missing',
|
|
202
|
+
[-32013]: 'Unit invalid value',
|
|
203
|
+
[-32014]: 'Unit delete forbidden',
|
|
204
|
+
[-32015]: 'Unit repair failed',
|
|
205
|
+
[-32016]: 'Unit validation failed',
|
|
206
|
+
[-32017]: 'Transform not found',
|
|
207
|
+
[-32018]: 'Invalid transform reference',
|
|
208
|
+
[-32019]: 'Invalid name format - hyphens not allowed',
|
|
209
|
+
[-32020]: 'Name contains forbidden characters',
|
|
210
|
+
[-32021]: 'Invalid nuclide format - use concatenated format',
|
|
211
|
+
[-32022]: 'Nuclide contains forbidden hyphen',
|
|
212
|
+
[-32023]: 'ATMOSPHERE is reserved - cannot be used as body name',
|
|
213
|
+
[-32024]: 'ATMOSPHERE zone is mandatory and cannot be deleted',
|
|
214
|
+
[-32025]: 'Multiple ATMOSPHERE zones not allowed',
|
|
215
|
+
[-32026]: 'ATMOSPHERE zone must exist in zone section',
|
|
216
|
+
[-32027]: 'ATMOSPHERE zone material assignment required',
|
|
217
|
+
[-32028]: 'Density cannot be specified for VOID material',
|
|
218
|
+
[-32029]: 'Density must be specified for non-VOID materials',
|
|
219
|
+
[-32030]: 'Missing required density parameter for physical material',
|
|
220
|
+
[-32050]: 'cutoff_rate parameter is required',
|
|
221
|
+
[-32051]: 'show_path_trace parameter is required',
|
|
222
|
+
[-32052]: 'use_slant_correction parameter is required',
|
|
223
|
+
[-32053]: 'use_finite_medium_correction parameter is required',
|
|
224
|
+
[-32054]: 'Unsupported material with suggestion'
|
|
225
|
+
};
|