@moziaverse/omni-cli
v1.0.1
Published
MCP Vision Server for OpenAI-compatible omni models
Readme
Omni CLI
@moziaverse/omni-cli 是一个同时提供 CLI 和 MCP Server 的视觉分析工具,用于 OpenAI-compatible 视觉模型部署,支持图像分析、视频片段分析和 LocateAnything 图片定位。
功能特性
图像分析 (analyze_image)
- 通用图像分析工具,适用于日常视觉内容理解
- 对象识别和描述
- 场景理解和上下文分析
- 自然图像文本提取(标志、标签、文档)
- 通用视觉问答
- 照片构图和内容描述
- 识别人物、地点、动物和日常物品
- 可选传入
system_prompt覆盖默认图像分析角色提示词
视频片段分析
旧版 analyze_video 已移除。视频分析统一走片段化接口:
analyze_video_segment:分析单个时间段或帧段。整段视频可传start_seconds=0, end_seconds=-1。analyze_video_segments:并发分析多个指定时间段或帧段。scan_video:按固定间隔自动切片、压缩、并发调用 omni model,返回片段级观察数组。
这些工具会在 MCP 内部用 ffprobe/ffmpeg 读取元数据、切片、压缩,再把标准化短视频传给 omni model。
LocateAnything 通用检测工具(可选)
只有设置 LOCATEANYTHING_API_URL 时才会注册以下工具:
locate_image:检测单张图片中的目标,固定调用 LocateAnything OpenAI-compatible/v1/chat/completions。
MCP 只保留可靠的 Locate API 原子包装。视频抽帧、track 拼接、假框过滤、D2 合并等业务逻辑应放在 skill 中完成。
默认策略:
targets默认["person"];未传prompt时自动生成官方 Object Detection Prompt。prompt可传完整官方 Prompt,也可传目标描述;简单目标描述会自动包成检测 Prompt。- 默认
max_tokens=512、temperature=0.2、top_p=0.9,不暴露为工具参数。 - 可视化图片始终生成,不暴露
return_visualization。 quality三档:low=448px、medium=640px、high=768px,表示抽帧/图片预处理后的长边上限。
支持格式:
- 图像:所有常见图像格式(JPG, PNG, GIF 等)
- 视频:由本地
ffmpeg/ffprobe支持的本地路径或远程 URL。片段工具不再使用旧版 8MB 原视频限制,会先切片压缩后调用 omni model。
环境要求
- Node.js >= 18.0.0
- npm 或 yarn
- OpenAI-compatible 视觉模型服务(如 GLM-4.6V-W8A8)
安装
npm 全局安装
npm install -g @moziaverse/omni-cli
omni-cli --helpnpx 临时使用
npx -y @moziaverse/omni-cli --help
npx -y @moziaverse/omni-cli image analyze --image /path/to/image.jpg --prompt "请描述画面内容"本地开发安装
git clone <repository-url>
cd mcp-vision-local
npm install编译
npm run build编译后的文件将输出到 build/ 目录。
配置
环境变量
创建 .env 文件或设置以下环境变量:
# 视觉模型 API 端点(必需)
export OMNI_MODEL_API_URL="http://117.161.30.145:8001/v1/"
# 模型名称(必需)
export OMNI_MODEL_NAME="GLM-4.6V-W8A8"
# API 密钥(本地模型可设为 EMPTY)
export OMNI_MODEL_API_KEY="EMPTY"
# 请求超时时间(可选,默认 300000ms)
export OMNI_MODEL_TIMEOUT="300000"
# 单个视频片段的端到端超时时间(可选,默认跟随 OMNI_MODEL_TIMEOUT)
export OMNI_MODEL_SEGMENT_TIMEOUT="90000"
# 视频片段与 omni model 结果缓存目录(可选)
export MCP_VISION_CACHE_DIR="/tmp/mcp-vision-local"
# LocateAnything OpenAI-compatible v1 服务地址(可选;未设置时不会注册 locate_* 工具)
# 可填 http://host:8010 或 http://host:8010/v1
export LOCATEANYTHING_API_URL="http://116.136.189.17:8010/v1"
# LocateAnything 模型名称和 API Key(可选)
export LOCATEANYTHING_MODEL="LocateAnything-3B"
export LOCATEANYTHING_API_KEY="EMPTY"
# LocateAnything 请求超时(可选,默认 300000ms)
export LOCATEANYTHING_TIMEOUT="300000"
# LocateAnything 输出 token 上限(可选,默认 512)
export LOCATEANYTHING_MAX_TOKENS="512"
# LocateAnything 本地上传大小限制(可选)
export LOCATEANYTHING_MAX_IMAGE_MB="25"配置说明:
OMNI_MODEL_API_URL: OpenAI-compatible 视觉模型服务端点地址OMNI_MODEL_NAME: 使用的视觉模型名称OMNI_MODEL_API_KEY: API 密钥,本地部署的模型通常设为EMPTYOMNI_MODEL_TIMEOUT: 请求超时时间(毫秒)OMNI_MODEL_SEGMENT_TIMEOUT: 单个视频片段的端到端超时时间,覆盖切片、编码、omni model 调用和重试预算。批量接口中某个片段超时会返回该片段ok=false,不会阻塞其他片段结果返回。MCP_VISION_CACHE_DIR: 视频切片和片段级 omni model 结果缓存目录,默认是系统临时目录下的mcp-vision-localLOCATEANYTHING_API_URL: LocateAnything OpenAI-compatible v1 服务地址。可填到服务根路径或/v1,只有设置该变量时,MCP 才会注册locate_image。LOCATEANYTHING_MODEL: LocateAnything 模型名,默认LocateAnything-3B。LOCATEANYTHING_API_KEY: API 密钥,默认EMPTY。LOCATEANYTHING_TIMEOUT: LocateAnything 单次请求超时。LOCATEANYTHING_MAX_TOKENS: LocateAnything 输出 token 上限,默认512。LOCATEANYTHING_MAX_IMAGE_MB: 上传给 LocateAnything 前的本地图像文件大小限制。
使用
启动服务器
全局安装后启动 MCP Server:
mcp-vision-local-mcp不安装,直接用 npx 启动:
npx -y -p @moziaverse/omni-cli mcp-vision-local-mcp本地开发启动:
npm start服务器将以 stdio 模式启动,等待 MCP 客户端连接。日志会输出到 stderr,stdout 保留给 MCP 协议。
CLI 使用
CLI 与 MCP 工具共用同一套核心实现,适合长视频任务、离线脚本、断点重跑和把结果写入文件。
查看命令帮助:
omni-cli --help
omni-cli video segment --help
omni-cli locate image --help# 图像分析,对应 MCP 工具 analyze_image
omni-cli image analyze \
--image /path/to/image.jpg \
--prompt "请描述画面内容" \
--output 图像分析结果.json
# LocateAnything 图片定位,对应 MCP 工具 locate_image
omni-cli locate image \
--image /path/to/image.jpg \
--targets person \
--quality high \
--output-dir 人物定位 \
--output 人物定位结果.json
# 单个视频片段,对应 MCP 工具 analyze_video_segment
omni-cli video segment \
--video /path/to/video.mp4 \
--start 0 \
--end 12 \
--fps 1 \
--width 384 \
--timeout-ms 120000 \
--prompt "请描述人物之间的动作关系" \
--output 视频片段分析结果.json
# 多个指定片段,对应 MCP 工具 analyze_video_segments
omni-cli video segments \
--video /path/to/video.mp4 \
--segments '[{"id":"seg1","start_seconds":0,"end_seconds":12},{"id":"seg2","start_seconds":12,"end_seconds":24}]' \
--concurrency 1 \
--prompt "请描述人物之间的动作关系" \
--output 多片段分析结果.json
# 自动扫描视频,对应 MCP 工具 scan_video
omni-cli video scan \
--video /path/to/video.mp4 \
--segment-seconds 12 \
--stride-seconds 12 \
--fps 1 \
--width 384 \
--concurrency 1 \
--prompt "请描述每个片段中人物之间的动作关系" \
--output 视频扫描结果.jsonCLI 输出是与 MCP 语义一致的 JSON envelope:
{
"success": true,
"data": {},
"timestamp": 1780000000000
}长视频建议优先使用 --fps 1 --width 384 --concurrency 1 起步;如果结果稳定,再逐步提高 fps、width 或并发。
CLI 多轮对话
image analyze 和 video segment 支持 --history-file。CLI 会读取历史,把历史图片/视频片段重新带入本轮请求,并把本轮问题、回答、媒体引用追加回同一个 JSON 文件。历史文件只保存媒体路径和文本,不保存图片或视频 base64。
omni-cli image analyze \
--image ./frame.jpg \
--prompt "画面里有几个人?" \
--history-file ./chat-history.json
omni-cli image analyze \
--image ./frame.jpg \
--prompt "左边那个人在做什么?" \
--history-file ./chat-history.json
omni-cli video segment \
--video ./case.mp4 \
--start 10 \
--end 20 \
--fps 1 \
--width 384 \
--prompt "这个片段和上一段是否是同一事件?" \
--history-file ./chat-history.json集成到 MCP 客户端
Claude Code 集成
使用已全局安装的命令:
claude mcp add vision-local \
-- mcp-vision-local-mcp或直接使用 npx:
claude mcp add vision-local \
-- npx -y -p @moziaverse/omni-cli mcp-vision-local-mcp其他 MCP 客户端
推荐使用 npx,不需要提前全局安装:
{
"mcpServers": {
"vision-local": {
"command": "npx",
"args": ["-y", "-p", "@moziaverse/omni-cli", "mcp-vision-local-mcp"],
"env": {
"OMNI_MODEL_API_URL": "http://117.161.30.145:8001/v1/",
"OMNI_MODEL_NAME": "GLM-4.6V-W8A8",
"OMNI_MODEL_API_KEY": "EMPTY",
"LOCATEANYTHING_API_URL": "http://116.136.189.17:8010/v1",
"LOCATEANYTHING_MODEL": "LocateAnything-3B",
"LOCATEANYTHING_API_KEY": "EMPTY"
}
}
}
}本地开发时也可以把 command 改成 node,args 指向本仓库的 build/index.js。
工具使用示例
图像分析示例
{
"tool": "analyze_image",
"parameters": {
"image_source": "/path/to/image.jpg",
"prompt": "这是一张用户旅行日记中的照片。请识别地标并描述周围环境。",
"system_prompt": "你是一个严谨的视觉观察助手,只根据图像内容回答。"
}
}支持的输入源:
- 本地文件路径:
/path/to/image.jpg - 远程 URL:
https://example.com/image.jpg
单片段视频分析示例
{
"tool": "analyze_video_segment",
"parameters": {
"video_source": "/path/to/video.mp4",
"start_seconds": 120,
"end_seconds": 150,
"prompt": "描述视频中发生了什么,识别主要的人物和动作。",
"system_prompt": "你是一个视频证据观察器,只描述可见内容和不确定性。",
"fps": 2,
"width": 512
}
}整段视频分析也使用 analyze_video_segment:
{
"tool": "analyze_video_segment",
"parameters": {
"video_source": "/path/to/video.mp4",
"start_seconds": 0,
"end_seconds": -1,
"prompt": "概括整个视频发生了什么。"
}
}批量片段并发分析示例
{
"tool": "analyze_video_segments",
"parameters": {
"video_source": "/path/to/video.mp4",
"segments": [
{"id": "seg_0001", "start_seconds": 0, "end_seconds": 30},
{"id": "seg_0002", "start_seconds": 15, "end_seconds": 45}
],
"prompt": "判断这个片段中是否有可疑行为,并给出 active interval 和不确定点。",
"concurrency": 16,
"segment_timeout_ms": 90000,
"fps": 2,
"width": 512
}
}批量接口支持片段级超时和部分返回:
segment_timeout_ms是单个片段的端到端预算,包含 ffmpeg 切片、编码、omni model 请求和重试等待。- 超时片段会出现在
results中,字段为ok=false、timed_out=true、timeout_ms=<传入值>。 - 其他片段不会因为某一个片段超时而被丢弃;响应会包含
summary.total/ok/failed/timed_out。
全局扫描示例
{
"tool": "scan_video",
"parameters": {
"video_source": "/path/to/video.mp4",
"prompt": "判断每个片段是否存在打架、追逐、摔倒、车辆碰撞、火光烟雾等可疑行为。",
"segment_seconds": 30,
"stride_seconds": 15,
"concurrency": 16,
"segment_timeout_ms": 90000,
"fps": 2,
"width": 512,
"max_segments": 300
}
}system_prompt 是可选字段。未提供时:
- 视频片段工具仅使用调用方传入的
prompt analyze_image使用内置通用图像分析提示词
模型参数如温度、输出 token 数、JSON 格式约束不在工具参数中暴露,建议由服务端模型配置或上游流程控制。
支持的输入源:
- 本地文件路径:
/path/to/video.mp4 - 远程 URL:
https://example.com/video.mp4
LocateAnything 单图检测示例
{
"tool": "locate_image",
"parameters": {
"image_path": "/path/to/frame.jpg",
"targets": ["person"],
"prompt": null,
"quality": "high",
"output_dir": "/tmp/person-detect"
}
}返回中的 boxes 是预处理图片尺寸下的坐标;visualization_path 是框选后的图片路径。
LocateAnything 现在走 OpenAI-compatible v1 调用。MCP 内部默认使用 max_tokens=512、temperature=0.2、top_p=0.9,并从响应中的 locateanything.boxes 和 locateanything.points 读取定位结果。MCP 不再注册 locate 视频工具,需要视频检测时由上层流程抽帧后调用 locate_image。
测试
准备测试文件
# 创建测试目录
mkdir -p test-images test-videos
# 将你的测试文件放入相应目录
# test-images/test.jpg
# test-videos/test.mp4手动测试
启动 MCP Server:
mcp-vision-local-mcp使用 MCP 客户端调用工具进行测试
CLI smoke test:
omni-cli image analyze \
--image /path/to/image.jpg \
--prompt "用一句话描述图片内容"
omni-cli video segment \
--video /path/to/video.mp4 \
--start 0 \
--end 12 \
--prompt "用一句话描述视频内容"项目结构
mcp-vision-local/
├── src/
│ ├── index.ts # 主入口
│ ├── cli.ts # omni-cli 入口
│ ├── tools/
│ │ ├── image-analysis.ts # 图像分析工具
│ │ ├── locateanything.ts # LocateAnything 图片定位工具
│ │ └── video-analysis.ts # 视频片段分析、批量分析和全局扫描工具
│ ├── core/
│ │ ├── api-common.ts # API 通用功能
│ │ ├── chat-service.ts # 聊天服务
│ │ ├── environment.ts # 环境配置
│ │ ├── file-service.ts # 文件服务
│ │ ├── video-metadata.ts # ffprobe 视频元数据读取
│ │ ├── video-segmenter.ts # ffmpeg 切片压缩
│ │ └── cache-service.ts # 片段和 omni model 结果缓存
│ ├── prompts/
│ │ └── index.ts # 提示词
│ ├── types/
│ │ └── index.ts # 类型定义
├── build/ # 编译输出目录
├── package.json
├── tsconfig.json
└── README.md故障排查
常见问题
文件未找到错误
- 检查文件路径是否正确
- 确保文件存在且有读取权限
API 连接失败
- 检查
OMNI_MODEL_API_URL是否正确 - 确保视觉模型服务正在运行
- 检查网络连接
- 检查
文件大小超限
analyze_image默认图像限制为 5MBlocate_image默认图像限制由LOCATEANYTHING_MAX_IMAGE_MB控制- 视频片段工具会先切片压缩;如果处理很慢,优先缩短片段、降低
fps或降低width
超时错误
- 增加
OMNI_MODEL_TIMEOUT值 - 检查视觉模型服务性能
- 增加
调试模式
服务器日志会输出到 stderr,可以使用以下命令查看:
mcp-vision-local-mcp 2> debug.log注意事项
- 视觉模型接口需兼容 OpenAI chat/completions
- 本地部署的视觉模型可以设置
OMNI_MODEL_API_KEY=EMPTY - 长视频建议使用片段化分析或扫描接口,不建议一次性把整段高分辨率视频送入模型
- 服务器使用 stdio 通信,确保 stdout 仅用于 MCP 协议
开发
构建
npm run build监听模式(开发)
# 需要安装 ts-node
npx ts-node src/index.ts维护者发布
npm version patch
npm run build
npm pack --dry-run
npm publish --access public发布后验证:
npm view @moziaverse/omni-cli version
npm install -g @moziaverse/omni-cli
omni-cli --help许可证
MIT
贡献
欢迎提交 Issue 和 Pull Request!
联系方式
如有问题,请提交 Issue 到项目仓库。
灵感来源
感谢 zai-mcp 的启发和灵感。
