spss-stats-mcp
by YokeSin
README.md
# spss-stats-mcp
IBM SPSS Statistics のシンタックス(.sps)を、コーディングエージェント
(IBM Bob など)から**安全に**バッチ実行するための
MCP サーバーです。
エージェントが IBM Documentation 検索 MCP などで公式ドキュメントを参照
しながら生成した SPSS シンタックスを、**静的安全検査**したうえで
**Desktop 版 IBM SPSS Statistics の `stats.exe`(Production モード)** で
実行し、結果テキスト/HTML を回収して返します。
- **通常の Python + pip だけで動きます。**
- **設定ファイルなしでも動きます。** `stats.exe` は標準インストール場所から
自動検出し、サンドボックスはエージェントのワークスペースになります。
- **設定に問題があってもサーバーは起動します**(fail-soft 起動)。原因と
直し方はツール応答(`get_spss_mcp_info` など)で確認でき、直せば再起動
不要で復帰します。設定が無効な間は一切実行しません(fail-closed 実行)。
- 実行バックエンドは **`stats.exe` Production モード専用**です
(Statistics Server / `statisticsb.exe` のサポートは削除しました)。
## 設計思想
このMCPは **「安全な実行ゲートウェイ」に徹します**。意図的に多機能化していません。
| 役割 | 担当 |
|---|---|
| シンタックスの安全検査と実行 | **このMCP** |
| シンタックス仕様・コマンドリファレンスの確認 | IBM Documentation 検索 MCP |
| 分析手法の選択・実行支援・結果解釈 | エージェントの Skills |
> IBM Documentation 検索 MCP: [hkwd/ibm-docs-mcp](https://github.com/hkwd/ibm-docs-mcp)
> (IBM 製品ドキュメントを検索・参照する MCP サーバー。本 MCP とは独立しており、無くても動作します)
安全方針は **fail-closed(疑わしきは実行しない)** です。
## 提供ツール(3つのみ)
| ツール | 説明 |
|---|---|
| `validate_spss_syntax` | 実行せず安全検査のみ。エージェントの事前自己修正用 |
| `execute_spss_syntax` | 安全検査 → `stats.exe` でバッチ実行 → 出力回収 |
| `get_spss_mcp_info` | サンドボックス設定の確認(秘密情報は含まない) |
## 必要要件
- **Python 3.10 以上** と **pip**
- Python パッケージ **`mcp`**(`pip install -e .` で自動インストール)
- **IBM SPSS Statistics Desktop**(v29/v30 で動作確認)
- `stats.exe` が存在し、Production モードで実行できること
(例: `C:\Program Files\IBM\SPSS Statistics\stats.exe`)
- 有効な SPSS ライセンス
- 読み書き可能な作業フォルダ(`allowed_directories` に設定)
- MCP クライアント(IBM Bob など)
- (任意)IBM Documentation 検索 MCP(例: [hkwd/ibm-docs-mcp](https://github.com/hkwd/ibm-docs-mcp))
— エージェントがシンタックス仕様を公式ドキュメントで裏取りしながら書けるようになります
> 補足: PATH の `python` が Microsoft Store のスタブの環境では、
> 実体のある Python(例: `C:\Program Files\IBM\SPSS Statistics\Python3\python.exe`
> や python.org 版)のフルパスを使ってください。
## インストール
### 最短ルート(推奨)
```bat
rem 1) リポジトリを取得(配置場所は任意)
git clone https://github.com/YokeSin/spss-stats-mcp.git
cd spss-stats-mcp
rem 2) セットアップ(リポジトリ直下に .venv を作成し、依存 mcp を導入)
setup.cmd
```
あとは MCP クライアント設定の `command` に
**`bin\spss-stats-mcp.cmd` の絶対パス**を書くだけです
(下記「MCP クライアントへの登録」)。ランチャーが適切な Python を
自動選択するため、Python のパスを調べて設定に書く必要はありません。
- mcp SDK 導入済みの Python が既に PATH にある場合、`setup.cmd` の実行すら
不要です(ランチャーがその Python を自動発見し、`src/` を直接 import して
動きます。pip install も不要)。
- ランチャーの Python 探索順: ①環境変数 `SPSS_STATS_MCP_PYTHON`
②リポジトリ直下 `.venv` ③`%USERPROFILE%\.venvs\spss-stats-mcp`
④PATH 上の python / py ランチャーのうち mcp SDK を import できるもの
### 手動セットアップ(任意の Python 環境に入れる場合)
```bat
rem 仮想環境を任意の場所に作成(例: %USERPROFILE%\.venvs\spss-stats-mcp)
python -m venv "%USERPROFILE%\.venvs\spss-stats-mcp"
rem インストール(依存パッケージ mcp も入る)
"%USERPROFILE%\.venvs\spss-stats-mcp\Scripts\python" -m pip install .
```
- インストール後は `<インストール先のpython> -m spss_stats_mcp.server`
(または `python -m spss_stats_mcp` / console script `spss-stats-mcp`)で
起動できます。実際の起動は MCP クライアントが行うため、手動で常駐させる
必要はありません。
- ソースを編集しながら使う場合は `pip install -e .`(editable)にすると、
リポジトリの変更が即座に反映されます。
- クローンせずに GitHub から直接インストールすることもできます:
`pip install git+https://github.com/YokeSin/spss-stats-mcp.git`
### 設定ファイル(config.json)— 任意
**config.json はなくても動きます。** 無い場合は次の既定値で起動します:
- `executable` … 標準インストール場所から `stats.exe` を**自動検出**
(`C:\Program Files\IBM\SPSS Statistics\stats.exe`、バージョン番号付きの
旧レイアウトにも対応。複数あれば新しいバージョンを優先)
- `allowed_directories` … `["${workspace}"]`(エージェントのワークスペース)
- `audit_log` … `~/.spss-stats-mcp/logs/audit.jsonl`
タイムアウト等をカスタマイズしたい場合のみ、`config.json.example` を参考に
`config.json` を作成します。探索順:
1. 環境変数 `SPSS_STATS_MCP_CONFIG` で指定されたパス
2. サーバープロセスのカレントディレクトリ
3. **リポジトリ直下**(クローン/editable 運用の場合。MCP クライアントが
どんな cwd でサーバーを起動しても見つかります)
4. `~/.spss-stats-mcp/config.json`
パス系の値(`executable` / `allowed_directories` / `audit_log` /
`SPSS_STATS_MCP_CONFIG`)では、先頭の `~` がホームディレクトリに展開されます。
`audit_log` の相対パスは config.json のあるフォルダ基準で解決されます。
| キー | 説明 |
|---|---|
| `executable` | 任意。Desktop 版 `stats.exe` のフルパス。未指定なら自動検出。環境変数 `SPSS_STATS_MCP_EXECUTABLE` での上書きが最優先 |
| `allowed_directories` | 任意(既定 `["${workspace}"]`)。AIが読み書きできる範囲(下記) |
| `default_output_type` | 出力形式の既定。`text`(既定)または `html` |
| `allowed_output_types` | 許可する出力形式。既定 `["text", "html"]` |
| `timeout_seconds` | 実行タイムアウトの既定(秒)。既定 300 |
| `max_timeout_seconds` | エージェントが指定できるタイムアウトの上限。既定 1800 |
| `max_output_chars` | 返却する出力の文字数上限(LLMコンテキスト保護)。既定 50000 |
| `audit_log` | 監査ログ(JSONL)の出力先。`~` や `${workspace}` が使える。親フォルダは起動時に自動作成。`null` で無効 |
| `env` | SPSS 実行プロセスへの追加環境変数。値は `{env:VAR名}` で参照可 |
| `safety` | 安全検査の調整(下記「高度な設定」) |
| `command_template` / `spj_template` | 通常は不要。実行コマンド/自動生成 `.spj` の上書き用 |
#### `allowed_directories` と `${workspace}` トークン(推奨設定)
`allowed_directories` に **`"${workspace}"`** と書くと、起動時に
「エージェントが管理しているワークスペース」に解決されます。解決順:
1. 環境変数 **`SPSS_MCP_WORKSPACE`**(クライアント設定の `env` で明示。**推奨**)
2. サーバープロセスのカレントディレクトリ(フォールバック。MCP クライアント
が cwd をどこにして起動するかはクライアント実装依存のため、env の明示が確実)
エージェント自身のファイル操作権限(ワークスペース内)と SPSS 実行の
サンドボックスが**同じ境界**になるため、これが推奨です。`audit_log` の
値でも `${workspace}` は使えます。固定パス(例: `C:\\projects\\spss-work`)も
指定できます。
> ⚠️ 広すぎるディレクトリは**拒否**されます:
> ドライブルート(`C:\` 等)、ホームディレクトリとその親(`C:\Users` 等)、
> Windows システム領域(`C:\Windows`、`Program Files` 等)。
> `${workspace}` がこれらに解決された場合も同様です。この場合もサーバー自体は
> 起動を継続し、ツールが `config_error` として原因と直し方を返します
> (実行は一切されません)。
### MCP クライアントへの登録
書くのは実質2つだけです。**`cwd` の指定は不要**です(サーバーは cwd に
依存しません。MCP クライアントが cwd をどこにして起動しても動きます):
- `command` … **ランチャー `bin\spss-stats-mcp.cmd` の絶対パス**(推奨)。
または spss-stats-mcp をインストールした Python のフルパス +
`args: ["-m", "spss_stats_mcp.server"]`
- `env.SPSS_MCP_WORKSPACE` … **ワークスペース(プロジェクトのルート)の
絶対パス**。`${workspace}` サンドボックスの解決先になります。
未指定時はサーバー起動時の cwd にフォールバックしますが、IBM Bob のように
cwd の扱いが不定なクライアントでは必ず明示してください
一般的な stdio MCP クライアント(JSON 形式)、ランチャー使用:
```json
{
"mcpServers": {
"spss-stats-mcp": {
"command": "C:\\path\\to\\spss-stats-mcp\\bin\\spss-stats-mcp.cmd",
"env": {
"SPSS_MCP_WORKSPACE": "C:\\path\\to\\your-workspace"
}
}
}
}
```
IBM Bob(プロジェクトの `.bob/mcp.json` や
`C:\Users\<ユーザー名>\.bob\settings\mcp_settings.json`)も同じ JSON 形式です。
Python を直接指定する場合の例(`.cmd` を起動できないクライアント向け):
```json
{
"mcpServers": {
"spss-stats-mcp": {
"command": "C:\\Users\\<ユーザー名>\\.venvs\\spss-stats-mcp\\Scripts\\python.exe",
"args": ["-m", "spss_stats_mcp.server"],
"env": {
"SPSS_MCP_WORKSPACE": "C:\\path\\to\\your-workspace"
}
}
}
}
```
`get_spss_mcp_info` の `diagnostics` に `bob_workspace_resolved_from_cwd` が
出た場合は、`env` の `SPSS_MCP_WORKSPACE` 設定を確認してください。
### 起動時の挙動と診断(fail-soft 起動 / fail-closed 実行)
- **設定に問題があってもサーバーは必ず起動してツールを登録します。**
起動時にクラッシュするとクライアントからは「ツールが存在しない」
(IBM Bob では `Tool does not exist`)ようにしか見えず、原因究明が
非常に難しいためです。
- 設定が無効な間、`validate_spss_syntax` / `execute_spss_syntax` は
`status: "config_error"` と原因(`reason`)・直し方(`fix`)を返し、
**実行は一切行いません**(fail-closed)。
- `get_spss_mcp_info` は常に応答します。`status` の値:
- `ok` … 実行可能
- `executable_not_found` … stats.exe 未検出(validate のみ利用可)。
`diagnostics` に検出を試みた経緯が入ります
- `config_error` … 設定不備。`reason` / `fix` / `config_search_paths` 参照
- **設定を直した後のクライアント再起動は不要です。** 次のツール呼び出しで
自動的に再読込・復帰します(stats.exe の後付けインストールも同様)。
- 起動経緯はクライアントの MCP ログで `[spss-stats-mcp] ready(...)` /
`[spss-stats-mcp] 設定エラー: ...` の行からも確認できます(stderr 出力)。
## 実行のしくみ(stats.exe Production モード)
Desktop 版の `stats.exe` は `.sps` を直接バッチ実行**できません**。
IBM 公式の非対話実行は Production ジョブ(`.spj`)経由で、コマンドは
`stats.exe <job>.spj -production silent` です
(IBM Docs: "Running production jobs from a command line")。
本MCPは実行のたびに:
1. 検査済みシンタックスに **OMS(Output Management System)を注入**し、
結果(テーブル・テキスト・見出し・警告)を text/html として
出力ファイルへ直接書き出すようにする
2. 一時 `.sps` と一時 `.spj` を **`allowed_directories` 配下に**自動生成する
3. `stats.exe <一時.spj> -production silent` を実行する(shell=False)
4. 出力ファイルを回収して返し、一時 `.sps` / `.spj` / 使い捨て Viewer(`.spv`)
を削除する(人間可読な出力ファイルは検証・再利用のため残す)
OMS を使うのは、`stats.exe -production` の `.spj` が
`<output outputFormat="text">` を解釈せず常に Viewer 文書(`.spv` = バイナリ)
を書き出すためです。`.spj` の役割は「シンタックスを実行する」ことだけで、
副産物の `.spv` は使い捨てにします。
- 出力エンコーディングは SPSS のセッションモードに追随します
(Unicode モード→UTF-8、コードページモード→ロケールのコードページ)。
MCP は両者を判別して正しく読みます。
- 自動生成する `.spj` は **v29/v30 想定**の組み込みテンプレートです。
他バージョンで実行に失敗する場合は、SPSS 本体の
**Utilities → Production Facility** から動作する `.spj` を書き出し、
パス部分をプレースホルダーに置換して `config.json` の **`spj_template`** に
貼り付けて上書きできます(コード変更不要):
- `{syntax_file}` … 実行する一時 `.sps` の絶対パス
- `{viewer_file}` … 使い捨て Viewer(`.spv`)の絶対パス。
**`<output>` はこちらを指すこと**(`{output_file}` を指すと OMS の
出力と書き込み先が衝突します)
- `{output_file}` … MCP が回収する出力ファイル(OMS の書き込み先)
- `{output_dir}` / `{output_format}` … 出力ディレクトリ / `text`・`html`
## セキュリティ制限
1. **危険コマンドの静的検査**: 実行前に必ず全文を字句解析。
デフォルトで以下をブロック(SPSSの3文字省略形、大文字小文字の揺れ、
コメント挟み込みにも対応):
- `HOST`(OSコマンド実行)/ `ERASE`(ファイル削除)/ `PERMISSIONS`
- `SCRIPT` / `BEGIN PROGRAM`(任意の Python/R 実行)
- `INSERT` / `INCLUDE`(検査を回避する外部シンタックス取り込み)
- `CD`(サンドボックス逸脱)
- マクロ難読化トークン `!CONCAT` `!UNQUOTE` `!EVAL`
2. **パスサンドボックス**: シンタックス内の絶対パス参照、`syntax_file`、
`working_directory` はすべて `allowed_directories` 配下に限定。
シンボリックリンク・`..` による逸脱も実パス解決でブロック。
3. **コマンドインジェクション対策**: shell=False のリスト引数実行のみ。
4. **タイムアウト**: プロセスツリーごと強制終了(Windows: taskkill /T)。
5. **同時実行制御**: 多重実行は即時 busy を返却。
6. **出力サイズ上限**: LLMコンテキスト溢れを防止。
7. **認証情報の扱い**: ツールパラメータでは一切受け取らない。
config の `{env:VAR名}` 形式で環境変数からのみ解決。
8. **監査ログ**: 全実行/拒否を JSONL で記録。シンタックス本文は記録せず
SHA-256 + 先頭プレビューのみ(機密データ保護)。
## できること / できないこと
**できること**
- SPSS シンタックスの静的安全検査(実行前の自己修正用)
- 検査済みシンタックスの無人バッチ実行(`stats.exe -production silent`)
- 結果の text / html での回収(グラフ等の画像は対象外)
- `allowed_directories` 内の `.sav` / `.csv` 等の読み書き
(シンタックス内から相対パスまたは許可範囲内の絶対パスで)
**できないこと**
- Statistics Server(`statisticsb.exe`)での実行(サポート削除済み)
- `HOST` / `SCRIPT` / `BEGIN PROGRAM` 等を含むシンタックスの実行
(`allow_begin_program` で明示的に緩めない限り)
- `allowed_directories` 外のファイルへのアクセス
- `.spv`(Viewer バイナリ)やグラフ画像の返却
- SPSS の GUI 操作・対話的実行
## 利用イメージ(エージェントへの指示例)
```
@/sales_analysis.sps を spss-stats-mcp で実行して
```
```
data.sav の売上を地域別にt検定するシンタックスを書いて、
validate_spss_syntax で検査してから実行して
```
## テスト方法
リポジトリのクローンで、インストールに使った Python を
`<python>` として実行します(例: `%USERPROFILE%\.venvs\spss-stats-mcp\Scripts\python`):
```bat
cd spss-stats-mcp
<python> -m pip install -e .[dev]
rem 単体テスト(SPSS本体不要。安全検査・.spj生成・config解決・fail-soft起動)
<python> -m pytest tests/ -v
rem サーバー起動確認(Ctrl+C で終了。config.json はなくてもよい)
<python> -m spss_stats_mcp.server
rem 起動直後に stderr に [spss-stats-mcp] ready(...) が出れば正常
```
SPSS 実機を使った疎通確認は、MCP クライアントから
`get_spss_mcp_info` → `execute_spss_syntax`(小さな `DATA LIST` +
`DESCRIPTIVES` など)を呼び、`status: "success"` が返ることを確認します。
## 高度な設定
```json
{
"safety": {
"allow_begin_program": false,
"blocked_commands_extra": {"OMS": "出力リダイレクトを禁止する場合"},
"unblocked_commands": ["CD"],
"max_syntax_bytes": 1000000
},
"env": {"MY_VAR": "{env:MY_ENV_VAR}"}
}
```
- `allow_begin_program: true` にすると `BEGIN PROGRAM` を許可できますが、
**任意コード実行と同義**のため、隔離環境以外では推奨しません。
- `unblocked_commands` でデフォルトブロックを個別解除できます(自己責任)。
- `blocked_commands_extra` で `OMS` をブロックしても、出力回収のために MCP が
内部注入する OMS(書き込み先はサンドボックス内に固定)には影響しません。
## トラブルシュート
| 症状 | 原因と対処 |
|---|---|
| ツールが登録されない(IBM Bob の `Tool does not exist` 等) | 本バージョンではサーバーは設定不備でも起動するため、通常は起きない。起きた場合はクライアントの MCP ログで `[spss-stats-mcp]` 行を確認。旧バージョンは config.json が見つからないと起動時にクラッシュしてこの症状になっていた(→ 更新する) |
| `status: "config_error"` が返る | `reason` と `fix` に原因と直し方が入っている。設定を直したら**再起動不要**でもう一度呼べばよい |
| `get_spss_mcp_info` が `executable_not_found` | stats.exe が自動検出できていない。SPSS Statistics(Desktop 版)をインストールするか、config.json の `executable` または環境変数 `SPSS_STATS_MCP_EXECUTABLE` にフルパスを設定する(`diagnostics` に探索の経緯あり) |
| 「allowed_directories に…指定できません」(config_error) | サンドボックスが広すぎる(ホーム直下等)。`${workspace}` 利用時は MCP 設定の `env` に `SPSS_MCP_WORKSPACE=<プロジェクトルート>` を明示する |
| `get_spss_mcp_info` の `diagnostics` に `bob_workspace_resolved_from_cwd` が出る | `${workspace}` が Bob 本体ディレクトリに解決されている。Bob の MCP 設定 `env` に `SPSS_MCP_WORKSPACE=<プロジェクトルート>` を追加する |
| `path_outside_sandbox` でワークスペース内のCSVが拒否される | `allowed_directories` が実データのあるプロジェクトを指していない。`SPSS_MCP_WORKSPACE`、シンタックス内のパスを確認する |
| 「'backend': 'statisticsb' はサポートされていません」(config_error) | 旧設定の名残。config.json から `backend` キーを削除する |
| `status: "error"` で `.spj` 関連のエラー | SPSS のバージョン差。`spj_template` で GUI 書き出しの `.spj` を貼り付けて上書き(上記参照) |
| `status: "timeout"` | `timeout_seconds` を増やす(上限 `max_timeout_seconds`) |
| `status: "busy"` | 別の実行が進行中。完了を待って再試行 |
| `status: "rejected"` | 安全検査で拒否。`findings` の理由を確認しシンタックスを修正。変数名が `HOST` 等と誤検知される場合は名称変更 |
| 出力が空 | ライセンス切れや SPSS 初回起動ダイアログの可能性。GUI で一度 `stats.exe` を起動して確認 |
| PATH の `python` が動かない | Microsoft Store スタブの可能性。実体のある Python のフルパスを `command` に指定する |
## 制限事項
- 静的検査は保守的なため、`HOST` 等と同名の変数・マクロ名は誤検知します
(名称変更で回避してください)。
- 出力形式は text / html のみ(`.spv` はバイナリのため LLM 返却に不向き)。
- 自動生成 `.spj` は v29/v30 想定。他バージョンは `spj_template` で上書き。
- Windows ローカル実行を対象としています。
## ライセンス
MIT License([LICENSE](LICENSE) を参照)。
IBM SPSS Statistics は IBM Corporation の製品・商標です。本プロジェクトは
IBM とは無関係の非公式ツールであり、SPSS 本体・ライセンスは含みません。
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues