@1mcp/agent 0.35.0-beta.1 → 0.35.0-beta.3
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/README.md +6 -2
- package/build/admin/assets/{admin-console-CkZ5lBKg.js → admin-console-BOl7XR0p.js} +6 -6
- package/build/admin/assets/{admin-console-CX5GzncA.css → admin-console-Bbil6BQU.css} +1 -1
- package/build/admin/index.html +2 -2
- package/build/application/services/healthService.d.ts +32 -0
- package/build/application/services/healthService.d.ts.map +1 -1
- package/build/application/services/healthService.js +49 -0
- package/build/application/services/healthService.js.map +1 -1
- package/build/auth/oauthAuthorizationFlow.d.ts +2 -2
- package/build/auth/oauthAuthorizationFlow.d.ts.map +1 -1
- package/build/auth/oauthAuthorizationFlow.js +1 -1
- package/build/auth/oauthAuthorizationFlow.js.map +1 -1
- package/build/auth/sdkOAuthServerProvider.d.ts +4 -3
- package/build/auth/sdkOAuthServerProvider.d.ts.map +1 -1
- package/build/auth/sdkOAuthServerProvider.js +132 -17
- package/build/auth/sdkOAuthServerProvider.js.map +1 -1
- package/build/auth/sessionTypes.d.ts +40 -5
- package/build/auth/sessionTypes.d.ts.map +1 -1
- package/build/auth/sessionTypes.js +33 -1
- package/build/auth/sessionTypes.js.map +1 -1
- package/build/auth/storage/fileStorageService.d.ts +18 -1
- package/build/auth/storage/fileStorageService.d.ts.map +1 -1
- package/build/auth/storage/fileStorageService.js +253 -3
- package/build/auth/storage/fileStorageService.js.map +1 -1
- package/build/auth/storage/oauthStorageService.d.ts +4 -1
- package/build/auth/storage/oauthStorageService.d.ts.map +1 -1
- package/build/auth/storage/oauthStorageService.js +8 -1
- package/build/auth/storage/oauthStorageService.js.map +1 -1
- package/build/auth/storage/refreshTokenFamilyRepository.d.ts +36 -0
- package/build/auth/storage/refreshTokenFamilyRepository.d.ts.map +1 -0
- package/build/auth/storage/refreshTokenFamilyRepository.js +167 -0
- package/build/auth/storage/refreshTokenFamilyRepository.js.map +1 -0
- package/build/auth/storage/sessionRepository.d.ts +14 -1
- package/build/auth/storage/sessionRepository.d.ts.map +1 -1
- package/build/auth/storage/sessionRepository.js +32 -9
- package/build/auth/storage/sessionRepository.js.map +1 -1
- package/build/commands/inspect/inspect.d.ts.map +1 -1
- package/build/commands/inspect/inspect.js +2 -9
- package/build/commands/inspect/inspect.js.map +1 -1
- package/build/commands/inspect/inspectUtils.d.ts +4 -0
- package/build/commands/inspect/inspectUtils.d.ts.map +1 -1
- package/build/commands/inspect/inspectUtils.js +12 -0
- package/build/commands/inspect/inspectUtils.js.map +1 -1
- package/build/commands/instructions/instructionsUtils.d.ts +2 -0
- package/build/commands/instructions/instructionsUtils.d.ts.map +1 -1
- package/build/commands/instructions/instructionsUtils.js +7 -3
- package/build/commands/instructions/instructionsUtils.js.map +1 -1
- package/build/commands/mcp/index.d.ts.map +1 -1
- package/build/commands/mcp/index.js +10 -0
- package/build/commands/mcp/index.js.map +1 -1
- package/build/commands/mcp/restart.d.ts +69 -0
- package/build/commands/mcp/restart.d.ts.map +1 -0
- package/build/commands/mcp/restart.js +259 -0
- package/build/commands/mcp/restart.js.map +1 -0
- package/build/commands/mcp/status.d.ts +24 -1
- package/build/commands/mcp/status.d.ts.map +1 -1
- package/build/commands/mcp/status.js +158 -14
- package/build/commands/mcp/status.js.map +1 -1
- package/build/commands/run/run.d.ts.map +1 -1
- package/build/commands/run/run.js +86 -7
- package/build/commands/run/run.js.map +1 -1
- package/build/commands/serve/asyncLoadingOptions.d.ts +30 -0
- package/build/commands/serve/asyncLoadingOptions.d.ts.map +1 -0
- package/build/commands/serve/asyncLoadingOptions.js +34 -0
- package/build/commands/serve/asyncLoadingOptions.js.map +1 -0
- package/build/commands/serve/index.d.ts +12 -1
- package/build/commands/serve/index.d.ts.map +1 -1
- package/build/commands/serve/index.js +26 -15
- package/build/commands/serve/index.js.map +1 -1
- package/build/commands/serve/serve.d.ts +15 -1
- package/build/commands/serve/serve.d.ts.map +1 -1
- package/build/commands/serve/serve.js +128 -65
- package/build/commands/serve/serve.js.map +1 -1
- package/build/commands/serve/serveBackground.d.ts +48 -26
- package/build/commands/serve/serveBackground.d.ts.map +1 -1
- package/build/commands/serve/serveBackground.js +231 -61
- package/build/commands/serve/serveBackground.js.map +1 -1
- package/build/commands/serve/serveRestart.d.ts +1 -1
- package/build/commands/serve/serveRestart.js +1 -1
- package/build/commands/serve/serveStatus.d.ts +20 -10
- package/build/commands/serve/serveStatus.d.ts.map +1 -1
- package/build/commands/serve/serveStatus.js +174 -13
- package/build/commands/serve/serveStatus.js.map +1 -1
- package/build/commands/serve/serveStop.d.ts +13 -4
- package/build/commands/serve/serveStop.d.ts.map +1 -1
- package/build/commands/serve/serveStop.js +212 -23
- package/build/commands/serve/serveStop.js.map +1 -1
- package/build/commands/shared/apiClient.d.ts +1 -1
- package/build/commands/shared/apiClient.d.ts.map +1 -1
- package/build/commands/shared/apiClient.js +2 -2
- package/build/commands/shared/apiClient.js.map +1 -1
- package/build/commands/shared/clientSurfaceAttachment.d.ts +3 -1
- package/build/commands/shared/clientSurfaceAttachment.d.ts.map +1 -1
- package/build/commands/shared/clientSurfaceAttachment.js +14 -4
- package/build/commands/shared/clientSurfaceAttachment.js.map +1 -1
- package/build/commands/shared/commandRunner.d.ts +1 -0
- package/build/commands/shared/commandRunner.d.ts.map +1 -1
- package/build/commands/shared/commandRunner.js +10 -2
- package/build/commands/shared/commandRunner.js.map +1 -1
- package/build/commands/shared/filterSelectionQuery.d.ts +8 -0
- package/build/commands/shared/filterSelectionQuery.d.ts.map +1 -0
- package/build/commands/shared/filterSelectionQuery.js +12 -0
- package/build/commands/shared/filterSelectionQuery.js.map +1 -0
- package/build/commands/shared/inspectApiSchemas.d.ts +83 -0
- package/build/commands/shared/inspectApiSchemas.d.ts.map +1 -0
- package/build/commands/shared/inspectApiSchemas.js +40 -0
- package/build/commands/shared/inspectApiSchemas.js.map +1 -0
- package/build/commands/shared/serveTargetResolver.d.ts.map +1 -1
- package/build/commands/shared/serveTargetResolver.js +19 -8
- package/build/commands/shared/serveTargetResolver.js.map +1 -1
- package/build/commands/wait/index.d.ts +3 -0
- package/build/commands/wait/index.d.ts.map +1 -0
- package/build/commands/wait/index.js +20 -0
- package/build/commands/wait/index.js.map +1 -0
- package/build/commands/wait/wait.d.ts +39 -0
- package/build/commands/wait/wait.d.ts.map +1 -0
- package/build/commands/wait/wait.js +161 -0
- package/build/commands/wait/wait.js.map +1 -0
- package/build/config/configLoader.d.ts.map +1 -1
- package/build/config/configLoader.js +12 -0
- package/build/config/configLoader.js.map +1 -1
- package/build/config/configManager.d.ts +2 -0
- package/build/config/configManager.d.ts.map +1 -1
- package/build/config/configManager.js +19 -8
- package/build/config/configManager.js.map +1 -1
- package/build/config/mcpConfigMerge.d.ts.map +1 -1
- package/build/config/mcpConfigMerge.js +13 -2
- package/build/config/mcpConfigMerge.js.map +1 -1
- package/build/constants/auth.d.ts +10 -1
- package/build/constants/auth.d.ts.map +1 -1
- package/build/constants/auth.js +11 -1
- package/build/constants/auth.js.map +1 -1
- package/build/constants/mcp.d.ts +7 -1
- package/build/constants/mcp.d.ts.map +1 -1
- package/build/constants/mcp.js +9 -1
- package/build/constants/mcp.js.map +1 -1
- package/build/core/capabilities/capabilityAggregator.d.ts.map +1 -1
- package/build/core/capabilities/capabilityAggregator.js +10 -9
- package/build/core/capabilities/capabilityAggregator.js.map +1 -1
- package/build/core/capabilities/capabilityCatalog.d.ts +6 -5
- package/build/core/capabilities/capabilityCatalog.d.ts.map +1 -1
- package/build/core/capabilities/capabilityCatalog.js +36 -23
- package/build/core/capabilities/capabilityCatalog.js.map +1 -1
- package/build/core/capabilities/capabilityVisibility.d.ts +12 -0
- package/build/core/capabilities/capabilityVisibility.d.ts.map +1 -0
- package/build/core/capabilities/capabilityVisibility.js +13 -0
- package/build/core/capabilities/capabilityVisibility.js.map +1 -0
- package/build/core/capabilities/internalCapabilitiesProvider.d.ts +2 -1
- package/build/core/capabilities/internalCapabilitiesProvider.d.ts.map +1 -1
- package/build/core/capabilities/internalCapabilitiesProvider.js +2 -2
- package/build/core/capabilities/internalCapabilitiesProvider.js.map +1 -1
- package/build/core/capabilities/lazyLoadingOrchestrator.d.ts +5 -23
- package/build/core/capabilities/lazyLoadingOrchestrator.d.ts.map +1 -1
- package/build/core/capabilities/lazyLoadingOrchestrator.js +25 -44
- package/build/core/capabilities/lazyLoadingOrchestrator.js.map +1 -1
- package/build/core/capabilities/metaToolProvider.d.ts +6 -21
- package/build/core/capabilities/metaToolProvider.d.ts.map +1 -1
- package/build/core/capabilities/metaToolProvider.js +18 -70
- package/build/core/capabilities/metaToolProvider.js.map +1 -1
- package/build/core/capabilities/toolRegistry.d.ts +5 -1
- package/build/core/capabilities/toolRegistry.d.ts.map +1 -1
- package/build/core/capabilities/toolRegistry.js +11 -3
- package/build/core/capabilities/toolRegistry.js.map +1 -1
- package/build/core/client/clientManager.d.ts +33 -1
- package/build/core/client/clientManager.d.ts.map +1 -1
- package/build/core/client/clientManager.js +350 -2
- package/build/core/client/clientManager.js.map +1 -1
- package/build/core/client/connectionHandler.d.ts.map +1 -1
- package/build/core/client/connectionHandler.js +18 -1
- package/build/core/client/connectionHandler.js.map +1 -1
- package/build/core/client/recreateHttpTransportOptions.d.ts +14 -0
- package/build/core/client/recreateHttpTransportOptions.d.ts.map +1 -0
- package/build/core/client/recreateHttpTransportOptions.js +2 -0
- package/build/core/client/recreateHttpTransportOptions.js.map +1 -0
- package/build/core/client/transportRecreator.d.ts +8 -1
- package/build/core/client/transportRecreator.d.ts.map +1 -1
- package/build/core/client/transportRecreator.js +11 -2
- package/build/core/client/transportRecreator.js.map +1 -1
- package/build/core/configChangeHandler.d.ts +1 -0
- package/build/core/configChangeHandler.d.ts.map +1 -1
- package/build/core/configChangeHandler.js +14 -0
- package/build/core/configChangeHandler.js.map +1 -1
- package/build/core/instructions/templateTypes.d.ts +2 -2
- package/build/core/instructions/templateTypes.d.ts.map +1 -1
- package/build/core/loading/mcpLoadingManager.d.ts.map +1 -1
- package/build/core/loading/mcpLoadingManager.js +16 -4
- package/build/core/loading/mcpLoadingManager.js.map +1 -1
- package/build/core/protocol/requestHandlerUtils.d.ts +3 -0
- package/build/core/protocol/requestHandlerUtils.d.ts.map +1 -1
- package/build/core/protocol/requestHandlerUtils.js +23 -7
- package/build/core/protocol/requestHandlerUtils.js.map +1 -1
- package/build/core/protocol/toolRequestHandlers.d.ts.map +1 -1
- package/build/core/protocol/toolRequestHandlers.js +13 -13
- package/build/core/protocol/toolRequestHandlers.js.map +1 -1
- package/build/core/runtime/runtimeIdentityService.d.ts +1 -0
- package/build/core/runtime/runtimeIdentityService.d.ts.map +1 -1
- package/build/core/runtime/runtimeIdentityService.js +4 -1
- package/build/core/runtime/runtimeIdentityService.js.map +1 -1
- package/build/core/server/backendStdioSupervisor.d.ts +73 -0
- package/build/core/server/backendStdioSupervisor.d.ts.map +1 -0
- package/build/core/server/backendStdioSupervisor.js +191 -0
- package/build/core/server/backendStdioSupervisor.js.map +1 -0
- package/build/core/server/backgroundLaunchConfig.d.ts +15 -0
- package/build/core/server/backgroundLaunchConfig.d.ts.map +1 -0
- package/build/core/server/backgroundLaunchConfig.js +46 -0
- package/build/core/server/backgroundLaunchConfig.js.map +1 -0
- package/build/core/server/backgroundRuntimeSupervisor.d.ts +44 -0
- package/build/core/server/backgroundRuntimeSupervisor.d.ts.map +1 -0
- package/build/core/server/backgroundRuntimeSupervisor.js +252 -0
- package/build/core/server/backgroundRuntimeSupervisor.js.map +1 -0
- package/build/core/server/backgroundRuntimeSupervisorState.d.ts +30 -0
- package/build/core/server/backgroundRuntimeSupervisorState.d.ts.map +1 -0
- package/build/core/server/backgroundRuntimeSupervisorState.js +81 -0
- package/build/core/server/backgroundRuntimeSupervisorState.js.map +1 -0
- package/build/core/server/clientInstanceFactory.d.ts.map +1 -1
- package/build/core/server/clientInstanceFactory.js +13 -3
- package/build/core/server/clientInstanceFactory.js.map +1 -1
- package/build/core/server/clientInstancePool.d.ts +17 -5
- package/build/core/server/clientInstancePool.d.ts.map +1 -1
- package/build/core/server/clientInstancePool.js +198 -33
- package/build/core/server/clientInstancePool.js.map +1 -1
- package/build/core/server/clientInstancePoolTypes.d.ts +7 -1
- package/build/core/server/clientInstancePoolTypes.d.ts.map +1 -1
- package/build/core/server/clientInstancePoolTypes.js.map +1 -1
- package/build/core/server/connectionManager.d.ts +0 -6
- package/build/core/server/connectionManager.d.ts.map +1 -1
- package/build/core/server/connectionManager.js +0 -39
- package/build/core/server/connectionManager.js.map +1 -1
- package/build/core/server/connectionResolver.d.ts.map +1 -1
- package/build/core/server/connectionResolver.js +35 -1
- package/build/core/server/connectionResolver.js.map +1 -1
- package/build/core/server/runtimeScopeOwnership.d.ts +61 -0
- package/build/core/server/runtimeScopeOwnership.d.ts.map +1 -0
- package/build/core/server/runtimeScopeOwnership.js +544 -0
- package/build/core/server/runtimeScopeOwnership.js.map +1 -0
- package/build/core/server/serverManager.d.ts +2 -0
- package/build/core/server/serverManager.d.ts.map +1 -1
- package/build/core/server/serverManager.js +30 -0
- package/build/core/server/serverManager.js.map +1 -1
- package/build/core/server/templateIdentity.d.ts +10 -0
- package/build/core/server/templateIdentity.d.ts.map +1 -1
- package/build/core/server/templateIdentity.js +33 -0
- package/build/core/server/templateIdentity.js.map +1 -1
- package/build/core/server/templateServerCleanup.d.ts.map +1 -1
- package/build/core/server/templateServerCleanup.js +7 -1
- package/build/core/server/templateServerCleanup.js.map +1 -1
- package/build/core/server/templateServerManager.d.ts +13 -0
- package/build/core/server/templateServerManager.d.ts.map +1 -1
- package/build/core/server/templateServerManager.js +129 -4
- package/build/core/server/templateServerManager.js.map +1 -1
- package/build/core/tools/handlers/serverManagementHandler.d.ts +111 -5
- package/build/core/tools/handlers/serverManagementHandler.d.ts.map +1 -1
- package/build/core/tools/handlers/serverManagementHandler.js +103 -45
- package/build/core/tools/handlers/serverManagementHandler.js.map +1 -1
- package/build/core/tools/internal/adapters/management/managementAdapter.d.ts +2 -2
- package/build/core/tools/internal/adapters/management/managementAdapter.d.ts.map +1 -1
- package/build/core/tools/internal/adapters/management/managementAdapter.js +45 -26
- package/build/core/tools/internal/adapters/management/managementAdapter.js.map +1 -1
- package/build/core/tools/internal/adapters/management/types.d.ts +21 -2
- package/build/core/tools/internal/adapters/management/types.d.ts.map +1 -1
- package/build/core/tools/internal/managementHandlers.d.ts.map +1 -1
- package/build/core/tools/internal/managementHandlers.js +73 -22
- package/build/core/tools/internal/managementHandlers.js.map +1 -1
- package/build/core/tools/internal/schemas/discovery.d.ts +2 -2
- package/build/core/tools/internal/schemas/edit.js +1 -1
- package/build/core/tools/internal/schemas/edit.js.map +1 -1
- package/build/core/tools/internal/schemas/index.d.ts +77 -6
- package/build/core/tools/internal/schemas/index.d.ts.map +1 -1
- package/build/core/tools/internal/schemas/management.d.ts +75 -4
- package/build/core/tools/internal/schemas/management.d.ts.map +1 -1
- package/build/core/tools/internal/schemas/management.js +69 -2
- package/build/core/tools/internal/schemas/management.js.map +1 -1
- package/build/core/types/client.d.ts +9 -2
- package/build/core/types/client.d.ts.map +1 -1
- package/build/core/types/client.js +4 -0
- package/build/core/types/client.js.map +1 -1
- package/build/core/types/transport.d.ts +27 -1
- package/build/core/types/transport.d.ts.map +1 -1
- package/build/core/types/transport.js +39 -8
- package/build/core/types/transport.js.map +1 -1
- package/build/domains/admin/adminBackendRestartService.d.ts +41 -0
- package/build/domains/admin/adminBackendRestartService.d.ts.map +1 -0
- package/build/domains/admin/adminBackendRestartService.js +22 -0
- package/build/domains/admin/adminBackendRestartService.js.map +1 -0
- package/build/domains/admin/adminDomain.d.ts +7 -0
- package/build/domains/admin/adminDomain.d.ts.map +1 -1
- package/build/domains/admin/adminDomain.js +13 -0
- package/build/domains/admin/adminDomain.js.map +1 -1
- package/build/domains/admin/adminOAuthService.d.ts +26 -0
- package/build/domains/admin/adminOAuthService.d.ts.map +1 -0
- package/build/domains/admin/adminOAuthService.js +71 -0
- package/build/domains/admin/adminOAuthService.js.map +1 -0
- package/build/domains/admin/adminOperationService.d.ts +1 -0
- package/build/domains/admin/adminOperationService.d.ts.map +1 -1
- package/build/domains/admin/adminOperationService.js +39 -14
- package/build/domains/admin/adminOperationService.js.map +1 -1
- package/build/domains/admin/runtimeServerManagerBackendRestartService.d.ts +20 -0
- package/build/domains/admin/runtimeServerManagerBackendRestartService.d.ts.map +1 -0
- package/build/domains/admin/runtimeServerManagerBackendRestartService.js +78 -0
- package/build/domains/admin/runtimeServerManagerBackendRestartService.js.map +1 -0
- package/build/domains/backend-logs/backendLogBroker.d.ts +47 -0
- package/build/domains/backend-logs/backendLogBroker.d.ts.map +1 -0
- package/build/domains/backend-logs/backendLogBroker.js +249 -0
- package/build/domains/backend-logs/backendLogBroker.js.map +1 -0
- package/build/domains/backend-logs/backendLogProjection.d.ts +9 -0
- package/build/domains/backend-logs/backendLogProjection.d.ts.map +1 -0
- package/build/domains/backend-logs/backendLogProjection.js +40 -0
- package/build/domains/backend-logs/backendLogProjection.js.map +1 -0
- package/build/domains/backend-logs/backendLogRuntime.d.ts +4 -0
- package/build/domains/backend-logs/backendLogRuntime.d.ts.map +1 -0
- package/build/domains/backend-logs/backendLogRuntime.js +11 -0
- package/build/domains/backend-logs/backendLogRuntime.js.map +1 -0
- package/build/domains/backend-logs/backendLogSanitizer.d.ts +2 -0
- package/build/domains/backend-logs/backendLogSanitizer.d.ts.map +1 -0
- package/build/domains/backend-logs/backendLogSanitizer.js +30 -0
- package/build/domains/backend-logs/backendLogSanitizer.js.map +1 -0
- package/build/domains/backend-logs/backendLogSource.d.ts +8 -0
- package/build/domains/backend-logs/backendLogSource.d.ts.map +1 -0
- package/build/domains/backend-logs/backendLogSource.js +22 -0
- package/build/domains/backend-logs/backendLogSource.js.map +1 -0
- package/build/domains/backend-logs/backendLogTypes.d.ts +49 -0
- package/build/domains/backend-logs/backendLogTypes.d.ts.map +1 -0
- package/build/domains/backend-logs/backendLogTypes.js +2 -0
- package/build/domains/backend-logs/backendLogTypes.js.map +1 -0
- package/build/domains/runtime-targets/runtimeIdentityVerification.d.ts +8 -1
- package/build/domains/runtime-targets/runtimeIdentityVerification.d.ts.map +1 -1
- package/build/domains/runtime-targets/runtimeIdentityVerification.js +62 -3
- package/build/domains/runtime-targets/runtimeIdentityVerification.js.map +1 -1
- package/build/domains/runtime-targets/runtimeProbe.d.ts +34 -0
- package/build/domains/runtime-targets/runtimeProbe.d.ts.map +1 -0
- package/build/domains/runtime-targets/runtimeProbe.js +71 -0
- package/build/domains/runtime-targets/runtimeProbe.js.map +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -0
- package/build/index.js.map +1 -1
- package/build/server.d.ts.map +1 -1
- package/build/server.js +18 -2
- package/build/server.js.map +1 -1
- package/build/transport/http/routes/adminRoutes.d.ts +6 -0
- package/build/transport/http/routes/adminRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/adminRoutes.js +438 -38
- package/build/transport/http/routes/adminRoutes.js.map +1 -1
- package/build/transport/http/routes/healthRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/healthRoutes.js +70 -2
- package/build/transport/http/routes/healthRoutes.js.map +1 -1
- package/build/transport/http/routes/inspectHelpers.d.ts +11 -4
- package/build/transport/http/routes/inspectHelpers.d.ts.map +1 -1
- package/build/transport/http/routes/inspectHelpers.js +21 -2
- package/build/transport/http/routes/inspectHelpers.js.map +1 -1
- package/build/transport/http/routes/inspectRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/inspectRoutes.js +55 -4
- package/build/transport/http/routes/inspectRoutes.js.map +1 -1
- package/build/transport/http/routes/oauthRoutes.d.ts +3 -2
- package/build/transport/http/routes/oauthRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/oauthRoutes.js +10 -8
- package/build/transport/http/routes/oauthRoutes.js.map +1 -1
- package/build/transport/http/routes/toolRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/toolRoutes.js +37 -29
- package/build/transport/http/routes/toolRoutes.js.map +1 -1
- package/build/transport/http/server.d.ts.map +1 -1
- package/build/transport/http/server.js +16 -5
- package/build/transport/http/server.js.map +1 -1
- package/build/transport/managedStdioStderr.d.ts +17 -1
- package/build/transport/managedStdioStderr.d.ts.map +1 -1
- package/build/transport/managedStdioStderr.js +129 -5
- package/build/transport/managedStdioStderr.js.map +1 -1
- package/build/transport/managedStdioStderrOptions.d.ts +2 -0
- package/build/transport/managedStdioStderrOptions.d.ts.map +1 -1
- package/build/transport/restartableStdioTransport.js +1 -1
- package/build/transport/restartableStdioTransport.js.map +1 -1
- package/build/transport/transportFactory.d.ts +6 -2
- package/build/transport/transportFactory.d.ts.map +1 -1
- package/build/transport/transportFactory.js +69 -29
- package/build/transport/transportFactory.js.map +1 -1
- package/build/transport/transportFactory.testSetup.js +2 -0
- package/build/transport/transportFactory.testSetup.js.map +1 -1
- package/build/types/serverStatus.d.ts +3 -0
- package/build/types/serverStatus.d.ts.map +1 -0
- package/build/types/serverStatus.js +13 -0
- package/build/types/serverStatus.js.map +1 -0
- package/build/utils/core/errorTypes.d.ts +3 -0
- package/build/utils/core/errorTypes.d.ts.map +1 -1
- package/build/utils/core/errorTypes.js +7 -0
- package/build/utils/core/errorTypes.js.map +1 -1
- package/build/utils/validation/urlDetection.d.ts +12 -9
- package/build/utils/validation/urlDetection.d.ts.map +1 -1
- package/build/utils/validation/urlDetection.js +233 -31
- package/build/utils/validation/urlDetection.js.map +1 -1
- package/package.json +4 -3
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createHmac } from 'node:crypto';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { MCP_PROJECT_METADATA } from '../../../constants.js';
|
|
6
|
+
import { parseTemplateConnectionKey } from '../../../core/server/templateIdentity.js';
|
|
5
7
|
import { AdminConfiguredServerApplyError, AdminConfiguredServerNotFoundError, } from '../../../domains/admin/adminConfiguredServerService.js';
|
|
6
8
|
import { ADMIN_SESSION_COOKIE_NAME, AdminIdentityError, } from '../../../domains/admin/adminIdentityService.js';
|
|
7
9
|
import { AdminPresetConflictError, AdminPresetNotFoundError, } from '../../../domains/admin/adminPresetService.js';
|
|
10
|
+
import { sensitiveOperationLimiter } from '../../../transport/http/middlewares/securityMiddleware.js';
|
|
8
11
|
import { sanitizeErrorMessage } from '../../../utils/validation/sanitization.js';
|
|
9
12
|
import express, { Router } from 'express';
|
|
10
|
-
import
|
|
13
|
+
import rateLimit from 'express-rate-limit';
|
|
11
14
|
import { z } from 'zod';
|
|
12
15
|
const FAILED_LOGIN_LIMIT = 5;
|
|
13
16
|
const FAILED_LOGIN_WINDOW_MS = 15 * 60 * 1000;
|
|
14
17
|
const FAILED_LOGIN_MAX_ACTIVE_KEYS = 10_000;
|
|
18
|
+
const ADMIN_AUTH_RATE_LIMIT = 30;
|
|
19
|
+
const ADMIN_AUTH_RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000;
|
|
20
|
+
const ADMIN_STATUS_RATE_LIMIT = 120;
|
|
21
|
+
const ADMIN_STATUS_RATE_LIMIT_WINDOW_MS = 60 * 1000;
|
|
15
22
|
const ADMIN_USERNAME_MAX_LENGTH = 256;
|
|
16
23
|
const ADMIN_PASSWORD_MAX_LENGTH = 4096;
|
|
17
24
|
const CLI_ADMIN_PROTOCOL_VERSION = '1';
|
|
@@ -19,16 +26,33 @@ const CLI_ADMIN_RESPONSE_MAX_BYTES = 256 * 1024;
|
|
|
19
26
|
const CLI_ADMIN_RESPONSE_TOO_LARGE_MESSAGE = 'CLI Admin response exceeded the maximum supported size; use a narrower or paginated request.';
|
|
20
27
|
const CLI_SESSION_OPERATIONS = ['admin.login', 'admin.status', 'admin.logout'];
|
|
21
28
|
const ADMIN_API_PROTOCOL_VERSION = '1';
|
|
22
|
-
const
|
|
23
|
-
const
|
|
29
|
+
const TEMPLATE_INSTANCE_ID_DISPLAY_LENGTH = 12;
|
|
30
|
+
const CLI_CONFIGURED_SERVER_OPERATIONS = ['mcp.enable', 'mcp.disable'];
|
|
31
|
+
const CLI_BACKEND_RESTART_OPERATION = 'mcp.restart';
|
|
32
|
+
const SEA_ADMIN_CONSOLE_ASSETS_KEY = '__1MCP_SEA_ADMIN_CONSOLE_ASSETS__';
|
|
24
33
|
const adminLoginBodySchema = z.object({
|
|
25
34
|
username: z.string().trim().min(1).max(ADMIN_USERNAME_MAX_LENGTH),
|
|
26
35
|
password: z.string().min(1).max(ADMIN_PASSWORD_MAX_LENGTH),
|
|
27
36
|
});
|
|
37
|
+
const adminOAuthServiceParamsSchema = z.object({
|
|
38
|
+
serviceId: z.string().trim().min(1).max(256),
|
|
39
|
+
});
|
|
40
|
+
const backendLogSnapshotQuerySchema = z.object({
|
|
41
|
+
sourceId: z.string().trim().min(1).max(256).optional(),
|
|
42
|
+
});
|
|
28
43
|
const cliConfiguredServerMutationBodySchema = z.object({
|
|
29
44
|
targetName: z.string().trim().min(1).max(256),
|
|
30
45
|
dryRun: z.boolean().optional(),
|
|
31
46
|
});
|
|
47
|
+
const cliBackendRestartBodySchema = z
|
|
48
|
+
.object({
|
|
49
|
+
targetName: z.string().trim().min(1).max(256),
|
|
50
|
+
instance: z.string().trim().min(1).max(64).optional(),
|
|
51
|
+
allInstances: z.boolean().optional(),
|
|
52
|
+
})
|
|
53
|
+
.refine((value) => !(value.instance !== undefined && value.allInstances === true), {
|
|
54
|
+
message: 'instance and allInstances are mutually exclusive',
|
|
55
|
+
});
|
|
32
56
|
export function createAdminRoutes(options) {
|
|
33
57
|
if (!options.adminEnabled) {
|
|
34
58
|
options.adminService.revokeAllSessions();
|
|
@@ -36,6 +60,18 @@ export function createAdminRoutes(options) {
|
|
|
36
60
|
}
|
|
37
61
|
const router = Router();
|
|
38
62
|
const failedLoginLimiter = new FailedLoginLimiter();
|
|
63
|
+
const authenticationLimiter = rateLimit({
|
|
64
|
+
windowMs: ADMIN_AUTH_RATE_LIMIT_WINDOW_MS,
|
|
65
|
+
max: ADMIN_AUTH_RATE_LIMIT,
|
|
66
|
+
standardHeaders: true,
|
|
67
|
+
legacyHeaders: false,
|
|
68
|
+
});
|
|
69
|
+
const statusLimiter = rateLimit({
|
|
70
|
+
windowMs: ADMIN_STATUS_RATE_LIMIT_WINDOW_MS,
|
|
71
|
+
max: ADMIN_STATUS_RATE_LIMIT,
|
|
72
|
+
standardHeaders: true,
|
|
73
|
+
legacyHeaders: false,
|
|
74
|
+
});
|
|
39
75
|
const adminConsoleAssets = resolveAdminConsoleAssets(options.adminConsoleAssetsDir);
|
|
40
76
|
options.adminService.bootstrapFirstAdminFromEnvironment();
|
|
41
77
|
router.get('/cli/v1/capabilities', (req, res) => {
|
|
@@ -43,9 +79,18 @@ export function createAdminRoutes(options) {
|
|
|
43
79
|
const setupRequired = !options.adminService.hasAdminAccount();
|
|
44
80
|
const mutationAvailability = cliMutationAvailability(options, setupRequired);
|
|
45
81
|
const configuredServerOperationsSupported = Boolean(options.configuredServerService);
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
const
|
|
82
|
+
const backendRestartSupported = Boolean(options.backendRestartService);
|
|
83
|
+
const mcpMutationsReady = (configuredServerOperationsSupported || backendRestartSupported) && mutationAvailability.available;
|
|
84
|
+
const mcpOperations = [
|
|
85
|
+
...(configuredServerOperationsSupported ? [...CLI_CONFIGURED_SERVER_OPERATIONS] : []),
|
|
86
|
+
...(backendRestartSupported ? [CLI_BACKEND_RESTART_OPERATION] : []),
|
|
87
|
+
];
|
|
88
|
+
const mcpMutationOperations = mutationAvailability.available
|
|
89
|
+
? [
|
|
90
|
+
...(configuredServerOperationsSupported ? ['enable', 'disable'] : []),
|
|
91
|
+
...(backendRestartSupported ? ['restart'] : []),
|
|
92
|
+
]
|
|
93
|
+
: [];
|
|
49
94
|
const mcpReadinessStatus = cliMcpReadinessStatus(mutationAvailability);
|
|
50
95
|
sendCliSuccess(req, res, {
|
|
51
96
|
runtime: toCliRuntimeIdentity(identity),
|
|
@@ -67,11 +112,12 @@ export function createAdminRoutes(options) {
|
|
|
67
112
|
adminSessions: true,
|
|
68
113
|
bearerSessionAuth: true,
|
|
69
114
|
csrfTokens: true,
|
|
70
|
-
mcpEnableDisable:
|
|
115
|
+
mcpEnableDisable: configuredServerOperationsSupported && mutationAvailability.available,
|
|
116
|
+
mcpRestart: backendRestartSupported && mutationAvailability.available,
|
|
71
117
|
},
|
|
72
118
|
});
|
|
73
119
|
});
|
|
74
|
-
router.post('/cli/v1/session/login', async (req, res) => {
|
|
120
|
+
router.post('/cli/v1/session/login', authenticationLimiter, async (req, res) => {
|
|
75
121
|
const parsedBody = adminLoginBodySchema.safeParse(req.body);
|
|
76
122
|
if (!parsedBody.success) {
|
|
77
123
|
sendCliError(req, res, {
|
|
@@ -143,7 +189,10 @@ export function createAdminRoutes(options) {
|
|
|
143
189
|
router.post('/cli/v1/operations/disable-server', async (req, res) => {
|
|
144
190
|
await handleCliConfiguredServerMutation(req, res, options, 'disableConfiguredServer');
|
|
145
191
|
});
|
|
146
|
-
router.post('/
|
|
192
|
+
router.post('/cli/v1/operations/restart-server', async (req, res) => {
|
|
193
|
+
await handleCliBackendRestart(req, res, options);
|
|
194
|
+
});
|
|
195
|
+
router.post('/api/session/login', authenticationLimiter, async (req, res) => {
|
|
147
196
|
const parsedBody = adminLoginBodySchema.safeParse(req.body);
|
|
148
197
|
if (!parsedBody.success) {
|
|
149
198
|
res.status(400).json({ error: 'admin_login_request_invalid' });
|
|
@@ -205,7 +254,7 @@ export function createAdminRoutes(options) {
|
|
|
205
254
|
clearAdminSessionCookie(res, options.getRuntimeIdentity().externalUrl);
|
|
206
255
|
res.status(200).json({ ok: true });
|
|
207
256
|
});
|
|
208
|
-
router.get('/api/status', (req, res) => {
|
|
257
|
+
router.get('/api/status', statusLimiter, (req, res) => {
|
|
209
258
|
const session = options.adminService.validateSession(getAdminSessionCookie(req));
|
|
210
259
|
if (!session) {
|
|
211
260
|
res.status(401).json({ authenticated: false });
|
|
@@ -231,6 +280,55 @@ export function createAdminRoutes(options) {
|
|
|
231
280
|
}),
|
|
232
281
|
});
|
|
233
282
|
});
|
|
283
|
+
router.get('/api/logs/snapshot', statusLimiter, (req, res) => {
|
|
284
|
+
const broker = options.getBackendLogBroker?.();
|
|
285
|
+
if (!broker) {
|
|
286
|
+
res.status(404).json({ error: 'admin_backend_logs_unavailable' });
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
const parsedQuery = backendLogSnapshotQuerySchema.safeParse(req.query);
|
|
290
|
+
if (!parsedQuery.success) {
|
|
291
|
+
res.status(400).json({ error: 'admin_backend_logs_query_invalid' });
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
res.status(200).json(broker.snapshot(parsedQuery.data.sourceId));
|
|
295
|
+
});
|
|
296
|
+
router.get('/api/logs/stream', (req, res) => {
|
|
297
|
+
const broker = options.getBackendLogBroker?.();
|
|
298
|
+
if (!broker) {
|
|
299
|
+
res.status(404).json({ error: 'admin_backend_logs_unavailable' });
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
streamBackendLogs(req, res, broker, options.adminService);
|
|
303
|
+
});
|
|
304
|
+
router.post('/api/oauth/:serviceId/authorize', sensitiveOperationLimiter, async (req, res) => {
|
|
305
|
+
if (!options.oauthService) {
|
|
306
|
+
res.status(503).json({ error: 'backend_oauth_runtime_unavailable' });
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const serviceId = parseAdminOAuthServiceId(req, res);
|
|
310
|
+
if (!serviceId)
|
|
311
|
+
return;
|
|
312
|
+
const result = await options.oauthService.authorizeService({
|
|
313
|
+
context: buildAdminOperationContext(req, options, { type: 'backend_oauth_service', id: serviceId }),
|
|
314
|
+
serviceId,
|
|
315
|
+
});
|
|
316
|
+
sendAdminOAuthOperationResult(res, result);
|
|
317
|
+
});
|
|
318
|
+
router.post('/api/oauth/:serviceId/restart', sensitiveOperationLimiter, async (req, res) => {
|
|
319
|
+
if (!options.oauthService) {
|
|
320
|
+
res.status(503).json({ error: 'backend_oauth_runtime_unavailable' });
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const serviceId = parseAdminOAuthServiceId(req, res);
|
|
324
|
+
if (!serviceId)
|
|
325
|
+
return;
|
|
326
|
+
const result = await options.oauthService.restartService({
|
|
327
|
+
context: buildAdminOperationContext(req, options, { type: 'backend_oauth_service', id: serviceId }),
|
|
328
|
+
serviceId,
|
|
329
|
+
});
|
|
330
|
+
sendAdminOAuthOperationResult(res, result);
|
|
331
|
+
});
|
|
234
332
|
router.get('/api/presets', async (req, res) => {
|
|
235
333
|
if (!options.presetService)
|
|
236
334
|
return void res.status(404).json({ error: 'admin_presets_unavailable' });
|
|
@@ -340,10 +438,27 @@ export function createAdminRoutes(options) {
|
|
|
340
438
|
router.post('/api/configured-servers/:name/disable', async (req, res) => {
|
|
341
439
|
await handleConfiguredServerMutation(req, res, options, 'disableConfiguredServer');
|
|
342
440
|
});
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
441
|
+
if (adminConsoleAssets.kind === 'filesystem') {
|
|
442
|
+
router.use('/assets', express.static(path.join(adminConsoleAssets.rootDir, 'assets'), {
|
|
443
|
+
immutable: true,
|
|
444
|
+
maxAge: '1y',
|
|
445
|
+
}));
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
router.use('/assets', (req, res, next) => {
|
|
449
|
+
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
450
|
+
next();
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
const asset = adminConsoleAssets.assets.get(`assets/${req.path.replace(/^\//u, '')}`);
|
|
454
|
+
if (!asset) {
|
|
455
|
+
next();
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
res.set('Cache-Control', 'public, max-age=31536000, immutable');
|
|
459
|
+
res.status(200).type(path.extname(req.path)).send(asset);
|
|
460
|
+
});
|
|
461
|
+
}
|
|
347
462
|
router.use('/assets', (_req, res) => {
|
|
348
463
|
res.status(404).type('text/plain').send('Admin Console asset not found');
|
|
349
464
|
});
|
|
@@ -352,29 +467,136 @@ export function createAdminRoutes(options) {
|
|
|
352
467
|
next();
|
|
353
468
|
return;
|
|
354
469
|
}
|
|
355
|
-
sendAdminConsoleIndex(res, adminConsoleAssets
|
|
470
|
+
sendAdminConsoleIndex(res, adminConsoleAssets);
|
|
356
471
|
});
|
|
357
472
|
return router;
|
|
358
473
|
}
|
|
474
|
+
function streamBackendLogs(req, res, broker, adminService) {
|
|
475
|
+
const sessionToken = getAdminSessionCookie(req);
|
|
476
|
+
let closed = false;
|
|
477
|
+
let unsubscribe = () => undefined;
|
|
478
|
+
let sessionTimer = null;
|
|
479
|
+
const close = () => {
|
|
480
|
+
if (closed)
|
|
481
|
+
return;
|
|
482
|
+
closed = true;
|
|
483
|
+
if (sessionTimer)
|
|
484
|
+
clearInterval(sessionTimer);
|
|
485
|
+
unsubscribe();
|
|
486
|
+
if (!res.writableEnded)
|
|
487
|
+
res.end();
|
|
488
|
+
};
|
|
489
|
+
const writeFrame = (frame) => {
|
|
490
|
+
if (closed || res.writableEnded)
|
|
491
|
+
return false;
|
|
492
|
+
try {
|
|
493
|
+
res.write(frame);
|
|
494
|
+
return true;
|
|
495
|
+
}
|
|
496
|
+
catch {
|
|
497
|
+
close();
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
const write = (event, data, id) => {
|
|
502
|
+
const frame = `${id === undefined ? '' : `id: ${id}\n`}event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
503
|
+
return writeFrame(frame);
|
|
504
|
+
};
|
|
505
|
+
res.status(200);
|
|
506
|
+
res.set({
|
|
507
|
+
'Content-Type': 'text/event-stream; charset=utf-8',
|
|
508
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
509
|
+
Connection: 'keep-alive',
|
|
510
|
+
'X-Accel-Buffering': 'no',
|
|
511
|
+
});
|
|
512
|
+
res.flushHeaders?.();
|
|
513
|
+
const requestedSequence = parseBackendLogSequence(req.header('Last-Event-ID'));
|
|
514
|
+
if (requestedSequence === undefined) {
|
|
515
|
+
const snapshot = broker.snapshot();
|
|
516
|
+
if (!write('snapshot', snapshot, snapshot.sequence))
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
const snapshot = broker.snapshot();
|
|
521
|
+
if (!write('sources', snapshot.sources))
|
|
522
|
+
return;
|
|
523
|
+
const replay = broker.replayAfter(requestedSequence);
|
|
524
|
+
if (replay.kind === 'gap') {
|
|
525
|
+
if (!write('gap', replay.snapshot, replay.snapshot.sequence))
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
for (const entry of replay.entries) {
|
|
530
|
+
if (!write('entry', entry, entry.sequence))
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
unsubscribe = broker.subscribe({
|
|
536
|
+
onEvent: (entry) => void write('entry', entry, entry.sequence),
|
|
537
|
+
onSourceUpdate: (update) => void write('source', update),
|
|
538
|
+
onDisconnect: close,
|
|
539
|
+
});
|
|
540
|
+
sessionTimer = setInterval(() => {
|
|
541
|
+
if (!adminService.validateSession(sessionToken)) {
|
|
542
|
+
close();
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
void writeFrame(': keep-alive\n\n');
|
|
546
|
+
}, 10_000);
|
|
547
|
+
sessionTimer.unref?.();
|
|
548
|
+
req.on('close', close);
|
|
549
|
+
res.on('close', close);
|
|
550
|
+
}
|
|
551
|
+
function parseBackendLogSequence(value) {
|
|
552
|
+
if (!value || !/^\d+$/.test(value))
|
|
553
|
+
return undefined;
|
|
554
|
+
const sequence = Number(value);
|
|
555
|
+
return Number.isSafeInteger(sequence) ? sequence : undefined;
|
|
556
|
+
}
|
|
359
557
|
function resolveAdminConsoleAssets(configuredDir) {
|
|
558
|
+
if (!configuredDir) {
|
|
559
|
+
const embeddedAssets = readEmbeddedAdminConsoleAssets();
|
|
560
|
+
if (embeddedAssets) {
|
|
561
|
+
return { kind: 'embedded', assets: embeddedAssets };
|
|
562
|
+
}
|
|
563
|
+
}
|
|
360
564
|
const rootDir = configuredDir ?? resolveDefaultAdminConsoleAssetsDir();
|
|
361
565
|
return {
|
|
566
|
+
kind: 'filesystem',
|
|
362
567
|
rootDir,
|
|
363
568
|
indexPath: path.join(rootDir, 'index.html'),
|
|
364
569
|
};
|
|
365
570
|
}
|
|
571
|
+
function readEmbeddedAdminConsoleAssets() {
|
|
572
|
+
const rawAssets = globalThis[SEA_ADMIN_CONSOLE_ASSETS_KEY];
|
|
573
|
+
if (!rawAssets || typeof rawAssets !== 'object' || Array.isArray(rawAssets)) {
|
|
574
|
+
return undefined;
|
|
575
|
+
}
|
|
576
|
+
const assets = new Map();
|
|
577
|
+
for (const [assetPath, encodedAsset] of Object.entries(rawAssets)) {
|
|
578
|
+
if (typeof encodedAsset === 'string') {
|
|
579
|
+
assets.set(assetPath, Buffer.from(encodedAsset, 'base64'));
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return assets.has('index.html') ? assets : undefined;
|
|
583
|
+
}
|
|
366
584
|
export function resolveDefaultAdminConsoleAssetsDir() {
|
|
367
585
|
return fileURLToPath(new URL('../../../admin', import.meta.url));
|
|
368
586
|
}
|
|
369
587
|
function isAdminApiPath(pathname) {
|
|
370
588
|
return (pathname === '/api' || pathname.startsWith('/api/') || pathname === '/cli/v1' || pathname.startsWith('/cli/v1/'));
|
|
371
589
|
}
|
|
372
|
-
function sendAdminConsoleIndex(res,
|
|
373
|
-
if (
|
|
590
|
+
function sendAdminConsoleIndex(res, adminConsoleAssets) {
|
|
591
|
+
if (adminConsoleAssets.kind === 'embedded') {
|
|
592
|
+
res.status(200).type('html').send(adminConsoleAssets.assets.get('index.html'));
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
if (!fs.existsSync(adminConsoleAssets.indexPath)) {
|
|
374
596
|
res.status(503).type('text/plain').send('Admin Console assets are not available. Run the package build first.');
|
|
375
597
|
return;
|
|
376
598
|
}
|
|
377
|
-
res.status(200).sendFile(indexPath);
|
|
599
|
+
res.status(200).sendFile(adminConsoleAssets.indexPath, { dotfiles: 'allow' });
|
|
378
600
|
}
|
|
379
601
|
function unauthenticatedAdminApiResponse(options) {
|
|
380
602
|
return options.adminService.hasAdminAccount()
|
|
@@ -452,6 +674,109 @@ async function handleCliConfiguredServerMutation(req, res, options, operationNam
|
|
|
452
674
|
: await options.configuredServerService.disableConfiguredServer(input);
|
|
453
675
|
sendCliAdminOperationResult(req, res, result);
|
|
454
676
|
}
|
|
677
|
+
async function handleCliBackendRestart(req, res, options) {
|
|
678
|
+
if (!options.backendRestartService) {
|
|
679
|
+
sendCliError(req, res, {
|
|
680
|
+
status: 404,
|
|
681
|
+
code: 'backend_restart_unavailable',
|
|
682
|
+
message: 'Backend restart administration is unavailable',
|
|
683
|
+
retryable: false,
|
|
684
|
+
});
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
if (isMutationLocked(options)) {
|
|
688
|
+
sendCliError(req, res, {
|
|
689
|
+
status: 409,
|
|
690
|
+
code: 'runtime_scope_locked',
|
|
691
|
+
message: 'Runtime scope admin mutations are locked by another writer',
|
|
692
|
+
retryable: true,
|
|
693
|
+
details: { operationName: 'restartBackend', reason: 'writer_lock_unavailable' },
|
|
694
|
+
});
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
const sessionToken = getBearerSessionToken(req);
|
|
698
|
+
const session = sessionToken ? options.adminService.validateSession(sessionToken) : null;
|
|
699
|
+
if (!sessionToken || !session) {
|
|
700
|
+
sendCliError(req, res, {
|
|
701
|
+
status: 401,
|
|
702
|
+
code: 'admin_session_required',
|
|
703
|
+
message: 'A valid admin session bearer token is required',
|
|
704
|
+
retryable: false,
|
|
705
|
+
});
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
const parsedBody = cliBackendRestartBodySchema.safeParse(req.body);
|
|
709
|
+
if (!parsedBody.success) {
|
|
710
|
+
sendCliError(req, res, {
|
|
711
|
+
status: 400,
|
|
712
|
+
code: 'validation_request_invalid',
|
|
713
|
+
message: 'Backend targetName and restart selectors must have valid, mutually exclusive values',
|
|
714
|
+
retryable: false,
|
|
715
|
+
});
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
const { targetName, instance, allInstances = false } = parsedBody.data;
|
|
719
|
+
const selection = instance
|
|
720
|
+
? { mode: 'instance', instanceIdOrPrefix: instance }
|
|
721
|
+
: allInstances
|
|
722
|
+
? { mode: 'all_instances' }
|
|
723
|
+
: { mode: 'target_default' };
|
|
724
|
+
const context = buildCliAdminOperationContext(req, options, session.account, sessionToken, {
|
|
725
|
+
type: 'backend',
|
|
726
|
+
id: targetName,
|
|
727
|
+
});
|
|
728
|
+
const result = await options.backendRestartService.restartBackend({
|
|
729
|
+
context,
|
|
730
|
+
targetName,
|
|
731
|
+
selection,
|
|
732
|
+
confirmationRequirements: cliBackendRestartConfirmationRequirements(options, targetName),
|
|
733
|
+
});
|
|
734
|
+
if (result.ok && isBackendRestartFailureResult(result.result)) {
|
|
735
|
+
sendCliBackendRestartOutcome(req, res, result.result);
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
sendCliAdminOperationResult(req, res, result);
|
|
739
|
+
}
|
|
740
|
+
function sendCliBackendRestartOutcome(req, res, result) {
|
|
741
|
+
const response = backendRestartFailure(result.outcome);
|
|
742
|
+
sendCliError(req, res, {
|
|
743
|
+
status: response.status,
|
|
744
|
+
code: response.code,
|
|
745
|
+
message: response.message,
|
|
746
|
+
retryable: false,
|
|
747
|
+
details: {
|
|
748
|
+
targetName: result.targetName,
|
|
749
|
+
...(result.candidateInstanceIds ? { candidateInstanceIds: result.candidateInstanceIds } : {}),
|
|
750
|
+
},
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
function isBackendRestartFailureResult(result) {
|
|
754
|
+
return result.outcome !== 'restarted';
|
|
755
|
+
}
|
|
756
|
+
function backendRestartFailure(outcome) {
|
|
757
|
+
switch (outcome) {
|
|
758
|
+
case 'target_not_found':
|
|
759
|
+
return { status: 404, code: 'backend_not_found', message: 'Backend target was not found' };
|
|
760
|
+
case 'target_disabled':
|
|
761
|
+
return { status: 409, code: 'backend_disabled', message: 'Backend target is disabled' };
|
|
762
|
+
case 'instance_not_found':
|
|
763
|
+
return { status: 404, code: 'backend_instance_not_found', message: 'Backend instance was not found' };
|
|
764
|
+
case 'instance_ambiguous':
|
|
765
|
+
return { status: 409, code: 'backend_instance_ambiguous', message: 'Backend instance prefix is ambiguous' };
|
|
766
|
+
case 'no_active_instances':
|
|
767
|
+
return {
|
|
768
|
+
status: 409,
|
|
769
|
+
code: 'backend_no_active_instances',
|
|
770
|
+
message: 'Backend has no active instances to restart',
|
|
771
|
+
};
|
|
772
|
+
case 'no_unhealthy_instances':
|
|
773
|
+
return {
|
|
774
|
+
status: 409,
|
|
775
|
+
code: 'backend_no_unhealthy_instances',
|
|
776
|
+
message: 'Backend has no unhealthy active instances to restart by default',
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
}
|
|
455
780
|
async function handleConfiguredServerDetail(req, res, options) {
|
|
456
781
|
if (!options.configuredServerService) {
|
|
457
782
|
res.status(404).json({ error: 'admin_configured_servers_unavailable' });
|
|
@@ -623,7 +948,7 @@ async function handleConfiguredServerMutation(req, res, options, operationName)
|
|
|
623
948
|
sendAdminOperationResult(res, result);
|
|
624
949
|
}
|
|
625
950
|
function cliMutationAvailability(options, setupRequired) {
|
|
626
|
-
if (!options.configuredServerService) {
|
|
951
|
+
if (!options.configuredServerService && !options.backendRestartService) {
|
|
627
952
|
return {
|
|
628
953
|
available: false,
|
|
629
954
|
reason: 'mutation_service_unavailable',
|
|
@@ -745,9 +1070,20 @@ function getBearerSessionToken(req) {
|
|
|
745
1070
|
if (!authorization) {
|
|
746
1071
|
return undefined;
|
|
747
1072
|
}
|
|
748
|
-
const
|
|
749
|
-
|
|
750
|
-
|
|
1073
|
+
const bearerScheme = 'Bearer';
|
|
1074
|
+
if (authorization.length <= bearerScheme.length ||
|
|
1075
|
+
authorization.slice(0, bearerScheme.length).toLowerCase() !== bearerScheme.toLowerCase()) {
|
|
1076
|
+
return undefined;
|
|
1077
|
+
}
|
|
1078
|
+
let tokenStart = bearerScheme.length;
|
|
1079
|
+
if (authorization.charCodeAt(tokenStart) !== 0x20) {
|
|
1080
|
+
return undefined;
|
|
1081
|
+
}
|
|
1082
|
+
while (authorization.charCodeAt(tokenStart) === 0x20) {
|
|
1083
|
+
tokenStart += 1;
|
|
1084
|
+
}
|
|
1085
|
+
const token = authorization.slice(tokenStart);
|
|
1086
|
+
return token && !/\s/u.test(token) ? token : undefined;
|
|
751
1087
|
}
|
|
752
1088
|
function isHttpsRuntime(externalUrl) {
|
|
753
1089
|
try {
|
|
@@ -864,6 +1200,26 @@ function sendAdminOperationResult(res, result) {
|
|
|
864
1200
|
const status = result.status === 'idempotency_key_required' ? 400 : result.status === 'mutation_failed' ? 409 : 409;
|
|
865
1201
|
res.status(status).json(result);
|
|
866
1202
|
}
|
|
1203
|
+
function sendAdminOAuthOperationResult(res, result) {
|
|
1204
|
+
if (!result.ok && result.status === 'mutation_failed') {
|
|
1205
|
+
const status = result.error === 'backend_oauth_service_not_found'
|
|
1206
|
+
? 404
|
|
1207
|
+
: result.error === 'backend_oauth_runtime_unavailable'
|
|
1208
|
+
? 503
|
|
1209
|
+
: 502;
|
|
1210
|
+
res.status(status).json({ ok: false, error: result.error });
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
sendAdminOperationResult(res, result);
|
|
1214
|
+
}
|
|
1215
|
+
function parseAdminOAuthServiceId(req, res) {
|
|
1216
|
+
const parsed = adminOAuthServiceParamsSchema.safeParse(req.params);
|
|
1217
|
+
if (!parsed.success) {
|
|
1218
|
+
res.status(400).json({ error: 'backend_oauth_service_id_invalid' });
|
|
1219
|
+
return null;
|
|
1220
|
+
}
|
|
1221
|
+
return parsed.data.serviceId;
|
|
1222
|
+
}
|
|
867
1223
|
async function handlePresetMutation(req, res, options, action) {
|
|
868
1224
|
if (!options.presetService) {
|
|
869
1225
|
res.status(404).json({ error: 'admin_presets_unavailable' });
|
|
@@ -937,16 +1293,10 @@ function buildAboutMetadata(runtime, ui) {
|
|
|
937
1293
|
timestamp: process.env.ADMIN_UI_BUILD_TIMESTAMP || undefined,
|
|
938
1294
|
},
|
|
939
1295
|
project: {
|
|
940
|
-
|
|
941
|
-
documentation: packageMetadata.documentation,
|
|
942
|
-
issues: packageMetadata.bugs?.url,
|
|
943
|
-
license: packageMetadata.license,
|
|
1296
|
+
...MCP_PROJECT_METADATA,
|
|
944
1297
|
},
|
|
945
1298
|
};
|
|
946
1299
|
}
|
|
947
|
-
function normalizeRepositoryUrl(value) {
|
|
948
|
-
return value?.replace(/^git\+/u, '').replace(/\.git$/u, '');
|
|
949
|
-
}
|
|
950
1300
|
function buildAdminOperationContext(req, options, target) {
|
|
951
1301
|
const sessionToken = getAdminSessionCookie(req);
|
|
952
1302
|
const session = options.adminService.validateSession(sessionToken);
|
|
@@ -972,7 +1322,9 @@ function buildAdminOperationContext(req, options, target) {
|
|
|
972
1322
|
jsonMode: true,
|
|
973
1323
|
},
|
|
974
1324
|
idempotencyKey: req.header('Idempotency-Key'),
|
|
975
|
-
requestFingerprint:
|
|
1325
|
+
requestFingerprint: target.type === 'backend_oauth_service'
|
|
1326
|
+
? backendOAuthRequestFingerprint(operationName, target.id)
|
|
1327
|
+
: configuredServerRequestFingerprint(operationName, target.id, req.body),
|
|
976
1328
|
confirmationFacts: getBodyRecord(req.body, 'confirmationFacts'),
|
|
977
1329
|
};
|
|
978
1330
|
}
|
|
@@ -1016,6 +1368,19 @@ function cliConfiguredServerConfirmationRequirements(options, targetName, operat
|
|
|
1016
1368
|
},
|
|
1017
1369
|
];
|
|
1018
1370
|
}
|
|
1371
|
+
function cliBackendRestartConfirmationRequirements(options, targetName) {
|
|
1372
|
+
const identity = options.getRuntimeIdentity();
|
|
1373
|
+
if (isLoopbackRuntimeUrl(identity.externalUrl)) {
|
|
1374
|
+
return [];
|
|
1375
|
+
}
|
|
1376
|
+
const target = { type: 'backend', id: targetName };
|
|
1377
|
+
return [
|
|
1378
|
+
{ code: 'confirm_non_loopback_runtime', expected: true, target },
|
|
1379
|
+
{ code: 'confirmedOperation', expected: 'mcp.restart', target },
|
|
1380
|
+
{ code: 'confirmedRuntimeScopeId', expected: identity.runtimeScopeId, target },
|
|
1381
|
+
{ code: 'confirmationSource', expected: 'cli_flag', target },
|
|
1382
|
+
];
|
|
1383
|
+
}
|
|
1019
1384
|
function buildCliAdminOperationContext(req, options, account, sessionToken, target) {
|
|
1020
1385
|
const runtimeIdentity = options.getRuntimeIdentity();
|
|
1021
1386
|
const operationName = operationNameForRequest(req);
|
|
@@ -1036,31 +1401,51 @@ function buildCliAdminOperationContext(req, options, account, sessionToken, targ
|
|
|
1036
1401
|
jsonMode: true,
|
|
1037
1402
|
},
|
|
1038
1403
|
idempotencyKey: req.header('Idempotency-Key'),
|
|
1039
|
-
requestFingerprint: configuredServerRequestFingerprint(operationName, target.id),
|
|
1404
|
+
requestFingerprint: configuredServerRequestFingerprint(operationName, target.id, req.body),
|
|
1040
1405
|
confirmationFacts: getBodyRecord(req.body, 'confirmationFacts'),
|
|
1041
1406
|
};
|
|
1042
1407
|
}
|
|
1043
1408
|
function configuredServerRequestFingerprint(operationName, targetName, body) {
|
|
1409
|
+
const previewFingerprint = getBodyString(body, 'previewFingerprint');
|
|
1044
1410
|
const normalized = stableJsonStringify({
|
|
1045
1411
|
schemaVersion: 1,
|
|
1046
1412
|
operationName,
|
|
1047
1413
|
target: {
|
|
1048
|
-
type: 'configured_server',
|
|
1414
|
+
type: operationName === 'restartBackend' ? 'backend' : 'configured_server',
|
|
1049
1415
|
id: targetName ?? '',
|
|
1050
1416
|
},
|
|
1051
1417
|
...(operationName === 'applyConfiguredServerEdit'
|
|
1052
1418
|
? {
|
|
1053
|
-
previewFingerprint
|
|
1054
|
-
editDigest:
|
|
1055
|
-
|
|
1056
|
-
|
|
1419
|
+
previewFingerprint,
|
|
1420
|
+
editDigest: keyedRequestFingerprint(previewFingerprint, 'configured-server-edit', stableJsonStringify(getBodyValue(body, 'edit') ?? {})),
|
|
1421
|
+
}
|
|
1422
|
+
: {}),
|
|
1423
|
+
...(operationName === 'restartBackend'
|
|
1424
|
+
? {
|
|
1425
|
+
restartSelection: {
|
|
1426
|
+
instance: getBodyString(body, 'instance'),
|
|
1427
|
+
allInstances: getBodyValue(body, 'allInstances') === true,
|
|
1428
|
+
},
|
|
1057
1429
|
}
|
|
1058
1430
|
: {}),
|
|
1059
1431
|
});
|
|
1060
1432
|
return operationName === 'applyConfiguredServerEdit'
|
|
1061
|
-
? `configured_server_apply_${
|
|
1433
|
+
? `configured_server_apply_${keyedRequestFingerprint(previewFingerprint, 'configured-server-apply', normalized)}`
|
|
1062
1434
|
: normalized;
|
|
1063
1435
|
}
|
|
1436
|
+
function keyedRequestFingerprint(key, domain, value) {
|
|
1437
|
+
return createHmac('sha256', key).update(domain).update('\0').update(value).digest('hex');
|
|
1438
|
+
}
|
|
1439
|
+
function backendOAuthRequestFingerprint(operationName, serviceId) {
|
|
1440
|
+
return stableJsonStringify({
|
|
1441
|
+
schemaVersion: 1,
|
|
1442
|
+
operationName,
|
|
1443
|
+
target: {
|
|
1444
|
+
type: 'backend_oauth_service',
|
|
1445
|
+
id: serviceId ?? '',
|
|
1446
|
+
},
|
|
1447
|
+
});
|
|
1448
|
+
}
|
|
1064
1449
|
function stableJsonStringify(value) {
|
|
1065
1450
|
if (Array.isArray(value)) {
|
|
1066
1451
|
return `[${value.map((item) => stableJsonStringify(item)).join(',')}]`;
|
|
@@ -1130,6 +1515,12 @@ function cliOperationErrorDetails(result) {
|
|
|
1130
1515
|
return details;
|
|
1131
1516
|
}
|
|
1132
1517
|
function operationNameForRequest(req) {
|
|
1518
|
+
if (req.path.startsWith('/api/oauth/')) {
|
|
1519
|
+
return req.path.endsWith('/restart') ? 'restartBackendOAuth' : 'authorizeBackendOAuth';
|
|
1520
|
+
}
|
|
1521
|
+
if (req.path.endsWith('/restart-server')) {
|
|
1522
|
+
return 'restartBackend';
|
|
1523
|
+
}
|
|
1133
1524
|
if (req.path.endsWith('/enable') || req.path.endsWith('/enable-server')) {
|
|
1134
1525
|
return 'enableConfiguredServer';
|
|
1135
1526
|
}
|
|
@@ -1179,10 +1570,19 @@ function sanitizeOAuthDashboard(dashboard) {
|
|
|
1179
1570
|
...dashboard,
|
|
1180
1571
|
services: dashboard.services.map((service) => ({
|
|
1181
1572
|
...service,
|
|
1573
|
+
id: service.name,
|
|
1574
|
+
displayName: backendOAuthServiceDisplayName(service.name),
|
|
1182
1575
|
lastError: service.lastError ? sanitizeErrorMessage(service.lastError) : undefined,
|
|
1183
1576
|
})),
|
|
1184
1577
|
};
|
|
1185
1578
|
}
|
|
1579
|
+
function backendOAuthServiceDisplayName(serviceId) {
|
|
1580
|
+
const identity = parseTemplateConnectionKey(serviceId);
|
|
1581
|
+
if (identity.kind !== 'rendered' || identity.renderedHash.length <= TEMPLATE_INSTANCE_ID_DISPLAY_LENGTH) {
|
|
1582
|
+
return serviceId;
|
|
1583
|
+
}
|
|
1584
|
+
return `${identity.templateName}:${identity.renderedHash.slice(0, TEMPLATE_INSTANCE_ID_DISPLAY_LENGTH)}`;
|
|
1585
|
+
}
|
|
1186
1586
|
function getBodyValue(body, key) {
|
|
1187
1587
|
if (!body || typeof body !== 'object') {
|
|
1188
1588
|
return undefined;
|