关于 venira-mcp
venira-mcp 是面向编码 Agent 的工作区范围 MCP 服务,提供文件操作、代码搜索、Shell、检查点和诊断工具。它按配置限制文件路径并审计调用,另有包含 PR 和 CI/CD 工具的 Expert 模式;Shell 仍以启动进程的操作系统用户权限运行。
主要功能
- 01工作区内文件读取、编辑与搜索
- 02批量读取和代码符号分析
- 03创建与恢复文件检查点
- 04策略控制并审计 Shell 调用
- 05Expert 模式提供 PR 与 CI 工具
- 06可选启用 JavaScript 执行工具
适用场景
- 01让编码 Agent 检查并修改项目文件
- 02批量读取文件并搜索代码符号
- 03创建检查点以恢复文件更改
- 04在 Expert 模式下处理 PR 和 CI 操作
MCP 相关
venira-mcp 为 OpenCode、Claude Desktop 及其他 MCP 客户端提供工作区范围工具。Default 模式不含 CI/CD;Expert 模式增加 PR 和 CI 工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y venira-mcpVENIRA_WORKSPACEAbsolute path of the project folder the server works in. Defaults to the current directory.VENIRA_DATA_DIRFolder for the audit database and encrypted secrets. Defaults to <workspace>/data.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
32收录的工具列表 · 更新于 3 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| depth | integer | 否 | |
| limit | integer | 否 | |
| relative_path | string | 否 | 工作区内的路径(相对路径,或工作区内的绝对路径) |
| include_ignored | integer | 否 | 数字标志:1=启用,0=禁用。 |
详细介绍
venira-mcp
面向编码 Agent(OpenCode、Claude Desktop 及任何 MCP 客户端)的快速、限定于工作区的 MCP 服务。
两种工具模式——Default(32 个编码工具 + shell,不含 CI/CD)· Expert(43 个工具:Default + CI/CD)。设置 VENIRA_ALLOW_JS_EXEC=1 会添加 project_execute_js(33 / 44)。
纯 Node,仅 1 个原生依赖(better-sqlite3),无 GUI,无外部二进制文件。
安全范围。 Venira 是带审计追踪的防护栏,不是沙箱。它以启动它的 OS 用户权限运行。工作区锁限制文件工具可操作的路径(除非设置
VENIRA_UNRESTRICTED=1),但不会限制 shell 命令的行为:命令会按规则分类(允许 / 询问 / 拒绝),且每次调用都会被审计;但恶意提示词仍可能诱导 Agent 运行当前配置允许执行的有害命令(使用off时,每条命令都会运行)。任何以同一 OS 用户身份运行的程序都能读取VENIRA_DATA_DIR中的密钥。对于不可信的工作区,或任何需要真正隔离边界的情况,请在容器或 VM 中运行 Venira。详情见:SECURITY.md。
1. 设置
一行安装(在项目中运行,然后重启客户端):
npx --yes venira-mcp@latest --install auto --workspace .
更喜欢使用 Agent?将此提示词粘贴到 OpenCode/Claude/Cursor:
Set up Venira MCP for this workspace.
1. Detect my MCP client config path.
2. Run: npx --yes venira-mcp@latest --install auto --workspace .
3. Restart the client. Then call project_health to verify.
手动配置(选择你的客户端):
| 客户端 | 配置路径 | 格式 |
|---|---|---|
| VS Code | <workspace>/.vscode/mcp.json | JSONC |
| OpenCode | ~/.config/opencode/opencode.jsonc | JSONC |
| Claude Desktop | claude_desktop_config.json | JSON |
| Cursor | ~/.cursor/mcp.json | JSON |
| Codex | ~/.codex/config.toml | TOML |
都使用相同的 npx 命令。可在 §2 中查看可直接复制的 JSON/TOML。
在此仓库中,.vscode/mcp.json 被 Git 忽略,因为它包含特定于机器的设置(且可能放宽安全标志)。将 .vscode/mcp.example.json 复制到 .vscode/mcp.json,并在本地进行调整。
2. 客户端配置(复制粘贴)
示例使用四个环境变量:工作区、工具集、输出大小和安全策略。对大多数用户而言,只需更改 VENIRA_WORKSPACE,并保留 VENIRA_SECURITY_PROFILE=balanced。
OpenCode / VS Code / Cursor / Claude / Kimi / DeepSeek / Antigravity——使用客户端支持的包装格式:
// OpenCode: "mcp" > "venira" > "environment"
{
"mcp": {
"venira": {
"type": "local",
"command": ["npx", "--yes", "--package=venira-mcp@latest", "venira-mcp"],
"enabled": true,
"environment": {
"VENIRA_WORKSPACE": "/absolute/path/to/project",
"VENIRA_TOOL_MODE": "expert",
"VENIRA_OUTPUT_MODE": "full",
"VENIRA_SECURITY_PROFILE": "balanced"
}
}
}
}
// VS Code: "servers" > "venira" > "env"; ${workspaceFolder} expands automatically.
{
"servers": {
"venira": {
"type": "stdio",
"command": "npx",
"args": ["--yes", "--package=venira-mcp@latest", "venira-mcp"],
"env": {
"VENIRA_WORKSPACE": "${workspaceFolder}",
"VENIRA_TOOL_MODE": "expert",
"VENIRA_OUTPUT_MODE": "full",
"VENIRA_SECURITY_PROFILE": "balanced"
}
}
}
}
// Claude / Cursor and compatible clients: "mcpServers" > "venira" > "env"
{
"mcpServers": {
"venira": {
"command": "npx",
"args": ["--yes", "--package=venira-mcp@latest", "venira-mcp"],
"env": {
"VENIRA_WORKSPACE": "/absolute/path/to/project",
"VENIRA_TOOL_MODE": "expert",
"VENIRA_OUTPUT_MODE": "full",
"VENIRA_SECURITY_PROFILE": "balanced"
}
}
}
}
通用 MCP JSON 示例
对于接受通用 mcpServers JSON 结构的客户端,请使用与你的操作系统相符的示例作为实际起点。将示例路径替换为你机器上的路径;VENIRA_DATA_DIR 为可选项,可指向任何可写目录。如果文件包含本地路径或凭据,请妥善保管。
Windows:
{
"mcpServers": {
"venira": {
"command": "npx",
"args": ["--yes", "--package=venira-mcp@latest", "venira-mcp"],
"env": {
"VENIRA_WORKSPACE": "C:\\Users\\YourName\\Projects\\my-app",
"VENIRA_DATA_DIR": "C:\\Users\\YourName\\AppData\\Local\\venira",
"VENIRA_TOOL_MODE": "expert",
"VENIRA_OUTPUT_MODE": "full",
"VENIRA_SECURITY_PROFILE": "balanced"
}
}
}
}
Linux:
{
"mcpServers": {
"venira": {
"command": "npx",
"args": ["--yes", "--package=venira-mcp@latest", "venira-mcp"],
"env": {
"VENIRA_WORKSPACE": "/home/yourname/projects/my-app",
"VENIRA_DATA_DIR": "/home/yourname/.local/share/venira-mcp",
"VENIRA_TOOL_MODE": "expert",
"VENIRA_OUTPUT_MODE": "full",
"VENIRA_SECURITY_PROFILE": "balanced"
}
}
}
}
mcpServers 是一种常见的客户端配置结构,但有些客户端使用不同的外层键或文件格式。调整示例时,请保留 Venira 命令、参数和环境变量值。运行时返回的审批命令会使用此配置中的有效数据目录,因此用户和 Agent 应复制 data.approval.approve_command,而不是自行构造路径。
Codex(~/.codex/config.toml):
[mcp_servers.venira]
command = "npx"
args = ["--yes", "--package=venira-mcp@latest", "venira-mcp"]
[mcp_servers.venira.env]
VENIRA_WORKSPACE = "C:\\path\\to\\project"
VENIRA_TOOL_MODE = "expert"
VENIRA_OUTPUT_MODE = "full"
VENIRA_SECURITY_PROFILE = "balanced"
安全配置
VENIRA_SECURITY_PROFILE | Shell 策略 | JavaScript 审批 | 用途 |
|---|---|---|---|
strict | strict | 必需 | 只读和工作区内的允许列表操作无需审批 |
balanced (默认) | balanced | 必需 | 推荐的通用设置 |
trusted | permissive | 必需 | 按规则和未分类的命令可运行;硬性拒绝的命令需要审批 |
off | off | 禁用 | 仅限可信环境;会打印警告并审计 Shell 命令 |
VENIRA_SHELL_MODE 和 VENIRA_JS_EXEC_APPROVAL 是高级覆盖项,其优先级高于配置档。VENIRA_ALLOW_JS_EXEC=1 会单独注册 JavaScript 工具;默认情况下仍处于禁用状态。
如果你想在个人计算机上减少提示,请选择
trusted。只有在你明确接受禁用 Shell 检查和逐次调用 JavaScript 审批时,才选择off。所有配置档中,secret_env门控仍保持启用。
高级配置
| 变量 | 默认值 | 适用情况 |
|---|---|---|
VENIRA_SHELL_MODE | 配置档映射 | 只需覆盖 Shell 策略(strict、balanced、permissive 或 off)时 |
VENIRA_JS_EXEC_APPROVAL | 配置档映射 | 可信自动化需要跳过逐次调用的 JS 审批时 |
VENIRA_ALLOW_JS_EXEC | 0 | 需要注册 project_execute_js 时 |
VENIRA_UNRESTRICTED | 0 | 保持启用工作区路径限制;生产环境中不要将其设为 1 |
缓存、Shell、提供方和诊断选项,请参阅 §6 中的完整环境变量参考。
3. 基准测试(每次操作,p50)
测量环境:Windows + Node 24,独立构建,2026-11-01。
| 操作 | p50 | 备注 |
|---|---|---|
缓存的 read_file | 8.0 ms | 热缓存 |
read_batch(8 个文件) | 12.8 ms | 一次调用,8 项 |
get_file_info | 6.2 ms | 已缓存 |
search(字面匹配,*.ts) | 11.5 ms | p95 ≈ 1.3 s(取决于文件数量) |
health(无 DB) | 28.5 ms | |
shell_run + 状态 | ~930 ms | 2 s 等待预算占主要部分 |
| 首次调用 | 113.7 ms | 预热后 |
批处理:一次批量调用读取 8 个文件(16.6 ms),而逐个读取 8 次约需 76 ms——节省往返时间, 让 Agent 循环更快。
Agent 工具路径基准测试:Venira MCP 与 Codex exec_command
测量于 2026-11-07,使用一台 Windows 11 build 26200 计算机(Intel Core i5-1035G1、
8 个逻辑处理器、11.8 GiB RAM、Node v24.20.0)。每项工作负载在每个阶段进行了 20 组配对
采样,调用顺序交替进行。Venira 使用持久 MCP 连接;
每次原生 exec_command 调用都会启动一个新的 PowerShell 进程。缓存未命中采样会清除 Venira 的进程内缓存;热缓存采样则会复用该缓存。操作系统文件系统缓存保持热状态。
| 工作负载 | 阶段 | Venira p50 / p95 | exec_command p50 / p95 | p50 比率 |
|---|---|---|---|---|
| 一次批量读取 8 个文件的首行 | 缓存未命中 | 53.5 / 72 ms | 962 / 1,121 ms | 17.98× |
| 一次批量读取 8 个文件的首行 | 热缓存 | 39 / 60 ms | 1,103.5 / 1,549 ms | 28.29× |
在整个工作区中搜索 VENIRA_WORKSPACE(49 处匹配) | 缓存未命中 | 118.5 / 188 ms | 1,034.5 / 1,507 ms | 8.73× |
在整个工作区中搜索 VENIRA_WORKSPACE(49 处匹配) | 热缓存 | 34.5 / 152 ms | 1,018 / 1,383 ms | 29.51× |
两种工作负载在全部 20 组配对中结果完全一致:8 文件批量读取的规范化文本,以及搜索结果中排序后的文件/行位置。这些是实际 Agent 工具路径的耗时,并非原始文件系统耗时。另一项单独的 100 次采样组件基准测试显示,对于简单的未缓存读取,原生 PowerShell 可能更快;Venira 的最大优势体现在热缓存下的列表/搜索操作,以及避免启动新的 Shell 进程。20 次采样得出的 p95 估算较为粗略,而且这台计算机上的结果不构成普遍的性能保证。
请参阅完整方法和结果以及
原始采样数据。在仓库根目录运行 npm run bench:tools -- --runs=100,即可复现组件基准测试。
4. 两种工具模式
两种工具模式决定客户端可以看到哪些工具。通过 VENIRA_TOOL_MODE 环境变量或 venira.config.json 中的 "toolMode" 设置(环境变量优先)。VENIRA_PROFILE=core|full 仍会在此基础上生效。
| 模式 | 工具数 | 包含内容 |
|---|---|---|
default | 32(设置 VENIRA_ALLOW_JS_EXEC=1 时为 33) | 读取/写入/编辑/搜索、代码智能、快照、Shell、project_delete_path、可选的 JS 执行——不包含 CI/CD |
expert | 43(设置 VENIRA_ALLOW_JS_EXEC=1 时为 44) | 包含 default 中的所有工具,外加 project_pr_*、project_ci_* |
project_delete_path 始终可用。在 balanced / strict 模式下,Shell 命令 rm -rf / / ~ 和针对整个 Windows 驱动器的删除会被硬性拒绝;递归/强制删除(Remove-Item -Recurse -Force、rd /s /q、del /f /q)则需要审批。permissive 模式允许普通的 ask 规则和未分类命令在不提示的情况下运行,但硬性拒绝的命令仍需审批;在所有启用策略的模式下,无法检查的命令替换也都需要审批。
5. 工具速查
所有工具均返回标准封装(ok、kind、data、hint、elapsed_ms)。
读取(可批处理,可缓存)
| 工具 | 用途 |
|---|---|
project_list_files | 列出文件/目录,深度为 1–3,数量上限 ≤ 200 |
project_read_file | 按行范围读取文件;可选 ranges[](最多 16 个) |
project_get_file_info | 文件/目录元数据(类型、大小、mtime) |
project_search | 按文件/目录名、内容、正则表达式或符号搜索;hybrid: 1 会为匹配结果添加 source+confidence 标记 |
project_recent_files | 最近修改的文件(优先使用索引,失败时扫描) |
project_read_batch | 一次调用最多执行 8 个只读操作;每个条目接受与对应独立工具相同的参数(search 条目支持 regex、case_sensitive、hybrid 等) |
project_health | 诊断信息:能力、队列、缓存命中率、p50/p95、安全限制提示,以及 server.workspace_switching(enabled、allowed_roots) |
project_read_audit | 读取最近的审计日志行 |
写入(会修改内容,需传入 reason)
| 工具 | 用途 |
|---|---|
project_write_file | 创建/覆盖/追加;expected_sha256 可防止盲目覆盖 |
project_edit_file | 将 old_text 替换为 new_text;edits[](最多 64 个);可选择启用模糊编辑 |
project_edit_batch | 执行多项编辑;首次失败时停止并尝试通过检查点回滚。检查 data.atomic 和 data.rollback_succeeded;如果快照失败/不完整,或仅部分恢复,则更改可能仍然存在。 |
project_create | 创建文件或目录 |
project_delete_path | 删除文件/目录;无法撤销 |
检查点(无需 Git 即可回滚)
project_snapshot — create/list/restore/delete。基于内容寻址并去重;逐文件原子恢复。
代码智能
| 工具 | 用途 |
|---|---|
project_outline_symbol | 解析文件中的符号(函数、类、类型)及其行号 |
project_diff_files | 对两个文件生成统一差异 |
project_symbol_references | 查找指定符号的所有出现位置 |
project_selective_search | 使用 AND/NOT 和模糊评分执行多查询搜索 |
project_dependency_graph | TS/JS/Python/Rust/Go/Java/Kotlin 导入/符号图(JSON/DOT/Mermaid) |
project_change_impact | “如果我编辑这个,会有什么影响?”——有界反向/正向闭包 |
Shell(异步,受策略控制)
| 工具 | 用途 |
|---|---|
project_shell_run | 运行命令;background: 0 会等待并返回最终输出;1 会返回 run_id。shell 可设为:powershell(Windows PowerShell 5.1)、pwsh(PowerShell 7+)、cmd 或 bash;省略时使用 VENIRA_DEFAULT_SHELL,否则 Windows 上使用 cmd,其他系统上使用 $SHELL/bash |
project_shell_status | 轮询正在运行的命令(不包括排队中的命令,也不会记录到审计日志) |
project_shell_cancel | 根据 run_id 终止正在运行的命令 |
project_shell_cancel_session | 终止此会话中的所有 Shell 运行任务 |
在 Windows 上选择 shell。 powershell 会启动 powershell.exe(5.1),它没有 && / ` |
Git 提供商:PR/CI(GitHub、GitLab、Bitbucket)
project_pr_create/comment/merge/list/close/reopen、project_ci_status/trigger/logs/wait、project_ci_control(取消 / 重试失败项;Bitbucket 仅支持取消)——各提供商使用相同的工具参数;令牌来自 project_secret 或环境变量。
CI 读取操作有上限,且不会隐瞒达到上限的情况:
- 分页 — 状态 / 作业 / 检查运行 / 步骤列表会根据提供商的下一页链接继续读取(GitHub/GitLab 使用
Link标头,Bitbucket 使用响应正文中的next),最多读取 5 页 / 200 项;请求会限定在已配置的 API 源站内,且不会重复获取同一页面。达到上限或提供商报告的总数后停止遍历时,结果会说明这一点(truncated/partial),不会把不完整列表报告为完整列表。 - 结果判定 — Bitbucket 已结束的流水线 / 步骤会根据
state.result读取(而不只是COMPLETED),因此失败的运行不会显示为绿色。 - 日志 — 优先读取失败的步骤 / 作业;归档文件和条目均设有字节数上限(参见
VENIRA_GIT_LOG_*),并且声明大小超过上限的日志会在下载前被拒绝。 project_ci_wait— 执行一次有界长轮询(不循环轮询)。返回summary(一行摘要)、next_step(wait_again·merge_or_continue·fix_failing_step_then_push·read_logs·inspect_status)、failing_jobs(最多 5 项),以及在失败时返回首个失败作业的failure_tail(GitHub/GitLab 使用数字 ID,Bitbucket 使用 UUID 步骤 ID)。
密钥(静态加密)
project_secret — 按名称存储 / 检查 / 移除凭据;使用 AES-256-GCM;包含轮换元数据;拒绝已过期的密钥。
project_github_connect — GitHub Device Flow,令牌存储在保险库中。
诊断与规划
project_explain_error — 将错误转换为原因和后续工具调用(规则表,不使用模型)。
project_plan_read_batch — 为任务规划要读取的文件,并返回可直接使用的 project_read_batch 调用。
JS 执行
project_execute_js — 运行同步 JS(需选择启用 VENIRA_ALLOW_JS_EXEC=1);默认情况下每次调用都需要人工批准。
6. 环境变量(主要变量)
完整参考:源代码读取 90 多个不同的 VENIRA_* 名称;此表列出有文档说明的变量。其余内容请参阅源代码或运行 npx venira-mcp --help。
| 变量 | 默认值 | 功能说明 |
|---|---|---|
VENIRA_WORKSPACE | process.cwd() | 工作区根目录;所有路径均相对于此目录解析 |
VENIRA_TOOL_MODE | default | default(32 个工具)或 expert(43 个工具);设置 VENIRA_ALLOW_JS_EXEC=1 时增加 1 个 |
VENIRA_OUTPUT_MODE | full | full 或 compact(对超过 8 KiB 的负载进行摘要/截断;通用负载使用 preview_text) |
VENIRA_PROFILE | full | full 或 core(禁用依赖关系图/变更影响分析) |
VENIRA_UNRESTRICTED | "0" | "1" 会禁用工作区锁定(绝不可用于生产环境) |
VENIRA_SECURITY_PROFILE | balanced | 选择 shell 策略和 JS 审批默认设置:strict、balanced、trusted 或 off |
VENIRA_SHELL_MODE | 配置文件映射 | shell 策略的高级覆盖选项:strict、balanced、permissive 或 off |
VENIRA_SHELL_EXIT_EARLY | "1" | "1" 表示轮询器在确定退出代码后立即返回 |
VENIRA_SHELL_TIMEOUT_POLICY | "soft" | "soft" 在超时时发出警告 · "hard" 终止进程树 |
VENIRA_SHELL_ENV_PASS_ALL | "0" | "1" 将主机的完整环境变量传递给 shell(供需要这些变量的构建工具使用) |
VENIRA_DEFAULT_SHELL | Windows 上为 cmd,其他系统上为 $SHELL / bash | 调用未指定 shell 时使用的 shell:powershell(5.1)、pwsh(7+)、cmd、bash |
VENIRA_ALLOW_JS_EXEC | "0" | "1" 注册 project_execute_js |
VENIRA_JS_EXEC_APPROVAL | 配置文件映射 | JavaScript 调用级审批的高级覆盖选项 |
VENIRA_USE_RIPGREP | "1" | "1" 表示已安装 ripgrep 时使用它(在大型代码仓库中更快) |
VENIRA_CACHE_ALL | "1" | "1" 启用 TTL 缓存 · "0" 始终获取最新数据(速度较慢) |
VENIRA_EDIT_FUZZY | "0" | "1" 为 old_text 启用模糊匹配回退 |
VENIRA_DATA_DIR | 每用户的 OS 路径 | 审计数据库和加密密钥的存放位置 |
VENIRA_SNAPSHOT_ROOT | <per-user data dir>/snapshots | 所有项目和客户端共用的检查点根目录;每个工作区各自使用一个子文件夹(绝对路径) |
VENIRA_SNAPSHOT_DIR | 未设置 | 单个项目专用的精确检查点存储目录,不设子文件夹;优先级高于 VENIRA_SNAPSHOT_ROOT(绝对路径) |
VENIRA_SNAPSHOT_KEEP | 20 | 每个项目保留的检查点数量(创建时清理最旧的检查点) |
VENIRA_SNAPSHOT_MIRROR_DIR | 未设置 | 可选的追加写入副本,位于此已存在文件夹中,保存检查点存储内容(OneDrive/Dropbox、NAS 共享、USB 驱动器、rclone 挂载);绝对路径,必须位于存储目录和工作区之外 |
VENIRA_SNAPSHOT_MIRROR_TIMEOUT_MS | create 后为 20000,action=mirror 时为 100000 | 单次镜像运行的时间预算;会在文件之间停止(partial),下次运行时继续 |
VENIRA_DISABLE_TOOLS | 未设置 | 以逗号分隔的工具名称,这些工具将从 tools/list 中隐藏 |
VENIRA_GIT_PROVIDER | 自动推断 | github / gitlab / bitbucket |
VENIRA_GIT_TOKEN | 未设置 | 找不到提供商专用密钥时使用的备用令牌 |
VENIRA_GIT_TIMEOUT_MS | 60000 | 提供商 JSON 调用的单次请求超时时间(1 000–600 000) |
VENIRA_GIT_RETRIES | 1 | 仅对安全的 GET 读取操作重试(0–3);绝不重放 POST 请求 |
VENIRA_GIT_LOG_TIMEOUT_MS | 90000 | CI 日志下载的超时时间(1 000–900 000) |
VENIRA_GIT_LOG_ZIP_BYTES | 33554432 | CI 日志归档的最大字节数;下载前会拒绝声明大小超出限制的归档 |
VENIRA_GIT_LOG_ENTRY_BYTES / VENIRA_GIT_LOG_TEXT_BYTES | 4194304 / 8388608 | 单个条目及解码后日志文本总量的上限 |
VENIRA_SECRET_ALLOW_REVEAL | "0" | "1" 允许通过 reveal=1 打印密钥明文 |
VENIRA_SHELL_OVERRIDES | 未设置 | 操作员允许列表:ALLOW_GIT_PUSH、ALLOW_ENV_READ |
VENIRA_TRACE | "0" | "1" 将每次工具调用记录到 stderr(仅用于调试) |
VENIRA_PERMISSION_MODE | allow_all | 会话范围打开时传递的权限模式(manual / best_effort / allow_all);显示在 project_health 中 |
VENIRA_SESSION_ID | 自动生成 | 为测试/验证运行设置,以便区分审计记录 |
VENIRA_SHELL_ELICIT | "0" | "1" 通过 MCP 确认对话框向用户询问(客户端必须支持征询) |
VENIRA_SESSION_GRANT_RULES | 内置:cd_outside_workspace | 可通过 --approve --session 批准的额外询问规则 ID(以逗号分隔) |
VENIRA_SHELL_APPROVAL_TTL_MS | 600000(10 分钟) | 内存中 --session 授权的有效期;待处理的审批始终在固定的 5 分钟后过期 |
VENIRA_ALLOW_SELF_INSTALL | "0" | "1" 允许 project_install_self 写入其他客户端的配置文件 |
VENIRA_SHELL_POLICY_FILE | 未设置 | JSON shell 策略文件的路径(allow/ask/deny 规则);绝不会自动从工作区读取 |
VENIRA_TOOL_POLICY_JSON / VENIRA_TOOL_POLICY_FILE | 未设置 | 每个工具的策略规则,可使用内联 JSON 或文件(参见 lib/tool-policy.ts) |
7. 安全模型
默认采取保守策略:
- 工作区锁定:所有路径均在
VENIRA_WORKSPACE内验证;拒绝通过../越界(path_escape)。 - 安全配置(
VENIRA_SECURITY_PROFILE,默认值为balanced):同时设置 Shell 策略和每次调用的 JS 审批。VENIRA_SHELL_MODE和VENIRA_JS_EXEC_APPROVAL可分别覆盖其中一项设置。每条project_shell_run命令都会被归类为allow、ask或deny。balanced(默认):硬拒绝规则会阻止命令;询问规则需要审批;常规开发工作区命令可运行;未归类的命令需要审批。strict:与balanced类似,但只有只读且位于工作区内的允许列表命令无需审批即可运行。permissive(即trusted配置):普通询问规则和未归类的命令无需提示即可运行;匹配硬拒绝规则时会转为审批请求(ask.deny.<rule>);无法检查的命令替换始终需要审批。off:Shell 策略已禁用——所有命令都会运行,不会询问或拒绝(只有secret_env注入仍需询问)。启动时会显示警告;仅在可信环境中使用。先前的permissive行为(v1.14.4)=off。- 硬拒绝(14 条规则):破坏磁盘、挂载/覆盖文件系统、关机/重启、Fork 炸弹、将下载内容通过管道传给 Shell、权限提升(sudo/doas/runas)、删除文件系统根目录/驱动器家目录(
rm -rf /、rm -rf C:\、Remove-Item -Recurse -Force $HOME等)、chmod 777 /、删除整个 Windows 驱动器及通配符批量删除、编码后的 PowerShell 命令、自行批准(触及批准 CLI 或审批存储)、受保护的凭据/密钥文件。 - 询问(20 条规则):命令替换、在工作区外读写/执行
cd、网络访问、软件包变更、重写 Git 历史记录、容器/虚拟机控制及状态、进程控制和taskkill /f、机密信息转储、动态执行和包装命令、find -delete/-exec、破坏性递归/强制删除(Remove-Item -Recurse -Force、rd /s /q、del /f /q;建议使用project_delete_path)、属性重置、无限写入 NUL、无法解析的文件参数。 - 始终以拒绝规则优先于询问规则。
- 机密信息:静态存储时使用 AES-256-GCM 加密;工具元数据中永不包含机密值;
secret_env需要人工审批;拒绝使用过期机密信息。 - 提供方 DLP:Secretlint 会扫描 PR/CI 请求参数和 HTTP 负载;检测到的凭据会在发送前被拦截,且不会包含在响应中。
- 审计记录:所有操作(包括失败操作)都会写入 SQLite WAL;可使用
project_read_audit进行事后分析。 - 令牌传输:提供方令牌仅通过
Authorization标头传输;跨源重定向时会丢弃该令牌。
审批——哪些操作需要人工审批,以及如何授予
| 门禁 | 触发条件 | 开关(默认值) |
|---|---|---|
Shell deny | 匹配硬拒绝规则:直接拒绝,无法审批 | VENIRA_SECURITY_PROFILE(balanced;trusted 会询问;off 会禁用 Shell 检查) |
Shell ask | 匹配询问规则,或命令在 balanced/strict 下未归类 | VENIRA_SECURITY_PROFILE(balanced)· 高级覆盖项:VENIRA_SHELL_MODE |
| 机密注入 | 使用 secret_env 调用 project_shell_run | 所有模式下始终询问 |
project_execute_js | 每次调用 | VENIRA_ALLOW_JS_EXEC(0:不注册该工具)· 配置的 JS 门禁(strict/balanced/trusted:开启;off:关闭)· 高级覆盖项:VENIRA_JS_EXEC_APPROVAL |
| 机密明文 | project_secret 且 reveal=1 | VENIRA_SECRET_ALLOW_REVEAL(0) |
| 自行安装 | project_install_self 写入另一个客户端的配置 | VENIRA_ALLOW_SELF_INSTALL(0) |
| 指定的 Shell 覆盖项 | ALLOW_GIT_PUSH/ALLOW_ENV_READ | VENIRA_SHELL_OVERRIDES(未设置),且调用时需提供 override 和 reason |
ALLOW_GIT_PUSH 仅涵盖向远程 名称 和普通引用执行的一条 git push 命令,且只能带发布标志(-u、--follow-tags、--tags、--atomic、--dry-run 等)。它不涵盖暂存、提交或链式命令;请在正常策略下分别运行这些操作,以便操作人员在发布前检查仓库变更。强制推送(-f、+ref、--force-with-lease)、删除(:ref、--delete)、--mirror、--prune、--no-verify、将 URL 用作远程地址、管道、重定向和替换都会回退到正常判定(询问/拒绝)。 |
授予 shell 或 JS 批准:
- 调用失败并返回
[approval_required],同时返回data.approval_id(有效期为 5 分钟)、命令或代码、规则和原因。Shell 和 JS 共用一个负载data.approval:{ approval_id, gate, rule, reason, subject_preview, expires_at, approve_command, retry_with: { tool, arguments } }。 - 有人将
data.approval.approve_command原样复制到交互式 PowerShell 终端(返回的命令包含服务器数据目录,可在 Windows PowerShell 和 PowerShell 7 中运行),检查请求并回答y。CLI 在没有 TTY 时会拒绝。--yes会跳过提示。--session会将授权扩展到同一命令组,直到其过期,但仅适用于VENIRA_SESSION_GRANT_RULES中的规则(内置规则:cd_outside_workspace)。 - Agent 使用
approval_id重试相同调用。授权带有 HMAC 签名,与会话关联,并绑定到精确的命令/shell/cwd/secret_env/规则(JS 则绑定到代码/argv),且只能使用一次。同一 ID 的并发重试无法同时运行:授权通过原子文件声明来消耗,因此恰有一次重试成功。
**TTL 行为:**待处理请求(approval_id)的有效期固定为 5 分钟,重试无法恢复过期请求。--session 授权默认持续 10 分钟(VENIRA_SHELL_APPROVAL_TTL_MS),且仅存在于当前服务器进程中;重启服务器会清除该授权。
Agent 辅助工具:
project_shell_run设置dry_run: 1时,会返回层级、规则以及would_run/requires_approval,但不会运行任何内容或创建授权,因此 Agent 可以提前知道哪些命令会要求批准。- 在
project_shell_run/project_execute_js中设置approval_wait_ms(最长 45000),可在等待人工批准期间保持调用打开;如果及时收到授权,命令会在同一次调用中运行,否则会返回常规的[approval_required](待处理的approval_id仍然有效)。请将其设为低于客户端的请求超时时间。 project_health会报告approvals(模式、JS 门控、引导交互、会话规则、TTL、最长等待时间)、共享的posture报告(level、稳定的发现 ID,如workspace.unrestricted、profile.off、combo.unrestricted_open_shell、js.exec_without_approval)以及扁平的warnings列表。Posture 发现仅为警告;无效值已在启动时以默认拒绝方式处理。doctor会显示相同的报告。
替代方案(默认关闭,仅适用于 project_shell_run):VENIRA_SHELL_ELICIT=1 会在支持引导交互的 MCP 客户端中显示确认对话框;接受后会自动记录授权。
v1.15 中已移除:approval_token 和 VENIRA_SHELL_AUTO_APPROVE_TOKEN。现在传入 approval_token 会返回 [approval_invalid],并提示改用 approval_id;设置该环境变量只会记录警告并被忽略。
批准是一道防护措施,并非沙箱:以相同 OS 用户身份运行的进程可以读取批准密钥。
快照存储(检查点)
检查点存储在所有工作区之外,位于一个供每位用户共用的文件夹中,因此每个打开同一项目的 MCP 客户端都能看到相同的历史记录:
%LOCALAPPDATA%\venira\snapshots\ (Linux: ~/.local/share/venira/snapshots, macOS: ~/Library/Application Support/venira/snapshots)
my-app\ project.json index\ blobs\
my-app-6cb89aac\ a second workspace that is also called "my-app"
- 文件夹名称 = 工作区文件夹名称。第一个占用某名称的工作区会保留该名称(记录在
project.json中);其他同名工作区会获得-<hash8>后缀。同一工作区始终映射到同一个文件夹,不受路径大小写或 8.3/符号链接写法影响。 - 使用
VENIRA_SNAPSHOT_ROOT(共享根目录)或VENIRA_SNAPSHOT_DIR(确切文件夹,单个项目)进行覆盖。两者都必须是绝对路径;相对路径会导致[config_invalid]。 - 文件工具(读取、写入、编辑、搜索、删除)会拒绝对快照根目录或确切目录下的任何内容进行操作,方式与拒绝操作数据目录相同。只有
project_snapshot会访问此存储。 - 保留策略按项目设置(
VENIRA_SNAPSHOT_KEEP),因此一个繁忙的项目不会挤掉其他项目的检查点。 - Shell 命令也会受到保护:在
balanced/strict模式下,任何位于快照存储内的读取、写入或删除操作数都会被直接拒绝(deny.protected_file_access);在permissive模式下则需要审批。off会完全停用 Shell 策略,因此请同时将重要检查点备份到其他位置。 - 无法读取的检查点会被报告,不会被静默丢弃。
project_snapshot action=list会添加unreadable[](snapshot_version_unsupported= 由更新版本的 venira-mcp 写入,snapshot_corrupt= 索引文件损坏)和一条提示。只要有任何索引无法读取,就会暂停 Blob 清理(删除时显示gc_skipped: "unreadable_manifests"),因为该索引仍拥有此版本无法枚举的 Blob。第一种情况请升级 venira-mcp;第二种情况请自行删除损坏的index\<id>.json.gz(出于设计原因,Agent 的 Shell 访问会被拒绝),之后清理会恢复。 - 清单包含一个
version。读取旧版布局时会在内存中升级(lib/snapshot-store.ts中的MIGRATIONS);磁盘上的文件不会被重写。
备份存储
此存储由普通文件组成:不可变的内容寻址文件 blobs\<ab>\<sha256>、通过先写入再重命名方式写入 index\ 的 gzip 清单,以及记录所属工作区的 project.json。备份就是复制文件夹;恢复就是将其复制回原位置(检查点只会恢复到其清单中记录的工作区)。
- 请在 Agent 之外自行执行复制操作:Shell 策略会拒绝 Agent 命令访问此存储。
- 复制共享根目录(
VENIRA_SNAPSHOT_ROOT)以覆盖所有项目,或只复制单个项目文件夹。Windows:robocopy "%LOCALAPPDATA%\venira\snapshots" "D:\backup\venira-snapshots" /E;Linux/macOS:rsync -a ~/.local/share/venira/snapshots/ /mnt/backup/venira-snapshots/(macOS:使用上文的Application Support路径)。 - 请在没有 Agent 创建或删除检查点时进行复制。如果分两轮复制,请先复制
index\,再复制blobs\:Blob 总是在引用它的清单写入之前写入,因此此顺序不会遗漏清单所需的 Blob,而反过来则可能会。没有清单的 Blob 只是无害的残留文件。 - 恢复备份后,
project_snapshot action=list应显示预期数量,且不应有unreadable条目。
镜像存储(可选)
将 VENIRA_SNAPSHOT_MIRROR_DIR 设置为一个已存在的绝对路径,venira 就会在那里保留第二份副本,无需云 SDK、凭据或自带网络代码(可将其指向 OneDrive/Dropbox 文件夹、NAS 共享、USB 驱动器或 rclone 挂载点,再让相应工具传输数据)。
- 与存储区的布局相同(
<mirror>\<project>\project.json、index\、blobs\),因此恢复时只需将文件夹复制回存储区位置;不存在单独的格式。 - 每次
project_snapshot action=create后,结果都会包含mirror(status、copied_blobs、copied_indexes、bytes、failed[]、error)。此操作尽力而为:镜像问题不会改变检查点本身的状态。project_snapshot action=mirror可按需运行相同的同步;添加verify=1可重新哈希镜像中已有的每个 blob,并重新复制校验失败的文件。 - 先复制 blob,再复制索引,最后复制
project.json,因此镜像不会保存缺少 blob 的检查点。每次复制都会经过验证(blob 的 sha256 必须与其文件名相符;索引字节必须与源文件相同),验证通过后才会使用最终文件名。损坏的本地 blob 只会影响使用它的检查点。 - 仅追加:venira 不会删除镜像中的任何内容。在本地被清理(
VENIRA_SNAPSHOT_KEEP)或删除的检查点仍会保留在镜像中,直到你手动移除,因此请预期镜像会不断增大;唯一的覆盖情况是verify=1替换与源文件不再匹配的文件。 - 有时间限制:运行会在时间预算耗尽时于文件之间停止,并报告
partial/timed_out;再次运行即可继续(只复制缺失的文件)。首次同步大型存储区可能需要运行几次。 - 拒绝处理(
[config_invalid]):相对路径、不存在的文件夹(venira 不会创建镜像根目录,因此未挂载的驱动器不会被悄悄替换为本地文件夹),以及与本地存储区相同、包含本地存储区、位于本地存储区内或位于工作区内的文件夹。已归属于其他工作区的镜像文件夹会报错[mirror_conflict]。 - 镜像文件夹与存储区一样,是受保护的根目录:文件工具会拒绝访问,读取、写入或删除其中内容的 shell 命令也会被禁止。
- 如果存储区丢失,需要恢复时:先停止运行 venira,再将
<mirror>\<project>复制回存储区位置(例如%LOCALAPPDATA%\venira\snapshots\<project>),然后运行project_snapshot action=list。无法读取的本地索引不会被镜像(会计入skipped_unreadable)。
本功能无法防范的威胁:恶意提示词仍可能指示 Agent 运行破坏性命令。对于不可信的工作区,请使用容器/虚拟机;Docker、WSL 2 和 Windows Sandbox 的配置方法(包括挂载、网络控制及其限制)请参见 ISOLATION.md。
8. 信封与错误代码
成功:
{ "ok": true, "status": "completed", "kind": "file_read", "data": { … }, "hint": "Next chunk: …", "elapsed_ms": 2.57 }
失败:
{ "ok": false, "status": "failed", "error": { "code": "not_found", "message": "…", "retryable": false }, "hint": "Check with project_list_files first", "next_actions": [{ "tool": "project_list_files", "arguments": { "relative_path": "." } }] }
ok 描述工具操作的结果。对于 project_shell_run,即使命令已运行但退出代码非零,ok: true 仍然表示工具操作成功;command_status: "failed" 和 hint 会报告命令的执行结果。运行中或已取消的命令会报告 command_status: "running" 或 "cancelled"。如果批量读取中有项目失败,顶层会报告 ok: false、status: "partial" 和 error.code: "batch_partial_failure";请检查 data.responses 中的各项结果。
在 compact 模式下,缩短后的载荷会设置 trimmed: true 和 truncated: true;summary 会说明省略的内容。对于其他方式无法处理的大型载荷,data.preview_text 会包含有长度限制的 JSON 文本预览,summary 会报告原始大小和结构。大型错误消息或附加的错误数据也会明确标记为已缩短。需要完整载荷时,请使用 full。
常见代码:not_found、invalid_request、old_text_not_found、old_text_ambiguous、stale_content、path_escape、resource_limit、sensitive_result、unsupported、internal。
9. Agent 指令(粘贴到 AGENTS.md / CLAUDE.md)
Venira MCP rules:
1. Unfamiliar task: call project_plan_read_batch first, then run steps[0].
2. Read with project_read_batch (up to 8 items). Never re-read a file a tool already returned.
3. Prefer project_edit_file / project_edit_batch over project_write_file; pass `reason` on every mutation.
4. Snapshot before multi-file or destructive changes.
5. Short commands: project_shell_run with background: 0. Long jobs: background: 1, then poll project_shell_status.
6. Do not call project_execute_js unless the user asked for JS; it needs per-call approval.
7. On failure, follow the envelope's hint. Treat ok:false + retryable:false as final.
8. Report only what the tool returned.
9. On [approval_required]: stop, tell the user the approval_id and approve_command, do not loop or approve it yourself; retry once with data.approval.retry_with after they confirm. Use dry_run: 1 to preview a command's tier.
10. 开发
npm run build # tsc → dist/ (verify launches dist/server.js, so rebuild before verifying)
npm run smoke # in-process sanity check
npm run doctor # 15 preflight checks
npm run verify # 518 behavioural + security checks
npm run coverage:shell # V8 coverage for lib/shell-*.ts (report only, no thresholds)
npm run bench:mcp # end-to-end numbers
添加工具:
- 在
tools/project.ts→registerProjectTools中注册,并使用config()辅助函数。 - 只读操作:通过
executeCached路由;变更操作:添加到MUTATING集合。 - 响应封装:使用
lib/output.ts中的buildEnvelope/errorEnvelope。 - 在
scripts/verify/下对应的分区模块中添加检查(scripts/verify.ts仅负责协调);更新server.tsINSTRUCTIONS 中的决策树。 - 运行
npm run build && npm run verify && npm run bench:mcp,并将结果粘贴到 PR 中。
11. 故障排除
| 症状 | 解决方法 |
|---|---|
路径看起来正常,却出现 not_found | 运行 npm run doctor;确认 VENIRA_WORKSPACE 指向的是你预期的位置 |
path_escape | 路径解析到了工作区之外;请使用相对于工作区的路径 |
| Shell 命令迟迟未完成 | 使用 project_shell_status 并设置 wait_seconds: 30;检查 project_health → shells.active |
better-sqlite3 构建失败 | 平台较特殊;安装构建工具后运行 npm rebuild better-sqlite3,或使用 Docker 镜像 |
| SQLite 绑定不可用 | 服务仍会启动。在默认的尽力而为模式下,将跳过审计写入;设置 VENIRA_AUDIT_STRICT=1 可在操作无法记录时使其失败。安装或重新构建 better-sqlite3 可恢复审计跟踪。 |
无法打开 venira.db | 另一个进程锁定了 WAL;请确保只有一个服务向同一数据目录写入 |
| 所有操作都很慢 | 检查 project_health → queue.depth 和各操作的 p95 |
许可证
根据 GNU Affero 通用公共许可证 v3.0(AGPLv3) 授权,详见 LICENSE。
开发者、个人用户和开源项目可免费使用。将 Venira 嵌入专有闭源服务或商业 Agent 平台,需要获得作者的商业许可证。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。