@mcp-z/cli 1.0.0

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 (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +166 -0
  3. package/bin/cli.js +5 -0
  4. package/dist/cjs/cli.d.cts +1 -0
  5. package/dist/cjs/cli.d.ts +1 -0
  6. package/dist/cjs/cli.js +576 -0
  7. package/dist/cjs/cli.js.map +1 -0
  8. package/dist/cjs/commands/call-tool.d.cts +26 -0
  9. package/dist/cjs/commands/call-tool.d.ts +26 -0
  10. package/dist/cjs/commands/call-tool.js +362 -0
  11. package/dist/cjs/commands/call-tool.js.map +1 -0
  12. package/dist/cjs/commands/get-prompt.d.cts +26 -0
  13. package/dist/cjs/commands/get-prompt.d.ts +26 -0
  14. package/dist/cjs/commands/get-prompt.js +335 -0
  15. package/dist/cjs/commands/get-prompt.js.map +1 -0
  16. package/dist/cjs/commands/inspect.d.cts +35 -0
  17. package/dist/cjs/commands/inspect.d.ts +35 -0
  18. package/dist/cjs/commands/inspect.js +896 -0
  19. package/dist/cjs/commands/inspect.js.map +1 -0
  20. package/dist/cjs/commands/manifest/env-prompting.d.cts +21 -0
  21. package/dist/cjs/commands/manifest/env-prompting.d.ts +21 -0
  22. package/dist/cjs/commands/manifest/env-prompting.js +657 -0
  23. package/dist/cjs/commands/manifest/env-prompting.js.map +1 -0
  24. package/dist/cjs/commands/manifest/generate.d.cts +124 -0
  25. package/dist/cjs/commands/manifest/generate.d.ts +124 -0
  26. package/dist/cjs/commands/manifest/generate.js +2541 -0
  27. package/dist/cjs/commands/manifest/generate.js.map +1 -0
  28. package/dist/cjs/commands/manifest/index.d.cts +2 -0
  29. package/dist/cjs/commands/manifest/index.d.ts +2 -0
  30. package/dist/cjs/commands/manifest/index.js +229 -0
  31. package/dist/cjs/commands/manifest/index.js.map +1 -0
  32. package/dist/cjs/commands/manifest/metadata-reader.d.cts +71 -0
  33. package/dist/cjs/commands/manifest/metadata-reader.d.ts +71 -0
  34. package/dist/cjs/commands/manifest/metadata-reader.js +441 -0
  35. package/dist/cjs/commands/manifest/metadata-reader.js.map +1 -0
  36. package/dist/cjs/commands/manifest/validate.d.cts +1 -0
  37. package/dist/cjs/commands/manifest/validate.d.ts +1 -0
  38. package/dist/cjs/commands/manifest/validate.js +525 -0
  39. package/dist/cjs/commands/manifest/validate.js.map +1 -0
  40. package/dist/cjs/commands/read-resource.d.cts +24 -0
  41. package/dist/cjs/commands/read-resource.d.ts +24 -0
  42. package/dist/cjs/commands/read-resource.js +311 -0
  43. package/dist/cjs/commands/read-resource.js.map +1 -0
  44. package/dist/cjs/commands/search.d.cts +31 -0
  45. package/dist/cjs/commands/search.d.ts +31 -0
  46. package/dist/cjs/commands/search.js +464 -0
  47. package/dist/cjs/commands/search.js.map +1 -0
  48. package/dist/cjs/commands/up.d.cts +49 -0
  49. package/dist/cjs/commands/up.d.ts +49 -0
  50. package/dist/cjs/commands/up.js +235 -0
  51. package/dist/cjs/commands/up.js.map +1 -0
  52. package/dist/cjs/index.d.cts +7 -0
  53. package/dist/cjs/index.d.ts +7 -0
  54. package/dist/cjs/index.js +85 -0
  55. package/dist/cjs/index.js.map +1 -0
  56. package/dist/cjs/lib/find-config.d.cts +14 -0
  57. package/dist/cjs/lib/find-config.d.ts +14 -0
  58. package/dist/cjs/lib/find-config.js +93 -0
  59. package/dist/cjs/lib/find-config.js.map +1 -0
  60. package/dist/cjs/lib/json-schema.d.cts +18 -0
  61. package/dist/cjs/lib/json-schema.d.ts +18 -0
  62. package/dist/cjs/lib/json-schema.js +306 -0
  63. package/dist/cjs/lib/json-schema.js.map +1 -0
  64. package/dist/cjs/lib/resolve-server-config.d.cts +50 -0
  65. package/dist/cjs/lib/resolve-server-config.d.ts +50 -0
  66. package/dist/cjs/lib/resolve-server-config.js +214 -0
  67. package/dist/cjs/lib/resolve-server-config.js.map +1 -0
  68. package/dist/cjs/package.json +1 -0
  69. package/dist/cjs/types.d.cts +21 -0
  70. package/dist/cjs/types.d.ts +21 -0
  71. package/dist/cjs/types.js +32 -0
  72. package/dist/cjs/types.js.map +1 -0
  73. package/dist/esm/cli.d.ts +1 -0
  74. package/dist/esm/cli.js +129 -0
  75. package/dist/esm/cli.js.map +1 -0
  76. package/dist/esm/commands/call-tool.d.ts +26 -0
  77. package/dist/esm/commands/call-tool.js +151 -0
  78. package/dist/esm/commands/call-tool.js.map +1 -0
  79. package/dist/esm/commands/get-prompt.d.ts +26 -0
  80. package/dist/esm/commands/get-prompt.js +118 -0
  81. package/dist/esm/commands/get-prompt.js.map +1 -0
  82. package/dist/esm/commands/inspect.d.ts +35 -0
  83. package/dist/esm/commands/inspect.js +438 -0
  84. package/dist/esm/commands/inspect.js.map +1 -0
  85. package/dist/esm/commands/manifest/env-prompting.d.ts +21 -0
  86. package/dist/esm/commands/manifest/env-prompting.js +213 -0
  87. package/dist/esm/commands/manifest/env-prompting.js.map +1 -0
  88. package/dist/esm/commands/manifest/generate.d.ts +124 -0
  89. package/dist/esm/commands/manifest/generate.js +1087 -0
  90. package/dist/esm/commands/manifest/generate.js.map +1 -0
  91. package/dist/esm/commands/manifest/index.d.ts +2 -0
  92. package/dist/esm/commands/manifest/index.js +23 -0
  93. package/dist/esm/commands/manifest/index.js.map +1 -0
  94. package/dist/esm/commands/manifest/metadata-reader.d.ts +71 -0
  95. package/dist/esm/commands/manifest/metadata-reader.js +143 -0
  96. package/dist/esm/commands/manifest/metadata-reader.js.map +1 -0
  97. package/dist/esm/commands/manifest/validate.d.ts +1 -0
  98. package/dist/esm/commands/manifest/validate.js +167 -0
  99. package/dist/esm/commands/manifest/validate.js.map +1 -0
  100. package/dist/esm/commands/read-resource.d.ts +24 -0
  101. package/dist/esm/commands/read-resource.js +95 -0
  102. package/dist/esm/commands/read-resource.js.map +1 -0
  103. package/dist/esm/commands/search.d.ts +31 -0
  104. package/dist/esm/commands/search.js +145 -0
  105. package/dist/esm/commands/search.js.map +1 -0
  106. package/dist/esm/commands/up.d.ts +49 -0
  107. package/dist/esm/commands/up.js +74 -0
  108. package/dist/esm/commands/up.js.map +1 -0
  109. package/dist/esm/index.d.ts +7 -0
  110. package/dist/esm/index.js +11 -0
  111. package/dist/esm/index.js.map +1 -0
  112. package/dist/esm/lib/find-config.d.ts +14 -0
  113. package/dist/esm/lib/find-config.js +42 -0
  114. package/dist/esm/lib/find-config.js.map +1 -0
  115. package/dist/esm/lib/json-schema.d.ts +18 -0
  116. package/dist/esm/lib/json-schema.js +66 -0
  117. package/dist/esm/lib/json-schema.js.map +1 -0
  118. package/dist/esm/lib/resolve-server-config.d.ts +50 -0
  119. package/dist/esm/lib/resolve-server-config.js +154 -0
  120. package/dist/esm/lib/resolve-server-config.js.map +1 -0
  121. package/dist/esm/package.json +1 -0
  122. package/dist/esm/types.d.ts +21 -0
  123. package/dist/esm/types.js +11 -0
  124. package/dist/esm/types.js.map +1 -0
  125. package/package.json +99 -0
  126. package/schemas/server.schema.json +489 -0
@@ -0,0 +1,213 @@
1
+ import confirm from '@inquirer/confirm';
2
+ import input from '@inquirer/input';
3
+ import password from '@inquirer/password';
4
+ import select from '@inquirer/select';
5
+ /**
6
+ * Redact sensitive values for display, showing only first 4 characters
7
+ * Example: "sk-1234567890abcdef" -> "sk-1XXX"
8
+ */ function redactValue(value, isSecret) {
9
+ if (!isSecret) {
10
+ return value;
11
+ }
12
+ if (value.length <= 6) {
13
+ return 'XXX';
14
+ }
15
+ return `${value.substring(0, 4)}XXX`;
16
+ }
17
+ /**
18
+ * Substitute template variables in a string
19
+ * Replaces any {VARIABLE_NAME} with the corresponding value from the variables map
20
+ * Variable names are case-insensitive
21
+ */ export function substituteTemplateVars(template, variables) {
22
+ if (!template || !variables) {
23
+ return template;
24
+ }
25
+ // Replace any {VARIABLE_NAME} with corresponding value from variables map
26
+ return template.replace(/\{([^}]+)\}/g, (match, varName)=>{
27
+ // Case-insensitive lookup
28
+ const key = Object.keys(variables).find((k)=>k.toLowerCase() === varName.toLowerCase());
29
+ return key ? variables[key] : match;
30
+ });
31
+ }
32
+ /**
33
+ * Get dynamic placeholder for env vars by substituting template variables
34
+ */ function getDynamicPlaceholder(envVar, variables) {
35
+ return substituteTemplateVars(envVar.placeholder, variables);
36
+ }
37
+ /**
38
+ * Prompt user for environment variables with support for:
39
+ * - Environment variable detection with partial redaction
40
+ * - Interactive prompts for required fields
41
+ * - Choice-based selection
42
+ * - Password input for secrets
43
+ * - Default values
44
+ * - Non-interactive mode (-y flag)
45
+ * - Dynamic placeholders via template variable substitution
46
+ */ export async function promptForEnvVars(serverName, envVars, options = {}) {
47
+ const env = {};
48
+ for (const envVar of envVars){
49
+ var _envVar_default;
50
+ const envValue = process.env[envVar.name];
51
+ // Support both 'default' (MCP schema standard) and 'value' (legacy) fields
52
+ const defaultValue = (_envVar_default = envVar.default) !== null && _envVar_default !== void 0 ? _envVar_default : envVar.value;
53
+ if (defaultValue) {
54
+ // Use default value from metadata if available
55
+ env[envVar.name] = defaultValue;
56
+ } else if (envValue && !options.yes && process.stdin.isTTY) {
57
+ // Environment variable exists - present option with partial redaction
58
+ const redactedValue = redactValue(envValue, envVar.isSecret);
59
+ const useEnvChoice = `${redactedValue} (environment)`;
60
+ if (envVar.choices && envVar.choices.length > 0) {
61
+ // Has choices - add environment value as an option
62
+ const choices = [
63
+ useEnvChoice,
64
+ ...envVar.choices,
65
+ 'Enter custom value'
66
+ ];
67
+ // Add skip option for optional fields
68
+ if (!envVar.isRequired) {
69
+ choices.push('Skip (optional)');
70
+ }
71
+ const message = `[${serverName}] ${envVar.name}`;
72
+ const value = await select({
73
+ message,
74
+ choices
75
+ });
76
+ if (value === useEnvChoice) {
77
+ env[envVar.name] = envValue;
78
+ } else if (value === 'Skip (optional)') {
79
+ // Skip this optional env var - don't add to env object
80
+ } else if (value === 'Enter custom value') {
81
+ const promptFn = envVar.isSecret ? password : input;
82
+ const customValue = await promptFn({
83
+ message: `[${serverName}] ${envVar.name} (enter value)`,
84
+ validate: (input)=>{
85
+ if (envVar.isRequired && (!input || input.trim() === '')) {
86
+ return 'This field is required';
87
+ }
88
+ return true;
89
+ }
90
+ });
91
+ env[envVar.name] = customValue;
92
+ } else {
93
+ env[envVar.name] = value;
94
+ }
95
+ } else {
96
+ // No choices - simple confirmation or new value
97
+ const actionChoices = [
98
+ {
99
+ name: `Use ${useEnvChoice}`,
100
+ value: 'use-env'
101
+ },
102
+ {
103
+ name: 'Enter new value',
104
+ value: 'enter-new'
105
+ }
106
+ ];
107
+ // Add skip option for optional fields
108
+ if (!envVar.isRequired) {
109
+ actionChoices.push({
110
+ name: 'Skip (optional)',
111
+ value: 'skip'
112
+ });
113
+ }
114
+ const message = `[${serverName}] ${envVar.name}`;
115
+ const action = await select({
116
+ message,
117
+ choices: actionChoices
118
+ });
119
+ if (action === 'use-env') {
120
+ env[envVar.name] = envValue;
121
+ } else if (action === 'skip') {
122
+ // Skip this optional env var - don't add to env object
123
+ } else {
124
+ const promptFn = envVar.isSecret ? password : input;
125
+ const newValue = await promptFn({
126
+ message: `[${serverName}] ${envVar.name} (enter value)`,
127
+ validate: (input)=>{
128
+ if (envVar.isRequired && (!input || input.trim() === '')) {
129
+ return 'This field is required';
130
+ }
131
+ return true;
132
+ }
133
+ });
134
+ env[envVar.name] = newValue;
135
+ }
136
+ }
137
+ } else if (options.yes) {
138
+ // -y mode: skip required vars without defaults (trust shell environment)
139
+ if (envVar.choices && envVar.choices.length > 0 && envVar.choices[0]) {
140
+ // Has choices - use first choice
141
+ env[envVar.name] = envVar.choices[0];
142
+ } else if (envVar.isRequired) {
143
+ // Required but no default - skip with warning
144
+ console.log(` ⚠️ Skipping ${envVar.name}`);
145
+ }
146
+ // Optional vars without defaults: skip silently
147
+ } else if (envVar.choices && envVar.choices.length > 0 && envVar.choices[0]) {
148
+ if (process.stdin.isTTY) {
149
+ // Interactive mode with choices - prompt user to select
150
+ const choices = [
151
+ ...envVar.choices
152
+ ];
153
+ // Add skip option for optional fields
154
+ if (!envVar.isRequired) {
155
+ choices.push('Skip (optional)');
156
+ }
157
+ const value = await select({
158
+ message: `[${serverName}] ${envVar.name}`,
159
+ choices
160
+ });
161
+ if (value !== 'Skip (optional)') {
162
+ env[envVar.name] = value;
163
+ }
164
+ // If 'Skip (optional)' selected, don't add to env object
165
+ } else {
166
+ // Non-interactive: use first choice
167
+ env[envVar.name] = envVar.choices[0];
168
+ }
169
+ } else if (envVar.isRequired) {
170
+ if (process.stdin.isTTY) {
171
+ // Interactive mode - required field - prompt for value
172
+ const promptFn = envVar.isSecret ? password : input;
173
+ const placeholder = getDynamicPlaceholder(envVar, options.templateVars);
174
+ const value = await promptFn({
175
+ message: `[${serverName}] ${envVar.name} (required)`,
176
+ ...placeholder ? {
177
+ default: placeholder
178
+ } : {},
179
+ validate: (input)=>{
180
+ if (!input || input.trim() === '') {
181
+ return 'This field is required';
182
+ }
183
+ return true;
184
+ }
185
+ });
186
+ env[envVar.name] = value;
187
+ }
188
+ // Non-interactive without -y: skip (will fail at runtime if truly required)
189
+ } else if (!envVar.isRequired && !options.yes && process.stdin.isTTY) {
190
+ // Interactive mode - optional env var without defaults
191
+ // Ask user if they want to set it
192
+ const shouldSet = await confirm({
193
+ message: `[${serverName}] Set optional ${envVar.name}? (${envVar.description || 'optional'})`,
194
+ default: false
195
+ });
196
+ if (shouldSet) {
197
+ const promptFn = envVar.isSecret ? password : input;
198
+ const placeholder = getDynamicPlaceholder(envVar, options.templateVars);
199
+ const value = await promptFn({
200
+ message: `[${serverName}] ${envVar.name}`,
201
+ ...placeholder ? {
202
+ default: placeholder
203
+ } : {}
204
+ });
205
+ if (value && value.trim() !== '') {
206
+ env[envVar.name] = value;
207
+ }
208
+ }
209
+ }
210
+ // Other optional env vars are skipped
211
+ }
212
+ return env;
213
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/cli/src/commands/manifest/env-prompting.ts"],"sourcesContent":["import confirm from '@inquirer/confirm';\nimport input from '@inquirer/input';\nimport password from '@inquirer/password';\nimport select from '@inquirer/select';\nimport type { EnvVarMetadata } from './metadata-reader.ts';\n\n/**\n * Redact sensitive values for display, showing only first 4 characters\n * Example: \"sk-1234567890abcdef\" -> \"sk-1XXX\"\n */\nfunction redactValue(value: string, isSecret: boolean): string {\n if (!isSecret) {\n return value;\n }\n\n if (value.length <= 6) {\n return 'XXX';\n }\n\n return `${value.substring(0, 4)}XXX`;\n}\n\n/**\n * Substitute template variables in a string\n * Replaces any {VARIABLE_NAME} with the corresponding value from the variables map\n * Variable names are case-insensitive\n */\nexport function substituteTemplateVars(template: string | undefined, variables?: Record<string, string>): string | undefined {\n if (!template || !variables) {\n return template;\n }\n\n // Replace any {VARIABLE_NAME} with corresponding value from variables map\n return template.replace(/\\{([^}]+)\\}/g, (match, varName) => {\n // Case-insensitive lookup\n const key = Object.keys(variables).find((k) => k.toLowerCase() === varName.toLowerCase());\n return key ? variables[key] : match;\n });\n}\n\n/**\n * Get dynamic placeholder for env vars by substituting template variables\n */\nfunction getDynamicPlaceholder(envVar: EnvVarMetadata, variables?: Record<string, string>): string | undefined {\n return substituteTemplateVars(envVar.placeholder, variables);\n}\n\n/**\n * Prompt user for environment variables with support for:\n * - Environment variable detection with partial redaction\n * - Interactive prompts for required fields\n * - Choice-based selection\n * - Password input for secrets\n * - Default values\n * - Non-interactive mode (-y flag)\n * - Dynamic placeholders via template variable substitution\n */\nexport async function promptForEnvVars(serverName: string, envVars: EnvVarMetadata[], options: { yes?: boolean; templateVars?: Record<string, string> } = {}): Promise<Record<string, string>> {\n const env: Record<string, string> = {};\n\n for (const envVar of envVars) {\n const envValue = process.env[envVar.name];\n // Support both 'default' (MCP schema standard) and 'value' (legacy) fields\n const defaultValue = envVar.default ?? envVar.value;\n\n if (defaultValue) {\n // Use default value from metadata if available\n env[envVar.name] = defaultValue;\n } else if (envValue && !options.yes && process.stdin.isTTY) {\n // Environment variable exists - present option with partial redaction\n const redactedValue = redactValue(envValue, envVar.isSecret);\n const useEnvChoice = `${redactedValue} (environment)`;\n\n if (envVar.choices && envVar.choices.length > 0) {\n // Has choices - add environment value as an option\n const choices = [useEnvChoice, ...envVar.choices, 'Enter custom value'];\n\n // Add skip option for optional fields\n if (!envVar.isRequired) {\n choices.push('Skip (optional)');\n }\n\n const message = `[${serverName}] ${envVar.name}`;\n\n const value = await select({\n message,\n choices,\n });\n\n if (value === useEnvChoice) {\n env[envVar.name] = envValue;\n } else if (value === 'Skip (optional)') {\n // Skip this optional env var - don't add to env object\n } else if (value === 'Enter custom value') {\n const promptFn = envVar.isSecret ? password : input;\n const customValue = await promptFn({\n message: `[${serverName}] ${envVar.name} (enter value)`,\n validate: (input: string) => {\n if (envVar.isRequired && (!input || input.trim() === '')) {\n return 'This field is required';\n }\n return true;\n },\n });\n env[envVar.name] = customValue as string;\n } else {\n env[envVar.name] = value as string;\n }\n } else {\n // No choices - simple confirmation or new value\n const actionChoices = [\n { name: `Use ${useEnvChoice}`, value: 'use-env' },\n { name: 'Enter new value', value: 'enter-new' },\n ];\n\n // Add skip option for optional fields\n if (!envVar.isRequired) {\n actionChoices.push({ name: 'Skip (optional)', value: 'skip' });\n }\n\n const message = `[${serverName}] ${envVar.name}`;\n\n const action = await select({\n message,\n choices: actionChoices,\n });\n\n if (action === 'use-env') {\n env[envVar.name] = envValue;\n } else if (action === 'skip') {\n // Skip this optional env var - don't add to env object\n } else {\n const promptFn = envVar.isSecret ? password : input;\n const newValue = await promptFn({\n message: `[${serverName}] ${envVar.name} (enter value)`,\n validate: (input: string) => {\n if (envVar.isRequired && (!input || input.trim() === '')) {\n return 'This field is required';\n }\n return true;\n },\n });\n env[envVar.name] = newValue as string;\n }\n }\n } else if (options.yes) {\n // -y mode: skip required vars without defaults (trust shell environment)\n if (envVar.choices && envVar.choices.length > 0 && envVar.choices[0]) {\n // Has choices - use first choice\n env[envVar.name] = envVar.choices[0];\n } else if (envVar.isRequired) {\n // Required but no default - skip with warning\n console.log(` ⚠️ Skipping ${envVar.name}`);\n }\n // Optional vars without defaults: skip silently\n } else if (envVar.choices && envVar.choices.length > 0 && envVar.choices[0]) {\n if (process.stdin.isTTY) {\n // Interactive mode with choices - prompt user to select\n const choices = [...envVar.choices];\n\n // Add skip option for optional fields\n if (!envVar.isRequired) {\n choices.push('Skip (optional)');\n }\n\n const value = await select({\n message: `[${serverName}] ${envVar.name}`,\n choices,\n });\n\n if (value !== 'Skip (optional)') {\n env[envVar.name] = value as string;\n }\n // If 'Skip (optional)' selected, don't add to env object\n } else {\n // Non-interactive: use first choice\n env[envVar.name] = envVar.choices[0];\n }\n } else if (envVar.isRequired) {\n if (process.stdin.isTTY) {\n // Interactive mode - required field - prompt for value\n const promptFn = envVar.isSecret ? password : input;\n const placeholder = getDynamicPlaceholder(envVar, options.templateVars);\n const value = await promptFn({\n message: `[${serverName}] ${envVar.name} (required)`,\n ...(placeholder ? { default: placeholder } : {}),\n validate: (input: string) => {\n if (!input || input.trim() === '') {\n return 'This field is required';\n }\n return true;\n },\n });\n env[envVar.name] = value as string;\n }\n // Non-interactive without -y: skip (will fail at runtime if truly required)\n } else if (!envVar.isRequired && !options.yes && process.stdin.isTTY) {\n // Interactive mode - optional env var without defaults\n // Ask user if they want to set it\n const shouldSet = await confirm({\n message: `[${serverName}] Set optional ${envVar.name}? (${envVar.description || 'optional'})`,\n default: false,\n });\n\n if (shouldSet) {\n const promptFn = envVar.isSecret ? password : input;\n const placeholder = getDynamicPlaceholder(envVar, options.templateVars);\n const value = await promptFn({\n message: `[${serverName}] ${envVar.name}`,\n ...(placeholder ? { default: placeholder } : {}),\n });\n\n if (value && (value as string).trim() !== '') {\n env[envVar.name] = value as string;\n }\n }\n }\n // Other optional env vars are skipped\n }\n\n return env;\n}\n"],"names":["confirm","input","password","select","redactValue","value","isSecret","length","substring","substituteTemplateVars","template","variables","replace","match","varName","key","Object","keys","find","k","toLowerCase","getDynamicPlaceholder","envVar","placeholder","promptForEnvVars","serverName","envVars","options","env","envValue","process","name","defaultValue","default","yes","stdin","isTTY","redactedValue","useEnvChoice","choices","isRequired","push","message","promptFn","customValue","validate","trim","actionChoices","action","newValue","console","log","templateVars","shouldSet","description"],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ import type { MCPConfiguration } from '../../types.js';
2
+ import { promptForEnvVars } from './env-prompting.js';
3
+ import { MetadataReader, type ServerMetadata } from './metadata-reader.js';
4
+ export type ConfigurationMode = 'env' | 'args' | 'both' | 'none';
5
+ export interface Dimension {
6
+ name: string;
7
+ type: 'env' | 'arg';
8
+ choices: string[];
9
+ }
10
+ export interface Combination {
11
+ name: string;
12
+ envKeys: string[];
13
+ argNames: string[];
14
+ defaults: Record<string, string>;
15
+ argDefaults: Record<string, string>;
16
+ dimensionValues: Record<string, string>;
17
+ }
18
+ export interface ConfigChoice {
19
+ combination: Combination;
20
+ transport: 'stdio' | 'streamable-http';
21
+ label: string;
22
+ }
23
+ /** Maps user-facing transport names to internal types */
24
+ export declare const TRANSPORT_MAP: Record<string, 'stdio' | 'streamable-http'>;
25
+ /**
26
+ * Build config choices from combinations and transports.
27
+ * Used for both "select all" and "select specific" flows.
28
+ * @param combinations - Array of config combinations
29
+ * @param transports - Array of transport names ('stdio', 'http', or 'streamable-http')
30
+ * @returns Array of ConfigChoice objects
31
+ */
32
+ export declare function createConfigChoices(combinations: Combination[], transports: string[]): ConfigChoice[];
33
+ /**
34
+ * Filter config choices by selected labels.
35
+ * @param allChoices - All available config choices
36
+ * @param selectedLabels - Labels of configs to include
37
+ * @returns Filtered array of ConfigChoice objects
38
+ */
39
+ export declare function filterConfigChoices(allChoices: ConfigChoice[], selectedLabels: string[]): ConfigChoice[];
40
+ /**
41
+ * Generate combinations from env vars with choices (simple cartesian product).
42
+ * All combinations are generated - user can filter via selection pass.
43
+ */
44
+ export declare function generateMatrixCombinations(envVars: Array<{
45
+ name: string;
46
+ choices: string[];
47
+ }>): Combination[];
48
+ /**
49
+ * Generate combinations respecting dependsOn relationships.
50
+ * Conditional dimensions are only included when their dependencies are satisfied.
51
+ * Example: DCR_MODE only generates variations when AUTH_MODE=dcr
52
+ */
53
+ export declare function generateConditionalCombinations(envVars: Array<{
54
+ name: string;
55
+ choices: string[];
56
+ dependsOn?: Record<string, string[]>;
57
+ }>): Combination[];
58
+ /**
59
+ * Check if an environment variable should be prompted based on dependsOn conditions.
60
+ * Returns true if the envVar has no dependencies, or if all dependencies are satisfied.
61
+ *
62
+ * @param envVar - Environment variable metadata with optional dependsOn field
63
+ * @param selectedValues - Currently selected dimension values (e.g., { AUTH_MODE: 'loopback-oauth' })
64
+ * @returns true if the env var should be prompted, false if it should be skipped
65
+ */
66
+ export declare function shouldPromptEnvVar(envVar: {
67
+ dependsOn?: Record<string, string[]>;
68
+ }, selectedValues: Record<string, string>): boolean;
69
+ /**
70
+ * Generate server configuration interactively.
71
+ * Discovers server.json in current directory, prompts for configuration,
72
+ * and generates config files for selected combinations and transports.
73
+ *
74
+ * @param options - Command options
75
+ * @param options.source - Use source code paths (node instead of npx)
76
+ * @param options.json - Output to stdout instead of writing files
77
+ * @param options.matrix - Non-interactive mode: generate all matrix combinations
78
+ * @param options.output - Output directory (default: examples for --matrix, . otherwise)
79
+ * @param options.quick - Skip all optional env var prompts, use defaults
80
+ */
81
+ export declare function generateCommand(options?: {
82
+ source?: boolean;
83
+ json?: boolean;
84
+ matrix?: boolean;
85
+ output?: string;
86
+ quick?: boolean;
87
+ }): Promise<void>;
88
+ /** Exported for testing */
89
+ export declare function discoverServerJson(basePath?: string): string | null;
90
+ /** Exported for testing */
91
+ export declare function extractServerName(packageName: string): string;
92
+ /** Generate config object (for JSON output or testing) - Exported for testing */
93
+ export declare function generateConfigObject(params: {
94
+ serverName: string;
95
+ combination: Combination;
96
+ transport: string;
97
+ packageName: string;
98
+ packageDir?: string;
99
+ binPath?: string;
100
+ metadata: ServerMetadata;
101
+ metadataReader: Pick<MetadataReader, 'getPackageForTransport'>;
102
+ httpHost?: string;
103
+ httpPort?: number;
104
+ useSource?: boolean;
105
+ quick?: boolean;
106
+ optionalVarsToPrompt?: Set<string>;
107
+ }, envPromptFn?: typeof promptForEnvVars): Promise<MCPConfiguration>;
108
+ /** Generate config file - Exported for testing */
109
+ export declare function generateConfigFile(params: {
110
+ serverName: string;
111
+ combination: Combination;
112
+ transport: string;
113
+ outputDir: string;
114
+ packageName: string;
115
+ packageDir?: string;
116
+ binPath?: string;
117
+ metadata: ServerMetadata;
118
+ metadataReader: Pick<MetadataReader, 'getPackageForTransport'>;
119
+ httpHost?: string;
120
+ httpPort?: number;
121
+ useSource?: boolean;
122
+ quick?: boolean;
123
+ optionalVarsToPrompt?: Set<string>;
124
+ }, envPromptFn?: typeof promptForEnvVars): Promise<boolean>;