@1mcp/agent 0.34.3 → 0.35.0-beta.1

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 (244) hide show
  1. package/build/admin/assets/admin-console-CX5GzncA.css +1 -0
  2. package/build/admin/assets/admin-console-CkZ5lBKg.js +61 -0
  3. package/build/admin/index.html +13 -0
  4. package/build/commands/admin/admin.d.ts +90 -0
  5. package/build/commands/admin/admin.d.ts.map +1 -0
  6. package/build/commands/admin/admin.js +545 -0
  7. package/build/commands/admin/admin.js.map +1 -0
  8. package/build/commands/admin/index.d.ts +3 -0
  9. package/build/commands/admin/index.d.ts.map +1 -0
  10. package/build/commands/admin/index.js +99 -0
  11. package/build/commands/admin/index.js.map +1 -0
  12. package/build/commands/auth/index.d.ts.map +1 -1
  13. package/build/commands/auth/index.js +24 -5
  14. package/build/commands/auth/index.js.map +1 -1
  15. package/build/commands/auth/login.d.ts +1 -0
  16. package/build/commands/auth/login.d.ts.map +1 -1
  17. package/build/commands/auth/login.js +6 -10
  18. package/build/commands/auth/login.js.map +1 -1
  19. package/build/commands/auth/logout.d.ts +3 -0
  20. package/build/commands/auth/logout.d.ts.map +1 -1
  21. package/build/commands/auth/logout.js +19 -32
  22. package/build/commands/auth/logout.js.map +1 -1
  23. package/build/commands/auth/runtimeTargetContext.d.ts +25 -0
  24. package/build/commands/auth/runtimeTargetContext.d.ts.map +1 -0
  25. package/build/commands/auth/runtimeTargetContext.js +69 -0
  26. package/build/commands/auth/runtimeTargetContext.js.map +1 -0
  27. package/build/commands/auth/status.d.ts +1 -0
  28. package/build/commands/auth/status.d.ts.map +1 -1
  29. package/build/commands/auth/status.js +10 -33
  30. package/build/commands/auth/status.js.map +1 -1
  31. package/build/commands/inspect/index.d.ts.map +1 -1
  32. package/build/commands/inspect/index.js +4 -0
  33. package/build/commands/inspect/index.js.map +1 -1
  34. package/build/commands/inspect/inspect.d.ts +1 -0
  35. package/build/commands/inspect/inspect.d.ts.map +1 -1
  36. package/build/commands/inspect/inspect.js +2 -2
  37. package/build/commands/inspect/inspect.js.map +1 -1
  38. package/build/commands/instructions/index.d.ts.map +1 -1
  39. package/build/commands/instructions/index.js +4 -0
  40. package/build/commands/instructions/index.js.map +1 -1
  41. package/build/commands/instructions/instructions.d.ts +1 -0
  42. package/build/commands/instructions/instructions.d.ts.map +1 -1
  43. package/build/commands/instructions/instructions.js.map +1 -1
  44. package/build/commands/instructions/instructionsUtils.js +1 -1
  45. package/build/commands/instructions/instructionsUtils.js.map +1 -1
  46. package/build/commands/mcp/enable.d.ts +89 -2
  47. package/build/commands/mcp/enable.d.ts.map +1 -1
  48. package/build/commands/mcp/enable.js +555 -35
  49. package/build/commands/mcp/enable.js.map +1 -1
  50. package/build/commands/proxy/index.d.ts +1 -0
  51. package/build/commands/proxy/index.d.ts.map +1 -1
  52. package/build/commands/proxy/index.js +4 -0
  53. package/build/commands/proxy/index.js.map +1 -1
  54. package/build/commands/run/index.d.ts.map +1 -1
  55. package/build/commands/run/index.js +4 -0
  56. package/build/commands/run/index.js.map +1 -1
  57. package/build/commands/run/run.d.ts +1 -0
  58. package/build/commands/run/run.d.ts.map +1 -1
  59. package/build/commands/run/run.js +2 -2
  60. package/build/commands/run/run.js.map +1 -1
  61. package/build/commands/serve/serve.d.ts.map +1 -1
  62. package/build/commands/serve/serve.js +4 -0
  63. package/build/commands/serve/serve.js.map +1 -1
  64. package/build/commands/shared/apiClient.d.ts +5 -1
  65. package/build/commands/shared/apiClient.d.ts.map +1 -1
  66. package/build/commands/shared/apiClient.js +17 -9
  67. package/build/commands/shared/apiClient.js.map +1 -1
  68. package/build/commands/shared/clientSurfaceAttachment.d.ts +14 -0
  69. package/build/commands/shared/clientSurfaceAttachment.d.ts.map +1 -1
  70. package/build/commands/shared/clientSurfaceAttachment.js +51 -9
  71. package/build/commands/shared/clientSurfaceAttachment.js.map +1 -1
  72. package/build/commands/shared/commandRunner.d.ts +3 -1
  73. package/build/commands/shared/commandRunner.d.ts.map +1 -1
  74. package/build/commands/shared/commandRunner.js +59 -2
  75. package/build/commands/shared/commandRunner.js.map +1 -1
  76. package/build/commands/shared/serveTargetResolver.d.ts +14 -1
  77. package/build/commands/shared/serveTargetResolver.d.ts.map +1 -1
  78. package/build/commands/shared/serveTargetResolver.js +145 -3
  79. package/build/commands/shared/serveTargetResolver.js.map +1 -1
  80. package/build/commands/target/index.d.ts +3 -0
  81. package/build/commands/target/index.d.ts.map +1 -0
  82. package/build/commands/target/index.js +171 -0
  83. package/build/commands/target/index.js.map +1 -0
  84. package/build/commands/target/target.d.ts +78 -0
  85. package/build/commands/target/target.d.ts.map +1 -0
  86. package/build/commands/target/target.js +471 -0
  87. package/build/commands/target/target.js.map +1 -0
  88. package/build/constants/mcp.d.ts +1 -1
  89. package/build/constants/mcp.d.ts.map +1 -1
  90. package/build/constants/mcp.js +1 -1
  91. package/build/constants/mcp.js.map +1 -1
  92. package/build/core/capabilities/asyncLoadingOrchestrator.d.ts +6 -14
  93. package/build/core/capabilities/asyncLoadingOrchestrator.d.ts.map +1 -1
  94. package/build/core/capabilities/asyncLoadingOrchestrator.js +24 -17
  95. package/build/core/capabilities/asyncLoadingOrchestrator.js.map +1 -1
  96. package/build/core/capabilities/asyncLoadingOrchestratorEvent.d.ts +6 -0
  97. package/build/core/capabilities/asyncLoadingOrchestratorEvent.d.ts.map +1 -0
  98. package/build/core/capabilities/asyncLoadingOrchestratorEvent.js +7 -0
  99. package/build/core/capabilities/asyncLoadingOrchestratorEvent.js.map +1 -0
  100. package/build/core/capabilities/lazyLoadingOrchestrator.d.ts.map +1 -1
  101. package/build/core/capabilities/lazyLoadingOrchestrator.js +6 -5
  102. package/build/core/capabilities/lazyLoadingOrchestrator.js.map +1 -1
  103. package/build/core/client/clientManager.d.ts +2 -0
  104. package/build/core/client/clientManager.d.ts.map +1 -1
  105. package/build/core/client/clientManager.js +27 -24
  106. package/build/core/client/clientManager.js.map +1 -1
  107. package/build/core/client/connectedClient.d.ts +7 -0
  108. package/build/core/client/connectedClient.d.ts.map +1 -0
  109. package/build/core/client/connectedClient.js +2 -0
  110. package/build/core/client/connectedClient.js.map +1 -0
  111. package/build/core/client/connectionHandler.d.ts +2 -1
  112. package/build/core/client/connectionHandler.d.ts.map +1 -1
  113. package/build/core/client/connectionHandler.js +2 -5
  114. package/build/core/client/connectionHandler.js.map +1 -1
  115. package/build/core/client/transportRecreationState.d.ts +11 -0
  116. package/build/core/client/transportRecreationState.d.ts.map +1 -0
  117. package/build/core/client/transportRecreationState.js +2 -0
  118. package/build/core/client/transportRecreationState.js.map +1 -0
  119. package/build/core/client/transportRecreator.d.ts +2 -0
  120. package/build/core/client/transportRecreator.d.ts.map +1 -1
  121. package/build/core/client/transportRecreator.js +24 -4
  122. package/build/core/client/transportRecreator.js.map +1 -1
  123. package/build/core/loading/parallelExecutor.d.ts +5 -5
  124. package/build/core/loading/parallelExecutor.d.ts.map +1 -1
  125. package/build/core/loading/parallelExecutor.js +31 -33
  126. package/build/core/loading/parallelExecutor.js.map +1 -1
  127. package/build/core/runtime/runtimeIdentityService.d.ts +30 -0
  128. package/build/core/runtime/runtimeIdentityService.d.ts.map +1 -0
  129. package/build/core/runtime/runtimeIdentityService.js +63 -0
  130. package/build/core/runtime/runtimeIdentityService.js.map +1 -0
  131. package/build/core/server/agentConfig.d.ts +4 -0
  132. package/build/core/server/agentConfig.d.ts.map +1 -1
  133. package/build/core/server/agentConfig.js +3 -0
  134. package/build/core/server/agentConfig.js.map +1 -1
  135. package/build/core/tools/handlers/serverManagementHandler.d.ts +7 -7
  136. package/build/core/tools/internal/adapters/helpers/configTransformers.d.ts +2 -2
  137. package/build/core/tools/internal/schemas/discovery.d.ts +1 -1
  138. package/build/core/tools/internal/schemas/index.d.ts +13 -13
  139. package/build/core/tools/internal/schemas/installation.d.ts +7 -7
  140. package/build/core/tools/internal/schemas/management.d.ts +5 -5
  141. package/build/core/types/transport.d.ts +24 -3
  142. package/build/core/types/transport.d.ts.map +1 -1
  143. package/build/core/types/transport.js +7 -2
  144. package/build/core/types/transport.js.map +1 -1
  145. package/build/domains/admin/adminConfiguredServerService.d.ts +275 -0
  146. package/build/domains/admin/adminConfiguredServerService.d.ts.map +1 -0
  147. package/build/domains/admin/adminConfiguredServerService.js +1926 -0
  148. package/build/domains/admin/adminConfiguredServerService.js.map +1 -0
  149. package/build/domains/admin/adminConnectivityChecker.d.ts +7 -0
  150. package/build/domains/admin/adminConnectivityChecker.d.ts.map +1 -0
  151. package/build/domains/admin/adminConnectivityChecker.js +42 -0
  152. package/build/domains/admin/adminConnectivityChecker.js.map +1 -0
  153. package/build/domains/admin/adminDomain.d.ts +29 -0
  154. package/build/domains/admin/adminDomain.d.ts.map +1 -0
  155. package/build/domains/admin/adminDomain.js +39 -0
  156. package/build/domains/admin/adminDomain.js.map +1 -0
  157. package/build/domains/admin/adminIdentityService.d.ts +75 -0
  158. package/build/domains/admin/adminIdentityService.d.ts.map +1 -0
  159. package/build/domains/admin/adminIdentityService.js +321 -0
  160. package/build/domains/admin/adminIdentityService.js.map +1 -0
  161. package/build/domains/admin/adminOperationService.d.ts +202 -0
  162. package/build/domains/admin/adminOperationService.d.ts.map +1 -0
  163. package/build/domains/admin/adminOperationService.js +724 -0
  164. package/build/domains/admin/adminOperationService.js.map +1 -0
  165. package/build/domains/admin/adminPresetService.d.ts +140 -0
  166. package/build/domains/admin/adminPresetService.d.ts.map +1 -0
  167. package/build/domains/admin/adminPresetService.js +248 -0
  168. package/build/domains/admin/adminPresetService.js.map +1 -0
  169. package/build/domains/admin/runtimeScopeAdminLock.d.ts +22 -0
  170. package/build/domains/admin/runtimeScopeAdminLock.d.ts.map +1 -0
  171. package/build/domains/admin/runtimeScopeAdminLock.js +121 -0
  172. package/build/domains/admin/runtimeScopeAdminLock.js.map +1 -0
  173. package/build/domains/config-change/configChange.d.ts +6 -1
  174. package/build/domains/config-change/configChange.d.ts.map +1 -1
  175. package/build/domains/config-change/configChange.js +344 -0
  176. package/build/domains/config-change/configChange.js.map +1 -1
  177. package/build/domains/config-change/types.d.ts +18 -3
  178. package/build/domains/config-change/types.d.ts.map +1 -1
  179. package/build/domains/preset/manager/presetManager.d.ts +1 -0
  180. package/build/domains/preset/manager/presetManager.d.ts.map +1 -1
  181. package/build/domains/preset/manager/presetManager.js +3 -0
  182. package/build/domains/preset/manager/presetManager.js.map +1 -1
  183. package/build/domains/preset/tagAuthoring.d.ts +10 -0
  184. package/build/domains/preset/tagAuthoring.d.ts.map +1 -0
  185. package/build/domains/preset/tagAuthoring.js +94 -0
  186. package/build/domains/preset/tagAuthoring.js.map +1 -0
  187. package/build/domains/runtime-targets/runtimeIdentityVerification.d.ts +51 -0
  188. package/build/domains/runtime-targets/runtimeIdentityVerification.d.ts.map +1 -0
  189. package/build/domains/runtime-targets/runtimeIdentityVerification.js +258 -0
  190. package/build/domains/runtime-targets/runtimeIdentityVerification.js.map +1 -0
  191. package/build/domains/runtime-targets/runtimeTargetStore.d.ts +222 -0
  192. package/build/domains/runtime-targets/runtimeTargetStore.d.ts.map +1 -0
  193. package/build/domains/runtime-targets/runtimeTargetStore.js +1456 -0
  194. package/build/domains/runtime-targets/runtimeTargetStore.js.map +1 -0
  195. package/build/index.d.ts.map +1 -1
  196. package/build/index.js +7 -1
  197. package/build/index.js.map +1 -1
  198. package/build/transport/http/routes/adminRoutes.d.ts +34 -0
  199. package/build/transport/http/routes/adminRoutes.d.ts.map +1 -0
  200. package/build/transport/http/routes/adminRoutes.js +1217 -0
  201. package/build/transport/http/routes/adminRoutes.js.map +1 -0
  202. package/build/transport/http/routes/oauthRoutes.d.ts +2 -0
  203. package/build/transport/http/routes/oauthRoutes.d.ts.map +1 -1
  204. package/build/transport/http/routes/oauthRoutes.js +5 -185
  205. package/build/transport/http/routes/oauthRoutes.js.map +1 -1
  206. package/build/transport/http/routes/runtimeIdentityRoutes.d.ts +7 -0
  207. package/build/transport/http/routes/runtimeIdentityRoutes.d.ts.map +1 -0
  208. package/build/transport/http/routes/runtimeIdentityRoutes.js +9 -0
  209. package/build/transport/http/routes/runtimeIdentityRoutes.js.map +1 -0
  210. package/build/transport/http/routes/toolRoutes.d.ts.map +1 -1
  211. package/build/transport/http/routes/toolRoutes.js +1 -7
  212. package/build/transport/http/routes/toolRoutes.js.map +1 -1
  213. package/build/transport/http/server.d.ts +3 -0
  214. package/build/transport/http/server.d.ts.map +1 -1
  215. package/build/transport/http/server.js +92 -3
  216. package/build/transport/http/server.js.map +1 -1
  217. package/build/transport/managedStdioStderr.d.ts +40 -0
  218. package/build/transport/managedStdioStderr.d.ts.map +1 -0
  219. package/build/transport/managedStdioStderr.js +198 -0
  220. package/build/transport/managedStdioStderr.js.map +1 -0
  221. package/build/transport/managedStdioStderrEvent.d.ts +6 -0
  222. package/build/transport/managedStdioStderrEvent.d.ts.map +1 -0
  223. package/build/transport/managedStdioStderrEvent.js +7 -0
  224. package/build/transport/managedStdioStderrEvent.js.map +1 -0
  225. package/build/transport/managedStdioStderrMetadata.d.ts +9 -0
  226. package/build/transport/managedStdioStderrMetadata.d.ts.map +1 -0
  227. package/build/transport/managedStdioStderrMetadata.js +2 -0
  228. package/build/transport/managedStdioStderrMetadata.js.map +1 -0
  229. package/build/transport/managedStdioStderrOptions.d.ts +10 -0
  230. package/build/transport/managedStdioStderrOptions.d.ts.map +1 -0
  231. package/build/transport/managedStdioStderrOptions.js +2 -0
  232. package/build/transport/managedStdioStderrOptions.js.map +1 -0
  233. package/build/transport/restartableStdioTransport.d.ts +3 -1
  234. package/build/transport/restartableStdioTransport.d.ts.map +1 -1
  235. package/build/transport/restartableStdioTransport.js +5 -1
  236. package/build/transport/restartableStdioTransport.js.map +1 -1
  237. package/build/transport/transportFactory.d.ts.map +1 -1
  238. package/build/transport/transportFactory.js +21 -3
  239. package/build/transport/transportFactory.js.map +1 -1
  240. package/build/utils/validation/urlDetection.d.ts +13 -2
  241. package/build/utils/validation/urlDetection.d.ts.map +1 -1
  242. package/build/utils/validation/urlDetection.js +37 -6
  243. package/build/utils/validation/urlDetection.js.map +1 -1
  244. package/package.json +22 -9
@@ -1,58 +1,254 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { ApiClient } from '../../commands/shared/apiClient.js';
3
+ import { resolveServeTarget, } from '../../commands/shared/serveTargetResolver.js';
4
+ import { RuntimeTargetStore, RuntimeTargetStoreError } from '../../domains/runtime-targets/runtimeTargetStore.js';
1
5
  import printer from '../../utils/ui/printer.js';
6
+ import { stripMcpSuffix } from '../../utils/urlUtils.js';
7
+ import { LocalRuntimeUnavailableError } from '../../utils/validation/urlDetection.js';
8
+ import prompts from 'prompts';
2
9
  import { backupConfig, getServer, initializeConfigContext, serverExists, setServer, validateConfigPath, } from './utils/mcpServerConfig.js';
3
10
  import { validateServerName } from './utils/validation.js';
11
+ const DEFAULT_REMOTE_MUTATION_WAIT_MS = 5_000;
12
+ class McpRuntimeCommandError extends Error {
13
+ code;
14
+ recoveryCommand;
15
+ details;
16
+ retryable;
17
+ retryAfterMs;
18
+ constructor(code, message, recoveryCommand, details, retryable = false, retryAfterMs) {
19
+ super(message);
20
+ this.code = code;
21
+ this.recoveryCommand = recoveryCommand;
22
+ this.details = details;
23
+ this.retryable = retryable;
24
+ this.retryAfterMs = retryAfterMs;
25
+ this.name = 'McpRuntimeCommandError';
26
+ }
27
+ }
4
28
  /**
5
29
  * Build the enable command configuration
6
30
  */
7
31
  export function buildEnableCommand(yargs) {
8
- return yargs
9
- .positional('name', {
10
- describe: 'Name of the MCP server to enable',
11
- type: 'string',
12
- demandOption: true,
13
- })
14
- .example([['$0 mcp enable myserver', 'Enable a disabled server']]);
32
+ return buildEnableDisableCommand(yargs, 'enable');
15
33
  }
16
34
  /**
17
35
  * Build the disable command configuration
18
36
  */
19
37
  export function buildDisableCommand(yargs) {
38
+ return buildEnableDisableCommand(yargs, 'disable');
39
+ }
40
+ /**
41
+ * Enable a disabled MCP server
42
+ */
43
+ export async function enableCommand(argv, dependencies = {}) {
44
+ await runEnableDisableCommand(argv, true, dependencies);
45
+ }
46
+ /**
47
+ * Disable an MCP server without removing it
48
+ */
49
+ export async function disableCommand(argv, dependencies = {}) {
50
+ await runEnableDisableCommand(argv, false, dependencies);
51
+ }
52
+ function buildEnableDisableCommand(yargs, operation) {
53
+ const enabled = operation === 'enable';
20
54
  return yargs
21
55
  .positional('name', {
22
- describe: 'Name of the MCP server to disable',
56
+ describe: `Name of the MCP server to ${operation}`,
23
57
  type: 'string',
24
58
  demandOption: true,
25
59
  })
26
- .example([['$0 mcp disable myserver', 'Disable a server temporarily']]);
60
+ .option('context', {
61
+ describe: 'Runtime Target Context name for runtime-backed admin mutation',
62
+ type: 'string',
63
+ })
64
+ .option('url', {
65
+ describe: 'Ephemeral Runtime URL selector; credentialed admin mutation requires --context',
66
+ type: 'string',
67
+ })
68
+ .option('idempotency-key', {
69
+ describe: 'Stable idempotency key for retrying runtime-backed admin mutation',
70
+ type: 'string',
71
+ })
72
+ .option('wait-ms', {
73
+ describe: 'Maximum time to wait for runtime-backed mutation completion',
74
+ type: 'number',
75
+ default: DEFAULT_REMOTE_MUTATION_WAIT_MS,
76
+ })
77
+ .option('dry-run', {
78
+ describe: 'Preview the enable/disable operation without writing config or reloading servers',
79
+ type: 'boolean',
80
+ default: false,
81
+ })
82
+ .option('confirm-non-loopback', {
83
+ describe: 'Confirm mutation against a non-loopback runtime target',
84
+ type: 'boolean',
85
+ default: false,
86
+ })
87
+ .option('yes', {
88
+ describe: 'Skip confirmation prompts for supported runtime-backed mutations',
89
+ type: 'boolean',
90
+ default: false,
91
+ })
92
+ .option('login-prompt', {
93
+ describe: 'Prompt for Admin credentials when a selected Runtime Target has no Admin Session',
94
+ type: 'boolean',
95
+ default: true,
96
+ })
97
+ .option('json', {
98
+ describe: 'Write machine-readable JSON output',
99
+ type: 'boolean',
100
+ default: false,
101
+ })
102
+ .example([[`$0 mcp ${operation} myserver`, enabled ? 'Enable a disabled server' : 'Disable a server temporarily']]);
27
103
  }
28
- /**
29
- * Enable a disabled MCP server
30
- */
31
- export async function enableCommand(argv) {
104
+ async function runEnableDisableCommand(argv, enabled, dependencies) {
32
105
  try {
33
- await setServerEnabledState(argv, true);
106
+ const store = dependencies.runtimeTargetStore ?? new RuntimeTargetStore();
107
+ const contextName = selectRuntimeBackedContext(argv, store);
108
+ if (contextName === 'local') {
109
+ const handledByRuntime = await trySetRuntimeBackedLocalServerEnabledState(argv, enabled, contextName, store, dependencies);
110
+ if (handledByRuntime) {
111
+ return;
112
+ }
113
+ }
114
+ else if (contextName) {
115
+ await setRuntimeBackedServerEnabledState(argv, enabled, contextName, store, dependencies);
116
+ return;
117
+ }
118
+ const result = await setLocalServerEnabledState(argv, enabled, { silent: argv.json === true });
119
+ if (argv.json) {
120
+ writeJsonSuccess(argv, {
121
+ operation: operationId(enabled),
122
+ target: { context: 'local' },
123
+ result,
124
+ });
125
+ }
34
126
  }
35
127
  catch (error) {
36
- printer.error(`Failed to enable server: ${error instanceof Error ? error.message : error}`);
37
- process.exit(1);
128
+ handleEnableDisableError(argv, enabled, error);
38
129
  }
39
130
  }
40
- /**
41
- * Disable an MCP server without removing it
42
- */
43
- export async function disableCommand(argv) {
131
+ function selectRuntimeBackedContext(argv, store) {
132
+ if (argv.url && argv.context) {
133
+ throw new RuntimeTargetStoreError('target_selector_conflict', 'Use either --url or --context, not both, when selecting a runtime target');
134
+ }
135
+ if (argv.url) {
136
+ throw new RuntimeTargetStoreError('target_url_credentialed_mutation_unsupported', 'Ephemeral URL targets cannot perform credentialed admin mutations; add a Runtime Target Context first', { url: argv.url });
137
+ }
138
+ if (argv.context) {
139
+ if (argv.context === 'local') {
140
+ return 'local';
141
+ }
142
+ const target = store.inspect(argv.context);
143
+ return target.name === 'local' ? 'local' : target.name;
144
+ }
145
+ const current = store.current();
146
+ return current.name === 'local' ? null : current.name;
147
+ }
148
+ async function trySetRuntimeBackedLocalServerEnabledState(argv, enabled, contextName, store, dependencies) {
149
+ let target;
150
+ try {
151
+ target = await resolveRuntimeBackedTarget(argv, contextName, dependencies);
152
+ }
153
+ catch (error) {
154
+ if (error instanceof LocalRuntimeUnavailableError) {
155
+ return false;
156
+ }
157
+ throw error;
158
+ }
159
+ if (target.runtimeTargetContext?.name !== 'local' ||
160
+ target.runtimeTargetContext.kind !== 'local' ||
161
+ !target.runtimeTargetContext.runtimeScopeId) {
162
+ return false;
163
+ }
164
+ await setRuntimeBackedServerEnabledState(argv, enabled, contextName, store, dependencies, target);
165
+ return true;
166
+ }
167
+ async function resolveRuntimeBackedTarget(argv, contextName, dependencies) {
168
+ const resolver = dependencies.resolveTarget ?? ((input) => resolveServeTarget(input));
169
+ return resolver({ ...argv, context: contextName, url: undefined });
170
+ }
171
+ async function setRuntimeBackedServerEnabledState(argv, enabled, contextName, store, dependencies, resolvedTarget) {
172
+ validateServerName(argv.name);
173
+ const target = resolvedTarget ?? (await resolveRuntimeBackedTarget(argv, contextName, dependencies));
174
+ const baseUrl = stripMcpSuffix(target.discoveredUrl);
175
+ const unauthenticatedClient = createClient(dependencies, baseUrl);
176
+ const capabilities = await fetchCapabilities(unauthenticatedClient, enabled ? 'mcp.enable' : 'mcp.disable');
177
+ const runtimeScopeId = requireRuntimeScopeId(capabilities);
178
+ let reference = toAdminSessionReference(store.getAdminSessionReference(contextName, runtimeScopeId));
179
+ if (!reference) {
180
+ reference = await createPromptedAdminSession(argv, contextName, runtimeScopeId, baseUrl, unauthenticatedClient, store, dependencies);
181
+ }
182
+ let authenticatedClient = createClient(dependencies, baseUrl, reference.sessionToken);
44
183
  try {
45
- await setServerEnabledState(argv, false);
184
+ await validateAdminSession(authenticatedClient, store, contextName, runtimeScopeId);
46
185
  }
47
186
  catch (error) {
48
- printer.error(`Failed to disable server: ${error instanceof Error ? error.message : error}`);
49
- process.exit(1);
187
+ if (!shouldRetryWithPromptedAdminSession(argv, dependencies, error)) {
188
+ throw error;
189
+ }
190
+ reference = await createPromptedAdminSession(argv, contextName, runtimeScopeId, baseUrl, unauthenticatedClient, store, dependencies);
191
+ authenticatedClient = createClient(dependencies, baseUrl, reference.sessionToken);
192
+ await validateAdminSession(authenticatedClient, store, contextName, runtimeScopeId);
193
+ }
194
+ const idempotencyKey = argv.idempotencyKey?.trim() || dependencies.createIdempotencyKey?.() || randomUUID();
195
+ const mutationClient = createClient(dependencies, baseUrl, reference.sessionToken, {
196
+ timeout: mutationRequestTimeoutMs(argv.waitMs),
197
+ });
198
+ const mutationEnvelope = await postMutationWithBoundedWait({
199
+ argv,
200
+ enabled,
201
+ contextName,
202
+ runtimeScopeId,
203
+ baseUrl,
204
+ client: mutationClient,
205
+ idempotencyKey,
206
+ wait: dependencies.wait ?? defaultWait,
207
+ });
208
+ if (!mutationEnvelope.ok) {
209
+ const confirmationRequired = mutationEnvelope.error?.code === 'mutation_confirmation_required';
210
+ throw envelopeError(mutationEnvelope, `Runtime-backed mcp ${enabled ? 'enable' : 'disable'} failed`, recoveryCommand(argv, enabled, contextName, idempotencyKey, {
211
+ includeNonLoopbackConfirmation: confirmationRequired,
212
+ }));
213
+ }
214
+ writeJsonSuccess(argv, {
215
+ operation: operationId(enabled),
216
+ target: { context: contextName, runtimeScopeId, url: baseUrl },
217
+ warnings: mutationEnvelope.warnings,
218
+ result: mutationEnvelope.result,
219
+ });
220
+ if (!argv.json) {
221
+ printer.success(`Successfully ${enabled ? 'enabled' : 'disabled'} server '${argv.name}' on '${contextName}'`);
50
222
  }
51
223
  }
52
- async function setServerEnabledState(argv, enabled) {
224
+ async function postMutationWithBoundedWait(input) {
225
+ const waitMs = boundedMutationWaitMs(input.argv.waitMs);
226
+ const deadline = Date.now() + waitMs;
227
+ const path = `/admin/cli/v1/operations/${input.enabled ? 'enable-server' : 'disable-server'}`;
228
+ while (true) {
229
+ const requestTimeoutMs = Math.max(1, deadline - Date.now());
230
+ const envelope = await postEnvelope(input.client, path, mutationRequestBody(input.argv, {
231
+ enabled: input.enabled,
232
+ contextName: input.contextName,
233
+ runtimeScopeId: input.runtimeScopeId,
234
+ baseUrl: input.baseUrl,
235
+ }), { 'Idempotency-Key': input.idempotencyKey }, requestTimeoutMs);
236
+ if (envelope.ok || envelope.error?.code !== 'operation_in_progress') {
237
+ return envelope;
238
+ }
239
+ const retryAfterMs = Math.max(1, envelope.error.retryAfterMs ?? 100);
240
+ if (Date.now() + retryAfterMs > deadline) {
241
+ return envelope;
242
+ }
243
+ await input.wait(retryAfterMs);
244
+ }
245
+ }
246
+ async function setLocalServerEnabledState(argv, enabled, options = {}) {
53
247
  const { name, config: configPath, 'config-dir': configDir } = argv;
54
248
  initializeConfigContext(configPath, configDir);
55
- printer.info(`${enabled ? 'Enabling' : 'Disabling'} MCP server: ${name}`);
249
+ if (!options.silent) {
250
+ printer.info(`${enabled ? 'Enabling' : 'Disabling'} MCP server: ${name}`);
251
+ }
56
252
  validateServerName(name);
57
253
  validateConfigPath();
58
254
  if (!serverExists(name)) {
@@ -63,8 +259,25 @@ async function setServerEnabledState(argv, enabled) {
63
259
  throw new Error(`Failed to retrieve server '${name}' configuration.`);
64
260
  }
65
261
  if (Boolean(currentConfig.disabled) === !enabled) {
66
- printer.info(`Server '${name}' is already ${enabled ? 'enabled' : 'disabled'}.`);
67
- return;
262
+ if (!options.silent) {
263
+ printer.info(`Server '${name}' is already ${enabled ? 'enabled' : 'disabled'}.`);
264
+ }
265
+ return {
266
+ targetName: name,
267
+ enabled,
268
+ outcome: enabled ? 'already_enabled' : 'already_disabled',
269
+ };
270
+ }
271
+ if (isDryRun(argv)) {
272
+ if (!options.silent) {
273
+ printer.info(`Dry run: would ${enabled ? 'enable' : 'disable'} server '${name}'.`);
274
+ }
275
+ return {
276
+ mode: 'dry_run',
277
+ targetName: name,
278
+ enabled,
279
+ outcome: enabled ? 'enabled' : 'disabled',
280
+ };
68
281
  }
69
282
  const backupPath = backupConfig();
70
283
  const updatedConfig = {
@@ -75,14 +288,321 @@ async function setServerEnabledState(argv, enabled) {
75
288
  delete updatedConfig.disabled;
76
289
  }
77
290
  setServer(name, updatedConfig);
78
- printer.success(`Successfully ${enabled ? 'enabled' : 'disabled'} server '${name}'`);
79
- printer.keyValue({ Status: enabled ? 'Disabled → Enabled' : 'Enabled → Disabled', 'Backup created': backupPath });
80
- printer.blank();
81
- printer.info(enabled
82
- ? 'Server enabled. If 1mcp is running, the server will be started automatically.'
83
- : 'Server disabled. If 1mcp is running, the server will be stopped automatically.');
84
- if (!enabled) {
85
- printer.info(`Use 'mcp enable ${name}' to re-enable it later.`);
291
+ if (!options.silent) {
292
+ printer.success(`Successfully ${enabled ? 'enabled' : 'disabled'} server '${name}'`);
293
+ printer.keyValue({ Status: enabled ? 'Disabled → Enabled' : 'Enabled → Disabled', 'Backup created': backupPath });
294
+ printer.blank();
295
+ printer.info(enabled
296
+ ? 'Server enabled. If 1mcp is running, the server will be started automatically.'
297
+ : 'Server disabled. If 1mcp is running, the server will be stopped automatically.');
298
+ if (!enabled) {
299
+ printer.info(`Use 'mcp enable ${name}' to re-enable it later.`);
300
+ }
301
+ }
302
+ return {
303
+ targetName: name,
304
+ enabled,
305
+ outcome: enabled ? 'enabled' : 'disabled',
306
+ backupPath,
307
+ };
308
+ }
309
+ async function fetchCapabilities(client, requiredOperation) {
310
+ const envelope = await getEnvelope(client, '/admin/cli/v1/capabilities');
311
+ if (!envelope.ok) {
312
+ throw envelopeError(envelope, 'CLI Admin capabilities check failed');
86
313
  }
314
+ if (envelope.cliProtocolVersion !== '1') {
315
+ throw new McpRuntimeCommandError('protocol_incompatible', 'CLI Admin protocol is not compatible');
316
+ }
317
+ if (!envelope.result) {
318
+ throw new McpRuntimeCommandError('protocol_invalid_response', 'CLI Admin capabilities omitted result');
319
+ }
320
+ if (!envelope.result.supportedOperations?.includes(requiredOperation)) {
321
+ throw new McpRuntimeCommandError('capability_operation_unsupported', `CLI Admin operation "${requiredOperation}" is not supported by this runtime`);
322
+ }
323
+ requireMutationReadiness(envelope.result, requiredOperation);
324
+ return envelope.result;
325
+ }
326
+ async function validateAdminSession(client, store, contextName, runtimeScopeId) {
327
+ const envelope = await getEnvelope(client, '/admin/cli/v1/session/status');
328
+ if (envelope.ok && envelope.result?.authenticated) {
329
+ return;
330
+ }
331
+ if (shouldClearAdminSessionReference(envelope.error?.code)) {
332
+ store.clearAdminSessionReference(contextName, runtimeScopeId);
333
+ }
334
+ throw new McpRuntimeCommandError(envelope.error?.code ?? 'auth_admin_session_required', envelope.error?.message ?? `Admin Session is required for Runtime Target Context "${contextName}"`, `1mcp admin login --context ${contextName}`, envelope.error?.details, envelope.error?.retryable ?? false, envelope.error?.retryAfterMs);
335
+ }
336
+ async function createPromptedAdminSession(argv, contextName, runtimeScopeId, baseUrl, client, store, dependencies) {
337
+ if (!canPromptForAdminCredentials(argv, dependencies)) {
338
+ throw new McpRuntimeCommandError('auth_admin_session_required', `Admin Session is required for Runtime Target Context "${contextName}"`, `1mcp admin login --context ${contextName}`);
339
+ }
340
+ const credentials = await promptForAdminCredentials(contextName, dependencies);
341
+ if (credentials.cancelled || !credentials.username || !credentials.password) {
342
+ throw new McpRuntimeCommandError('auth_admin_session_required', `Admin Session is required for Runtime Target Context "${contextName}"`, `1mcp admin login --context ${contextName}`);
343
+ }
344
+ const loginEnvelope = await postEnvelope(client, '/admin/cli/v1/session/login', {
345
+ username: credentials.username,
346
+ password: credentials.password,
347
+ });
348
+ if (!loginEnvelope.ok) {
349
+ throw envelopeError(loginEnvelope, 'admin login failed', `1mcp admin login --context ${contextName}`);
350
+ }
351
+ if (!loginEnvelope.result?.sessionToken) {
352
+ throw new McpRuntimeCommandError('protocol_invalid_response', 'CLI Admin login response did not include a session');
353
+ }
354
+ const reference = {
355
+ sessionToken: loginEnvelope.result.sessionToken,
356
+ ...(loginEnvelope.result.csrfToken ? { csrfToken: loginEnvelope.result.csrfToken } : {}),
357
+ ...(loginEnvelope.result.expiresAt ? { expiresAt: loginEnvelope.result.expiresAt } : {}),
358
+ };
359
+ try {
360
+ store.setAdminSessionReference(contextName, runtimeScopeId, reference);
361
+ }
362
+ catch (error) {
363
+ await revokePromptedAdminSession(createClient(dependencies, baseUrl, reference.sessionToken));
364
+ throw error;
365
+ }
366
+ return reference;
367
+ }
368
+ async function revokePromptedAdminSession(client) {
369
+ try {
370
+ await postEnvelope(client, '/admin/cli/v1/session/logout', {});
371
+ }
372
+ catch {
373
+ // Preserve the local persistence failure as the operator-facing error.
374
+ }
375
+ }
376
+ async function promptForAdminCredentials(contextName, dependencies) {
377
+ if (dependencies.promptForAdminCredentials) {
378
+ return dependencies.promptForAdminCredentials(contextName);
379
+ }
380
+ const result = await prompts([
381
+ {
382
+ type: 'text',
383
+ name: 'username',
384
+ message: `Admin username for ${contextName}`,
385
+ },
386
+ {
387
+ type: 'password',
388
+ name: 'password',
389
+ message: `Admin password for ${contextName}`,
390
+ },
391
+ ]);
392
+ return {
393
+ username: typeof result.username === 'string' ? result.username : undefined,
394
+ password: typeof result.password === 'string' ? result.password : undefined,
395
+ cancelled: result.username === undefined || result.password === undefined,
396
+ };
397
+ }
398
+ function canPromptForAdminCredentials(argv, dependencies) {
399
+ if (argv.json || argv.loginPrompt === false || argv['login-prompt'] === false) {
400
+ return false;
401
+ }
402
+ return Boolean(dependencies.promptForAdminCredentials) || Boolean(process.stdin.isTTY);
403
+ }
404
+ function shouldRetryWithPromptedAdminSession(argv, dependencies, error) {
405
+ return (canPromptForAdminCredentials(argv, dependencies) &&
406
+ isCodedError(error) &&
407
+ (error.code.startsWith('auth_') || error.code.includes('session')));
408
+ }
409
+ function requireMutationReadiness(capabilities, requiredOperation) {
410
+ const requiredMcpOperation = requiredOperation === 'mcp.enable' ? 'enable' : 'disable';
411
+ if (capabilities.adminMutationsAvailable === false) {
412
+ throw new McpRuntimeCommandError('capability_mutation_unavailable', `MCP mutation operation "${requiredOperation}" is unavailable on this runtime`, undefined, {
413
+ status: capabilities.adminMutationsUnavailableReason,
414
+ });
415
+ }
416
+ if (capabilities.features?.mcpEnableDisable === false ||
417
+ capabilities.mutationReadiness?.mcp?.enabled === false ||
418
+ !capabilities.mutationReadiness?.mcp?.operations?.includes(requiredMcpOperation)) {
419
+ throw new McpRuntimeCommandError('capability_mutation_unavailable', `MCP mutation operation "${requiredOperation}" is unavailable on this runtime`, undefined, {
420
+ status: capabilities.mutationReadiness?.mcp?.status,
421
+ });
422
+ }
423
+ }
424
+ async function getEnvelope(client, path) {
425
+ const response = await client.get(path);
426
+ if (response.data) {
427
+ return response.data;
428
+ }
429
+ throw new McpRuntimeCommandError('runtime_unreachable', response.error ?? `Runtime returned HTTP ${response.status}`);
430
+ }
431
+ async function postEnvelope(client, path, body, headers = {}, timeout) {
432
+ const options = Object.keys(headers).length === 0 && timeout === undefined
433
+ ? undefined
434
+ : { headers, ...(timeout === undefined ? {} : { timeout }) };
435
+ const response = options === undefined
436
+ ? await client.post(path, body)
437
+ : await client.post(path, body, options);
438
+ if (response.data) {
439
+ return response.data;
440
+ }
441
+ if (isRequestTimeout(response)) {
442
+ return {
443
+ ok: false,
444
+ cliProtocolVersion: '1',
445
+ warnings: [],
446
+ error: {
447
+ code: 'operation_in_progress',
448
+ message: 'Admin operation did not finish before the CLI wait window',
449
+ retryable: true,
450
+ retryAfterMs: timeout,
451
+ },
452
+ };
453
+ }
454
+ throw new McpRuntimeCommandError('runtime_unreachable', response.error ?? `Runtime returned HTTP ${response.status}`);
455
+ }
456
+ function mutationRequestBody(argv, confirmationContext) {
457
+ const body = {
458
+ targetName: argv.name,
459
+ };
460
+ if (isDryRun(argv)) {
461
+ body.dryRun = true;
462
+ }
463
+ if (hasNonLoopbackConfirmation(argv)) {
464
+ body.confirmationFacts = {
465
+ confirm_non_loopback_runtime: true,
466
+ confirmationSource: 'cli_flag',
467
+ confirmedOperation: operationId(confirmationContext.enabled),
468
+ confirmedRuntimeScopeId: confirmationContext.runtimeScopeId,
469
+ confirmedTargetContext: confirmationContext.contextName,
470
+ confirmedTargetUrl: confirmationContext.baseUrl,
471
+ };
472
+ }
473
+ return body;
474
+ }
475
+ function isDryRun(argv) {
476
+ return argv.dryRun === true || argv['dry-run'] === true;
477
+ }
478
+ function hasNonLoopbackConfirmation(argv) {
479
+ return argv.confirmNonLoopback === true || argv['confirm-non-loopback'] === true || argv.yes === true;
480
+ }
481
+ function boundedMutationWaitMs(value) {
482
+ if (value === undefined || !Number.isFinite(value)) {
483
+ return DEFAULT_REMOTE_MUTATION_WAIT_MS;
484
+ }
485
+ return Math.max(0, value);
486
+ }
487
+ function mutationRequestTimeoutMs(value) {
488
+ return Math.max(1, boundedMutationWaitMs(value));
489
+ }
490
+ function isRequestTimeout(response) {
491
+ return response.status === 0 && /timed out/i.test(response.error ?? '');
492
+ }
493
+ function envelopeError(envelope, fallbackMessage, fallbackRecoveryCommand) {
494
+ return new McpRuntimeCommandError(envelope.error?.code ?? 'internal_error', envelope.error?.message ?? fallbackMessage, envelope.error?.recoveryCommand ?? fallbackRecoveryCommand, {
495
+ ...(envelope.error?.details && typeof envelope.error.details === 'object' ? envelope.error.details : {}),
496
+ ...(envelope.error?.retryAfterMs !== undefined ? { retryAfterMs: envelope.error.retryAfterMs } : {}),
497
+ }, envelope.error?.retryable ?? false, envelope.error?.retryAfterMs);
498
+ }
499
+ function shouldClearAdminSessionReference(code) {
500
+ return (code === undefined ||
501
+ code.startsWith('auth_session_') ||
502
+ code === 'auth_admin_disabled' ||
503
+ code === 'auth_account_deleted' ||
504
+ code === 'admin_account_not_found' ||
505
+ code === 'capability_admin_disabled');
506
+ }
507
+ function requireRuntimeScopeId(capabilities) {
508
+ const runtimeScopeId = capabilities.runtime?.runtimeScopeId;
509
+ if (!runtimeScopeId) {
510
+ throw new McpRuntimeCommandError('protocol_invalid_response', 'CLI Admin capabilities omitted runtime identity');
511
+ }
512
+ return runtimeScopeId;
513
+ }
514
+ function toAdminSessionReference(value) {
515
+ if (!value || typeof value !== 'object') {
516
+ return null;
517
+ }
518
+ const candidate = value;
519
+ return typeof candidate.sessionToken === 'string' && candidate.sessionToken.length > 0
520
+ ? { sessionToken: candidate.sessionToken }
521
+ : null;
522
+ }
523
+ function createClient(dependencies, baseUrl, bearerToken, options = {}) {
524
+ return (dependencies.createApiClient?.(baseUrl, bearerToken, options) ?? new ApiClient({ baseUrl, bearerToken, ...options }));
525
+ }
526
+ function writeJsonSuccess(argv, input) {
527
+ if (!argv.json) {
528
+ return;
529
+ }
530
+ process.stdout.write(`${JSON.stringify({
531
+ ok: true,
532
+ cliProtocolVersion: '1',
533
+ requestId: createCliRequestId(),
534
+ operation: input.operation,
535
+ target: input.target,
536
+ warnings: input.warnings ?? [],
537
+ result: input.result,
538
+ })}\n`);
539
+ }
540
+ function handleEnableDisableError(argv, enabled, error) {
541
+ const message = error instanceof Error ? error.message : String(error);
542
+ if (argv.json) {
543
+ const coded = isCodedError(error) ? error : undefined;
544
+ process.stdout.write(`${JSON.stringify({
545
+ ok: false,
546
+ cliProtocolVersion: '1',
547
+ requestId: createCliRequestId(),
548
+ operation: operationId(enabled),
549
+ target: errorTarget(argv),
550
+ error: {
551
+ code: coded?.code ?? 'command_failed',
552
+ message,
553
+ retryable: coded?.retryable ?? false,
554
+ ...(coded?.recoveryCommand ? { recoveryCommand: coded.recoveryCommand } : {}),
555
+ ...(coded?.retryAfterMs !== undefined ? { retryAfterMs: coded.retryAfterMs } : {}),
556
+ ...(coded?.details !== undefined ? { details: coded.details } : {}),
557
+ },
558
+ })}\n`);
559
+ process.exitCode = exitCodeForError(error);
560
+ return;
561
+ }
562
+ printer.error(`Failed to ${enabled ? 'enable' : 'disable'} server: ${message}`);
563
+ process.exit(1);
564
+ }
565
+ function errorTarget(argv) {
566
+ if (argv.context) {
567
+ return { context: argv.context };
568
+ }
569
+ if (argv.url) {
570
+ return { url: argv.url };
571
+ }
572
+ return { context: 'current' };
573
+ }
574
+ function isCodedError(error) {
575
+ return typeof error === 'object' && error !== null && 'code' in error && typeof error.code === 'string';
576
+ }
577
+ function exitCodeForError(error) {
578
+ if (!isCodedError(error)) {
579
+ return 1;
580
+ }
581
+ if (error.code.startsWith('auth_') || error.code.includes('session')) {
582
+ return 3;
583
+ }
584
+ if (error.code.startsWith('target_') ||
585
+ error.code.startsWith('identity_') ||
586
+ error.code.startsWith('protocol_') ||
587
+ error.code.startsWith('capability_')) {
588
+ return 4;
589
+ }
590
+ if (error.code.startsWith('credential_') || error.code.startsWith('validation_')) {
591
+ return 2;
592
+ }
593
+ return 1;
594
+ }
595
+ function recoveryCommand(argv, enabled, contextName, idempotencyKey, options = {}) {
596
+ const confirmation = options.includeNonLoopbackConfirmation && !hasNonLoopbackConfirmation(argv) ? ' --confirm-non-loopback' : '';
597
+ return `1mcp mcp ${enabled ? 'enable' : 'disable'} ${argv.name} --context ${contextName} --idempotency-key ${idempotencyKey}${confirmation}${argv.json ? ' --json' : ''}`;
598
+ }
599
+ function operationId(enabled) {
600
+ return enabled ? 'mcp.enable' : 'mcp.disable';
601
+ }
602
+ function createCliRequestId() {
603
+ return `cli_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
604
+ }
605
+ async function defaultWait(ms) {
606
+ await new Promise((resolve) => setTimeout(resolve, ms));
87
607
  }
88
608
  //# sourceMappingURL=enable.js.map