@ductape/mcp 0.2.34 → 0.2.35
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 +90 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -316,8 +316,16 @@ PRODUCT RUNTIME SNAPSHOT — REQUIRED FOR SERVER INITIALIZATION:
|
|
|
316
316
|
product runtime snapshot during onModuleInit, before the application accepts traffic. The
|
|
317
317
|
snapshot preloads connected App versions/actions plus database actions/schema metadata, graphs,
|
|
318
318
|
vectors, storage, brokers/topics, sessions, notifications, resilience assets, agents, functions,
|
|
319
|
-
and caches into the execution bootstrap cache.
|
|
320
|
-
|
|
319
|
+
and caches into the execution bootstrap cache. It also hydrates the selected Workbench App
|
|
320
|
+
connection for product+env (variables and token_access credentials). Do not emit api.config()
|
|
321
|
+
or api.oauth() boilerplate when that connection is already configured on the product. Explicit
|
|
322
|
+
api.config() is only a process-local override and has higher precedence. credential_access login
|
|
323
|
+
material remains isolated to the auth action and its encrypted refresh path. External provider/
|
|
324
|
+
database connections remain lazy and pooled.
|
|
325
|
+
|
|
326
|
+
Features, Quotas, Fallbacks, health checks, and direct api.run calls all reuse this same hydrated
|
|
327
|
+
connection through the action processor. Never create a second connection or copy secrets into a
|
|
328
|
+
Feature/Quota/Fallback definition. Reference the existing connected App access_tag and action tag.
|
|
321
329
|
|
|
322
330
|
Runtime synchronization is enabled by default when product + env are present. Do not set
|
|
323
331
|
runtimeSync:false merely to simplify generated code. Configure it only when the user has an
|
|
@@ -492,6 +500,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
|
|
|
492
500
|
ductape_cli("products apps list --product <id_or_tag> --json") ← compact linked apps only
|
|
493
501
|
ductape_cli("products apps actions list --product <id_or_tag> --app <app_tag> --json")
|
|
494
502
|
ductape_cli("products apps actions get --product <id_or_tag> --app <app_tag> --action <action_tag> --json")
|
|
503
|
+
ductape_cli("products apps configure --product <id_or_tag> --app <app_or_access_tag> --connection-file ductape/apps/<app_tag>/connection.json --json")
|
|
495
504
|
|
|
496
505
|
SDK method signatures (for reference, admin key only):
|
|
497
506
|
product.create [data: { name, description, tag?, envs?: [{slug, name}] }]
|
|
@@ -503,6 +512,7 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
|
|
|
503
512
|
product.apps.add [product_tag, app: { access_tag, envs: [{ app_env_slug, product_env_slug, variables?, auth? }] }]
|
|
504
513
|
product.apps.list [product_tag]
|
|
505
514
|
product.apps.fetch [product_tag, access_tag]
|
|
515
|
+
product.apps.update [product_tag, access_tag, { envs }] ← prefer CLI configure; it preserves omitted auth/variables
|
|
506
516
|
|
|
507
517
|
━━━ MODULE: app ━━━
|
|
508
518
|
app.create [data: { app_name: string, description: string, unique?: boolean }]
|
|
@@ -1205,6 +1215,11 @@ const marketplaceConnectInputSchema = z.object({
|
|
|
1205
1215
|
product_env_slug: z.string().min(1),
|
|
1206
1216
|
})).min(1).describe('Explicit app-to-product environment mappings. Include every product environment that will use the app.'),
|
|
1207
1217
|
});
|
|
1218
|
+
const appConnectionConfigureInputSchema = z.object({
|
|
1219
|
+
product_tag: z.string().min(1).describe('Product containing the existing App connection.'),
|
|
1220
|
+
app_tag: z.string().min(1).describe('Connected App tag or exact product access tag returned by products apps list.'),
|
|
1221
|
+
file: z.string().min(1).describe('Canonical JSON file under ductape/apps/<app-tag>/connection.json containing { envs: [...] }.'),
|
|
1222
|
+
});
|
|
1208
1223
|
const marketplaceInspectInputSchema = z.object({
|
|
1209
1224
|
app_tag: z.string().min(1).describe('Exact public app tag returned by ductape_marketplace_discover.'),
|
|
1210
1225
|
});
|
|
@@ -3073,20 +3088,49 @@ CONNECT A DISCOVERED APP THROUGH MCP:
|
|
|
3073
3088
|
4. Match each product environment explicitly to one environment exposed by the app.
|
|
3074
3089
|
5. Call ductape_marketplace_connect({ product_tag, app_tag, environments }).
|
|
3075
3090
|
6. Verify with ductape_cli("products apps list --product <product_tag> --json").
|
|
3091
|
+
7. If the App requires variables or auth, create the canonical file at
|
|
3092
|
+
ductape/apps/<app_tag>/connection.json and call ductape_app_connection_configure. A bare
|
|
3093
|
+
connect only establishes access + environment mapping; it does not invent configuration.
|
|
3076
3094
|
Never guess environment mappings or action tags. Connecting mutates product configuration;
|
|
3077
3095
|
obtain user approval when the user has not already requested the connection.
|
|
3078
3096
|
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3097
|
+
Visibility: public marketplace Apps and private Apps owned by the current workspace can be
|
|
3098
|
+
connected. A private App owned by another workspace must be rejected; do not retry around that
|
|
3099
|
+
ownership boundary.
|
|
3100
|
+
|
|
3101
|
+
CONNECTION FILE — REQUIRED SHAPE:
|
|
3102
|
+
File: ductape/apps/<app_tag>/connection.json
|
|
3103
|
+
{
|
|
3104
|
+
"envs": [{
|
|
3105
|
+
"product_env_slug": "prd",
|
|
3106
|
+
"app_env_slug": "production",
|
|
3107
|
+
"variables": [{ "key": "region", "value": "ng" }],
|
|
3108
|
+
"auth": {
|
|
3109
|
+
"auth_tag": "secret-key",
|
|
3110
|
+
"data": {
|
|
3111
|
+
"headers": { "Authorization": "$Secret{PAYSTACK_SECRET_KEY}" },
|
|
3112
|
+
"query": {}, "params": {}, "body": {}
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
}]
|
|
3116
|
+
}
|
|
3117
|
+
|
|
3118
|
+
Before writing this file, inspect the exact App version/auth/action schemas. auth.data must have
|
|
3119
|
+
headers/query/params/body objects and must match the selected auth schema. Never guess an auth_tag,
|
|
3120
|
+
variable key, input location, or required field. Store credentials with secrets.create first and
|
|
3121
|
+
write $Secret{KEY}, never plaintext, into the connection file.
|
|
3122
|
+
|
|
3123
|
+
CREATE/REPAIR/ROTATE:
|
|
3124
|
+
ductape_cli("products apps configure --product <product_tag> --app <app_or_access_tag> \
|
|
3125
|
+
--connection-file ductape/apps/<app_tag>/connection.json --json")
|
|
3126
|
+
The command is merge-safe: an omitted auth or variables field preserves the existing saved field.
|
|
3127
|
+
Providing auth or variables explicitly replaces that field for the named product environment.
|
|
3128
|
+
It never returns saved credential values. Include only environments intentionally being changed;
|
|
3129
|
+
other existing mappings are retained. To repair an old connection with no mapping, add its row.
|
|
3130
|
+
|
|
3131
|
+
After configuration, verify the non-secret summary with products apps list, then inspect the exact
|
|
3132
|
+
action contract. Do not test a payment or other side-effecting action merely to verify connection
|
|
3133
|
+
persistence unless the user explicitly requests a safe test and supplies appropriate test input.
|
|
3090
3134
|
|
|
3091
3135
|
ONLY after all five steps can any code call:
|
|
3092
3136
|
ctx.api.run({ app: '<app_tag>', action: '<action_tag>', input: { ... } }) ← in a feature handler
|
|
@@ -5731,6 +5775,12 @@ const integrateEndpointHandler = async (args) => {
|
|
|
5731
5775
|
'Run: ductape_cli("products apps connect --product <product_tag> --app <app_tag> --env-map ' +
|
|
5732
5776
|
'<app_env>:<product_env> [repeat --env-map per environment] --json"). If the app is a public ' +
|
|
5733
5777
|
'marketplace app, ductape_marketplace_connect does the same thing in one call.',
|
|
5778
|
+
'If the App declares variables or auth, connecting is not the end: call ductape_schema for the ' +
|
|
5779
|
+
'exact app/auth contract, store credential values with secrets.create, write ' +
|
|
5780
|
+
'ductape/apps/<app_tag>/connection.json using $Secret{KEY} references, and call ' +
|
|
5781
|
+
'ductape_app_connection_configure. Never put plaintext secrets in the asset file.',
|
|
5782
|
+
'For an already-connected App, skip connect and use configure. Omitted auth/variables preserve ' +
|
|
5783
|
+
'the current encrypted values, so mapping-only repairs must not force credential rotation.',
|
|
5734
5784
|
],
|
|
5735
5785
|
});
|
|
5736
5786
|
stages.push({
|
|
@@ -5933,6 +5983,11 @@ const DUCTAPE_FIRST_DOCTRINE = 'Follow this checklist before defaulting to plain
|
|
|
5933
5983
|
'(ductape.functions.register/use) — register portable business logic once and reuse it across ' +
|
|
5934
5984
|
'every Feature that needs it. Call ductape_schema before constructing any new resource file, ' +
|
|
5935
5985
|
'so you match the exact required shape rather than guessing.\n\n' +
|
|
5986
|
+
'7. A Workbench App connection is perpetual product+environment runtime configuration. Once its ' +
|
|
5987
|
+
'environment mapping, variables, and auth are saved, generated server code must initialize the ' +
|
|
5988
|
+
'SDK with product+env and await ready(); do not repeat api.config/api.oauth in every codebase. ' +
|
|
5989
|
+
'Direct actions, Features, Quotas, Fallbacks, and health checks reuse that hydrated connection. ' +
|
|
5990
|
+
'Use api.config only when the user explicitly asks for a local override.\n\n' +
|
|
5936
5991
|
'Default assumption for any backend built through this MCP server: orchestration goes through ' +
|
|
5937
5992
|
'Features, provider risk goes through Quotas/Fallback, credentials go through Secrets, shared ' +
|
|
5938
5993
|
'capability goes through reuse, and the ductape/ folder is what ships — not a database table ' +
|
|
@@ -6679,6 +6734,28 @@ async function main() {
|
|
|
6679
6734
|
command: `products apps connect --product ${shellArgument(args.product_tag)} --app ${shellArgument(args.app_tag)}${mappings} --json`,
|
|
6680
6735
|
});
|
|
6681
6736
|
});
|
|
6737
|
+
server.registerTool('ductape_app_connection_configure', {
|
|
6738
|
+
title: 'Configure a Connected Ductape App',
|
|
6739
|
+
description: 'Configure, repair, or rotate an existing product App connection from its canonical JSON asset. ' +
|
|
6740
|
+
'Inspect the App/auth schema first, store secrets separately, use $Secret{KEY} references, and ' +
|
|
6741
|
+
'keep the file under ductape/apps/<app-tag>/connection.json. Omitted auth or variables preserve ' +
|
|
6742
|
+
'the saved encrypted field; the tool never reads credential values back.',
|
|
6743
|
+
inputSchema: appConnectionConfigureInputSchema,
|
|
6744
|
+
}, async (args) => {
|
|
6745
|
+
const normalized = args.file.replace(/\\/g, '/');
|
|
6746
|
+
if (!/(^|\/)ductape\/apps\/[^/]+\/connection\.json$/.test(normalized)) {
|
|
6747
|
+
return {
|
|
6748
|
+
content: [{ type: 'text', text: JSON.stringify({
|
|
6749
|
+
error: 'INVALID_ASSET_PATH',
|
|
6750
|
+
message: 'Connection assets must be permanent JSON files at ductape/apps/<app-tag>/connection.json.',
|
|
6751
|
+
}, null, 2) }],
|
|
6752
|
+
isError: true,
|
|
6753
|
+
};
|
|
6754
|
+
}
|
|
6755
|
+
return cliHandler({
|
|
6756
|
+
command: `products apps configure --product ${shellArgument(args.product_tag)} --app ${shellArgument(args.app_tag)} --connection-file ${shellArgument(args.file)} --json`,
|
|
6757
|
+
});
|
|
6758
|
+
});
|
|
6682
6759
|
server.registerTool('ductape_integrate_endpoint', {
|
|
6683
6760
|
title: 'Integrate a New Endpoint',
|
|
6684
6761
|
description: 'Call this FIRST whenever the user wants to integrate a new API endpoint — before writing any ' +
|