@ductape/mcp 0.1.4 → 0.1.6
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 +124 -34
- package/package.json +1 -1
- package/src/index.ts +129 -34
package/dist/index.js
CHANGED
|
@@ -31,20 +31,39 @@ There are THREE categories of operations. Use the right tool for each:
|
|
|
31
31
|
These require an access key and CANNOT be done via ductape_execute (publishable key only).
|
|
32
32
|
→ Use ductape_cli instead. Examples:
|
|
33
33
|
ductape_cli("products list")
|
|
34
|
-
ductape_cli("
|
|
35
|
-
ductape_cli("environments list my-product")
|
|
34
|
+
ductape_cli("products create --name \\"My Product\\" --tag my-product")
|
|
36
35
|
ductape_cli("cloud connections list")
|
|
36
|
+
ductape_cli("link --product my-product --env dev")
|
|
37
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
|
|
38
56
|
|
|
39
57
|
1. ASSET CREATION / UPDATE (create, update, add, register… for ANY asset type)
|
|
40
58
|
ALL creation and update operations require an access key and CANNOT go through ductape_execute.
|
|
41
59
|
→ Use ductape_cli for every create/update operation. Examples:
|
|
42
|
-
ductape_cli("
|
|
60
|
+
ductape_cli("apps create --name \\"Email Service\\" --description \\"Transactional email\\"")
|
|
43
61
|
ductape_cli("apps list")
|
|
44
|
-
ductape_cli("
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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.
|
|
48
67
|
|
|
49
68
|
2. RUNTIME OPERATIONS (run, dispatch, execute, start, send, produce, query, insert, update, delete…)
|
|
50
69
|
The "input" field shape is product- and operation-specific — it is NOT derivable from Joi validators.
|
|
@@ -787,28 +806,22 @@ function buildSnippet(language, payload, operationFamily, method) {
|
|
|
787
806
|
: buildTypeScriptSnippet(payload, operationFamily, method);
|
|
788
807
|
}
|
|
789
808
|
// ─── CLI helpers ─────────────────────────────────────────────────────────────
|
|
809
|
+
// Per-process cache: avoids re-running whoami / workspaces use on every call.
|
|
810
|
+
let authState = 'unknown';
|
|
811
|
+
let workspaceSynced = false;
|
|
790
812
|
const ADMIN_SUBCOMMANDS = [
|
|
791
|
-
'
|
|
792
|
-
'
|
|
793
|
-
'workspaces',
|
|
794
|
-
'
|
|
813
|
+
'login', 'logout', 'whoami',
|
|
814
|
+
'profiles',
|
|
815
|
+
'workspaces',
|
|
816
|
+
'link', 'unlink', 'init',
|
|
817
|
+
'products', 'apps',
|
|
818
|
+
'resources',
|
|
795
819
|
'cloud',
|
|
796
820
|
'secrets',
|
|
797
|
-
'databases',
|
|
798
|
-
'storage',
|
|
799
|
-
'graphs',
|
|
800
|
-
'vectors',
|
|
801
|
-
'brokers',
|
|
802
|
-
'notifications',
|
|
803
|
-
'sessions',
|
|
804
|
-
'caches',
|
|
805
|
-
'jobs',
|
|
806
821
|
'generate',
|
|
807
|
-
'
|
|
808
|
-
'
|
|
809
|
-
'
|
|
810
|
-
'logout',
|
|
811
|
-
'whoami',
|
|
822
|
+
'apply',
|
|
823
|
+
'db',
|
|
824
|
+
'graph',
|
|
812
825
|
];
|
|
813
826
|
function checkCli() {
|
|
814
827
|
try {
|
|
@@ -819,6 +832,29 @@ function checkCli() {
|
|
|
819
832
|
return { available: false };
|
|
820
833
|
}
|
|
821
834
|
}
|
|
835
|
+
function checkLoginState() {
|
|
836
|
+
try {
|
|
837
|
+
execSync('ductape whoami --json', { encoding: 'utf8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
838
|
+
authState = 'ok';
|
|
839
|
+
return 'ok';
|
|
840
|
+
}
|
|
841
|
+
catch {
|
|
842
|
+
authState = 'none';
|
|
843
|
+
return 'none';
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
function syncWorkspace() {
|
|
847
|
+
const target = process.env.DUCTAPE_WORKSPACE;
|
|
848
|
+
workspaceSynced = true; // mark done regardless so we don't retry on every call
|
|
849
|
+
if (!target)
|
|
850
|
+
return;
|
|
851
|
+
try {
|
|
852
|
+
execSync(`ductape workspaces use "${target}"`, { encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
853
|
+
}
|
|
854
|
+
catch {
|
|
855
|
+
// best-effort; if it fails the user will see workspace-mismatch errors on subsequent commands
|
|
856
|
+
}
|
|
857
|
+
}
|
|
822
858
|
function runCli(command) {
|
|
823
859
|
const first = command.trim().split(/\s+/)[0];
|
|
824
860
|
if (!ADMIN_SUBCOMMANDS.includes(first)) {
|
|
@@ -827,8 +863,14 @@ function runCli(command) {
|
|
|
827
863
|
output: `Subcommand "${first}" is not in the allowed admin subcommand list. Allowed: ${ADMIN_SUBCOMMANDS.join(', ')}.`,
|
|
828
864
|
};
|
|
829
865
|
}
|
|
866
|
+
// Auto-inject --workspace on login if DUCTAPE_WORKSPACE is set and caller hasn't specified one
|
|
867
|
+
let finalCommand = command;
|
|
868
|
+
const ws = process.env.DUCTAPE_WORKSPACE;
|
|
869
|
+
if (first === 'login' && ws && !command.includes('--workspace') && !command.includes('--skip-workspace-select')) {
|
|
870
|
+
finalCommand = `${command} --workspace "${ws}"`;
|
|
871
|
+
}
|
|
830
872
|
try {
|
|
831
|
-
const output = execSync(`ductape ${
|
|
873
|
+
const output = execSync(`ductape ${finalCommand}`, {
|
|
832
874
|
encoding: 'utf8',
|
|
833
875
|
timeout: 30000,
|
|
834
876
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -842,10 +884,14 @@ function runCli(command) {
|
|
|
842
884
|
}
|
|
843
885
|
const cliInputSchema = z.object({
|
|
844
886
|
command: z.string().describe('The ductape CLI command to run, without the leading "ductape" word. ' +
|
|
845
|
-
'Examples: "products list", "
|
|
846
|
-
'"
|
|
847
|
-
'
|
|
848
|
-
'
|
|
887
|
+
'Examples: "products list", "products create --name \\"My Product\\" --tag my-product", ' +
|
|
888
|
+
'"apps list", "apps create -f app.json", "resources storage list", ' +
|
|
889
|
+
'"cloud connections list", "link --product my-product --env dev".\n\n' +
|
|
890
|
+
'Use this tool for administrative operations: creating or updating products, apps, ' +
|
|
891
|
+
'resources (databases, storage, caches…), cloud connections, secrets, ' +
|
|
892
|
+
'and for apply/migrate workflows.\n\n' +
|
|
893
|
+
'Note: environments, app actions, features, quotas, fallbacks, and jobs are configured ' +
|
|
894
|
+
'in the Workbench UI — there are no CLI commands for them.\n\n' +
|
|
849
895
|
'The CLI uses the user\'s local logged-in session (ductape login) — no key is required.'),
|
|
850
896
|
});
|
|
851
897
|
async function loadMcpSdk() {
|
|
@@ -923,7 +969,45 @@ async function main() {
|
|
|
923
969
|
isError: true,
|
|
924
970
|
};
|
|
925
971
|
}
|
|
972
|
+
const firstWord = args.command.trim().split(/\s+/)[0];
|
|
973
|
+
const isAuthCommand = firstWord === 'login' || firstWord === 'logout';
|
|
974
|
+
if (!isAuthCommand) {
|
|
975
|
+
// Check login status once per process (cached after first call)
|
|
976
|
+
if (authState === 'unknown') {
|
|
977
|
+
checkLoginState();
|
|
978
|
+
}
|
|
979
|
+
if (authState === 'none') {
|
|
980
|
+
const wsFlag = process.env.DUCTAPE_WORKSPACE ? ` --workspace "${process.env.DUCTAPE_WORKSPACE}"` : '';
|
|
981
|
+
return {
|
|
982
|
+
content: [{
|
|
983
|
+
type: 'text',
|
|
984
|
+
text: [
|
|
985
|
+
'Not logged in to the Ductape CLI.',
|
|
986
|
+
'',
|
|
987
|
+
'Ask the user for their Ductape email and password, then call:',
|
|
988
|
+
` ductape_cli("login --email <email> --password <password>${wsFlag}")`,
|
|
989
|
+
'',
|
|
990
|
+
'Or the user can run `ductape login` in their terminal and then retry.',
|
|
991
|
+
].join('\n'),
|
|
992
|
+
}],
|
|
993
|
+
isError: true,
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
// Sync to the configured workspace once per process (best-effort)
|
|
997
|
+
if (!workspaceSynced) {
|
|
998
|
+
syncWorkspace();
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
926
1001
|
const result = runCli(args.command);
|
|
1002
|
+
// Update cached state after auth commands
|
|
1003
|
+
if (firstWord === 'login' && result.success) {
|
|
1004
|
+
authState = 'ok';
|
|
1005
|
+
workspaceSynced = false; // re-sync workspace after fresh login
|
|
1006
|
+
}
|
|
1007
|
+
if (firstWord === 'logout' && result.success) {
|
|
1008
|
+
authState = 'none';
|
|
1009
|
+
workspaceSynced = false;
|
|
1010
|
+
}
|
|
927
1011
|
return {
|
|
928
1012
|
content: [{ type: 'text', text: result.output || '(no output)' }],
|
|
929
1013
|
...(result.success ? {} : { isError: true }),
|
|
@@ -1035,11 +1119,17 @@ async function main() {
|
|
|
1035
1119
|
title: 'Ductape CLI',
|
|
1036
1120
|
description: 'Run a Ductape CLI command for administrative operations.\n\n' +
|
|
1037
1121
|
'USE THIS TOOL for any operation that creates or modifies platform configuration:\n' +
|
|
1038
|
-
' - Creating or updating products
|
|
1039
|
-
' -
|
|
1122
|
+
' - Creating or updating products (products create/update) and apps (apps create/update)\n' +
|
|
1123
|
+
' - Importing an app from a Postman v2.1 or OpenAPI 3.0 file: "apps import <file> -t postman|openapi"\n' +
|
|
1124
|
+
' - Managing resources via "resources <type> <verb>" (databases, storage, caches…)\n' +
|
|
1125
|
+
' - Managing cloud connections and cloud-linked resources\n' +
|
|
1040
1126
|
' - Listing workspaces, products, secrets\n' +
|
|
1041
|
-
' -
|
|
1042
|
-
'
|
|
1127
|
+
' - Linking a project folder: "link --product <tag> --env <slug>"\n' +
|
|
1128
|
+
' - Syncing sessions/notifications/events: "apply" or "apply sessions" etc.\n' +
|
|
1129
|
+
' - Running database migrations: "db migrate", "db schema generate"\n\n' +
|
|
1130
|
+
'NOTE: Environments, app actions, auths, features, quotas, fallbacks, and jobs are ' +
|
|
1131
|
+
'configured in the Workbench UI — the CLI does not have commands for them.\n\n' +
|
|
1132
|
+
'DO NOT use ductape_execute for admin operations — it uses a publishable key which only ' +
|
|
1043
1133
|
'covers runtime operations. Administrative operations will fail with "Authentication failed".\n\n' +
|
|
1044
1134
|
'The CLI uses the user\'s local logged-in session (ductape login). ' +
|
|
1045
1135
|
'If the CLI is not installed, this tool will return install instructions automatically.',
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -42,20 +42,39 @@ There are THREE categories of operations. Use the right tool for each:
|
|
|
42
42
|
These require an access key and CANNOT be done via ductape_execute (publishable key only).
|
|
43
43
|
→ Use ductape_cli instead. Examples:
|
|
44
44
|
ductape_cli("products list")
|
|
45
|
-
ductape_cli("
|
|
46
|
-
ductape_cli("environments list my-product")
|
|
45
|
+
ductape_cli("products create --name \\"My Product\\" --tag my-product")
|
|
47
46
|
ductape_cli("cloud connections list")
|
|
47
|
+
ductape_cli("link --product my-product --env dev")
|
|
48
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
|
|
49
67
|
|
|
50
68
|
1. ASSET CREATION / UPDATE (create, update, add, register… for ANY asset type)
|
|
51
69
|
ALL creation and update operations require an access key and CANNOT go through ductape_execute.
|
|
52
70
|
→ Use ductape_cli for every create/update operation. Examples:
|
|
53
|
-
ductape_cli("
|
|
71
|
+
ductape_cli("apps create --name \\"Email Service\\" --description \\"Transactional email\\"")
|
|
54
72
|
ductape_cli("apps list")
|
|
55
|
-
ductape_cli("
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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.
|
|
59
78
|
|
|
60
79
|
2. RUNTIME OPERATIONS (run, dispatch, execute, start, send, produce, query, insert, update, delete…)
|
|
61
80
|
The "input" field shape is product- and operation-specific — it is NOT derivable from Joi validators.
|
|
@@ -831,28 +850,23 @@ function buildSnippet(
|
|
|
831
850
|
|
|
832
851
|
// ─── CLI helpers ─────────────────────────────────────────────────────────────
|
|
833
852
|
|
|
853
|
+
// Per-process cache: avoids re-running whoami / workspaces use on every call.
|
|
854
|
+
let authState: 'unknown' | 'ok' | 'none' = 'unknown';
|
|
855
|
+
let workspaceSynced = false;
|
|
856
|
+
|
|
834
857
|
const ADMIN_SUBCOMMANDS = [
|
|
835
|
-
'
|
|
836
|
-
'
|
|
837
|
-
'workspaces',
|
|
838
|
-
'
|
|
858
|
+
'login', 'logout', 'whoami',
|
|
859
|
+
'profiles',
|
|
860
|
+
'workspaces',
|
|
861
|
+
'link', 'unlink', 'init',
|
|
862
|
+
'products', 'apps',
|
|
863
|
+
'resources',
|
|
839
864
|
'cloud',
|
|
840
865
|
'secrets',
|
|
841
|
-
'databases',
|
|
842
|
-
'storage',
|
|
843
|
-
'graphs',
|
|
844
|
-
'vectors',
|
|
845
|
-
'brokers',
|
|
846
|
-
'notifications',
|
|
847
|
-
'sessions',
|
|
848
|
-
'caches',
|
|
849
|
-
'jobs',
|
|
850
866
|
'generate',
|
|
851
|
-
'
|
|
852
|
-
'
|
|
853
|
-
'
|
|
854
|
-
'logout',
|
|
855
|
-
'whoami',
|
|
867
|
+
'apply',
|
|
868
|
+
'db',
|
|
869
|
+
'graph',
|
|
856
870
|
];
|
|
857
871
|
|
|
858
872
|
function checkCli(): { available: boolean; version?: string } {
|
|
@@ -864,6 +878,28 @@ function checkCli(): { available: boolean; version?: string } {
|
|
|
864
878
|
}
|
|
865
879
|
}
|
|
866
880
|
|
|
881
|
+
function checkLoginState(): 'ok' | 'none' {
|
|
882
|
+
try {
|
|
883
|
+
execSync('ductape whoami --json', { encoding: 'utf8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
884
|
+
authState = 'ok';
|
|
885
|
+
return 'ok';
|
|
886
|
+
} catch {
|
|
887
|
+
authState = 'none';
|
|
888
|
+
return 'none';
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
function syncWorkspace(): void {
|
|
893
|
+
const target = process.env.DUCTAPE_WORKSPACE;
|
|
894
|
+
workspaceSynced = true; // mark done regardless so we don't retry on every call
|
|
895
|
+
if (!target) return;
|
|
896
|
+
try {
|
|
897
|
+
execSync(`ductape workspaces use "${target}"`, { encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
898
|
+
} catch {
|
|
899
|
+
// best-effort; if it fails the user will see workspace-mismatch errors on subsequent commands
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
867
903
|
function runCli(command: string): { success: boolean; output: string } {
|
|
868
904
|
const first = command.trim().split(/\s+/)[0];
|
|
869
905
|
if (!ADMIN_SUBCOMMANDS.includes(first)) {
|
|
@@ -872,8 +908,14 @@ function runCli(command: string): { success: boolean; output: string } {
|
|
|
872
908
|
output: `Subcommand "${first}" is not in the allowed admin subcommand list. Allowed: ${ADMIN_SUBCOMMANDS.join(', ')}.`,
|
|
873
909
|
};
|
|
874
910
|
}
|
|
911
|
+
// Auto-inject --workspace on login if DUCTAPE_WORKSPACE is set and caller hasn't specified one
|
|
912
|
+
let finalCommand = command;
|
|
913
|
+
const ws = process.env.DUCTAPE_WORKSPACE;
|
|
914
|
+
if (first === 'login' && ws && !command.includes('--workspace') && !command.includes('--skip-workspace-select')) {
|
|
915
|
+
finalCommand = `${command} --workspace "${ws}"`;
|
|
916
|
+
}
|
|
875
917
|
try {
|
|
876
|
-
const output = execSync(`ductape ${
|
|
918
|
+
const output = execSync(`ductape ${finalCommand}`, {
|
|
877
919
|
encoding: 'utf8',
|
|
878
920
|
timeout: 30000,
|
|
879
921
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -888,10 +930,14 @@ function runCli(command: string): { success: boolean; output: string } {
|
|
|
888
930
|
const cliInputSchema = z.object({
|
|
889
931
|
command: z.string().describe(
|
|
890
932
|
'The ductape CLI command to run, without the leading "ductape" word. ' +
|
|
891
|
-
'Examples: "products list", "
|
|
892
|
-
'"
|
|
893
|
-
'
|
|
894
|
-
'
|
|
933
|
+
'Examples: "products list", "products create --name \\"My Product\\" --tag my-product", ' +
|
|
934
|
+
'"apps list", "apps create -f app.json", "resources storage list", ' +
|
|
935
|
+
'"cloud connections list", "link --product my-product --env dev".\n\n' +
|
|
936
|
+
'Use this tool for administrative operations: creating or updating products, apps, ' +
|
|
937
|
+
'resources (databases, storage, caches…), cloud connections, secrets, ' +
|
|
938
|
+
'and for apply/migrate workflows.\n\n' +
|
|
939
|
+
'Note: environments, app actions, features, quotas, fallbacks, and jobs are configured ' +
|
|
940
|
+
'in the Workbench UI — there are no CLI commands for them.\n\n' +
|
|
895
941
|
'The CLI uses the user\'s local logged-in session (ductape login) — no key is required.',
|
|
896
942
|
),
|
|
897
943
|
});
|
|
@@ -981,7 +1027,50 @@ async function main() {
|
|
|
981
1027
|
isError: true,
|
|
982
1028
|
};
|
|
983
1029
|
}
|
|
1030
|
+
|
|
1031
|
+
const firstWord = args.command.trim().split(/\s+/)[0];
|
|
1032
|
+
const isAuthCommand = firstWord === 'login' || firstWord === 'logout';
|
|
1033
|
+
|
|
1034
|
+
if (!isAuthCommand) {
|
|
1035
|
+
// Check login status once per process (cached after first call)
|
|
1036
|
+
if (authState === 'unknown') {
|
|
1037
|
+
checkLoginState();
|
|
1038
|
+
}
|
|
1039
|
+
if (authState === 'none') {
|
|
1040
|
+
const wsFlag = process.env.DUCTAPE_WORKSPACE ? ` --workspace "${process.env.DUCTAPE_WORKSPACE}"` : '';
|
|
1041
|
+
return {
|
|
1042
|
+
content: [{
|
|
1043
|
+
type: 'text',
|
|
1044
|
+
text: [
|
|
1045
|
+
'Not logged in to the Ductape CLI.',
|
|
1046
|
+
'',
|
|
1047
|
+
'Ask the user for their Ductape email and password, then call:',
|
|
1048
|
+
` ductape_cli("login --email <email> --password <password>${wsFlag}")`,
|
|
1049
|
+
'',
|
|
1050
|
+
'Or the user can run `ductape login` in their terminal and then retry.',
|
|
1051
|
+
].join('\n'),
|
|
1052
|
+
}],
|
|
1053
|
+
isError: true,
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
// Sync to the configured workspace once per process (best-effort)
|
|
1057
|
+
if (!workspaceSynced) {
|
|
1058
|
+
syncWorkspace();
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
|
|
984
1062
|
const result = runCli(args.command);
|
|
1063
|
+
|
|
1064
|
+
// Update cached state after auth commands
|
|
1065
|
+
if (firstWord === 'login' && result.success) {
|
|
1066
|
+
authState = 'ok';
|
|
1067
|
+
workspaceSynced = false; // re-sync workspace after fresh login
|
|
1068
|
+
}
|
|
1069
|
+
if (firstWord === 'logout' && result.success) {
|
|
1070
|
+
authState = 'none';
|
|
1071
|
+
workspaceSynced = false;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
985
1074
|
return {
|
|
986
1075
|
content: [{ type: 'text', text: result.output || '(no output)' }],
|
|
987
1076
|
...(result.success ? {} : { isError: true }),
|
|
@@ -1124,11 +1213,17 @@ async function main() {
|
|
|
1124
1213
|
description:
|
|
1125
1214
|
'Run a Ductape CLI command for administrative operations.\n\n' +
|
|
1126
1215
|
'USE THIS TOOL for any operation that creates or modifies platform configuration:\n' +
|
|
1127
|
-
' - Creating or updating products
|
|
1128
|
-
' -
|
|
1216
|
+
' - Creating or updating products (products create/update) and apps (apps create/update)\n' +
|
|
1217
|
+
' - Importing an app from a Postman v2.1 or OpenAPI 3.0 file: "apps import <file> -t postman|openapi"\n' +
|
|
1218
|
+
' - Managing resources via "resources <type> <verb>" (databases, storage, caches…)\n' +
|
|
1219
|
+
' - Managing cloud connections and cloud-linked resources\n' +
|
|
1129
1220
|
' - Listing workspaces, products, secrets\n' +
|
|
1130
|
-
' -
|
|
1131
|
-
'
|
|
1221
|
+
' - Linking a project folder: "link --product <tag> --env <slug>"\n' +
|
|
1222
|
+
' - Syncing sessions/notifications/events: "apply" or "apply sessions" etc.\n' +
|
|
1223
|
+
' - Running database migrations: "db migrate", "db schema generate"\n\n' +
|
|
1224
|
+
'NOTE: Environments, app actions, auths, features, quotas, fallbacks, and jobs are ' +
|
|
1225
|
+
'configured in the Workbench UI — the CLI does not have commands for them.\n\n' +
|
|
1226
|
+
'DO NOT use ductape_execute for admin operations — it uses a publishable key which only ' +
|
|
1132
1227
|
'covers runtime operations. Administrative operations will fail with "Authentication failed".\n\n' +
|
|
1133
1228
|
'The CLI uses the user\'s local logged-in session (ductape login). ' +
|
|
1134
1229
|
'If the CLI is not installed, this tool will return install instructions automatically.',
|