@ductape/mcp 0.3.0 → 0.3.2

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 +86 -7
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -2904,11 +2904,23 @@ Import an existing resource and register it on the product:
2904
2904
  Use import-persist-all for multi-env products (required):
2905
2905
  ductape_cli("cloud resources import-persist-all -f all-envs.json --json")
2906
2906
  File is a JSON ARRAY — one entry per env, same product + component tag across all entries.
2907
- Each entry: { cloud, service, type, product, component, env, resource, region?, dbName? }
2907
+ Each entry: { cloud, service, type, product, component, env, resource, region?, dbName?, masterPassword? }
2908
2908
  Supported service identifiers: s3, gcs, blob, rds, postgresql, cloudsql, sqs, pubsub,
2909
2909
  servicebus, neptune, cosmos-gremlin, opensearch, azure-search, atlas-cluster, aura-instance,
2910
2910
  vertex-vector-search, spanner-graph, dynamodb, keyspaces, mysql
2911
2911
 
2912
+ masterPassword is required for self-hosted-style imports where Ductape cannot mint or fetch
2913
+ credentials on its own: rds, postgresql, cloudsql, mysql (unless the instance already has
2914
+ stored Ductape credentials from a prior link), and — critically — aura-instance. Neo4j Aura
2915
+ shows the auto-generated database password only ONCE, at instance creation, in the Aura
2916
+ console, and it can never be retrieved again via the Aura API. Importing an Aura instance
2917
+ without masterPassword will fail with a clear error at import time; skipping that check and
2918
+ importing anyway is not possible — always ask the user for the instance's password before
2919
+ calling import-persist-all for an aura-instance entry, the same as you would ask for an RDS
2920
+ master password. Aura's username is always "neo4j" — never ask the user for it. Atlas
2921
+ (atlas-cluster) does NOT need masterPassword — Ductape mints/rotates its own database user via
2922
+ the Atlas Admin API.
2923
+
2912
2924
  Provision a brand-new resource and register it:
2913
2925
  ductape_cli("cloud resources provision-persist-all -f all-envs.json --json")
2914
2926
  Additional per-entry fields: tier, region/location, waitForReady.
@@ -3709,7 +3721,7 @@ QUOTAS — weighted/provider-capacity routing pools (NOT request rate limiting):
3709
3721
  input: { to: { type: "string", required: true }, message: { type: "string" } },
3710
3722
  options: [
3711
3723
  { provider: "twilio", app: "twilio-app", type: "action", event: "send-sms",
3712
- quota: 1000, uses: 0, retries: 2,
3724
+ quota: 1000, uses: 0, retries: 2, health: "twilio-health",
3713
3725
  input: { "body:to": "$Input{to}", "body:message": "$Input{message}" },
3714
3726
  output: {} },
3715
3727
  { provider: "nexmo", app: "nexmo-app", type: "action", event: "send-sms",
@@ -3731,13 +3743,54 @@ FALLBACKS — automatic provider switching on failure:
3731
3743
  fallback.run [{ product, env, tag, input }] ← CALL ductape_generate_payload FIRST
3732
3744
  fallback.dispatch [{ product, env, tag, input, schedule? }]
3733
3745
 
3746
+ HEALTH-GATED PROVIDERS — REQUIRED BEHAVIOR:
3747
+ Provider options may declare health: "<healthcheck-tag>". healthcheck is a deprecated input alias;
3748
+ generate health in new JSON and code. Before creating a quota/fallback, list the product's existing
3749
+ healthchecks and reuse one whose probe targets the same app/resource and operation. Create a new
3750
+ healthcheck only when no equivalent check exists. Verify the referenced tag exists in the same
3751
+ product and covers every environment used by the quota/fallback.
3752
+
3753
+ This is an active prerequisite, not optional advice. When creating or updating a quota/fallback:
3754
+ 1. List existing healthchecks and connected product providers.
3755
+ 2. Match each provider to an existing check by probe type + provider asset/app + safe probe event.
3756
+ 3. For every unmatched provider, inspect its live action/resource schema, choose a repeat-safe probe,
3757
+ write ductape/healthchecks/<tag>.json, and run: ductape resources health create --tag <product>
3758
+ -f ductape/healthchecks/<tag>.json --json.
3759
+ 4. Fetch and explicitly run each newly-created check in every target environment. Do not create the
3760
+ quota/fallback until the probe schema and status lookup both succeed.
3761
+ 5. Put health: "<verified-healthcheck-tag>" on every provider option, then create/update and refetch
3762
+ the quota/fallback. A provider without a verified health tag is an incomplete resilience asset.
3763
+ If no safe repeatable probe exists, stop and explain the blocker; never invent an endpoint or omit
3764
+ health silently.
3765
+
3766
+ Runtime contract:
3767
+ - Read the linked health status before provider selection.
3768
+ - Never select a provider whose linked status is unavailable, even when every provider is down.
3769
+ Return NO_HEALTHY_PROVIDERS/NO_PROVIDERS_AVAILABLE instead of forcing traffic through it.
3770
+ - When a selected provider exhausts its bounded retries, immediately mark the linked healthcheck
3771
+ unavailable. The current fallback or quota invocation must immediately continue/reselect from
3772
+ the remaining healthy options; subsequent invocations must also skip it. Never wait for the
3773
+ health poll before performing local failover.
3774
+ - Runtime success does not close the circuit. Only a successful scheduled or explicit health probe
3775
+ restores available, preventing one opportunistic request from bypassing recovery validation.
3776
+ - One global Tickets-hosted scheduler is the fallback runner when no fresh local SDK monitor result
3777
+ exists. Do not require application code to call monitor() for platform healthchecks to run.
3778
+ - Remote and local runtimes share health through the product's centrally persisted health state,
3779
+ not through a common Redis instance. SDK runtime-manifest polling compares healthRevision and
3780
+ atomically refreshes an in-process health snapshot in the background. Quota/fallback routing uses
3781
+ synchronous snapshot reads; never add a bootstrap, Redis, or backend lookup to the invocation path.
3782
+ A local provider failure trips the in-process state immediately and persists it asynchronously so
3783
+ other instances receive it on their next lightweight poll.
3784
+ - A transition from available to unavailable sends one alert to accepted workspace participants;
3785
+ repeated unhealthy probe results must not generate duplicate transition emails.
3786
+
3734
3787
  HEALTHCHECKS — continuous probe with failure notifications:
3735
- Scheduled probes have a platform-owned fallback runner in the Ductape proxy. A local SDK monitor
3736
- may also run them: while it consistently persists a fresh lastChecked record, the proxy defers
3737
- that product/env/check. The proxy freshness window accounts for the SDK's batched backend status
3788
+ Scheduled probes have a platform-owned global fallback runner in the Ductape Tickets service. A local SDK monitor
3789
+ may also run them: while it consistently persists a fresh lastChecked record, the global worker defers
3790
+ that product/env/check. The server freshness window accounts for the SDK's batched backend status
3738
3791
  flush (currently five minutes), not only the shorter probe interval. If records stop arriving and
3739
- the freshness window expires, the proxy automatically takes over. Do not instruct users to
3740
- disable the proxy fallback when using a local monitor.
3792
+ the freshness window expires, the global worker automatically takes over. Do not instruct users to
3793
+ disable the server fallback when using a local monitor.
3741
3794
 
3742
3795
  Workbench definition shape:
3743
3796
  {
@@ -6912,6 +6965,32 @@ async function main() {
6912
6965
  ' "product":"my-product","component":"billing-db","env":"snd","resource":"Cluster0","dbName":"billing_snd"},\n' +
6913
6966
  ' {"cloud":"atlas-tag","service":"atlas-cluster","type":"databases",\n' +
6914
6967
  ' "product":"my-product","component":"billing-db","env":"prd","resource":"Cluster0","dbName":"billing_prd"}]\n' +
6968
+ ' - Neo4j Aura (graph) import flow — service identifier is "aura-instance":\n' +
6969
+ ' CRITICAL: masterPassword is REQUIRED in every import entry for aura-instance. Aura shows the\n' +
6970
+ ' auto-generated database password only ONCE, at instance creation, in the Aura console, and it\n' +
6971
+ ' can never be retrieved again via the Aura API — Ductape has no way to source it automatically.\n' +
6972
+ ' Always ask the user for the instance password before calling import-persist-all for an\n' +
6973
+ ' aura-instance entry; do not attempt the import without it, it will fail with a clear error\n' +
6974
+ ' naming exactly this. The username is always "neo4j" for every Aura instance — never ask the\n' +
6975
+ ' user for it, and never put it in masterPassword by mistake.\n' +
6976
+ ' Step 1 — discover the instance:\n' +
6977
+ ' ductape_cli("cloud resources list -f /tmp/aura-list.json --json")\n' +
6978
+ ' File: {"cloud": "<aura-connection-tag>", "service": "aura-instance"}\n' +
6979
+ ' Returns a list of Aura instances; note the "id" or "name" field (this is your resource\n' +
6980
+ ' identifier). Aura instances cannot be created through Ductape — provision-persist-all is\n' +
6981
+ ' not supported for this provider; only an already-existing instance can be linked.\n' +
6982
+ ' Step 2 — import (one entry per product env, same instance across all envs unless the user\n' +
6983
+ ' explicitly wants different Aura instances per environment):\n' +
6984
+ ' cloud (connection tag), service: "aura-instance", type: "graphs",\n' +
6985
+ ' product, component (new or existing graph tag), env, resource (instance id/name from\n' +
6986
+ ' Step 1), masterPassword (the instance password — ask the user, do not guess or omit).\n' +
6987
+ ' Example (two envs, same Aura instance):\n' +
6988
+ ' [{"cloud":"aura-tag","service":"aura-instance","type":"graphs",\n' +
6989
+ ' "product":"my-product","component":"commerce-network","env":"snd",\n' +
6990
+ ' "resource":"1d7fc731","masterPassword":"<user-supplied>"},\n' +
6991
+ ' {"cloud":"aura-tag","service":"aura-instance","type":"graphs",\n' +
6992
+ ' "product":"my-product","component":"commerce-network","env":"prd",\n' +
6993
+ ' "resource":"1d7fc731","masterPassword":"<user-supplied>"}]\n' +
6915
6994
  ' - Message broker / event broker import:\n' +
6916
6995
  ' CLI accepts these aliases for the messageBrokers module: events, event, broker, brokers, message-brokers.\n' +
6917
6996
  ' List existing brokers: ductape_cli("resources events list --json")\n' +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ductape/mcp",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "MCP server that exposes Ductape SDK operations via the backend proxy",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -15,7 +15,7 @@
15
15
  ],
16
16
  "scripts": {
17
17
  "build": "tsc",
18
- "test": "npm run build && node scripts/check-cli-command-security.mjs && node scripts/check-frontend-analytics-guidance.mjs && node scripts/check-events-discovery.mjs && node scripts/check-schema-fallback.mjs && node scripts/check-paystack-action-schema.mjs && node scripts/check-portable-functions.mjs && node scripts/check-feature-control-flow.mjs && node scripts/check-project-link-guidance.mjs && node scripts/check-graph-vector-projection-guidance.mjs && node scripts/check-asset-file-guidance.mjs && node scripts/check-database-action-contract-guidance.mjs && node scripts/check-runtime-sync-guidance.mjs && node scripts/check-runtime-input-recovery.mjs",
18
+ "test": "npm run build && node scripts/check-cli-command-security.mjs && node scripts/check-frontend-analytics-guidance.mjs && node scripts/check-events-discovery.mjs && node scripts/check-schema-fallback.mjs && node scripts/check-paystack-action-schema.mjs && node scripts/check-portable-functions.mjs && node scripts/check-feature-control-flow.mjs && node scripts/check-project-link-guidance.mjs && node scripts/check-graph-vector-projection-guidance.mjs && node scripts/check-asset-file-guidance.mjs && node scripts/check-database-action-contract-guidance.mjs && node scripts/check-runtime-sync-guidance.mjs && node scripts/check-runtime-input-recovery.mjs && node scripts/check-resilience-health-guidance.mjs",
19
19
  "start": "node dist/index.js",
20
20
  "dev": "tsx src/index.ts"
21
21
  },