@ductape/mcp 0.2.26 → 0.2.28

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.
Files changed (2) hide show
  1. package/dist/index.js +76 -25
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -780,11 +780,21 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
780
780
  databases.migration.rollback [migrations, count?]
781
781
  databases.migration.history []
782
782
  databases.migration.status [migrations]
783
- databases.action.create [{ product, database, data: { tag, name, description?, type:"sql"|"nosql", query } }]
784
- databases.action.update [{ product: string, tag: string, data: { name?: string, description?: string, query?: string } }]
785
- databases.action.fetch [action_tag]
786
- databases.action.list [database_tag]
787
- databases.action.delete [action_tag]
783
+ databases.action.create [{ tag: "product:database:action", name, tableName, operation: "query"|"insert"|"update"|"delete"|"upsert"|"aggregate"|"rawSql", template: { where?, select?, limit?, offset?, orderBy?, records?, query?, params?, ... }, description?, filterTemplate? }]
784
+ ADMINISTRATIVE (access key required). FORBIDDEN via ductape_execute (publishable key)
785
+ use ductape_cli("db actions create --action-file action.json") instead. tag MUST be fully qualified
786
+ "product_tag:database_tag:action_tag" — a 2-part "database:action" shorthand only resolves
787
+ inside a long-lived process that already has that product's builder cached, never in a
788
+ fresh CLI/MCP call. This is pure metadata registration; it never connects to the live
789
+ database, so it does NOT require the database to be reachable at call time.
790
+ databases.action.update [{ tag, name?, description?, template?, filterTemplate? }]
791
+ ← ADMINISTRATIVE. Use ductape_cli("db actions update --tag <tag> --action-file patch.json").
792
+ databases.action.fetch [action_tag] ← read-only, safe via ductape_execute
793
+ databases.action.fetchAll [database_tag] ← read-only, safe via ductape_execute.
794
+ NOTE: the method is fetchAll — "action.list" is not a callable method on this sub-object.
795
+ databases.action.delete [action_tag] ← ADMINISTRATIVE. Use ductape_cli("db actions delete <tag>").
796
+ databases.execute [{ product, env, database, action, input, session? }] ← synchronous saved-action execution
797
+ CLI: ductape db actions execute --action-file execute.json --json
788
798
  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
789
799
  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
790
800
  databases.beginTransaction [{ product, env, database, isolationLevel?: "READ_COMMITTED"|"REPEATABLE_READ"|"SERIALIZABLE" }]
@@ -845,6 +855,13 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
845
855
  graph.getAction [actionTag, graphTag?, productTag?]
846
856
  graph.updateAction [actionTag, updates, graphTag?, productTag?]
847
857
  graph.deleteAction [actionTag, graphTag?, productTag?]
858
+ graph.action.create [{ product, graph|graphTag, name, description?, operation, query, parameters? }]
859
+ graph.action.update [{ product, graph|graphTag, action|actionTag, name?, description?, query?, parameters? }]
860
+ graph.action.fetch [{ product, graph|graphTag, action|actionTag }]
861
+ graph.action.fetchAll [{ product, graph|graphTag }]
862
+ graph.action.delete [{ product, graph|graphTag, action|actionTag }]
863
+ graph.action.execute [{ product, env, graph, action, input }]
864
+ graph.action.dispatch [{ product, env, graph, event, input, schedule? }]
848
865
  graph.beginTransaction [options?]
849
866
  graph.commitTransaction [transaction]
850
867
  graph.rollbackTransaction [transaction]
@@ -879,6 +896,12 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
879
896
  vector.deleteIndex [{ product, env, vector, name }]
880
897
  vector.listIndexes [{ product, env, vector }]
881
898
  vector.count [{ product, env, vector, namespace? }]
899
+ vector.actions.create [{ product, vector, actionTag, name, operation, template, description?, parameters? }]
900
+ vector.actions.update [{ product, vector, actionTag, name?, description?, template?, parameters? }]
901
+ vector.actions.fetch [{ product, vector, actionTag }]
902
+ vector.actions.fetchAll [{ product, vector }]
903
+ vector.actions.delete [{ product, vector, actionTag }]
904
+ vector.actions.execute [{ product, env, vector, action, input }]
882
905
 
883
906
  ━━━ MODULE: features ━━━
884
907
  Feature definitions are code-first. Use features.define in application source; do not call
@@ -910,7 +933,8 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
910
933
  // ctx.step(tag, fn, rollback?, opts?) – define a durable step
911
934
  // ctx.api.run({ app, action, input }) – call an app action (NOT 'event' -- that field name
912
935
  // only applies to ctx.database/ctx.notification/ctx.storage below, never ctx.api/ctx.action)
913
- // ctx.database.query/insert/update/delete({ database, event, ... })
936
+ // ctx.database.execute({ database, action, input }) for a saved database action
937
+ // ctx.database.query/insert/update/delete({ database, table, ... }) for direct operations
914
938
  // ctx.graph.execute({ graph, action, input })
915
939
  // ctx.notification.send/email/push/sms({ notification, event, ... })
916
940
  // ctx.storage.upload/download({ storage, event, input })
@@ -2399,12 +2423,41 @@ DUCTAPE DATABASE PERFORMANCE GUIDANCE
2399
2423
  actions: `
2400
2424
  DUCTAPE DATABASE ACTIONS
2401
2425
 
2402
- A database action is a saved query or mutation (SQL string or NoSQL command) stored
2403
- on the Ductape product and executed by tag at runtime.
2404
-
2405
- Create/update actions in Workbench (administrative access), never through ductape_execute.
2426
+ A database action is a saved, parameterized query or mutation template (with {{placeholder}}
2427
+ fields) stored on a database component and executed by tag at runtime. This is what
2428
+ ctx.database.execute inside a Feature step invokes a saved action through its \`action\` field.
2429
+ Direct ctx.database.query/insert/update/delete calls retain their normal {table, where, data, ...}
2430
+ shape and do not resolve a saved action.
2431
+
2432
+ Create/update/delete are ADMINISTRATIVE (access key) — FORBIDDEN through ductape_execute
2433
+ (publishable key). Use ductape_cli, same as every other admin resource:
2434
+ ductape_cli("db actions create --action-file action.json")
2435
+ File: { tag: "product:database:action", name, tableName,
2436
+ operation: "query"|"insert"|"update"|"delete"|"upsert"|"aggregate"|"rawSql",
2437
+ template: { where?, select?, limit?, offset?, orderBy?, records?, query?, params? },
2438
+ description?, filterTemplate? }
2439
+ tag MUST be fully qualified "product_tag:database_tag:action_tag" — the SDK's 2-part
2440
+ "database:action" shorthand only works inside one already-warm process, never a fresh CLI call.
2441
+ This is pure metadata registration — it does not connect to the live database, so the
2442
+ database does not need to be reachable at creation time.
2443
+ ductape_cli("db actions update --tag <tag> --action-file patch.json")
2444
+ ductape_cli("db actions delete <tag>")
2445
+
2446
+ List/fetch are read-only and safe via ductape_execute:
2447
+ ductape_execute("databases.action.fetchAll", ["product_tag:database_tag"])
2448
+ NOTE: the method is fetchAll — "action.list" is not a callable method on this sub-object.
2449
+ ductape_execute("databases.action.fetch", ["product_tag:database_tag:action_tag"])
2406
2450
 
2407
2451
  Dispatch an action at runtime:
2452
+ Synchronous execution:
2453
+ ductape_execute("databases.execute", [{
2454
+ product: "my-product", env: "prd", database: "core-db",
2455
+ action: "get-active-users", input: { status: "active" }
2456
+ }])
2457
+ CLI equivalent:
2458
+ ductape_cli("db actions execute --action-file execute.json --json")
2459
+
2460
+ Deferred or scheduled execution:
2408
2461
  → CALL ductape_generate_payload FIRST to get the canonical input shape.
2409
2462
  ductape_execute("databases.action.dispatch", [{
2410
2463
  product: "my-product",
@@ -2414,13 +2467,6 @@ Dispatch an action at runtime:
2414
2467
  input: { status: "active" },
2415
2468
  }])
2416
2469
 
2417
- List actions for a database:
2418
- ductape_execute("databases.action.list", ["database_tag"])
2419
-
2420
- Fetch:
2421
- ductape_execute("databases.action.fetch", ["action_tag"])
2422
- Update/delete are administrative and must be performed in Workbench.
2423
-
2424
2470
  Actions are the preferred way to encapsulate complex or reused queries — they can be
2425
2471
  scheduled, dispatched with retries, and audited via logs.
2426
2472
  `.trim(),
@@ -2840,8 +2886,8 @@ Run an action at runtime:
2840
2886
  In a Ductape feature handler, call the registered action through:
2841
2887
  await ctx.api.run({ app: "<app_tag>", action: "<action_tag>", input: { ... } })
2842
2888
  ctx.api is the supported feature-context surface (also described as ctx.action in older code).
2843
- NEVER use 'event' as the field name here -- that is only correct for ctx.database/ctx.notification/
2844
- ctx.storage steps. ctx.api.run's real field is 'action'; passing 'event' instead silently produces
2889
+ NEVER use 'event' as the field name here -- that is only correct for ctx.notification/ctx.storage
2890
+ steps. ctx.api.run and ctx.database.execute both use 'action'; passing 'event' instead produces
2845
2891
  an unset step and fails feature compilation with "did not record a portable operation".
2846
2892
  There is no ctx.apps, ctx.integrations, or generic external-HTTP feature surface.
2847
2893
 
@@ -3882,9 +3928,9 @@ Synchronous multi-step Feature (no Event, schedule, sleep, signal, or external s
3882
3928
  },
3883
3929
  handler: async (ctx) => {
3884
3930
  const validated = await ctx.step('validate-orders', () =>
3885
- ctx.database.execute({ database: 'orders-db', event: 'validate-orders', input: ctx.input }));
3931
+ ctx.database.execute({ database: 'orders-db', action: 'validate-orders', input: ctx.input }));
3886
3932
  return ctx.step('resolve-orders', () =>
3887
- ctx.database.execute({ database: 'orders-db', event: 'resolve-orders', input: validated }));
3933
+ ctx.database.execute({ database: 'orders-db', action: 'resolve-orders', input: validated }));
3888
3934
  },
3889
3935
  });
3890
3936
  This is a valid Feature despite requiring no signal and producing no Event. Its qualification comes
@@ -3898,9 +3944,9 @@ Define a feature (write this into the project's source files — do NOT use feat
3898
3944
  name: "Onboard User",
3899
3945
  handler: async (ctx) => {
3900
3946
  const account = await ctx.step("create-account", async () =>
3901
- ctx.database.insert({ database: "core-db", event: "insert-user",
3947
+ ctx.database.insert({ database: "core-db", table: "users",
3902
3948
  data: { userId: ctx.input.userId, email: ctx.input.email } }),
3903
- async (result) => ctx.database.delete({ database: "core-db", event: "delete-user",
3949
+ async (result) => ctx.database.delete({ database: "core-db", table: "users",
3904
3950
  where: { id: result.id } }) // rollback
3905
3951
  );
3906
3952
 
@@ -4995,9 +5041,9 @@ SAVED GRAPH ACTION ASSET AND CLI CONTRACT:
4995
5041
  Validate without mutation:
4996
5042
  ductape graph validateAction -f ductape/graphs/discovery-graph/actions/upsert-product-v1.action.json --json
4997
5043
  Create and persist against the linked product:
4998
- ductape graph createAction -f ductape/graphs/discovery-graph/actions/upsert-product-v1.action.json --json
5044
+ ductape graph actions create --action-file ductape/graphs/discovery-graph/actions/upsert-product-v1.action.json --json
4999
5045
  Read back with graph.getAction/listActions before relying on it. In-place updates use:
5000
- ductape graph updateAction -f <patch.json> --json
5046
+ ductape graph actions update --action-file <patch.json> --json
5001
5047
  where patch.json is { "actionTag":"upsert-product-v1", "graphTag":"discovery-graph", "updates":{...} }.
5002
5048
  Updating name does not change the stored tag. For breaking query/input/result changes, create a new
5003
5049
  name/tag such as V2 and migrate callers; use updateAction for compatible corrections only.
@@ -5023,6 +5069,11 @@ EXACT CODE-FIRST VECTOR CONTEXT:
5023
5069
  Product/env and the Feature's inherited session are supplied by the executor. Do not serialize
5024
5070
  them into the Feature definition. Note the deliberate naming: ctx.vector.query uses values for
5025
5071
  the embedding, while the lower-level ductape.vector.query runtime facade uses vector.
5072
+ Register reusable vector actions administratively, then read them back before compiling Features:
5073
+ ductape vector actions create --action-file vector-action.json --json
5074
+ ductape vector actions get <action-tag> --vector <vector-tag> --json
5075
+ Update/delete/list use the same \`ductape vector actions\` surface. At runtime the SDK namespace is
5076
+ \`ductape.vector.actions.*\` (plural), while Feature reuse is singular \`ctx.vector.execute(...)\`.
5026
5077
  Vertex AI Vector Search stores and searches supplied vectors. It does NOT generate embeddings.
5027
5078
  Do not claim that a Vertex Vector Search index embeds text.
5028
5079
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ductape/mcp",
3
- "version": "0.2.26",
3
+ "version": "0.2.28",
4
4
  "description": "MCP server that exposes Ductape SDK operations via the backend proxy",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",