MCP (Model Context Protocol) server for PTZ camera control with gimbal positioning, snapshots, and AI visual analysis integration.
Designed for OBSBOT Tiny SE but works with any UVC PTZ camera that supports v4l2 controls.
- Full Gimbal Control: Pan, tilt, zoom with safety limits
- Real-time Position Feedback: Human-readable directions
- Camera Snapshots: High-resolution capture
- Visual Analysis: LM Studio integration for vision-language models
- Area Scanning: Horizontal, vertical, grid, and panoramic patterns
- Autonomous Search: Shell scripts for systematic exploration
- Python Library: Direct control for custom applications
- Linux with v4l2 support
- Node.js 18+ (for MCP server)
- Python 3.8+ (for Python library)
# Ubuntu/Debian
sudo apt install v4l-utils ffmpeg python3-opencv
# Fedora
sudo dnf install v4l-utils ffmpeg python3-opencv- LM Studio for visual analysis
- Vision-language model (e.g., Qwen2.5-VL, LLaVA)
cd obsbot-camera-mcp
npm installpip install opencv-pythonexport OBSBOT_DEVICE="/dev/video0" # Camera device
export OBSBOT_OUTPUT_DIR="/tmp/obsbot" # Capture directory
export LM_STUDIO_URL="http://localhost:1234/v1/chat/completions"
export OBSBOT_VL_MODEL="qwen2.5-vl-7b-instruct"Add to ~/.config/claude/claude_desktop_config.json:
{
"mcpServers": {
"obsbot": {
"command": "node",
"args": ["/path/to/obsbot-camera-mcp/src/obsbot-mcp-server.mjs"],
"env": {
"OBSBOT_DEVICE": "/dev/video0"
}
}
}
}Get current pan, tilt, zoom with readable directions.
Move gimbal to absolute position.
- Pan: -468000 (right) to 468000 (left)
- Tilt: -324000 (down) to 324000 (up)
- Zoom: 0 (wide) to 12 (telephoto)
Return to neutral position (0, 0, 0).
Capture image with optional LM Studio analysis.
{
"analyzeWithLM": true,
"customPrompt": "Describe what you see"
}Move camera and take analyzed snapshot in one operation.
Systematic multi-position scan.
{
"pattern": "horizontal", // or vertical, grid, panoramic
"steps": 5
}Verify camera and LM Studio availability.
from python.obsbot_control import OBSBOTController
camera = OBSBOTController()
camera.connect()
# Move to position
camera.set_position(pan=200000, tilt=100000, zoom=2)
# Use presets
camera.preset_position("left")
camera.preset_position("center")
# Capture
camera.save_frame("snapshot.jpg")
# Scan
results = camera.scan_horizontal(steps=5, capture=True)
camera.disconnect()# Basic search
./scripts/autonomous_scan.sh "find the window"
# Grid pattern with verbose output
./scripts/autonomous_scan.sh --pattern grid --verbose "locate books"
# Quick scan
./scripts/autonomous_scan.sh --pattern quick "identify objects"Tested with:
- OBSBOT Tiny SE
- OBSBOT Meet
Should work with any UVC PTZ camera supporting:
pan_absolutecontroltilt_absolutecontrolzoom_absolutecontrol
Check your camera's controls:
v4l2-ctl -d /dev/video0 --list-ctrlsThe v4l2 control values map to directions:
- Pan: Positive = LEFT, Negative = RIGHT
- Tilt: Positive = UP, Negative = DOWN
- Zoom: Higher = telephoto (zoomed in)
v4l2-ctl --list-devices
ls -la /dev/video*sudo usermod -a -G video $USER
# Logout and login again# Check available controls
v4l2-ctl -d /dev/video0 --list-ctrls
# Test manual control
v4l2-ctl -d /dev/video0 --set-ctrl=pan_absolute=100000MIT License - See LICENSE file
- sam-angle-detection - SAM-based angle measurement
- openwebui-anthropic-pipe - Anthropic API pipe for Open WebUI