@ductape/mcp 0.1.3 → 0.1.5
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 +152 -17
- package/package.json +1 -1
- package/src/index.ts +164 -18
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* the env var when provided.
|
|
11
11
|
*/
|
|
12
12
|
import { createRequire } from 'module';
|
|
13
|
+
import { execSync } from 'child_process';
|
|
13
14
|
import { z } from 'zod';
|
|
14
15
|
import { executeViaProxy, generateExecutablePayload, getAssetSchemas, } from './proxy-client.js';
|
|
15
16
|
const MODULES = [
|
|
@@ -24,18 +25,45 @@ const MODULES = [
|
|
|
24
25
|
const METHOD_DOCS = `
|
|
25
26
|
━━━ TOOL SELECTION GUIDE ━━━
|
|
26
27
|
|
|
27
|
-
There are
|
|
28
|
+
There are THREE categories of operations. Use the right tool for each:
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
→
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
0. ADMINISTRATIVE OPERATIONS (create/update products, apps, environments, cloud connections…)
|
|
31
|
+
These require an access key and CANNOT be done via ductape_execute (publishable key only).
|
|
32
|
+
→ Use ductape_cli instead. Examples:
|
|
33
|
+
ductape_cli("products list")
|
|
34
|
+
ductape_cli("products create --name \\"My Product\\" --tag my-product")
|
|
35
|
+
ductape_cli("cloud connections list")
|
|
36
|
+
ductape_cli("link --product my-product --env dev")
|
|
37
|
+
If the CLI is not installed, ductape_cli will return install instructions automatically.
|
|
38
|
+
NOTE: Environments and app actions are configured in the Workbench UI — there are no CLI commands for them.
|
|
39
|
+
|
|
40
|
+
DECLARATIVE SYNC (apply sessions, notifications, events from code; run DB migrations)
|
|
41
|
+
→ Also use ductape_cli. The project must be linked first (ductape init --link).
|
|
42
|
+
ductape_cli("apply") # sync all: sessions + notifications + events
|
|
43
|
+
ductape_cli("apply sessions") # sessions only
|
|
44
|
+
ductape_cli("apply notifications") # notifications only
|
|
45
|
+
ductape_cli("apply events") # event brokers only
|
|
46
|
+
ductape_cli("apply --dry-run") # preview without changes
|
|
47
|
+
ductape_cli("db schema generate") # diff schema.json → write migration files
|
|
48
|
+
ductape_cli("db schema generate --destructive") # also generate drop operations
|
|
49
|
+
ductape_cli("db migrate") # apply pending migration files
|
|
50
|
+
ductape_cli("db migrate --dry-run") # preview without applying
|
|
51
|
+
ductape_cli("db migrate --env prd") # apply to a specific environment
|
|
52
|
+
ductape_cli("db migrate status") # show applied vs pending migrations
|
|
53
|
+
ductape_cli("db migrate status --json") # machine-readable status
|
|
54
|
+
ductape_cli("db migrate rollback") # roll back last migration
|
|
55
|
+
ductape_cli("db migrate rollback -n 3") # roll back last 3 migrations
|
|
56
|
+
|
|
57
|
+
1. ASSET CREATION / UPDATE (create, update, add, register… for ANY asset type)
|
|
58
|
+
ALL creation and update operations require an access key and CANNOT go through ductape_execute.
|
|
59
|
+
→ Use ductape_cli for every create/update operation. Examples:
|
|
60
|
+
ductape_cli("apps create --name \\"Email Service\\" --description \\"Transactional email\\"")
|
|
61
|
+
ductape_cli("apps list")
|
|
62
|
+
ductape_cli("resources storage list")
|
|
63
|
+
ductape_cli("resources database create -f db-config.json")
|
|
64
|
+
This applies to: products, apps, and resources (databases, storage, caches, etc.),
|
|
65
|
+
cloud connections, and secrets. Environments, app actions, auths, features, quotas,
|
|
66
|
+
fallbacks, jobs, and healthchecks are configured in the Workbench UI.
|
|
39
67
|
|
|
40
68
|
2. RUNTIME OPERATIONS (run, dispatch, execute, start, send, produce, query, insert, update, delete…)
|
|
41
69
|
The "input" field shape is product- and operation-specific — it is NOT derivable from Joi validators.
|
|
@@ -777,6 +805,63 @@ function buildSnippet(language, payload, operationFamily, method) {
|
|
|
777
805
|
? buildPythonSnippet(payload, operationFamily, method)
|
|
778
806
|
: buildTypeScriptSnippet(payload, operationFamily, method);
|
|
779
807
|
}
|
|
808
|
+
// ─── CLI helpers ─────────────────────────────────────────────────────────────
|
|
809
|
+
const ADMIN_SUBCOMMANDS = [
|
|
810
|
+
'login', 'logout', 'whoami',
|
|
811
|
+
'profiles',
|
|
812
|
+
'workspaces',
|
|
813
|
+
'link', 'unlink', 'init',
|
|
814
|
+
'products', 'apps',
|
|
815
|
+
'resources',
|
|
816
|
+
'cloud',
|
|
817
|
+
'secrets',
|
|
818
|
+
'generate',
|
|
819
|
+
'apply',
|
|
820
|
+
'db',
|
|
821
|
+
'graph',
|
|
822
|
+
];
|
|
823
|
+
function checkCli() {
|
|
824
|
+
try {
|
|
825
|
+
const out = execSync('ductape --version', { encoding: 'utf8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
826
|
+
return { available: true, version: out || 'unknown' };
|
|
827
|
+
}
|
|
828
|
+
catch {
|
|
829
|
+
return { available: false };
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
function runCli(command) {
|
|
833
|
+
const first = command.trim().split(/\s+/)[0];
|
|
834
|
+
if (!ADMIN_SUBCOMMANDS.includes(first)) {
|
|
835
|
+
return {
|
|
836
|
+
success: false,
|
|
837
|
+
output: `Subcommand "${first}" is not in the allowed admin subcommand list. Allowed: ${ADMIN_SUBCOMMANDS.join(', ')}.`,
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
try {
|
|
841
|
+
const output = execSync(`ductape ${command}`, {
|
|
842
|
+
encoding: 'utf8',
|
|
843
|
+
timeout: 30000,
|
|
844
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
845
|
+
});
|
|
846
|
+
return { success: true, output: output.trim() };
|
|
847
|
+
}
|
|
848
|
+
catch (err) {
|
|
849
|
+
const msg = (err.stderr || err.stdout || err.message || String(err)).trim();
|
|
850
|
+
return { success: false, output: msg };
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
const cliInputSchema = z.object({
|
|
854
|
+
command: z.string().describe('The ductape CLI command to run, without the leading "ductape" word. ' +
|
|
855
|
+
'Examples: "products list", "products create --name \\"My Product\\" --tag my-product", ' +
|
|
856
|
+
'"apps list", "apps create -f app.json", "resources storage list", ' +
|
|
857
|
+
'"cloud connections list", "link --product my-product --env dev".\n\n' +
|
|
858
|
+
'Use this tool for administrative operations: creating or updating products, apps, ' +
|
|
859
|
+
'resources (databases, storage, caches…), cloud connections, secrets, ' +
|
|
860
|
+
'and for apply/migrate workflows.\n\n' +
|
|
861
|
+
'Note: environments, app actions, features, quotas, fallbacks, and jobs are configured ' +
|
|
862
|
+
'in the Workbench UI — there are no CLI commands for them.\n\n' +
|
|
863
|
+
'The CLI uses the user\'s local logged-in session (ductape login) — no key is required.'),
|
|
864
|
+
});
|
|
780
865
|
async function loadMcpSdk() {
|
|
781
866
|
try {
|
|
782
867
|
const [{ McpServer }, { StdioServerTransport }] = await Promise.all([
|
|
@@ -831,6 +916,33 @@ async function main() {
|
|
|
831
916
|
const { McpServer, StdioServerTransport } = await loadMcpSdk();
|
|
832
917
|
const server = new McpServer({ name: 'ductape-mcp', version: '0.1.0' });
|
|
833
918
|
const transport = new StdioServerTransport();
|
|
919
|
+
const cliHandler = async (args) => {
|
|
920
|
+
const cli = checkCli();
|
|
921
|
+
if (!cli.available) {
|
|
922
|
+
return {
|
|
923
|
+
content: [{
|
|
924
|
+
type: 'text',
|
|
925
|
+
text: [
|
|
926
|
+
'The Ductape CLI is not installed or not in PATH.',
|
|
927
|
+
'',
|
|
928
|
+
'Install it with:',
|
|
929
|
+
' npm install --global @ductape/cli',
|
|
930
|
+
'',
|
|
931
|
+
'Then log in:',
|
|
932
|
+
' ductape login',
|
|
933
|
+
'',
|
|
934
|
+
'After logging in, retry this operation.',
|
|
935
|
+
].join('\n'),
|
|
936
|
+
}],
|
|
937
|
+
isError: true,
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
const result = runCli(args.command);
|
|
941
|
+
return {
|
|
942
|
+
content: [{ type: 'text', text: result.output || '(no output)' }],
|
|
943
|
+
...(result.success ? {} : { isError: true }),
|
|
944
|
+
};
|
|
945
|
+
};
|
|
834
946
|
const executeHandler = async (args) => {
|
|
835
947
|
try {
|
|
836
948
|
const key = args.publishable_key || process.env.DUCTAPE_PUBLISHABLE_KEY;
|
|
@@ -899,12 +1011,14 @@ async function main() {
|
|
|
899
1011
|
if (typeof server.registerTool === 'function') {
|
|
900
1012
|
server.registerTool('ductape_execute', {
|
|
901
1013
|
title: 'Ductape SDK Execute',
|
|
902
|
-
description: 'Execute a Ductape SDK operation via the backend proxy.\n\n' +
|
|
903
|
-
'
|
|
904
|
-
'
|
|
905
|
-
'
|
|
906
|
-
'
|
|
907
|
-
'
|
|
1014
|
+
description: 'Execute a Ductape SDK RUNTIME operation via the backend proxy (publishable key).\n\n' +
|
|
1015
|
+
'ONLY use this tool for runtime operations: run, dispatch, execute, start, send, produce, query, insert, update, delete.\n' +
|
|
1016
|
+
'Do NOT use this for creating or updating any asset (product, app, action, environment, database, storage, etc.) — ' +
|
|
1017
|
+
'those require an access key. Use ductape_cli for all creation and update operations.\n\n' +
|
|
1018
|
+
'Two-step rule for runtime operations:\n' +
|
|
1019
|
+
' 1. Call ductape_generate_payload first to get the canonical payload template.\n' +
|
|
1020
|
+
' This reveals the exact "input" field keys — they are product/env/operation-specific.\n' +
|
|
1021
|
+
' 2. Fill in the values from the template, then call ductape_execute.',
|
|
908
1022
|
inputSchema: executeInputSchema,
|
|
909
1023
|
}, executeHandler);
|
|
910
1024
|
server.registerTool('ductape_generate_payload', {
|
|
@@ -931,12 +1045,33 @@ async function main() {
|
|
|
931
1045
|
'Pass module="app" or module="product" to scope the result.',
|
|
932
1046
|
inputSchema: schemaInputSchema,
|
|
933
1047
|
}, schemaHandler);
|
|
1048
|
+
server.registerTool('ductape_cli', {
|
|
1049
|
+
title: 'Ductape CLI',
|
|
1050
|
+
description: 'Run a Ductape CLI command for administrative operations.\n\n' +
|
|
1051
|
+
'USE THIS TOOL for any operation that creates or modifies platform configuration:\n' +
|
|
1052
|
+
' - Creating or updating products (products create/update) and apps (apps create/update)\n' +
|
|
1053
|
+
' - Importing an app from a Postman v2.1 or OpenAPI 3.0 file: "apps import <file> -t postman|openapi"\n' +
|
|
1054
|
+
' - Managing resources via "resources <type> <verb>" (databases, storage, caches…)\n' +
|
|
1055
|
+
' - Managing cloud connections and cloud-linked resources\n' +
|
|
1056
|
+
' - Listing workspaces, products, secrets\n' +
|
|
1057
|
+
' - Linking a project folder: "link --product <tag> --env <slug>"\n' +
|
|
1058
|
+
' - Syncing sessions/notifications/events: "apply" or "apply sessions" etc.\n' +
|
|
1059
|
+
' - Running database migrations: "db migrate", "db schema generate"\n\n' +
|
|
1060
|
+
'NOTE: Environments, app actions, auths, features, quotas, fallbacks, and jobs are ' +
|
|
1061
|
+
'configured in the Workbench UI — the CLI does not have commands for them.\n\n' +
|
|
1062
|
+
'DO NOT use ductape_execute for admin operations — it uses a publishable key which only ' +
|
|
1063
|
+
'covers runtime operations. Administrative operations will fail with "Authentication failed".\n\n' +
|
|
1064
|
+
'The CLI uses the user\'s local logged-in session (ductape login). ' +
|
|
1065
|
+
'If the CLI is not installed, this tool will return install instructions automatically.',
|
|
1066
|
+
inputSchema: cliInputSchema,
|
|
1067
|
+
}, cliHandler);
|
|
934
1068
|
}
|
|
935
1069
|
else if (typeof server.tool === 'function') {
|
|
936
1070
|
server.tool('ductape_execute', executeInputSchema.shape, executeHandler);
|
|
937
1071
|
server.tool('ductape_generate_payload', payloadGenerateInputSchema.shape, payloadGenerateHandler);
|
|
938
1072
|
server.tool('ductape_generate_snippet', snippetGenerateInputSchema.shape, snippetGenerateHandler);
|
|
939
1073
|
server.tool('ductape_schema', schemaInputSchema.shape, schemaHandler);
|
|
1074
|
+
server.tool('ductape_cli', cliInputSchema.shape, cliHandler);
|
|
940
1075
|
}
|
|
941
1076
|
else {
|
|
942
1077
|
console.error('MCP server does not expose .registerTool() or .tool()');
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { createRequire } from 'module';
|
|
14
|
+
import { execSync } from 'child_process';
|
|
14
15
|
import { z } from 'zod';
|
|
15
16
|
import {
|
|
16
17
|
executeViaProxy,
|
|
@@ -35,18 +36,45 @@ const MODULES: SDKModule[] = [
|
|
|
35
36
|
const METHOD_DOCS = `
|
|
36
37
|
━━━ TOOL SELECTION GUIDE ━━━
|
|
37
38
|
|
|
38
|
-
There are
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
→
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
There are THREE categories of operations. Use the right tool for each:
|
|
40
|
+
|
|
41
|
+
0. ADMINISTRATIVE OPERATIONS (create/update products, apps, environments, cloud connections…)
|
|
42
|
+
These require an access key and CANNOT be done via ductape_execute (publishable key only).
|
|
43
|
+
→ Use ductape_cli instead. Examples:
|
|
44
|
+
ductape_cli("products list")
|
|
45
|
+
ductape_cli("products create --name \\"My Product\\" --tag my-product")
|
|
46
|
+
ductape_cli("cloud connections list")
|
|
47
|
+
ductape_cli("link --product my-product --env dev")
|
|
48
|
+
If the CLI is not installed, ductape_cli will return install instructions automatically.
|
|
49
|
+
NOTE: Environments and app actions are configured in the Workbench UI — there are no CLI commands for them.
|
|
50
|
+
|
|
51
|
+
DECLARATIVE SYNC (apply sessions, notifications, events from code; run DB migrations)
|
|
52
|
+
→ Also use ductape_cli. The project must be linked first (ductape init --link).
|
|
53
|
+
ductape_cli("apply") # sync all: sessions + notifications + events
|
|
54
|
+
ductape_cli("apply sessions") # sessions only
|
|
55
|
+
ductape_cli("apply notifications") # notifications only
|
|
56
|
+
ductape_cli("apply events") # event brokers only
|
|
57
|
+
ductape_cli("apply --dry-run") # preview without changes
|
|
58
|
+
ductape_cli("db schema generate") # diff schema.json → write migration files
|
|
59
|
+
ductape_cli("db schema generate --destructive") # also generate drop operations
|
|
60
|
+
ductape_cli("db migrate") # apply pending migration files
|
|
61
|
+
ductape_cli("db migrate --dry-run") # preview without applying
|
|
62
|
+
ductape_cli("db migrate --env prd") # apply to a specific environment
|
|
63
|
+
ductape_cli("db migrate status") # show applied vs pending migrations
|
|
64
|
+
ductape_cli("db migrate status --json") # machine-readable status
|
|
65
|
+
ductape_cli("db migrate rollback") # roll back last migration
|
|
66
|
+
ductape_cli("db migrate rollback -n 3") # roll back last 3 migrations
|
|
67
|
+
|
|
68
|
+
1. ASSET CREATION / UPDATE (create, update, add, register… for ANY asset type)
|
|
69
|
+
ALL creation and update operations require an access key and CANNOT go through ductape_execute.
|
|
70
|
+
→ Use ductape_cli for every create/update operation. Examples:
|
|
71
|
+
ductape_cli("apps create --name \\"Email Service\\" --description \\"Transactional email\\"")
|
|
72
|
+
ductape_cli("apps list")
|
|
73
|
+
ductape_cli("resources storage list")
|
|
74
|
+
ductape_cli("resources database create -f db-config.json")
|
|
75
|
+
This applies to: products, apps, and resources (databases, storage, caches, etc.),
|
|
76
|
+
cloud connections, and secrets. Environments, app actions, auths, features, quotas,
|
|
77
|
+
fallbacks, jobs, and healthchecks are configured in the Workbench UI.
|
|
50
78
|
|
|
51
79
|
2. RUNTIME OPERATIONS (run, dispatch, execute, start, send, produce, query, insert, update, delete…)
|
|
52
80
|
The "input" field shape is product- and operation-specific — it is NOT derivable from Joi validators.
|
|
@@ -820,6 +848,68 @@ function buildSnippet(
|
|
|
820
848
|
}
|
|
821
849
|
|
|
822
850
|
|
|
851
|
+
// ─── CLI helpers ─────────────────────────────────────────────────────────────
|
|
852
|
+
|
|
853
|
+
const ADMIN_SUBCOMMANDS = [
|
|
854
|
+
'login', 'logout', 'whoami',
|
|
855
|
+
'profiles',
|
|
856
|
+
'workspaces',
|
|
857
|
+
'link', 'unlink', 'init',
|
|
858
|
+
'products', 'apps',
|
|
859
|
+
'resources',
|
|
860
|
+
'cloud',
|
|
861
|
+
'secrets',
|
|
862
|
+
'generate',
|
|
863
|
+
'apply',
|
|
864
|
+
'db',
|
|
865
|
+
'graph',
|
|
866
|
+
];
|
|
867
|
+
|
|
868
|
+
function checkCli(): { available: boolean; version?: string } {
|
|
869
|
+
try {
|
|
870
|
+
const out = execSync('ductape --version', { encoding: 'utf8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
871
|
+
return { available: true, version: out || 'unknown' };
|
|
872
|
+
} catch {
|
|
873
|
+
return { available: false };
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
function runCli(command: string): { success: boolean; output: string } {
|
|
878
|
+
const first = command.trim().split(/\s+/)[0];
|
|
879
|
+
if (!ADMIN_SUBCOMMANDS.includes(first)) {
|
|
880
|
+
return {
|
|
881
|
+
success: false,
|
|
882
|
+
output: `Subcommand "${first}" is not in the allowed admin subcommand list. Allowed: ${ADMIN_SUBCOMMANDS.join(', ')}.`,
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
try {
|
|
886
|
+
const output = execSync(`ductape ${command}`, {
|
|
887
|
+
encoding: 'utf8',
|
|
888
|
+
timeout: 30000,
|
|
889
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
890
|
+
});
|
|
891
|
+
return { success: true, output: output.trim() };
|
|
892
|
+
} catch (err: any) {
|
|
893
|
+
const msg = (err.stderr || err.stdout || err.message || String(err)).trim();
|
|
894
|
+
return { success: false, output: msg };
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
const cliInputSchema = z.object({
|
|
899
|
+
command: z.string().describe(
|
|
900
|
+
'The ductape CLI command to run, without the leading "ductape" word. ' +
|
|
901
|
+
'Examples: "products list", "products create --name \\"My Product\\" --tag my-product", ' +
|
|
902
|
+
'"apps list", "apps create -f app.json", "resources storage list", ' +
|
|
903
|
+
'"cloud connections list", "link --product my-product --env dev".\n\n' +
|
|
904
|
+
'Use this tool for administrative operations: creating or updating products, apps, ' +
|
|
905
|
+
'resources (databases, storage, caches…), cloud connections, secrets, ' +
|
|
906
|
+
'and for apply/migrate workflows.\n\n' +
|
|
907
|
+
'Note: environments, app actions, features, quotas, fallbacks, and jobs are configured ' +
|
|
908
|
+
'in the Workbench UI — there are no CLI commands for them.\n\n' +
|
|
909
|
+
'The CLI uses the user\'s local logged-in session (ductape login) — no key is required.',
|
|
910
|
+
),
|
|
911
|
+
});
|
|
912
|
+
|
|
823
913
|
async function loadMcpSdk(): Promise<{
|
|
824
914
|
McpServer: new (info: { name: string; version: string }) => any;
|
|
825
915
|
StdioServerTransport: new () => any;
|
|
@@ -884,6 +974,34 @@ async function main() {
|
|
|
884
974
|
const server = new McpServer({ name: 'ductape-mcp', version: '0.1.0' });
|
|
885
975
|
const transport = new StdioServerTransport();
|
|
886
976
|
|
|
977
|
+
const cliHandler = async (args: { command: string }) => {
|
|
978
|
+
const cli = checkCli();
|
|
979
|
+
if (!cli.available) {
|
|
980
|
+
return {
|
|
981
|
+
content: [{
|
|
982
|
+
type: 'text',
|
|
983
|
+
text: [
|
|
984
|
+
'The Ductape CLI is not installed or not in PATH.',
|
|
985
|
+
'',
|
|
986
|
+
'Install it with:',
|
|
987
|
+
' npm install --global @ductape/cli',
|
|
988
|
+
'',
|
|
989
|
+
'Then log in:',
|
|
990
|
+
' ductape login',
|
|
991
|
+
'',
|
|
992
|
+
'After logging in, retry this operation.',
|
|
993
|
+
].join('\n'),
|
|
994
|
+
}],
|
|
995
|
+
isError: true,
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
const result = runCli(args.command);
|
|
999
|
+
return {
|
|
1000
|
+
content: [{ type: 'text', text: result.output || '(no output)' }],
|
|
1001
|
+
...(result.success ? {} : { isError: true }),
|
|
1002
|
+
};
|
|
1003
|
+
};
|
|
1004
|
+
|
|
887
1005
|
const executeHandler = async (args: { publishable_key?: string; module: SDKModule; method: string; params: unknown[] }) => {
|
|
888
1006
|
try {
|
|
889
1007
|
const key = args.publishable_key || process.env.DUCTAPE_PUBLISHABLE_KEY;
|
|
@@ -963,12 +1081,14 @@ async function main() {
|
|
|
963
1081
|
{
|
|
964
1082
|
title: 'Ductape SDK Execute',
|
|
965
1083
|
description:
|
|
966
|
-
'Execute a Ductape SDK operation via the backend proxy.\n\n' +
|
|
967
|
-
'
|
|
968
|
-
'
|
|
969
|
-
'
|
|
970
|
-
'
|
|
971
|
-
'
|
|
1084
|
+
'Execute a Ductape SDK RUNTIME operation via the backend proxy (publishable key).\n\n' +
|
|
1085
|
+
'ONLY use this tool for runtime operations: run, dispatch, execute, start, send, produce, query, insert, update, delete.\n' +
|
|
1086
|
+
'Do NOT use this for creating or updating any asset (product, app, action, environment, database, storage, etc.) — ' +
|
|
1087
|
+
'those require an access key. Use ductape_cli for all creation and update operations.\n\n' +
|
|
1088
|
+
'Two-step rule for runtime operations:\n' +
|
|
1089
|
+
' 1. Call ductape_generate_payload first to get the canonical payload template.\n' +
|
|
1090
|
+
' This reveals the exact "input" field keys — they are product/env/operation-specific.\n' +
|
|
1091
|
+
' 2. Fill in the values from the template, then call ductape_execute.',
|
|
972
1092
|
inputSchema: executeInputSchema,
|
|
973
1093
|
},
|
|
974
1094
|
executeHandler,
|
|
@@ -1011,11 +1131,37 @@ async function main() {
|
|
|
1011
1131
|
},
|
|
1012
1132
|
schemaHandler,
|
|
1013
1133
|
);
|
|
1134
|
+
server.registerTool(
|
|
1135
|
+
'ductape_cli',
|
|
1136
|
+
{
|
|
1137
|
+
title: 'Ductape CLI',
|
|
1138
|
+
description:
|
|
1139
|
+
'Run a Ductape CLI command for administrative operations.\n\n' +
|
|
1140
|
+
'USE THIS TOOL for any operation that creates or modifies platform configuration:\n' +
|
|
1141
|
+
' - Creating or updating products (products create/update) and apps (apps create/update)\n' +
|
|
1142
|
+
' - Importing an app from a Postman v2.1 or OpenAPI 3.0 file: "apps import <file> -t postman|openapi"\n' +
|
|
1143
|
+
' - Managing resources via "resources <type> <verb>" (databases, storage, caches…)\n' +
|
|
1144
|
+
' - Managing cloud connections and cloud-linked resources\n' +
|
|
1145
|
+
' - Listing workspaces, products, secrets\n' +
|
|
1146
|
+
' - Linking a project folder: "link --product <tag> --env <slug>"\n' +
|
|
1147
|
+
' - Syncing sessions/notifications/events: "apply" or "apply sessions" etc.\n' +
|
|
1148
|
+
' - Running database migrations: "db migrate", "db schema generate"\n\n' +
|
|
1149
|
+
'NOTE: Environments, app actions, auths, features, quotas, fallbacks, and jobs are ' +
|
|
1150
|
+
'configured in the Workbench UI — the CLI does not have commands for them.\n\n' +
|
|
1151
|
+
'DO NOT use ductape_execute for admin operations — it uses a publishable key which only ' +
|
|
1152
|
+
'covers runtime operations. Administrative operations will fail with "Authentication failed".\n\n' +
|
|
1153
|
+
'The CLI uses the user\'s local logged-in session (ductape login). ' +
|
|
1154
|
+
'If the CLI is not installed, this tool will return install instructions automatically.',
|
|
1155
|
+
inputSchema: cliInputSchema,
|
|
1156
|
+
},
|
|
1157
|
+
cliHandler,
|
|
1158
|
+
);
|
|
1014
1159
|
} else if (typeof server.tool === 'function') {
|
|
1015
1160
|
server.tool('ductape_execute', executeInputSchema.shape, executeHandler);
|
|
1016
1161
|
server.tool('ductape_generate_payload', payloadGenerateInputSchema.shape, payloadGenerateHandler);
|
|
1017
1162
|
server.tool('ductape_generate_snippet', snippetGenerateInputSchema.shape, snippetGenerateHandler);
|
|
1018
1163
|
server.tool('ductape_schema', schemaInputSchema.shape, schemaHandler);
|
|
1164
|
+
server.tool('ductape_cli', cliInputSchema.shape, cliHandler);
|
|
1019
1165
|
} else {
|
|
1020
1166
|
console.error('MCP server does not expose .registerTool() or .tool()');
|
|
1021
1167
|
process.exit(1);
|