mcpField
S
Seal

Seal

本地服务
github.com/aurumflux20金融数据07 周前更新

关于 Seal

Seal 是用于跨进程协调支付等不可逆操作的 Python 库和 MCP 服务。它通过共享 Postgres 原子准入,并结合支付服务商确认记录,防止重复执行和核验结果。

主要功能

  1. 01通过共享 Postgres 原子准入
  2. 02哈希链式操作证书
  3. 03服务商见证与结果核验
  4. 04支付路径的自主等级
  5. 05执行前检查世界数据是否过期

适用场景

  1. 01阻止并发 Agent 重复扣款
  2. 02向支付服务商核实不确定的付款
  3. 03发现网关外扣款后暂停支出

MCP 相关

Seal 向 MCP 主机提供 12 个工具,用于提议、准入、执行和核验不可逆操作;网关模式使用一次性票据,而非暴露服务商密钥。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"aurumflux20-seal": {
"command": "uvx",
"args": [
"seal-kernel"
]
}
}
}
启动命令uvx seal-kernel

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiseal-kernel0.5.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

seal

公开登记册:重试安全性索引列出了哪些 Agent 付款实现会在答案丢失时只付款一次,包括已验证安全、已发现并修复(附修复耗时),以及如何获得验证。每一行都链接到相应的证明。

让你的 Agent 赢得无需你介入即可支出的权利。

Seal 与 Coherence 不同

Seal 和 EffectFence 会在不可逆操作发生时阻止它重复执行——在资金转移过程中进行运行时强制执行。Coherence 从不接触你的运行时;它会在事后读取记录,并对照 Agent 的声明与其证明进行评估。**预防与证明。**解决的问题不同,代码不同,彼此没有重叠。

免费:提交任何会转移资金的客户端、支付协调器、SDK 或工具包——无论是你自己的还是别人的——我们都会阅读并在重试安全性索引上免费发布评估结果。反馈会附上机制、文件和行号,以及一个失败测试。在你发布修复之前,我们只统计,不公布名称。提交评估 →

Seal 是一个 MCP 服务(seal-mcp、stdio、JSON-RPC 2.0),也是一个 Python 库。它为 MCP 主机提供 12 个工具,用于不可逆操作的恰好一次执行:seal_propose、seal_execute、seal_paths(网关模式——Agent 持有一次性票据,而非服务提供方密钥),以及 seal_admit、seal_commit、seal_abort、seal_heartbeat、seal_get、 seal_verify、seal_incident_receipt、seal_expect、seal_obligations。

docker run -i ghcr.io/aurumflux20/seal          # or: python -m seal.mcp_server

启动时处于仅检查模式,无需环境配置——initialize 和 tools/list 无需数据库即可响应,因此主机或注册表探测可以立即连接。 设置 SEAL_DSN 为 Postgres DSN 才能实际准入操作;网关模式则需设置 SEAL_EXECUTORS=your.module。

// claude_desktop_config.json
{ "mcpServers": { "seal": { "command": "python", "args": ["-m", "seal.mcp_server"],
                            "env": { "SEAL_DSN": "postgres://..." } } } }

不是工程师?请改读 docs/PLAIN-ENGLISH.md—— 内容相同,但没有术语,也包括我们做不到的事。

其他人提供的都是锁:设定一次就不再过问的支出上限。上限永远不会学习,因此,已经顺利结算一万笔付款的 Agent,与今天早上刚安装的 Agent 得到的信任程度完全相同——而你仍然要不断点击“批准”。

Seal 提供的是解锁。它会读取付款路径实际证明了什么——服务提供方确认的结算,以及表明没有资金在其背后转移的清扫记录——并计算该路径赢得的自主权。L0 OBSERVED → L5 AUTONOMOUS。 无需任何人手动输入等级。

████████············  L2 ASSISTED      50 proven · 100% confirmed   [human required]
     fifty settlements — but volume alone is not trust.
████████████········  L3 DELEGATED     50 proven · 100% confirmed   [unattended]
     one clean sweep later: the human stops clicking Approve.
····················  L0 OBSERVED      50 proven · 100% confirmed   [SUSPENDED]
     one charge the gateway never admitted. fifty clean ones don't outweigh it.
SEAL_DSN="..." python3 license_demo.py     # watch a path earn L3 and lose it

自 0.4.0 起,许可证会驱动实际执行,而不只是仪表板。启用 自主权解锁——使用 Gateway(seal, earned_autonomy=True),或为 MCP 服务设置 SEAL_EARNED_AUTONOMY=1——网关就只会在路径凭自身记录赢得相应权限(L3+)的范围内,在操作方设定的上限内,允许该路径无人值守地转移资金,绝不会超出上限。三种情况会立即将控制权交还给人工:路径尚未赢得相应权限、服务暂停(资金绕过网关发生了转移),以及暂停等待——执行已到达服务提供方,但结果未知,因此路径会暂停,直到 settle() 向服务提供方查询结果。世界给出答复后,暂停等待会自动解除。人工仍可通过同一个制作者-复核者流程(tier=LICENCE)批准任何单笔操作。此功能默认关闭:切换启用前,一切照旧。

你能证明你的 Agent 不会向客户重复收费吗? 三档服务,一条晋级路径,仅书面交付:300 美元创始合规测试——对你的实现运行整套测试,并将结果发布到 Index(仅限前三位; 预订)· 1,200 美元认证测试 ——针对你的在线端点测试所有模糊结果,签署测试结果,五个工作日内提供调查结果,通过测试后在 24 小时内签署认证 (预订)· 12,000 美元固定范围的 资金路径审查——在 7–10 天内读取、测试并认证一条生产资金路径,如果没有证据表明你运行的路径会实际触发重复操作,则不收费。如需先免费自查, hostile-facilitator 会在 60 秒内给出结果。

信誉建立缓慢,失去却只需一瞬——这才是让过往记录真正有意义的唯一方式。完整的等级定义见:docs/AUTONOMY-LEVELS.md。

Seal 的模糊结果处理原则——“无法确定”是终态,绝不等于“未发生”——现已写入由我们共同起草的 MCP 重试安全提案第 4.3 节,其测试套件就是我们的合规测试集。

底层机制:恰好一次准入

两个不同的 Agent,在两台不同的机器上,同时决定对订单 123 收费。进程内幂等性无济于事——防护机制必须位于两个 Agent 都能访问的存储中,并且必须在其中原子性地决定谁胜出。

Seal 就是这一层。一个 Postgres,每个意图对应一行,只允许一个胜出者:

INSERT ... ON CONFLICT DO NOTHING     -- one row, one winner, no check-then-act window

每个获准执行的操作最终都会生成一份证书:一个内容寻址哈希,基于意图、参数摘要、结果摘要以及上一份证书的哈希计算得出。编辑、删除或重新排列任意证书,都会破坏之后的所有哈希——任何拥有 DSN 的人都能检查,无需联网,也无需信任我们:

SEAL_DSN="..." python3 -m seal verify
# chain VERIFIED — 41 cert(s), every link intact   (exit 0; broken chain → exit 1)

验证

我们以对抗性方式测试这一声明:1,000 个真实线程通过同一道屏障,同时向一个共享 Postgres 发起请求。“收费”操作会递增一个计量计数器——如果两个调用方都执行,计数器就会显示 2,测试会明确报错。

连续四次运行的结果:ACTUAL_EXECUTIONS = 1。 每个未胜出的请求要么重放已封存的证书,要么在操作进行中主动退出,要么在存储不可达时安全失败。封存后再发起 50 个调用:全部重放,没有一个重新执行。完整数据及坦诚说明的限制见:STORM-PROOF.md。

自行运行:

pip install seal-kernel

export SEAL_DSN="host=... dbname=seal"
python3 -m seal verify          # chain check, no network, no trust in us

如需自行运行 1,000 线程风暴证明,请克隆仓库(测试工具随源代码提供,不包含在 wheel 中):

# Needs Python 3.10+. macOS ships 3.9 with pip 21, which fails an editable
# install with a misleading "setup.py not found" error — use a venv rather
# than debugging that.
git clone https://github.com/aurumflux20/seal && cd seal
python3 -m venv .venv && source .venv/bin/activate
python3 -m pip install -U pip && python3 -m pip install -e .

export SEAL_DSN="host=... dbname=seal"
python3 storm.py --n 1000

测试你自己的服务,而不只是我们的服务

将上面的精确测试工具泛化为一个独立文件,与本仓库零依赖——复制它,将其指向你自己的、可写入数据的工具,然后亲自验证:

python3 range_safety_test.py --n 1000

在你真正运行测试之前,它会先针对已知不安全和已知安全的目标自行演示,因此通过测试才有意义。完整说明见 docs/RANGE-SAFETY-TEST.md,其中包括早期版本的这项测试曾经误导我们的三种情况,以及我们如何修复它们。

用法

from seal import Seal

seal = Seal(dsn); seal.setup()

adm = seal.admit("charge", {"order_id": "123", "amount": 4900})
if adm.fresh:                     # you won — run the effect, then seal it
    result = stripe_charge(...)
    cert = seal.seal(adm.intent, adm.fence, result)
elif adm.cert is not None:        # already done — here is the receipt
    return adm.cert
else:                             # someone else is mid-flight — stand down
    raise InFlight()

如果效果在尚未发生任何不可逆操作之前失败,请释放声明,以便可以安全重试:seal.fail(adm.intent, adm.fence, reason)。

当持有者在效果执行期间死亡时(其租约过期,而意图仍处于打开状态),下一次 admit() 不会发放新的声明。过期本身无法说明持有者是在提供方响应前崩溃,还是仍在等待一个缓慢的提供方调用,因此重新执行就意味着在结果未知的情况下执行——而 Seal 承诺绝不会这样做。你会得到 fresh=False, cert=None, reason="lease expired with no witness…";请通过见证进行处理(Gateway.register_witness 或 seal.settle(intent, witness)):如果效果已生效,则修复记录;如果没有生效,则释放声明。Seal(dsn, blind_reclaim=True) 会恢复旧的接管行为,适用于从设计上就具备幂等性的提供方。网关会在整个提供方调用期间为租约发送心跳,因此缓慢的 Stripe 调用会保留其声明,而不会丢失。

世界确认——基于真实 Stripe 测量,而非模拟

一张声称“只准入一次”的证书,说的是我们自己的情况。接下来要问的是 Stripe(或 Resend,或你的银行 Webhook)实际记录了什么——答案可以与我们不一致。

export SEAL_DSN="host=... dbname=..."
export STRIPE_TEST_KEY="sk_test_..."   # your own test-mode key, Dashboard -> API keys
python3 stripe_demo.py

它在你的真实 Stripe 测试账户上执行以下操作,不使用模拟:

  1. 两个 Agent 在同一时刻发起相同的扣款。 Seal 只准入其中一个。 实际创建的 PaymentIntent 恰好只有一个。
  2. 见证查询 Stripe: “有多少笔扣款带有此意图?” Stripe 回答一笔 → 证书升级为 WORLD_FINAL。
  3. 在网关之外创建一笔违规扣款——这是本地围栏无法独自阻止的情况。见证再次查询;Stripe 此时回答两笔 → 证书变为 WORLD_DIVERGED,该域被冻结,系统会自动拒绝在该域上继续支出。

这次真实运行让我们确认了两件实事,两者都已修复并经过测试:Stripe 的搜索索引最终一致(新扣款可能要过好几秒才会出现——见证会持续轮询,直到得到确定答案,绝不会把“尚未编入索引”的空查询结果当作权威的“不存在”记录);而一旦真实状态与账本矛盾,之后不稳定的重新计数绝不能悄悄将证书降回 WORLD_FINAL——按设计,状态分歧一经确认便会持续保留。

提交前冻结世界状态——不要依据已经变化的事实采取行动

admit() 一直接受 read_set——即决策所依赖的世界事实(例如购物车总额、库存数量)——并将其存储在证书中。直到现在,这些事实从未得到检查:调用方以为自己有过期保护,实际上却没有。其缺陷与当天早些时候修复的另一个缺陷如出一辙,只是高了一层——约束已写入架构,却从未真正执行。

from seal.freshness import CallableChecker

fresh = CallableChecker(lambda rs: current_cart_total(rs["order_id"]) == rs["total"])

adm = seal.admit("charge", {"amount": 5000}, key="order-777",
                 read_set={"order_id": "777", "total": 5000}, checker=fresh)
# StaleWorldRead is raised BEFORE a fence is granted if the checker says no —
# nothing runs on facts that already changed. Gateway.propose() takes the
# same read_set/checker kwargs and passes them straight through.

选择在围栏之前而非效果执行之后进行检查,是经过审慎考虑的:事后检查只能拒绝确认成功,却无法阻止基于过时信息转移资金,而这正是此功能要防止的实际故障。此功能采用可选启用且向后兼容的方式,遵循本库其他功能一贯的规则:只有调用方同时提供 read_set 和 checker 时才会启用。我们会如实说明其限制,并在适用之处直接指出,而不是等人发现:检查器调用本身无法与准入 INSERT 保持原子性,因此在这个狭窄间隙内发生的变化仍会留下一个窗口——这与见证所依赖的提供方索引最终一致属于同一类注意事项。

Clearance — 必须通过赢得信任获得,而非自行宣称

围栏证明某项操作曾经运行过一次。Clearance 是更上一层的机制,也是公司真正愿意为之付费的东西:Agent 可以在无人值守的情况下调用哪些工具路径,以及需要什么证据。

from seal.clearance import Clearance, CLEARED

cl = Clearance(seal)
cl.set_policy("charge", CLEARED)                       # an operator's intent
cl.record_proof("charge", green=True, storm_n=1000, executions=1)  # from CI

cl.status("charge")["effective"]   # CLEARED — but only because both are true

让这不只是一个开关的规则是:CLEARED 必须通过赢得信任获得,而非自行宣称。 只有操作员设置了某条路径,并且最近记录了绿色风暴证明,该路径才会报告为有效的 CLEARED。如果最近一次证明变为红色,或证明已过期,status() 就会自行报告 HOLD——没人需要记得将其降级。REVOKED 始终优先,永远不会自动恢复;revoke_all() 则是一个能在关口处停止所有已知路径的开关。range_report() 会导出计数后的事件和引用提供商信息的认证——这正是安全问卷或 CFO 真正会查看的材料。

独占权限 — Agent 获得的是票据,而非凭证

Clearance 是策略。如果 Agent 仍持有 sk_live,它就能绕过策略;这不是防护栏,而只是建议。独占权限会彻底移除 Agent 持有的凭证。

from seal.authority import Gateway

gw = Gateway(seal)
gw.register_executor("charge", lambda args: stripe_charge(args))  # secret lives HERE only

prop = gw.propose("charge", {"amount": 4900}, key="order-777")
if prop["status"] == "cleared":
    result = gw.execute(prop["ticket"], {"amount": 4900})  # gateway calls Stripe, not the agent

Agent 调用 propose() 后会获得一个票据——证明某项意图已获准、通过 Clearance 并纳入预算——绝不会获得密钥。只有 execute() 会实际调用提供商;票据会绑定到已获准的确切参数:如果传给 execute() 的内容与提议的内容不符,票据就会被拒绝;票据只能使用一次,并且会过期。(最初版本没有将参数绑定到签名,这意味着为 1 美元获准的票据本可以用于任意金额——这个问题是在发布前通过攻击我们自己的构建发现的,而不是发布后才发现。)

直白说明保管模式: 网关运行在你自己的基础设施内。AurumFlux 从不持有、查看或传输你的提供商密钥——我们提供的软件会将密钥从 Agent 手中移走;我们自己不会充当保险库。坦诚地说:同一主机上能读取网关自身环境的进程仍然可以窃取密钥。这提高了窃取密钥的门槛,让它变成“从保险库里偷”,但并非让窃取在物理上不可能。

分级 Clearance — 对重要金额实行经办与审批分离

对于 5 美元的 API 调用,二元式 CLEARED 已足够。但对于 50,000 美元的付款,财务部门不会就此签字——他们签字认可的是职责分离:提出支出的人绝不能是审批该支出的人,并且要留下记录。分级 Clearance 在 Clearance 之上增加了阈值:

from seal.graduated import GraduatedClearance, APPROVE

gc = GraduatedClearance(seal)
gc.set_thresholds("payout", auto_ceiling=100, dual_ceiling=10_000, required_approvers=2)

# amount 50   -> AUTO, ordinary Clearance applies
# amount 5000 -> DUAL, needs 2 distinct human approvals before it can execute
r = gc.request("payout", 5000, maker="alice", intent=intent)
gc.add_vote(r["id"], "bob", APPROVE)
gc.add_vote(r["id"], "carol", APPROVE)   # now APPROVED — a THIRD person, not alice

该机制已接入网关:对于配置了阈值的路径,调用 Gateway.propose(..., amount=X) 会返回 {"status": "needs_approval", "tier": "DUAL"},而不是票据,直到提供符合要求的 approval_id。经办人不能审批自己的请求——这是由代码强制执行,而非依赖策略;即使发生真实的并发竞争,同一审批人也不能被重复计入,因为这是由 Postgres 的 (approval, approver) 上的 UNIQUE 约束保证的,而非应用层检查。一次拒绝即可终止审批。一次审批仅授权一次执行,并绑定到请求审批的确切意图。每个已作出决定的审批——无论批准还是拒绝,包括每一票——都会追加到与执行认证相同的哈希链中,因此 seal verify 会像验证实际运行的内容一样验证治理决策。

此设计向后兼容:从未对其运行过 set_thresholds() 的路径不会触发分级 Clearance,即使调用 propose() 时提供了金额也是如此——现有的仅预算集成不受影响。

端到端运行完整流程——无需支付提供商,也不会产生任何扣款:

python3 approval_demo.py

200 美元的采购会自动获准;12,000 美元的支出在两位不同的人类审批前会被拒绝;请求者尝试审批自己的请求时会被拒绝;同一审批人的重复投票会被拒绝;一次拒绝即可终止审批;250,000 美元的支出永远不会自动获准;而一次 revoke 会停止包括 200 美元路径在内的所有操作。流程最终会生成 Range Report,其中以金额说明审批情况——批准和拒绝的总额,而不是按事件类型统计数量。

可移植回执——可带出机构的证据

真正的争议涉及三方——授权 Agent 的用户、运行它的运营方,以及收款的商户——每一方都持有另外两方无法读取的数据库。seal verify 回答“这次运行是否恰好发生了一次,世界是否确认了它?”,但只有持有 DSN 的人才能获得答案,也就是说,只有被要求证明自己清白的一方才能获得答案。

可移植回执就是以文件形式呈现这个答案。证书在写入时会基于 RFC 8785 规范化 JSON 计算哈希,并在配置了密钥时通过 Ed25519 签名,因此对手方无需 数据库、网络,也无需我们的任何代码 就能验证它们——docs/verify-receipt.mjs 用大约 30 行 Node 代码就能完成:

pip install 'seal-kernel[signing]'
python -m seal keygen                     # SEAL_SIGNING_KEY= secret · public key= publish it
python -m seal export --intent <id> > receipt.json
python -m seal verify-receipt receipt.json --pubkey <hex>    # needs NO DSN
node docs/verify-receipt.mjs receipt.json <hex>              # or no Python at all

关于判定本身,请注意这些诚实的限制:使用固定密钥进行验证通过,证明 这些证书由密钥持有者生成且未被篡改——但无法证明完整性(是否存在其他证书,需要对照存储进行链检查);未固定密钥的验证只能证明内部一致性,绝不证明作者身份。签名是可选的;未签名的存储仍会像以前一样正常工作,v1 证书也会永远与 v2 证书一同通过验证。

settle()——去重不等于结算

幂等键可以让同一请求的重试安全进行,但无法回答超时后发生了什么,因为服务提供方可能已经采取了行动。这类意图会保持 open 状态;在 settle() 出现之前,唯一的解决方式是隐式的——未来某个调用方可能永远不会执行 admit(heal_with=…)。现在,解决它只需一个动词:

gateway.settle(intent)      # uses the path's registered witness
# CONFIRMED_ONE → healed to WORLD_FINAL, budget reservation settled
# ABSENT        → claim released for a clean retry, budget returned
# MULTIPLE      → WORLD_DIVERGED on the chain, domain frozen
# UNKNOWN       → unresolved, loudly — the claim stands, nothing is guessed

义务——警示 Agent 未能做到的事

上面提到的每种防护措施——以及我们所知的每种 Agent 安全工具——监控的都是作为:重复扣费、超支、矛盾。没有工具监控未作为。崩溃、丢失密钥或悄然停止运行的 Agent,看起来与无事可做的 Agent 完全一样——直到工资未能发放,或依法应在 14 天内退还的款项悄无声息地未能退还。

本仓库已经在测试中杜绝了这种失败模式(conftest.py:所有测试都被跳过的运行不算通过)。义务将同一原则应用于生产环境中的资金。这是对账扫描的对偶:

reconcile:    provider effects − admitted intents = out-of-band  (did too much)
obligations:  declared duties  − sealed intents   = BREACH       (did too little)
from seal.obligation import Obligations
obs = Obligations(seal); obs.setup()

# at decision time, the agent binds its future self:
obs.expect(action="refund", key="return-123", due_in_sec=14*86400,
           description="statutory refund window for return #123")

# the business heartbeat:
obs.expect_recurring(action="renewal", every_sec=86400, min_count=1)

obs.sweep()   # or: python -m seal obligations   (exit 1 on any open breach)

让遗漏不只是仪表板上一行记录的关键在于:违约事件本身会追加到防篡改链中(删除它会破坏其后的每个哈希),而且 obligation_breached 是一个会暂停许可的事件——对已声明工作保持沉默的路径,会像重复扣费的路径一样失去已获得的自主权。Agent 可以声明职责(通过 MCP 使用 seal_expect);取消职责则是运营方的操作,没有面向 Agent 的工具,因为 Agent 可以取消的义务就不算义务。违约不会故意冻结路径——被冻结的退款路径无法补救未退还的退款;可采取的手段是证据、警报和许可。

Seal 证书声明了什么,又没有声明什么

证书证明该操作已在此网关获准执行且仅执行一次,并且记录的结果自此未被篡改。它并不证明外部世界已完成结算——每张 v1 证书都永久且有意地带有 world: "unconfirmed"。“我们只批准了这次操作一次”和“Stripe 已收款”是不同的声明;混淆两者正是此工具旨在阻止的错误类型。世界确认(通过服务提供方适配器,对照 Stripe 或你自己的服务提供方记录更新该字段)是下一层功能,而证书架构已经包含此字段,因此格式不会因此改变。

与 once-kernel、effectfence 和 coherence 的关系

once-kernel 证明了单个 进程没有重复执行某项操作。 effectfence 为单个 MCP 服务提供防护。Seal 是位于两者之上的跨进程层,适用于你的 Agent 超出单台机器的能力范围时。免费的基础组件将永远保持免费 (Apache-2.0 / MIT)。

关于 Agent PR 和 CI 中的声明与证据(说了 ≠ 证明了),请参阅独立项目 coherence—— 它不属于本仓库;包不同,Git 历史也不同。

许可证

Business Source License 1.1:可以阅读、运行,并在内部用于生产环境 (包括商业用途)——但不能将其作为托管服务转售。 将于 2030-08-12 转为 Apache-2.0。


mcp-name: io.github.aurumflux20/seal

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。