AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻譯準備中
MCP 伺服器用於 SLURM HPC 叢集——零相依、單檔案、TTY 感知的作業監視並提供桌面通知
AI 翻譯
MCP server for SLURM HPC clusters — zero-dependency, single-file, TTY-aware job watching with desktop notifications
開發工具JavaScript · TypeScriptGitHub @Charlie-Z-work自行安裝營運者未確認
試用過了嗎? 點一下就好,不需要登入。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
安裝型專案無需部署網域也可驗證。個人儲存庫可透過 GitHub 登入驗證,組織儲存庫可使用上方的儲存庫驗證檔案。
製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗A zero-dependency MCP server for SLURM HPC clusters. Single file, npx-ready.
npx slurm-mcp-server and you're doneN ok / M failed tallyslurm_submit warns when a per-user QoS cap will serialize your jobs or reject the request; cluster_info lists the capsexport HPC_HOST=your-cluster # SSH host alias or hostname (user@host also works)
export HPC_USER=your-username # Your cluster username (used for squeue/sacct -u)
# Optional:
export SLURM_ACCOUNT=your-account # SLURM account; unset = no #SBATCH --account (site default)
export HPC_PREAMBLE='module load python/3.11\nconda activate myenv'
export SLURM_DEFAULT_PARTITION=batch # default partition for slurm_submit (per-cluster list allowed)
export SLURM_DEFAULT_GPUS=1 # sites without GPUs: set SLURM_DEFAULT_GPUS=0 (per-cluster list allowed)
Values are validated at startup (the server exits with an error otherwise);
none may start with -, and comma-separated lists configure multiple clusters:
HPC_HOST: letters, digits, _ . -, optionally user@hostHPC_USER: letters, digits, _ . - @ \ (AD/LDAP/Kerberos names such as
[email protected] or DOMAIN\u; always single-quoted in remote commands)SLURM_ACCOUNT: letters, digits, _ . -; an empty list entry means "no
account" for that cluster (acct1,,acct3)SLURM_DEFAULT_PARTITION: letters, digits, _ . - (e.g. gpu.a100)SLURM_DEFAULT_PARTITION / SLURM_DEFAULT_GPUS: one value for every
cluster, or a list in HPC_HOST order (batch,standard-s, 1,0); a shorter
list reuses its last entry, an empty entry means the built-in defaultAdd to your .mcp.json:
{
"mcpServers": {
"hpc": {
"command": "npx",
"args": ["-y", "slurm-mcp-server"],
"env": {
"HPC_HOST": "your-cluster",
"HPC_USER": "your-username",
"SLURM_ACCOUNT": "your-account"
}
}
}
}
Add to your ~/.codex/config.json:
{
"mcpServers": {
"hpc": {
"command": "npx",
"args": ["-y", "slurm-mcp-server"],
"env": {
"HPC_HOST": "your-cluster",
"HPC_USER": "your-username",
"SLURM_ACCOUNT": "your-account"
}
}
}
}
Add to .cursor/mcp.json in your project root:
{
"mcpServers": {
"hpc": {
"command": "npx",
"args": ["-y", "slurm-mcp-server"],
"env": {
"HPC_HOST": "your-cluster",
"HPC_USER": "your-username",
"SLURM_ACCOUNT": "your-account"
}
}
}
}
This is a standard MCP server using stdio transport. Configure it in your client with:
npx -y slurm-mcp-serverHPC_HOST, HPC_USER (required), SLURM_ACCOUNT, HPC_PREAMBLE, NOTIFY_WEBHOOK, HPC_RESOURCE_LOG, HPC_GUIDE_EXTRA, SLURM_DEFAULT_PARTITION, SLURM_DEFAULT_GPUS, HPC_REQUIRE_MASTER, HPC_ALLOW_UNSAFE_REUSE (optional)That's it. See SSH Setup for the two connection modes (ControlMaster, required on MFA clusters, or direct BatchMode connections).
Each terminal window tracks its own SLURM jobs independently. No cross-talk between windows. Automatic 30-second polling (one batched sacct per cluster) with state change detection. A watch only expires after successful sacct queries of its cluster have not reported the job for max(48h, 4 × the time limit); long queue waits and master outages (no successful query) never expire it. Watches are keyed by cluster + job id, so the same id on two clusters never collides. Array jobs are tracked per task and reported once all tasks reach a terminal state (CANCELLED by <uid>, PREEMPTED, BOOT_FAIL, DEADLINE, REVOKED included). Watch/notification/template state files are written atomically under a lock file, and a corrupt file is moved aside as .corrupt-<ts> instead of being overwritten.
Every server writes a heartbeat every 30s on its own timer (independent of poll backoff); when a session dies, its watches are adopted by any live instance and keep being monitored. Pending notifications from closed sessions are surfaced (and drained) by whichever session runs next — long jobs never complete silently.
Blocks 8 patterns of SSH escape traps that silently corrupt commands, plus a length limit:
python -c, multi-line commandsThe Command Guard prevents accidental breakage, it is not a security boundary: ssh_exec still runs arbitrary commands as your cluster user.
Job completion triggers native desktop notifications:
osascript with soundnotify-sendBefore submitting jobs, automatically queries sacct for historical resource usage of similar jobs (peak MaxRSS over all job steps, elapsed time). Warns when requested resources exceed 10× actual usage. An ssh/sacct failure is reported as "resource history unavailable: ", distinct from "no history yet".
Per-window working directory tracking prevents accidentally submitting jobs to wrong directories.
Configure multiple clusters with comma-separated HPC_HOST. Switch between them with cluster_switch. Each watch remembers its cluster, so jobs on multiple clusters are polled correctly at the same time. HPC_PREAMBLE is only injected on the primary cluster (module names differ across clusters); pass preamble: false on slurm_submit to skip it entirely.
On clusters enforcing chained MFA (publickey and Duo), a background process can never re-authenticate — each blind reconnect attempt is just a failed login that feeds the bastion's fail2ban. This server therefore never kills or rebuilds your SSH ControlMaster. Every ssh/rsync call runs with BatchMode=yes, so nothing ever falls back to an interactive prompt. It probes the master socket locally (ssh -O check, zero network) before any traffic; if the master is dead it fails fast with instructions to reconnect interactively, and polling of that cluster pauses with exponential backoff (30s → 10min). Backoff is per cluster: a dead master on one cluster never delays notifications from another.
Save and reuse common SLURM configurations (partition, GPU count, memory, time, extra preamble lines). Apply with template: "my-template" on submit; an unknown template name is an error.
slurm_submit validates every parameter (job name, partition, mem, time, array, dependency, output dir) before building the script, then reads the partition's MaxTime and QoS per-user caps (MaxJobsPU, MaxTRESPU). It appends non-blocking ⚠️ hints when array tasks or extra jobs would serialize on a 1–2 job partition, or when gpus/mem/time exceed the cap. cluster_info shows a Per-user limits section for every partition (partition QoS only; association limits and a job QoS are not queried and may be stricter).
Summarize your compute usage over any time period — total jobs, compute hours, GPU jobs, peak memory.
Send job completion alerts to Slack, Discord, or any webhook endpoint via NOTIFY_WEBHOOK env var.
Submit existing .slurm/.sh files on the cluster without rebuilding the script locally.
Start a tmux-based interactive SSH session for commands needing 2FA, confirmation prompts, or long-running monitoring.
| Category | Tool | Description |
|---|---|---|
| SSH | ssh_status | Check SSH connection |
ssh_exec | Execute command on HPC | |
ssh_read_file | Read file from HPC | |
ssh_write_file | Write file to HPC | |
ssh_interactive | Start interactive SSH session via tmux | |
| SLURM | slurm_status | Check job status |
slurm_submit | Submit batch job (supports arrays + templates) | |
slurm_submit_file | Submit existing .slurm/.sh script | |
slurm_cancel | Cancel job | |
slurm_logs | Read job output log (remembers --output patterns of jobs it submitted → sacct → scontrol → workdir fallback; path reads a file directly) | |
slurm_watches | List active job watches | |
resource_check | Check historical resource usage | |
resource_report | Summarize usage over time period | |
cluster_info | Get cluster info + queue estimate | |
cluster_switch | Switch active cluster | |
| Files | sync_files | rsync between local and HPC |
| Workdir | workdir_set | Set working directory (per window and cluster) |
workdir_get | Get working directory (per window and cluster) | |
| Templates | template_save | Save reusable job template |
template_list | List saved templates | |
| Terminal |
| Variable | Required | Description |
|---|---|---|
HPC_HOST | ✅ | SSH host (alias from ~/.ssh/config or hostname) |
HPC_USER | ✅ | Username on HPC cluster |
SLURM_ACCOUNT | ❌ | SLURM account for job submission. Unset/empty: no #SBATCH --account line (the site's default account applies) |
HPC_PREAMBLE | ❌ | Shell commands to run before job scripts (module loads, conda activate, etc.) — newline-separated |
NOTIFY_WEBHOOK | ❌ | Slack/Discord webhook URL for job completion alerts |
HPC_RESOURCE_LOG | ❌ | Path on the cluster to an extra resource log (e.g. TSV of past runs) that resource_check greps by job name |
HPC_GUIDE_EXTRA | ❌ | Local path to a site-specific guide appended to the guide tool output (accounts, partition policy, envs) |
SLURM_DEFAULT_PARTITION | ❌ | Default partition for slurm_submit (default batch). Comma-separated list = one per cluster, HPC_HOST order |
SLURM_DEFAULT_GPUS | ❌ | Default gpus for slurm_submit (default 1). Sites without GPUs: set SLURM_DEFAULT_GPUS=0 (no --gres line). Comma-separated list = one per cluster |
HPC_REQUIRE_MASTER | ❌ | 1 = require a ControlMaster: a host without ControlPath is treated like a dead master (fail fast, no direct connection). Recommended on MFA clusters |
HPC_ALLOW_UNSAFE_REUSE | ❌ | 1 = when the master is alive but its ControlPath cannot be resolved safely via ssh -G, run calls with plain BatchMode=yes instead of refusing them (a new connection is opened if the master dies meanwhile). Ignored under |
Every ssh/rsync call runs with BatchMode=yes (never an interactive prompt).
Before connecting, the server runs ssh -O check <host> locally and picks one
of two modes:
1. ControlMaster (required for MFA clusters, e.g. publickey + Duo). A
background process can never answer an MFA prompt, so all traffic must reuse a
master connection you opened interactively. ~/.ssh/config:
Host mycluster
HostName login.cluster.edu
User yourusername
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 12h
Create the socket directory (mkdir -p ~/.ssh/sockets) and run ssh mycluster
once in a terminal. If the master dies, tools fail fast with a "reconnect
interactively" message and polling of that cluster pauses — nothing ever
retries a login in the background. In this mode every ssh/rsync call also
carries -o ProxyCommand=false: if the master dies between the local check and
the call, ssh cannot reuse it and fails locally instead of opening a new
connection (a doomed publickey attempt that would feed the bastion's
fail2ban). The effective ControlPath (read locally with ssh -G <host>) is
passed explicitly as well, because a %C socket name hashes the ProxyJump
value and would otherwise change. If it cannot be resolved safely (ssh -G
fails, or the path contains %, quotes, backslashes or tabs), every call is
refused locally — nothing is sent — unless HPC_ALLOW_UNSAFE_REUSE=1
(plain BatchMode=yes). Paths with plain spaces work (quoted for ssh and for
rsync -e). Set HPC_REQUIRE_MASTER=1 so that a
missing ControlPath is also treated as "dead" instead of falling back to
mode 2.
2. Direct connections (no ControlPath configured, no MFA). When ssh -O check answers "No ControlPath specified", every call connects directly with
ssh -o BatchMode=yes — this works with key-based login without MFA (an
agent or unencrypted key). ssh_status reports "ControlMaster not configured —
direct BatchMode connections". Each call is a new login, so on clusters with
fail2ban prefer mode 1.
execFileSync, so while one remote command runs (up to its timeout, max 10 min for ssh_exec), the server handles no other request and the poller waits. The heartbeat announces busyUntil for the duration, so other windows do not mistake the busy server for a dead one. Moving to async execution is planned.sync_files, state files under ~/.claude), the tty detection and the ControlMaster checks assume a POSIX client (macOS / Linux).bash --login -c '...' transport; ssh_exec runs arbitrary commands as your cluster user.SLURM_DEFAULT_GPUS defaults to 1 for backward compatibility, so on a CPU-only site every slurm_submit without gpus writes --gres=gpu:1 and sbatch rejects it; the error then suggests SLURM_DEFAULT_GPUS=0 / gpus: 0. Set SLURM_DEFAULT_GPUS=0 on such sites.sacct (Slurm accounting). The watcher polls sacct; on a site without accounting storage (no slurmdbd) sacct fails, so slurm_submit registers no watch and says "sacct unavailable on this cluster — job watches cannot complete; use slurm_status". Check such jobs with slurm_status.sync_files and rsync -s. -s (protect-args) is passed when the local rsync supports it; macOS' default openrsync does not, so remote paths are restricted to a whitelist (no whitespace or shell metacharacters) either way.cluster_info and the submit hints read partition MaxTime and the partition QoS (sacctmgr show qos); limits set on your user/account association are not queried.MIT
terminal_start |
| Start tmux session |
terminal_read | Read tmux output |
terminal_send | Send keys to tmux |
terminal_exec | Run interactive command |
terminal_stop | Kill tmux session |
| Reference | guide | Read HPC usage guide |
HPC_REQUIRE_MASTER=1