jobd

io.github.musharna由 GitHub 账号 musharna 发布v0.5.54更新于 Nov 8, 2026

Self-hostable GPU-aware job broker: submit, route by VRAM, babysit jobs across machines via MCP.

概览

AI 生成的概览

面向自建 jobd 代理的 MCP 服务器,让助手在你自己的多台机器上提交、按显存路由、监控和抢占 GPU 作业。

可以做什么
  • 向代理队列提交作业,包括以 bash 执行的命令字符串。
  • 查看队列和单个作业状态,读取捕获的作业日志。
  • 取消或抢占正在运行的作业,并查看事件历史。
  • 列出各 worker 的健康状况与空闲容量,并将 worker 从集群中移除。
适用场景
适合拥有几台带 GPU 的自有机器、希望由助手代为排队训练或批处理作业、按空闲显存路由到合适 worker,并持续跟踪作业进展,而不是在终端里长时间运行命令的场景。
运行要求
本机需 Python 3.11 及以上并安装 jobd 的 MCP 附加组件(jobd-mcp),且能访问 jobd 代理。需设置 JOBD_URL 为代理基础地址(默认 JOBD_API_TOKEN 为与代理一致的 Bearer 令牌,除非代理以 JOBD_ALLOW_NO_AUTH=1 运行。需要能访问该代理的网络。
安装前请注意
JOBD_API_TOKEN 对应的是一个会在你机器上执行命令的代理,务必让代理只监听回环地址或私有 tailnet;在其他绑定上启用免认证会向网络暴露未认证的代码执行。提交的命令字符串经 bash 执行。抢占会先发 SIGTERM 再发 SIGKILL,且不会自动重跑作业;移除 worker 会改变集群组成。

安装

在 SourceWeft 中

  1. 打开 控制台中的 jobd,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

jobd

jobd is a job broker with an MCP server that lets AI agents submit, route and babysit jobs on a few machines of your own. Like task-spooler or pueue, but across all your machines on Tailscale or a LAN, routing each job to a worker with the VRAM free, with no cloud, Kubernetes or Slurm.

[CI] [PyPI] [Python] [License] [DOI] [Glama]

[jobd in action: job fleet status shows four workers and their versions; a GPU job routes to the worker with enough free VRAM and streams back; a stdin batch submits two jobs at once; job logs -f follows one to completion]

bash
# from any machine on your tailnet:job submit --project myproj --gpu --vram-required 16 --wait -- python train.py# → routed to whichever worker has ≥16 GB VRAM free, streamed back to your terminal

VRAM routing tracks one GPU per host: the worker reports free memory on GPU index 0 only.

Why it exists

  • VRAM-fit routing. Each job goes to a worker whose live free VRAM, RAM, CPUs, capability tags and arch/OS fit it, instead of you guessing which box is free.
  • Preemption with a checkpoint window. A higher-priority job can preempt a running one: SIGTERM, a grace window for the workload to save into its JOBD_CHECKPOINT_DIR, then SIGKILL. A preempted job is not re-run; to resume, submit a new job pointed at the checkpoint (docs/preemption.md).
  • Survives sessions. Jobs live in the broker, not your shell. Submit, close the laptop, check back tomorrow.
  • Agent-native. An MCP server lets an AI agent submit, monitor and babysit jobs as tool calls (benchmark).
  • Yours. One broker process on a machine you own. No accounts, no telemetry, no per-GPU-hour billing. Only the optional self-update scripts go online (runbook).

Why not just use…?

ToolWhat it gives youWhy jobd instead
nohup / tmux / sshRuns a command on one boxNo queue, VRAM-aware routing, preemption, or record of what ran where
task-spoolerA job queue on one machinejobd queues across all your machines and routes by live VRAM/CPU fit
PueueA mature single-machine queue daemonPueue's README puts distributed execution out of scope; jobd is that layer, plus GPU awareness
HyperQueueMulti-machine scheduling with HPC roots, single binaryCounts GPUs but doesn't track VRAM; no preemption/checkpoint contract or agent interface
SlurmDatacenter-grade schedulingHeavy to stand up and operate for 2–3 personal boxes
SkyPilot / dstackRuns on clouds and your own machinesSkyPilot's "existing machines" mode installs Kubernetes (k3s) on your boxes; dstack wants Docker and passwordless sudo on every host
ModalServerless GPU computeRuns on Modal's machines, not yours
RayDistributed compute; Ray Jobs runs any shell command on a Ray clusterYou first stand up and run a Ray cluster

Install

bash
pip install jobd               # broker + CLIpip install "jobd[mcp]"        # adds the MCP serverpip install "jobd[worker]"     # adds the worker daemon (jobd-worker)

Requires Python ≥ 3.11. scripts/install-worker.sh sets up a worker under ~/jobd-worker with its own venv and a generated config.

Quickstart (single host)

bash
# 1. start the broker (binds 127.0.0.1:8765 by default)JOBD_ALLOW_NO_AUTH=1 jobd          # no-auth is fine for a loopback-only broker
# 2. in another shell, install + start a worker pointed at itpip install "jobd[worker]"JOBD_URL=http://127.0.0.1:8765 JOBD_WORKER_HOST=local jobd-worker
# 3. submit a job and wait for itjob submit --project demo --wait -- echo hellojob listjob logs <id>

For a multi-host deployment (Docker broker, systemd workers, Tailscale binding, shared auth token), see docs/security.md and the templates in docker-compose.yml and scripts/. Adding a worker to a running fleet is one command:

bash
job fleet add user@newbox      # ssh in, install pinned to the broker's version,                               # wire systemd units + the self-update timer,                               # verify it registers. `job fleet status` shows drift.

Day-2 operations (health, draining a worker, upgrades, token rotation, backups) are in docs/runbook.md.

How it works

[Architecture: job CLI, jobd-mcp MCP tools, and HTTP/SSE clients talk to the jobd broker (FastAPI — queue, VRAM matcher, priorities, SQLite) over one tailnet; the broker dispatches via long-poll claims and heartbeats to workers A (24 GB GPU), B (8 GB GPU), and C (CPU-only)]

The broker (FastAPI + SQLite) holds the queue, runs the matcher and resolves per-project priorities. Workers, one per host, poll it, so nothing connects in to a worker: each heartbeats its live capacity, claims jobs it can run, streams logs back and honors preemption. The argv you submit runs as-is (shell=False); job submit --stdin and the MCP jobd_submit tool are the exceptions and run a command string as bash -c <string>. Design notes: docs/ARCHITECTURE.md.

CLI

job submit -p PROJ [options] -- CMD...       # queue a jobjob list [--state STATE] [--project P]       # queue + recent jobsjob status ID | A<id> [--watch]              # one job, or an array's aggregatejob logs ID [-n BYTES]                       # tail captured outputjob wait ID                                  # block until terminaljob cancel ID  /  job preempt ID             # stop a jobjob adopt --pid N -p PROJ [--gpu]            # track a process started outside jobd (Linux)job workers                                  # fleet snapshot + healthjob projects list | set NAME PRI | nudge NAME DELTAjob audit [--project P] [--since 24h]        # event history

Job arrays and sweeps, --explain dry runs, job adopt, and a pueue/task-spooler command map: docs/cli.md.

MCP / agent integration

jobd-mcp exposes the queue as nine tools: jobd_submit, jobd_status, jobd_logs, jobd_list, jobd_cancel, jobd_preempt, jobd_events, jobd_workers, jobd_worker_delete. docs/agent-cookbook.md walks through babysitting, preemption, sweeps, and asking why a job won't schedule.

For Claude Code:

bash
claude mcp add jobd \  --env JOBD_URL=http://127.0.0.1:8765 \  --env JOBD_API_TOKEN=<your-token> \  -- jobd-mcp

Any other MCP client:

json
{  "mcpServers": {    "jobd": {      "command": "jobd-mcp",      "env": {        "JOBD_URL": "http://127.0.0.1:8765",        "JOBD_API_TOKEN": "<your-token>"      }    }  }}

JOBD_API_TOKEN must match the broker's token, or every call returns 401. examples/claude-code-hooks/ has optional hooks that nudge (or hard-block) an agent toward submitting heavy commands through jobd.

What the benchmark shows

Claude with the server was compared with Claude using jobd's own job CLI, on 38 questions about a live broker, 3 runs each. With Claude Haiku 5.5 the server got all 38 right in every run and the CLI 29: a pre-registered win (Holm-adjusted McNemar p = 0.008). With Sonnet 5.5 it was 36 against 30 and with Opus 5.5 38 against 37, neither separated. On all three models the server's answers were cheaper and faster; with Sonnet, 0.20 times the cost and 0.17 times the time.

[Bar chart of right and wrong answers to 38 questions about a live jobd broker, 3 runs per question for each Claude setup. Constant guess with no model: 3 right, 35 wrong. Best constant fit to the answer key: 9 right, 29 wrong. Claude with the job CLI: 113 right, 1 wrong. Claude with jobd-mcp: 114 of 114 right.]

The chart is the Opus 5.5 run (2026-10-18). There the server's median answer cost 0.20 times as much (95% CI 0.15 to 0.28) and took 0.16 times as long (0.13 to 0.20), and it was cheaper and faster on all 38 questions. These were secondary endpoints, measured on an unreleased commit that adds a finished_at window to jobd_list. On an earlier, easier set both setups got 123 of 123.

We wrote the questions and ran the benchmark ourselves; an outside re-run is welcome. Method, controls and limitations: benchmarks/agent_qa; the Haiku and Sonnet runs: 2026-10-20 re-run.

Supported platforms

ComponentLinuxmacOSWindows
Broker (jobd)testedexpectedexpected (WSL recommended)
CLI (job) / MCP (jobd-mcp)testedexpectedexpected
Worker (jobd-worker)testeddegradeduntested

CI runs on Ubuntu with no GPU runner (VRAM paths are tested against mocks), and without a systemd user instance the worker still runs jobs but drops its memory caps, process reaping and preemption guarantees.

Configuration

Security

Run the broker on loopback or a Tailscale tailnet, never a public interface. Three stacked controls:

  1. Bind: JOBD_HOST is 127.0.0.1 by default; set it to a Tailscale address (100.64.0.0/10), never 0.0.0.0. The broker does not enforce this.
  2. Source IP: requests from outside loopback and 100.64.0.0/10 get 403 (JOBD_DISABLE_TAILNET_ACL=1 turns this off).
  3. Token: every host sets JOBD_API_TOKEN; JOBD_ALLOW_NO_AUTH=1 is for a loopback-only broker, and on any other bind exposes unauthenticated code execution to your tailnet.

/livez, /readyz and /metrics are exempt from both the source-IP check and the token; /metrics shows every worker's hostname and version, so don't port-forward the broker. Threat model and token rotation: docs/security.md.

License

MIT; see LICENSE.

来源:README.md,提交 11e0fdd

工具

0
SourceWeft 曾在隔离沙箱中以无凭据方式启动该软件包一次,以列出其工具,但未能完成:服务器未能启动。

版本历史

8
  1. v0.5.52Oct 20, 2026
  2. v0.5.51Sep 26, 2026
  3. v0.5.50Sep 26, 2026
  4. v0.5.49Sep 24, 2026
  5. v0.5.48Sep 23, 2026
  6. v0.5.47Sep 23, 2026
  7. v0.5.46Sep 19, 2026
  8. v0.5.44Sep 16, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分