axis-camera-mcp
axis-camera-mcp
MCP-сервер (Model Context Protocol), который позволяет LLM (Claude Code/Desktop) общаться с сетевой камерой Axis через VAPIX (HTTP/JSON API камер Axis): просматривать живой поток в VLC, управлять панорамированием/наклоном/зумом, регулировать настройки сенсора изображения (яркость, экспозицию, усиление, баланс белого), делать снимки, добавлять текстовые и графические оверлеи, получать/устанавливать время, управлять локальными учетными записями пользователей камеры и управлять подсветкой.
Разработан и проверен вживую на камере AXIS M3057-PLVE Mk II в локальной сети. См. docs/live-verification-checklist.md — там указано, что именно проверялось вживую, а что нет, и docs/open-questions.md — там описано подтверждённое ограничение этой конкретной камеры: команды PTZ выполняются, сообщаемая позиция обновляется, но на этой модели с фиксированной камерой не дают реального визуального эффекта панорамирования/наклона/зума.
Архитектура
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На этой камере сосуществуют два стиля запросов VAPIX, и клиентский слой обрабатывает оба, не допуская, чтобы это различие просачивалось в код инструментов:
Современный стиль JSON-RPC (
api-discovery,basicdeviceinfo,streamprofile,lightcontrol,time.cgi,dynamicoverlay): POST JSON-телом{"apiVersion", "method", "params"}, ответ{"data"}или{"error"}.Устаревшие CGI с query-параметрами и обычным текстом (
com/ptz.cgi,com/ptzconfig.cgi,pwdgrp.cgi,usergroup.cgi,jpg/image.cgi): обычный GET с query-параметрами, ответы — обычный текст (иногда строкиkey=value) или, для эндпоинта снимков, сырые байты JPEG.
Настройка
Учётные данные хранятся в файле конфигурации, а не в коде или переменных окружения:
copy config.example.json config.json
notepad config.json # fill in host/username/passwordconfig.json находится в .gitignore — он никогда не попадает в коммиты.
py -m venv .venv
.venv\Scripts\python -m pip install -e ".[dev]"Запуск
.venv\Scripts\python -m axis_camera_mcp.serverБаза знаний (RAG)
Локальная автономная база знаний позволяет LLM искать в реальной документации VAPIX API и в собственных добытых с трудом и проверенных вживую находках этого проекта (недокументированные обязательные поля, реальные значения параметров, подтверждённые только методом проб и ошибок вживую, и т.д.) вместо того, чтобы каждый раз гадать или выводить их заново.
Всё открытое, всё локальное — никаких платных API, никакого сервиса векторной БД:
Краулер (
rag/crawler.py): обычныйrequests+ BeautifulSoup дляdeveloper.axis.com(сайт с серверным рендерингом на Docusaurus — headless-браузер не нужен), плюс собственные README/docs/vapix/*.pyпроекта в качестве локальных источников.Разбиение на чанки (
rag/chunker.py): с учётом абзацев, ~700 символов с перекрытием 100.Поиск (
rag/retriever.py): гибридный — BM25 (rank-bm25, точные совпадения по ключевым словам, напримерstreamProfileName) и плотные эмбеддинги (sentence-transformers,all-MiniLM-L6-v2, только CPU, для перефразированных вопросов), объединённые через взаимное ранговое слияние (reciprocal rank fusion). В качестве векторного хранилища используется обычный numpy-файл.npz(несколько сотен чанков делают переборный косинусный поиск микросекундным — не стоит ради этого вводить зависимость от настоящей векторной БД).Отслеживание (
rag/tracking.py): локальный файл SQLite записывает каждый запуск индексации (количество чанков/символов по источникам, статус ok/error) и каждый запрос (текст, результаты, оценки) — просматривать можно напрямую или через инструментrag_stats.
Установка: sentence-transformers тянет за собой torch — это действительно тяжёлая установка. На машине только с CPU сначала явно установите CPU-only wheel, чтобы он был значительно меньше, чем сборка, разрешаемая по умолчанию:
.venv\Scripts\python -m pip install torch --index-url https://download.pytorch.org/whl/cpu
.venv\Scripts\python -m pip install -e ".[dev]"Сборка/обновление индекса (отдельный шаг, запускаемый вручную — никогда не выполняется автоматически при запуске сервера, поэтому запуск остаётся быстрым и без сетевых вызовов):
.venv\Scripts\python -m axis_camera_mcp.rag.ingestОтредактируйте axis_camera_mcp/rag/sources.json, чтобы добавить/удалить страницы документации или локальные файлы, затем снова выполните команду выше. Модель эмбеддингов (~80МБ) при первом запуске один раз загружается с Hugging Face Hub и затем кэшируется; всё остальное полностью автономно. Сгенерированные файлы индекса (rag/data/*.jsonl, *.npz, *.sqlite3) находятся в .gitignore.
Запрашивать её можно с помощью инструментов search_knowledge и rag_stats (см. «Справочник инструментов» ниже).
Регистрация в Claude Code/Desktop
{
"mcpServers": {
"axis-camera": {
"command": "<path-to-repo>\\.venv\\Scripts\\python.exe",
"args": ["-m", "axis_camera_mcp.server"]
}
}
}Перезапустите Claude Code/Desktop после добавления, чтобы инструменты появились.
Тестирование
.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Скрипты в tests/manual/ общаются с реальной камерой из config.json — просмотрите, что делает каждый из них, прежде чем запускать его на камере, которая вам важна. live_smoke_test.py — только чтение. Скрипты mcp_harness_*.py проверяют полный путь вызова инструментов MCP (включая изменяющие операции: движения PTZ, изменения времени/часового пояса, добавление/удаление пользователей) — это собственные скрипты живой проверки проекта; относитесь к ним как к справочному материалу, а не как к тому, что можно бездумно перезапускать на продакшн-камере.
Справочник инструментов
Информация об устройстве/API (только чтение): get_device_info, get_supported_apis, get_camera_overview
Стриминг (просмотр живого видеопотока в локально установленном VLC): start_stream, stop_stream, get_stream_status, list_stream_profiles
Снимки (одиночный неподвижный кадр, отдельно от видеопотока): save_snapshot (только файл, LLM никогда не видит изображение), get_snapshot (возвращается напрямую LLM, чтобы он мог описать, что находится в кадре)
PTZ (панорамирование/наклон/зум — см. docs/open-questions.md об отсутствии визуального эффекта на этой конкретной камере): ptz_move_absolute, ptz_move_relative, ptz_get_position, ptz_save_preset, ptz_goto_preset, ptz_list_presets
Сенсор изображения (яркость/контраст/насыщенность/резкость, экспозиция, усиление, выдержка, баланс белого — фактические настройки сенсора/ISP, в отличие от кадрирования/обрезки при PTZ и физического осветителя подсветки): get_image_settings, set_image_appearance, set_exposure_mode, set_exposure_value, set_manual_gain, set_manual_shutter, set_white_balance
Оверлеи (текст/изображение, встраиваемые в видеопоток): add_text_overlay, set_text_overlay, add_image_overlay, set_image_overlay, list_overlays, remove_overlay, get_overlay_capabilities
Часы: get_clock_info, set_clock, set_timezone
Подсветка (на этой конкретной камере нет аппаратной подсветки — подтверждено через get_light_status, который сообщает об этом явно): get_light_status, activate_light/deactivate_light, enable_light/disable_light, set_light_intensity, get_valid_intensity, set_light_auto_mode
Пользователи — изменяющие операции требуют confirm: true, это единственная область с реальными последствиями для безопасности: list_users (возвращает все учетные записи с их группами привилегий для привилегированного вызывающего), add_user, update_user, remove_user
База знаний (см. «База знаний (RAG)» выше): search_knowledge (гибридный поиск BM25+эмбеддинги по документации VAPIX и собственным проверенным вживую находкам проекта, с указанием источников и оценками), rag_stats (что проиндексировано, откуда и когда, а также недавняя история запросов — прямо сообщает, требует ли индекс запуска rag.ingest)
Безопасность
Изменяющие операции с учетными записями пользователей (add_user, update_user, remove_user) требуют явного аргумента confirm: true и без него вызывают понятную ошибку — это единственная область, где неосторожный вызов имеет реальные последствия для безопасности (несанкционированный доступ или случайная блокировка). Всё остальное (PTZ, подсветка, часы, стриминг, оверлеи, снимки) по замыслу не требует подтверждения: это полностью обратимо, и это одна камера, которой пользователь владеет напрямую, а не общая продакшн-система.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for Pentest-Tools.com: run scans, manage findings and reports via your preffered LLM.
MCP server for Clipkit — gives AI agents a video toolbox via the Clipkit schema.
MCP server for AI dialogue using various LLM models via AceDataCloud
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/cdp/GSX2026-axis-camera-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server