@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.
- package/dist/index.js +86 -7
- 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
|
|
3736
|
-
may also run them: while it consistently persists a fresh lastChecked record, the
|
|
3737
|
-
that product/env/check. The
|
|
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
|
|
3740
|
-
disable the
|
|
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.
|
|
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
|
},
|