upscayl-docker-worker

upscayl-docker-worker

Enables private, GPU-backed image upscaling via a local Hermes MCP bridge that submits jobs to an authenticated Upscayl worker API.

Category
访问服务器

README

Upscayl Docker Worker

A private, authenticated, GPU-backed Upscayl worker with a local Hermes Agent MCP bridge. The worker runs the standalone NCNN/Vulkan backend in Docker; Hermes runs the bridge locally so private image files do not pass through model context.

For a complete worker-to-Hermes installation, follow HOWTO.md. It covers host preparation, secure configuration, deployment, MCP registration, end-to-end GPU verification, and troubleshooting.

Hermes -> local stdio MCP bridge -> authenticated worker API -> NVIDIA/Vulkan
       <- validated local PNG    <- validated job result      <- Upscayl NCNN

This repository intentionally contains both halves:

  • upscayl_worker/ — the FastAPI service packaged in the Docker image.
  • upscayl_bridge/ — the local stdio MCP bridge installed on the Hermes host.

A separate MCP repository is not needed. The bridge and worker share one API contract, test suite, and release lifecycle, while still running in different places. Splitting them would add version coordination without improving the security boundary.

Published image

The production image is published at:

yellowcooln/upscayl-docker-worker

Supported platform: linux/amd64.

GitHub Actions publishes:

  • latest from the default branch
  • branch tags such as main and dev
  • version tags such as v1.0.0
  • source-reference tags such as sha-0883691

Registry tags, including sha-*, can be overwritten. Only a registry digest is an immutable deployment reference.

The image is built from the official Upscayl Flatpak on a hosted runner. The backend and models remain absent from Git, while their Flatpak version and commit are recorded inside the image at:

/usr/share/doc/upscayl-docker-worker/upscayl-source.txt

What is included

  • Pre-parser bearer authentication and streamed upload limits
  • Decoded pixel, dimension, output, intermediate, timeout, queue, and disk limits
  • One active GPU worker with bounded pending admission
  • Automatic photo/digital routing and exact 1×–16× output planning
  • Expiring opaque job storage and restart orphan cleanup
  • A narrow MCP surface: upscale_image, list_models, and worker_status
  • Real API, MCP, PNG/CRC, and GPU-utilization verification scripts

Worker prerequisites

  • Linux x86-64 Docker host with an NVIDIA GPU
  • NVIDIA driver and NVIDIA Container Toolkit
  • Docker Engine; Docker Compose is optional
  • Python 3 for fixture generation and independent PNG validation

Confirm basic GPU visibility:

docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 \
  nvidia-smi --query-gpu=name,driver_version --format=csv,noheader

nvidia-smi alone is not proof that Upscayl works. NCNN also requires a functional Vulkan ICD inside the container.

Deploy the published image

Clone the repository for the hardened deployment scripts and configuration:

git clone https://github.com/yellowcooln/upscayl-docker-worker.git
cd upscayl-docker-worker
cp .env.example .env
chmod 600 .env

Set a random UPSCAYL_WORKER_TOKEN, the correct NVIDIA driver version, and the private bind address in .env. The worker and deployment script reject the public placeholder token from .env.example. Then deploy and verify:

scripts/deploy-api.sh
scripts/verify-api.sh

deploy-api.sh pulls yellowcooln/upscayl-docker-worker:latest by default, validates that it is linux/amd64, and only then recreates the service. It prints the deployed image ID and repository digest.

Docker Compose provides the same image-first deployment:

docker compose up -d

For reproducible production deployment, set UPSCAYL_IMAGE to a version tag or immutable registry digest instead of latest:

UPSCAYL_IMAGE=yellowcooln/upscayl-docker-worker@sha256:<digest>
UPSCAYL_PULL_POLICY=always

The API binds to loopback by default. Plain HTTP is appropriate only on loopback or an encrypted trusted network such as a VPN; use HTTPS for any other path and never publish the worker directly to the Internet.

Verify direct GPU inference

The direct backend verifier now uses the published image rather than rebuilding locally:

scripts/verify-gpu.sh

It generates a deterministic 512×384 fixture, invokes the container's upscayl-bin entrypoint directly, validates the 2048×1536 output structure and CRCs, and prints hashes.

For a manual invocation, place an image under io/ and run:

scripts/run-worker.sh \
  -i /work/input.png \
  -o /work/output.png \
  -m /opt/upscayl/models \
  -n high-fidelity-4x \
  -z 4 \
  -s 4 \
  -f png \
  -v

Hermes MCP bridge

The bridge must run on the Hermes host because that is where local attachments and filesystem paths exist. It should not run inside the remote GPU container. Install it from this same checkout:

uv sync --frozen --no-dev --extra bridge

The bridge uses these environment-backed settings:

UPSCAYL_WORKER_URL=http://private-gpu-host:8788
UPSCAYL_WORKER_TOKEN=<secret>
UPSCAYL_ALLOW_INSECURE_HTTP=true
UPSCAYL_ALLOWED_INPUT_ROOTS=/home/user/.hermes:/home/user/Pictures
UPSCAYL_OUTPUT_DIR=/home/user/Pictures/upscayl

Non-loopback HTTP requires the explicit UPSCAYL_ALLOW_INSECURE_HTTP=true acknowledgement; omit it when using HTTPS or loopback. UPSCAYL_ALLOWED_INPUT_ROOTS is required; the bridge fails closed instead of defaulting to the whole home directory. Store these settings in the active Hermes profile's mode-0600 .env. Register the bridge without copying the token into config.yaml or process arguments:

hermes mcp add upscayl \
  --command /usr/bin/bash \
  --connect-timeout 60 \
  --args -lc 'set -a; source "${HERMES_HOME:-$HOME/.hermes}/.env"; set +a; exec /absolute/path/to/repo/.venv/bin/upscayl-mcp'

Enable only upscale_image, list_models, and worker_status. Then verify both discovery and a real GPU job:

hermes mcp test upscayl
python3 scripts/create_fixture.py io/upscayl-mcp-fixture.png
uv run python scripts/verify-mcp.py io/upscayl-mcp-fixture.png

Run /reload-mcp or start a new Hermes session after changing the MCP setup. Image bytes travel directly between the local bridge and authenticated worker; they never enter model context.

Maintainer/local image build

Consumers do not need Upscayl or Flatpak installed on the Docker host. These steps are only for maintainers who want to build the image locally from their currently installed Flatpak:

scripts/stage-from-flatpak.sh
scripts/build-local.sh
UPSCAYL_IMAGE=local/upscayl-api:latest \
UPSCAYL_PULL_POLICY=never \
  scripts/deploy-api.sh

stage-from-flatpak.sh copies the backend, four reviewed model pairs, and Flatpak provenance from the reviewed org.upscayl.Upscayl Flatpak into ignored vendor/ paths. It rejects unexpected Flatpak versions, OSTree commits, manifests, binaries, or model hashes. scripts/build-local.sh refuses to build when any required asset or provenance file is missing. Matching the build process does not prove byte-for-byte reproduction of a published artifact; use the recorded Flatpak commit, image digest, and asset hashes for exact provenance. UltraSharp and UltraMix Balanced retain CC BY-NC-SA 4.0/non-commercial terms; see THIRD_PARTY_NOTICES.md before redistributing or using the complete image commercially.

NVIDIA/Vulkan compatibility

NVIDIA Container Toolkit 1.19.x on Debian 13 can expose CUDA while omitting libraries needed by Vulkan. The deployment mounts the exact host-driver versions of these libraries read-only:

  • libnvidia-eglcore
  • libnvidia-glsi
  • libnvidia-tls
  • libnvidia-glcore
  • libnvidia-gpucomp
  • libnvidia-glvkspirv

The image also installs libegl1. Re-run both GPU and API verification after an NVIDIA driver or container-toolkit update.

Worker API

  • GET /healthz — unauthenticated process liveness
  • GET /readyz — authenticated model/GPU readiness and queue depth
  • GET /v1/models — authenticated model capabilities
  • POST /v1/jobs — authenticated multipart submission
  • GET /v1/jobs/{id} — authenticated status
  • GET /v1/jobs/{id}/result — authenticated PNG result
  • DELETE /v1/jobs/{id} — authenticated terminal-job cleanup

POST /v1/jobs accepts scales from 1 through 16, image_type as auto, photo, or digital, and model as auto or an allow-listed ID.

Development

uv sync --frozen --extra test
uv run pytest -q
uv run ruff check upscayl_worker upscayl_bridge tests scripts
uv run ruff format --check upscayl_worker upscayl_bridge tests scripts

See docs/mcp-architecture.md for the implemented integration boundary and docs/operations.md for deployment limits, token rotation, cleanup, and release verification.

Licensing

Original repository code and deployment glue are MIT licensed. The published container also contains unmodified third-party Upscayl runtime and model assets with separate licenses and attribution requirements, including non-commercial terms for some models. See NOTICE and THIRD_PARTY_NOTICES.md before redistribution or commercial use.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选