关于 Kaval
Kaval 是供 Agent 使用的 MCP 服务,用于核验行动所依赖的事实是否仍然成立,并返回 ALLOW、REVIEW 或 BLOCK 及签名凭证。核验、来源监控和文档提取由托管 API 完成。
主要功能
- 01事实核验并返回 ALLOW、REVIEW 或 BLOCK
- 02提供含证据详情的签名凭证
- 03合同导入与声明审核
- 04来源监控与事实批量导入
- 05按 Schema 提取文档数据
适用场景
- 01在 Agent 执行重要操作前核验事实
- 02查看决策背后的证据
- 03审核从合同提取的声明
- 04从监控文档中提取结构化记录
MCP 相关
通过 MCP 工具和 JSON 资源提供 Kaval 核验、凭证、来源管理、合同审核及提取操作,并连接托管的 Kaval API。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @usekaval/mcpKAVAL_API_KEY密钥Bring-your-own Kaval bearer key (kv_live_…). Create one at https://usekaval.com.KAVAL_BASE_URLPoint at a self-hosted or staging Kaval API instead of the hosted one. Defaults to https://api.usekaval.com.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
@usekaval/mcp
在 AI Agent 执行操作前,Kaval 会验证该操作所依赖的事实,并通过签名回执回答 ALLOW、REVIEW 或 BLOCK。此软件包将其封装为 MCP 服务。
策略引擎会根据规则判断是否允许执行某项操作;Kaval 则会验证这些规则所依赖的事实是否仍然成立。
此软件包是托管 Kaval API 的轻量客户端。所有编译、事实依据构建和检索都在服务端运行,因此你只需提供 Kaval API 密钥——无需模型或搜索密钥,也无需本地引擎。
0.6 是一次破坏性更新。 九个工具缩减为七个(之后又加入了投资组合和信息提取工具),所有移除的功能都并入了
check;对于旧路由,API 会返回410 tool_retired,此服务会将其转换为错误,并提示 Agent 调用check。请参阅从 0.5 迁移。
运行
npx -y @usekaval/mcp
它通过标准输入输出使用 MCP。将任意 MCP 客户端指向它即可。
客户端配置
{
"mcpServers": {
"kaval": {
"command": "npx",
"args": ["-y", "@usekaval/mcp"],
"env": {
"KAVAL_API_KEY": "kv_live_…",
},
},
},
}
工具
| Tool | 作用 |
|---|---|
check | 执行实际工作的工具。 发送你即将采取的操作(或其依据的主张)→ ALLOW / REVIEW / BLOCK、逐项事实状态和签名回执。 |
get_receipt | 获取某次检查的 receipt.id 背后的完整签名文档——逐项事实的证据依据、决策规则版本、签名密钥。Agent 阻止操作时附上的就是这份文档。 |
prepare_contract_upload | 创建私有 PDF 上传目标。 |
ingest_contract | 将规范文本、HTTPS 文档或上传的 PDF 加入提取队列。 |
get_contract | 获取合同处理状态、候选项数量和提取问题状态。 |
list_contract_claims | 列出提取出的候选项及其精确证据范围。 |
list_contract_extraction_issues | 列出需要客户审核的确定性提取失败。 |
review_contract_claim | 通过不可变版本控制,批准、更正或拒绝一项候选项。 |
import_facts | 将最多 400 条已审核事实加入队列,以供快速检查。 |
get_fact_import | 获取一项批量导入及其所有条目的结果。 |
list_bulletins | 已软弃用 — 按付款方、政策、代码、日期或状态筛选结构化公告。对于新的集成,请优先使用 list_extraction_runs。 |
get_bulletin | 已软弃用 — 获取一份包含字段证据的结构化公告。请优先使用 get_extraction_run。 |
list_bulletin_extraction_attempts | 已软弃用 — 列出客户可查看的公告提取状态和失败情况。请优先使用 list_extraction_runs。 |
get_bulletin_extraction_attempt | 已软弃用 — 按源版本 ID 获取一次公告提取尝试。请优先使用 get_extraction_run。 |
list_training_jobs | 列出只读训练和评估状态。 |
get_training_job | 获取一项只读训练任务。 |
list_training_feedback | 列出已审核的反馈及其有效的训练使用状态。 |
record_training_feedback_consent | 记录一项已审核反馈的明确训练使用决定。 |
create_extraction_schema | 注册 Kaval 据以提取结构化记录的 JSON Schema。需要 policy-update:manage。 |
list_extraction_schemas | 列出此工作区中注册的提取架构。 |
create_extraction_run | 请求针对绑定架构执行一次性发布方 + 期间提取任务。需要 policy-update:manage。 |
get_extraction_run | 按 ID 获取一次提取任务——包括状态、架构以及成功后的结果。 |
list_extraction_runs | 列出提取任务,支持按发布方 / 期间 / 时间筛选、游标分页以及嵌套的 document 界面信息(传入 expand_document: false 可省略)。 |
list_extraction_packages | 列出提取任务打包成的月度 PDF + 清单汇总。 |
list_publishers | 列出此工作区账单账户中由组织拥有的发布方。 |
create_publisher | 创建由组织拥有的发布方(以 UUID 标识;显示名称可重命名)。 |
get_publisher | 按 UUID 获取一个由组织拥有的发布方。 |
update_publisher | 重命名一个由组织拥有的发布方。UUID 标识不变。 |
add_source | 告知 Kaval 要监控的内容——需要 publisher_id(组织发布方 UUID)。可以是 URL、待解析的指定权威机构,或你将推送的文档。 |
list_sources | 列出 Kaval 当前为此工作区监控的内容,包括检查引用后自动注册的来源。 |
remove_source | 停止监控某个来源并将其移除。只有此操作可以释放已注册 / 已解析的工作区名额(自动注册的引用也计入该名额;发现的子项另有按父项计算的上限)。 |
update_source | 为受监控的来源绑定(或解绑)提取架构,和 / 或设置 publisher_id。传入 reprocess: true 可重新提取先前版本中缺失的内容。需要 policy-update:manage。 |
get_source_version_content | 获取某个已抓取来源版本的内容,格式为原始文本或预先拆分的 sections。 |
report_outcome | 报告此前检查(通过 receipt.id 标识)之后实际发生的情况,以便 Kaval 进行校准。 |
verify | 已弃用的试点别名:单个结论 + 明确的 evidence_refs → 已签名的 ProofPacket 回执。请使用 check。 |
资源
该服务发布以下 JSON 资源:
kaval://bulletinskaval://bulletins/extraction-attemptskaval://training-jobskaval://training-feedbackkaval://contracts/{contract_id}kaval://contracts/{contract_id}/claimskaval://contracts/{contract_id}/extraction-issueskaval://bulletins/{source_version_id}kaval://bulletins/extraction-attempts/{source_version_id}kaval://fact-imports/{import_id}kaval://training-jobs/{job_id}
训练资源为只读。审查反馈和管理同意需要 training:manage。
公报提取状态为只读。MCP 不提供操作员重新排队的控制功能。
MCP 不会启动训练或晋升模型。
check
// arguments
{
"action": "Approve this prior-authorization request at the in-network rate",
"context": "payer: Aetna; CPT 12345; plan HMO",
"materiality": "critical",
}
或者直接指定事实,完全跳过提取:
{
"claims": [
{
"subject": "Aetna",
"predicate": "requires_prior_auth_for",
"object": "CPT 12345",
"scope": { "plan": "HMO", "state": "CA" },
},
"The 2024 IBC is the current edition",
],
"mode": "fast",
}
响应:
| 字段 | 含义 |
|---|---|
decision | ALLOW — 所有重要事实在新证据下仍然成立,可以继续。REVIEW — 存在未知事实、正在重新评估的事实,或重要性为低/中等的事实发生了变化。REVIEW 绝不代表可以采取行动。BLOCK — 高/关键事实发生变化,或关键事实未知。 |
reason_codes | 一个或多个代码:ALL_FACTS_HOLD、FACT_CHANGED、FACT_EXPIRED、FACT_UNKNOWN、SOURCE_UPDATED_PENDING_REVIEW、SOURCE_UNREACHABLE、NEW_FACT_UNVERIFIED、COMPILATION_UNCERTAIN |
facts[] | { fingerprint, text, status: holds | changed | unknown, materiality, served_from_state, last_verified_at, sources[] } — 用于查看_具体是哪个_认知发生了变化 |
receipt | { id, signature, signed_at }。将 receipt.id 传给 report_outcome,或传给 get_receipt 以获取完整的签名文档 |
latency_ms | { compile, lookup, live, total } |
mode: "fast" 仅根据存储的状态作答,并将任何未知内容报告为 unknown;
"standard"(默认)可以在 max_wait_ms 时间内研究过时或新出现的事实。超出预算的事实会以
unknown 返回——不会为下一次检查预热,因为下一次检查会重新编译操作,并询问不同的事实指纹。
时间预算。 API 自身的默认值是 100000 ms,因为冷启动时检查一个包含若干新前提的操作,实时研究通常需要
50–100s。MCP 无法等待这么久:MCP 客户端会在 60s 后取消工具调用。因此,此服务会显式发送
max_wait_ms: 45000,并将该参数限制在此值以内;同时为其 HTTP 客户端设置 55s 截止时间,让超时在服务端触发——以
{"error":"timeout"} 的形式返回,并提供恢复操作——而不是让请求被取消。如果有界等待并返回
REVIEW 比继续等待更合适,可以传入更小的 max_wait_ms;0 表示完全禁用研究,mode: "fast" 就是如此。
直接使用 HTTP 和 SDK 的调用方不受上述限制,可使用完整的 100000。
已有受监控来源支持的事实,会直接从存储状态中作答,不调用模型,也不获取数据,因此对每项重要操作都调用
check 的成本很低。Kaval 从未见过的事实必须先经过研究,这需要几秒钟。
让检查保持温热
add_source 可以让检查变成数据库读取,而不是一轮调研。通常只需注册权威来源的_名称_:
{ "kind": "entity", "name": "Aetna", "intent": "payer policy bulletins" }
Kaval 会将其解析为发布该来源的页面,并进行自适应监控。kind: "url" 用于监控单个页面;kind: "push" 则表示由你自己的系统发送到 POST /v1/events 的文档。注册是可选的——检查引用的来源会自动受到监控——但提前注册,才能让对某项事实的_首次_检查足够迅速。
因此才有 remove_source。容量有两个上限,而不是一个:
- 每个工作区最多有 200 个处于活动状态的
registered/resolved来源(自动注册的引用也计入此处;发现的子来源不计入) - 每个父来源最多有 200 个处于活动状态的
discovered子来源
只有删除才能释放名额——暂停不会释放。若 Agent 按任务注册来源,却从不删除,最终会占满工作区的 registered / resolved 上限;之后新引用会被静默丢弃,原本可以快速完成的检查又会退回到调研模式。任务完成后,请移除该任务注册的来源。
提取
create_extraction_schema 用于注册 JSON Schema;使用 update_source({ id, extraction_schema_id }) 将其 id 绑定到受监控的来源,此后该来源收到的每份文档都会自动按照该 Schema 提取——无需轮询。传入 reprocess: true,还会补充重新提取之前已按其他 Schema 处理过的版本;这些 webhook 会携带 source_change: "schema_changed"(通过 source_version_id 与原始提取结果关联)。如果想针对某个发布方和时期一次性运行,而不是等待下一份文档,请直接调用 create_extraction_run。无论哪种方式,
get_extraction_run / list_extraction_runs 都会报告运行的生命周期
(processing → retry → succeeded / review_required / failed),而
list_extraction_packages 会列出每个发布方和时期归档的月度 PDF + 清单汇总。每个归档的 pdf_href 都是持久有效的 Kaval URL——对其发起 GET(或 HEAD)并跟随 302 跳转,即可获取短时有效的签名 PDF(MCP 不提供单独的下载工具;请使用支持重定向的 HTTP)。get_source_version_content 可获取提取运行所依据的规范文本(或 format: "sections")。
这是基于 Schema 的后继方案,取代了自由文本公告工具(list_bulletins、get_bulletin、list_bulletin_extraction_attempts、get_bulletin_extraction_attempt);这些工具虽已软弃用,但仍可使用。
Delta webhook 不是 Agent 工具
受监控的来源只是整个机制的一半:来源发生变化时,Kaval 会重新评估依赖该来源的事实,并推送一条 fact_state.delta webhook,指出发生变化的内容;绑定了提取 Schema 的来源还会推送 extraction.document(以及每月推送的 extraction.package),其中包含提取出的记录(每条记录都嵌套了 evidence),以及用于 PDF 高亮的可选分节 page / bbox。extraction_run.period 表示出版物 / 新闻简报的月份。**这些订阅不会作为 MCP 工具开放。**它们是一次性部署配置——每个订阅都会创建一个长期有效的出站回调,绑定到 https 端点和必须妥善保管的签名密钥。这是由人工或服务在部署时作出的决定,不是既没有端点也没有签名密钥的 Agent 在循环中作出的选择。
请通过 SDK(Node 中使用 kaval.subscribeFactStateDeltas({ callback_url }) / kaval.subscribeExtractions({ callback_url }),Python 中使用 kaval.subscribe_fact_state_deltas(…) / kaval.subscribe_extractions(…))、通过带有 subscription_kind: "fact_state" 或 "extraction" 的 POST /v1/webhooks(创建时不接受 policy_update),或通过控制面板配置一次。之后,Agent 只需调用 check(或读取 list_extraction_runs),检查便会始终迅速且保持最新。
从 0.5 迁移
| 0.5 工具 | 0.6 |
|---|---|
currentness_check | check — { action } 或 { claims: ["…"] } |
currentness_verify | check — 根据 decision === "ALLOW" 分支判断,而不是 act === true |
currentness_extract_and_check | check — 将段落作为 action/context 传入;Kaval 会自行整理事实 |
currentness_scan_store | check — { claims: [...] },每次调用最多 20 条 |
currentness_monitor | add_source + fact_state webhook 订阅(见上文)——变更会推送给你 |
proof_audit | check — 回执就是证明;get_receipt 会返回已签名的文档 |
proof_gate | check — 热路径会从已存储的状态重新检查,因此无需重新应用 |
report_outcome | report_outcome(未变更;传入 receipt.id) |
verify | verify,现已弃用 → 改用 check |
状态映射:current + act: true → decision: "ALLOW",且每项事实均为 holds;
stale/contradicted → 某项事实为 changed(根据重要性判定为 REVIEW 或 BLOCK);
unsupported/insufficient/conflicting → 某项事实为 unknown(REVIEW,或关键事实为 BLOCK)。
0.5 客户端调用已移除的路由时,会收到 410 {"error":"tool_retired","replacement":"/v1/check"},
此服务会将其转换为 {"error":"tool_retired","message":"this capability was folded into the check tool …","status":410}。
幂等性
合同上传、合同创建、声明审核、事实导入、create_extraction_schema、
create_extraction_run 和 verify 都带有操作键。如果你未提供操作键,服务器会自动创建一个。
发生结果不明确的故障后,请复用返回的操作键。
check 则有意不带操作键:它会读取当前状态,因此重试时会重新计算,而不是重放,也不会重复计数。
工具错误
工具调用失败时会返回 isError: true 和一段说明错误情况的 JSON 正文,Agent 可以据此进行分支判断,而不必解析散文。
error | 应对方式 |
|---|---|
任意 API 代码(unauthorized、subscription_required、bad_request,……) | 原样返回,并附带 status 和 API 的 message |
tool_retired | 410 — 消息会指出替代所调用路由的路由 |
timeout | 使用 mode: "fast" 重试,或调小 max_wait_ms |
network_unreachable | 未能连接到 API — 检查 KAVAL_BASE_URL 和网络访问 |
request_ambiguous | 幂等调用的结果未知;使用返回的 idempotency_key 重试 |
已签名回执
检查回执由 Ed25519 签名,且可自行推导:由于决策表是公开的,回执自身的事实列表可以离线逐字节重新推导出判定结果,无需服务器。使用 @usekaval/kaval/verify 验证回执——这是本软件包已依赖的 Node SDK 中无依赖的子路径,也可以使用该 SDK 随附的 kaval-receipt-verify CLI。它会分别检查密码学有效性、密钥信任和时效性,无需 Kaval 账户或 API 密钥;公钥从无需身份验证的 GET /v1/proof-verification-keys/:kid 读取,也可以从与回执一同归档的密钥集读取,这是完全离线的方式。
npx -p @usekaval/kaval kaval-receipt-verify verify receipt.json \
--key-url https://api.usekaval.com/v1/proof-verification-keys
check 仅返回 { id, signature, signed_at }。使用该 id 调用 get_receipt,即可获取实际签名的文档——其中包含每项事实及其状态、相应的证据依据(来源定位符、内容摘要及摘要涵盖的内容、抓取时间和发布时间)、决策规则版本以及签名密钥 ID。这就是升级处理 BLOCK 时应附上的材料。
**明确的边界:**演示结果不具有组织授权效力;生产环境中的 ALLOW 需要绑定客户的操作策略以及适用的经验校准;REVIEW 绝不代表允许采取行动。
环境
| 变量 | 必填 | 用途 |
|---|---|---|
KAVAL_API_KEY | 是 | 托管 Kaval API 的 Bearer 密钥(在 https://usekaval.com 创建) |
KAVAL_BASE_URL | 否 | 覆盖 API 基础 URL(可自托管/暂存环境)。默认为 https://api.usekaval.com |
这两个变量均在 server.json 和 smithery.yaml 中声明,因此通过注册表安装时,可以指向自托管部署,而不局限于托管 API。
营销网站的 /api/verify 代理使用 KAVAL_API_URL,而不是 KAVAL_BASE_URL。
编程式用法
本软件包主要是一个 CLI(kaval-mcp)。它还导出了服务器工厂,可用于嵌入:
import { createMcpServer, createClientFromEnv } from "@usekaval/mcp";
const server = createMcpServer(createClientFromEnv());
// connect `server` to your own MCP transport
或者传入你自行配置的客户端:
import { createMcpServer } from "@usekaval/mcp";
import { Kaval } from "@usekaval/kaval";
const server = createMcpServer(
new Kaval({ apiKey: process.env.KAVAL_API_KEY }),
);
使用 delete_extraction_schema 并传入 { "id": "<schema-id>" },即可删除未使用的架构。
删除后,该架构会从列表和选择器中移除。历史提取记录仍会保留其定义。
如果有正在监视的活动来源使用该架构,API 会返回 409 schema_in_use。
使用 rename_extraction_schema 并传入 { "id": "<schema-id>", "name": "New name" },即可重命名架构。
其定义和哈希保持不变。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。