
Kubernetes Ephemeral Job
io.github.inhuman由 GitHub 帳號 inhuman 發布v0.7.1更新於 Oct 24, 2026
Runs a command in a throwaway Kubernetes pod and returns exit code, output and artifacts.
概覽
一個 MCP 伺服器,在一次性 Kubernetes Pod 中依允許清單映像執行指令,並回傳結束碼、輸出與產物。
- 可以做什麼
- 在全新的臨時 Pod 中執行指令,回傳結束碼、合併輸出、耗時與內嵌產物,之後刪除該 Pod。在背景提交長時間任務,稍後取得結果,並支援長輪詢等待。可選擇在指令執行前將 git 儲存庫複製到工作目錄。每次任務可傳入輸入檔案、環境變數、資源限制、工作目錄與逾時時間。
- 適用情境
- 適合需要讓助理在真實容器中執行建置、測試套件或腳本,使用指定工具鏈、為相依套件存取網路並取回檔案產物,同時不留下殘留 Pod 的情境。適合已在運作 Kubernetes、希望為代理提供命名空間層級、映像允許清單執行沙箱的團隊。
- 執行需求
- 以 Docker 映像在本機執行,傳輸方式為 stdio(或 http/sse)。需要存取 Kubernetes 叢集:掛載的 kubeconfig(MCP_K8S_KUBECONFIG)或叢集內憑證;一個命名空間(MCP_K8S_NAMESPACE)及針對 jobs、pods 與日誌的 Role/RoleBinding;以及非空的映像允許清單(MCP_K8S_ALLOWED_IMAGES)。可選的複製功能需要 MCP_K8S_CLONE_IMAGE 與 MCP_K8S_CLONE_SECRET。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Kubernetes Ephemeral Job,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
mcp-k8s-ephemeral-job
English | Русский
[Version] [MCP Registry] [Docker Pulls] [Docker Image Version] [Build] [Go Version] [Go Report Card] [License: MIT] [Issues] [Last Commit]
Public OSS MCP server (Go, MIT) that spawns an ephemeral Kubernetes Job/pod from a
caller-chosen image, runs a command inside it, returns exit_code / stdout / artifacts, and
deletes the pod. The server builds the pod manifest in code — the caller passes parameters
only, never raw YAML.
It is the "operating room" counterpart to mcp-exec (the
"scalpel"): where mcp-exec runs a single Python file in a locked-down, network-less sandbox in
milliseconds, this one spins up a full pod with the toolchain/image you choose, controlled
network (clone repos, pull deps), long tasks and file artifacts out. They complement each
other.
Works over three transports — stdio / HTTP / SSE — with an identical tool set everywhere
(official modelcontextprotocol/go-sdk).
Tools
run_job — run and wait
Input: { image (required), command (required), files?, env?, limits?, timeout_s?, workdir?, clone? }
Output: { exit_code, stdout, stderr, duration_ms, status, artifacts, truncated }
statusis one ofsucceeded/failed/timeout/error. A non-zeroexit_codeor atimeoutis a normal result, not a tool error. Only invalid input (empty image/command, image not in the allowlist, bad file path) is a tool-call error.stdoutcarries the container's combined stdout+stderr — Kubernetes merges the two streams in pod logs.stderris reserved and always empty, so adding stream separation later stays backward-compatible.- Artifacts (files from the working directory) come back inline (base64) under a size cap.
Exceeding a cap never loses data silently: the matching
truncatedflag is set. - The manifest is built deterministically by the server — no raw YAML from the caller.
submit_job / fetch_job — run in the background
submit_job takes the same arguments as run_job but returns a job_token immediately;
fetch_job collects the result later. This is what lets an agent start a long job (a full test
battery, a build) and keep working instead of idling inside one synchronous call for its whole
wall-clock time.
fetch_jobreturnsstatus=runningwhile the job is in flight; passwait_s(≤120) to long-poll instead of hammering. It answers as soon as the job is done rather than sitting out the full wait.- Results are retained for 60 minutes and can be fetched more than once.
- Arguments are validated at submit time, so a bad image fails the submit while the caller can still fix it.
- Handles live in memory (the server is single-replica by design): a restart drops pending tokens and the caller simply resubmits.
Cloning a repository
With clone: { repo_url, ref, subdir? } an init container checks the repo out into the working
directory before the command runs. The caller never handles credentials: the server holds a
secret with one token per git host, mounts it only on the cloner, and the token is masked in
.git/config afterwards — the main container never sees it. The clone field is accepted only when
the operator has configured MCP_K8S_CLONE_IMAGE + MCP_K8S_CLONE_SECRET.
Security model (invariants)
Per run: a fresh ephemeral pod, deleted afterwards (success / failure / timeout). The server's
RBAC is namespace-scoped (Role/RoleBinding, never ClusterRole) — create/delete jobs,pods
plus pods/log, pods/exec in one namespace. Spawned pods run with cap-drop=ALL,
no-privilege-escalation, seccomp RuntimeDefault. The blast radius is that one namespace:
LimitRange (per-pod default+max) + ResourceQuota (namespace ceiling) + wall-clock timeout
(→ kill) + TTL/owner-reference GC + a concurrency cap. Images must pass a strict allowlist
(MCP_K8S_ALLOWED_IMAGES; empty = nothing runs). Caller data (command / files / output /
artifacts) is never persisted and never logged in full — only metadata.
run_jobis the most powerful surface there is (it creates pods). When embedding it in an agent, gate it behind that agent's tool-policy (trusted roles only).
Network note: the pod's network is not disabled (it's needed to clone repos / pull deps).
Egress is controlled by a namespace NetworkPolicy (allowlist) as a deployment concern, not a
right baked into the code. The invariant is ephemerality + deletion, not the absence of network.
Resources: the server's MCP_K8S_DEFAULT_CPU/MEMORY are pod requests (the scheduler's
reservation). Limits are set only when the caller passes limits; otherwise the ceiling comes from
the namespace LimitRange. Passing limits.memory also raises the memory request to match, since
memory is incompressible and the pod must land on a node that actually has it.
Run
Published in the MCP Registry as
io.github.inhuman/mcp-k8s-ephemeral-job; the image is on Docker Hub as
idconstruct/mcp-k8s-ephemeral-job.
From source, against a dev cluster, over stdio:
In production the server runs in-cluster as a Deployment with its own ServiceAccount +
Role/RoleBinding on the ephemeral namespace + ResourceQuota/LimitRange (+ optional egress
NetworkPolicy), usually on the http transport.
Example call (run_job)
Returns exit_code, captured output, and out.png inline in artifacts. Afterwards the pod is
gone (kubectl get jobs,pods -n $NS is empty).
Optional auth (HTTP/SSE)
Set MCP_K8S_AUTH_TOKEN to require every HTTP/SSE request to carry a matching X-MCP-AUTH header
(constant-time compare; 401 otherwise). Empty token disables it. Not applicable to stdio.
Configuration
Both cache variables must be set together for the cache to mount. The PVC itself is provisioned out-of-band (helm/manifest); the server only references it by name and fails fast at startup if it is missing.
Not implemented
PVC / object-storage delivery for artifacts too large to inline, multi-cluster support, and proxying other MCP servers into the pod.
License
MIT.
來源:README.md,提交 1623e64
工具
0版本歷史
1- v0.7.1最新Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分