tcs_mcp_claude
# tcs_mcp_claude
九州大学スーパーコンピュータ**玄界**の TCS(Fujitsu PRIMEHPC JobScheduler / PJM)を Claude から操作するための [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) サーバー。
Claude Code と統合することで、ジョブの投入・状態確認・削除・リソース照会・出力ファイルの読み取りを自然言語で行えるようになる。
---
## 提供ツール
| ツール | 対応コマンド | 説明 |
|--------|-------------|------|
| `submit_job` | `pjsub` | ジョブスクリプトを投入してジョブ ID を返す |
| `list_jobs` | `pjstat` | 実行中・キュー待ちジョブの一覧(履歴も取得可) |
| `get_job_status` | `pjstat <id>` | 特定ジョブの状態確認 |
| `delete_job` | `pjdel` | ジョブの削除・キャンセル |
| `get_resource_groups` | `pjstat --rsc` | 利用可能なリソースグループの一覧 |
| `get_quota_limits` | `pjstat --limit` | クォータ・上限値の確認 |
| `generate_job_template` | — | Genkai 向けジョブスクリプトのテンプレート生成 |
| `list_resource_groups` | — | Genkai の既知リソースグループ一覧 |
| `list_files` | — | 作業ディレクトリのファイル一覧 |
| `read_file` | — | テキストファイルの内容を読み取り |
| `read_job_output` | — | ジョブの標準出力・エラーファイルを読み取り |
---
## 利用形態
### シナリオ A(推奨): 玄界のログインノード上で Claude Code を直接実行
```
[玄界ログインノード]
Claude Code → tcs-mcp (stdio) → pjsub/pjstat/pjdel
```
### シナリオ B: ローカル PC から SSH 経由でサーバープロセスを玄界で動かす
```
[ローカル PC] [玄界ログインノード]
Claude Code → SSH トンネル → tcs-mcp (stdio) → pjsub/pjstat/pjdel
```
### シナリオ C: ローカル PC に MCP サーバーを置き、SSH で玄界へ接続
```
[ローカル PC]
Claude Code → tcs-mcp (SSH モード) → SSH → pjsub/pjstat/pjdel [玄界]
```
---
## インストール
### 前提条件
- Python 3.11 以上(玄界では miniforge3 を推奨)
- 玄界アカウントと PJM コマンド(`/usr/local/bin/pjsub` 等)へのアクセス
### 手順(玄界ログインノード上)
```bash
# miniforge 環境をアクティベート
source ~/miniforge3/bin/activate
# このリポジトリをクローン
git clone git@github.com:exthnet/tcs_mcp_claude.git
cd tcs_mcp_claude
# パッケージをインストール(開発モード)
pip install -e .
# インストール確認
tcs-mcp --help
```
---
## Claude Code への登録
### シナリオ A / B(玄界上で tcs-mcp を動かす場合)
プロジェクトルートの `.mcp.json` がそのまま使えます(Claude Code を `tcs_mcp_claude/` ディレクトリで起動した場合に自動読み込み)。
```json
{
"mcpServers": {
"tcs": {
"type": "stdio",
"command": "/home/pj24001603/ku40000105/miniforge3/bin/tcs-mcp",
"env": {
"TCS_MODE": "local",
"TCS_WORK_DIR": "/home/pj24001603/ku40000105/work"
}
}
}
}
```
別のディレクトリで Claude Code を使う場合は、`~/.claude/` 以下に `.mcp.json` を置くか、`claude mcp add` コマンドで追加してください。
### シナリオ B(ローカル PC から SSH トンネル経由)
ローカル PC の `.mcp.json` または Claude Code の MCP 設定に追加:
```json
{
"mcpServers": {
"tcs": {
"type": "stdio",
"command": "ssh",
"args": [
"-i", "~/.ssh/id_rsa_genkai",
"ku40000105@genkai.cc.kyushu-u.ac.jp",
"/home/pj24001603/ku40000105/miniforge3/bin/tcs-mcp"
]
}
}
}
```
### シナリオ C(ローカル PC に MCP サーバーをインストール、SSH で玄界へ)
ローカル PC にもパッケージをインストールし、SSH モードで起動:
```json
{
"mcpServers": {
"tcs": {
"type": "stdio",
"command": "tcs-mcp",
"env": {
"TCS_MODE": "ssh",
"TCS_SSH_HOST": "genkai.cc.kyushu-u.ac.jp",
"TCS_SSH_USER": "ku40000105",
"TCS_SSH_KEY_FILE": "~/.ssh/id_rsa_genkai"
}
}
}
}
```
---
## 設定
環境変数または `.env` ファイル(`.env.example` を参照)で設定します。
| 変数 | デフォルト | 説明 |
|------|-----------|------|
| `TCS_MODE` | `local` | 実行モード: `local` または `ssh` |
| `TCS_WORK_DIR` | `~/work` | ジョブ出力ファイルを探す作業ディレクトリ |
| `TCS_SSH_HOST` | `genkai.cc.kyushu-u.ac.jp` | SSH ホスト名(ssh モード時) |
| `TCS_SSH_USER` | — | SSH ユーザ名(ssh モード時、必須) |
| `TCS_SSH_KEY_FILE` | `~/.ssh/id_rsa` | SSH 秘密鍵パス |
| `TCS_PJSUB_PATH` | `/usr/local/bin/pjsub` | pjsub の絶対パス |
| `TCS_PJSTAT_PATH` | `/usr/local/bin/pjstat` | pjstat の絶対パス |
| `TCS_PJDEL_PATH` | `/usr/local/bin/pjdel` | pjdel の絶対パス |
| `TCS_LOG_LEVEL` | `INFO` | ログレベル |
---
## 使用例(Claude との会話)
```
あなた: 現在のジョブ一覧を見せて
Claude: [list_jobs を呼び出し]
現在実行中のジョブはありません。
あなた: a-batch-low で4コア、30分のジョブを投入したい
Claude: [generate_job_template を呼び出し]
以下のスクリプトを生成しました:
#!/bin/bash
#PJM -N myjob
#PJM -L rscgrp=a-batch-low
#PJM -L vnode-core=4
#PJM -L elapse=00:30:00
...
投入しますか?
あなた: 投入して
Claude: [submit_job を呼び出し]
ジョブ ID 6401234 で投入しました。
```
---
## 開発
### テストの実行
```bash
source ~/miniforge3/bin/activate
pip install -e ".[dev]"
pytest tests/ -v
```
テストは `tests/fixtures/` に保存した実際の `pjstat` 出力を使用するため、玄界への接続不要で実行できます。
### プロジェクト構造
```
src/tcs_mcp/
├── __main__.py # エントリポイント
├── server.py # MCPServer の構築・ツール登録
├── config.py # TCSConfig (pydantic-settings)
├── executor.py # LocalExecutor / SSHExecutor
├── parsers.py # pjstat 出力パーサ
└── tools/
├── jobs.py # submit_job, list_jobs, get_job_status, delete_job
├── resources.py # get_resource_groups, get_quota_limits
├── files.py # list_files, read_file, read_job_output
├── templates.py # ジョブスクリプトテンプレートロジック
└── templates_tool.py # generate_job_template, list_resource_groups (MCP ツール)
```
### 対応リソースグループ(Genkai)
| グループ | 種別 | 用途 |
|----------|------|------|
| `a-batch-low` / `a-batch` | CPU | バッチジョブ(Xeon Platinum 8490H) |
| `a-inter-low` / `a-inter` | CPU | インタラクティブジョブ |
| `b-batch-low` / `b-batch` | GPU | GPU バッチジョブ(NVIDIA A100) |
| `b-batch-mig-low` / `b-batch-mig` | GPU (MIG) | MIG パーティション GPU ジョブ |
| `b-inter-low` / `b-inter` | GPU | GPU インタラクティブジョブ |
| `c-batch-low` / `c-batch` | CPU | その他バッチ |
---
## 注意事項
- `pjmod` は玄界に存在しないため非対応
- ファイル操作ツール(`read_file`, `list_files`)は `TCS_WORK_DIR` 配下のみアクセス可(パストラバーサル防止)
- MCP バージョン 2.0.0 を使用(`mcp.server.mcpserver.MCPServer`)
TDQS
Scored across 11 tools
Most tools have distinct purposes: file operations, job lifecycle, and resource queries are clearly separated. However, list_resource_groups and get_resource_groups both list resource groups but with differing details, which could cause misselection.
Tool names generally follow a consistent verb_noun pattern in snake_case, such as list_files, submit_job, delete_job. The overlap between list_resource_groups and get_resource_groups introduces slight inconsistency, but the overall pattern is predictable.
Eleven tools is well within the ideal range for a domain-specific server covering file access and job management. Each tool serves a clear purpose without unnecessary bloat.
The surface covers the full job lifecycle: template generation, submission, listing, status check, output retrieval, and deletion. Additionally, resource group and quota queries address administrative needs. No obvious dead ends.