@ductape/mcp 0.1.43 → 0.1.44

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/dist/index.js CHANGED
@@ -180,29 +180,33 @@ global interceptors, decorators, and type-safe resource handles.
180
180
 
181
181
  SETUP — register once in AppModule:
182
182
 
183
+ ╔══════════════════════════════════════════════════════════════════════════╗
184
+ ║ redisUrl IS REQUIRED TO USE ANY *.dispatch() ║
185
+ ║ ║
186
+ ║ Every dispatch() call (actions, features, events, databases, storage, ║
187
+ ║ graph, notifications, messageBrokers, quotas, fallback) enqueues jobs ║
188
+ ║ via BullMQ over Redis. Without redisUrl the call throws at runtime: ║
189
+ ║ "Queues not configured. dispatch() requires a queue connection." ║
190
+ ║ ║
191
+ ║ *.run(), events.produce(), and @Events.Consumer do NOT need Redis. ║
192
+ ║ Only dispatch() does — and it is non-negotiable. ║
193
+ ╚══════════════════════════════════════════════════════════════════════════╝
194
+
183
195
  import { DuctapeModule } from '@ductape/nestjs';
184
196
 
185
197
  @Module({
186
198
  imports: [
187
199
  DuctapeModule.forIntegration({
188
200
  accessKey: process.env.DUCTAPE_ACCESS_KEY,
189
- product: 'my-product', // optional default — overridable per controller
201
+ product: 'my-product',
190
202
  env: process.env.NODE_ENV === 'production' ? 'prd' : 'snd',
191
- redisUrl: process.env.REDIS_URL, // REQUIRED when using events.dispatch() or @Events.Dispatch
203
+ redisUrl: process.env.DUCTAPE_REDIS_URL, // required no dispatch() works without this
192
204
  }),
193
205
  ],
194
206
  })
195
207
  export class AppModule {}
196
208
 
197
- IMPORTANT redisUrl:
198
- ALL *.dispatch() calls (actions.dispatch, features.dispatch, events.dispatch, databases.dispatch,
199
- storage.dispatch, graph.dispatch, notifications.dispatch, messageBrokers.dispatch, quotas.dispatch,
200
- fallback.dispatch, etc.) enqueue jobs via BullMQ, which requires a Redis connection.
201
- Without redisUrl ANY dispatch() call throws "Queues not configured. dispatch() requires a queue connection."
202
- Set REDIS_URL (e.g. redis://localhost:6379 or a managed Redis connection string) and pass it as redisUrl.
203
- *.run(), events.produce(), and @Events.Consumer do NOT require Redis — only dispatch() does.
204
-
205
- // Async (e.g. pulling key from ConfigService):
209
+ // Async (e.g. pulling from ConfigService):
206
210
  DuctapeModule.forRootAsync({
207
211
  imports: [ConfigModule],
208
212
  inject: [ConfigService],
@@ -210,10 +214,14 @@ SETUP — register once in AppModule:
210
214
  accessKey: cfg.get('DUCTAPE_ACCESS_KEY'),
211
215
  product: cfg.get('DUCTAPE_PRODUCT'),
212
216
  env: cfg.get('DUCTAPE_ENV'),
213
- redisUrl: cfg.get('REDIS_URL'), // required for dispatch
217
+ redisUrl: cfg.get('DUCTAPE_REDIS_URL'), // required no dispatch() works without this
214
218
  }),
215
219
  })
216
220
 
221
+ Environment variable (add to .env and deployment secrets):
222
+ DUCTAPE_REDIS_URL=redis://localhost:6379 # local dev
223
+ DUCTAPE_REDIS_URL=rediss://:<password>@host:6380 # managed Redis (TLS)
224
+
217
225
  INJECTING IN SERVICES AND CONTROLLERS — use @InjectContext():
218
226
 
219
227
  import { InjectContext, DuctapeContext } from '@ductape/nestjs';
@@ -268,7 +276,7 @@ FOR MESSAGING (events.produce / events.consume / events.dispatch):
268
276
  @Events.Produce({ event: 'broker-tag:topic-tag' })
269
277
  emitOrderCreated(payload: { orderId: string }) { return payload; }
270
278
 
271
- Dispatch (scheduled or immediate) — REQUIRES redisUrl in DuctapeModule.forIntegration:
279
+ Dispatch (scheduled or immediate) — dispatch() CANNOT be used without redisUrl in forIntegration:
272
280
  @Events.Dispatch({ broker: 'order-events', event: 'order-events:order-created', schedule: { every: 60000 } })
273
281
  dispatchHeartbeat(payload: { message: { ping: boolean } }) { return payload; }
274
282
 
@@ -343,7 +351,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
343
351
  actions.fetch [app_tag, action_tag]
344
352
  actions.list [app_tag]
345
353
  actions.run [{ product, env, app, action, input: { "body:fieldName": value, ... } }] ← CALL ductape_generate_payload FIRST (operation_family="action", method="run", targets={app, action})
346
- actions.dispatch [{ product, env, app, action, input, retries?, session?, cache?, schedule?: { start_at?, cron?, every?, limit?, tz? } }] ← CALL ductape_generate_payload FIRST (operation_family="action", method="dispatch")
354
+ actions.dispatch [{ product, env, app, action, input, retries?, session?, cache?, schedule?: { start_at?, cron?, every?, limit?, tz? } }] ← CALL ductape_generate_payload FIRST (operation_family="action", method="dispatch") — requires redisUrl in ductape initialization
347
355
 
348
356
  ━━━ MODULE: auths ━━━
349
357
  auths.create [app_tag, data: { tag: string, name: string, setup_type: "header"|"bearer"|"basic"|"oauth2"|"apikey", expiry: number, period: "seconds"|"minutes"|"hours"|"days", description: string, action_tag?: string }]
@@ -421,7 +429,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
421
429
  quotas.list [product_tag]
422
430
  quotas.delete [product_tag, quota_tag]
423
431
  quotas.run [{ product: string, env: string, tag: string, input: { fieldName: value }, session?: string, cache?: string }] ← CALL ductape_generate_payload FIRST (operation_family="quota", method="run", targets={tag})
424
- quotas.dispatch [{ product: string, env: string, tag: string, input: object, session?: string, cache?: string, schedule?: { cron?: string, delay?: number, at?: string } }] ← CALL ductape_generate_payload FIRST (operation_family="quota", method="dispatch")
432
+ quotas.dispatch [{ product: string, env: string, tag: string, input: object, session?: string, cache?: string, schedule?: { cron?: string, delay?: number, at?: string } }] ← CALL ductape_generate_payload FIRST (operation_family="quota", method="dispatch") — requires redisUrl in ductape initialization
425
433
 
426
434
  ━━━ MODULE: fallback ━━━
427
435
  fallback.create [product_tag, data: {
@@ -464,7 +472,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
464
472
  fallback.list [product_tag]
465
473
  fallback.delete [product_tag, fallback_tag]
466
474
  fallback.run [{ product: string, env: string, tag: string, input: { fieldName: value }, session?: string, cache?: string }] ← CALL ductape_generate_payload FIRST (operation_family="fallback", method="run", targets={tag})
467
- fallback.dispatch [{ product: string, env: string, tag: string, input: object, session?: string, cache?: string, schedule?: { cron?: string, delay?: number, at?: string } }] ← CALL ductape_generate_payload FIRST (operation_family="fallback", method="dispatch")
475
+ fallback.dispatch [{ product: string, env: string, tag: string, input: object, session?: string, cache?: string, schedule?: { cron?: string, delay?: number, at?: string } }] ← CALL ductape_generate_payload FIRST (operation_family="fallback", method="dispatch") — requires redisUrl in ductape initialization
468
476
 
469
477
  ━━━ MODULE: health ━━━
470
478
  health.create [product_tag, data: { tag: string, name: string, description?: string, app?: string, event?: string, probe?: { type: "app"|"database"|"feature", app?: string, event?: string, input?: object }, interval: number, retries: number, envs: [{ slug: string, input?: object }], onFailure?: { notifications?: [{ notification: string, message: string, channels: { email?: { recipients: string[] }, push?: { recipients?: string[] }, sms?: { recipients: string[] } } }], webhooks?: [{ url: string, method?: "GET"|"POST", headers?: object, body?: object }] } }]
@@ -491,7 +499,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
491
499
  notifications.push.send [{ product, env, notification, input: { ... }, session?, cache? }] ← CALL ductape_generate_payload FIRST (operation_family="notification", method="push.send")
492
500
  notifications.sms.send [{ product, env, notification, input: { ... }, session?, cache? }] ← CALL ductape_generate_payload FIRST (operation_family="notification", method="sms.send")
493
501
  notifications.callback.send [{ product, env, notification, input: { ... }, session?, cache? }] ← CALL ductape_generate_payload FIRST (operation_family="notification", method="callback.send")
494
- notifications.dispatch [{ product, env, notification, event, input, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }] ← CALL ductape_generate_payload FIRST (operation_family="notification", method="dispatch")
502
+ notifications.dispatch [{ product, env, notification, event, input, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }] ← CALL ductape_generate_payload FIRST (operation_family="notification", method="dispatch") — requires redisUrl in ductape initialization
495
503
  notifications.getMessages [{ product_tag?, env?, notification_tag?, status?, type?, start_date?, end_date?, page?, limit? }]
496
504
 
497
505
  ━━━ MODULE: messageBrokers ━━━
@@ -514,7 +522,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
514
522
  messageBrokers.topics.list [product_tag, broker_tag] ← safe via ductape_execute
515
523
  messageBrokers.produce [{ product, env, event: "broker_tag:topic_tag", message: { key: value }, session?, cache? }]
516
524
  messageBrokers.consume [{ product, env, event: "broker_tag:topic_tag", callback: "function_ref" }]
517
- messageBrokers.dispatch [{ product, env, broker, event, input: { message }, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }]
525
+ messageBrokers.dispatch [{ product, env, broker, event, input: { message }, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }] — requires redisUrl in ductape initialization
518
526
  messageBrokers.messages.query [{ product, env, brokerTag, topicTag?, producerTag?, consumerTag?, status?, startDate?, endDate?, page?, limit? }]
519
527
  messageBrokers.messages.getProducers [{ product, env, brokerTag, topicTag?, page?, limit? }]
520
528
  messageBrokers.messages.getConsumers [{ product, env, brokerTag, topicTag?, page?, limit? }]
@@ -540,7 +548,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
540
548
  storage.files.delete [{ product, env, storage, fileName }]
541
549
  storage.files.list [{ product, env, storage, prefix?, limit?, continuationToken? }]
542
550
  storage.files.getSignedUrl [{ product, env, storage, fileName, expiresIn?, action? }]
543
- storage.dispatch [{ product, env, storage, operation, input, retries?, session?, cache?, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="storage", method="dispatch", targets={storage})
551
+ storage.dispatch [{ product, env, storage, operation, input, retries?, session?, cache?, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="storage", method="dispatch", targets={storage}) — requires redisUrl in ductape initialization
544
552
 
545
553
  ━━━ MODULE: databases ━━━
546
554
  databases.create [{ product, tag, name, description?, type: "mongodb"|"postgresql"|"mysql"|"sqlite",
@@ -608,8 +616,8 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
608
616
  databases.action.fetch [action_tag]
609
617
  databases.action.list [database_tag]
610
618
  databases.action.delete [action_tag]
611
- databases.action.dispatch [{ product, env, database, action, input, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="database", method="dispatch", targets={database: "db_tag", table: "table_name"})
612
- databases.dispatch [{ product, env, database, action, input, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="database", method="dispatch", targets={database: "db_tag", table: "table_name"})
619
+ databases.action.dispatch [{ product, env, database, action, input, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="database", method="dispatch", targets={database: "db_tag", table: "table_name"}) — requires redisUrl in ductape initialization
620
+ databases.dispatch [{ product, env, database, action, input, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="database", method="dispatch", targets={database: "db_tag", table: "table_name"}) — requires redisUrl in ductape initialization
613
621
  databases.beginTransaction [{ product, env, database, isolationLevel?: "READ_COMMITTED"|"REPEATABLE_READ"|"SERIALIZABLE" }]
614
622
  → returns a transaction object; pass it to insert/update/delete/upsert/query calls as the last argument.
615
623
  Commit with: transaction.commit() Rollback with: transaction.rollback()
@@ -671,7 +679,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
671
679
  graph.beginTransaction [options?]
672
680
  graph.commitTransaction [transaction]
673
681
  graph.rollbackTransaction [transaction]
674
- graph.dispatch [data] ← CALL ductape_generate_payload FIRST (operation_family="graph", method="dispatch", targets={graph})
682
+ graph.dispatch [data] ← CALL ductape_generate_payload FIRST (operation_family="graph", method="dispatch", targets={graph}) — requires redisUrl in ductape initialization
675
683
 
676
684
  ━━━ MODULE: vector ━━━
677
685
  vector.create [{ product, tag, name, description?, provider: "pinecone"|"qdrant"|"weaviate", dimensions: number, metric?: "cosine"|"euclidean"|"dotproduct", envs: [{slug, api_key, environment?}] }]
@@ -791,7 +799,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
791
799
  timeout?: number
792
800
  }]
793
801
 
794
- features.dispatch [{ ← CALL ductape_generate_payload FIRST (operation_family="features", method="dispatch", targets={feature})
802
+ features.dispatch [{ ← CALL ductape_generate_payload FIRST (operation_family="features", method="dispatch", targets={feature}) — requires redisUrl in ductape initialization
795
803
  product: string,
796
804
  env: string,
797
805
  feature: string,
@@ -3268,6 +3276,7 @@ async function loadMcpSdk() {
3268
3276
  console.error('Failed to load MCP SDK. Install: npm install @modelcontextprotocol/sdk zod\n' +
3269
3277
  'Or v2 alpha: npm install @modelcontextprotocol/server zod @cfworker/json-schema');
3270
3278
  process.exit(1);
3279
+ throw new Error('MCP SDK not available');
3271
3280
  }
3272
3281
  function handleCliFlags() {
3273
3282
  const arg = process.argv[2];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ductape/mcp",
3
- "version": "0.1.43",
3
+ "version": "0.1.44",
4
4
  "description": "MCP server that exposes Ductape SDK operations via the backend proxy",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/index.ts CHANGED
@@ -191,29 +191,33 @@ global interceptors, decorators, and type-safe resource handles.
191
191
 
192
192
  SETUP — register once in AppModule:
193
193
 
194
+ ╔══════════════════════════════════════════════════════════════════════════╗
195
+ ║ redisUrl IS REQUIRED TO USE ANY *.dispatch() ║
196
+ ║ ║
197
+ ║ Every dispatch() call (actions, features, events, databases, storage, ║
198
+ ║ graph, notifications, messageBrokers, quotas, fallback) enqueues jobs ║
199
+ ║ via BullMQ over Redis. Without redisUrl the call throws at runtime: ║
200
+ ║ "Queues not configured. dispatch() requires a queue connection." ║
201
+ ║ ║
202
+ ║ *.run(), events.produce(), and @Events.Consumer do NOT need Redis. ║
203
+ ║ Only dispatch() does — and it is non-negotiable. ║
204
+ ╚══════════════════════════════════════════════════════════════════════════╝
205
+
194
206
  import { DuctapeModule } from '@ductape/nestjs';
195
207
 
196
208
  @Module({
197
209
  imports: [
198
210
  DuctapeModule.forIntegration({
199
211
  accessKey: process.env.DUCTAPE_ACCESS_KEY,
200
- product: 'my-product', // optional default — overridable per controller
212
+ product: 'my-product',
201
213
  env: process.env.NODE_ENV === 'production' ? 'prd' : 'snd',
202
- redisUrl: process.env.REDIS_URL, // REQUIRED when using events.dispatch() or @Events.Dispatch
214
+ redisUrl: process.env.DUCTAPE_REDIS_URL, // required no dispatch() works without this
203
215
  }),
204
216
  ],
205
217
  })
206
218
  export class AppModule {}
207
219
 
208
- IMPORTANT redisUrl:
209
- ALL *.dispatch() calls (actions.dispatch, features.dispatch, events.dispatch, databases.dispatch,
210
- storage.dispatch, graph.dispatch, notifications.dispatch, messageBrokers.dispatch, quotas.dispatch,
211
- fallback.dispatch, etc.) enqueue jobs via BullMQ, which requires a Redis connection.
212
- Without redisUrl ANY dispatch() call throws "Queues not configured. dispatch() requires a queue connection."
213
- Set REDIS_URL (e.g. redis://localhost:6379 or a managed Redis connection string) and pass it as redisUrl.
214
- *.run(), events.produce(), and @Events.Consumer do NOT require Redis — only dispatch() does.
215
-
216
- // Async (e.g. pulling key from ConfigService):
220
+ // Async (e.g. pulling from ConfigService):
217
221
  DuctapeModule.forRootAsync({
218
222
  imports: [ConfigModule],
219
223
  inject: [ConfigService],
@@ -221,10 +225,14 @@ SETUP — register once in AppModule:
221
225
  accessKey: cfg.get('DUCTAPE_ACCESS_KEY'),
222
226
  product: cfg.get('DUCTAPE_PRODUCT'),
223
227
  env: cfg.get('DUCTAPE_ENV'),
224
- redisUrl: cfg.get('REDIS_URL'), // required for dispatch
228
+ redisUrl: cfg.get('DUCTAPE_REDIS_URL'), // required no dispatch() works without this
225
229
  }),
226
230
  })
227
231
 
232
+ Environment variable (add to .env and deployment secrets):
233
+ DUCTAPE_REDIS_URL=redis://localhost:6379 # local dev
234
+ DUCTAPE_REDIS_URL=rediss://:<password>@host:6380 # managed Redis (TLS)
235
+
228
236
  INJECTING IN SERVICES AND CONTROLLERS — use @InjectContext():
229
237
 
230
238
  import { InjectContext, DuctapeContext } from '@ductape/nestjs';
@@ -279,7 +287,7 @@ FOR MESSAGING (events.produce / events.consume / events.dispatch):
279
287
  @Events.Produce({ event: 'broker-tag:topic-tag' })
280
288
  emitOrderCreated(payload: { orderId: string }) { return payload; }
281
289
 
282
- Dispatch (scheduled or immediate) — REQUIRES redisUrl in DuctapeModule.forIntegration:
290
+ Dispatch (scheduled or immediate) — dispatch() CANNOT be used without redisUrl in forIntegration:
283
291
  @Events.Dispatch({ broker: 'order-events', event: 'order-events:order-created', schedule: { every: 60000 } })
284
292
  dispatchHeartbeat(payload: { message: { ping: boolean } }) { return payload; }
285
293
 
@@ -354,7 +362,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
354
362
  actions.fetch [app_tag, action_tag]
355
363
  actions.list [app_tag]
356
364
  actions.run [{ product, env, app, action, input: { "body:fieldName": value, ... } }] ← CALL ductape_generate_payload FIRST (operation_family="action", method="run", targets={app, action})
357
- actions.dispatch [{ product, env, app, action, input, retries?, session?, cache?, schedule?: { start_at?, cron?, every?, limit?, tz? } }] ← CALL ductape_generate_payload FIRST (operation_family="action", method="dispatch")
365
+ actions.dispatch [{ product, env, app, action, input, retries?, session?, cache?, schedule?: { start_at?, cron?, every?, limit?, tz? } }] ← CALL ductape_generate_payload FIRST (operation_family="action", method="dispatch") — requires redisUrl in ductape initialization
358
366
 
359
367
  ━━━ MODULE: auths ━━━
360
368
  auths.create [app_tag, data: { tag: string, name: string, setup_type: "header"|"bearer"|"basic"|"oauth2"|"apikey", expiry: number, period: "seconds"|"minutes"|"hours"|"days", description: string, action_tag?: string }]
@@ -432,7 +440,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
432
440
  quotas.list [product_tag]
433
441
  quotas.delete [product_tag, quota_tag]
434
442
  quotas.run [{ product: string, env: string, tag: string, input: { fieldName: value }, session?: string, cache?: string }] ← CALL ductape_generate_payload FIRST (operation_family="quota", method="run", targets={tag})
435
- quotas.dispatch [{ product: string, env: string, tag: string, input: object, session?: string, cache?: string, schedule?: { cron?: string, delay?: number, at?: string } }] ← CALL ductape_generate_payload FIRST (operation_family="quota", method="dispatch")
443
+ quotas.dispatch [{ product: string, env: string, tag: string, input: object, session?: string, cache?: string, schedule?: { cron?: string, delay?: number, at?: string } }] ← CALL ductape_generate_payload FIRST (operation_family="quota", method="dispatch") — requires redisUrl in ductape initialization
436
444
 
437
445
  ━━━ MODULE: fallback ━━━
438
446
  fallback.create [product_tag, data: {
@@ -475,7 +483,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
475
483
  fallback.list [product_tag]
476
484
  fallback.delete [product_tag, fallback_tag]
477
485
  fallback.run [{ product: string, env: string, tag: string, input: { fieldName: value }, session?: string, cache?: string }] ← CALL ductape_generate_payload FIRST (operation_family="fallback", method="run", targets={tag})
478
- fallback.dispatch [{ product: string, env: string, tag: string, input: object, session?: string, cache?: string, schedule?: { cron?: string, delay?: number, at?: string } }] ← CALL ductape_generate_payload FIRST (operation_family="fallback", method="dispatch")
486
+ fallback.dispatch [{ product: string, env: string, tag: string, input: object, session?: string, cache?: string, schedule?: { cron?: string, delay?: number, at?: string } }] ← CALL ductape_generate_payload FIRST (operation_family="fallback", method="dispatch") — requires redisUrl in ductape initialization
479
487
 
480
488
  ━━━ MODULE: health ━━━
481
489
  health.create [product_tag, data: { tag: string, name: string, description?: string, app?: string, event?: string, probe?: { type: "app"|"database"|"feature", app?: string, event?: string, input?: object }, interval: number, retries: number, envs: [{ slug: string, input?: object }], onFailure?: { notifications?: [{ notification: string, message: string, channels: { email?: { recipients: string[] }, push?: { recipients?: string[] }, sms?: { recipients: string[] } } }], webhooks?: [{ url: string, method?: "GET"|"POST", headers?: object, body?: object }] } }]
@@ -502,7 +510,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
502
510
  notifications.push.send [{ product, env, notification, input: { ... }, session?, cache? }] ← CALL ductape_generate_payload FIRST (operation_family="notification", method="push.send")
503
511
  notifications.sms.send [{ product, env, notification, input: { ... }, session?, cache? }] ← CALL ductape_generate_payload FIRST (operation_family="notification", method="sms.send")
504
512
  notifications.callback.send [{ product, env, notification, input: { ... }, session?, cache? }] ← CALL ductape_generate_payload FIRST (operation_family="notification", method="callback.send")
505
- notifications.dispatch [{ product, env, notification, event, input, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }] ← CALL ductape_generate_payload FIRST (operation_family="notification", method="dispatch")
513
+ notifications.dispatch [{ product, env, notification, event, input, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }] ← CALL ductape_generate_payload FIRST (operation_family="notification", method="dispatch") — requires redisUrl in ductape initialization
506
514
  notifications.getMessages [{ product_tag?, env?, notification_tag?, status?, type?, start_date?, end_date?, page?, limit? }]
507
515
 
508
516
  ━━━ MODULE: messageBrokers ━━━
@@ -525,7 +533,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
525
533
  messageBrokers.topics.list [product_tag, broker_tag] ← safe via ductape_execute
526
534
  messageBrokers.produce [{ product, env, event: "broker_tag:topic_tag", message: { key: value }, session?, cache? }]
527
535
  messageBrokers.consume [{ product, env, event: "broker_tag:topic_tag", callback: "function_ref" }]
528
- messageBrokers.dispatch [{ product, env, broker, event, input: { message }, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }]
536
+ messageBrokers.dispatch [{ product, env, broker, event, input: { message }, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }] — requires redisUrl in ductape initialization
529
537
  messageBrokers.messages.query [{ product, env, brokerTag, topicTag?, producerTag?, consumerTag?, status?, startDate?, endDate?, page?, limit? }]
530
538
  messageBrokers.messages.getProducers [{ product, env, brokerTag, topicTag?, page?, limit? }]
531
539
  messageBrokers.messages.getConsumers [{ product, env, brokerTag, topicTag?, page?, limit? }]
@@ -551,7 +559,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
551
559
  storage.files.delete [{ product, env, storage, fileName }]
552
560
  storage.files.list [{ product, env, storage, prefix?, limit?, continuationToken? }]
553
561
  storage.files.getSignedUrl [{ product, env, storage, fileName, expiresIn?, action? }]
554
- storage.dispatch [{ product, env, storage, operation, input, retries?, session?, cache?, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="storage", method="dispatch", targets={storage})
562
+ storage.dispatch [{ product, env, storage, operation, input, retries?, session?, cache?, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="storage", method="dispatch", targets={storage}) — requires redisUrl in ductape initialization
555
563
 
556
564
  ━━━ MODULE: databases ━━━
557
565
  databases.create [{ product, tag, name, description?, type: "mongodb"|"postgresql"|"mysql"|"sqlite",
@@ -619,8 +627,8 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
619
627
  databases.action.fetch [action_tag]
620
628
  databases.action.list [database_tag]
621
629
  databases.action.delete [action_tag]
622
- databases.action.dispatch [{ product, env, database, action, input, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="database", method="dispatch", targets={database: "db_tag", table: "table_name"})
623
- databases.dispatch [{ product, env, database, action, input, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="database", method="dispatch", targets={database: "db_tag", table: "table_name"})
630
+ databases.action.dispatch [{ product, env, database, action, input, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="database", method="dispatch", targets={database: "db_tag", table: "table_name"}) — requires redisUrl in ductape initialization
631
+ databases.dispatch [{ product, env, database, action, input, schedule? }] ← CALL ductape_generate_payload FIRST (operation_family="database", method="dispatch", targets={database: "db_tag", table: "table_name"}) — requires redisUrl in ductape initialization
624
632
  databases.beginTransaction [{ product, env, database, isolationLevel?: "READ_COMMITTED"|"REPEATABLE_READ"|"SERIALIZABLE" }]
625
633
  → returns a transaction object; pass it to insert/update/delete/upsert/query calls as the last argument.
626
634
  Commit with: transaction.commit() Rollback with: transaction.rollback()
@@ -682,7 +690,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
682
690
  graph.beginTransaction [options?]
683
691
  graph.commitTransaction [transaction]
684
692
  graph.rollbackTransaction [transaction]
685
- graph.dispatch [data] ← CALL ductape_generate_payload FIRST (operation_family="graph", method="dispatch", targets={graph})
693
+ graph.dispatch [data] ← CALL ductape_generate_payload FIRST (operation_family="graph", method="dispatch", targets={graph}) — requires redisUrl in ductape initialization
686
694
 
687
695
  ━━━ MODULE: vector ━━━
688
696
  vector.create [{ product, tag, name, description?, provider: "pinecone"|"qdrant"|"weaviate", dimensions: number, metric?: "cosine"|"euclidean"|"dotproduct", envs: [{slug, api_key, environment?}] }]
@@ -802,7 +810,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
802
810
  timeout?: number
803
811
  }]
804
812
 
805
- features.dispatch [{ ← CALL ductape_generate_payload FIRST (operation_family="features", method="dispatch", targets={feature})
813
+ features.dispatch [{ ← CALL ductape_generate_payload FIRST (operation_family="features", method="dispatch", targets={feature}) — requires redisUrl in ductape initialization
806
814
  product: string,
807
815
  env: string,
808
816
  feature: string,
@@ -3355,6 +3363,7 @@ async function loadMcpSdk(): Promise<{
3355
3363
  'Or v2 alpha: npm install @modelcontextprotocol/server zod @cfworker/json-schema',
3356
3364
  );
3357
3365
  process.exit(1);
3366
+ throw new Error('MCP SDK not available');
3358
3367
  }
3359
3368
 
3360
3369
  function handleCliFlags(): boolean {
package/tsconfig.json CHANGED
@@ -9,7 +9,8 @@
9
9
  "esModuleInterop": true,
10
10
  "skipLibCheck": true,
11
11
  "declaration": true,
12
- "declarationMap": true
12
+ "declarationMap": true,
13
+ "types": ["node"]
13
14
  },
14
15
  "include": ["src/**/*"],
15
16
  "exclude": ["node_modules"]