feat(mcp-server): add scheduler_checkpoint + scheduler_restart tools

Expose two backend capabilities MCP previously omitted:
- scheduler_checkpoint: control action "checkpoint" (CRIU)
- scheduler_restart: POST /xce/v1/jobs/:id/restart (re-queues as a new
  job, resuming from the last checkpoint if one exists; returns new jobid)

schedulerclient gains CheckpointJob/RestartJob (RestartJobResult,
JobRestartRequest); Client interface updated. Both tools marked
destructive (confirm required). tools/list now reports 17 tools.

Unit tests added/updated in both modules — all pass. Backend endpoints
are existing apiserver routes; no backend changes in this commit.

Also syncs left_scheduler_work.md §八.4 (checkpoint/restart done; the
only remaining MCP tool gap is scheduler_modify, blocked on a controller
job-field-update opcode that does not exist yet).

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
lei.chen 2026-08-30 10:35:50 +00:00
parent 05ac57b183
commit 6020015fa7
7 changed files with 279 additions and 10 deletions

View file

@ -25,7 +25,7 @@ const serverInstructions = "XCE scheduler agent — cluster status, not an incid
"root causes, do NOT reference \"known bugs\", and do NOT propose diagnostic or repair actions (checking logs, " +
"restarting daemons, opening tickets, ssh'ing to nodes, etc.) unless the user explicitly asks for help or " +
"remediation. If you believe action may be warranted, say so in at most one line and let the user decide.\n\n" +
"Write tools (scheduler_submit/hold/release/cancel) are destructive and require the user's explicit intent."
"Write tools (scheduler_submit/cancel/hold/release/checkpoint/restart) are destructive and require the user's explicit intent."
func main() {
baseURL := os.Getenv("XCE_API_URL")
@ -221,6 +221,22 @@ func main() {
mcp.WithDestructiveHintAnnotation(true),
), app.HandleReleaseJob)
// ── scheduler_checkpoint ──
s.AddTool(mcp.NewTool("scheduler_checkpoint",
mcp.WithDescription("Checkpoint a running job by ID (action 'checkpoint', CRIU). Destructive — you will be asked to confirm before execution."),
mcp.WithString("id", mcp.Description("Job ID to checkpoint"), mcp.Required()),
mcp.WithReadOnlyHintAnnotation(false),
mcp.WithDestructiveHintAnnotation(true),
), app.HandleCheckpointJob)
// ── scheduler_restart ──
s.AddTool(mcp.NewTool("scheduler_restart",
mcp.WithDescription("Restart (re-queue) a finished job as a new job by ID, resuming from its last checkpoint if one exists. Returns the new job ID. Destructive — you will be asked to confirm before execution."),
mcp.WithString("id", mcp.Description("Job ID to restart"), mcp.Required()),
mcp.WithReadOnlyHintAnnotation(false),
mcp.WithDestructiveHintAnnotation(true),
), app.HandleRestartJob)
log.Printf("Starting scheduler-agent MCP server (base-url: %s)", baseURL)
if err := mcps.ServeStdio(s); err != nil {
log.Fatalf("server error: %v", err)