mcp-event-intelligence 0.4.0 → 0.6.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 +100 -0
- package/README.md +107 -26
- package/SECURITY.md +4 -4
- package/bin/mcp-event-intelligence.mjs +3 -3
- package/dist/src/composite/engine.d.ts +14 -4
- package/dist/src/composite/engine.js +533 -208
- package/dist/src/composite/matching.d.ts +1 -5
- package/dist/src/composite/matching.js +45 -54
- package/dist/src/composite/runtimeSupport.js +10 -6
- package/dist/src/composite/store.d.ts +38 -4
- package/dist/src/composite/temporal.d.ts +0 -17
- package/dist/src/composite/temporal.js +0 -266
- package/dist/src/intelligenceProtocol/activationSchemas.d.ts +38 -3
- package/dist/src/intelligenceProtocol/activationSchemas.js +5 -3
- package/dist/src/intelligenceProtocol/index.d.ts +12 -9
- package/dist/src/intelligenceProtocol/index.js +6 -5
- package/dist/src/intelligenceProtocol/lifecycle.js +2 -10
- package/dist/src/intelligenceProtocol/operatorRegistry.d.ts +300 -0
- package/dist/src/intelligenceProtocol/operatorRegistry.js +338 -0
- package/dist/src/intelligenceProtocol/patternV2Schemas.d.ts +188 -0
- package/dist/src/intelligenceProtocol/patternV2Schemas.js +801 -0
- package/dist/src/intelligenceProtocol/schemas.d.ts +4 -189
- package/dist/src/intelligenceProtocol/schemas.js +3 -97
- package/dist/src/intelligenceProtocol/triggerPlanSchemas.d.ts +114 -38
- package/dist/src/intelligenceProtocol/triggerPlanSchemas.js +27 -18
- package/dist/src/intelligenceProtocol/triggerSchemas.d.ts +268 -213
- package/dist/src/intelligenceProtocol/triggerSchemas.js +155 -169
- package/dist/src/intelligenceProtocol/version.d.ts +2 -2
- package/dist/src/intelligenceProtocol/version.js +2 -2
- package/dist/src/mcpEvents/consumer.d.ts +1 -0
- package/dist/src/mcpEvents/consumer.js +1 -0
- package/dist/src/patternV2/evaluator.d.ts +51 -0
- package/dist/src/patternV2/evaluator.js +986 -0
- package/dist/src/semantic/types.d.ts +6 -0
- package/dist/src/semantic/typesafeJevEvaluator.d.ts +1 -0
- package/dist/src/semantic/typesafeJevEvaluator.js +6 -0
- package/package.json +9 -3
- package/scripts/host-integration.d.mts +54 -4
- package/scripts/host-integration.mjs +25 -4
- package/scripts/lib/activation-hydrator.mjs +13 -12
- package/scripts/lib/composite-event-consumer.mjs +10 -28
- package/scripts/lib/composite-wake-coordinator.mjs +19 -19
- package/scripts/lib/derived-contract-registry.mjs +4 -4
- package/scripts/lib/derived-event-coordinator.mjs +69 -6
- package/scripts/lib/local-event-intelligence-runtime.mjs +35 -3
- package/scripts/lib/mcp-events-client.mjs +97 -55
- package/scripts/lib/mcp-events-compatibility.mjs +54 -0
- package/scripts/lib/persistent-event-store.mjs +228 -61
- package/scripts/lib/store-capabilities.mjs +88 -0
- package/scripts/lib/store-conformance.mjs +127 -0
- package/scripts/lib/temporal-deadline-scheduler.mjs +3 -3
- package/scripts/lib/trigger-control-plane.mjs +202 -53
- package/scripts/lib/trigger-inspector.mjs +50 -147
- package/scripts/lib/trigger-planner.mjs +141 -52
- package/scripts/lib/wake-retry-scheduler.mjs +2 -19
- package/scripts/mcp-stdio-server.mjs +46 -61
- package/scripts/service.mjs +19 -138
- package/server.json +4 -4
- package/dist/src/intelligenceProtocol/invariants.d.ts +0 -3
- package/dist/src/intelligenceProtocol/invariants.js +0 -36
- package/dist/src/intelligenceProtocol/mapper.d.ts +0 -14
- package/dist/src/intelligenceProtocol/mapper.js +0 -28
- package/scripts/lib/event-processor.mjs +0 -624
- package/scripts/lib/http-wake-deliverer.mjs +0 -31
|
@@ -2,6 +2,8 @@ import { McpServer } from '@modelcontextprotocol/server';
|
|
|
2
2
|
import { serveStdio } from '@modelcontextprotocol/server/stdio';
|
|
3
3
|
import * as z from 'zod/v4';
|
|
4
4
|
import {
|
|
5
|
+
TriggerPlanInputSchema,
|
|
6
|
+
describeTriggerLanguage,
|
|
5
7
|
parseCompositeTriggerDefinition,
|
|
6
8
|
} from '../dist/src/intelligenceProtocol/index.js';
|
|
7
9
|
import {
|
|
@@ -57,59 +59,26 @@ function ownerFromEnv(env) {
|
|
|
57
59
|
};
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
const
|
|
61
|
-
path: z.string().min(1),
|
|
62
|
-
op: z.enum(['eq', 'neq', 'contains', 'in', 'exists', 'gt', 'gte', 'lt', 'lte']),
|
|
63
|
-
value: z.unknown().optional(),
|
|
64
|
-
});
|
|
62
|
+
const triggerPlanInputSchema = TriggerPlanInputSchema;
|
|
65
63
|
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
eventId: z.string().min(1),
|
|
82
|
-
atLeast: z.number().int().min(1),
|
|
83
|
-
}),
|
|
64
|
+
const triggerLanguageDescribeInputSchema = z.object({
|
|
65
|
+
category: z.enum([
|
|
66
|
+
'predicates',
|
|
67
|
+
'composition',
|
|
68
|
+
'temporal',
|
|
69
|
+
'pattern',
|
|
70
|
+
'windows',
|
|
71
|
+
'aggregates',
|
|
72
|
+
'state',
|
|
73
|
+
'selection',
|
|
74
|
+
'semantic',
|
|
75
|
+
'execution',
|
|
76
|
+
'correlation',
|
|
77
|
+
'timing',
|
|
78
|
+
'lifecycle',
|
|
84
79
|
]).optional(),
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
oneShot: z.boolean().optional(),
|
|
88
|
-
maxFirings: z.number().int().min(1).optional(),
|
|
89
|
-
cooldownMs: z.number().int().nonnegative().optional(),
|
|
90
|
-
expiresAt: z.string().optional(),
|
|
91
|
-
leaseUntil: z.string().optional(),
|
|
92
|
-
completeOnGoal: z.boolean().optional(),
|
|
93
|
-
}).optional(),
|
|
94
|
-
target: z.object({
|
|
95
|
-
runtime: z.string().min(1),
|
|
96
|
-
kind: z.enum(['goal', 'session', 'conversation', 'task', 'spawn_template']),
|
|
97
|
-
id: z.string().min(1),
|
|
98
|
-
}),
|
|
99
|
-
continuation: z.object({
|
|
100
|
-
instruction: z.string().min(1).max(4000),
|
|
101
|
-
contextPolicy: z.object({
|
|
102
|
-
evidence: z.enum(['matched_events', 'refs_only']).optional(),
|
|
103
|
-
maxEvents: z.number().int().min(1).max(50).optional(),
|
|
104
|
-
includeData: z.boolean().optional(),
|
|
105
|
-
}).optional(),
|
|
106
|
-
}),
|
|
107
|
-
correlateBy: z.array(z.object({
|
|
108
|
-
eventId: z.string().min(1),
|
|
109
|
-
path: z.string().min(1),
|
|
110
|
-
})).min(2).optional(),
|
|
111
|
-
semanticCorrelation: z.record(z.string(), z.unknown()).optional(),
|
|
112
|
-
});
|
|
80
|
+
operator: z.string().min(1).optional(),
|
|
81
|
+
}).strict();
|
|
113
82
|
|
|
114
83
|
function registerReadTools(server, runtime) {
|
|
115
84
|
server.registerTool(
|
|
@@ -124,7 +93,7 @@ function registerReadTools(server, runtime) {
|
|
|
124
93
|
async ({ connectionIds }) => {
|
|
125
94
|
try {
|
|
126
95
|
return jsonResult({
|
|
127
|
-
sources: runtime.triggerControl.listEventSources({
|
|
96
|
+
sources: await runtime.triggerControl.listEventSources({
|
|
128
97
|
...(connectionIds ? { connectionIds } : {}),
|
|
129
98
|
}),
|
|
130
99
|
});
|
|
@@ -134,6 +103,22 @@ function registerReadTools(server, runtime) {
|
|
|
134
103
|
},
|
|
135
104
|
);
|
|
136
105
|
|
|
106
|
+
server.registerTool(
|
|
107
|
+
'trigger_language_describe',
|
|
108
|
+
{
|
|
109
|
+
description:
|
|
110
|
+
'Describe the public Event Intelligence trigger authoring language. Use this when you need to discover supported predicates, composition, temporal, correlation, timing, or lifecycle operators before planning a trigger.',
|
|
111
|
+
inputSchema: triggerLanguageDescribeInputSchema,
|
|
112
|
+
},
|
|
113
|
+
async (input) => {
|
|
114
|
+
try {
|
|
115
|
+
return jsonResult(describeTriggerLanguage(input));
|
|
116
|
+
} catch (error) {
|
|
117
|
+
return errorResult(error);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
);
|
|
121
|
+
|
|
137
122
|
server.registerTool(
|
|
138
123
|
'trigger_plan',
|
|
139
124
|
{
|
|
@@ -162,7 +147,7 @@ function registerReadTools(server, runtime) {
|
|
|
162
147
|
async ({ ownerOnly }) => {
|
|
163
148
|
try {
|
|
164
149
|
return jsonResult({
|
|
165
|
-
triggers: runtime.triggerControl.listTriggers(
|
|
150
|
+
triggers: await runtime.triggerControl.listTriggers(
|
|
166
151
|
ownerOnly ? { owner: ownerFromEnv(process.env) } : {},
|
|
167
152
|
),
|
|
168
153
|
});
|
|
@@ -225,7 +210,7 @@ function registerReadTools(server, runtime) {
|
|
|
225
210
|
async ({ eventName }) => {
|
|
226
211
|
try {
|
|
227
212
|
return jsonResult({
|
|
228
|
-
contracts: runtime.store.listDerivedContracts(eventName),
|
|
213
|
+
contracts: await runtime.store.listDerivedContracts(eventName),
|
|
229
214
|
});
|
|
230
215
|
} catch (error) {
|
|
231
216
|
return errorResult(error);
|
|
@@ -244,7 +229,7 @@ function registerReadTools(server, runtime) {
|
|
|
244
229
|
},
|
|
245
230
|
async ({ wakeId }) => {
|
|
246
231
|
try {
|
|
247
|
-
return jsonResult(runtime.activationHydrator.hydrateWake(wakeId));
|
|
232
|
+
return jsonResult(await runtime.activationHydrator.hydrateWake(wakeId));
|
|
248
233
|
} catch (error) {
|
|
249
234
|
return errorResult(error);
|
|
250
235
|
}
|
|
@@ -262,11 +247,11 @@ function registerReadTools(server, runtime) {
|
|
|
262
247
|
try {
|
|
263
248
|
return jsonResult({
|
|
264
249
|
restored: runtime.restored,
|
|
265
|
-
hostMcpEventConnections: runtime.mcpEventsClient.status(),
|
|
250
|
+
hostMcpEventConnections: await runtime.mcpEventsClient.status(),
|
|
266
251
|
pendingTemporalDeadlines:
|
|
267
|
-
runtime.store.listTemporalDeadlines({ status: 'pending' }).length,
|
|
268
|
-
derivedEvents: runtime.store.listDerivedEvents().length,
|
|
269
|
-
derivedContracts: runtime.store.listDerivedContracts().length,
|
|
252
|
+
(await runtime.store.listTemporalDeadlines({ status: 'pending' })).length,
|
|
253
|
+
derivedEvents: (await runtime.store.listDerivedEvents()).length,
|
|
254
|
+
derivedContracts: (await runtime.store.listDerivedContracts()).length,
|
|
270
255
|
writeEnabled: process.env.MCP_WRITE_ENABLED === 'true',
|
|
271
256
|
});
|
|
272
257
|
} catch (error) {
|
|
@@ -452,11 +437,11 @@ export async function buildEventIntelligenceMcpServer({
|
|
|
452
437
|
const server = new McpServer(
|
|
453
438
|
{
|
|
454
439
|
name: 'mcp-event-intelligence',
|
|
455
|
-
version: '0.
|
|
440
|
+
version: '0.5.0',
|
|
456
441
|
},
|
|
457
442
|
{
|
|
458
443
|
instructions:
|
|
459
|
-
'Use Event Intelligence to discover event sources, inspect/simulate durable trigger programs, and govern continuations.
|
|
444
|
+
'Use Event Intelligence to discover event sources and the trigger authoring language, plan/inspect/simulate durable trigger programs, and govern continuations. Prefer event_sources_list plus trigger_language_describe when needed, then author through trigger_plan instead of raw canonical definitions. Persistent mutations are unavailable unless the operator enables MCP_WRITE_ENABLED=true, and each mutation requires confirmationId.',
|
|
460
445
|
},
|
|
461
446
|
);
|
|
462
447
|
|
package/scripts/service.mjs
CHANGED
|
@@ -13,13 +13,10 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
ExperimentalMcpEventsServer,
|
|
15
15
|
} from '../dist/src/mcpEvents/server.js';
|
|
16
|
-
import { EventProcessor } from './lib/event-processor.mjs';
|
|
17
16
|
import {
|
|
18
|
-
githubEventPassesStructuredFilter,
|
|
19
17
|
translateGitHubWebhook,
|
|
20
18
|
verifyGitHubWebhookSignature,
|
|
21
19
|
} from './lib/github-webhook.mjs';
|
|
22
|
-
import { createHttpWakeDeliverer } from './lib/http-wake-deliverer.mjs';
|
|
23
20
|
import {
|
|
24
21
|
CompositeWakeCoordinator,
|
|
25
22
|
} from './lib/composite-wake-coordinator.mjs';
|
|
@@ -65,10 +62,6 @@ const evaluator = process.env.TYPESAFE_API_KEY
|
|
|
65
62
|
? TypeSafeJevEvaluator.fromEnvironment(process.env)
|
|
66
63
|
: null;
|
|
67
64
|
|
|
68
|
-
const wakeDeliverer = createHttpWakeDeliverer(
|
|
69
|
-
process.env.RUNTIME_WAKE_URL ?? '',
|
|
70
|
-
);
|
|
71
|
-
|
|
72
65
|
const deliveryOptions = {
|
|
73
66
|
leaseMs: Number(process.env.WAKE_DELIVERY_LEASE_MS ?? 30000),
|
|
74
67
|
maxAttempts: Number(process.env.WAKE_DELIVERY_MAX_ATTEMPTS ?? 5),
|
|
@@ -76,12 +69,6 @@ const deliveryOptions = {
|
|
|
76
69
|
retryMaxDelayMs: Number(process.env.WAKE_RETRY_MAX_DELAY_MS ?? 60000),
|
|
77
70
|
};
|
|
78
71
|
|
|
79
|
-
const processor = new EventProcessor({
|
|
80
|
-
store,
|
|
81
|
-
evaluator,
|
|
82
|
-
wakeDeliverer,
|
|
83
|
-
...deliveryOptions,
|
|
84
|
-
});
|
|
85
72
|
const compositeTriggers = new CompositeTriggerEngine(store, evaluator);
|
|
86
73
|
const runtimeWakeTargets = readRuntimeWakeTargets(
|
|
87
74
|
process.env.RUNTIME_WAKE_TARGETS_JSON,
|
|
@@ -104,7 +91,6 @@ const compositeEventConsumer = new CompositeEventConsumer({
|
|
|
104
91
|
triggerEngine: compositeTriggers,
|
|
105
92
|
wakeCoordinators,
|
|
106
93
|
derivedEventCoordinator,
|
|
107
|
-
processor,
|
|
108
94
|
maxDerivedDepth: Number(process.env.MAX_DERIVED_EVENT_DEPTH ?? 16),
|
|
109
95
|
});
|
|
110
96
|
const temporalScheduler = new TemporalDeadlineScheduler({
|
|
@@ -116,7 +102,6 @@ temporalScheduler.start();
|
|
|
116
102
|
|
|
117
103
|
const wakeRetryScheduler = new WakeRetryScheduler({
|
|
118
104
|
store,
|
|
119
|
-
eventProcessor: processor,
|
|
120
105
|
resolveCoordinator: (runtime) => wakeCoordinators.get(runtime) ?? null,
|
|
121
106
|
intervalMs: Number(process.env.WAKE_RETRY_TICK_MS ?? 1000),
|
|
122
107
|
});
|
|
@@ -167,59 +152,6 @@ function requireBearer(request, response) {
|
|
|
167
152
|
return true;
|
|
168
153
|
}
|
|
169
154
|
|
|
170
|
-
function githubSemanticCondition() {
|
|
171
|
-
const instruction = process.env.SEMANTIC_INSTRUCTION;
|
|
172
|
-
if (!instruction) return undefined;
|
|
173
|
-
|
|
174
|
-
return {
|
|
175
|
-
type: 'semantic_boolean',
|
|
176
|
-
instruction,
|
|
177
|
-
input: ['data.title', 'data.bodyPreview', 'data.labels'],
|
|
178
|
-
matchThreshold: Number(process.env.SEMANTIC_MATCH_THRESHOLD ?? 0.8),
|
|
179
|
-
rejectThreshold: Number(process.env.SEMANTIC_REJECT_THRESHOLD ?? 0.2),
|
|
180
|
-
uncertain: process.env.SEMANTIC_UNCERTAIN_POLICY ?? 'escalate',
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
function logProcessingResult(result) {
|
|
185
|
-
console.log(
|
|
186
|
-
JSON.stringify({
|
|
187
|
-
message: 'event_intelligence_result',
|
|
188
|
-
traceId: result.traceId,
|
|
189
|
-
sourceEventId: result.sourceEventId,
|
|
190
|
-
status: result.status,
|
|
191
|
-
decisionId: result.decision?.decisionId ?? null,
|
|
192
|
-
outcome: result.decision?.outcome ?? null,
|
|
193
|
-
probability: result.decision?.probability ?? null,
|
|
194
|
-
evaluator: result.decision?.evaluator ?? null,
|
|
195
|
-
providerEvidence: result.decision?.providerEvidence ?? null,
|
|
196
|
-
wakeId: result.wake?.wakeId ?? null,
|
|
197
|
-
wakeStatus: result.wake?.status ?? null,
|
|
198
|
-
}),
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function githubContext() {
|
|
203
|
-
const targetId = process.env.RUNTIME_TARGET_ID;
|
|
204
|
-
if (!targetId) {
|
|
205
|
-
throw new Error('RUNTIME_TARGET_ID is required for GitHub webhook delivery');
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return {
|
|
209
|
-
environmentId,
|
|
210
|
-
subscriptionId:
|
|
211
|
-
process.env.GITHUB_SUBSCRIPTION_ID ?? 'github-issues-default',
|
|
212
|
-
serverId: process.env.GITHUB_SERVER_ID ?? 'github-webhook-adapter',
|
|
213
|
-
transport: 'webhook',
|
|
214
|
-
provider: 'github',
|
|
215
|
-
target: {
|
|
216
|
-
runtime: process.env.RUNTIME_TARGET_RUNTIME ?? 'agent-runtime',
|
|
217
|
-
kind: process.env.RUNTIME_TARGET_KIND ?? 'session',
|
|
218
|
-
id: targetId,
|
|
219
|
-
},
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
|
|
223
155
|
const server = createServer(async (request, response) => {
|
|
224
156
|
try {
|
|
225
157
|
const url = new URL(
|
|
@@ -237,28 +169,20 @@ const server = createServer(async (request, response) => {
|
|
|
237
169
|
|
|
238
170
|
if (request.method === 'GET' && url.pathname === '/readyz') {
|
|
239
171
|
const auditValid = await store.verifyAudit();
|
|
240
|
-
const semanticRequired = Boolean(process.env.SEMANTIC_INSTRUCTION);
|
|
241
172
|
const evaluatorConfigured = Boolean(evaluator);
|
|
242
|
-
const ready =
|
|
243
|
-
auditValid &&
|
|
244
|
-
(!semanticRequired || evaluatorConfigured);
|
|
173
|
+
const ready = auditValid;
|
|
245
174
|
|
|
246
175
|
return sendJson(response, ready ? 200 : 503, {
|
|
247
|
-
status: ready
|
|
248
|
-
? 'ready'
|
|
249
|
-
: !auditValid
|
|
250
|
-
? 'audit_invalid'
|
|
251
|
-
: 'semantic_evaluator_unavailable',
|
|
176
|
+
status: ready ? 'ready' : 'audit_invalid',
|
|
252
177
|
auditValid,
|
|
253
|
-
semanticRequired,
|
|
254
178
|
evaluatorConfigured,
|
|
255
|
-
wakeCallbackConfigured:
|
|
179
|
+
wakeCallbackConfigured: runtimeWakeTargets.size > 0,
|
|
256
180
|
genericRuntimeWakeTargets: [...runtimeWakeTargets.keys()],
|
|
257
|
-
eventSources: store.listEventSources().length,
|
|
181
|
+
eventSources: (await store.listEventSources()).length,
|
|
258
182
|
pendingTemporalDeadlines:
|
|
259
|
-
store.listTemporalDeadlines({ status: 'pending' }).length,
|
|
260
|
-
derivedEvents: store.listDerivedEvents().length,
|
|
261
|
-
derivedContracts: store.listDerivedContracts().length,
|
|
183
|
+
(await store.listTemporalDeadlines({ status: 'pending' })).length,
|
|
184
|
+
derivedEvents: (await store.listDerivedEvents()).length,
|
|
185
|
+
derivedContracts: (await store.listDerivedContracts()).length,
|
|
262
186
|
});
|
|
263
187
|
}
|
|
264
188
|
|
|
@@ -338,27 +262,11 @@ const server = createServer(async (request, response) => {
|
|
|
338
262
|
}));
|
|
339
263
|
}
|
|
340
264
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
})
|
|
346
|
-
) {
|
|
347
|
-
return sendJson(response, 202, {
|
|
348
|
-
status: 'filtered_structured',
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
const result = await processor.ingest({
|
|
353
|
-
event: translated.event,
|
|
354
|
-
context: githubContext(),
|
|
355
|
-
semanticCondition: githubSemanticCondition(),
|
|
356
|
-
wakeOnEscalation:
|
|
357
|
-
process.env.WAKE_ON_ESCALATION === 'true',
|
|
265
|
+
return sendJson(response, 202, {
|
|
266
|
+
status: mcpReceipt.accepted ? 'accepted' : 'duplicate',
|
|
267
|
+
mcpReceipt,
|
|
268
|
+
composite,
|
|
358
269
|
});
|
|
359
|
-
|
|
360
|
-
logProcessingResult(result);
|
|
361
|
-
return sendJson(response, 202, result);
|
|
362
270
|
}
|
|
363
271
|
|
|
364
272
|
if (request.method === 'POST' && url.pathname === '/mcp') {
|
|
@@ -422,7 +330,7 @@ const server = createServer(async (request, response) => {
|
|
|
422
330
|
url.pathname === '/v1/derived-contracts'
|
|
423
331
|
) {
|
|
424
332
|
return sendJson(response, 200, {
|
|
425
|
-
contracts: store.listDerivedContracts(
|
|
333
|
+
contracts: await store.listDerivedContracts(
|
|
426
334
|
url.searchParams.get('eventName') ?? undefined,
|
|
427
335
|
),
|
|
428
336
|
});
|
|
@@ -433,7 +341,7 @@ const server = createServer(async (request, response) => {
|
|
|
433
341
|
url.pathname === '/v1/derived-events'
|
|
434
342
|
) {
|
|
435
343
|
return sendJson(response, 200, {
|
|
436
|
-
events: store.listDerivedEvents({
|
|
344
|
+
events: await store.listDerivedEvents({
|
|
437
345
|
...(url.searchParams.get('triggerId')
|
|
438
346
|
? { triggerId: url.searchParams.get('triggerId') }
|
|
439
347
|
: {}),
|
|
@@ -454,7 +362,7 @@ const server = createServer(async (request, response) => {
|
|
|
454
362
|
const triggerId = decodeURIComponent(
|
|
455
363
|
url.pathname.slice('/v1/inspector/triggers/'.length),
|
|
456
364
|
);
|
|
457
|
-
return sendJson(response, 200, triggerInspector.inspect({
|
|
365
|
+
return sendJson(response, 200, await triggerInspector.inspect({
|
|
458
366
|
triggerId,
|
|
459
367
|
version: url.searchParams.get('version') ?? undefined,
|
|
460
368
|
matchId: url.searchParams.get('matchId') ?? undefined,
|
|
@@ -481,7 +389,7 @@ const server = createServer(async (request, response) => {
|
|
|
481
389
|
url.pathname === '/v1/temporal/deadlines'
|
|
482
390
|
) {
|
|
483
391
|
return sendJson(response, 200, {
|
|
484
|
-
deadlines: store.listTemporalDeadlines({
|
|
392
|
+
deadlines: await store.listTemporalDeadlines({
|
|
485
393
|
...(url.searchParams.get('triggerId')
|
|
486
394
|
? { triggerId: url.searchParams.get('triggerId') }
|
|
487
395
|
: {}),
|
|
@@ -507,7 +415,7 @@ const server = createServer(async (request, response) => {
|
|
|
507
415
|
if (request.method === 'GET' && url.pathname === '/v1/event-sources') {
|
|
508
416
|
const connectionIds = url.searchParams.getAll('connectionId');
|
|
509
417
|
return sendJson(response, 200, {
|
|
510
|
-
eventSources: triggerControl.listEventSources({
|
|
418
|
+
eventSources: await triggerControl.listEventSources({
|
|
511
419
|
...(connectionIds.length ? { connectionIds } : {}),
|
|
512
420
|
}),
|
|
513
421
|
});
|
|
@@ -528,7 +436,7 @@ const server = createServer(async (request, response) => {
|
|
|
528
436
|
const ownerId = url.searchParams.get('ownerId');
|
|
529
437
|
const tenantId = url.searchParams.get('tenantId');
|
|
530
438
|
return sendJson(response, 200, {
|
|
531
|
-
triggers: triggerControl.listTriggers({
|
|
439
|
+
triggers: await triggerControl.listTriggers({
|
|
532
440
|
...(ownerType && ownerId
|
|
533
441
|
? {
|
|
534
442
|
owner: {
|
|
@@ -633,14 +541,14 @@ const server = createServer(async (request, response) => {
|
|
|
633
541
|
|
|
634
542
|
if (request.method === 'GET' && url.pathname === '/v1/triggers') {
|
|
635
543
|
return sendJson(response, 200, {
|
|
636
|
-
triggers: store.listTriggers(),
|
|
544
|
+
triggers: await store.listTriggers(),
|
|
637
545
|
});
|
|
638
546
|
}
|
|
639
547
|
|
|
640
548
|
if (request.method === 'GET' && url.pathname === '/v1/trigger-matches') {
|
|
641
549
|
const triggerId = url.searchParams.get('triggerId') ?? undefined;
|
|
642
550
|
return sendJson(response, 200, {
|
|
643
|
-
matches: store.listTriggerMatches(triggerId),
|
|
551
|
+
matches: await store.listTriggerMatches(triggerId),
|
|
644
552
|
});
|
|
645
553
|
}
|
|
646
554
|
|
|
@@ -704,13 +612,6 @@ const server = createServer(async (request, response) => {
|
|
|
704
612
|
});
|
|
705
613
|
}
|
|
706
614
|
|
|
707
|
-
if (request.method === 'POST' && url.pathname === '/v1/events/ingest') {
|
|
708
|
-
const raw = await readRawBody(request);
|
|
709
|
-
const body = JSON.parse(raw.toString('utf8'));
|
|
710
|
-
const result = await processor.ingest(body);
|
|
711
|
-
logProcessingResult(result);
|
|
712
|
-
return sendJson(response, 202, result);
|
|
713
|
-
}
|
|
714
615
|
|
|
715
616
|
if (request.method === 'GET' && url.pathname === '/v1/audit') {
|
|
716
617
|
const afterSequence = Number(url.searchParams.get('afterSequence') ?? -1);
|
|
@@ -731,26 +632,6 @@ const server = createServer(async (request, response) => {
|
|
|
731
632
|
return sendJson(response, 200, store.trace(traceId));
|
|
732
633
|
}
|
|
733
634
|
|
|
734
|
-
if (
|
|
735
|
-
request.method === 'POST' &&
|
|
736
|
-
url.pathname.startsWith('/v1/wakes/') &&
|
|
737
|
-
url.pathname.endsWith('/ack')
|
|
738
|
-
) {
|
|
739
|
-
const wakeId = decodeURIComponent(
|
|
740
|
-
url.pathname.slice('/v1/wakes/'.length, -'/ack'.length),
|
|
741
|
-
);
|
|
742
|
-
const raw = await readRawBody(request);
|
|
743
|
-
const body = raw.length
|
|
744
|
-
? JSON.parse(raw.toString('utf8'))
|
|
745
|
-
: {};
|
|
746
|
-
const handled = await processor.acknowledgeWake(
|
|
747
|
-
wakeId,
|
|
748
|
-
typeof body.runtimeReceiptId === 'string'
|
|
749
|
-
? body.runtimeReceiptId
|
|
750
|
-
: undefined,
|
|
751
|
-
);
|
|
752
|
-
return sendJson(response, 200, handled);
|
|
753
|
-
}
|
|
754
635
|
|
|
755
636
|
return sendJson(response, 404, { error: 'NOT_FOUND' });
|
|
756
637
|
} catch (error) {
|
package/server.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.sarooo17/event-intelligence",
|
|
4
4
|
"title": "MCP Event Intelligence",
|
|
5
|
-
"description": "
|
|
6
|
-
"version": "0.
|
|
5
|
+
"description": "MCP-native CEP for durable agents: event-time patterns, semantic predicates, derived events.",
|
|
6
|
+
"version": "0.6.0",
|
|
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.
|
|
16
|
+
"version": "0.6.0",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
},
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
"name": "TYPESAFE_API_KEY",
|
|
52
|
-
"description": "Optional TypeSafe Jev API key for semantic
|
|
52
|
+
"description": "Optional TypeSafe Jev API key for explicit semantic Pattern AST nodes.",
|
|
53
53
|
"isRequired": false,
|
|
54
54
|
"isSecret": true,
|
|
55
55
|
"format": "string"
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { EventLineage, SemanticDecisionRecord, WakeRecord } from './schemas.js';
|
|
2
|
-
export declare function assertDecisionLineage(event: EventLineage, decision: SemanticDecisionRecord): void;
|
|
3
|
-
export declare function assertWakeLineage(event: EventLineage, decision: SemanticDecisionRecord | null, wake: WakeRecord): void;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export function assertDecisionLineage(event, decision) {
|
|
2
|
-
if (decision.traceId !== event.traceId) {
|
|
3
|
-
throw new Error('Decision traceId does not match source event');
|
|
4
|
-
}
|
|
5
|
-
if (decision.subscriptionId !== event.subscriptionId) {
|
|
6
|
-
throw new Error('Decision subscriptionId does not match source event');
|
|
7
|
-
}
|
|
8
|
-
if (decision.sourceEventId !== event.sourceEventId) {
|
|
9
|
-
throw new Error('Decision sourceEventId does not match source event');
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
export function assertWakeLineage(event, decision, wake) {
|
|
13
|
-
if (wake.traceId !== event.traceId) {
|
|
14
|
-
throw new Error('Wake traceId does not match source event');
|
|
15
|
-
}
|
|
16
|
-
if (wake.subscriptionId !== event.subscriptionId) {
|
|
17
|
-
throw new Error('Wake subscriptionId does not match source event');
|
|
18
|
-
}
|
|
19
|
-
if (wake.sourceEventId !== event.sourceEventId) {
|
|
20
|
-
throw new Error('Wake sourceEventId does not match source event');
|
|
21
|
-
}
|
|
22
|
-
if (decision) {
|
|
23
|
-
assertDecisionLineage(event, decision);
|
|
24
|
-
if (wake.decisionId !== decision.decisionId) {
|
|
25
|
-
throw new Error('Wake decisionId does not match semantic decision');
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
else if (wake.decisionId !== null) {
|
|
29
|
-
throw new Error('Wake has decisionId but no decision record was supplied');
|
|
30
|
-
}
|
|
31
|
-
if (wake.target.runtime !== event.target.runtime ||
|
|
32
|
-
wake.target.kind !== event.target.kind ||
|
|
33
|
-
wake.target.id !== event.target.id) {
|
|
34
|
-
throw new Error('Wake target does not match source event target');
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { EventOccurrence } from '../protocol/types.js';
|
|
2
|
-
import { type EventLineage, type RuntimeTarget } from './schemas.js';
|
|
3
|
-
export interface MapMcpEventInput {
|
|
4
|
-
event: EventOccurrence;
|
|
5
|
-
traceId: string;
|
|
6
|
-
environmentId: string;
|
|
7
|
-
subscriptionId: string;
|
|
8
|
-
serverId: string;
|
|
9
|
-
transport: 'stdio' | 'streamable_http' | 'webhook' | 'poll' | 'internal';
|
|
10
|
-
provider?: string;
|
|
11
|
-
target: RuntimeTarget;
|
|
12
|
-
observedAt: string;
|
|
13
|
-
}
|
|
14
|
-
export declare function mapMcpEventToLineage(input: MapMcpEventInput): Promise<EventLineage>;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { sha256Hex } from './canonical.js';
|
|
2
|
-
import { EventLineageSchema, } from './schemas.js';
|
|
3
|
-
import { EVENT_INTELLIGENCE_PROTOCOL, EVENT_INTELLIGENCE_PROTOCOL_VERSION, EVENT_INTELLIGENCE_SCHEMA_VERSION, } from './version.js';
|
|
4
|
-
export async function mapMcpEventToLineage(input) {
|
|
5
|
-
const payloadHash = await sha256Hex(input.event.data);
|
|
6
|
-
return EventLineageSchema.parse({
|
|
7
|
-
protocol: EVENT_INTELLIGENCE_PROTOCOL,
|
|
8
|
-
protocolVersion: EVENT_INTELLIGENCE_PROTOCOL_VERSION,
|
|
9
|
-
schemaVersion: EVENT_INTELLIGENCE_SCHEMA_VERSION,
|
|
10
|
-
traceId: input.traceId,
|
|
11
|
-
environmentId: input.environmentId,
|
|
12
|
-
subscriptionId: input.subscriptionId,
|
|
13
|
-
sourceEventId: input.event.eventId,
|
|
14
|
-
observedAt: input.observedAt,
|
|
15
|
-
source: {
|
|
16
|
-
serverId: input.serverId,
|
|
17
|
-
transport: input.transport,
|
|
18
|
-
...(input.provider ? { provider: input.provider } : {}),
|
|
19
|
-
cursor: input.event.cursor ?? null,
|
|
20
|
-
},
|
|
21
|
-
target: input.target,
|
|
22
|
-
event: {
|
|
23
|
-
name: input.event.name,
|
|
24
|
-
occurredAt: input.event.timestamp,
|
|
25
|
-
payloadHash,
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
}
|