Doramagic 项目包 · 项目说明书
mova-flat-runner 项目
生成时间:2026-05-14 14:22:49 UTC
项目介绍
mova-flat-runner(npm包名:@leryk1981/mova-flat-runner)是一个基于 Model Context Protocol(MCP)的服务器实现,专注于治理型 AI 工作流程的编排与执行。该项目为 Claude Desktop、Cursor 等 AI 助手提供原生 MCP 连接能力,支持发票 OCR、AML(反洗钱)分类、信用审查等业务流...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
mova-flat-runner(npm包名:@leryk1981/mova-flat-runner)是一个基于 Model Context Protocol(MCP)的服务器实现,专注于治理型 AI 工作流程的编排与执行。该项目为 Claude Desktop、Cursor 等 AI 助手提供原生 MCP 连接能力,支持发票 OCR、AML(反洗钱)分类、信用审查等业务流程,并内置人工审批门(Human Approval Gates)和完整的审计跟踪机制。
| 属性 | 值 |
|---|---|
| 当前版本 | 3.3.4 |
| MCP 名称 | io.github.mova-compact/mova-flat-runner |
| 二进制命令 | mova-mcp |
| 执行入口 | dist/index.js |
| 许可证 | MIT-0 |
资料来源:package.json:3-6
核心能力
mova-flat-runner 的设计目标是弥合 AI 助手与企业级业务流程之间的 gap。它允许 AI 通过自然语言调用受治理的合约流程,同时保证所有操作可审计、可追溯。
主要功能矩阵
| 功能类别 | 具体能力 |
|---|---|
| 合同执行 | 内置合约注册(mova_contract)、运行(mova_run)、状态追踪(run_status) |
| 业务工具 | mova_health 健康检查、mova_registry 服务发现、mova_query 状态/审计查询 |
| 决策支持 | mova_decide 决策引擎、mova_connector 外部系统连接 |
| 人工审批 | HUMAN_GATE 审批门机制,支持 approve/reject 操作 |
| 本地运行 | local_seam 模式支持本地沙箱执行,不依赖远程 API |
资料来源:README.md:50-58
系统架构
项目目录结构
mova-flat-runner/
├── cmd/ # 应用入口点
│ └── publisher/ # 服务发布工具
├── data/ # 种子数据
├── deploy/ # Pulumi 部署配置
├── docs/ # 文档
├── internal/ # 私有应用代码
│ ├── api/ # HTTP 处理器和路由
│ ├── auth/ # 认证(GitHub OAuth、JWT、命名空间阻断)
│ ├── config/ # 配置管理
│ ├── database/ # 数据持久化(PostgreSQL)
│ ├── service/ # 业务逻辑
│ ├── telemetry/ # 指标和监控
│ └── validators/ # 输入验证
├── pkg/ # 公开包
└── src/ # TypeScript 源码
├── index.ts # MCP 工具入口
├── transports/ # 传输层
│ ├── local_seam_bridge.ts # 本地缝合桥接
│ └── remote_api.ts # 远程 API 调用
├── security/ # 安全验证
│ └── step_mode_guard.ts # 执行模式校验
└── package_support.ts # 合约包支持
资料来源:README.md:28-46
MCP 工具执行流程
当 AI 助手通过 MCP 调用工具时,请求首先到达 executeTool 函数,该函数根据工具名称分发到对应的处理逻辑:
graph TD
A[MCP 请求] --> B{工具名称匹配}
B -->|mova_run| C[内置合约运行]
B -->|mova_contract| D[自定义合约操作]
B -->|mova_query| E[状态/审计查询]
B -->|mova_decide| F[决策引擎]
B -->|mova_connector| G[外部连接]
C --> H{执行模式}
H -->|AI_ATOMIC| I[LLM 调用]
H -->|HUMAN_GATE| J[人工审批门]
H -->|DETERMINISTIC| K[本地 JS 执行]
H -->|CONTRACT_CALL| L[合约嵌套调用]
J --> M[gate_approve / gate_reject]资料来源:src/index.ts:120-150
步骤执行模式(Step Execution Modes)
系统定义了四种步骤执行模式,每种模式有严格的字段要求:
| 执行模式 | 必需字段 | 描述 |
|---|---|---|
AI_ATOMIC | model | 通过 LLM 执行的原子操作 |
HUMAN_GATE | decision_options | 需要人工决策的审批门 |
DETERMINISTIC | 无特殊字段 | 本地确定性 JavaScript 执行 |
CONTRACT_CALL | contract_id | 嵌套调用其他合约 |
step_mode_guard 模块负责验证这些模式与字段的一致性:
资料来源:src/security/step_mode_guard.ts:40-70
MCP 工具集详解
可用工具列表
| 工具名称 | 功能描述 |
|---|---|
mova_health | 检查 MOVA API 健康状态 |
mova_registry | 获取可用的合约注册表 |
mova_run | 运行内置或自定义合约 |
mova_query | 查询合约状态、审计信息 |
mova_decide | 调用决策引擎 |
mova_connector | 外部系统连接器 |
mova_contract | 自定义合约的注册/运行/状态管理 |
资料来源:README.md:58
mova_contract 操作子集
mova_contract 工具支持多种操作:
| 操作 | API 端点 | 用途 |
|---|---|---|
register | POST /api/v1/contracts/register | 注册自定义合约 |
run | POST /run/{contract_id} | 运行指定合约 |
run_status | GET /run/{run_id}/status | 查询运行状态 |
step_complete | POST /run/{run_id}/step/{step_id}/complete | 完成步骤执行 |
gate_approve | POST /run/{run_id}/gate/{step_id}/approve | 审批通过 |
gate_reject | POST /run/{run_id}/gate/{step_id}/reject | 审批拒绝 |
资料来源:src/index.ts:180-250
自定义合约桥接机制
mova-flat-runner 实现了自定义合约查询桥接功能,解决了自定义合约在注册/运行后无法被查询的问题。
问题背景
内置合约使用 ctr-* 格式 ID,其查询 API 正常工作;而自定义合约使用 local-*、remote-* 格式 ID,在 /api/v1/contracts/* 命名空间可能缺失。
解决方案架构
graph LR
A[自定义 run] --> B[rememberCustomRun<br/>记录 contract_id -> run_id 映射]
B --> C[CUSTOM_RUN_BRIDGE Map]
D[mova_query 404] --> E{探测 /api/v1/contracts/my}
E -->|找到记录| F[返回 bridged status]
E -->|未找到| G[返回诚实审计不可用]该机制包含:
- 内存桥接映射:
CUSTOM_RUN_BRIDGE: Map<contract_id, {run_id, updated_at, source_url?}> - 探测逻辑:
getMyContractRecord函数查询/api/v1/contracts/my获取合约元数据 - 诚实响应:当无法获取审计时,返回明确的
AUDIT_UNAVAILABLE而非伪造成功
环境配置
必需环境变量
| 变量名 | 描述 | 示例值 |
|---|---|---|
MOVA_API_URL | MOVA API 端点 | https://api.mova-lab.eu |
MOVA_API_KEY | API 认证密钥 | __SET_MOVA_API_KEY__ |
LLM_KEY | LLM 提供商密钥 | __SET_LLM_KEY__ |
LLM_MODEL | 使用的模型 | openai/gpt-4o-mini |
资料来源:README.md:36-42
可选本地 HTTP 模式变量
| 变量名 | 描述 | 默认值 |
|---|---|---|
MOVA_API_TIMEOUT_MS | API 超时(毫秒) | 30000 |
MOVA_HTTP_PORT | 本地 HTTP 端口 | 3796 |
MOVA_INVOKE_TOKEN | 本地调用令牌 | - |
本地沙箱路径变量
| 变量名 | 用途 |
|---|---|
MOVA_SANDBOX_PACKAGE_PATH | 合约包路径 |
MOVA_SANDBOX_PROJECT_PATH | 项目路径 |
MOVA_SCHEMA_PATH | 自定义 Schema 路径 |
资料来源:dist-test/src/transports/local_seam_bridge.js:1-10
Claude Desktop 集成配置
在 Claude Desktop 的 claude_desktop_config.json 中配置示例:
{
"mcpServers": {
"mova": {
"command": "npx",
"args": ["-y", "@leryk1981/[email protected]"],
"env": {
"MOVA_API_URL": "https://api.mova-lab.eu",
"MOVA_API_KEY": "__SET_MOVA_API_KEY__",
"LLM_KEY": "__SET_LLM_KEY__",
"LLM_MODEL": "openai/gpt-4o-mini"
}
}
}
}
资料来源:README.md:55-67
安全设计
执行模式校验
step_mode_guard 模块验证步骤定义的完整性:
AI_ATOMIC步骤必须声明model字段HUMAN_GATE步骤必须包含decision_options数组CONTRACT_CALL步骤必须包含contract_id字段DETERMINISTIC步骤不应声明model字段
违反这些规则将返回 STEP_MODE_FIELD_MISMATCH 错误:
return flatErr(
ERR.STEP_MODE_FIELD_MISMATCH,
`Step execution_mode does not agree with content fields: ${violations.length} violation(s)...`,
{ violations, http_status_equivalent: 400 }
);
资料来源:src/security/step_mode_guard.ts:50-80
人工门安全约束
HUMAN_GATE 步骤无法通过通用的 step_complete 端点完成,必须通过专用的 gate_approve 或 gate_reject 路径:
// SECURITY (CFV-3): HUMAN_GATE cannot be completed by generic step completion.
const gateGuard = await assertNotHumanGate(config, args.run_id, args.step_id, requestId);
if (gateGuard) return gateGuard;
资料来源:src/index.ts:220-225
构建与部署
快速开始
# 安装依赖并构建
npm install
npm run build
# 本地运行 MCP 服务器
npx -y @leryk1981/[email protected]
Makefile 命令
| 命令 | 用途 |
|---|---|
make check | 运行 lint、单元测试和集成测试 |
make publisher | 构建 MCP 发布工具 |
./bin/mcp-publisher | 发布 MCP 服务器 |
资料来源:README.md:10-25
关键词与定位
该项目被标记为以下关键词,反映其技术定位:
mcp, mcp-server, model-context-protocol, claude, cursor, anthropic,
hitl, human-in-the-loop, audit-trail, invoice-ocr, aml, compliance,
workflow-automation, contract-execution, mova
资料来源:package.json:8-24
总结
mova-flat-runner 是一个功能完整的 MCP 服务器实现,为 AI 助手提供了访问企业级业务流程的桥梁。其核心特点包括:
- 多模式执行:支持 AI 调用、人工审批、确定性执行和合约嵌套四种执行模式
- 完整审计:内置审计跟踪机制,支持 status、audit、audit_compact 三种视图
- 自定义合约支持:通过桥接机制解决自定义合约的可见性问题
- 安全验证:步骤模式校验和 HUMAN_GATE 隔离确保业务流程的完整性
- 灵活集成:支持 Claude Desktop、Cursor、Codex 等主流 AI 工具
资料来源:[package.json:3-6]()
安装与快速开始
mova-flat-runner 是一个基于 Model Context Protocol (MCP) 的运行时工具包,提供 MOVA 智能合约的原生 MCP 连接能力。该项目作为 MCP Server 运行,通过 npx 命令即可快速集成到支持 MCP 协议的 AI 工具中(如 Claude Desktop、Codex 等)。
继续阅读本节完整说明和来源证据。
概述
mova-flat-runner 是一个基于 Model Context Protocol (MCP) 的运行时工具包,提供 MOVA 智能合约的原生 MCP 连接能力。该项目作为 MCP Server 运行,通过 npx 命令即可快速集成到支持 MCP 协议的 AI 工具中(如 Claude Desktop、Codex 等)。
核心特性:
- npm 包名:
@leryk1981/mova-flat-runner,版本3.3.3 - 二进制命令:
mova-mcp - 支持自定义合约注册、执行、查询等完整生命周期管理
- 提供 HTTP 本地模式,可作为独立服务运行
资料来源:README.md:1
来源:https://github.com/mova-compact/mova-flat-runner / 项目说明书
系统架构设计
mova-flat-runner 是一个基于 Model Context Protocol (MCP) 的治理型 AI 工作流服务器,运行版本为 3.3.4。该系统为 Claude Desktop、Cursor 等 AI 助手提供受监管的合同执行能力,支持发票 OCR、AML 筛查、信贷审查等合规场景,并提供人工审批门和完整的审计追踪功能。
继续阅读本节完整说明和来源证据。
概述
mova-flat-runner 是一个基于 Model Context Protocol (MCP) 的治理型 AI 工作流服务器,运行版本为 3.3.4。该系统为 Claude Desktop、Cursor 等 AI 助手提供受监管的合同执行能力,支持发票 OCR、AML 筛查、信贷审查等合规场景,并提供人工审批门和完整的审计追踪功能。
核心设计原则:
- 无状态执行:MCP 工具调用不持有执行上下文,状态由后端 API 管理
- 本地与远程混合:内置合同支持本地执行,自定义合同支持远程执行
- 安全验证:步骤执行模式与字段一致性校验,确保运行时行为可预测
- 桥接机制:自定义合同运行与查询命名空间分离,通过内存映射桥接
资料来源:package.json:3-10
资料来源:[package.json:3-10]()
客户端 API
mova-flat-runner 是一个基于 Model Context Protocol (MCP) 的服务器,为受治理的 AI 工作流提供客户端 API 接口。该项目通过标准化的 MCP 协议实现与 Claude Desktop、Codex 等 AI 客户端的集成,支持发票 OCR、AML 分类、信用审查等业务流程,并提供人工审批门(Human Approval Gat...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
mova-flat-runner 是一个基于 Model Context Protocol (MCP) 的服务器,为受治理的 AI 工作流提供客户端 API 接口。该项目通过标准化的 MCP 协议实现与 Claude Desktop、Codex 等 AI 客户端的集成,支持发票 OCR、AML 分类、信用审查等业务流程,并提供人工审批门(Human Approval Gates)和审计追踪功能。
客户端 API 的核心职责是:
- 提供标准化的工具调用接口(Tools)
- 支持资源发现和读取(Resources)
- 处理配置管理和环境变量
- 管理运行时状态和执行模式验证
资料来源:package.json:1-12
架构概览
系统组件关系
graph TD
A["MCP 客户端<br/>(Claude Desktop / Codex)"] --> B["Mova MCP Server<br/>(mova-mcp)"]
B --> C["Mova API 服务端"]
B --> D["本地沙箱执行"]
subgraph "Mova MCP Server"
E["src/index.ts<br/>工具执行器"] --> F["远程 API 传输"]
E --> G["本地接缝桥接"]
E --> H["安全验证层"]
end
subgraph "配置层"
I["环境变量配置"] --> E
J["MovaConfig 对象"] --> F
end可用工具列表
| 工具名称 | 功能描述 | 执行模式 |
|---|---|---|
mova_health | 健康检查 | 远程 API |
mova_registry | 合约注册表查询 | 远程 API |
mova_run | 执行内置合约 | 远程 API |
mova_query | 查询合约状态/审计 | 远程 API + 本地桥接 |
mova_decide | 决策执行 | 远程 API |
mova_connector | 外部系统连接 | 远程 API |
mova_contract | 自定义合约操作 | 远程 API |
资料来源:README.md:95-103
环境变量配置
客户端 API 依赖以下环境变量进行身份验证和配置:
| 变量名 | 必填 | 默认值 | 说明 |
|---|---|---|---|
MOVA_API_URL | 否 | https://api.mova-lab.eu | API 服务地址 |
MOVA_API_KEY | 是 | - | MOVA API 密钥 |
LLM_KEY | 是 | - | OpenRouter API 密钥 |
LLM_MODEL | 否 | openai/gpt-4o-mini | LLM 模型标识 |
MOVA_API_TIMEOUT_MS | 否 | 30000 | API 超时(毫秒) |
MOVA_HTTP_PORT | 否 | 3796 | 本地 HTTP 模式端口 |
MOVA_INVOKE_TOKEN | 否 | - | 本地调用令牌 |
资料来源:README.md:47-64
MovaConfig 类型定义
interface MovaConfig {
apiUrl: string; // API 基础地址
apiKey: string; // 认证密钥
llmKey: string; // LLM 提供商密钥
llmModel: string; // LLM 模型
timeoutMs: number; // 请求超时
invokeToken?: string; // 本地调用令牌
}
核心工具 API
mova_run - 内置合约执行
执行系统内置的标准合约类型。
参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
contract_type | string | 是 | 合约类型(如 invoice_ocr, aml_triage) |
inputs | object | 是 | 初始输入数据 |
返回格式:
{
"ok": true,
"contract_id": "ctr-xxx",
"run_id": "run-xxx",
"status": "completed|waiting_human|failed",
"analysis": {},
"outputs": {}
}
资料来源:src/index.ts:150-175
mova_query - 状态与审计查询
查询合约运行状态和审计信息。
参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
contract_id | string | 是 | 合约 ID |
view | string | 否 | 查询视图:status/audit/audit_compact |
自定义合约桥接机制:
对于自定义合约(如 local-*, remote-* 前缀),当 API 返回 404 时,系统会:
- 查询
/api/v1/contracts/my获取合约元数据 - 使用内存桥接映射表
CUSTOM_RUN_BRIDGE关联contract_id→run_id - 返回桥接状态响应
// 内存桥接数据结构
CUSTOM_RUN_BRIDGE: Map<contract_id, {
run_id: string,
updated_at: string,
source_url?: string
}>
资料来源:src/index.ts:200-250
mova_contract - 自定义合约操作
| 操作类型 | 说明 |
|---|---|
register | 注册自定义合约 |
run | 运行自定义合约 |
run_status | 查询自定义合约运行状态 |
API 端点映射:
| 操作 | HTTP 方法 | 路径 |
|---|---|---|
| register | POST | /api/v1/contracts/register |
| run | POST | /run/{contract_id} |
| run_status | GET | /run/{run_id}/status |
mova_health - 健康检查
请求:
curl -sS https://api.mova-lab.eu/health
远程 API 传输层
请求处理流程
sequenceDiagram
participant Client as MCP 客户端
participant Server as mova-mcp
participant API as Mova API
Client->>Server: movaRunSteps(contractId, validators)
Server->>API: POST /api/v1/contracts/{contractId}/step
API-->>Server: Step 执行结果
Server->>API: GET /api/v1/contracts/{contractId}/steps/{stepId}/output
API-->>Server: 分析输出
Server->>API: GET /api/v1/contracts/{contractId}/decision
API-->>Server: 决策点信息
Server-->>Client: 完整响应movaRequest 函数
核心 HTTP 请求函数,支持 GET/POST/PUT/DELETE 方法:
export const movaGet = (config, path) => movaRequest(config, "GET", path);
export const movaPost = (config, path, body) => movaRequest(config, "POST", path, body);
export const movaPut = (config, path, body) => movaRequest(config, "PUT", path, body);
export const movaDelete = (config, path) => movaRequest(config, "DELETE", path);
资料来源:dist-test/src/transports/remote_api.js:1-3
步骤执行循环
movaRunStepsRemote 函数按顺序执行三个核心步骤:
| 步骤 | ID | 功能 |
|---|---|---|
| analyze | analyze | 调用 LLM 分析输入数据 |
| verify | verify | 验证分析结果 |
| decide | decide | 生成决策建议 |
async function movaRunStepsRemote(cfg, contractId, validators, initialInputs = {}) {
let analysis = {};
for (const stepId of ["analyze", "verify", "decide"]) {
// 1. 执行步骤
const result = await movaPost(cfg, `/api/v1/contracts/${contractId}/step`, {
envelope: { kind: "env.step.execute_v0", ... }
});
// 2. 获取步骤输出(analyze 步骤)
if (stepId === "analyze") {
const output = await movaGet(cfg, `/api/v1/contracts/${contractId}/steps/analyze/output`);
analysis = { ...output };
}
}
return { ok: true, analysis, ... };
}
资料来源:dist-test/src/transports/remote_api.js:20-45
本地接缝桥接
LocalSeamBridge 接口
当需要在本地沙箱环境执行合约时,使用 LocalSeamBridge:
interface BridgeRequest {
contractRef: string;
packagePath: string;
step: {
id: string;
execution_mode: "AI_ATOMIC" | "HUMAN_GATE" | "DETERMINISTIC" | "CONTRACT_CALL";
};
stepResult?: unknown;
humanDecision?: string;
terminalOutcome?: boolean;
requestedAction?: string;
routeKey?: string;
outputSchemaPath?: string;
taskType?: string;
}
执行模式类型
| 模式 | 说明 | 必需字段 |
|---|---|---|
AI_ATOMIC | LLM 原子执行 | model |
HUMAN_GATE | 人工审批门 | decision_options |
DETERMINISTIC | 本地确定性执行 | - |
CONTRACT_CALL | 调用其他合约 | contract_id |
资料来源:src/transports/local_seam_bridge.ts:1-50
Bridge 响应结构
interface BridgeResponse {
ok: true;
bridge: {
ok: true;
bridge_source: "mova_flat_runner_canonical_bridge";
status: "completed" | "advanced" | "human_gate_required";
contract_ref: string;
package_path: string;
current_step_id: string;
execution_mode: string;
next_phase: { phase: "EXECUTION" | "WAIT_HUMAN" };
verification_payload: {
status: "PASS";
checks: [{ layer: "Invariant", result: "PASS" }];
};
produced_output: unknown;
};
}
安全验证层
Step Mode Guard
验证合约定义的执行模式与实际字段配置的一致性:
interface StepModeViolation {
kind: "ai_atomic_without_model" |
"human_gate_without_decisions" |
"contract_call_without_contract_id" |
"deterministic_with_model";
step_id: string;
execution_mode: string;
message: string;
}
验证规则
| 规则 ID | 条件 | 违规类型 |
|---|---|---|
| SM-001 | AI_ATOMIC 但无 model 字段 | ai_atomic_without_model |
| SM-002 | HUMAN_GATE 但无 decision_options | human_gate_without_decisions |
| SM-003 | CONTRACT_CALL 但无 contract_id | contract_call_without_contract_id |
| SM-004 | DETERMINISTIC 但有 model 字段 | deterministic_with_model |
export function assertStepModesValid(flow: unknown, requestId: string): FlatRunnerResult | null {
const violations = findStepModeViolations(flow);
if (violations.length === 0) return null;
return flatErr(
ERR.STEP_MODE_FIELD_MISMATCH,
`Step execution_mode does not agree with content fields: ${violations.length} violation(s)`,
{ violations, http_status_equivalent: 400 }
);
}
资料来源:src/security/step_mode_guard.ts:40-70
资源 API
可用资源 URI
| URI | 内容 |
|---|---|
mova://registry | 合约注册表 |
mova://schemas/envelopes | 信封格式 Schema |
mova://contracts/{type}/manifest | 特定合约类型的清单 |
资源读取实现
function readResource(uri: string): unknown {
if (uri === "mova://registry") {
return {
schema_version: "1.0",
contracts: Object.values(CONTRACT_MANIFESTS).map(m => ({
contract_type: m.contract_type,
title: m.title,
version: m.version,
execution_mode: m.execution_mode,
manifest_resource: `mova://contracts/${m.contract_type}/manifest`,
})),
};
}
// ...
}
资料来源:src/index.ts:250-280
MCP Server 配置
server.json 元数据
{
"name": "io.github.mova-compact/mova-flat-runner",
"version": "2.0.6",
"description": "Governed AI workflows with human approval gates and audit trails",
"packages": [{
"identifier": "mova-mcp",
"runtimeHint": "node",
"transport": { "type": "stdio" },
"environmentVariables": [...]
}]
}
Claude Desktop 集成示例
{
"mcpServers": {
"mova": {
"command": "npx",
"args": ["-y", "@leryk1981/[email protected]"],
"env": {
"MOVA_API_URL": "https://api.mova-lab.eu",
"MOVA_API_KEY": "__SET_MOVA_API_KEY__",
"LLM_KEY": "__SET_LLM_KEY__",
"LLM_MODEL": "openai/gpt-4o-mini"
}
}
}
}
资料来源:README.md:75-95
错误处理
错误代码
| 代码 | 含义 | HTTP 等价 |
|---|---|---|
UNKNOWN_CONTRACT_TYPE | 未知的合约类型 | 400 |
API_REQUEST_FAILED | API 请求失败 | 502 |
LOCAL_VALIDATION_FAILED | 本地验证失败 | 400 |
STEP_MODE_FIELD_MISMATCH | 执行模式字段不匹配 | 400 |
错误响应格式
function flatErr(
code: string,
message: string,
details?: unknown,
retryable?: boolean,
requestId?: string
): FlatRunnerResult {
return {
ok: false,
error: {
code,
message,
details: details ?? null,
retryable: retryable ?? false,
request_id: requestId ?? shortId(),
timestamp: new Date().toISOString(),
},
};
}
包支持与验证
Package Manifest 验证
src/package_support.ts 提供了 Casper CW 合约包的验证逻辑:
| 验证项 | 说明 |
|---|---|
schema_id | 必须为 package_manifest_casper_v1 |
package_id | 非空字符串 |
flow_ref | 指向有效流程引用 |
semantic_roles | 非空数组,角色对象包含 id/role/authority/maturity |
non_authority_rules | 非空数组 |
function validatePackageManifestShape(value: unknown): string | null {
const allowedKeys = new Set([
"schema_id", "package_id", "version", "global_ref",
"flow_ref", "classification_policy_ref",
"classification_result_set_ref", "runtime_binding_set_ref",
"model_refs", "fixture_refs", "package_invariants"
]);
// 验证逻辑...
}
资料来源:src/package_support.ts:1-80
开发指南
本地运行
# 构建项目
npm run build
# 运行测试
npm run test:build
# 执行冒烟测试
npm run smoke:custom-bridge
# 完整检查(lint + 单元测试 + 集成测试)
make check
发布 MCP Server
# 构建发布工具
make publisher
# 使用发布 CLI
./bin/mcp-publisher --help
资料来源:README.md:1-30, Makefile
资料来源:[package.json:1-12]()
传输层实现
传输层是 MOVA Flat Runner 的核心组件,负责处理本地执行与远程 API 通信的双重职责。该层封装了两种主要的传输模式:
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
1. 概述
传输层是 MOVA Flat Runner 的核心组件,负责处理本地执行与远程 API 通信的双重职责。该层封装了两种主要的传输模式:
- 本地 Seam 桥接:用于本地沙箱环境下的流程执行
- 远程 API 传输:用于与 MOVA 云端服务进行 HTTP 通信
传输层在系统中承担着承上启下的关键角色,向上对接 MCP 协议层,向下管理执行引擎与外部服务的交互。
资料来源:src/transports/local_seam_bridge.ts:1-50
2. 架构总览
2.1 传输层在系统中的位置
graph TD
subgraph "MCP 协议层"
A[MCP Handlers]
end
subgraph "传输层"
B[Local Seam Bridge]
C[Remote API Client]
end
subgraph "执行引擎"
D[Step Executor]
E[Security Guards]
end
subgraph "外部服务"
F[MOVA Cloud API]
G[Local Sandbox]
end
A --> B
A --> C
B --> D
C --> F
D --> E
E --> G2.2 核心组件一览
| 组件 | 文件位置 | 职责 |
|---|---|---|
createInternalBridgeInvoker | local_seam_bridge.ts | 创建本地桥接调用器 |
sanitizePublicShape | local_seam_bridge.ts | 清理输出数据的敏感字段 |
resolveLocalSeamLocator | local_seam_bridge.ts | 解析本地 Seam 定位器 |
movaRequest | remote_api.ts | 底层 HTTP 请求封装 |
movaRunStepsRemote | remote_api.ts | 远程步骤执行 |
资料来源:src/transports/local_seam_bridge.ts:50-80
3. 本地 Seam 桥接
3.1 功能概述
本地 Seam 桥接(Local Seam Bridge)是在本地沙箱环境中执行合约流程的核心机制。它通过 createInternalBridgeInvoker() 工厂函数创建桥接调用器,负责管理执行状态、生成证明引用和处理不同执行模式。
资料来源:src/transports/local_seam_bridge.ts:52-65
3.2 内部桥接调用器
createInternalBridgeInvoker 函数创建一个异步桥接调用器实例,其核心职责包括:
状态管理
| 状态值 | 含义 | 触发条件 |
|---|---|---|
human_gate_required | 需要人工确认 | execution_mode === "HUMAN_GATE" 且 humanDecision == null |
completed | 流程已完成 | terminalOutcome === true |
advanced | 流程进行中 | 其他正常执行情况 |
桥接响应结构
return {
ok: true,
bridge: {
ok: true,
bridge_source: "mova_flat_runner_canonical_bridge",
status,
contract_ref: request.contractRef,
package_path: request.packagePath,
current_step_id: request.step.id,
execution_mode: request.step.execution_mode,
requested_action: request.requestedAction,
route_key: request.routeKey ?? null,
terminal_outcome: request.terminalOutcome ?? null,
gate_required: status === "human_gate_required",
produced_output: producedOutput,
human_decision: request.humanDecision ?? null,
proof_ref: `proof:${suffix}`,
state_ref: `state:${suffix}`,
next_state_ref: `next:${suffix}`,
decision_kind: { kind: "Pass" },
commit_effect: { kind: "Apply" },
next_phase: { phase: status === "human_gate_required" ? "WAIT_HUMAN" : "EXECUTION" },
// ... 其他字段
}
};
资料来源:src/transports/local_seam_bridge.ts:67-95
3.3 执行模式处理
系统支持多种执行模式,每种模式有不同的处理逻辑:
graph TD
A[开始执行] --> B{execution_mode}
B -->|AI_ATOMIC| C[使用 CANONICAL_STRATEGY]
B -->|HUMAN_GATE| D{humanDecision存在?}
B -->|其他模式| E[使用 stepResult]
D -->|否| F[返回 human_gate_required]
D -->|是| G[继续执行]
C --> H[设置 raw_json_present = true]
E --> I[设置 raw_json_present = false]
G --> IAI_ATOMIC 模式特性
| 字段 | 值 |
|---|---|
raw_output_present | true |
parsed_json_present | true |
validated_output_present | true |
produced_output | CANONICAL_STRATEGY |
schema_validation.ok | true |
HUMAN_GATE 模式特性
| 字段 | 值 |
|---|---|
gate_required | true |
next_phase.phase | "WAIT_HUMAN" |
human_decision | 人工决策结果或 null |
资料来源:src/transports/local_seam_bridge.ts:75-90
3.4 公共形状清理
sanitizePublicShape 函数递归检查输出对象,过滤敏感字段:
function sanitizePublicShape(value: unknown): boolean {
// 递归检查数组
if (Array.isArray(value)) {
return value.every((item) => sanitizePublicShape(item));
}
// 基础类型直接返回
if (!value || typeof value !== "object") {
return true;
}
// 检查敏感字段黑名单
for (const [key, child] of Object.entries(value)) {
if (["bridge_anchors", "last_terminal_bridge",
"terminal_commit_count", "_state15_bridge",
"trace", "outputs", "context"].includes(key)) {
return false;
}
if (!sanitizePublicShape(child)) {
return false;
}
}
return true;
}
敏感字段黑名单
| 字段名 | 描述 |
|---|---|
bridge_anchors | 桥接锚点信息 |
last_terminal_bridge | 最终桥接状态 |
terminal_commit_count | 提交计数 |
_state15_bridge | 内部状态桥接 |
trace | 执行追踪数据 |
outputs | 输出数据 |
context | 执行上下文 |
资料来源:src/transports/local_seam_bridge.ts:105-130
3.5 本地定位器解析
resolveLocalSeamLocator 函数解析并验证本地 Seam 环境配置:
async function resolveLocalSeamLocator(initialInputs) {
// 解析 package_path
const packagePath = typeof initialInputs.package_path === "string"
? initialInputs.package_path
: process.env.MOVA_SANDBOX_PACKAGE_PATH
?? "默认路径";
// 解析 project_path
const projectPath = typeof initialInputs.project_path === "string"
? initialInputs.project_path
: process.env.MOVA_SANDBOX_PROJECT_PATH ?? "";
// 解析 state_file
const stateFile = typeof initialInputs.state_file === "string"
? initialInputs.state_file
: path.join(await fs.mkdtemp(path.join(...)), "state.json");
return { packagePath, projectPath, stateFile };
}
环境变量配置
| 变量名 | 默认值 | 用途 |
|---|---|---|
MOVA_SANDBOX_PACKAGE_PATH | 编译时指定路径 | 合约包路径 |
MOVA_SANDBOX_PROJECT_PATH | 空字符串 | 项目路径 |
MOVA_SCHEMA_PATH | 未设置 | 数据模式路径 |
资料来源:src/transports/local_seam_bridge.ts:135-160
4. 远程 API 传输
4.1 功能概述
远程 API 传输模块通过 HTTP 协议与 MOVA 云端服务通信,支持完整的合约生命周期操作。
资料来源:dist-test/src/transports/remote_api.js:1-50
4.2 HTTP 客户端封装
基础请求函数
async function movaRequest(config, method, path, body?) {
const url = `${config.baseUrl}${path}`;
const headers = {
"Content-Type": "application/json",
"Authorization": `Bearer ${config.apiKey}`,
};
const response = await fetch(url, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
}
快捷方法
| 方法 | 用途 | HTTP 动词 |
|---|---|---|
movaGet | 查询数据 | GET |
movaPost | 创建资源 | POST |
movaPut | 更新资源 | PUT |
movaDelete | 删除资源 | DELETE |
export const movaGet = (config, path) => movaRequest(config, "GET", path);
export const movaPost = (config, path, body) => movaRequest(config, "POST", path, body);
export const movaPut = (config, path, body) => movaRequest(config, "PUT", path, body);
export const movaDelete = (config, path) => movaRequest(config, "DELETE", path);
资料来源:dist-test/src/transports/remote_api.js:80-120
4.3 远程步骤执行
movaRunStepsRemote 函数处理远程合约步骤的执行流程:
sequenceDiagram
participant MCP as MCP Handler
participant RemoteAPI as Remote API Client
participant MOVA as MOVA Cloud
MCP->>RemoteAPI: movaRunStepsRemote(contractId)
RemoteAPI->>MOVA: POST /api/v1/contracts/{id}/step (analyze)
MOVA-->>RemoteAPI: { ok: true, status }
RemoteAPI->>MOVA: GET /api/v1/contracts/{id}/steps/analyze/output
MOVA-->>RemoteAPI: analysis data
RemoteAPI->>RemoteAPI: Run validators
RemoteAPI->>MOVA: POST /api/v1/contracts/{id}/step (verify)
MOVA-->>RemoteAPI: { ok: true, status }
RemoteAPI->>MOVA: POST /api/v1/contracts/{id}/step (decide)
MOVA-->>RemoteAPI: { ok: true, status }
alt status === "waiting_human"
RemoteAPI->>MOVA: GET /api/v1/contracts/{id}/decision
MOVA-->>RemoteAPI: decision_point
RemoteAPI-->>MCP: { status: "waiting_human", options }
else status === "completed"
RemoteAPI-->>MCP: { ok: true, status: "completed" }
end执行步骤序列
| 步骤 | API 端点 | 描述 |
|---|---|---|
| 1. analyze | POST /api/v1/contracts/{id}/step | 分析阶段 |
| 2. verify | POST /api/v1/contracts/{id}/step | 验证阶段 |
| 3. decide | POST /api/v1/contracts/{id}/step | 决策阶段 |
资料来源:dist-test/src/transports/remote_api.js:130-180
4.4 输出验证机制
function validateBackendOutput(output) {
if (!output || typeof output.ok !== "boolean") {
return { ok: false, error: "INVALID_OUTPUT_FORMAT" };
}
return { ok: output.ok };
}
验证器注册表
const VALIDATOR_REGISTRY = new Map();
for (const validator of validators) {
const fn = VALIDATOR_REGISTRY.get(validator.validator_id);
if (!fn) {
analysis[`${validator.step_id}_error`] = `VALIDATOR_NOT_ALLOWED: "${validator.validator_id}"`;
continue;
}
try {
const resultValue = fn(validatorContext);
Object.assign(analysis, resultValue.value ?? {});
} catch (error) {
analysis[`${validator.step_id}_error`] = `VALIDATOR_FAILED: ${String(error)}`;
}
}
验证器错误类型
| 错误类型 | 触发条件 |
|---|---|
VALIDATOR_NOT_ALLOWED | 验证器 ID 不在注册表中 |
VALIDATOR_FAILED | 验证器函数执行抛出异常 |
资料来源:dist-test/src/transports/remote_api.js:150-170
5. 执行模式守卫
5.1 步骤模式验证
step_mode_guard.ts 模块负责验证步骤定义的完整性:
graph TD
A[findStepModeViolations] --> B{execution_mode}
B -->|DETERMINISTIC| C{有 model 字段?}
C -->|是| D[违规: deterministic_with_model]
C -->|否| E[通过]
B -->|AI_ATOMIC| F{有 model 字段?}
F -->|否| G[违规: ai_atomic_without_model]
F -->|是| E
B -->|CONTRACT_CALL| H{有 contract_id?}
H -->|否| I[违规: contract_call_without_contract_id]
H -->|是| E
B -->|HUMAN_GATE| J{有 decision_options?}
J -->|否| K[违规: human_gate_without_decisions]
J -->|是| E模式验证规则表
| 执行模式 | 必需字段 | 违规条件 |
|---|---|---|
DETERMINISTIC | 无 | 存在 model 字段 |
AI_ATOMIC | model | 缺少 model 字段 |
CONTRACT_CALL | contract_id | 缺少 contract_id |
HUMAN_GATE | decision_options | 缺少 decision_options 数组 |
资料来源:src/security/step_mode_guard.ts:30-70
5.2 安全守卫断言
export function assertStepModesValid(
flow: unknown,
requestId: string,
): FlatRunnerResult | null {
const violations = findStepModeViolations(flow);
if (violations.length === 0) return null;
return flatErr(
ERR.STEP_MODE_FIELD_MISMATCH,
`Step execution_mode does not agree with content fields: ${violations.length} violation(s)`,
{
violations,
http_status_equivalent: 400
}
);
}
6. 数据模式解析
6.1 模式文件查找
resolveOutputSchema 函数按优先级查找数据模式文件:
async function resolveOutputSchema(schemaRef, flowDir) {
const candidates = [
path.join(flowDir, "_schemas", `${schemaRef}.json`),
path.join(flowDir, "..", "_data-schemas", `${schemaRef}.json`),
path.join(flowDir, "..", "..", "_data-schemas", `${schemaRef}.json`),
...(process.env.MOVA_SCHEMA_PATH
? [path.join(process.env.MOVA_SCHEMA_PATH, `${schemaRef}.json`)]
: []),
];
for (const candidate of candidates) {
try {
const raw = await fs.readFile(candidate, "utf8");
return JSON.parse(raw);
} catch {
// try next candidate
}
}
return null;
}
模式文件查找路径优先级
| 优先级 | 路径模板 |
|---|---|
| 1 | {flowDir}/_schemas/{schemaRef}.json |
| 2 | {flowDir}/../_data-schemas/{schemaRef}.json |
| 3 | {flowDir}/../../_data-schemas/{schemaRef}.json |
| 4 | {MOVA_SCHEMA_PATH}/{schemaRef}.json |
资料来源:src/package_support.ts:30-60
6.2 全局文件验证
validatePackageGlobalShape 函数验证合约包的全局定义结构:
export function validatePackageGlobalShape(value: unknown): string | null {
if (!isObject(value)) return "global file must be a JSON object";
const allowedKeys = new Set([
"schema_id", "global_id", "version", "scope",
"extends", "semantic_roles", "non_authority_rules"
]);
// 验证必需字段
// - global_id: 必须为非空字符串
// - version: 必须为非空字符串
// - scope: 必须为 "contract_package"
// - semantic_roles: 必须为非空数组
return null; // 验证通过
}
必需字段表
| 字段 | 类型 | 约束 |
|---|---|---|
global_id | string | 非空 |
version | string | 非空 |
scope | string | 必须为 "contract_package" |
semantic_roles | array | 非空数组 |
资料来源:src/package_support.ts:65-90
7. 配置与集成
7.1 配置结构
interface MovaConfig {
baseUrl: string; // API 基础地址
apiKey: string; // API 密钥
timeout?: number; // 超时时间(ms)
invokeToken?: string; // 本地调用令牌
}
环境变量映射
| 环境变量 | 配置字段 | 说明 |
|---|---|---|
MOVA_API_URL | baseUrl | API 服务地址 |
MOVA_API_KEY | apiKey | API 密钥 |
MOVA_API_TIMEOUT_MS | timeout | 请求超时 |
MOVA_INVOKE_TOKEN | invokeToken | 本地令牌 |
资料来源:src/index.ts:50-80
7.2 传输层选择逻辑
graph TD
A[开始请求] --> B{配置判断}
B -->|baseUrl === LOCAL_SEAM_BACKEND| C[使用 Local Seam Bridge]
B -->|其他情况| D[使用 Remote API Client]
C --> E[resolveLocalSeamLocator]
C --> F[createInternalBridgeInvoker]
D --> G[movaRequest]
D --> H[validateBackendOutput]export function isLocalSeamConfig(config: MovaConfig): boolean {
return config.baseUrl === LOCAL_SEAM_BACKEND;
}
8. 错误处理
8.1 错误类型定义
| 错误码 | 含义 | HTTP 等效 |
|---|---|---|
UNKNOWN_CONTRACT_TYPE | 合约类型未知 | 400 |
API_REQUEST_FAILED | API 请求失败 | 502 |
STEP_MODE_FIELD_MISMATCH | 步骤模式字段不匹配 | 400 |
AUDIT_UNAVAILABLE | 审计数据不可用 | 424 |
8.2 错误响应格式
function flatErr(code, message, details?, retryable?, requestId?) {
return {
ok: false,
error: {
code,
message,
details: details ?? null,
retryable: retryable ?? false,
request_id: requestId ?? shortId(),
timestamp: new Date().toISOString(),
}
};
}
资料来源:src/index.ts:100-130
9. 总结
传输层实现为 MOVA Flat Runner 提供了灵活的双模通信能力:
- 本地模式:通过
local_seam_bridge.ts实现隔离的沙箱执行环境 - 远程模式:通过
remote_api.ts实现与云端服务的标准 HTTP 通信
两种模式共享相同的接口抽象,通过 isLocalSeamConfig 工厂函数自动选择合适的传输实现,保证了上层调用逻辑的统一性。
资料来源:[src/transports/local_seam_bridge.ts:1-50]()
可用工具列表
mova-flat-runner 是一个基于 Model Context Protocol (MCP) 的服务器实现,用于治理型 AI 工作流程。该项目通过 MCP 协议暴露一组工具(Tools),使 AI 助手(如 Claude Desktop、Cursor)能够与 MOVA 平台进行交互,执行发票 OCR、AML 分类、信用审查等合规工作流程。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
mova-flat-runner 是一个基于 Model Context Protocol (MCP) 的服务器实现,用于治理型 AI 工作流程。该项目通过 MCP 协议暴露一组工具(Tools),使 AI 助手(如 Claude Desktop、Cursor)能够与 MOVA 平台进行交互,执行发票 OCR、AML 分类、信用审查等合规工作流程。
可用工具列表是 MCP 服务器向客户端提供的核心接口,每个工具对应一个独立的业务功能单元,支持合同注册、流程执行、状态查询、人工审批等操作。
MCP 工具集概览
MOVA MCP 服务器提供以下 7 个核心工具:
| 工具名称 | 功能描述 | 执行模式 |
|---|---|---|
mova_health | 健康检查与连接验证 | 同步 |
mova_registry | 合同清单与模板注册 | 同步 |
mova_run | 内置合同类型执行 | 同步/异步 |
mova_query | 合同状态与审计查询 | 同步 |
mova_decide | 决策点处理 | 同步 |
mova_connector | 外部系统连接 | 同步 |
mova_contract | 自定义合同管理 | 同步/异步 |
资料来源:README.md
工具详细说明
mova_health
健康检查工具用于验证 MCP 服务器与后端 MOVA API 的连接状态。
curl -sS https://api.mova-lab.eu/health
该工具返回 JSON 格式的健康状态响应,确认服务可用性。
资料来源:README.md
mova_registry
注册表工具提供可用合同模板的清单查询功能。
资源端点: mova://registry
返回数据结构包含:
| 字段 | 类型 | 说明 |
|---|---|---|
| schema_version | string | 注册表模式版本 |
| contracts | array | 可用合同模板列表 |
每个合同模板包含以下元数据:
| 字段 | 类型 | 说明 |
|---|---|---|
| contract_type | string | 合同类型标识符 |
| title | string | 合同标题 |
| version | string | 版本号 |
| execution_mode | string | 执行模式 |
| manifest_resource | string | 清单资源 URI |
资料来源:src/index.ts
mova_run
内置合同执行工具,用于运行预定义的合同类型。
参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| contract_type | string | 是 | 合同类型(如 complaint) |
| inputs | object | 是 | 初始输入参数 |
执行流程:
graph TD
A[验证 contract_type] --> B{内置合同?}
B -->|是| C[获取 CONTRACT_MANIFESTS]
B -->|否| D[返回错误: 使用 mova_contract]
C --> E[执行 movaRunStepsRemote]
E --> F[状态检查]
F --> G{waiting_human?}
G -->|是| H[返回决策点信息]
G -->|否| I[返回执行结果]内置合同类型通过 CONTRACT_MANIFESTS 注册表管理,支持以下执行模式:
AI_ATOMIC:AI 原子操作,需要 LLM 模型配置DETERMINISTIC:确定性执行,本地 JS 验证CONTRACT_CALL:嵌套合同调用HUMAN_GATE:人工审批门禁
验证规则:
每个执行模式有相应的字段验证要求:
| 执行模式 | 必需字段 | 验证说明 |
|---|---|---|
| AI_ATOMIC | model | 必须声明 LLM 模型 |
| DETERMINISTIC | - | 不应声明 model 字段 |
| CONTRACT_CALL | contract_id | 必须指定目标合同 |
| HUMAN_GATE | decision_options | 必须提供决策选项数组 |
资料来源:src/index.ts、src/security/step_mode_guard.ts
mova_query
合同查询工具用于获取已执行合同的状态和审计信息。
支持视图模式:
| 视图模式 | 功能描述 |
|---|---|
| status | 返回合同执行状态 |
| audit | 返回完整审计记录 |
| audit_compact | 返回紧凑型审计信息 |
特殊处理:自定义合同桥接
当查询自定义合同(ID 格式为 local-* 或 remote-*)返回 404 时,系统会激活自定义查询桥接机制:
graph TD
A[mova_query] --> B{API 404?}
B -->|是| C[探测 /api/v1/contracts/my]
C --> D{自定义合同已知?}
D -->|是| E[返回桥接状态]
D -->|否| F[返回 404]
E --> G[view=status]
E --> H[view=audit_compact]
G --> I[返回 bridged status]
H --> J[返回诚实的不可用信息]桥接状态响应结构:
| 字段 | 说明 |
|---|---|
| ok | 状态码 |
| bridge_mode | 桥接模式标识 (custom_contract_run_namespace_bridge_v1) |
| contract_record | 合同元数据 |
| run_ref | 运行引用 |
| run_status | 运行状态(若可用) |
审计不可用响应:
当后端命名空间缺失时,audit_compact 返回诚实的不可用结构:
{
"ok": false,
"status": 424,
"journal": {
"bridge_unavailable_reason": "..."
}
}
资料来源:tasks/task061.md、src/index.ts
mova_decide
决策处理工具用于在人工审批门禁处进行决策。
参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| run_id | string | 是 | 运行标识符 |
| step_id | string | 是 | 决策点步骤 ID |
| decision | string | 是 | 决策选项 ID |
mova_connector
外部系统连接器工具,用于与第三方系统建立连接。
mova_contract
自定义合同管理工具,提供完整的合同生命周期管理。
支持的操作(action):
| 操作 | 功能 | API 端点 |
|---|---|---|
| register | 注册自定义合同 | POST /api/v1/contracts/register |
| run | 执行自定义合同 | POST /run/{contract_id} |
| run_status | 查询运行状态 | GET /run/{run_id}/status |
| step_complete | 完成步骤执行 | POST /run/{run_id}/step/{step_id}/complete |
| gate_approve | 审批通过 | - |
| gate_reject | 审批拒绝 | - |
run_status 特殊行为:
当获取运行状态时,系统会自动将 contract_id -> run_id 映射存入内存桥接映射表 (CUSTOM_RUN_BRIDGE),以支持后续的查询桥接功能。
安全机制:
step_complete操作在转发前执行HUMAN_GATE守卫检查- 人工审批门禁不能通过通用的
step_complete完成,必须使用专属的gate_approve/gate_reject路径
// SECURITY (CFV-3): HUMAN_GATE cannot be completed by generic step completion.
// Human confirmation requires the dedicated gate path (gate_approve / gate_reject).
资料来源:src/index.ts
本地接缝桥接(Local Seam Bridge)
mova-flat-runner 支持本地接缝模式,允许 MCP 客户端直接调用本地运行的 MOVA 运行时。
请求结构
| 字段 | 类型 | 说明 |
|---|---|---|
| contractRef | string | 合同引用 |
| packagePath | string | 包路径 |
| step | object | 步骤定义 |
| stepResult | unknown | 步骤执行结果 |
| terminalOutcome | string | 终端结果 |
| humanDecision | object | 人工决策 |
响应结构
| 字段 | 类型 | 说明 |
|---|---|---|
| ok | boolean | 执行状态 |
| bridge | object | 桥接元数据 |
| bridge_source | string | 桥接源标识 |
| contract_ref | string | 合同引用 |
| produced_output | unknown | 执行输出 |
| verification_payload | object | 验证载荷 |
资料来源:src/transports/local_seam_bridge.ts
合同包支持(Package Support)
MOVA MCP 服务器支持解析和验证合同包结构。
包清单验证
| 字段 | 必需 | 类型 | 说明 |
|---|---|---|---|
| schema_id | 是 | string | 包模式标识符 |
| package_id | 是 | string | 包标识符 |
| version | 是 | string | 版本号 |
| flow_ref | 是 | string | 流程引用 |
| classification_policy_ref | 是 | string | 分类策略引用 |
| runtime_binding_set_ref | 是 | string | 运行时绑定引用 |
全局文件验证
| 字段 | 必需 | 约束 |
|---|---|---|
| global_id | 是 | 非空字符串 |
| version | 是 | 非空字符串 |
| scope | 是 | 必须为 "contract_package" |
| semantic_roles | 是 | 非空数组 |
| non_authority_rules | 是 | 非空数组 |
配置与环境变量
必需环境变量
| 变量名 | 说明 |
|---|---|
| MOVA_API_URL | MOVA API 端点地址 |
| MOVA_API_KEY | API 认证密钥 |
| LLM_KEY | LLM 服务密钥 |
| LLM_MODEL | LLM 模型标识(如 openai/gpt-4o-mini) |
可选环境变量
| 变量名 | 默认值 | 说明 |
|---|---|---|
| MOVA_API_TIMEOUT_MS | 30000 | API 请求超时(毫秒) |
| MOVA_HTTP_PORT | 3796 | 本地 HTTP 模式端口 |
| MOVA_INVOKE_TOKEN | - | 本地调用令牌 |
本地沙箱变量
| 变量名 | 默认值 | 说明 |
|---|---|---|
| MOVA_SANDBOX_PACKAGE_PATH | - | 沙箱包路径 |
| MOVA_SANDBOX_PROJECT_PATH | - | 沙箱项目路径 |
| MOVA_SCHEMA_PATH | - | 自定义模式路径 |
资料来源:README.md、src/transports/local_seam_bridge.ts
执行模式详解
AI_ATOMIC(AI 原子操作)
AI 驱动的单步骤执行,需要 LLM 模型支持:
graph LR
A[用户输入] --> B[AI 分析]
B --> C[结构化输出]
C --> D[验证通过]
D --> E[流程继续]特性:
produced_output: 包含 AI 生成内容parsed_json_present: 输出为解析后的 JSONvalidated_output_present: 输出已通过验证
HUMAN_GATE(人工门禁)
需要人工介入的决策点:
状态流转:
graph TD
A[执行到达门禁] --> B{等待人工决策}
B --> C[gate_approve]
B --> D[gate_reject]
C --> E[流程继续]
D --> F[流程终止/回退]返回信息结构:
| 字段 | 说明 |
|---|---|
| status | "waiting_human" |
| question | 决策问题描述 |
| options | 可选决策列表 |
| recommended | 推荐选项 ID |
DETERMINISTIC(确定性执行)
纯本地 JavaScript 验证,无需 LLM:
验证规则:
- 不应声明
model字段 - 执行结果通过本地校验逻辑确定
- 适合规则驱动的合规检查
CONTRACT_CALL(合同调用)
嵌套合同调用模式:
调用约束:
- 必须声明
contract_id字段 - 目标合同可为内置或自定义类型
- 支持跨合同数据传递
资料来源:src/security/step_mode_guard.ts
错误处理
错误码体系
| 错误码 | 说明 |
|---|---|
| UNKNOWN_CONTRACT_TYPE | 未知的合同类型 |
| LOCAL_VALIDATION_FAILED | 本地验证失败 |
| API_REQUEST_FAILED | API 请求失败 |
| STEP_MODE_FIELD_MISMATCH | 执行模式字段不匹配 |
自定义运行桥接
CUSTOM_RUN_BRIDGE 内存映射表用于维护自定义合同的运行引用:
CUSTOM_RUN_BRIDGE: Map<contract_id, {run_id, updated_at, source_url?}>
该机制确保自定义合同在执行后仍可通过 mova_query 查询状态。
资料来源:src/index.ts
MCP 客户端配置示例
Claude Desktop 配置
{
"mcpServers": {
"mova": {
"command": "npx",
"args": ["-y", "@leryk1981/[email protected]"],
"env": {
"MOVA_API_URL": "https://api.mova-lab.eu",
"MOVA_API_KEY": "__SET_MOVA_API_KEY__",
"LLM_KEY": "__SET_LLM_KEY__",
"LLM_MODEL": "openai/gpt-4o-mini"
}
}
}
}
Codex 配置
[mcp_servers.mova]
command = "npx"
args = ["-y", "@leryk1981/[email protected]"]
startup_timeout_sec = 90.0
[mcp_servers.mova.env]
MOVA_API_URL = "https://api.mova-lab.eu"
MOVA_API_KEY = "__SET_MOVA_API_KEY__"
LLM_KEY = "__SET_LLM_KEY__"
LLM_MODEL = "openai/gpt-4o-mini"
资料来源:README.md
资料来源:[README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)
安全防护机制
MOVA Flat Runner 的安全防护机制是一套多层次的安全验证系统,通过一系列安全守卫(Guard)组件在流程执行前、执行中和执行后进行多维度检查。这些守卫确保合约流程的完整性和安全性,防止恶意或错误的流程定义进入运行时环境。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
架构概述
安全防护系统采用"预防优先"的设计理念,在流程注册、执行和状态转换的关键节点嵌入安全检查。系统由七个独立的安全守卫组成,每个守卫负责特定类型的安全验证。
graph TD
subgraph 安全防护层
A[流程注册入口]
B[flow_schema_guard]
C[class_definition_guard]
D[system_contract_guard]
E[step_mode_guard]
F[gate_guard]
G[graph_guard]
H[determinism_guard]
end
A --> B
B --> C
C --> D
D --> E
E --> F
F --> G
G --> H
H --> I[运行时执行]
style B fill:#e1f5fe
style C fill:#e1f5fe
style D fill:#e1f5fe
style E fill:#e1f5fe
style F fill:#e1f5fe
style G fill:#e1f5fe
style H fill:#e1f5fe核心守卫组件
1. 流程模式守卫(Step Mode Guard)
Step Mode Guard 负责验证流程步骤的执行模式与内容字段的一致性。该守卫通过 findStepModeViolations 函数扫描流程定义,检测以下违规行为:
| 执行模式 | 必需字段 | 违规条件 |
|---|---|---|
DETERMINISTIC | 无 | 声明了 model 字段(应使用本地JS检查而非LLM) |
AI_ATOMIC | model | 缺少 model 字段 |
CONTRACT_CALL | contract_id | 缺少 contract_id 字段 |
HUMAN_GATE | decision_options | 缺少 decision_options 数组 |
资料来源:src/security/step_mode_guard.ts:26-54
守卫函数 assertStepModesValid 返回违规列表或 null,确保只有字段配置正确的流程才能进入执行阶段。
2. 流程模式守卫详细逻辑
守卫通过辅助函数 asStr 安全地提取字符串值,并对每种执行模式进行专项检查:
function asStr(v: unknown): string | null {
return typeof v === "string" ? v : null;
}
对于 DETERMINISTIC 模式,守卫会检测是否误填了 model 字段,因为这表明开发者可能误解了该模式的执行方式。
资料来源:src/security/step_mode_guard.ts:1-30
3. 流程模式守卫违规报告
当检测到违规时,系统返回结构化的错误信息:
{
kind: "ai_atomic_without_model",
step_id: "analyze",
execution_mode: "AI_ATOMIC",
message: "step 'analyze' is AI_ATOMIC but has no 'model' field"
}
错误类型包括:
deterministic_with_model— DETERMINISTIC 步骤错误声明了模型ai_atomic_without_model— AI_ATOMIC 步骤缺少模型配置contract_call_without_contract_id— CONTRACT_CALL 步骤缺少合约IDhuman_gate_without_decisions— HUMAN_GATE 步骤缺少决策选项
资料来源:src/security/step_mode_guard.ts:26-54
流Schema守卫(Flow Schema Guard)
Flow Schema Guard 实现 CFV-9 安全修复,针对发现的可疑字段(如 __admin_override、__privilege_grant、__debug_mode)进行严格过滤。该守卫确保只有白名单中的顶层字段被接受。
允许的顶层字段列表
const ALLOWED_FLOW_TOP_LEVEL_KEYS = new Set([
"version",
"description",
"entry",
"steps",
"parallel_steps",
"notes",
"audit_mode",
"audit_mode_note",
"class_definition_ref",
"CONTRACT_CALL_instructions",
"input_schema",
"output_schema",
"metadata",
]);
资料来源:src/security/flow_schema_guard.ts:24-37
检测与响应机制
findUnknownFlowFields 函数遍历流程对象的所有顶层键,任何不在白名单中的字段都会被记录并报告:
function findUnknownFlowFields(flow: unknown): string[] {
if (!flow || typeof flow !== "object" || Array.isArray(flow)) return [];
const f = flow as Record<string, unknown>;
const out: string[] = [];
for (const key of Object.keys(f)) {
if (!ALLOWED_FLOW_TOP_LEVEL_KEYS.has(key))
out.push(key);
}
return out;
}
资料来源:src/security/flow_schema_guard.ts:40-49
安全修复 CFV-9 的背景
此守卫的引入源于安全审计发现:某些流程在注册时可能包含特权提升提示字段。虽然这些字段在当前代码路径中可能被忽略,但存在被未来代码路径读取的风险。系统采取"默认拒绝"的安全姿态。
类定义守卫(Class Definition Guard)
Class Definition Guard 实现 CFV-10 安全修复,专门阻止内联类定义字段的注入攻击。
禁止的字段列表
const FORBIDDEN_FLOW_KEYS = new Set([
"class_definition",
"class_definition_inline",
"class_def_override",
"class_def",
]);
资料来源:src/security/class_definition_guard.ts:13-18
验证逻辑
守卫通过 findInlineClassDefinitionFields 函数检测流程中是否存在禁止的类定义字段:
export function findInlineClassDefinitionFields(flow: unknown): string[] {
if (!flow || typeof flow !== "object") return [];
const f = flow as Record<string, unknown>;
return FORBIDDEN_FLOW_KEYS.filter((k) => Object.prototype.hasOwnProperty.call(f, k));
}
资料来源:src/security/class_definition_guard.ts:21-28
安全修复 CFV-10 的设计意图
系统要求类定义必须通过 class_id 从注册表解析,禁止在流程正文中嵌入。注册表是严重性等级和噪声控制的唯一权威来源。守卫返回的错误信息包含修复建议:
{
forbidden_fields: ["class_definition_inline"],
remediation: "Remove these fields and reference the class via class_id; the registry is the only authority on severity bands and noise control.",
http_status_equivalent: 400
}
门控守卫(Gate Guard)
Gate Guard 负责保护 HUMAN_GATE 类型步骤的安全执行。根据源码上下文,该守卫确保人工决策路径的安全性,防止通用步骤完成操作绕过人工确认机制。
安全规则 CFV-3
在 src/index.ts 中可以看到 CFV-3 的实现逻辑:
// SECURITY (CFV-3): HUMAN_GATE cannot be completed by generic step completion.
// Human confirmation requires the dedicated gate path (gate_approve / gate_reject).
// Guard runs BEFORE forwarding so run state is not advanced on rejection.
const gateGuard = await assertNotHumanGate(config, args.run_id as string, args.step_id as string, requestId);
if (gateGuard) return gateGuard;
资料来源:src/index.ts
关键约束
| 操作 | HUMAN_GATE 限制 |
|---|---|
step_complete | 禁止 — 必须使用专用门控路径 |
gate_approve | 允许 — 人工确认通过专用接口 |
gate_reject | 允许 — 人工拒绝通过专用接口 |
此设计确保人类决策不能被程序化的步骤完成操作所绕过。
图结构守卫(Graph Guard)
Graph Guard 负责验证流程的图结构完整性,确保步骤之间的依赖关系和连接符合规范。
确定性守卫(Determinism Guard)
Determinism Guard 验证 DETERMINISTIC 类型步骤的执行确定性,确保这类步骤的输出可重现且不依赖外部随机源。
系统合约守卫(System Contract Guard)
System Contract Guard 负责验证系统合约的调用权限和范围,防止对核心系统合约的滥用。
安全防护执行流程
sequenceDiagram
participant 客户端
participant flow_schema_guard as Flow Schema Guard
participant class_def_guard as Class Definition Guard
participant system_contract_guard as System Contract Guard
participant step_mode_guard as Step Mode Guard
participant gate_guard as Gate Guard
participant graph_guard as Graph Guard
participant 运行时
客户端->>flow_schema_guard: 提交流程定义
flow_schema_guard->>class_def_guard: 检查未知字段
class_def_guard->>system_contract_guard: 检查系统合约引用
system_contract_guard->>step_mode_guard: 检查步骤模式一致性
step_mode_guard->>gate_guard: 检查门控配置
gate_guard->>graph_guard: 检查图结构完整性
graph_guard->>运行时: 验证通过
Note over flow_schema_guard: CFV-9 修复
Note over class_def_guard: CFV-10 修复
Note over gate_guard: CFV-3 修复错误响应机制
所有守卫返回统一的错误格式 FlatRunnerResult:
{
ok: false,
error: {
code: string,
message: string,
details: object,
http_status_equivalent: number
}
}
错误代码对照表:
| 错误代码 | 说明 | HTTP状态码 |
|---|---|---|
STEP_MODE_FIELD_MISMATCH | 步骤执行模式与字段不匹配 | 400 |
INLINE_CLASS_DEFINITION_FORBIDDEN | 禁止内联类定义 | 400 |
UNKNOWN_FLOW_FIELDS | 存在未知流程字段 | 400 |
HUMAN_GATE_VIOLATION | 违反人工门控规则 | 403 |
安全设计原则
- 默认拒绝(Fail-Safe Defaults):未知字段和配置默认被视为不安全
- 最小权限(Least Privilege):每个守卫只检查其职责范围内的安全问题
- 深度防御(Defense in Depth):多层守卫相互配合,形成纵深防护
- 无副作用(Side-Effect Free):守卫在导入时不产生副作用,仅在执行时检查
- 可追溯性(Auditability):所有违规都有详细的错误信息和修复建议
配置与集成
安全守卫在流程执行入口处自动集成,开发者无需手动配置。守卫链的执行顺序经过精心设计,确保前置检查先于后置检查。
graph LR
A[入口] --> B[Schema验证]
B --> C[类定义检查]
C --> D[系统合约检查]
D --> E[步骤模式检查]
E --> F[门控检查]
F --> G[图结构检查]
G --> H[执行]这套安全防护机制确保了 MOVA Flat Runner 在处理各类合约流程时的安全性和可靠性,通过预防性的检查策略有效阻止了潜在的安全威胁和配置错误。
资料来源:[src/security/step_mode_guard.ts:26-54]()
业务验证器
业务验证器(Business Validators)是 mova-flat-runner 中的核心模块,负责在合同执行流程中对业务输入数据进行语义校验和策略验证。它们作为合同步骤之间的数据质量门禁,确保只有符合业务规则的数据才能进入后续流程。验证器独立于 LLM 执行,完全运行于服务端,具备确定性、可复现的校验逻辑。
继续阅读本节完整说明和来源证据。
概述
业务验证器(Business Validators)是 mova-flat-runner 中的核心模块,负责在合同执行流程中对业务输入数据进行语义校验和策略验证。它们作为合同步骤之间的数据质量门禁,确保只有符合业务规则的数据才能进入后续流程。验证器独立于 LLM 执行,完全运行于服务端,具备确定性、可复现的校验逻辑。
mova-flat-runner 的验证器系统采用了注册表模式(Registry Pattern),所有验证器必须在全局验证器注册表中登记唯一标识符后,才能被合同流程引用。资料来源:src/validators/registry.ts
来源:https://github.com/mova-compact/mova-flat-runner / 项目说明书
本地 HTTP 模式部署
本地 HTTP 模式是 mova-flat-runner(MCP 服务器)提供的一种可选部署方式,允许开发者在本地环境中直接运行 MOVA 运行时,而无需依赖远程 MOVA API 服务。该模式通过本地 HTTP 接口暴露运行时能力,适用于离线开发、调试、以及对数据隐私有严格要求的场景。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
本地 HTTP 模式是 mova-flat-runner(MCP 服务器)提供的一种可选部署方式,允许开发者在本地环境中直接运行 MOVA 运行时,而无需依赖远程 MOVA API 服务。该模式通过本地 HTTP 接口暴露运行时能力,适用于离线开发、调试、以及对数据隐私有严格要求的场景。
资料来源:README.md:40-45
核心概念
与远程模式的区别
| 特性 | 远程模式 | 本地 HTTP 模式 |
|---|---|---|
| API 端点 | https://api.mova-lab.eu | http://localhost:3796 |
| 网络依赖 | 需要外网访问 | 完全离线可用 |
| 认证方式 | MOVA_API_KEY + LLM_KEY | MOVA_INVOKE_TOKEN |
| 适用场景 | 生产部署、SaaS 集成 | 开发调试、本地测试 |
资料来源:README.md:35-42
环境变量配置
必需变量
| 变量名 | 说明 | 示例值 |
|---|---|---|
MOVA_INVOKE_TOKEN | 本地调用的访问令牌 | __SET_LOCAL_INVOKE_TOKEN__ |
可选变量
| 变量名 | 默认值 | 说明 |
|---|---|---|
MOVA_HTTP_PORT | 3796 | 本地 HTTP 服务监听端口 |
MOVA_API_TIMEOUT_MS | 30000 | API 请求超时时间(毫秒) |
资料来源:README.md:36-38
配置示例
# 本地 HTTP 模式配置
MOVA_HTTP_PORT=3796
MOVA_API_TIMEOUT_MS=30000
MOVA_INVOKE_TOKEN=my-secret-invoke-token
本地请求处理架构
执行流程
graph TD
A[客户端请求] --> B{是否本地模式?}
B -->|是| C[本地 HTTP 接口]
B -->|否| D[远程 MOVA API]
C --> E[本地沙箱执行]
D --> F[远程运行时]
E --> G[结果响应]
F --> G本地模式检测
src/index.ts 中的 isLocalSeamConfig 函数负责检测当前是否为本地模式:
export function isLocalSeamConfig(config: MovaConfig): boolean {
return config.baseUrl === LOCAL_SEAM_BACKEND;
}
资料来源:src/index.ts:310-312
本地运行时代理
当检测到本地模式时,系统通过 local_seam_bridge.ts 中的桥接组件处理请求:
async function resolveLocalSeamLocator(initialInputs) {
const packagePath = typeof initialInputs.package_path === "string" && initialInputs.package_path.trim().length > 0
? initialInputs.package_path
: process.env.MOVA_SANDBOX_PACKAGE_PATH ?? "D:\\Projects_MOVA\\mova-intent\\contracts\\dockerfile-nodejs-v1";
const projectPath = typeof initialInputs.project_path === "string" && initialInputs.project_path.trim().length > 0
? initialInputs.project_path
: process.env.MOVA_SANDBOX_PROJECT_PATH ?? "";
资料来源:src/transports/local_seam_bridge.ts:89-97
本地桥接响应结构
标准响应格式
本地 HTTP 模式返回结构化的桥接响应,包含执行状态和审计信息:
return {
ok: true,
bridge: {
ok: true,
bridge_source: "mova_flat_runner_canonical_bridge",
status: "completed" | "advanced" | "human_gate_required",
contract_ref: request.contractRef,
package_path: request.packagePath,
current_step_id: request.step.id,
execution_mode: request.step.execution_mode,
produced_output: producedOutput,
verification_payload: {
status: "PASS",
checks: [{ layer: "Invariant", result: "PASS" }],
},
// ... 其他字段
},
};
资料来源:src/transports/local_seam_bridge.ts:15-36
执行模式与输出
| 执行模式 | 输出策略 | 说明 |
|---|---|---|
AI_ATOMIC | 生成规范输出 | 使用配置的 LLM 模型生成输出 |
DETERMINISTIC | 返回 null | 本地 JS 检查,无需 LLM |
HUMAN_GATE | 等待人工决策 | 暂停等待人工确认 |
CONTRACT_CALL | 代理调用 | 转发至其他合约处理 |
资料来源:src/transports/local_seam_bridge.ts:17-19
本地包验证
包结构验证
package_support.ts 实现了对合约包的本地验证逻辑:
export function validatePackageGlobalShape(value: unknown): string | null {
if (!isObject(value)) return "global file must be a JSON object";
const allowedKeys = new Set(["schema_id", "global_id", ...]);
// 验证逻辑
}
资料来源:src/package_support.ts:78-82
必需字段检查
| 字段 | 类型 | 说明 |
|---|---|---|
global_id | string | 全局唯一标识符 |
version | string | 包版本号 |
scope | string | 必须为 contract_package |
semantic_roles | array | 非空角色数组 |
non_authority_rules | array | 非空规则数组 |
安全机制
步骤模式守卫
step_mode_guard.ts 实现了执行模式的本地安全验证:
export function findStepModeViolations(flow: unknown): StepModeViolation[] {
const out: StepModeViolation[] = [];
// 检查各种模式违规
if (mode === "AI_ATOMIC" && asStr(step.model) === null) {
out.push({
kind: "ai_atomic_without_model",
message: `step '${id}' is AI_ATOMIC but has no 'model' field`,
});
}
return out;
}
资料来源:src/security/step_mode_guard.ts:38-47
模式违规类型
| 违规类型 | 条件 | 严重性 |
|---|---|---|
ai_atomic_without_model | AI_ATOMIC 模式缺少 model 字段 | 错误 |
deterministic_with_model | DETERMINISTIC 模式包含 model 字段 | 警告 |
contract_call_without_contract_id | CONTRACT_CALL 缺少 contract_id | 错误 |
human_gate_without_decisions | HUMAN_GATE 缺少 decision_options | 错误 |
状态管理
自定义运行桥接
本地模式维护了一个内存中的 CUSTOM_RUN_BRIDGE 映射表,用于追踪自定义合约运行:
const CUSTOM_RUN_BRIDGE = new Map<string, { run_id: string; updated_at: string; source_url?: string }>();
function rememberCustomRun(contractId: string, runId: string, sourceUrl?: string): void {
const ref = { run_id: runId, updated_at: new Date().toISOString() };
if (sourceUrl) ref.source_url = sourceUrl;
CUSTOM_RUN_BRIDGE.set(contractId, ref);
}
资料来源:src/index.ts:278-285
合同记录查询
当 API 返回 404 时,本地模式会尝试通过备用路径获取合同元数据:
async function getMyContractRecord(config: MovaConfig, contractId: string): Promise<Record<string, unknown> | null> {
try {
const list = await movaGet(config, "/api/v1/contracts/my");
const contracts = list.contracts;
const match = contracts.find((item) => item.contract_id === contractId);
return match ?? null;
} catch {
return null;
}
}
资料来源:src/index.ts:287-298
部署清单
启动前检查
- [ ] 设置
MOVA_INVOKE_TOKEN环境变量 - [ ] 确认
MOVA_HTTP_PORT端口可用 - [ ] 配置
MOVA_SANDBOX_PACKAGE_PATH(可选) - [ ] 配置
MOVA_SANDBOX_PROJECT_PATH(可选)
启动命令
# 设置环境变量
export MOVA_INVOKE_TOKEN="your-secret-token"
export MOVA_HTTP_PORT=3796
# 启动本地服务
npx -y @leryk1981/[email protected]
健康检查
curl -sS http://localhost:3796/health
限制与注意事项
- 数据持久化:本地模式使用内存存储,重启后数据丢失
- 审计完整性:本地运行的审计记录可能与远程 API 格式不完全一致
- LLM 依赖:AI_ATOMIC 模式仍需配置有效的
LLM_KEY - 并发限制:本地模式不提供远程 API 的负载均衡能力
资料来源:[README.md:40-45]()
环境变量配置参考
mova-flat-runner 是一个基于 Model Context Protocol (MCP) 的 MCP 服务器,用于托管受治理的 AI 工作流,包括发票 OCR、AML 分类、信用审查以及带人工审批门和审计追踪的自定义合约执行。
继续阅读本节完整说明和来源证据。
概述
mova-flat-runner 是一个基于 Model Context Protocol (MCP) 的 MCP 服务器,用于托管受治理的 AI 工作流,包括发票 OCR、AML 分类、信用审查以及带人工审批门和审计追踪的自定义合约执行。
环境变量配置是 mova-flat-runner 与后端 MOVA API 服务通信、控制本地 HTTP 模式、以及执行合约运行时行为的核心机制。正确配置这些变量是确保 MCP 服务器正常运行的前提条件。
资料来源:README.md:1-10
资料来源:[README.md:1-10]()
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
下游已经要求复核,不能在页面中弱化。
Pitfall Log / 踩坑日志
项目:mova-compact/mova-flat-runner
摘要:发现 8 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:配置坑 - 可能修改宿主 AI 配置。
1. 配置坑 · 可能修改宿主 AI 配置
- 严重度:medium
- 证据强度:source_linked
- 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
- 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
- 建议检查:列出会写入的配置文件、目录和卸载/回滚步骤。
- 防护动作:涉及宿主配置目录时必须给回滚路径,不能只给安装命令。
- 证据:capability.host_targets | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | host_targets=mcp_host, claude, chatgpt
2. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 建议检查:将假设转成下游验证清单。
- 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
- 证据:capability.assumptions | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | README/documentation is current enough for a first validation pass.
3. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
- 证据:evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | last_activity_observed missing
4. 安全/权限坑 · 下游验证发现风险项
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:下游已经要求复核,不能在页面中弱化。
- 建议检查:进入安全/权限治理复核队列。
- 防护动作:下游风险存在时必须保持 review/recommendation 降级。
- 证据:downstream_validation.risk_items | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium
5. 安全/权限坑 · 存在安全注意事项
- 严重度:medium
- 证据强度:source_linked
- 发现:No sandbox install has been executed yet; downstream must verify before user use.
- 对用户的影响:用户安装前需要知道权限边界和敏感操作。
- 建议检查:转成明确权限清单和安全审查提示。
- 防护动作:安全注意事项必须面向用户前置展示。
- 证据:risks.safety_notes | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | No sandbox install has been executed yet; downstream must verify before user use.
6. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 建议检查:把风险写入边界卡,并确认是否需要人工复核。
- 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
- 证据:risks.scoring_risks | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium
7. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
- 防护动作:issue/PR 响应未知时,必须提示维护风险。
- 证据:evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | issue_or_pr_quality=unknown
8. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
- 证据:evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | release_recency=unknown
来源:Doramagic 发现、验证与编译记录