@ductape/mcp 0.1.45 → 0.1.47

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
@@ -522,7 +522,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
522
522
  events.topics.list [product_tag, broker_tag] ← safe via ductape_execute
523
523
  events.produce [{ product, env, event: "broker_tag:topic_tag", message: { key: value }, session?, cache? }]
524
524
  events.consume [{ product, env, event: "broker_tag:topic_tag", callback: "function_ref" }]
525
- events.dispatch [{ product, env, broker, event, input: { message }, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }] — requires redisUrl in ductape initialization
525
+ events.dispatch [{ product, env, event: "broker_tag:topic_tag", input: { message }, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }] — event is always the fully-qualified "broker:topic" string; do NOT pass broker separately — requires redisUrl in ductape initialization
526
526
  events.messages.query [{ product, env, brokerTag, topicTag?, producerTag?, consumerTag?, status?, startDate?, endDate?, page?, limit? }]
527
527
  events.messages.getProducers [{ product, env, brokerTag, topicTag?, page?, limit? }]
528
528
  events.messages.getConsumers [{ product, env, brokerTag, topicTag?, page?, limit? }]
@@ -2579,8 +2579,7 @@ Import (register an EXISTING cloud resource):
2579
2579
  SCHEDULED DISPATCH (background job):
2580
2580
  ductape_execute("events.dispatch", [{
2581
2581
  product, env,
2582
- broker: "order-events", // broker tag
2583
- event: "order-events:reminder-due", // "broker:topic"
2582
+ event: "order-events:reminder-due", // fully-qualified "broker-tag:topic-tag" — no separate broker field
2584
2583
  input: { message: { orderId: "123" } },
2585
2584
  retries?: 3,
2586
2585
  session?: "session-tag:jwt",
@@ -3396,7 +3395,26 @@ async function main() {
3396
3395
  }
3397
3396
  // The TS SDK uses ductape.events.* for broker operations; the backend proxy uses messageBrokers.
3398
3397
  const proxyModule = args.module === 'events' ? 'messageBrokers' : args.module;
3399
- const result = await executeViaProxy(key, proxyModule, args.method, args.params);
3398
+ // Normalize events.dispatch params: event must be fully-qualified "broker:topic".
3399
+ // If an agent passes both broker and event="broker:topic", strip broker and de-duplicate.
3400
+ let params = args.params;
3401
+ if ((args.module === 'events' || args.module === 'messageBrokers') && args.method === 'dispatch') {
3402
+ params = params.map((p) => {
3403
+ if (p && typeof p === 'object' && !Array.isArray(p)) {
3404
+ const obj = p;
3405
+ const broker = typeof obj['broker'] === 'string' ? obj['broker'] : '';
3406
+ const event = typeof obj['event'] === 'string' ? obj['event'] : '';
3407
+ if (broker && event) {
3408
+ // Strip broker prefix if event is already "broker:..." to avoid "broker:broker:topic"
3409
+ const normalized = event.startsWith(broker + ':') ? event : `${broker}:${event}`;
3410
+ const { broker: _removed, ...rest } = obj;
3411
+ return { ...rest, event: normalized };
3412
+ }
3413
+ }
3414
+ return p;
3415
+ });
3416
+ }
3417
+ const result = await executeViaProxy(key, proxyModule, args.method, params);
3400
3418
  return { content: [{ type: 'text', text: JSON.stringify(result ?? null, null, 2) }] };
3401
3419
  }
3402
3420
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ductape/mcp",
3
- "version": "0.1.45",
3
+ "version": "0.1.47",
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
@@ -533,7 +533,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
533
533
  events.topics.list [product_tag, broker_tag] ← safe via ductape_execute
534
534
  events.produce [{ product, env, event: "broker_tag:topic_tag", message: { key: value }, session?, cache? }]
535
535
  events.consume [{ product, env, event: "broker_tag:topic_tag", callback: "function_ref" }]
536
- events.dispatch [{ product, env, broker, event, input: { message }, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }] — requires redisUrl in ductape initialization
536
+ events.dispatch [{ product, env, event: "broker_tag:topic_tag", input: { message }, retries?, session?, cache?, schedule?: { cron?, every?, start_at? } }] — event is always the fully-qualified "broker:topic" string; do NOT pass broker separately — requires redisUrl in ductape initialization
537
537
  events.messages.query [{ product, env, brokerTag, topicTag?, producerTag?, consumerTag?, status?, startDate?, endDate?, page?, limit? }]
538
538
  events.messages.getProducers [{ product, env, brokerTag, topicTag?, page?, limit? }]
539
539
  events.messages.getConsumers [{ product, env, brokerTag, topicTag?, page?, limit? }]
@@ -2652,8 +2652,7 @@ Import (register an EXISTING cloud resource):
2652
2652
  SCHEDULED DISPATCH (background job):
2653
2653
  ductape_execute("events.dispatch", [{
2654
2654
  product, env,
2655
- broker: "order-events", // broker tag
2656
- event: "order-events:reminder-due", // "broker:topic"
2655
+ event: "order-events:reminder-due", // fully-qualified "broker-tag:topic-tag" — no separate broker field
2657
2656
  input: { message: { orderId: "123" } },
2658
2657
  retries?: 3,
2659
2658
  session?: "session-tag:jwt",
@@ -3494,7 +3493,28 @@ async function main() {
3494
3493
  }
3495
3494
  // The TS SDK uses ductape.events.* for broker operations; the backend proxy uses messageBrokers.
3496
3495
  const proxyModule: SDKModule = args.module === 'events' ? 'messageBrokers' : args.module;
3497
- const result = await executeViaProxy(key, proxyModule, args.method, args.params);
3496
+
3497
+ // Normalize events.dispatch params: event must be fully-qualified "broker:topic".
3498
+ // If an agent passes both broker and event="broker:topic", strip broker and de-duplicate.
3499
+ let params = args.params;
3500
+ if ((args.module === 'events' || args.module === 'messageBrokers') && args.method === 'dispatch') {
3501
+ params = params.map((p) => {
3502
+ if (p && typeof p === 'object' && !Array.isArray(p)) {
3503
+ const obj = p as Record<string, unknown>;
3504
+ const broker = typeof obj['broker'] === 'string' ? obj['broker'] : '';
3505
+ const event = typeof obj['event'] === 'string' ? obj['event'] : '';
3506
+ if (broker && event) {
3507
+ // Strip broker prefix if event is already "broker:..." to avoid "broker:broker:topic"
3508
+ const normalized = event.startsWith(broker + ':') ? event : `${broker}:${event}`;
3509
+ const { broker: _removed, ...rest } = obj;
3510
+ return { ...rest, event: normalized };
3511
+ }
3512
+ }
3513
+ return p;
3514
+ });
3515
+ }
3516
+
3517
+ const result = await executeViaProxy(key, proxyModule, args.method, params);
3498
3518
  return { content: [{ type: 'text', text: JSON.stringify(result ?? null, null, 2) }] };
3499
3519
  } catch (err) {
3500
3520
  const message = err instanceof Error ? err.message : String(err);