@ductape/mcp 0.1.36 → 0.1.38

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 (3) hide show
  1. package/dist/index.js +27 -25
  2. package/package.json +1 -1
  3. package/src/index.ts +31 -29
package/dist/index.js CHANGED
@@ -276,19 +276,24 @@ SPECIALIZED MODULES (for injecting handles directly without @InjectContext):
276
276
  ALL params are passed as a JSON array in positional order matching the SDK signature.
277
277
 
278
278
  ━━━ MODULE: product ━━━
279
+ IMPORTANT: ALL product.* methods require the access key and will return 403 with a publishable key.
280
+ Use ductape_cli for ALL product operations — never ductape_execute:
281
+ ductape_cli("products get --tag <tag> --json") ← fetch product + full inventory
282
+ ductape_cli("products create --name <name> --tag <tag>")
283
+ ductape_cli("products environments list <tag> --json")
284
+ ductape_cli("products environments get <tag> <slug> --json")
285
+ ductape_cli("products apps list --product <id> --json")
286
+
287
+ SDK method signatures (for reference, admin key only):
279
288
  product.create [data: { name, description, tag?, envs?: [{slug, name}] }]
280
289
  product.fetch [product_tag: string]
281
290
  product.update [product_tag: string, data: { name?: string, description?: string }]
282
- product.init [product_tag: string]
283
- product.environments.create [product_tag, data: { slug: string, env_name: string, description: string, active?: boolean }]
284
- product.environments.update [product_tag, slug: string, data: { env_name?: string, description?: string, active?: boolean }]
291
+ product.environments.create [product_tag, data: { slug, env_name, description, active? }]
285
292
  product.environments.list [product_tag]
286
293
  product.environments.fetch [product_tag, slug]
287
- product.apps.connect [product_tag, app_tag]
288
- product.apps.add [product_tag, app: { access_tag: string, envs: [{ app_env_slug: string, product_env_slug: string, variables?: [{key: string, value: string}], auth?: { auth_tag: string, data: string|object, expiry?: number } }] }]
294
+ product.apps.add [product_tag, app: { access_tag, envs: [{ app_env_slug, product_env_slug, variables?, auth? }] }]
289
295
  product.apps.list [product_tag]
290
296
  product.apps.fetch [product_tag, access_tag]
291
- product.apps.update [product_tag, access_tag: string, data: { version?: string, envs?: [{ app_env_slug: string, product_env_slug: string, variables?: [{key: string, value: string}], auth?: { auth_tag: string, data: string|object, expiry?: number } }] }]
292
297
 
293
298
  ━━━ MODULE: app ━━━
294
299
  app.create [data: { app_name: string, description: string, unique?: boolean }]
@@ -1769,14 +1774,10 @@ Variables (per-env mutable values) and Constants (fixed values):
1769
1774
  ductape_execute("app.constants.create", [app_tag, { key, value }])
1770
1775
 
1771
1776
  Connecting an app to a product (after creation):
1772
- ductape_execute("product.apps.add", [product_tag, {
1773
- access_tag: "app_access_tag",
1774
- envs: [{ app_env_slug: "production", product_env_slug: "prd",
1775
- variables: [{ key: "BASE_URL", value: "https://api.example.com" }],
1776
- auth: { auth_tag: "api-key-auth", data: "$Secret{API_KEY}" } }]
1777
- }])
1778
- ductape_execute("product.apps.list", [product_tag])
1779
- ductape_execute("product.apps.fetch", [product_tag, access_tag])
1777
+ NOTE: All product.* module methods require the access key and CANNOT use ductape_execute (publishable key only).
1778
+ Use ductape_cli for all product-level operations:
1779
+ ductape_cli("products apps list --product <product_id> --json")
1780
+ ductape_cli("products get --tag <product_tag> --json") ← includes apps[], databases[], features[] etc.
1780
1781
  `.trim(),
1781
1782
  products: `
1782
1783
  DUCTAPE PRODUCTS
@@ -1785,20 +1786,20 @@ A product is the top-level namespace for all Ductape infrastructure: apps, datab
1785
1786
  vectors, storage, brokers, sessions, caches, notifications, resilience, features, jobs, and envs.
1786
1787
  Every SDK service call resolves within a product context.
1787
1788
 
1789
+ IMPORTANT: The product module requires the access key. ALL product operations must use ductape_cli,
1790
+ not ductape_execute (which only accepts the publishable key and will return 403 for product.*).
1791
+
1788
1792
  Create a product:
1789
1793
  ductape_cli("products create --name \\"My App\\" --tag my-app")
1790
- ductape_execute("product.create", [{ name: "My App", tag: "my-app",
1791
- envs: [{ slug: "dev", name: "Development" }, { slug: "prd", name: "Production" }] }])
1792
1794
 
1793
1795
  Environments — every resource's envs array MUST cover all product env slugs:
1794
- ductape_execute("product.environments.create", [product_tag, { slug, env_name, description, active? }])
1795
- ductape_execute("product.environments.list", [product_tag])
1796
- ductape_execute("product.environments.fetch", [product_tag, slug])
1797
- BEFORE registering any resource, always run environments.list and collect all slugs.
1796
+ ductape_cli("products environments list <product_tag> --json")
1797
+ ductape_cli("products environments get <product_tag> <slug> --json")
1798
+ BEFORE registering any resource, always run environments list and collect all slugs.
1798
1799
 
1799
1800
  Fetch / update:
1800
- ductape_execute("product.fetch", [product_tag])
1801
- ductape_execute("product.update", [product_tag, { name?, description? }])
1801
+ ductape_cli("products get --tag <product_tag> --json")
1802
+ ductape_cli("products get --id <product_id> --json")
1802
1803
 
1803
1804
  Connect apps to a product:
1804
1805
  See ductape_docs({ topic: "apps" }) for product.apps.add / product.apps.list.
@@ -2081,15 +2082,16 @@ STEP 1 — UNDERSTAND the goal
2081
2082
  understand: what the feature does, what it returns, what can fail and how failures should behave.
2082
2083
 
2083
2084
  STEP 2 — INVENTORY existing Ductape components
2084
- Call ductape_execute("products.fetch", [product_tag]) to read the product.
2085
+ Call ductape_cli("products get --tag <product_tag> --json") to read the full product document.
2086
+ (product.* requires the access key — never use ductape_execute for product reads, it will return 403)
2085
2087
  Note what already exists:
2086
2088
  - databases[] → available for ctx.database.insert/query/update/delete steps
2087
2089
  - apps[] → available for ctx.api.run steps (check app.events[] for event tags)
2088
2090
  - notifications[] → available for ctx.notification.email/sms/push steps
2089
2091
  - storage[] → available for ctx.storage.upload/download steps
2090
- - messageBrokers[] → available for ctx.messaging.produce steps
2092
+ - messageBrokers[] → available for ctx.events.produce steps
2091
2093
  - graphs[] → available for ctx.graph steps
2092
- - features[] → can be called as child features via ctx.feature()
2094
+ - features[] → can be called as child features via ctx.feature.execute()
2093
2095
  - caches[], sessions[]
2094
2096
  Do NOT assume a component or event tag exists — verify from the product before using it.
2095
2097
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ductape/mcp",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
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
@@ -287,19 +287,24 @@ SPECIALIZED MODULES (for injecting handles directly without @InjectContext):
287
287
  ALL params are passed as a JSON array in positional order matching the SDK signature.
288
288
 
289
289
  ━━━ MODULE: product ━━━
290
+ IMPORTANT: ALL product.* methods require the access key and will return 403 with a publishable key.
291
+ Use ductape_cli for ALL product operations — never ductape_execute:
292
+ ductape_cli("products get --tag <tag> --json") ← fetch product + full inventory
293
+ ductape_cli("products create --name <name> --tag <tag>")
294
+ ductape_cli("products environments list <tag> --json")
295
+ ductape_cli("products environments get <tag> <slug> --json")
296
+ ductape_cli("products apps list --product <id> --json")
297
+
298
+ SDK method signatures (for reference, admin key only):
290
299
  product.create [data: { name, description, tag?, envs?: [{slug, name}] }]
291
300
  product.fetch [product_tag: string]
292
301
  product.update [product_tag: string, data: { name?: string, description?: string }]
293
- product.init [product_tag: string]
294
- product.environments.create [product_tag, data: { slug: string, env_name: string, description: string, active?: boolean }]
295
- product.environments.update [product_tag, slug: string, data: { env_name?: string, description?: string, active?: boolean }]
302
+ product.environments.create [product_tag, data: { slug, env_name, description, active? }]
296
303
  product.environments.list [product_tag]
297
304
  product.environments.fetch [product_tag, slug]
298
- product.apps.connect [product_tag, app_tag]
299
- product.apps.add [product_tag, app: { access_tag: string, envs: [{ app_env_slug: string, product_env_slug: string, variables?: [{key: string, value: string}], auth?: { auth_tag: string, data: string|object, expiry?: number } }] }]
305
+ product.apps.add [product_tag, app: { access_tag, envs: [{ app_env_slug, product_env_slug, variables?, auth? }] }]
300
306
  product.apps.list [product_tag]
301
307
  product.apps.fetch [product_tag, access_tag]
302
- product.apps.update [product_tag, access_tag: string, data: { version?: string, envs?: [{ app_env_slug: string, product_env_slug: string, variables?: [{key: string, value: string}], auth?: { auth_tag: string, data: string|object, expiry?: number } }] }]
303
308
 
304
309
  ━━━ MODULE: app ━━━
305
310
  app.create [data: { app_name: string, description: string, unique?: boolean }]
@@ -733,7 +738,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
733
738
  handler: async (ctx) => {
734
739
  // ctx.input – typed feature input
735
740
  // ctx.step(tag, fn, rollback?, opts?) – define a durable step
736
- // ctx.action.run({ app, event, input }) – call an app action
741
+ // ctx.api.run({ app, event, input }) – call an app action
737
742
  // ctx.database.query/insert/update/delete({ database, event, ... })
738
743
  // ctx.graph.execute({ graph, action, input })
739
744
  // ctx.notification.send/email/push/sms({ notification, event, ... })
@@ -1835,14 +1840,10 @@ Variables (per-env mutable values) and Constants (fixed values):
1835
1840
  ductape_execute("app.constants.create", [app_tag, { key, value }])
1836
1841
 
1837
1842
  Connecting an app to a product (after creation):
1838
- ductape_execute("product.apps.add", [product_tag, {
1839
- access_tag: "app_access_tag",
1840
- envs: [{ app_env_slug: "production", product_env_slug: "prd",
1841
- variables: [{ key: "BASE_URL", value: "https://api.example.com" }],
1842
- auth: { auth_tag: "api-key-auth", data: "$Secret{API_KEY}" } }]
1843
- }])
1844
- ductape_execute("product.apps.list", [product_tag])
1845
- ductape_execute("product.apps.fetch", [product_tag, access_tag])
1843
+ NOTE: All product.* module methods require the access key and CANNOT use ductape_execute (publishable key only).
1844
+ Use ductape_cli for all product-level operations:
1845
+ ductape_cli("products apps list --product <product_id> --json")
1846
+ ductape_cli("products get --tag <product_tag> --json") ← includes apps[], databases[], features[] etc.
1846
1847
  `.trim(),
1847
1848
 
1848
1849
  products: `
@@ -1852,20 +1853,20 @@ A product is the top-level namespace for all Ductape infrastructure: apps, datab
1852
1853
  vectors, storage, brokers, sessions, caches, notifications, resilience, features, jobs, and envs.
1853
1854
  Every SDK service call resolves within a product context.
1854
1855
 
1856
+ IMPORTANT: The product module requires the access key. ALL product operations must use ductape_cli,
1857
+ not ductape_execute (which only accepts the publishable key and will return 403 for product.*).
1858
+
1855
1859
  Create a product:
1856
1860
  ductape_cli("products create --name \\"My App\\" --tag my-app")
1857
- ductape_execute("product.create", [{ name: "My App", tag: "my-app",
1858
- envs: [{ slug: "dev", name: "Development" }, { slug: "prd", name: "Production" }] }])
1859
1861
 
1860
1862
  Environments — every resource's envs array MUST cover all product env slugs:
1861
- ductape_execute("product.environments.create", [product_tag, { slug, env_name, description, active? }])
1862
- ductape_execute("product.environments.list", [product_tag])
1863
- ductape_execute("product.environments.fetch", [product_tag, slug])
1864
- BEFORE registering any resource, always run environments.list and collect all slugs.
1863
+ ductape_cli("products environments list <product_tag> --json")
1864
+ ductape_cli("products environments get <product_tag> <slug> --json")
1865
+ BEFORE registering any resource, always run environments list and collect all slugs.
1865
1866
 
1866
1867
  Fetch / update:
1867
- ductape_execute("product.fetch", [product_tag])
1868
- ductape_execute("product.update", [product_tag, { name?, description? }])
1868
+ ductape_cli("products get --tag <product_tag> --json")
1869
+ ductape_cli("products get --id <product_id> --json")
1869
1870
 
1870
1871
  Connect apps to a product:
1871
1872
  See ductape_docs({ topic: "apps" }) for product.apps.add / product.apps.list.
@@ -2153,15 +2154,16 @@ STEP 1 — UNDERSTAND the goal
2153
2154
  understand: what the feature does, what it returns, what can fail and how failures should behave.
2154
2155
 
2155
2156
  STEP 2 — INVENTORY existing Ductape components
2156
- Call ductape_execute("products.fetch", [product_tag]) to read the product.
2157
+ Call ductape_cli("products get --tag <product_tag> --json") to read the full product document.
2158
+ (product.* requires the access key — never use ductape_execute for product reads, it will return 403)
2157
2159
  Note what already exists:
2158
2160
  - databases[] → available for ctx.database.insert/query/update/delete steps
2159
- - apps[] → available for ctx.action.run steps (check app.events[] for event tags)
2161
+ - apps[] → available for ctx.api.run steps (check app.events[] for event tags)
2160
2162
  - notifications[] → available for ctx.notification.email/sms/push steps
2161
2163
  - storage[] → available for ctx.storage.upload/download steps
2162
- - messageBrokers[] → available for ctx.messaging.produce steps
2164
+ - messageBrokers[] → available for ctx.events.produce steps
2163
2165
  - graphs[] → available for ctx.graph steps
2164
- - features[] → can be called as child features via ctx.feature()
2166
+ - features[] → can be called as child features via ctx.feature.execute()
2165
2167
  - caches[], sessions[]
2166
2168
  Do NOT assume a component or event tag exists — verify from the product before using it.
2167
2169
 
@@ -2214,8 +2216,8 @@ STEP 8 — SET rollbacks for reversible steps
2214
2216
  Any step that allocates a resource should undo it if a later step fails:
2215
2217
  const charge = await ctx.step(
2216
2218
  'charge',
2217
- async () => ctx.action.run({ app: 'stripe', event: 'create-charge', input: { amount: ctx.input.amount } }),
2218
- async (result) => ctx.action.run({ app: 'stripe', event: 'refund', input: { chargeId: result.id } })
2219
+ async () => ctx.api.run({ app: 'stripe', event: 'create-charge', input: { amount: ctx.input.amount } }),
2220
+ async (result) => ctx.api.run({ app: 'stripe', event: 'refund', input: { chargeId: result.id } })
2219
2221
  );
2220
2222
 
2221
2223
  Step types: action | database | graph | notification | storage | produce | quota | fallback |