poker-mcp 1.2.0 → 1.2.6

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/.mcp.json CHANGED
@@ -9,7 +9,8 @@
9
9
  "command": "node",
10
10
  "args": ["src/mcp_server_stdio_v4.js"],
11
11
  "env": {
12
- "NODE_ENV": "production"
12
+ "NODE_ENV": "production",
13
+ "POKER_INSTALL_PATH": "C:/Poker"
13
14
  }
14
15
  },
15
16
  "capabilities": {
@@ -65,7 +66,25 @@
65
66
  "pending_file": "tasks/pending_changes.json",
66
67
  "backup_directory": "backups",
67
68
  "logs_directory": "logs",
68
- "nuclide_database": "data/ICRP-07.NDX"
69
+ "data_directory": "data",
70
+ "nuclide_database": {
71
+ "target_file": "data/ICRP-07.NDX",
72
+ "source_env_var": "POKER_INSTALL_PATH",
73
+ "source_relative_path": "lib/ICRP-07.NDX",
74
+ "default_install_path": "C:/Poker",
75
+ "skip_if_exists": true,
76
+ "fallback_behavior": "error_if_missing"
77
+ }
78
+ },
79
+ "environment_variables": {
80
+ "POKER_INSTALL_PATH": {
81
+ "description": "POKERインストールディレクトリのパス",
82
+ "required": false,
83
+ "default": "C:/Poker",
84
+ "purpose": "lib/ICRP-07.NDXファイルの取得元ディレクトリ指定",
85
+ "example_windows": "C:/Program Files/POKER",
86
+ "example_linux": "/usr/local/share/poker"
87
+ }
69
88
  },
70
89
  "documentation": {
71
90
  "manifest": "config/mcp-manifest.json",
package/README.md CHANGED
@@ -4,13 +4,13 @@ YAML-based input file management tool for radiation-shielding calculation code P
4
4
 
5
5
  ## 📋 クイック情報
6
6
 
7
- - **バージョン**: 1.2.0 (Enhanced Release)
7
+ - **バージョン**: 1.2.5 (Enhanced Release)
8
8
  - **プロトコル**: MCP (Model Context Protocol) 1.0.0 完全準拠
9
9
  - **メインサーバー**: `src/mcp_server_stdio_v4.js`
10
10
  - **データ保存**: tasks/ディレクトリ(実行時自動作成)
11
11
  - **実行方式**: STDIO通信(MCPプロトコル標準)
12
12
 
13
- ## 🆕 バージョン1.2.0の新機能
13
+ ## 🆕 バージョン1.2.5の新機能
14
14
 
15
15
  ### ⚡ 衝突検出システム
16
16
  - **リアルタイム干渉チェック**: 立体間の重なり・接触を自動検出
@@ -48,7 +48,26 @@ npm install
48
48
  npx poker-mcp
49
49
  ```
50
50
 
51
- ### 2. Claude Desktop設定
51
+ ### 2. 環境変数設定(オプション)
52
+
53
+ **POKER_INSTALL_PATH環境変数**(オプション):
54
+ ```bash
55
+ # Windowsの場合(コマンドプロンプト)
56
+ set POKER_INSTALL_PATH=C:/Poker
57
+
58
+ # Windowsの場合(PowerShell)
59
+ $env:POKER_INSTALL_PATH="C:/Poker"
60
+
61
+ # Linux/macOSの場合
62
+ export POKER_INSTALL_PATH="/usr/local/share/poker"
63
+ ```
64
+
65
+ - **デフォルト値**: `C:/Poker`
66
+ - **目的**: `lib/ICRP-07.NDX`核種データベースファイルの取得元ディレクトリ指定
67
+ - **動作**: 初回起動時に`{POKER_INSTALL_PATH}/lib/ICRP-07.NDX`を`data/`ディレクトリにコピー
68
+ - **注意**: `data/ICRP-07.NDX`が既に存在する場合はコピーをスキップ
69
+
70
+ ### 3. Claude Desktop設定
52
71
 
53
72
  **Claude Desktop アプリでの設定方法:**
54
73
 
@@ -66,7 +85,9 @@ npx poker-mcp
66
85
  "poker-mcp": {
67
86
  "command": "node",
68
87
  "args": ["C:\\Users\\yoshi\\Desktop\\poker_mcp\\src\\mcp_server_stdio_v4.js"],
69
- "env": {}
88
+ "env": {
89
+ "POKER_INSTALL_PATH": "C:/Poker"
90
+ }
70
91
  }
71
92
  }
72
93
  }
@@ -79,7 +100,9 @@ npx poker-mcp
79
100
  "poker-mcp": {
80
101
  "command": "npx",
81
102
  "args": ["poker-mcp"],
82
- "env": {}
103
+ "env": {
104
+ "POKER_INSTALL_PATH": "C:/Poker"
105
+ }
83
106
  }
84
107
  }
85
108
  }
@@ -87,7 +110,11 @@ npx poker-mcp
87
110
 
88
111
  4. **Claude Desktopを再起動** してMCPサーバーを有効化
89
112
 
90
- ### 3. 動作確認
113
+ **注意**:
114
+ - `env`セクションの`POKER_INSTALL_PATH`はオプションです(省略時は`C:/Poker`を使用)
115
+ - 環境変数で指定したパスの`lib/ICRP-07.NDX`ファイルが初回起動時に`data/`にコピーされます
116
+
117
+ ### 4. 動作確認
91
118
  Claude Desktopで以下のようにテストできます:
92
119
  ```
93
120
  放射線遮蔽計算用のコンクリート壁(100cm x 50cm x 30cm)を作成してください
@@ -255,7 +282,7 @@ poker_mcp/
255
282
  - **エラー回復**: ロールバック機能付き
256
283
  - **レスポンス速度**: <50ms応答時間
257
284
 
258
- ### **✅ エラーハンドリング強化(v1.2.0)**
285
+ ### **✅ エラーハンドリング強化(v1.2.5)**
259
286
  - **propose/update自動判別**: エラーメッセージによる適切なメソッド案内
260
287
  - **専用エラーコード**: 各操作に固有のエラーコード体系
261
288
  - **材料名サジェスト**: 類似材料名の自動提案機能
@@ -296,7 +323,7 @@ poker_mcp/
296
323
 
297
324
  ## 📝 更新履歴
298
325
 
299
- ### v1.2.0 (2025-01-24)
326
+ ### v1.2.5 (2025-01-24)
300
327
  - ✨ 衝突検出システム実装
301
328
  - ✨ 子孫核種自動補完機能追加(ICRP-07統合)
302
329
  - ✨ 単位系完全性検証強化(4キー保証)
@@ -326,6 +353,6 @@ poker_mcp/
326
353
 
327
354
  ---
328
355
 
329
- **🎯 Poker MCP Server v1.2.0**
356
+ **🎯 Poker MCP Server v1.2.5**
330
357
  **プロトコル**: MCP 1.0.0 完全準拠
331
358
  **作者**: Yoshihiro Hirao | **ライセンス**: ISC
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "poker-mcp",
3
- "version": "1.2.0",
4
- "description": "YAML-based input file management tool for radiation shielding calculation code POKER with MCP support - Enhanced with collision detection and daughter nuclide auto-completion",
3
+ "version": "1.2.6",
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
5
  "main": "src/mcp_server_stdio_v4.js",
6
6
  "type": "module",
7
7
  "bin": {
@@ -48,7 +48,6 @@
48
48
  },
49
49
  "files": [
50
50
  "src/",
51
- "data/",
52
51
  "README.md",
53
52
  ".mcp.json"
54
53
  ]
@@ -1,14 +1,21 @@
1
1
  // src/config/ConfigManager.js
2
2
  import fs from 'fs/promises';
3
3
  import path from 'path';
4
+ import { fileURLToPath } from 'url';
4
5
  import { logger } from '../utils/logger.js';
5
6
  import { DataError } from '../utils/errors.js';
7
+ import { USER_CONFIG } from '../utils/paths.js';
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
6
11
 
7
12
  export class ConfigManager {
8
13
  constructor() {
9
14
  this.config = null;
10
- this.configPath = 'src/config/default.json';
11
- this.userConfigPath = 'config.json';
15
+ // default.json はパッケージ同梱なので __dirname 基準の絶対パスで解決
16
+ this.configPath = path.join(__dirname, 'default.json');
17
+ // ユーザー設定は POKER_MCP_HOME 配下に置く
18
+ this.userConfigPath = USER_CONFIG;
12
19
  }
13
20
 
14
21
  async load() {
package/src/mcp/server.js CHANGED
@@ -7,9 +7,10 @@ import { allTools } from './tools/index.js';
7
7
  import { createAllHandlers } from './handlers/index.js';
8
8
  import { safeExecute } from './middleware/errorHandler.js';
9
9
  import { logger } from '../utils/logger.js';
10
+ import { YAML_FILE, PENDING_FILE } from '../utils/paths.js';
10
11
 
11
12
  export class PokerMcpServer {
12
- constructor(yamlFile = 'tasks/poker.yaml', pendingFile = 'tasks/pending_changes.json') {
13
+ constructor(yamlFile = YAML_FILE, pendingFile = PENDING_FILE) {
13
14
  this.server = new Server(
14
15
  {
15
16
  name: 'poker-mcp',
@@ -1,45 +1,47 @@
1
- #!/usr/bin/env node
2
- // mcp_server_stdio_v4.js - MCP専用版(stdout汚染防止)
3
- import { PokerMcpServer } from './mcp/server.js';
4
- import { logger } from './utils/logger.js';
5
-
6
- async function main() {
7
- try {
8
- const server = new PokerMcpServer();
9
- await server.initialize();
10
- await server.start();
11
- } catch (error) {
12
- logger.error('サーバー起動失敗', { error: error.message });
13
- // console.errorは削除(stdout汚染防止)
14
- process.exit(1);
15
- }
16
- }
17
-
18
- // 未処理の例外とプロミス拒否のハンドリング
19
- process.on('uncaughtException', (error) => {
20
- logger.error('Uncaught Exception', { error: error.message, stack: error.stack });
21
- // console.errorは削除(stdout汚染防止)
22
- process.exit(1);
23
- });
24
-
25
- process.on('unhandledRejection', (reason, promise) => {
26
- logger.error('Unhandled Rejection', { reason: reason?.message || reason, promise });
27
- // console.errorは削除(stdout汚染防止)
28
- process.exit(1);
29
- });
30
-
31
- // グレースフルシャットダウン
32
- process.on('SIGINT', () => {
33
- logger.info('SIGINT受信、サーバーを終了します');
34
- process.exit(0);
35
- });
36
-
37
- process.on('SIGTERM', () => {
38
- logger.info('SIGTERM受信、サーバーを終了します');
39
- process.exit(0);
40
- });
41
-
42
- main().catch((error) => {
43
- logger.error('メイン関数エラー', { error: error.message });
44
- process.exit(1);
45
- });
1
+ #!/usr/bin/env node
2
+ // mcp_server_stdio_v4.js - MCP専用版(stdout汚染防止)
3
+ import { PokerMcpServer } from './mcp/server.js';
4
+ import { logger } from './utils/logger.js';
5
+
6
+ async function main() {
7
+ try {
8
+ const server = new PokerMcpServer();
9
+ await server.initialize();
10
+ await server.start();
11
+ } catch (error) {
12
+ logger.error('サーバー起動失敗', { error: error.message });
13
+ // stdoutは汚染禁止だが、stderrへの出力は許容(Claude Desktopがログに記録する)
14
+ process.stderr.write(`[poker-mcp] Fatal: ${error.message}\n`);
15
+ process.exit(1);
16
+ }
17
+ }
18
+
19
+ // 未処理の例外とプロミス拒否のハンドリング
20
+ process.on('uncaughtException', (error) => {
21
+ logger.error('Uncaught Exception', { error: error.message, stack: error.stack });
22
+ process.stderr.write(`[poker-mcp] Uncaught Exception: ${error.message}\n`);
23
+ process.exit(1);
24
+ });
25
+
26
+ process.on('unhandledRejection', (reason, promise) => {
27
+ logger.error('Unhandled Rejection', { reason: reason?.message || reason, promise });
28
+ process.stderr.write(`[poker-mcp] Unhandled Rejection: ${reason?.message || reason}\n`);
29
+ process.exit(1);
30
+ });
31
+
32
+ // グレースフルシャットダウン
33
+ process.on('SIGINT', () => {
34
+ logger.info('SIGINT受信、サーバーを終了します');
35
+ process.exit(0);
36
+ });
37
+
38
+ process.on('SIGTERM', () => {
39
+ logger.info('SIGTERM受信、サーバーを終了します');
40
+ process.exit(0);
41
+ });
42
+
43
+ main().catch((error) => {
44
+ logger.error('メイン関数エラー', { error: error.message });
45
+ process.stderr.write(`[poker-mcp] Main error: ${error.message}\n`);
46
+ process.exit(1);
47
+ });
@@ -7,13 +7,16 @@ import { DataError } from '../utils/errors.js';
7
7
  import CollisionDetector from '../utils/CollisionDetector.js';
8
8
  import NuclideManager from '../utils/NuclideManager.js';
9
9
  import EnhancedValidator from '../utils/EnhancedValidator.js';
10
+ import { BACKUPS_DIR, LOGS_DIR, TASKS_DIR, DATA_DIR, NDX_FILE,
11
+ YAML_FILE, PENDING_FILE } from '../utils/paths.js';
10
12
 
11
13
  export class SafeDataManager {
12
14
  constructor(yamlFile, pendingFile) {
13
- this.yamlFile = yamlFile;
14
- this.pendingFile = pendingFile;
15
- this.backupDir = 'backups';
16
- this.maxBackups = 10;
15
+ // 引数が省略された場合は paths.js の絶対パスをデフォルトとして使用
16
+ this.yamlFile = yamlFile ?? YAML_FILE;
17
+ this.pendingFile = pendingFile ?? PENDING_FILE;
18
+ this.backupDir = BACKUPS_DIR;
19
+ this.maxBackups = 10;
17
20
  this.data = null;
18
21
  this.pendingChanges = [];
19
22
 
@@ -24,11 +27,11 @@ export class SafeDataManager {
24
27
  max_auto_corrections: 10
25
28
  });
26
29
 
27
- // 核種管理の初期化
30
+ // 核種管理の初期化(絶対パスを使用)
28
31
  this.nuclideManager = new NuclideManager({
29
32
  contribution_threshold: 0.05,
30
33
  user_confirmation: true,
31
- database_file: 'data/ICRP-07.NDX'
34
+ database_file: NDX_FILE
32
35
  });
33
36
 
34
37
  // 強化検証の初期化
@@ -41,10 +44,14 @@ export class SafeDataManager {
41
44
 
42
45
  async initialize() {
43
46
  try {
44
- // 必要なフォルダをすべて作成
45
- await fs.mkdir(this.backupDir, { recursive: true }); // backups
46
- await fs.mkdir('logs', { recursive: true }); // logs
47
- await fs.mkdir('tasks', { recursive: true }); // tasks
47
+ // 必要なフォルダをすべて作成(絶対パスで権限エラーを回避)
48
+ await fs.mkdir(BACKUPS_DIR, { recursive: true }); // backups
49
+ await fs.mkdir(LOGS_DIR, { recursive: true }); // logs
50
+ await fs.mkdir(TASKS_DIR, { recursive: true }); // tasks
51
+ await fs.mkdir(DATA_DIR, { recursive: true }); // data
52
+
53
+ // 必要なデータファイルをコピー
54
+ await this.ensureDataFiles();
48
55
 
49
56
  // 初期ファイル配置(既存ファイルがない場合のみ)
50
57
  await this.ensureInitialFiles();
@@ -63,6 +70,85 @@ export class SafeDataManager {
63
70
  }
64
71
  }
65
72
 
73
+ // 新規メソッド: 必要なデータファイルの確保
74
+ async ensureDataFiles() {
75
+ try {
76
+ const targetFile = NDX_FILE; // 絶対パスを使用
77
+
78
+ // ターゲットファイルの存在チェック
79
+ try {
80
+ await fs.access(targetFile);
81
+ logger.info('ICRP-07データベースファイルは既に存在します。コピーをスキップします。', {
82
+ file: targetFile
83
+ });
84
+ return; // 既に存在する場合は何もしない
85
+ } catch (targetError) {
86
+ if (targetError.code !== 'ENOENT') {
87
+ // アクセス権限などの別のエラー
88
+ throw targetError;
89
+ }
90
+ // ファイルが存在しない場合は以下の処理を続行
91
+ }
92
+
93
+ // 環境変数からインストールパスを取得(デフォルト値設定)
94
+ const installPath = process.env.POKER_INSTALL_PATH || 'C:/Poker';
95
+ logger.info('POKERインストールパスを確認', { installPath });
96
+
97
+ const sourceFile = path.join(installPath, 'lib', 'ICRP-07.NDX');
98
+
99
+ // ソースファイルの存在チェック
100
+ try {
101
+ await fs.access(sourceFile);
102
+ logger.info('ソースファイルが見つかりました', { sourceFile });
103
+ } catch (sourceError) {
104
+ if (sourceError.code === 'ENOENT') {
105
+ logger.error('ソースファイルが見つかりません', {
106
+ expectedPath: sourceFile,
107
+ installPath: installPath,
108
+ environmentVariable: 'POKER_INSTALL_PATH',
109
+ suggestion: installPath === 'C:/Poker'
110
+ ? 'POKER_INSTALL_PATH環境変数を正しいインストールディレクトリに設定してください'
111
+ : 'インストールディレクトリに lib/ICRP-07.NDX ファイルが存在することを確認してください'
112
+ });
113
+ throw new DataError(
114
+ `必要なデータファイルが見つかりません: ${sourceFile}`,
115
+ 'MISSING_SOURCE_FILE'
116
+ );
117
+ } else {
118
+ throw sourceError;
119
+ }
120
+ }
121
+
122
+ // ファイルをコピー
123
+ try {
124
+ await fs.copyFile(sourceFile, targetFile);
125
+ logger.info('ICRP-07データベースファイルをコピーしました', {
126
+ from: sourceFile,
127
+ to: targetFile
128
+ });
129
+ } catch (copyError) {
130
+ logger.error('ファイルのコピーに失敗しました', {
131
+ error: copyError.message,
132
+ sourceFile,
133
+ targetFile
134
+ });
135
+ throw copyError;
136
+ }
137
+
138
+ // コピー完了後のファイルサイズ確認
139
+ const finalStats = await fs.stat(targetFile);
140
+ logger.info('ICRP-07データベースファイルのコピーが完了しました', {
141
+ file: targetFile,
142
+ size: finalStats.size,
143
+ readable: true
144
+ });
145
+
146
+ } catch (error) {
147
+ logger.error('データファイル確保エラー', { error: error.message });
148
+ throw error;
149
+ }
150
+ }
151
+
66
152
  // 新規メソッド: 初期ファイルの確実な配置
67
153
  async ensureInitialFiles() {
68
154
  try {
@@ -1,24 +1,29 @@
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 };
1
+ // utils/logger.js - MCP専用版(stdout汚染防止)
2
+ import winston from 'winston';
3
+ import path from 'path';
4
+ import fs from 'fs';
5
+ import { LOGS_DIR } from './paths.js';
6
+
7
+ // ログディレクトリを起動時に確実に作成(相対パス問題を回避)
8
+ fs.mkdirSync(LOGS_DIR, { recursive: true });
9
+
10
+ const logger = winston.createLogger({
11
+ level: process.env.LOG_LEVEL || 'info',
12
+ format: winston.format.combine(
13
+ winston.format.timestamp(),
14
+ winston.format.errors({ stack: true }),
15
+ winston.format.json()
16
+ ),
17
+ transports: [
18
+ new winston.transports.File({
19
+ filename: path.join(LOGS_DIR, 'error.log'),
20
+ level: 'error'
21
+ }),
22
+ new winston.transports.File({
23
+ filename: path.join(LOGS_DIR, 'combined.log')
24
+ })
25
+ // Console transportは削除(MCPサーバーではstdout汚染禁止)
26
+ ]
27
+ });
28
+
29
+ export { logger };
@@ -0,0 +1,24 @@
1
+ // utils/paths.js - 実行時データの格納先を一元管理
2
+ //
3
+ // 優先順位:
4
+ // 1. 環境変数 POKER_MCP_HOME が設定されていれば、その値を使用
5
+ // 2. 未設定なら os.homedir()/.poker-mcp/ をデフォルトとする
6
+ //
7
+ // claude_desktop_config.json での設定例:
8
+ // "env": { "POKER_MCP_HOME": "C:\\Users\\yoshi\\poker_mcp_workspace" }
9
+ //
10
+ import path from 'path';
11
+ import os from 'os';
12
+
13
+ export const BASE_DIR = process.env.POKER_MCP_HOME
14
+ ?? path.join(os.homedir(), '.poker-mcp');
15
+
16
+ export const LOGS_DIR = path.join(BASE_DIR, 'logs');
17
+ export const TASKS_DIR = path.join(BASE_DIR, 'tasks');
18
+ export const BACKUPS_DIR = path.join(BASE_DIR, 'backups');
19
+ export const DATA_DIR = path.join(BASE_DIR, 'data');
20
+
21
+ export const YAML_FILE = path.join(TASKS_DIR, 'poker.yaml');
22
+ export const PENDING_FILE = path.join(TASKS_DIR, 'pending_changes.json');
23
+ export const NDX_FILE = path.join(DATA_DIR, 'ICRP-07.NDX');
24
+ export const USER_CONFIG = path.join(BASE_DIR, 'config.json');