mcp-event-intelligence 0.3.0 → 0.4.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 +40 -0
- package/README.md +26 -14
- package/SECURITY.md +11 -7
- package/bin/mcp-event-intelligence.mjs +2 -2
- package/dist/src/composite/matching.d.ts +1 -1
- package/dist/src/composite/matching.js +21 -1
- package/dist/src/intelligenceProtocol/schemas.d.ts +2 -0
- package/dist/src/intelligenceProtocol/schemas.js +1 -0
- package/dist/src/intelligenceProtocol/triggerPlanSchemas.d.ts +2 -0
- package/dist/src/intelligenceProtocol/triggerPlanSchemas.js +1 -0
- package/dist/src/intelligenceProtocol/triggerSchemas.d.ts +6 -0
- package/dist/src/intelligenceProtocol/triggerSchemas.js +3 -0
- package/dist/src/mcpEvents/consumer.d.ts +1 -0
- package/dist/src/mcpEvents/consumer.js +1 -0
- package/dist/src/mcpEvents/erpnextProvider.d.ts +0 -2
- package/dist/src/mcpEvents/erpnextProvider.js +0 -3
- package/dist/src/mcpEvents/provider.d.ts +24 -10
- package/dist/src/mcpEvents/provider.js +124 -55
- package/dist/src/mcpEvents/server.d.ts +3 -1
- package/dist/src/mcpEvents/server.js +20 -19
- package/dist/src/protocol/types.d.ts +1 -0
- package/package.json +1 -1
- package/scripts/host-integration.d.mts +40 -0
- package/scripts/lib/composite-event-consumer.mjs +2 -0
- package/scripts/lib/json-schema.mjs +134 -0
- package/scripts/lib/local-event-intelligence-runtime.mjs +1 -0
- package/scripts/lib/mcp-events-client.mjs +760 -253
- package/scripts/lib/persistent-event-store.mjs +68 -9
- package/scripts/lib/trigger-control-plane.mjs +26 -0
- package/scripts/lib/trigger-planner.mjs +23 -0
- package/scripts/mcp-stdio-server.mjs +2 -1
- package/server.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,47 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.0] - 2026-09-25
|
|
4
|
+
|
|
5
|
+
Current MCP Events draft alignment.
|
|
6
|
+
|
|
7
|
+
### MCP Events boundary
|
|
8
|
+
|
|
9
|
+
- switched event capability negotiation to `capabilities.extensions["io.modelcontextprotocol/events"]`;
|
|
10
|
+
- removed the legacy `server/discover` / `io.modelcontextprotocol.experimental/events` compatibility surface;
|
|
11
|
+
- added paginated `events/list`, draft error semantics, nullable cursors and `_meta` preservation;
|
|
12
|
+
- validates subscription `arguments` against advertised `inputSchema`;
|
|
13
|
+
- separates EventSource descriptors from durable EventSubscriptions keyed by connection + event name + canonical arguments;
|
|
14
|
+
- stores independent cursor/delivery state per subscription;
|
|
15
|
+
- poll scheduling now follows server `nextPollMs` and keeps `hasMore` distinct from `truncated`;
|
|
16
|
+
- host-owned push and webhook adapters feed the same EventOccurrence pipeline as poll;
|
|
17
|
+
- added current-draft discovery/poll conformance-shaped regression coverage.
|
|
18
|
+
|
|
19
|
+
### Compatibility
|
|
20
|
+
|
|
21
|
+
- trigger clauses gain additive `arguments: {}`; existing persisted trigger definitions remain readable because omitted arguments default to an empty object;
|
|
22
|
+
- composite, temporal, derived-event and wake semantics are unchanged;
|
|
23
|
+
- event ingress targets the 2026-09-25 experimental draft direction represented by experimental-ext-triggers-events PR #7 and conformance PR #521, not a finalized MCP specification.
|
|
24
|
+
|
|
3
25
|
All notable public changes are documented here.
|
|
4
26
|
|
|
27
|
+
## [0.3.1] - 2026-09-20
|
|
28
|
+
|
|
29
|
+
Public-polish and reliability patch before wider distribution.
|
|
30
|
+
|
|
31
|
+
### Reliability
|
|
32
|
+
|
|
33
|
+
- fixed the lease-claim test cleanup race that could surface intermittent `ENOTEMPTY` errors while an in-flight worker was still writing;
|
|
34
|
+
- added repeated direct lease-claim contention coverage and full coordinator contention stress coverage.
|
|
35
|
+
|
|
36
|
+
### Documentation and public surface
|
|
37
|
+
|
|
38
|
+
- refreshed Security Policy and Security Model for scoped multi-tenant hosts, Activation Envelopes and the v0.3 agent-friendly planning flow;
|
|
39
|
+
- clarified the distinction between package version 0.3.x and the intentionally compatible internal protocol/schema v0.1 identifiers;
|
|
40
|
+
- refreshed Architecture and Protocol docs for `planTrigger()`, continuation contracts and wake hydration;
|
|
41
|
+
- updated MCP Registry docs to reflect the package and Registry as live, not deferred;
|
|
42
|
+
- updated the CLI help banner;
|
|
43
|
+
- removed the obsolete one-shot v0.1.0 release workflow.
|
|
44
|
+
|
|
5
45
|
## [0.3.0] - 2026-09-20
|
|
6
46
|
|
|
7
47
|
Agent-integration release focused on making Event Intelligence usable as a plug-and-play future-condition primitive.
|
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.
|
|
@@ -169,9 +169,9 @@ const events = createMcpEventsProvider({
|
|
|
169
169
|
});
|
|
170
170
|
```
|
|
171
171
|
|
|
172
|
-
The package owns
|
|
172
|
+
The package owns the current draft Events extension identifier/settings, `events/list`, `events/poll`, common validation and response shapes. The embedding MCP server advertises `capabilities.extensions["io.modelcontextprotocol/events"]`; the provider owns domain event definitions, authentication, data queries, occurrence IDs and opaque cursor semantics.
|
|
173
173
|
|
|
174
|
-
This adapter
|
|
174
|
+
This adapter tracks the current experimental MCP Events draft. It is not a claim of finalized MCP Events conformance. The v0.4 compatibility snapshot follows the `io.modelcontextprotocol/events` extension-negotiation direction in experimental-ext-triggers-events PR #7 and the discovery/poll contract exercised by conformance PR #521 as of 2026-09-25.
|
|
175
175
|
|
|
176
176
|
|
|
177
177
|
An ERPNext-shaped **provider factory** is also exported:
|
|
@@ -203,15 +203,18 @@ timezone normalization and deterministic occurrence IDs. The local factory in
|
|
|
203
203
|
this package should therefore be read as a typed convenience API, not as the
|
|
204
204
|
production ERP connector itself.
|
|
205
205
|
|
|
206
|
-
## What v0.
|
|
206
|
+
## What v0.4 implements
|
|
207
207
|
|
|
208
208
|
### Host-owned event sources
|
|
209
209
|
|
|
210
210
|
- automatic discovery from the host's existing MCP registry;
|
|
211
211
|
- reuse of already-connected MCP clients without duplicate credentials;
|
|
212
|
-
-
|
|
213
|
-
- `events/list`
|
|
214
|
-
-
|
|
212
|
+
- direct MCP extension negotiation through `capabilities.extensions["io.modelcontextprotocol/events"]`;
|
|
213
|
+
- paginated `events/list` discovery;
|
|
214
|
+
- durable EventSubscription identity over `(connection, event name, arguments)`;
|
|
215
|
+
- `events/poll` with server-directed `nextPollMs`, nullable cursors and bounded page draining;
|
|
216
|
+
- host-owned push and webhook delivery adapters feeding the same EventOccurrence pipeline;
|
|
217
|
+
- persistent opaque cursors and per-subscription delivery state;
|
|
215
218
|
- per-scope source/cursor isolation for shared hosts;
|
|
216
219
|
- single-flight polling per connection plus bounded `hasMore` batch draining;
|
|
217
220
|
- automatic event-source registration;
|
|
@@ -228,10 +231,19 @@ production ERP connector itself.
|
|
|
228
231
|
- calendar-aware conditions with IANA timezones;
|
|
229
232
|
- durable deadlines that continue even when no new provider event arrives.
|
|
230
233
|
|
|
234
|
+
### Event sources vs subscriptions
|
|
235
|
+
|
|
236
|
+
`events/list` discovers an **EventSource** descriptor. A durable **EventSubscription** is a separate runtime object identified by the host connection, event name and canonical subscription `arguments`. Each subscription owns its cursor/delivery state independently.
|
|
237
|
+
|
|
238
|
+
This keeps MCP-side filtering separate from Event Intelligence conditions: `arguments` are validated against the provider's `inputSchema`; trigger `where` predicates are evaluated by EI against delivered payloads. Two triggers may therefore subscribe to the same event name with different arguments without sharing cursors.
|
|
239
|
+
|
|
240
|
+
Poll, push and webhook are treated only as delivery mechanisms. All three normalize into the same `EventOccurrence` ingestion path before correlation, temporal reasoning, derived events or wake logic.
|
|
241
|
+
|
|
231
242
|
### Agent-authored continuations
|
|
232
243
|
|
|
233
244
|
- event-source discovery;
|
|
234
245
|
- agent-friendly deterministic trigger planning/compilation;
|
|
246
|
+
- MCP subscription `arguments` validated against each source `inputSchema`, kept distinct from EI payload predicates;
|
|
235
247
|
- `eq`, `neq`, `contains`, `in`, `exists`, `gt`, `gte`, `lt`, `lte` predicates;
|
|
236
248
|
- persisted continuation contracts separated from trigger conditions;
|
|
237
249
|
- Activation Envelope hydration with matched event evidence;
|
|
@@ -300,13 +312,13 @@ Event Intelligence has one optional AI boundary: **semantic correlation**.
|
|
|
300
312
|
- embedded hosts may inject a compatible `semanticEvaluator` instead.
|
|
301
313
|
- there is no bundled OpenAI planner and no OpenAI API dependency.
|
|
302
314
|
|
|
303
|
-
The agent/harness is already responsible for reasoning
|
|
315
|
+
The agent/harness is already responsible for natural-language reasoning. It can use `trigger_plan` / `planTrigger()` to compile common requests deterministically against discovered source schemas, or submit a canonical trigger definition directly for advanced cases. Deterministic correlation, temporal logic, persistence, derived events and wake delivery require no model API.
|
|
304
316
|
|
|
305
317
|
## Full-system acceptance
|
|
306
318
|
|
|
307
|
-
The v0.
|
|
319
|
+
The v0.4 acceptance suite verifies:
|
|
308
320
|
|
|
309
|
-
- host-owned MCP client →
|
|
321
|
+
- host-owned MCP client → extension discovery → durable subscription → poll/push/webhook occurrence → composite match → in-process wake;
|
|
310
322
|
- provider-neutral events → composite match → derived event → derived composition → signed runtime wake;
|
|
311
323
|
- contract schema evolution and ambiguity rejection;
|
|
312
324
|
- refs-only root provenance;
|
|
@@ -350,13 +362,13 @@ The standalone service supports manual/provider-native event ingress. It does no
|
|
|
350
362
|
### Docker
|
|
351
363
|
|
|
352
364
|
```bash
|
|
353
|
-
docker build -t mcp-event-intelligence:0.
|
|
365
|
+
docker build -t mcp-event-intelligence:0.4.0 .
|
|
354
366
|
|
|
355
367
|
docker run --rm \
|
|
356
368
|
-p 3000:3000 \
|
|
357
369
|
-v mcp-event-intelligence-data:/data \
|
|
358
370
|
-e SERVICE_AUTH_TOKEN="$(openssl rand -hex 32)" \
|
|
359
|
-
mcp-event-intelligence:0.
|
|
371
|
+
mcp-event-intelligence:0.4.0
|
|
360
372
|
```
|
|
361
373
|
|
|
362
374
|
## Optional MCP control plane
|
|
@@ -432,7 +444,7 @@ In embedded mode, the host retains MCP authorization and credentials; Event Inte
|
|
|
432
444
|
|
|
433
445
|
There are two separate MCP boundaries:
|
|
434
446
|
|
|
435
|
-
- **event ingress**: host-owned, already-connected MCP clients exposing experimental
|
|
447
|
+
- **event ingress**: host-owned, already-connected MCP clients exposing the experimental `io.modelcontextprotocol/events` extension, plus provider-native adapters; poll is native in the reference provider adapter, while push/webhook receivers remain host-owned delivery adapters;
|
|
436
448
|
- **control plane**: optional standard MCP **stdio** server built on the official TypeScript SDK v2 and targeting protocol revision 2026-07-28.
|
|
437
449
|
|
|
438
450
|
Registry identity:
|
|
@@ -445,7 +457,7 @@ io.github.sarooo17/event-intelligence
|
|
|
445
457
|
|
|
446
458
|
## Project status
|
|
447
459
|
|
|
448
|
-
**v0.
|
|
460
|
+
**v0.4.x reference implementation / experimental.**
|
|
449
461
|
|
|
450
462
|
The architecture is implemented and exercised end-to-end. Storage is now injectable and scoped, while the bundled JSONL backend remains a single-process reference implementation. Remaining work is primarily production database adapters/HA validation, scale benchmarks and upstream feedback.
|
|
451
463
|
|
package/SECURITY.md
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Supported versions
|
|
4
4
|
|
|
5
|
-
The public
|
|
5
|
+
The public package is pre-1.0. Security fixes are supported on the current 0.3.x line.
|
|
6
6
|
|
|
7
7
|
| Version | Supported |
|
|
8
8
|
| --- | --- |
|
|
9
|
-
| 0.
|
|
10
|
-
| < 0.
|
|
9
|
+
| 0.3.x | Yes |
|
|
10
|
+
| < 0.3 | No |
|
|
11
11
|
|
|
12
12
|
## Reporting a vulnerability
|
|
13
13
|
|
|
@@ -26,17 +26,21 @@ Useful reports include:
|
|
|
26
26
|
|
|
27
27
|
## Security boundaries
|
|
28
28
|
|
|
29
|
-
Event Intelligence
|
|
29
|
+
Event Intelligence 0.3.x is an experimental reference implementation with scoped multi-tenant host support. It is not a turnkey hardened hosted service.
|
|
30
30
|
|
|
31
31
|
Important defaults and constraints:
|
|
32
32
|
|
|
33
|
-
-
|
|
33
|
+
- tenant/workspace isolation is implemented through scoped store partitions; tenant-facing code should receive only the corresponding scoped host view;
|
|
34
|
+
- protected standalone control-plane endpoints require `SERVICE_AUTH_TOKEN`;
|
|
34
35
|
- GitHub ingress verifies provider HMAC when configured;
|
|
35
|
-
- runtime wake packets are HMAC-signed and runtime targets are operator-configured;
|
|
36
|
+
- standalone runtime wake packets are HMAC-signed and runtime targets are operator-configured;
|
|
37
|
+
- embedded wakes preserve the configured continuation separately from untrusted matched-event evidence;
|
|
38
|
+
- event receipt never grants new downstream authorization;
|
|
36
39
|
- arbitrary public HTTP wake targets are rejected;
|
|
37
40
|
- derived-event lineage is refs-only by default;
|
|
38
41
|
- audit records are hash-linked and tamper-evident, not tamper-proof;
|
|
39
|
-
- the JSONL store is single-
|
|
42
|
+
- the bundled JSONL store is single-process reference infrastructure and is not safe as a shared multi-replica backend;
|
|
43
|
+
- horizontally scaled custom stores must preserve scope isolation and implement wake claim/lease operations atomically;
|
|
40
44
|
- secrets belong in environment variables / secret managers, never committed files.
|
|
41
45
|
|
|
42
46
|
See `docs/SECURITY-MODEL.md` for the architectural model.
|
|
@@ -4,12 +4,12 @@ const args = process.argv.slice(2);
|
|
|
4
4
|
const flags = new Set(args);
|
|
5
5
|
|
|
6
6
|
if (flags.has('--version') || flags.has('-v')) {
|
|
7
|
-
console.log('0.
|
|
7
|
+
console.log('0.4.0');
|
|
8
8
|
process.exit(0);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
if (flags.has('--help') || flags.has('-h')) {
|
|
12
|
-
console.log(`MCP Event Intelligence v0.
|
|
12
|
+
console.log(`MCP Event Intelligence v0.4
|
|
13
13
|
|
|
14
14
|
Durable temporal event intelligence for sleeping agents.
|
|
15
15
|
|
|
@@ -4,5 +4,5 @@ export declare function asSourceEvent(clauseId: string, event: CorrelatableEvent
|
|
|
4
4
|
export declare function expressionSatisfied(definition: CompositeTriggerDefinition, record: TriggerMatchRecord): boolean;
|
|
5
5
|
export declare function semanticSource(record: TriggerMatchRecord): Record<string, unknown>;
|
|
6
6
|
export declare function deterministicKeyForClause(definition: CompositeTriggerDefinition, clauseId: string, event: CorrelatableEvent): string | null;
|
|
7
|
-
export declare function sameEventIdentity(source: Pick<TriggerSourceEvent, 'sourceEventId' | 'serverId'>, event: Pick<CorrelatableEvent, 'sourceEventId' | 'serverId'>): boolean;
|
|
7
|
+
export declare function sameEventIdentity(source: Pick<TriggerSourceEvent, 'sourceEventId' | 'serverId' | 'subscriptionArguments'>, event: Pick<CorrelatableEvent, 'sourceEventId' | 'serverId' | 'subscriptionArguments'>): boolean;
|
|
8
8
|
export declare function matchesCorrelationKey(record: TriggerMatchRecord, key: string | null): boolean;
|
|
@@ -9,6 +9,23 @@ function getByPath(source, path) {
|
|
|
9
9
|
}
|
|
10
10
|
return current;
|
|
11
11
|
}
|
|
12
|
+
function stableValue(value) {
|
|
13
|
+
if (Array.isArray(value))
|
|
14
|
+
return value.map(stableValue);
|
|
15
|
+
if (value && typeof value === 'object') {
|
|
16
|
+
return Object.fromEntries(Object.keys(value)
|
|
17
|
+
.sort()
|
|
18
|
+
.map((key) => [
|
|
19
|
+
key,
|
|
20
|
+
stableValue(value[key]),
|
|
21
|
+
]));
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
function sameSubscriptionArguments(left, right) {
|
|
26
|
+
return JSON.stringify(stableValue(left ?? {})) ===
|
|
27
|
+
JSON.stringify(stableValue(right ?? {}));
|
|
28
|
+
}
|
|
12
29
|
function scalarKey(value) {
|
|
13
30
|
if (typeof value === 'string' ||
|
|
14
31
|
typeof value === 'number' ||
|
|
@@ -47,6 +64,7 @@ export function clauseMatches(clause, event) {
|
|
|
47
64
|
const contractVersion = getByPath(event.data, '_derived.contractVersion');
|
|
48
65
|
return (clause.event === event.name &&
|
|
49
66
|
(!clause.serverId || clause.serverId === event.serverId) &&
|
|
67
|
+
sameSubscriptionArguments(clause.arguments, event.subscriptionArguments) &&
|
|
50
68
|
(!clause.contractVersion ||
|
|
51
69
|
String(contractVersion ?? '') === String(clause.contractVersion)) &&
|
|
52
70
|
clause.where.every((predicate) => predicateMatches(event, predicate)));
|
|
@@ -60,6 +78,7 @@ export function asSourceEvent(clauseId, event) {
|
|
|
60
78
|
occurredAt: event.occurredAt,
|
|
61
79
|
...(event.provider ? { provider: event.provider } : {}),
|
|
62
80
|
...(event.serverId ? { serverId: event.serverId } : {}),
|
|
81
|
+
subscriptionArguments: event.subscriptionArguments ?? {},
|
|
63
82
|
...(event.payloadHash ? { payloadHash: event.payloadHash } : {}),
|
|
64
83
|
data: event.data,
|
|
65
84
|
};
|
|
@@ -108,7 +127,8 @@ export function deterministicKeyForClause(definition, clauseId, event) {
|
|
|
108
127
|
}
|
|
109
128
|
export function sameEventIdentity(source, event) {
|
|
110
129
|
return (source.sourceEventId === event.sourceEventId &&
|
|
111
|
-
(source.serverId ?? null) === (event.serverId ?? null)
|
|
130
|
+
(source.serverId ?? null) === (event.serverId ?? null) &&
|
|
131
|
+
sameSubscriptionArguments(source.subscriptionArguments, event.subscriptionArguments));
|
|
112
132
|
}
|
|
113
133
|
export function matchesCorrelationKey(record, key) {
|
|
114
134
|
if (record.correlationKey === null || key === null)
|
|
@@ -128,6 +128,7 @@ export declare const McpEventOccurrenceSchema: z.ZodObject<{
|
|
|
128
128
|
timestamp: z.ZodString;
|
|
129
129
|
data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
130
130
|
cursor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
131
|
+
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
131
132
|
}, z.core.$strip>;
|
|
132
133
|
export declare const SemanticConditionWireSchema: z.ZodObject<{
|
|
133
134
|
type: z.ZodLiteral<"semantic_boolean">;
|
|
@@ -148,6 +149,7 @@ export declare const EventIngestRequestSchema: z.ZodObject<{
|
|
|
148
149
|
timestamp: z.ZodString;
|
|
149
150
|
data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
150
151
|
cursor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
152
|
+
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
151
153
|
}, z.core.$strip>;
|
|
152
154
|
context: z.ZodObject<{
|
|
153
155
|
traceId: z.ZodOptional<z.ZodString>;
|
|
@@ -74,6 +74,7 @@ export const McpEventOccurrenceSchema = z.object({
|
|
|
74
74
|
timestamp: Timestamp,
|
|
75
75
|
data: z.record(z.string(), z.unknown()),
|
|
76
76
|
cursor: z.string().nullable().optional(),
|
|
77
|
+
_meta: z.record(z.string(), z.unknown()).optional(),
|
|
77
78
|
});
|
|
78
79
|
export const SemanticConditionWireSchema = z.object({
|
|
79
80
|
type: z.literal('semantic_boolean'),
|
|
@@ -3,6 +3,7 @@ export declare const TriggerPlanEventSchema: z.ZodObject<{
|
|
|
3
3
|
id: z.ZodOptional<z.ZodString>;
|
|
4
4
|
event: z.ZodString;
|
|
5
5
|
serverId: z.ZodOptional<z.ZodString>;
|
|
6
|
+
arguments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
6
7
|
where: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
7
8
|
path: z.ZodString;
|
|
8
9
|
op: z.ZodLiteral<"eq">;
|
|
@@ -58,6 +59,7 @@ export declare const TriggerPlanInputSchema: z.ZodObject<{
|
|
|
58
59
|
id: z.ZodOptional<z.ZodString>;
|
|
59
60
|
event: z.ZodString;
|
|
60
61
|
serverId: z.ZodOptional<z.ZodString>;
|
|
62
|
+
arguments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
61
63
|
where: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
62
64
|
path: z.ZodString;
|
|
63
65
|
op: z.ZodLiteral<"eq">;
|
|
@@ -6,6 +6,7 @@ export const TriggerPlanEventSchema = z.object({
|
|
|
6
6
|
id: Id.optional(),
|
|
7
7
|
event: z.string().min(1),
|
|
8
8
|
serverId: Id.optional(),
|
|
9
|
+
arguments: z.record(z.string(), z.unknown()).default({}),
|
|
9
10
|
where: z.array(StructuredPredicateSchema).default([]),
|
|
10
11
|
}).strict();
|
|
11
12
|
export const TriggerPlanMatchSchema = z.union([
|
|
@@ -43,6 +43,7 @@ export declare const TriggerClauseSchema: z.ZodObject<{
|
|
|
43
43
|
event: z.ZodString;
|
|
44
44
|
serverId: z.ZodOptional<z.ZodString>;
|
|
45
45
|
contractVersion: z.ZodOptional<z.ZodString>;
|
|
46
|
+
arguments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
46
47
|
where: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
47
48
|
path: z.ZodString;
|
|
48
49
|
op: z.ZodLiteral<"eq">;
|
|
@@ -260,6 +261,7 @@ export declare const CompositeTriggerDefinitionSchema: z.ZodObject<{
|
|
|
260
261
|
event: z.ZodString;
|
|
261
262
|
serverId: z.ZodOptional<z.ZodString>;
|
|
262
263
|
contractVersion: z.ZodOptional<z.ZodString>;
|
|
264
|
+
arguments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
263
265
|
where: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
264
266
|
path: z.ZodString;
|
|
265
267
|
op: z.ZodLiteral<"eq">;
|
|
@@ -433,6 +435,7 @@ export declare const CorrelatableEventSchema: z.ZodObject<{
|
|
|
433
435
|
occurredAt: z.ZodString;
|
|
434
436
|
provider: z.ZodOptional<z.ZodString>;
|
|
435
437
|
serverId: z.ZodOptional<z.ZodString>;
|
|
438
|
+
subscriptionArguments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
436
439
|
payloadHash: z.ZodOptional<z.ZodString>;
|
|
437
440
|
data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
438
441
|
}, z.core.$strip>;
|
|
@@ -444,6 +447,7 @@ export declare const DerivedEventRecordSchema: z.ZodObject<{
|
|
|
444
447
|
occurredAt: z.ZodString;
|
|
445
448
|
provider: z.ZodOptional<z.ZodString>;
|
|
446
449
|
serverId: z.ZodOptional<z.ZodString>;
|
|
450
|
+
subscriptionArguments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
447
451
|
payloadHash: z.ZodOptional<z.ZodString>;
|
|
448
452
|
data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
449
453
|
}, z.core.$strip>;
|
|
@@ -480,6 +484,7 @@ export declare const TriggerSourceEventSchema: z.ZodObject<{
|
|
|
480
484
|
occurredAt: z.ZodString;
|
|
481
485
|
provider: z.ZodOptional<z.ZodString>;
|
|
482
486
|
serverId: z.ZodOptional<z.ZodString>;
|
|
487
|
+
subscriptionArguments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
483
488
|
payloadHash: z.ZodOptional<z.ZodString>;
|
|
484
489
|
data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
485
490
|
}, z.core.$strip>;
|
|
@@ -529,6 +534,7 @@ export declare const TriggerMatchRecordSchema: z.ZodObject<{
|
|
|
529
534
|
occurredAt: z.ZodString;
|
|
530
535
|
provider: z.ZodOptional<z.ZodString>;
|
|
531
536
|
serverId: z.ZodOptional<z.ZodString>;
|
|
537
|
+
subscriptionArguments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
532
538
|
payloadHash: z.ZodOptional<z.ZodString>;
|
|
533
539
|
data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
534
540
|
}, z.core.$strip>>;
|
|
@@ -23,6 +23,7 @@ export const TriggerClauseSchema = z.object({
|
|
|
23
23
|
event: z.string().min(1),
|
|
24
24
|
serverId: Id.optional(),
|
|
25
25
|
contractVersion: z.string().min(1).max(50).optional(),
|
|
26
|
+
arguments: z.record(z.string(), z.unknown()).default({}),
|
|
26
27
|
where: z.array(StructuredPredicateSchema).default([]),
|
|
27
28
|
});
|
|
28
29
|
const TriggerExpressionSchema = z.discriminatedUnion('kind', [
|
|
@@ -333,6 +334,7 @@ export const CorrelatableEventSchema = z.object({
|
|
|
333
334
|
occurredAt: Timestamp,
|
|
334
335
|
provider: z.string().min(1).optional(),
|
|
335
336
|
serverId: Id.optional(),
|
|
337
|
+
subscriptionArguments: z.record(z.string(), z.unknown()).default({}),
|
|
336
338
|
payloadHash: z.string().regex(/^[a-f0-9]{64}$/).optional(),
|
|
337
339
|
data: z.record(z.string(), z.unknown()),
|
|
338
340
|
});
|
|
@@ -353,6 +355,7 @@ export const TriggerSourceEventSchema = z.object({
|
|
|
353
355
|
occurredAt: Timestamp,
|
|
354
356
|
provider: z.string().min(1).optional(),
|
|
355
357
|
serverId: Id.optional(),
|
|
358
|
+
subscriptionArguments: z.record(z.string(), z.unknown()).default({}),
|
|
356
359
|
payloadHash: z.string().regex(/^[a-f0-9]{64}$/).optional(),
|
|
357
360
|
data: z.record(z.string(), z.unknown()),
|
|
358
361
|
});
|
|
@@ -8,6 +8,7 @@ export async function mcpOccurrenceToCorrelatableEvent(event, input) {
|
|
|
8
8
|
occurredAt: event.timestamp,
|
|
9
9
|
...(input.provider ? { provider: input.provider } : {}),
|
|
10
10
|
...(input.serverId ? { serverId: input.serverId } : {}),
|
|
11
|
+
subscriptionArguments: input.subscriptionArguments ?? {},
|
|
11
12
|
payloadHash: await sha256Hex(event.data),
|
|
12
13
|
data: event.data,
|
|
13
14
|
});
|
|
@@ -14,7 +14,5 @@ export type ErpNextEventPoller<TContext = unknown> = (request: ProviderPollReque
|
|
|
14
14
|
export interface CreateErpNextEventsProviderOptions<TContext = unknown> {
|
|
15
15
|
pollSalesInvoices: ErpNextEventPoller<TContext>;
|
|
16
16
|
pollSalesOrders: ErpNextEventPoller<TContext>;
|
|
17
|
-
supportedVersions?: string[];
|
|
18
|
-
instructions?: string;
|
|
19
17
|
}
|
|
20
18
|
export declare function createErpNextEventsProvider<TContext = unknown>(options: CreateErpNextEventsProviderOptions<TContext>): McpEventsProvider<TContext>;
|
|
@@ -15,9 +15,6 @@ export function createErpNextEventsProvider(options) {
|
|
|
15
15
|
throw new Error('ERPNext Events provider requires pollSalesOrders()');
|
|
16
16
|
}
|
|
17
17
|
return createMcpEventsProvider({
|
|
18
|
-
supportedVersions: options.supportedVersions,
|
|
19
|
-
instructions: options.instructions ??
|
|
20
|
-
'ERPNext MCP Events adapter exposing host-owned Sales Invoice and Sales Order changes.',
|
|
21
18
|
events: [
|
|
22
19
|
{
|
|
23
20
|
descriptor: {
|
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
import type { EventDescriptor, EventOccurrence, JsonRpcRequest, JsonRpcResponse } from '../protocol/types.js';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const MCP_EVENTS_EXTENSION_ID: "io.modelcontextprotocol/events";
|
|
3
|
+
export declare const MCP_EVENTS_CAPABILITY_KEY: "io.modelcontextprotocol/events";
|
|
3
4
|
export declare const MCP_EVENTS_CAPABILITY: Readonly<{
|
|
4
|
-
status: "draft";
|
|
5
|
-
designDate: "2026-02-19";
|
|
6
|
-
methods: readonly ["events/list", "events/poll"];
|
|
7
5
|
listChanged: false;
|
|
8
6
|
}>;
|
|
7
|
+
export declare const MCP_EVENTS_ERROR: Readonly<{
|
|
8
|
+
INVALID_PARAMS: -32602;
|
|
9
|
+
METHOD_NOT_FOUND: -32601;
|
|
10
|
+
INTERNAL_ERROR: -32603;
|
|
11
|
+
NOT_FOUND: -32011;
|
|
12
|
+
FORBIDDEN: -32012;
|
|
13
|
+
RESOURCE_EXHAUSTED: -32013;
|
|
14
|
+
UNSUPPORTED: -32014;
|
|
15
|
+
CALLBACK_ENDPOINT_ERROR: -32015;
|
|
16
|
+
}>;
|
|
17
|
+
export declare class McpEventsProtocolError extends Error {
|
|
18
|
+
readonly code: number;
|
|
19
|
+
readonly data?: unknown;
|
|
20
|
+
constructor(code: number, message: string, data?: unknown);
|
|
21
|
+
}
|
|
9
22
|
export interface ProviderPollRequest<TContext = unknown> {
|
|
10
23
|
name: string;
|
|
11
24
|
arguments: Record<string, unknown>;
|
|
@@ -16,7 +29,7 @@ export interface ProviderPollRequest<TContext = unknown> {
|
|
|
16
29
|
}
|
|
17
30
|
export interface ProviderPollResult {
|
|
18
31
|
events: EventOccurrence[];
|
|
19
|
-
cursor: string;
|
|
32
|
+
cursor: string | null;
|
|
20
33
|
truncated?: boolean;
|
|
21
34
|
hasMore?: boolean;
|
|
22
35
|
nextPollMs?: number;
|
|
@@ -27,17 +40,18 @@ export interface McpProviderEvent<TContext = unknown> {
|
|
|
27
40
|
}
|
|
28
41
|
export interface CreateMcpEventsProviderOptions<TContext = unknown> {
|
|
29
42
|
events: McpProviderEvent<TContext>[];
|
|
30
|
-
|
|
31
|
-
instructions?: string;
|
|
43
|
+
listPageSize?: number;
|
|
32
44
|
}
|
|
33
45
|
export declare function assertJsonSchemaValue(schemaInput: Record<string, unknown>, value: unknown, path?: string): void;
|
|
34
46
|
export declare class McpEventsProvider<TContext = unknown> {
|
|
35
47
|
private readonly events;
|
|
36
|
-
readonly
|
|
37
|
-
readonly instructions: string;
|
|
48
|
+
private readonly listPageSize;
|
|
38
49
|
constructor(options: CreateMcpEventsProviderOptions<TContext>);
|
|
39
50
|
canHandle(method: string): boolean;
|
|
40
|
-
listEvents():
|
|
51
|
+
listEvents(paramsInput?: unknown): {
|
|
52
|
+
events: EventDescriptor[];
|
|
53
|
+
nextCursor?: string;
|
|
54
|
+
};
|
|
41
55
|
handleRequest(request: JsonRpcRequest, context?: TContext): Promise<JsonRpcResponse>;
|
|
42
56
|
private poll;
|
|
43
57
|
private ok;
|