mcp-event-intelligence 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.0] - 2026-10-05
4
+
5
+ ### Runtime-neutral observability
6
+
7
+ - add the public `mcp-event-intelligence/observability` surface for structured operational `ei.*` events;
8
+ - cover lifecycle, MCP/event-source health, trigger mutations, matches, wake delivery, retry/dead-letter and scheduler failures;
9
+ - keep observability best-effort and non-blocking so slow or failing telemetry sinks cannot change Event Intelligence execution semantics;
10
+ - defensively exclude event payloads, evidence, continuation instructions and credential-like metadata from operational events;
11
+ - keep audit and observability separate: the audit chain remains durable and tamper-evident while observability stays host-owned and ephemeral.
12
+
13
+ ### Host conformance
14
+
15
+ - add the public `mcp-event-intelligence/conformance` runner with a six-method runtime-neutral host adapter contract;
16
+ - emit machine-readable `event-intelligence.host-conformance.v1` reports;
17
+ - verify threshold/one-shot behavior, replay deduplication on persistent triggers, restart durability, bounded `maxFirings`, required observability and payload non-leakage;
18
+ - add a real embedded reference host and `npm run conformance:host`;
19
+ - document the integration contract without introducing Muffin, Artemis, OpenAI, Anthropic or logger-vendor adapters into EI core.
20
+
21
+
22
+ ## [0.8.2] - 2026-10-05
23
+
24
+ ### Embedded integration
25
+
26
+ - add deterministic namespaced activation receipts without ambiguous component encoding;
27
+ - allow static host-owned event connection iterables directly, snapshotting one-shot iterators safely;
28
+ - add normalized event-source diagnostics including registry attach failures and raw refresh outcomes;
29
+ - add generic tool/lifecycle binding for embedded runtime integrations;
30
+ - add host-owned error projection with canonical EI fallback semantics;
31
+ - document the reusable runtime-neutral host glue and keep named-runtime adapters out of EI core.
32
+
33
+ ### Fixed
34
+
35
+ - prevent one-shot event iterables from disappearing on the second registry refresh;
36
+ - preserve failed source attachment information in diagnostics instead of reporting a clean empty setup;
37
+ - prevent receipt namespace/wake-id tuple collisions.
38
+
3
39
  ## [0.8.1] - 2026-10-05
4
40
 
5
41
  ### Fixed
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![CI](https://github.com/sarooo17/event-intelligence/actions/workflows/ci.yml/badge.svg)](https://github.com/sarooo17/event-intelligence/actions/workflows/ci.yml)
6
6
  [![npm](https://img.shields.io/npm/v/mcp-event-intelligence.svg)](https://www.npmjs.com/package/mcp-event-intelligence)
7
- [![MCP Registry](https://img.shields.io/badge/MCP%20Registry-v0.8.1-5b5bd6)](https://registry.modelcontextprotocol.io/?q=io.github.sarooo17%2Fevent-intelligence)
7
+ [![MCP Registry](https://img.shields.io/badge/MCP%20Registry-v0.9.0-5b5bd6)](https://registry.modelcontextprotocol.io/?q=io.github.sarooo17%2Fevent-intelligence)
8
8
  [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
9
9
 
10
10
  MCP Event Intelligence is an experimental event runtime for agents that need to react to **future conditions over multiple event sources** without keeping an LLM or agent loop alive.
@@ -0,0 +1,59 @@
1
+ # Host conformance
2
+
3
+ Event Intelligence ships two separate conformance layers.
4
+
5
+ ## Runtime contract conformance
6
+
7
+ The existing fixtures and regression suite validate EI's own protocol, Pattern,
8
+ storage, audit and MCP Events boundaries.
9
+
10
+ A conforming EI adapter must preserve canonical schemas, stable event identity,
11
+ source evidence, lifecycle correctness, replay deduplication, hash-linked audit
12
+ history and the rule that external event data is evidence rather than
13
+ authorization.
14
+
15
+ Run the full internal suite with:
16
+
17
+ ```bash
18
+ npm run check
19
+ ```
20
+
21
+ ## Embedded host conformance
22
+
23
+ The public `mcp-event-intelligence/conformance` entry point validates an
24
+ embedding runtime without teaching EI about that runtime.
25
+
26
+ Implement `createHarness({ observability })` and return six operations:
27
+
28
+ - `createTrigger()`
29
+ - `emitEvent()`
30
+ - `deliveries()`
31
+ - `restart()`
32
+ - `inspectTrigger()`
33
+ - `close()`
34
+
35
+ Then run:
36
+
37
+ ```js
38
+ import { runHostConformance } from 'mcp-event-intelligence/conformance';
39
+
40
+ const report = await runHostConformance(myRuntimeAdapter, {
41
+ throwOnFailure: true,
42
+ });
43
+ ```
44
+
45
+ Core v1 checks cover one-shot delivery, replay deduplication, restart
46
+ persistence, bounded `maxFirings`, and required structured observability
47
+ (`ei.trigger.created`, `ei.match.matched`, `ei.wake.delivered`).
48
+
49
+ The scenarios are intentionally isolated and synthetic. Do not point the
50
+ conformance harness at production continuations or production event sources.
51
+
52
+ The repository reference adapter can be run with:
53
+
54
+ ```bash
55
+ npm run conformance:host
56
+ ```
57
+
58
+ The MCP Events draft remains upstream and experimental. These checks certify
59
+ Event Intelligence host behavior, not official MCP conformance.
@@ -0,0 +1,70 @@
1
+ {
2
+ "protocolVersion": "0.2.0",
3
+ "schemaVersion": "trigger.v0.2",
4
+ "triggerId": "issue-and-pippo-mail",
5
+ "version": "1",
6
+ "description": "Wake only when an issue exists and Pippo sends a related email.",
7
+ "clauses": [
8
+ {
9
+ "id": "issue",
10
+ "event": "github.issue.opened",
11
+ "where": [
12
+ {
13
+ "path": "repository",
14
+ "op": "eq",
15
+ "value": "acme/app"
16
+ }
17
+ ]
18
+ },
19
+ {
20
+ "id": "mail",
21
+ "event": "email.received",
22
+ "where": [
23
+ {
24
+ "path": "from",
25
+ "op": "eq",
26
+ "value": "pippo@example.com"
27
+ }
28
+ ]
29
+ }
30
+ ],
31
+ "pattern": {
32
+ "version": "2",
33
+ "root": {
34
+ "kind": "semantic",
35
+ "id": "same-problem",
36
+ "refs": [
37
+ "issue",
38
+ "mail"
39
+ ],
40
+ "instruction": "The email concerns the GitHub issue.",
41
+ "input": [
42
+ "issue.title",
43
+ "mail.subject",
44
+ "mail.bodyPreview"
45
+ ],
46
+ "matchThreshold": 0.8,
47
+ "rejectThreshold": 0.2,
48
+ "uncertain": "escalate",
49
+ "child": {
50
+ "kind": "allOf",
51
+ "children": [
52
+ {
53
+ "kind": "event",
54
+ "ref": "issue"
55
+ },
56
+ {
57
+ "kind": "event",
58
+ "ref": "mail"
59
+ }
60
+ ]
61
+ }
62
+ }
63
+ },
64
+ "withinMs": 86400000,
65
+ "target": {
66
+ "runtime": "runtime-probe",
67
+ "kind": "task",
68
+ "id": "issue-report"
69
+ }
70
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "protocol": "mcp-event-intelligence",
3
+ "protocolVersion": "0.1.0",
4
+ "schemaVersion": "ei.v0.1",
5
+ "traceId": "trace_fixture_001",
6
+ "environmentId": "env_test",
7
+ "subscriptionId": "sub_fixture",
8
+ "sourceEventId": "evt_fixture",
9
+ "observedAt": "2026-09-18T06:30:00.000Z",
10
+ "source": {
11
+ "serverId": "github-mcp",
12
+ "transport": "webhook",
13
+ "provider": "github",
14
+ "cursor": null
15
+ },
16
+ "target": {
17
+ "runtime": "openai-agents",
18
+ "kind": "session",
19
+ "id": "session_fixture"
20
+ },
21
+ "event": {
22
+ "name": "issue.opened",
23
+ "occurredAt": "2026-09-18T06:29:59.000Z",
24
+ "payloadHash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
25
+ }
26
+ }
@@ -0,0 +1,145 @@
1
+ import { mkdtemp, rm } from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { createEventIntelligenceHost } from '../scripts/host-integration.mjs';
5
+ import { runHostConformance } from '../scripts/host-conformance.mjs';
6
+
7
+ export const referenceHostAdapter = {
8
+ name: 'event-intelligence-reference-host',
9
+
10
+ async createHarness({ observability }) {
11
+ const dataDir = await mkdtemp(path.join(os.tmpdir(), 'ei-host-conformance-'));
12
+ const externalDeliveries = [];
13
+ let host = null;
14
+
15
+ const start = async () => {
16
+ host = await createEventIntelligenceHost({
17
+ dataDir,
18
+ observability,
19
+ env: {
20
+ TYPESAFE_API_KEY: '',
21
+ RUNTIME_WAKE_TARGETS_JSON: '{}',
22
+ TEMPORAL_TICK_MS: '100000',
23
+ WAKE_RETRY_TICK_MS: '100000',
24
+ },
25
+ wake: async (packet, activation) => {
26
+ const runtimeReceiptId = `conformance:${packet.wake_id}`;
27
+ externalDeliveries.push({
28
+ triggerId: activation.trigger.triggerId,
29
+ wakeId: packet.wake_id,
30
+ runtimeReceiptId,
31
+ });
32
+ return { runtimeReceiptId };
33
+ },
34
+ });
35
+ };
36
+
37
+ await start();
38
+
39
+ await host.triggerControl.registerEventSource({
40
+ sourceId: 'conformance:value-changed',
41
+ connectionId: 'conformance-connection',
42
+ serverId: 'conformance',
43
+ eventName: 'conformance.value.changed',
44
+ delivery: ['poll'],
45
+ payloadSchema: {
46
+ type: 'object',
47
+ additionalProperties: false,
48
+ required: ['value'],
49
+ properties: {
50
+ value: { type: 'number' },
51
+ secretProbe: { type: 'string' },
52
+ },
53
+ },
54
+ enabled: true,
55
+ }, {
56
+ type: 'system',
57
+ principal_id: 'host-conformance',
58
+ });
59
+
60
+ return {
61
+ async createTrigger({
62
+ triggerId,
63
+ threshold,
64
+ oneShot,
65
+ maxFirings,
66
+ }) {
67
+ const planned = await host.planTrigger({
68
+ triggerId,
69
+ events: [{
70
+ id: 'value',
71
+ event: 'conformance.value.changed',
72
+ serverId: 'conformance',
73
+ where: [{
74
+ path: 'value',
75
+ op: 'gt',
76
+ value: threshold,
77
+ }],
78
+ }],
79
+ lifecycle: {
80
+ oneShot,
81
+ ...(maxFirings === undefined ? {} : { maxFirings }),
82
+ },
83
+ target: {
84
+ runtime: 'conformance-host',
85
+ kind: 'task',
86
+ id: triggerId,
87
+ },
88
+ continuation: {
89
+ instruction: 'Continue the isolated Event Intelligence conformance scenario.',
90
+ },
91
+ });
92
+
93
+ await host.triggerControl.createTrigger({
94
+ definition: planned.definition,
95
+ connectionIds: planned.connectionIds,
96
+ actor: { type: 'user', principal_id: 'host-conformance-user' },
97
+ owner: { type: 'user', principal_id: 'host-conformance-user' },
98
+ });
99
+ },
100
+
101
+ async emitEvent({ eventId, value, secretProbe }) {
102
+ await host.runtime.compositeEventConsumer.ingestCorrelatable({
103
+ traceId: `conformance:${eventId}`,
104
+ sourceEventId: eventId,
105
+ name: 'conformance.value.changed',
106
+ serverId: 'conformance',
107
+ provider: 'conformance',
108
+ occurredAt: new Date().toISOString(),
109
+ data: {
110
+ value,
111
+ ...(secretProbe ? { secretProbe } : {}),
112
+ },
113
+ });
114
+ },
115
+
116
+ deliveries() {
117
+ return [...externalDeliveries];
118
+ },
119
+
120
+ async restart() {
121
+ await host.close();
122
+ await start();
123
+ },
124
+
125
+ async inspectTrigger(triggerId) {
126
+ const rows = await host.triggerControl.listTriggers();
127
+ const entry = rows.find(
128
+ (candidate) => candidate.definition.triggerId === triggerId,
129
+ );
130
+ return entry?.state ?? null;
131
+ },
132
+
133
+ async close() {
134
+ await host?.close();
135
+ await rm(dataDir, { recursive: true, force: true });
136
+ },
137
+ };
138
+ },
139
+ };
140
+
141
+ if (import.meta.url === `file://${process.argv[1]}`) {
142
+ const report = await runHostConformance(referenceHostAdapter);
143
+ console.log(JSON.stringify(report, null, 2));
144
+ if (!report.passed) process.exitCode = 1;
145
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-event-intelligence",
3
- "version": "0.8.1",
3
+ "version": "0.9.0",
4
4
  "description": "MCP-native complex event processing for durable agent workflows: event-time patterns, semantic predicates, derived events, and targeted wakeups.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -26,6 +26,14 @@
26
26
  "./embedded": {
27
27
  "types": "./scripts/embedded-host-kit.d.mts",
28
28
  "import": "./scripts/embedded-host-kit.mjs"
29
+ },
30
+ "./observability": {
31
+ "types": "./scripts/lib/observability.d.mts",
32
+ "import": "./scripts/lib/observability.mjs"
33
+ },
34
+ "./conformance": {
35
+ "types": "./scripts/host-conformance.d.mts",
36
+ "import": "./scripts/host-conformance.mjs"
29
37
  }
30
38
  },
31
39
  "bin": {
@@ -47,7 +55,10 @@
47
55
  "scripts/host-integration.d.mts",
48
56
  "scripts/run-tests.mjs",
49
57
  "scripts/embedded-host-kit.mjs",
50
- "scripts/embedded-host-kit.d.mts"
58
+ "scripts/embedded-host-kit.d.mts",
59
+ "scripts/host-conformance.mjs",
60
+ "scripts/host-conformance.d.mts",
61
+ "conformance/"
51
62
  ],
52
63
  "scripts": {
53
64
  "build": "tsc -p tsconfig.json",
@@ -64,7 +75,8 @@
64
75
  "conformance:pattern-v2": "npm run build && node scripts/evidence/pattern-v2-conformance.mjs",
65
76
  "bench:pattern-v2": "npm run build && node scripts/evidence/pattern-v2-benchmark.mjs --profile quick",
66
77
  "evidence:pattern-v2": "npm run build && node scripts/evidence/pattern-v2-conformance.mjs && node scripts/evidence/pattern-v2-benchmark.mjs --profile quick",
67
- "prepare": "npm run build"
78
+ "prepare": "npm run build",
79
+ "conformance:host": "npm run build && node conformance/reference-host.mjs"
68
80
  },
69
81
  "keywords": [
70
82
  "mcp",
@@ -134,6 +134,8 @@ export interface ActivationDispatcherOptions<Target = RuntimeTarget> {
134
134
  packet: Record<string, unknown>;
135
135
  activation: ActivationEnvelope;
136
136
  }) => string | Promise<string>;
137
+ /** Optional deterministic SHA-256 receipt namespace. Mutually exclusive with receiptId. */
138
+ receiptNamespace?: string;
137
139
  deliver(
138
140
  input: ActivationDeliveryInput<Target>,
139
141
  ): HostWakeReceipt | string | void | Promise<HostWakeReceipt | string | void>;
@@ -160,6 +162,27 @@ export interface PortableToolCatalog<RuntimeContext = unknown> {
160
162
  capabilities(): EventIntelligenceCapabilityMetadata[];
161
163
  }
162
164
 
165
+ export interface EventSourceDiagnostics {
166
+ readonly connections: number;
167
+ readonly eventsCapable: number;
168
+ readonly eventDefinitions: number;
169
+ readonly errors: number;
170
+ readonly statuses: readonly any[];
171
+ readonly refreshOutcomes: readonly any[];
172
+ }
173
+
174
+ export interface EmbeddedRuntimeBindOptions<
175
+ RuntimeContext = unknown,
176
+ HostTool = unknown,
177
+ > {
178
+ adapt(tool: PortableAgentTool<RuntimeContext>): HostTool;
179
+ register(
180
+ tool: HostTool,
181
+ portableTool: PortableAgentTool<RuntimeContext>,
182
+ ): void;
183
+ onClose?(close: () => Promise<void>): void;
184
+ }
185
+
163
186
  export interface EventIntelligenceAgentToolsOptions<RuntimeContext = unknown> {
164
187
  host: EventIntelligenceHost;
165
188
  resolveContext(
@@ -198,6 +221,19 @@ export interface EventIntelligenceAgentToolsOptions<RuntimeContext = unknown> {
198
221
  value: unknown;
199
222
  }): PortableProjectedResult | void | Promise<PortableProjectedResult | void>;
200
223
 
224
+ /**
225
+ * Optional host-owned projection for canonical EI failures. Returning null
226
+ * keeps the canonical error; projection failures also fall back to it.
227
+ */
228
+ projectError?(input: {
229
+ capability: EventIntelligenceCapabilityMetadata;
230
+ runtimeContext: RuntimeContext;
231
+ context?: EmbeddedToolContext;
232
+ phase: string;
233
+ error?: PortableToolResult['error'];
234
+ result: PortableToolResult;
235
+ }): PortableToolResult | void | Promise<PortableToolResult | void>;
236
+
201
237
  /**
202
238
  * @deprecated Compatibility only. New integrations should use control().
203
239
  */
@@ -249,6 +285,7 @@ export interface EmbeddedRuntimeTooling<RuntimeContext = unknown> {
249
285
  resolveContext: EventIntelligenceAgentToolsOptions<RuntimeContext>['resolveContext'];
250
286
  control: NonNullable<EventIntelligenceAgentToolsOptions<RuntimeContext>['control']>;
251
287
  projectResult?: EventIntelligenceAgentToolsOptions<RuntimeContext>['projectResult'];
288
+ projectError?: EventIntelligenceAgentToolsOptions<RuntimeContext>['projectError'];
252
289
  names?: {
253
290
  sources?: string;
254
291
  create?: string;
@@ -260,7 +297,10 @@ export interface EmbeddedRuntimeIntegrationOptions<RuntimeContext = unknown>
260
297
  EmbeddedEventIntelligenceOptions<RuntimeContext>,
261
298
  'mcpRegistry' | 'mcp' | 'agentTools'
262
299
  > {
263
- eventSources?: EventSourceRegistry | EventSourceRegistryOptions;
300
+ eventSources?:
301
+ | EventSourceRegistry
302
+ | EventSourceRegistryOptions
303
+ | Iterable<EventSourceConnection>;
264
304
  tooling?: EmbeddedRuntimeTooling<RuntimeContext>;
265
305
  }
266
306
 
@@ -270,8 +310,34 @@ export interface EmbeddedRuntimeIntegration<RuntimeContext = unknown>
270
310
  readonly toolCatalog: PortableToolCatalog<RuntimeContext>;
271
311
  readonly capabilities: readonly EventIntelligenceCapabilityMetadata[];
272
312
  readonly eventSources: EventSourceRegistry | null;
313
+ diagnostics(): Promise<EventSourceDiagnostics>;
314
+ bind<HostTool>(
315
+ options: EmbeddedRuntimeBindOptions<RuntimeContext, HostTool>,
316
+ ): readonly HostTool[];
273
317
  }
274
318
 
319
+ export function createDeterministicReceiptId(
320
+ namespace: string,
321
+ wakeId: string,
322
+ options?: { length?: number },
323
+ ): string;
324
+
325
+ export function summarizeEventSourceStatus(
326
+ statuses?: readonly any[],
327
+ refreshOutcomes?: readonly any[],
328
+ ): EventSourceDiagnostics;
329
+
330
+ export function bindEmbeddedRuntimeIntegration<
331
+ RuntimeContext = unknown,
332
+ HostTool = unknown,
333
+ >(
334
+ integration: Pick<
335
+ EmbeddedRuntimeIntegration<RuntimeContext>,
336
+ 'tools' | 'close'
337
+ >,
338
+ options: EmbeddedRuntimeBindOptions<RuntimeContext, HostTool>,
339
+ ): readonly HostTool[];
340
+
275
341
  export function createResultReference(
276
342
  input: PortableResultReference,
277
343
  ): PortableResultReference;