关于 MCP Event Intelligence
MCP Event Intelligence 是面向需要等待多来源未来事件的 Agent 主机的实验性事件运行时,可持久化条件并在满足时唤醒任务。它以确定性 CEP 为主,并通过宿主边界接入现有 MCP 连接。
主要功能
- 01持久化未来事件条件
- 02跨来源时序模式与窗口
- 03语义谓词与派生事件
- 04触发器生命周期管理
- 05租户范围隔离与持久存储
适用场景
- 01满足多事件条件后唤醒 Agent 任务
- 02根据事件时间与序列检测复杂模式
- 03在共享主机中隔离不同租户触发器
MCP 相关
作为 MCP 事件运行时,它发现宿主已连接且支持 Events 的客户端,并通过实验性 Events 扩展接收事件。还提供可嵌入 MCP 服务的事件提供方接口。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y mcp-event-intelligenceDATA_DIRPersistent Event Intelligence state directory.MCP_WRITE_ENABLEDSet to true to expose persistent trigger mutation tools. Read-only by default.RUNTIME_WAKE_TARGETS_JSON密钥Optional operator-configured signed runtime wake targets.TYPESAFE_API_KEY密钥Optional TypeSafe Jev API key for explicit semantic Pattern AST nodes.TYPESAFE_MODELOptional TypeSafe Jev model override. Defaults to jev-latest.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
MCP Event Intelligence
为休眠中的 Agent 提供持久化的时序事件智能。
MCP Event Intelligence 是一个实验性事件运行时,面向需要对多个事件源中的未来条件作出响应、又不需要让大模型或 Agent 循环持续运行的 Agent。
主要集成模式是嵌入式且由宿主掌控:Agent 宿主保留现有的 MCP 客户端、传输机制、OAuth 会话和提供方凭据。Event Intelligence 接收宿主 MCP 注册表的引用,自动发现已连接的客户端,并且只使用支持 Events 的客户端。
Agent 可以表达如下意图:
当此 PR 合并、生产环境部署成功,且连续 10 分钟未观察到错误时,唤醒此任务并检查发布情况。
Event Intelligence 独立于模型持久化未来条件,等待现实满足这些条件,并且仅在条件有激活目标时唤醒宿主。条件也可以在没有 Agent 后续执行的情况下存在;更高层级的事实则通过派生事件触发器单独组合。
将其嵌入现有 Agent 宿主
通过 npm 安装:
npm install mcp-event-intelligence
已发布的软件包:npm · Official MCP Registry
对于大多数运行时,请从与运行时无关的集成接口开始:
import {
createEmbeddedRuntimeIntegration,
createEventSourceRegistry,
} from 'mcp-event-intelligence/embedded';
const ei = await createEmbeddedRuntimeIntegration({
dataDir: './data/event-intelligence',
// The host owns transports, auth and connection lifecycle.
eventSources: createEventSourceRegistry({
list: () => runtime.events.connections(),
subscribe: (refresh) => runtime.events.onConnectionsChanged(refresh),
}),
// EI emits an activation. The host decides what "resume" means.
activation: {
resolveTarget: (target) => runtime.resolveContinuation(target),
hasReceipt: (receiptId) => runtime.hasWakeReceipt(receiptId),
deliver: ({ activation, target, receiptId }) =>
runtime.resumeFromEvent({ activation, target, receiptId }),
},
// Optional. Runtimes without an agent-tool surface can omit tooling entirely.
tooling: {
resolveContext: (ctx) => ({
target: runtime.currentContinuation(ctx),
actor: runtime.currentActor(ctx),
owner: runtime.currentOwner(ctx),
}),
// Host-owned control. EI does not reduce authorization/approval/interrupt
// semantics to a boolean.
control: (request) => runtime.policy.control(request),
// Optional host-owned result projection. Large results may be externalized
// behind a runtime-specific reference instead of entering model context.
projectResult: (request) => runtime.results.project(request),
},
});
除了 { runtime, kind, id } 之外,EI 不会对延续目标作任何假设。宿主可以将其映射到 Turn、Execution、线程、图检查点、工作流、Case 或任何其他持久化延续原语。
返回的工具是中立描述符,附带与 EI 无关的能力元数据:
for (const tool of ei.toolCatalog.all) {
// The host translates this descriptor into its own tool/capability system.
runtime.tools.register(tool);
}
嵌入式目录包含源发现,以及完整的持久化触发器生命周期:trigger_create、trigger_list、trigger_inspect、trigger_pause、trigger_resume、trigger_update 和 trigger_delete。触发器读取操作限定于 resolveContext() 返回的身份;持久化变更仍须经过宿主的 control() 边界。
EI 有意不提供诸如 toOpenAI()、toAnthropic()、toMuffin() 或 toArtemis() 这样的按运行时划分的适配器矩阵。运行时种类太多,而且添加运行时绝不能要求修改 EI 核心。宿主使用相同的中立契约,并在自己的边界处完成最终转换。
工具的暴露范围也由宿主负责。toolCatalog.list({ capabilityIds }) 可以仅投影宿主决定暴露的能力。EI 提供读取与持久化变更等元数据,但不会决定宿主的 RBAC、风险等级、审批流程或中断 UX。
对于持久化变更,tooling.control() 会返回以下其中一项:
{ action: 'execute', execution?: ... }— 继续执行,可选择附加宿主策略/审批来源信息;或{ action: 'return', result: ... }— 停止执行,并返回由宿主拥有的不透明结果。该结果可以表示拒绝、需要审批、已中断、已延迟,或宿主运行时支持的任何其他状态。
EI 绝不会解释第二种情况。这样可确保授权、人工审批和中断语义完全由事件引擎之外的部分处理。
结果处理遵循相同的边界。projectResult() 可以将小型值保留为内联内容,也可以将其替换为由宿主拥有的引用。EI 不会因此变成 blob 存储、制品系统或模型上下文管理器。
该软件包不包含诸如 if (runtime === "muffin")、"artemis"、"openai" 或 "anthropic" 这样的具名运行时分派逻辑。新增运行时只需在 EI 核心之外编写宿主边界代码。
当运行时需要直接控制时,仍可使用较低层级的宿主 API:
只需传入一次 harness 级别的 MCP 注册表,而不是逐个传入 MCP:
import {
createEventIntelligenceHost,
createMcpRegistryAdapter,
} from 'mcp-event-intelligence/host';
const ei = await createEventIntelligenceHost({
dataDir: './data',
mcpRegistry: createMcpRegistryAdapter({
listConnections: () => host.mcp.listConnections(),
subscribe: (refresh) => host.mcp.onConnectionsChanged(refresh),
}),
wake: async (packet, activation) => {
const receipt = await host.resume(packet.target, {
packet,
activation,
});
return { runtimeReceiptId: receipt.id };
},
});
Event Intelligence 会自动枚举宿主注册表。GitHub、Gmail、私有/公司 MCP 以及未来的连接,无需在 EI 中再次配置。仅提供工具的 MCP 仍可供 Agent 使用,并会被 Events 层忽略;支持 Events 的 MCP 则会自动接入。
面向 Agent 的触发流程
Agent 不需要第二种 DSL 或特定于模型的规划器。公开的编写方式如下:
event_sources_list
↓
trigger_language_describe (only when grammar discovery is useful)
↓
trigger_plan
↓
Pattern AST definition
↓
trigger_create
planTrigger() 是确定性的:它会解析实时事件源,填充 serverId,根据公布的架构验证订阅参数以及谓词/模式字段路径,并返回规范触发器定义和所需的连接 ID。
对于简单条件,省略 pattern 会根据声明的事件生成一个 allOf Pattern:
const plan = await ei.planTrigger({
events: [{
id: 'invoice',
event: 'erpnext.sales_invoice.submitted',
where: [
{ path: 'grand_total', op: 'gt', value: 10000 },
],
}],
withinMs: 60 * 60 * 1000,
target: {
runtime: 'agent',
kind: 'conversation',
id: 'chat-42',
},
continuation: {
instruction:
'Check the submitted invoice for anomalies and report back in this conversation.',
},
});
对于高级 CEP,可直接编写相同的规范 pattern:
const language = ei.describeTriggerLanguage({ category: 'pattern' });
const plan = await ei.planTrigger({
events: [
{ id: 'order', event: 'erpnext.sales_order.created' },
{ id: 'failure', event: 'payments.failed' },
{ id: 'ticket', event: 'support.ticket.created' },
],
withinMs: 30 * 60 * 1000,
pattern: {
version: '2',
partitionBy: [{
key: 'customer',
fields: [
{ ref: 'order', path: 'customer' },
{ ref: 'failure', path: 'customer' },
{ ref: 'ticket', path: 'customer' },
],
}],
root: {
kind: 'aggregate',
function: 'sum',
ref: 'order',
path: 'grand_total',
op: 'gte',
value: 10000,
child: {
kind: 'sequence',
contiguity: 'followedBy',
children: [
{ kind: 'event', ref: 'order' },
{
kind: 'repeat',
child: { kind: 'event', ref: 'failure' },
min: 2,
max: 5,
mode: 'greedy',
},
{
kind: 'optional',
child: { kind: 'event', ref: 'ticket' },
mode: 'greedy',
},
],
},
},
},
target: {
runtime: 'agent',
kind: 'conversation',
id: 'chat-42',
},
continuation: {
instruction: 'Review this customer payment-risk pattern.',
},
});
Pattern AST 是唯一规范的触发器执行模型。它涵盖嵌套布尔和序列模式、连续性、重复/可选量词、有界否定模式、日历/缺失/防抖/速率/去重语义、事件时间窗口、跨事件比较和算术、聚合、状态转换、分区、匹配选择策略以及确定性的派生度量。
线协议架构目前将此语法标识为 version: "2";这是架构版本,而非第二种执行架构。
运行时以确定性优先。只有在结构化数据无法可靠表达条件时,才可使用一等 semantic 节点。它与供应商无关,并会调用配置的 SemanticEvaluator;如果存在 TYPESAFE_API_KEY,则可选用随附的 TypeSafe Jev 适配器。语义调用是显式的、有界的、带超时的、可缓存的,并会记录审计日志;常规 CEP 执行无需模型 API。
持久化的 continuation 回答的问题与触发器条件不同:未来条件成立后,Agent 应该做什么? 触发器也可以设置 conditionOnly: true,只持久化条件状态,不设置运行时目标或后续操作。
线协议唤醒内容刻意保持精简,且只包含引用。嵌入式主机还会将 Activation Envelope 作为第二个唤醒参数传递。之后也可以重建相同的信封:
const activation = await ei.hydrateWake(wakeId);
信封包含配置的后续操作、规范 Pattern、匹配状态和匹配证据。事件负载会标记为不可信的外部信号,并且仅会根据触发器的 continuation.contextPolicy 纳入。
共享主机、租户隔离和存储
一个 EI 主机可服务多个租户/工作区,而不会共享触发器状态。为每个由主机管理的 MCP 连接设置 scopeId,并且只向面向租户的代码提供相应的限定范围视图:
const tenant = await ei.scope('tenant-acme');
await tenant.triggerControl.createTrigger({
definition,
connectionIds: ['acme-erp'],
actor,
owner,
});
const acmeConnections = await tenant.mcpStatus();
默认参考存储会将非默认范围物理隔离在单独的持久化存储分区中。因此,触发器 ID、匹配 ID、游标、事件源、截止时间、派生事件和唤醒传递状态都会在各自范围内解析,而非事后从全局结果中过滤。根主机对象是受信任的运维/控制平面能力;租户代码应接收限定范围的视图。
存储可注入:
const ei = await createEventIntelligenceHost({
store: myEventIntelligenceStore,
mcpRegistry,
wake,
});
PersistentEventStore 仍是零依赖的单进程默认存储。对于横向扩展的工作进程,请使用可选的 PostgreSQL 适配器:
import pg from 'pg';
import {
PostgresEventStore,
} from 'mcp-event-intelligence/storage/postgres';
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
const store = new PostgresEventStore({
pool,
dispatchPoolIdentity: pool, // required for fenced host dispatch
ownsPool: true,
});
运行共享部署时,请设置 EVENT_INTELLIGENCE_REQUIRE_SHARED_STORE=true 和全局唯一的 EVENT_INTELLIGENCE_WORKER_ID。PostgreSQL 路径提供由数据库权威控制的范围隔离、分布式原子唤醒认领以及触发器/版本/分区租约,并支持共享的重试/死信状态和崩溃恢复状态。随附的 JSONL 存储仅达到参考实现级别,不会假装提供多副本安全保障。请参阅存储和共享状态。
向 MCP 提供方添加事件
提供方可以公开实验性的 Events 边界,而无需重新实现通用 JSON-RPC 粘合逻辑:
import { createMcpEventsProvider } from 'mcp-event-intelligence/provider';
const events = createMcpEventsProvider({
events: [
{
descriptor: {
name: 'erpnext.sales_invoice.submitted',
description: 'A submitted Sales Invoice was observed.',
delivery: ['poll'],
inputSchema: { type: 'object' },
payloadSchema: {
type: 'object',
required: ['name', 'company', 'grand_total'],
properties: {
name: { type: 'string' },
company: { type: 'string' },
grand_total: { type: 'number' },
},
},
},
poll: async ({ cursor, maxEvents, context }) => {
return providerRuntime.pollInvoices({ cursor, maxEvents, context });
},
},
],
});
该软件包负责当前草案中的 Events 扩展标识符和设置、events/list、events/poll、通用验证及响应格式。嵌入式 MCP 服务通过 capabilities.extensions["io.modelcontextprotocol/events"] 声明支持;提供方负责定义领域事件、身份验证、数据查询、发生 ID 和不透明游标语义。
此适配器跟踪当前的实验性 MCP Events 草案,并不声称符合最终定稿的 MCP Events 标准。截至 2026-09-25,v0.4 兼容性快照遵循 experimental-ext-triggers-events PR #7 中的 io.modelcontextprotocol/events 扩展协商方向,以及 conformance PR #521 中验证的发现和轮询协议。
此外还导出了一个符合 ERPNext 风格的提供方工厂:
import {
createErpNextEventsProvider,
} from 'mcp-event-intelligence/provider/erpnext';
const events = createErpNextEventsProvider({
pollSalesInvoices: ({ cursor, maxEvents }) =>
erp.pollSubmittedInvoices({ cursor, maxEvents }),
pollSalesOrders: ({ cursor, maxEvents }) =>
erp.pollCreatedSalesOrders({ cursor, maxEvents }),
});
此辅助工具负责 erpnext.sales_invoice.submitted 和
erpnext.sales_order.created 的 MCP Events 描述符、架构和响应验证。它
不是负责凭据管理的 ERPNext 连接器:主机/提供方必须提供实际的数据访问函数。这种
分离是有意为之,目的是避免 Event
Intelligence 重复实现提供方身份验证。
该抽象可用于真实 ERP 数据层的生产验证,位于
sarooo17/world-capability-mcp:其中的 ERP Events 实现使用
createMcpEventsProvider 执行经过身份验证的 ERPNext/Frappe 记录查询,并支持
租户/公司筛选、不透明且可安全重放的游标、分页/hasMore、
时区规范化和确定性发生 ID。因此,应将此软件包中的本地工厂视为类型化便捷 API,
而不是生产环境中的 ERP 连接器本身。
v0.7 的实现内容
主机管理的事件源
- 从主机现有的 MCP 注册表自动发现;
- 复用已连接的 MCP 客户端,无需重复提供凭据;
- 通过
capabilities.extensions["io.modelcontextprotocol/events"]直接协商 MCP 扩展; - 分页发现
events/list; - 基于
(connection, event name, arguments)确保 EventSubscription 标识持久稳定; - 使用服务端指定的
nextPollMs、可为空的游标和有界页面排空来执行events/poll; - 主机管理的推送和 webhook 投递适配器,将事件送入同一 EventOccurrence 流水线;
- 持久化不透明游标和每个订阅的投递状态;
- 共享的上游订阅向使用相同
(connection, event, arguments)元组的每个活跃触发器分发事件; - 为共享主机按范围隔离来源/游标;
- 每个连接单飞轮询,并对
hasMore批次进行有界排空; - 自动注册事件源;
- 动态挂载/卸载主机 MCP 客户端;
- GitHub webhook 等提供方原生兼容适配器。
复合触发器和时间触发器
allOf、anyOf、sequence、count;- 确定性的同值关联;
- 可选的语义关联;
absence、not、unless、after、until;debounce、threshold、rate、distinct;- 支持 IANA 时区的日历感知条件;
- 即使没有新的提供方事件到达,持久化截止时间仍会继续生效。
事件源与订阅
events/list 用于发现 EventSource 描述符。持久化的 EventSubscription 是独立的运行时对象,由主机连接、事件名称和规范化订阅 arguments 标识。每个订阅都独立维护自己的游标和投递状态。
这样一来,MCP 侧的筛选就与 Event Intelligence 条件分开了:arguments 会根据提供方的 inputSchema 进行验证;触发器的 where 谓词则由 EI 根据已投递的载荷进行评估。因此,两个触发器可以使用不同的参数订阅同一个事件名称,而不共享游标。
轮询、推送和 webhook 仅被视为投递机制。三者都会先规范化并进入相同的 EventOccurrence 摄取路径,然后才进行关联、时序推理、派生事件或唤醒逻辑。
由 Agent 编写的续接
- 事件源发现;
- 便于 Agent 使用的确定性触发器规划/编译;
- 根据各事件源的
inputSchema验证 MCP 订阅arguments,并使其与 EI 载荷谓词保持区分; - 结构化谓词,包括
eq、neq、contains、startsWith、endsWith、regex、in、notIn、between、exists、isNull、type、gt、gte、lt、lte; - 将持久化续接契约与触发条件分开;
- 使用匹配的事件证据填充 Activation Envelope;
- 嵌入式唤醒回调接收
(packet, activation); - 根据真实事件源架构和已公布字段进行确定性验证;
- 需经审批的持久化变更;
- 一次性执行、冷却时间、最大触发次数、到期时间、租约、更新和删除。
派生事件与组合
触发器可以发出不可变的高层事件,而不是唤醒 Agent:
pr.merged + deploy.succeeded
↓
release.ready@1
+
manager.approved
↓
rollout.allowed@1
↓
runtime wake
派生事件仅通过引用保留其直接父事件的血缘关系,以及扁平化后的根证据。
版本化契约
派生事件名称是版本化契约,例如 release.ready@1。
- 首个生产者建立规范架构;
- 兼容的生产者可以加入同一契约版本;
- 不兼容的架构会在触发器持久化前失败;
- 多个版本可以共存;
- 无法确定对应版本的非版本化使用方会被拒绝;
- 每次事件发生都会携带架构指纹。
主机唤醒或回调唤醒
嵌入式运行框架可以提供一个进程内唤醒分发器,根据 target.runtime、target.kind 和 target.id 进行路由;也可以使用运行时专属处理程序作为较低层级的选项。独立部署则可以改用带签名的 HMAC 回调。两种路径都会返回稳定的 runtimeReceiptId。
运行时投递具有持久性:稳定的唤醒 ID 会对应一条持久化投递记录,工作进程通过租约取得该记录,临时故障会以有界指数退避策略重试,过期的认领可在重启后恢复,只有重试次数耗尽后才会进入死信队列。这样可以避免共享原子存储的两个工作进程同时有意认领同一条投递记录。不过,运行时仍应将稳定的唤醒 ID 视为幂等键,因为如果接收方不配合,任何系统都无法保证任意外部副作用实现事务性的恰好一次执行。
为何存在
MCP Events 关注的是事件传输/订阅边界。Event Intelligence 探索的是传输层之上的层面:
- Agent 如何声明未来条件;
- Agent 休眠时,多事件状态如何持续保存;
- 缺失或时间如何转化为事件;
- 如何在不调用模型的情况下推导更高层次的事实;
- 如何安全地组合这些事实;
- 在经过验证的场景中,主机如何有效地恢复 Agent。
本项目并非要取代 MCP Events,也不声称自己是官方 MCP 扩展。
AI 和 API 密钥
Event Intelligence 只有一个可选的 AI 边界:显式语义评估。
- Pattern AST 将与供应商无关的
semantic节点作为唯一的语义条件形式。 - 当触发器显式请求语义评估时,
TYPESAFE_API_KEY会启用捆绑的 TypeSafe Jev 评估器。 - 嵌入式宿主也可以注入兼容的
semanticEvaluator。 - 确定性谓词、模式、窗口、聚合、状态变更、截止时间和派生度量均不需要 AI 评估器。
- 不包含捆绑的 OpenAI 规划器,也不依赖 OpenAI API。
Agent/harness 已负责自然语言推理。它可以使用 trigger_plan / planTrigger(),根据已发现的源架构以确定性方式编译常见请求,也可以针对高级用例直接提交规范触发器定义。确定性关联、时序逻辑、持久化、派生事件和唤醒投递均不需要模型 API。
全系统验收
v0.6 验收套件会验证:
- 宿主拥有的 MCP 客户端 → 扩展发现 → 持久化订阅 → 轮询/推送/Webhook 事件 → 复合匹配 → 进程内唤醒;
- 与供应商无关的事件 → 复合匹配 → 派生事件 → 派生组合 → 已签名的运行时唤醒;
- 合约架构演进和歧义拒绝;
- 仅 refs 的根来源信息;
- 重放时不会重复产生派生事件或唤醒;
- 时间截止时间待处理时关闭进程;
- 截止时间过后在同一数据存储上重启;
- 无需新的供应商事件即可恢复唤醒;
- 进程重启后的重试状态恢复,以及基于租约的并发工作进程互斥;
- 共享宿主中的租户隔离,即使不同作用域中的触发器 ID 相同;
- 有界/单飞供应商轮询;
- 使用 ERPNext 形状的发票/订单事件进行供应商泛化覆盖;
- 哈希链审计验证。
另有一项独立的实时回归测试,验证了真实 GitHub Webhook 能够进入 MCP EventOccurrence / 复合扇入路径。
参考/调试服务
HTTP 服务仍适用于本地开发、一致性测试和供应商原生回归测试。它不是主要集成模式,也不会取代上述由嵌入式宿主拥有的包集成路径。
要求
- Node.js 22+
- 参考设置无需外部数据库
git clone https://github.com/sarooo17/event-intelligence.git
cd event-intelligence
npm ci
npm run check
export SERVICE_AUTH_TOKEN="$(openssl rand -hex 32)"
npm start
然后:
curl http://127.0.0.1:3000/readyz
独立服务支持手动/供应商原生事件接入。它不拥有任意 MCP 连接;由宿主拥有的 MCP 复用应通过上述包集成实现。
Docker
docker build -t mcp-event-intelligence:0.6.1 .
docker run --rm \
-p 3000:3000 \
-v mcp-event-intelligence-data:/data \
-e SERVICE_AUTH_TOKEN="$(openssl rand -hex 32)" \
mcp-event-intelligence:0.6.1
可选的 MCP 控制平面
该包还通过官方 TypeScript SDK v2 提供标准的 MCP stdio 控制平面:
npx mcp-event-intelligence mcp
默认提供读取/非变更类工具,包括 event_sources_list、trigger_plan、检查、模拟、wake_hydrate、合约和运行时状态。trigger_create 接受原始规范定义,也接受相同的 Agent 友好型计划格式;EI 会先编译后者,再应用常规变更控制。
只有当操作员显式启用 MCP_WRITE_ENABLED=true 时,才会注册持久化触发器变更;每项变更仍需提供 confirmationId。MCP 服务是一个控制平面适配器;它不是宿主必须通过其重新连接其他 MCP 服务的网关。
请参阅 docs/QUICKSTART.md 和 docs/MCP-REGISTRY.md。
配置
独立版/核心环境变量:
| 变量 | 必需 | 用途 |
|---|---|---|
SERVICE_AUTH_TOKEN | 受保护的 HTTP API 必需 | 控制平面端点的 bearer 令牌 |
DATA_DIR | 否 | 持久化 JSONL 目录,默认为 ./data |
PORT | 否 | HTTP 端口,默认为 3000 |
ENVIRONMENT_ID | 否 | 环境边界 |
RUNTIME_WAKE_TARGETS_JSON | 否 | 已签名的独立版运行时回调 |
GITHUB_WEBHOOK_SECRET | 否 | 验证 GitHub webhook 入站请求 |
TYPESAFE_API_KEY | 否 | 内置的 TypeSafe Jev 语义评估器 |
WAKE_DELIVERY_MAX_ATTEMPTS | 否 | 唤醒投递的最大尝试次数,默认为 5 |
WAKE_DELIVERY_LEASE_MS | 否 | 认领租约时长,默认为 30000 |
WAKE_RETRY_BASE_DELAY_MS | 否 | 首次重试延迟,默认为 1000 |
WAKE_RETRY_MAX_DELAY_MS | 否 | 重试退避上限,默认为 60000 |
WAKE_RETRY_TICK_MS | 否 | 重试调度器间隔,默认为 1000 |
嵌入式宿主会传入一个 MCP 注册表适配器。Event Intelligence 从该注册表中发现已连接的客户端;提供方的 MCP 连接设置不会在 EI 内重复配置。
架构
详细的执行模型、时钟、生命周期、持久化和信任边界见 docs/ARCHITECTURE.md。
重要语义
事件时间与处理时间
普通事件窗口使用事件的 occurredAt;MCP 入站请求也会在可用时保留宿主的 receivedAt。投递顺序不决定事件顺序。
乱序事件会与兼容的事件时间窗口进行匹配。只有在完整事件时间跨度仍符合 withinMs 的情况下,迟到事件才可能将部分匹配重新锚定到更早的 occurredAt;否则,它会启动单独的部分窗口,无法构成虚假的序列。
触发器可以设置 eventTime.allowedLatenessMs(默认为 0)。EI 会为每个触发器/关联流维护事件时间水位线:只有当旧部分窗口的过期时间晚于 maxObservedEventTime - allowedLatenessMs 时,才会保留这些窗口。早于水位线的事件仍可完成兼容且尚未过期的部分匹配,但无法创建新的过期窗口。
缺失事件/期限的推进使用 Event Intelligence 处理时间。这种区分是明确的,并经过测试。
实际上的运行时至多激活一次
该实现不声称能够实现理论上的分布式精确一次投递。
它使用稳定的唤醒 ID、持久化的投递状态、原子认领租约、有界重试、运行时回执和重放处理,在经过验证的参考场景中实现实际上的运行时至多激活一次。
派生事件与当前状态
派生事件描述的是历史中的某个时刻变成了什么状态。
Event Intelligence 有意不实现可变的当前状态/事实数据库。
安全
请阅读 SECURITY.md 和 docs/SECURITY-MODEL.md。
在嵌入式模式下,宿主负责保留 MCP 授权和凭据;Event Intelligence 只会发现宿主提供的 MCP 注册表中公开的客户端对象。面向租户的调用方只能获得 host.scope(scopeId)。参考 JSONL 存储按范围分区,且仅支持单进程;分布式自定义存储必须保留范围隔离和原子唤醒认领能力。
MCP 兼容性状态
MCP 边界分为两类:
- 事件入口:由宿主拥有、已连接的 MCP 客户端(可公开实验性的
io.modelcontextprotocol/events扩展),以及原生适配器;参考提供方适配器原生支持轮询,而推送/Webhook 接收器仍由宿主拥有,作为投递适配器; - 控制平面:基于官方 TypeScript SDK v2 构建的可选标准 MCP stdio 服务,目标协议修订版本为 2026-07-28。
注册表身份:
io.github.sarooo17/event-intelligence
CI 中使用官方 mcp-publisher validate 命令验证 server.json。MCP Events 本身仍处于实验阶段,并可能随着 Triggers & Events 工作的演进而变化。
项目状态
v0.6.x 参考实现/实验性。
该架构已实现并完成端到端验证。存储现可注入且具备作用域,而内置 JSONL 后端仍是单进程参考实现。剩余工作主要包括生产级数据库适配器/高可用性验证、规模基准测试及上游反馈。
示例
请参阅发布门控示例,了解一个组合式的未来条件流程,其中使用了持久化时间、派生事件和定向唤醒。
贡献
请参阅 CONTRIBUTING.md。
我们尤其欢迎围绕宿主适配器、MCP Events 兼容性、时间语义、生产级持久化、安全审查和可复现的提供方集成所做的贡献。
许可证
Apache License 2.0。请参阅 LICENSE。
免责声明
这是一个独立的开源项目。它不是官方的 Model Context Protocol 规范,也未与 MCP 维护者建立关联,亦未获得其认可。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。