
UVC PTZ Camera
io.github.AbhijatSaxenav0.1.1更新於 Oct 7, 2026
Control a USB (UVC) pan/tilt/zoom camera, with every move confirmed from the picture.
概覽
讓助理控制 USB(UVC)雲台變焦攝影機進行對準、微調、掃掠、變焦與取景,並以移動前後的畫面比對確認每次動作。
- 功能
- 為 USB UVC PTZ 攝影機提供工具:camera_status、aim、nudge、sweep、zoom、recentre 與 look,以及用來記住方向與檢查畫面的 aim_learn、aim_list、go_to、run_shot、mark_view、check_view。每次移動都透過比對前後畫面確認,裝置回報的位置只會以標註過的提示回傳。內建經校準的模擬器後端,可在沒有硬體時試用。
- 適用情境
- 適合需要助理實際轉動 USB PTZ 攝影機、且要求移動經過畫面驗證而非只信任裝置回讀的情境。可用於桌面或房間取景、儲存視角,以及在有直接連接攝影機的機器上執行多步驟拍攝。
- 執行需求
- 以 stdio 在本機執行,通常透過 uvx 或 pip 安裝該 PyPI 套件。真實攝影機路徑僅支援 Windows,且需要 DirectShow 附加元件;其他平台可使用模擬器後端。選用環境變數包括 UVC_PTZ_SIM_SOURCE 與 UVC_PTZ_STATE_DIR;不需要帳號、API 金鑰或雲端服務。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 UVC PTZ Camera,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
uvc-ptz-camera-mcp
An MCP server for USB (UVC) pan/tilt/zoom cameras: aim them, nudge them, sweep them smoothly, zoom, and look through them — with every move confirmed by comparing the picture before and after.
No account, no cloud, no vendor SDK. One device, one USB cable.
Why this exists
This class of camera reports positions it never moved to. Measured on the reference device (a DJI Osmo Pocket 4P in webcam mode, over its standard UVC controls):
- a command to pan to
180read back180while the video proved the camera had not moved at all; - a whole 32-second run read back
0on every sample while the frame demonstrably changed; - pan
120read back119, pan200read back199.
An agent acting on those values reports moves that never happened. So this server treats every
device-reported value as a hint — returned, labelled, never trusted — and decides moved
by comparing frames.
The threshold is not a guess either. It was calibrated on labelled hardware frames: every "same view" pair scored ≤ 0.104 (a 96-second quiet baseline, and two commands the hardware ignored), every "view changed" pair scored ≥ 0.624 (a pan, a tilt, a 12× zoom, two aim steps). The shipped threshold is the midpoint, 0.364 — a 6× separation — and the test suite asserts it still separates them.
What keeps the agent honest
movedcomes from the picture.device_reportedis returned beside it, labelled a hint.- A move that produced no change is an error, not a quiet success — after a bounded retry, the tool fails naming what was requested and what was observed.
- Already being at the target is success without movement:
moved: false, no error. - Blocking work never runs on the event loop (COM calls, ffmpeg captures), pinned by a test that records which thread the camera was touched on.
- Observation is explicit: nothing takes a picture except a tool you called.
- A refused write aborts a shot rather than continuing to drive a camera that stopped listening.
Install
For a real camera on Windows you also need the DirectShow extras:
Then point your host at it — --print-config emits the snippet with the right interpreter:
Where to put it
Claude Desktop, Cursor, VS Code and friends all take the same shape — this is the whole configuration, because there is nothing to authenticate:
Add "--device", "Osmo" (any substring of the name --list-devices prints) when the machine has
more than one camera, and "--backend", "simulator" to work with none. Both can also be set in the
environment instead of the args — UVC_PTZ_DEVICE, UVC_PTZ_BACKEND and UVC_PTZ_STATE_DIR — which
is what the Claude Desktop bundle uses, and which survives a host restart without editing its config
again. A flag wins over the environment, and an empty value means "not set" (a host that leaves an
option blank writes "", not nothing). Claude Desktop also accepts the .mcpb bundle attached to
each release as a one-click install.
Modes, and how you can tell which one you are in
Every result carries "simulated": true or false, and camera_status reports the reason when
the simulator is standing in. Nothing quietly pretends to be hardware: a caller must never
believe it is driving a camera when it is driving a model.
The simulator is calibrated from the reference device, not invented: ~0.4 s from write to first motion, a pan completing in about a second, a 4× zoom in about 2.5 s, silently dropped writes, and a read-back that echoes a request the hardware never applied. It renders frames by cropping a wide panorama, so a simulated pan genuinely changes the pixels — a simulator with a static picture would let verification pass vacuously.
Honest limitations
- The real-device path is Windows-only (DirectShow). A Linux backend would use
v4l2; the interface is in place, the implementation is not written. - No exposure, focus or white balance. The reference camera exposes no Processing Unit at all — only pan/tilt/roll/zoom.
- The vendor Extension Unit is unreachable on Windows, so features that live there (on the
reference camera, its built-in subject tracking) cannot be driven from software. Measured:
IKsControlis refused on the device filter,IKsTopologyInfolists three nodes and no vendor node, andCreateNodeInstancefails on all of them. Linux can reach it throughuvcvideo'sUVCIOC_CTRL_QUERY; that is a separate backend. - A moving subject looks like a moving camera. Frame comparison cannot tell the two apart;
the metric is calibrated so that a static scene behaves, and
check_viewis there for judging a view rather than a move. - One unusable device must not hide the others. A registered-but-unavailable virtual camera raised when its DirectShow moniker was bound, which aborted a listing that should have returned two working cameras. Enumeration now skips what it cannot load and says so, and the same rule applies inside the backend when it looks for the camera you named.
- Measured latency sets the ceiling: ~0.4 s from command to motion, so control loops run at a couple of hertz, not tens. That is the hardware's floor, not the software's.
- The DirectShow path is tested but dormant. The reference device was returned partway through development, so the hardware path is exercised up to its interface and typed correctly against it, while the simulator carries the test load. Treat the first run against a real camera as the true acceptance test.
Development
The suite is layered deliberately: the tool surface in-process against the simulator (mapping, validation, honest failure), pure unit tests for the compiler and the metric, and a real stdio handshake as a subprocess — including one run with a device name that cannot exist, because a server that dies at startup is invisible to every host and directory that lists it.
Reference device
Built against a DJI Osmo Pocket 4P in webcam mode: VID_2CA3 / PID_0023, exposing pan
−38…215°, tilt −33…105°, roll ±35°, zoom 100…1200 (1×–12×) as standard UVC camera controls.
Any UVC PTZ camera exposes the same surface; the ranges are read from the device at startup
rather than assumed, and nothing vendor-specific is hard-coded.
Not affiliated with, endorsed by, or supported by DJI.
來源:README.md,提交 9101220
工具
0版本歷史
1- v0.1.1最新Oct 7, 2026


