axis-camera-mcp
axis-camera-mcp
一个通过 MCP(Model Context Protocol)让 LLM(Claude Code/Desktop)与 Axis 网络摄像机通信的服务器:经 VAPIX(Axis 的 HTTP/JSON 摄像机 API)查看 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):发送 JSON body{"apiVersion", "method", "params"},响应为{"data"}或{"error"}。旧版查询参数/纯文本 CGI(
com/ptz.cgi、com/ptzconfig.cgi、pwdgrp.cgi、usergroup.cgi、jpg/image.cgi):纯 GET 并携带查询参数,响应体为纯文本(有时是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,无需向量数据库服务:
爬虫(
rag/crawler.py):使用requests+ BeautifulSoup 抓取developer.axis.com(这是一个服务端渲染的 Docusaurus 站点,不需要 headless browser),并把本项目自身的 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文件作为向量存储(几百个 chunk 已经让暴力余弦搜索达到微秒级,不值得为此引入真正的向量数据库依赖)。追踪(
rag/tracking.py):本地 SQLite 文件会记录每次索引导入(每个来源的 chunk/字符数量、成功/错误状态)以及每次查询(查询内容、结果、结构分数,可通过rag_stats工具直接查看)。
设置:sentence-transformers 会带入 torch,这是高难度的安装。在纯 CPU 机器上,最好先显式安装仅 CPU 的 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 来添加/删除文档页面或本地文件,然后重新运行上面的命令。嵌入模型(约 80MB)会在首次运行时从 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 cameratests/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(对 VAPIX 文档和本项目自己的真机经验进行混合 BM25+embedding 搜索,并返回引用与关联分数)、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