mcp-event-intelligence 0.2.0 → 0.2.1
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 +15 -0
- package/README.md +15 -3
- package/bin/mcp-event-intelligence.mjs +1 -1
- package/package.json +1 -1
- package/scripts/lib/local-event-intelligence-runtime.mjs +16 -6
- package/scripts/lib/mcp-events-client.mjs +11 -0
- package/scripts/lib/persistent-event-store.mjs +12 -0
- package/scripts/lib/temporal-deadline-scheduler.mjs +12 -2
- package/scripts/lib/wake-retry-scheduler.mjs +12 -2
- package/scripts/mcp-stdio-server.mjs +1 -1
- package/server.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable public changes are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.2.1] - 2026-09-20
|
|
6
|
+
|
|
7
|
+
Patch hardening for shutdown determinism and multi-tenant verification.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- host shutdown now drains in-flight MCP polling, temporal/wake schedulers and persistent JSONL writes before returning;
|
|
12
|
+
- prevents background writes from racing temporary-directory cleanup and causing intermittent `ENOTEMPTY` failures;
|
|
13
|
+
- scoped isolation regression coverage now includes event source discovery, MCP client state/cursors, occurrences, audit records and wake visibility.
|
|
14
|
+
|
|
15
|
+
### Clarified
|
|
16
|
+
|
|
17
|
+
- the exported ERPNext helper is a typed MCP Events provider factory, not a credential-owning ERP connector;
|
|
18
|
+
- the production authenticated ERPNext implementation remains in `world-capability-mcp`, where real data access, tenant/company filtering, pagination, cursors and timezone handling are implemented.
|
|
19
|
+
|
|
5
20
|
## [0.2.0] - 2026-09-20
|
|
6
21
|
|
|
7
22
|
Production-hardening release for shared Event Intelligence hosts.
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://github.com/sarooo17/event-intelligence/actions/workflows/ci.yml)
|
|
6
6
|
[](https://www.npmjs.com/package/mcp-event-intelligence)
|
|
7
|
-
[](https://registry.modelcontextprotocol.io/?q=io.github.sarooo17%2Fevent-intelligence)
|
|
8
8
|
[](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.
|
|
@@ -125,7 +125,7 @@ The package owns capability advertisement, `server/discover`, `events/list`, `ev
|
|
|
125
125
|
This adapter remains experimental compatibility work around MCP Events; it is not a claim of finalized MCP Events conformance.
|
|
126
126
|
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
An ERPNext-shaped **provider factory** is also exported:
|
|
129
129
|
|
|
130
130
|
```js
|
|
131
131
|
import {
|
|
@@ -140,7 +140,19 @@ const events = createErpNextEventsProvider({
|
|
|
140
140
|
});
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
This helper owns the MCP Events descriptors, schemas and response validation for
|
|
144
|
+
`erpnext.sales_invoice.submitted` and `erpnext.sales_order.created`. It is
|
|
145
|
+
**not** a credential-owning ERPNext connector: the host/provider must supply the
|
|
146
|
+
actual data-access functions. That separation is intentional so Event
|
|
147
|
+
Intelligence never duplicates provider authentication.
|
|
148
|
+
|
|
149
|
+
The production proof that the abstraction works against a real ERP data layer
|
|
150
|
+
lives in `sarooo17/world-capability-mcp`: its ERP Events implementation uses
|
|
151
|
+
`createMcpEventsProvider` with authenticated ERPNext/Frappe record queries,
|
|
152
|
+
tenant/company filters, opaque replay-safe cursors, pagination/`hasMore`,
|
|
153
|
+
timezone normalization and deterministic occurrence IDs. The local factory in
|
|
154
|
+
this package should therefore be read as a typed convenience API, not as the
|
|
155
|
+
production ERP connector itself.
|
|
144
156
|
|
|
145
157
|
## What v0.1 implements
|
|
146
158
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-event-intelligence",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Durable temporal event intelligence for agent hosts: host-owned MCP event discovery, composite triggers, derived events, and targeted wakeups.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -275,9 +275,11 @@ export async function createLocalEventIntelligenceRuntime({
|
|
|
275
275
|
wakeRetryScheduler,
|
|
276
276
|
wakeCoordinator,
|
|
277
277
|
wakeCoordinators,
|
|
278
|
-
close() {
|
|
279
|
-
|
|
280
|
-
|
|
278
|
+
async close() {
|
|
279
|
+
await Promise.all([
|
|
280
|
+
temporalScheduler.close(),
|
|
281
|
+
wakeRetryScheduler.close(),
|
|
282
|
+
]);
|
|
281
283
|
},
|
|
282
284
|
};
|
|
283
285
|
scopeContexts.set(scopeId, context);
|
|
@@ -329,9 +331,17 @@ export async function createLocalEventIntelligenceRuntime({
|
|
|
329
331
|
return [...scopeContexts.keys()].sort();
|
|
330
332
|
},
|
|
331
333
|
async close() {
|
|
332
|
-
mcpEventsClient.
|
|
333
|
-
|
|
334
|
-
|
|
334
|
+
await mcpEventsClient.close();
|
|
335
|
+
const contexts = [...scopeContexts.values()];
|
|
336
|
+
await Promise.all(contexts.map((context) => context.close()));
|
|
337
|
+
|
|
338
|
+
const stores = new Set(contexts.map((context) => context.store));
|
|
339
|
+
for (const store of stores) {
|
|
340
|
+
if (typeof store.close === 'function') {
|
|
341
|
+
await store.close();
|
|
342
|
+
} else if (typeof store.drain === 'function') {
|
|
343
|
+
await store.drain();
|
|
344
|
+
}
|
|
335
345
|
}
|
|
336
346
|
},
|
|
337
347
|
};
|
|
@@ -599,6 +599,17 @@ export class McpEventsClientManager {
|
|
|
599
599
|
this.intervals.clear();
|
|
600
600
|
}
|
|
601
601
|
|
|
602
|
+
async drain() {
|
|
603
|
+
while (this.pollInFlight.size > 0) {
|
|
604
|
+
await Promise.allSettled([...this.pollInFlight.values()]);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
async close() {
|
|
609
|
+
this.stop();
|
|
610
|
+
await this.drain();
|
|
611
|
+
}
|
|
612
|
+
|
|
602
613
|
status() {
|
|
603
614
|
return [...this.connections.values()].map((connection) => {
|
|
604
615
|
const context = this.scopeContexts.get(
|
|
@@ -1057,6 +1057,18 @@ export class PersistentEventStore {
|
|
|
1057
1057
|
return this.#auditChain.verify();
|
|
1058
1058
|
}
|
|
1059
1059
|
|
|
1060
|
+
async drain() {
|
|
1061
|
+
await this.#queue;
|
|
1062
|
+
const scoped = [...this.#scopeStores.values()];
|
|
1063
|
+
await Promise.all(scoped.map((store) =>
|
|
1064
|
+
typeof store.drain === 'function' ? store.drain() : undefined
|
|
1065
|
+
));
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
async close() {
|
|
1069
|
+
await this.drain();
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1060
1072
|
#eventKey(lineage) {
|
|
1061
1073
|
return `${lineage.environmentId}:${lineage.subscriptionId}:${lineage.sourceEventId}`;
|
|
1062
1074
|
}
|
|
@@ -104,8 +104,18 @@ export class TemporalDeadlineScheduler {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
stop() {
|
|
107
|
-
if (
|
|
108
|
-
clearInterval(this.timer);
|
|
107
|
+
if (this.timer) clearInterval(this.timer);
|
|
109
108
|
this.timer = null;
|
|
110
109
|
}
|
|
110
|
+
|
|
111
|
+
async drain() {
|
|
112
|
+
while (this.running) {
|
|
113
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async close() {
|
|
118
|
+
this.stop();
|
|
119
|
+
await this.drain();
|
|
120
|
+
}
|
|
111
121
|
}
|
|
@@ -87,8 +87,18 @@ export class WakeRetryScheduler {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
stop() {
|
|
90
|
-
if (
|
|
91
|
-
clearInterval(this.timer);
|
|
90
|
+
if (this.timer) clearInterval(this.timer);
|
|
92
91
|
this.timer = null;
|
|
93
92
|
}
|
|
93
|
+
|
|
94
|
+
async drain() {
|
|
95
|
+
while (this.running) {
|
|
96
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async close() {
|
|
101
|
+
this.stop();
|
|
102
|
+
await this.drain();
|
|
103
|
+
}
|
|
94
104
|
}
|
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "io.github.sarooo17/event-intelligence",
|
|
4
4
|
"title": "MCP Event Intelligence",
|
|
5
5
|
"description": "Durable temporal event intelligence: composite triggers, derived events, and runtime wakeups.",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.1",
|
|
7
7
|
"repository": {
|
|
8
8
|
"url": "https://github.com/sarooo17/event-intelligence",
|
|
9
9
|
"source": "github"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
15
15
|
"identifier": "mcp-event-intelligence",
|
|
16
|
-
"version": "0.2.
|
|
16
|
+
"version": "0.2.1",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
},
|