Axis Camera
FreeNot checkedMCP server that lets an LLM control an Axis network camera over VAPIX, including live streaming, PTZ, image settings, overlays, clock, light, user management, a
About
MCP server that lets an LLM control an Axis network camera over VAPIX, including live streaming, PTZ, image settings, overlays, clock, light, user management, and a built-in RAG knowledge base of VAPIX docs.
README
An MCP (Model Context Protocol) server that lets an LLM (Claude Code/Desktop) talk to an Axis network camera over VAPIX (Axis's HTTP/JSON camera API): view the live stream in VLC, control pan/tilt/zoom, adjust image sensor settings (brightness, exposure, gain, white balance), capture snapshots, add text/image overlays, get/set the clock, manage local camera user accounts, and control the light.
Built and live-verified against an AXIS M3057-PLVE Mk II on a local network.
See docs/live-verification-checklist.md for exactly what's been tested live vs.
not, and docs/open-questions.md for a confirmed limitation of this specific camera:
PTZ commands succeed and the reported position updates, but produce no real visual
pan/tilt/zoom effect on this fixed-camera model.
Architecture
axis_camera_mcp/
config.py Loads camera host/username/password from config.json
vapix/
session.py requests.Session + HTTP Digest auth
jsonrpc.py Client for VAPIX's modern JSON-RPC-style APIs
legacy.py Client for VAPIX's legacy query-param/plain-text CGIs
client.py VapixClient facade - the only thing tools/* imports
exceptions.py
vlc_launcher.py Starts/stops the local VLC install to view the RTSP stream
rag/ Local knowledge base: VAPIX docs + this project's own
live-verified findings, hybrid BM25+embedding search
(see "Knowledge base (RAG)" below)
app.py / context.py Shared FastMCP instance + lazy VapixClient/VlcLauncher/
HybridRetriever singletons
tools/ One module per capability, each registering @mcp.tool()s
server.py Entrypoint: import tools, preload_rag(), mcp.run()
tests/
test_*.py Unit tests, mocked HTTP, no live camera needed
manual/ Plain scripts (not pytest) exercised against the real camera
docs/
live-verification-checklist.md One row per tool - what's actually been tested live
open-questions.md Confirmed limitations and things not yet tried
Two VAPIX request styles exist side by side on this camera, and the client layer handles both without leaking the difference into tool code:
- Modern JSON-RPC style (
api-discovery,basicdeviceinfo,streamprofile,lightcontrol,time.cgi,dynamicoverlay): POST JSON body{"apiVersion", "method", "params"}, response{"data"}or{"error"}. - Legacy query-param/plain-text CGIs (
com/ptz.cgi,com/ptzconfig.cgi,pwdgrp.cgi,usergroup.cgi,jpg/image.cgi): plain GET with query params, responses are plain text (sometimeskey=valuelines) or, for the snapshot endpoint, raw JPEG bytes.
Setup
Credentials live in a config file, never in code or environment variables:
copy config.example.json config.json
notepad config.json # fill in host/username/password
config.json is gitignored - it never gets committed.
py -m venv .venv
.venv\Scripts\python -m pip install -e ".[dev]"
Running
.venv\Scripts\python -m axis_camera_mcp.server
Knowledge base (RAG)
A local, offline knowledge base lets the LLM search the real VAPIX API docs and this project's own hard-won, live-verified findings (undocumented required fields, real parameter values confirmed only through live trial-and-error, etc.) instead of guessing or re-deriving them each time.
All open-source, all local - no paid API, no vector-DB service:
- Crawler (
rag/crawler.py): plainrequests+ BeautifulSoup againstdeveloper.axis.com(a server-rendered Docusaurus site - no headless browser needed), plus this project's own README/docs/vapix/*.pyas local sources. - Chunking (
rag/chunker.py): paragraph-aware, ~700 chars with 100 overlap. - Retrieval (
rag/retriever.py): hybrid - BM25 (rank-bm25, exact keyword matches likestreamProfileName) and dense embeddings (sentence-transformers,all-MiniLM-L6-v2, CPU-only, for paraphrased questions), combined via reciprocal rank fusion. A plain numpy.npzfile serves as the vector store (a few hundred chunks makes brute-force cosine search microseconds-scale - not worth a real vector-DB dependency). - Tracking (
rag/tracking.py): a local SQLite file logs every ingestion run (per-source chunk/char counts, ok/error status) and every query (text, results, scores) - inspectable directly or via therag_statstool.
Setup: sentence-transformers pulls in torch, a genuinely heavy install. On a
CPU-only machine, install the CPU-only wheel explicitly first to keep it much
smaller than the default resolved build:
.venv\Scripts\python -m pip install torch --index-url https://download.pytorch.org/whl/cpu
.venv\Scripts\python -m pip install -e ".[dev]"
Build/refresh the index (a separate, manually-run step - never runs automatically at server startup, so startup stays fast and network-call-free):
.venv\Scripts\python -m axis_camera_mcp.rag.ingest
Edit axis_camera_mcp/rag/sources.json to add/remove doc pages or local files, then
re-run the command above. The embedding model (~80MB) downloads once from Hugging
Face Hub on first run and is cached afterward; everything else is fully offline.
Generated index files (rag/data/*.jsonl, *.npz, *.sqlite3) are gitignored.
Query it with the search_knowledge and rag_stats tools (see Tool reference below).
Register with Claude Code/Desktop
{
"mcpServers": {
"axis-camera": {
"command": "<path-to-repo>\\.venv\\Scripts\\python.exe",
"args": ["-m", "axis_camera_mcp.server"]
}
}
}
Restart Claude Code/Desktop after adding this for the tools to appear.
Testing
.venv\Scripts\python -m pytest tests/ --ignore=tests/manual # unit tests, mocked HTTP
.venv\Scripts\python tests/manual/live_smoke_test.py # read-only checks against the real camera
The tests/manual/ scripts talk to the real camera in config.json - review what
each one does before running it against a camera you care about. live_smoke_test.py
is read-only. The mcp_harness_*.py scripts exercise the full MCP tool-call path
(including mutations like PTZ moves, clock/timezone changes, and user add/remove) -
these were this project's own live-verification scripts; treat them as reference,
not something to re-run casually against a production camera.
Tool reference
Device/API info (read-only): get_device_info, get_supported_apis, get_camera_overview
Streaming (view the live stream in the local VLC install): start_stream,
stop_stream, get_stream_status, list_stream_profiles
Snapshot (single still frame, separate from the video stream): save_snapshot
(file only, the LLM never sees the image), get_snapshot (returned directly to the
LLM so it can describe what's in view)
PTZ (pan/tilt/zoom - see docs/open-questions.md re: no visual effect on
this specific camera): ptz_move_absolute, ptz_move_relative, ptz_get_position,
ptz_save_preset, ptz_goto_preset, ptz_list_presets
Image sensor (brightness/contrast/saturation/sharpness, exposure, gain,
shutter, white balance - the actual sensor/ISP settings, distinct from PTZ's
framing/crop and light's physical illuminator): get_image_settings,
set_image_appearance, set_exposure_mode, set_exposure_value,
set_manual_gain, set_manual_shutter, set_white_balance
Overlays (text/image burned into the video stream): add_text_overlay,
set_text_overlay, add_image_overlay, set_image_overlay, list_overlays,
remove_overlay, get_overlay_capabilities
Clock: get_clock_info, set_clock, set_timezone
Light (this specific camera has no light hardware - confirmed via
get_light_status, which reports that clearly): get_light_status,
activate_light/deactivate_light, enable_light/disable_light,
set_light_intensity, get_valid_intensity, set_light_auto_mode
Users - mutations require confirm: true, the one area with real security
consequence: list_users (returns every account with its privilege groups, for a
privileged caller), add_user, update_user, remove_user
Knowledge base (see "Knowledge base (RAG)" above): search_knowledge (hybrid
BM25+embedding search over VAPIX docs and this project's own live-verified findings,
with source citations and scores), rag_stats (what's indexed, from where, when,
and recent query history - states plainly if the index needs rag.ingest run)
Safety
User-account mutations (add_user, update_user, remove_user) require an explicit
confirm: true tool argument and raise a clear error without it - this is the one
area where a careless call has real security consequence (unauthorized access or an
accidental lockout). Everything else (PTZ, light, clock, streaming, overlays, snapshots)
is unconfirmed by design: it's freely reversible and this is a single camera the user
owns directly, not a shared production system.
Installing Axis Camera
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/cdp/GSX2026-axis-camera-mcpFAQ
Is Axis Camera MCP free?
Yes, Axis Camera MCP is free — one-click install via Unyly at no cost.
Does Axis Camera need an API key?
No, Axis Camera runs without API keys or environment variables.
Is Axis Camera hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Axis Camera in Claude Desktop, Claude Code or Cursor?
Open Axis Camera on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
ARA
Generate images, video and audio from any AI agent — one connector.
by ARAOmni Video
An MCP server that transforms LLM-enabled IDEs into professional video editors by pre-processing footage into text proxies, generating motion graphics via HTML/
by buildwithtazaYouTube
Transcripts, channel stats, search
by YouTubeEverArt
AI image generation using various models.
by modelcontextprotocolgpu-bridge/mcp-server
Unified GPU inference API with 30 AI services (LLM, image gen, video, TTS, whisper, embeddings, reranking, OCR) as MCP tools. Pay-per-use via x402 USDC or API k
by gpu-bridgehamflx/imagen3-mcp
A powerful image generation tool using Google's Imagen 3.0 API through MCP. Generate high-quality images from text prompts with advanced photography, artistic,
by hamflxmerterbak/Grok-MCP
MCP server for xAI's [Grok API](https://docs.x.ai/docs/overview) with agentic tool calling, image generation, vision, and file support.
by merterbakSureScaleAI/openai-gpt-image-mcp
OpenAI GPT image generation/editing MCP server.
by SureScaleAIYangLiangwei/PersonalizationMCP
Comprehensive personal data aggregation MCP server with Steam, YouTube, Bilibili, Spotify, Reddit and other platforms integrations. Features OAuth2 authenticati
by YangLiangweiAceDataCloud/MCPFlux
Flux AI image generation and editing (Black Forest Labs) via Ace Data Cloud API.
by AceDataCloudCompare Axis Camera with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All media MCPs
