@lobu/gateway 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +6 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/platform.d.ts +92 -0
- package/dist/api/platform.d.ts.map +1 -0
- package/dist/api/platform.js +236 -0
- package/dist/api/platform.js.map +1 -0
- package/dist/api/response-renderer.d.ts +44 -0
- package/dist/api/response-renderer.d.ts.map +1 -0
- package/dist/api/response-renderer.js +123 -0
- package/dist/api/response-renderer.js.map +1 -0
- package/dist/auth/agent-metadata-store.d.ts +64 -0
- package/dist/auth/agent-metadata-store.d.ts.map +1 -0
- package/dist/auth/agent-metadata-store.js +115 -0
- package/dist/auth/agent-metadata-store.js.map +1 -0
- package/dist/auth/api-auth-middleware.d.ts +19 -0
- package/dist/auth/api-auth-middleware.d.ts.map +1 -0
- package/dist/auth/api-auth-middleware.js +61 -0
- package/dist/auth/api-auth-middleware.js.map +1 -0
- package/dist/auth/api-key-provider-module.d.ts +60 -0
- package/dist/auth/api-key-provider-module.d.ts.map +1 -0
- package/dist/auth/api-key-provider-module.js +148 -0
- package/dist/auth/api-key-provider-module.js.map +1 -0
- package/dist/auth/base-provider-module.d.ts +70 -0
- package/dist/auth/base-provider-module.d.ts.map +1 -0
- package/dist/auth/base-provider-module.js +118 -0
- package/dist/auth/base-provider-module.js.map +1 -0
- package/dist/auth/chatgpt/chatgpt-oauth-module.d.ts +34 -0
- package/dist/auth/chatgpt/chatgpt-oauth-module.d.ts.map +1 -0
- package/dist/auth/chatgpt/chatgpt-oauth-module.js +136 -0
- package/dist/auth/chatgpt/chatgpt-oauth-module.js.map +1 -0
- package/dist/auth/chatgpt/device-code-client.d.ts +40 -0
- package/dist/auth/chatgpt/device-code-client.d.ts.map +1 -0
- package/dist/auth/chatgpt/device-code-client.js +165 -0
- package/dist/auth/chatgpt/device-code-client.js.map +1 -0
- package/dist/auth/chatgpt/index.d.ts +2 -0
- package/dist/auth/chatgpt/index.d.ts.map +1 -0
- package/dist/auth/chatgpt/index.js +6 -0
- package/dist/auth/chatgpt/index.js.map +1 -0
- package/dist/auth/claude/oauth-module.d.ts +29 -0
- package/dist/auth/claude/oauth-module.d.ts.map +1 -0
- package/dist/auth/claude/oauth-module.js +201 -0
- package/dist/auth/claude/oauth-module.js.map +1 -0
- package/dist/auth/cli/token-service.d.ts +35 -0
- package/dist/auth/cli/token-service.d.ts.map +1 -0
- package/dist/auth/cli/token-service.js +171 -0
- package/dist/auth/cli/token-service.js.map +1 -0
- package/dist/auth/external/client.d.ts +65 -0
- package/dist/auth/external/client.d.ts.map +1 -0
- package/dist/auth/external/client.js +348 -0
- package/dist/auth/external/client.js.map +1 -0
- package/dist/auth/external/device-code-client.d.ts +41 -0
- package/dist/auth/external/device-code-client.d.ts.map +1 -0
- package/dist/auth/external/device-code-client.js +128 -0
- package/dist/auth/external/device-code-client.js.map +1 -0
- package/dist/auth/mcp/config-service.d.ts +70 -0
- package/dist/auth/mcp/config-service.d.ts.map +1 -0
- package/dist/auth/mcp/config-service.js +269 -0
- package/dist/auth/mcp/config-service.js.map +1 -0
- package/dist/auth/mcp/proxy.d.ts +68 -0
- package/dist/auth/mcp/proxy.d.ts.map +1 -0
- package/dist/auth/mcp/proxy.js +783 -0
- package/dist/auth/mcp/proxy.js.map +1 -0
- package/dist/auth/mcp/string-substitution.d.ts +11 -0
- package/dist/auth/mcp/string-substitution.d.ts.map +1 -0
- package/dist/auth/mcp/string-substitution.js +21 -0
- package/dist/auth/mcp/string-substitution.js.map +1 -0
- package/dist/auth/mcp/tool-cache.d.ts +26 -0
- package/dist/auth/mcp/tool-cache.d.ts.map +1 -0
- package/dist/auth/mcp/tool-cache.js +58 -0
- package/dist/auth/mcp/tool-cache.js.map +1 -0
- package/dist/auth/oauth/base-client.d.ts +54 -0
- package/dist/auth/oauth/base-client.d.ts.map +1 -0
- package/dist/auth/oauth/base-client.js +191 -0
- package/dist/auth/oauth/base-client.js.map +1 -0
- package/dist/auth/oauth/client.d.ts +35 -0
- package/dist/auth/oauth/client.d.ts.map +1 -0
- package/dist/auth/oauth/client.js +96 -0
- package/dist/auth/oauth/client.js.map +1 -0
- package/dist/auth/oauth/credentials.d.ts +8 -0
- package/dist/auth/oauth/credentials.d.ts.map +1 -0
- package/dist/auth/oauth/credentials.js +3 -0
- package/dist/auth/oauth/credentials.js.map +1 -0
- package/dist/auth/oauth/providers.d.ts +44 -0
- package/dist/auth/oauth/providers.d.ts.map +1 -0
- package/dist/auth/oauth/providers.js +37 -0
- package/dist/auth/oauth/providers.js.map +1 -0
- package/dist/auth/oauth/state-store.d.ts +62 -0
- package/dist/auth/oauth/state-store.d.ts.map +1 -0
- package/dist/auth/oauth/state-store.js +84 -0
- package/dist/auth/oauth/state-store.js.map +1 -0
- package/dist/auth/oauth-templates.d.ts +15 -0
- package/dist/auth/oauth-templates.d.ts.map +1 -0
- package/dist/auth/oauth-templates.js +161 -0
- package/dist/auth/oauth-templates.js.map +1 -0
- package/dist/auth/provider-catalog.d.ts +52 -0
- package/dist/auth/provider-catalog.d.ts.map +1 -0
- package/dist/auth/provider-catalog.js +155 -0
- package/dist/auth/provider-catalog.js.map +1 -0
- package/dist/auth/provider-model-options.d.ts +3 -0
- package/dist/auth/provider-model-options.d.ts.map +1 -0
- package/dist/auth/provider-model-options.js +29 -0
- package/dist/auth/provider-model-options.js.map +1 -0
- package/dist/auth/settings/agent-settings-store.d.ts +112 -0
- package/dist/auth/settings/agent-settings-store.d.ts.map +1 -0
- package/dist/auth/settings/agent-settings-store.js +376 -0
- package/dist/auth/settings/agent-settings-store.js.map +1 -0
- package/dist/auth/settings/auth-profiles-manager.d.ts +26 -0
- package/dist/auth/settings/auth-profiles-manager.d.ts.map +1 -0
- package/dist/auth/settings/auth-profiles-manager.js +146 -0
- package/dist/auth/settings/auth-profiles-manager.js.map +1 -0
- package/dist/auth/settings/index.d.ts +4 -0
- package/dist/auth/settings/index.d.ts.map +1 -0
- package/dist/auth/settings/index.js +9 -0
- package/dist/auth/settings/index.js.map +1 -0
- package/dist/auth/settings/model-preference-store.d.ts +25 -0
- package/dist/auth/settings/model-preference-store.d.ts.map +1 -0
- package/dist/auth/settings/model-preference-store.js +50 -0
- package/dist/auth/settings/model-preference-store.js.map +1 -0
- package/dist/auth/settings/model-selection.d.ts +11 -0
- package/dist/auth/settings/model-selection.d.ts.map +1 -0
- package/dist/auth/settings/model-selection.js +83 -0
- package/dist/auth/settings/model-selection.js.map +1 -0
- package/dist/auth/settings/resolved-settings-view.d.ts +45 -0
- package/dist/auth/settings/resolved-settings-view.d.ts.map +1 -0
- package/dist/auth/settings/resolved-settings-view.js +152 -0
- package/dist/auth/settings/resolved-settings-view.js.map +1 -0
- package/dist/auth/settings/template-utils.d.ts +3 -0
- package/dist/auth/settings/template-utils.d.ts.map +1 -0
- package/dist/auth/settings/template-utils.js +43 -0
- package/dist/auth/settings/template-utils.js.map +1 -0
- package/dist/auth/settings/token-service.d.ts +86 -0
- package/dist/auth/settings/token-service.d.ts.map +1 -0
- package/dist/auth/settings/token-service.js +3 -0
- package/dist/auth/settings/token-service.js.map +1 -0
- package/dist/auth/system-env-store.d.ts +26 -0
- package/dist/auth/system-env-store.d.ts.map +1 -0
- package/dist/auth/system-env-store.js +92 -0
- package/dist/auth/system-env-store.js.map +1 -0
- package/dist/auth/user-agents-store.d.ts +31 -0
- package/dist/auth/user-agents-store.d.ts.map +1 -0
- package/dist/auth/user-agents-store.js +54 -0
- package/dist/auth/user-agents-store.js.map +1 -0
- package/dist/channels/binding-service.d.ts +69 -0
- package/dist/channels/binding-service.d.ts.map +1 -0
- package/dist/channels/binding-service.js +144 -0
- package/dist/channels/binding-service.js.map +1 -0
- package/dist/channels/index.d.ts +2 -0
- package/dist/channels/index.d.ts.map +1 -0
- package/dist/channels/index.js +6 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/cli/gateway.d.ts +31 -0
- package/dist/cli/gateway.d.ts.map +1 -0
- package/dist/cli/gateway.js +1062 -0
- package/dist/cli/gateway.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +56 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/built-in-commands.d.ts +10 -0
- package/dist/commands/built-in-commands.d.ts.map +1 -0
- package/dist/commands/built-in-commands.js +63 -0
- package/dist/commands/built-in-commands.js.map +1 -0
- package/dist/commands/command-dispatcher.d.ts +25 -0
- package/dist/commands/command-dispatcher.d.ts.map +1 -0
- package/dist/commands/command-dispatcher.js +50 -0
- package/dist/commands/command-dispatcher.js.map +1 -0
- package/dist/commands/command-reply-adapters.d.ts +3 -0
- package/dist/commands/command-reply-adapters.d.ts.map +1 -0
- package/dist/commands/command-reply-adapters.js +60 -0
- package/dist/commands/command-reply-adapters.js.map +1 -0
- package/dist/config/file-loader.d.ts +23 -0
- package/dist/config/file-loader.d.ts.map +1 -0
- package/dist/config/file-loader.js +495 -0
- package/dist/config/file-loader.js.map +1 -0
- package/dist/config/index.d.ts +96 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +357 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/network-allowlist.d.ts +18 -0
- package/dist/config/network-allowlist.d.ts.map +1 -0
- package/dist/config/network-allowlist.js +60 -0
- package/dist/config/network-allowlist.js.map +1 -0
- package/dist/connections/chat-instance-manager.d.ts +107 -0
- package/dist/connections/chat-instance-manager.d.ts.map +1 -0
- package/dist/connections/chat-instance-manager.js +886 -0
- package/dist/connections/chat-instance-manager.js.map +1 -0
- package/dist/connections/chat-response-bridge.d.ts +31 -0
- package/dist/connections/chat-response-bridge.d.ts.map +1 -0
- package/dist/connections/chat-response-bridge.js +465 -0
- package/dist/connections/chat-response-bridge.js.map +1 -0
- package/dist/connections/index.d.ts +4 -0
- package/dist/connections/index.d.ts.map +1 -0
- package/dist/connections/index.js +8 -0
- package/dist/connections/index.js.map +1 -0
- package/dist/connections/interaction-bridge.d.ts +7 -0
- package/dist/connections/interaction-bridge.d.ts.map +1 -0
- package/dist/connections/interaction-bridge.js +593 -0
- package/dist/connections/interaction-bridge.js.map +1 -0
- package/dist/connections/message-handler-bridge.d.ts +21 -0
- package/dist/connections/message-handler-bridge.d.ts.map +1 -0
- package/dist/connections/message-handler-bridge.js +314 -0
- package/dist/connections/message-handler-bridge.js.map +1 -0
- package/dist/connections/platform-auth-methods.d.ts +5 -0
- package/dist/connections/platform-auth-methods.d.ts.map +1 -0
- package/dist/connections/platform-auth-methods.js +13 -0
- package/dist/connections/platform-auth-methods.js.map +1 -0
- package/dist/connections/types.d.ts +52 -0
- package/dist/connections/types.d.ts.map +1 -0
- package/dist/connections/types.js +20 -0
- package/dist/connections/types.js.map +1 -0
- package/dist/gateway/connection-manager.d.ts +87 -0
- package/dist/gateway/connection-manager.d.ts.map +1 -0
- package/dist/gateway/connection-manager.js +216 -0
- package/dist/gateway/connection-manager.js.map +1 -0
- package/dist/gateway/index.d.ts +71 -0
- package/dist/gateway/index.d.ts.map +1 -0
- package/dist/gateway/index.js +509 -0
- package/dist/gateway/index.js.map +1 -0
- package/dist/gateway/job-router.d.ts +60 -0
- package/dist/gateway/job-router.d.ts.map +1 -0
- package/dist/gateway/job-router.js +148 -0
- package/dist/gateway/job-router.js.map +1 -0
- package/dist/gateway-main.d.ts +81 -0
- package/dist/gateway-main.d.ts.map +1 -0
- package/dist/gateway-main.js +143 -0
- package/dist/gateway-main.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/queue/index.d.ts +8 -0
- package/dist/infrastructure/queue/index.d.ts.map +1 -0
- package/dist/infrastructure/queue/index.js +12 -0
- package/dist/infrastructure/queue/index.js.map +1 -0
- package/dist/infrastructure/queue/queue-producer.d.ts +68 -0
- package/dist/infrastructure/queue/queue-producer.d.ts.map +1 -0
- package/dist/infrastructure/queue/queue-producer.js +72 -0
- package/dist/infrastructure/queue/queue-producer.js.map +1 -0
- package/dist/infrastructure/queue/redis-queue.d.ts +45 -0
- package/dist/infrastructure/queue/redis-queue.d.ts.map +1 -0
- package/dist/infrastructure/queue/redis-queue.js +273 -0
- package/dist/infrastructure/queue/redis-queue.js.map +1 -0
- package/dist/infrastructure/queue/types.d.ts +107 -0
- package/dist/infrastructure/queue/types.d.ts.map +1 -0
- package/dist/infrastructure/queue/types.js +7 -0
- package/dist/infrastructure/queue/types.js.map +1 -0
- package/dist/infrastructure/redis/system-message-limiter.d.ts +35 -0
- package/dist/infrastructure/redis/system-message-limiter.d.ts.map +1 -0
- package/dist/infrastructure/redis/system-message-limiter.js +61 -0
- package/dist/infrastructure/redis/system-message-limiter.js.map +1 -0
- package/dist/interactions/config-request-store.d.ts +41 -0
- package/dist/interactions/config-request-store.d.ts.map +1 -0
- package/dist/interactions/config-request-store.js +103 -0
- package/dist/interactions/config-request-store.js.map +1 -0
- package/dist/interactions.d.ts +134 -0
- package/dist/interactions.d.ts.map +1 -0
- package/dist/interactions.js +175 -0
- package/dist/interactions.js.map +1 -0
- package/dist/lobu.d.ts +78 -0
- package/dist/lobu.d.ts.map +1 -0
- package/dist/lobu.js +248 -0
- package/dist/lobu.js.map +1 -0
- package/dist/metrics/prometheus.d.ts +6 -0
- package/dist/metrics/prometheus.d.ts.map +1 -0
- package/dist/metrics/prometheus.js +78 -0
- package/dist/metrics/prometheus.js.map +1 -0
- package/dist/modules/module-system.d.ts +82 -0
- package/dist/modules/module-system.d.ts.map +1 -0
- package/dist/modules/module-system.js +53 -0
- package/dist/modules/module-system.js.map +1 -0
- package/dist/orchestration/base-deployment-manager.d.ts +173 -0
- package/dist/orchestration/base-deployment-manager.d.ts.map +1 -0
- package/dist/orchestration/base-deployment-manager.js +553 -0
- package/dist/orchestration/base-deployment-manager.js.map +1 -0
- package/dist/orchestration/deployment-utils.d.ts +25 -0
- package/dist/orchestration/deployment-utils.d.ts.map +1 -0
- package/dist/orchestration/deployment-utils.js +65 -0
- package/dist/orchestration/deployment-utils.js.map +1 -0
- package/dist/orchestration/impl/docker-deployment.d.ts +43 -0
- package/dist/orchestration/impl/docker-deployment.d.ts.map +1 -0
- package/dist/orchestration/impl/docker-deployment.js +480 -0
- package/dist/orchestration/impl/docker-deployment.js.map +1 -0
- package/dist/orchestration/impl/embedded-deployment.d.ts +16 -0
- package/dist/orchestration/impl/embedded-deployment.d.ts.map +1 -0
- package/dist/orchestration/impl/embedded-deployment.js +195 -0
- package/dist/orchestration/impl/embedded-deployment.js.map +1 -0
- package/dist/orchestration/impl/index.d.ts +8 -0
- package/dist/orchestration/impl/index.d.ts.map +1 -0
- package/dist/orchestration/impl/index.js +14 -0
- package/dist/orchestration/impl/index.js.map +1 -0
- package/dist/orchestration/impl/k8s/deployment.d.ts +204 -0
- package/dist/orchestration/impl/k8s/deployment.d.ts.map +1 -0
- package/dist/orchestration/impl/k8s/deployment.js +620 -0
- package/dist/orchestration/impl/k8s/deployment.js.map +1 -0
- package/dist/orchestration/impl/k8s/helpers.d.ts +34 -0
- package/dist/orchestration/impl/k8s/helpers.d.ts.map +1 -0
- package/dist/orchestration/impl/k8s/helpers.js +377 -0
- package/dist/orchestration/impl/k8s/helpers.js.map +1 -0
- package/dist/orchestration/impl/k8s/index.d.ts +2 -0
- package/dist/orchestration/impl/k8s/index.d.ts.map +1 -0
- package/dist/orchestration/impl/k8s/index.js +6 -0
- package/dist/orchestration/impl/k8s/index.js.map +1 -0
- package/dist/orchestration/index.d.ts +53 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +257 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/message-consumer.d.ts +49 -0
- package/dist/orchestration/message-consumer.d.ts.map +1 -0
- package/dist/orchestration/message-consumer.js +406 -0
- package/dist/orchestration/message-consumer.js.map +1 -0
- package/dist/orchestration/scheduled-wakeup.d.ts +110 -0
- package/dist/orchestration/scheduled-wakeup.d.ts.map +1 -0
- package/dist/orchestration/scheduled-wakeup.js +500 -0
- package/dist/orchestration/scheduled-wakeup.js.map +1 -0
- package/dist/permissions/approval-policy.d.ts +28 -0
- package/dist/permissions/approval-policy.d.ts.map +1 -0
- package/dist/permissions/approval-policy.js +33 -0
- package/dist/permissions/approval-policy.js.map +1 -0
- package/dist/permissions/grant-store.d.ts +52 -0
- package/dist/permissions/grant-store.d.ts.map +1 -0
- package/dist/permissions/grant-store.js +192 -0
- package/dist/permissions/grant-store.js.map +1 -0
- package/dist/platform/file-handler.d.ts +51 -0
- package/dist/platform/file-handler.d.ts.map +1 -0
- package/dist/platform/file-handler.js +6 -0
- package/dist/platform/file-handler.js.map +1 -0
- package/dist/platform/link-buttons.d.ts +21 -0
- package/dist/platform/link-buttons.d.ts.map +1 -0
- package/dist/platform/link-buttons.js +43 -0
- package/dist/platform/link-buttons.js.map +1 -0
- package/dist/platform/renderer-utils.d.ts +10 -0
- package/dist/platform/renderer-utils.d.ts.map +1 -0
- package/dist/platform/renderer-utils.js +42 -0
- package/dist/platform/renderer-utils.js.map +1 -0
- package/dist/platform/response-renderer.d.ts +66 -0
- package/dist/platform/response-renderer.d.ts.map +1 -0
- package/dist/platform/response-renderer.js +8 -0
- package/dist/platform/response-renderer.js.map +1 -0
- package/dist/platform/unified-thread-consumer.d.ts +41 -0
- package/dist/platform/unified-thread-consumer.d.ts.map +1 -0
- package/dist/platform/unified-thread-consumer.js +143 -0
- package/dist/platform/unified-thread-consumer.js.map +1 -0
- package/dist/platform.d.ts +255 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +40 -0
- package/dist/platform.js.map +1 -0
- package/dist/proxy/http-proxy.d.ts +32 -0
- package/dist/proxy/http-proxy.d.ts.map +1 -0
- package/dist/proxy/http-proxy.js +636 -0
- package/dist/proxy/http-proxy.js.map +1 -0
- package/dist/proxy/proxy-manager.d.ts +13 -0
- package/dist/proxy/proxy-manager.d.ts.map +1 -0
- package/dist/proxy/proxy-manager.js +68 -0
- package/dist/proxy/proxy-manager.js.map +1 -0
- package/dist/proxy/secret-proxy.d.ts +78 -0
- package/dist/proxy/secret-proxy.d.ts.map +1 -0
- package/dist/proxy/secret-proxy.js +309 -0
- package/dist/proxy/secret-proxy.js.map +1 -0
- package/dist/proxy/token-refresh-job.d.ts +29 -0
- package/dist/proxy/token-refresh-job.d.ts.map +1 -0
- package/dist/proxy/token-refresh-job.js +104 -0
- package/dist/proxy/token-refresh-job.js.map +1 -0
- package/dist/routes/internal/audio.d.ts +14 -0
- package/dist/routes/internal/audio.d.ts.map +1 -0
- package/dist/routes/internal/audio.js +118 -0
- package/dist/routes/internal/audio.js.map +1 -0
- package/dist/routes/internal/device-auth.d.ts +42 -0
- package/dist/routes/internal/device-auth.d.ts.map +1 -0
- package/dist/routes/internal/device-auth.js +397 -0
- package/dist/routes/internal/device-auth.js.map +1 -0
- package/dist/routes/internal/files.d.ts +9 -0
- package/dist/routes/internal/files.d.ts.map +1 -0
- package/dist/routes/internal/files.js +175 -0
- package/dist/routes/internal/files.js.map +1 -0
- package/dist/routes/internal/history.d.ts +9 -0
- package/dist/routes/internal/history.d.ts.map +1 -0
- package/dist/routes/internal/history.js +55 -0
- package/dist/routes/internal/history.js.map +1 -0
- package/dist/routes/internal/images.d.ts +10 -0
- package/dist/routes/internal/images.d.ts.map +1 -0
- package/dist/routes/internal/images.js +101 -0
- package/dist/routes/internal/images.js.map +1 -0
- package/dist/routes/internal/interactions.d.ts +9 -0
- package/dist/routes/internal/interactions.d.ts.map +1 -0
- package/dist/routes/internal/interactions.js +53 -0
- package/dist/routes/internal/interactions.js.map +1 -0
- package/dist/routes/internal/middleware.d.ts +7 -0
- package/dist/routes/internal/middleware.d.ts.map +1 -0
- package/dist/routes/internal/middleware.js +24 -0
- package/dist/routes/internal/middleware.js.map +1 -0
- package/dist/routes/internal/schedule.d.ts +14 -0
- package/dist/routes/internal/schedule.d.ts.map +1 -0
- package/dist/routes/internal/schedule.js +169 -0
- package/dist/routes/internal/schedule.js.map +1 -0
- package/dist/routes/internal/types.d.ts +22 -0
- package/dist/routes/internal/types.d.ts.map +1 -0
- package/dist/routes/internal/types.js +6 -0
- package/dist/routes/internal/types.js.map +1 -0
- package/dist/routes/openapi-auto.d.ts +8 -0
- package/dist/routes/openapi-auto.d.ts.map +1 -0
- package/dist/routes/openapi-auto.js +196 -0
- package/dist/routes/openapi-auto.js.map +1 -0
- package/dist/routes/public/agent-access.d.ts +11 -0
- package/dist/routes/public/agent-access.d.ts.map +1 -0
- package/dist/routes/public/agent-access.js +11 -0
- package/dist/routes/public/agent-access.js.map +1 -0
- package/dist/routes/public/agent-config.d.ts +42 -0
- package/dist/routes/public/agent-config.d.ts.map +1 -0
- package/dist/routes/public/agent-config.js +415 -0
- package/dist/routes/public/agent-config.js.map +1 -0
- package/dist/routes/public/agent-history.d.ts +17 -0
- package/dist/routes/public/agent-history.d.ts.map +1 -0
- package/dist/routes/public/agent-history.js +335 -0
- package/dist/routes/public/agent-history.js.map +1 -0
- package/dist/routes/public/agent-schedules.d.ts +18 -0
- package/dist/routes/public/agent-schedules.d.ts.map +1 -0
- package/dist/routes/public/agent-schedules.js +242 -0
- package/dist/routes/public/agent-schedules.js.map +1 -0
- package/dist/routes/public/agent.d.ts +23 -0
- package/dist/routes/public/agent.d.ts.map +1 -0
- package/dist/routes/public/agent.js +864 -0
- package/dist/routes/public/agent.js.map +1 -0
- package/dist/routes/public/agents.d.ts +22 -0
- package/dist/routes/public/agents.d.ts.map +1 -0
- package/dist/routes/public/agents.js +257 -0
- package/dist/routes/public/agents.js.map +1 -0
- package/dist/routes/public/channels.d.ts +23 -0
- package/dist/routes/public/channels.d.ts.map +1 -0
- package/dist/routes/public/channels.js +131 -0
- package/dist/routes/public/channels.js.map +1 -0
- package/dist/routes/public/cli-auth.d.ts +12 -0
- package/dist/routes/public/cli-auth.d.ts.map +1 -0
- package/dist/routes/public/cli-auth.js +552 -0
- package/dist/routes/public/cli-auth.js.map +1 -0
- package/dist/routes/public/connections.d.ts +20 -0
- package/dist/routes/public/connections.d.ts.map +1 -0
- package/dist/routes/public/connections.js +464 -0
- package/dist/routes/public/connections.js.map +1 -0
- package/dist/routes/public/landing.d.ts +3 -0
- package/dist/routes/public/landing.d.ts.map +1 -0
- package/dist/routes/public/landing.js +17 -0
- package/dist/routes/public/landing.js.map +1 -0
- package/dist/routes/public/oauth.d.ts +24 -0
- package/dist/routes/public/oauth.d.ts.map +1 -0
- package/dist/routes/public/oauth.js +108 -0
- package/dist/routes/public/oauth.js.map +1 -0
- package/dist/routes/public/settings-auth.d.ts +28 -0
- package/dist/routes/public/settings-auth.d.ts.map +1 -0
- package/dist/routes/public/settings-auth.js +90 -0
- package/dist/routes/public/settings-auth.js.map +1 -0
- package/dist/routes/public/slack.d.ts +4 -0
- package/dist/routes/public/slack.d.ts.map +1 -0
- package/dist/routes/public/slack.js +119 -0
- package/dist/routes/public/slack.js.map +1 -0
- package/dist/routes/shared/agent-ownership.d.ts +15 -0
- package/dist/routes/shared/agent-ownership.d.ts.map +1 -0
- package/dist/routes/shared/agent-ownership.js +61 -0
- package/dist/routes/shared/agent-ownership.js.map +1 -0
- package/dist/routes/shared/token-verifier.d.ts +21 -0
- package/dist/routes/shared/token-verifier.d.ts.map +1 -0
- package/dist/routes/shared/token-verifier.js +25 -0
- package/dist/routes/shared/token-verifier.js.map +1 -0
- package/dist/services/core-services.d.ts +133 -0
- package/dist/services/core-services.d.ts.map +1 -0
- package/dist/services/core-services.js +728 -0
- package/dist/services/core-services.js.map +1 -0
- package/dist/services/image-generation-service.d.ts +38 -0
- package/dist/services/image-generation-service.d.ts.map +1 -0
- package/dist/services/image-generation-service.js +167 -0
- package/dist/services/image-generation-service.js.map +1 -0
- package/dist/services/instruction-service.d.ts +41 -0
- package/dist/services/instruction-service.d.ts.map +1 -0
- package/dist/services/instruction-service.js +252 -0
- package/dist/services/instruction-service.js.map +1 -0
- package/dist/services/mcp-registry.d.ts +31 -0
- package/dist/services/mcp-registry.d.ts.map +1 -0
- package/dist/services/mcp-registry.js +69 -0
- package/dist/services/mcp-registry.js.map +1 -0
- package/dist/services/platform-helpers.d.ts +47 -0
- package/dist/services/platform-helpers.d.ts.map +1 -0
- package/dist/services/platform-helpers.js +200 -0
- package/dist/services/platform-helpers.js.map +1 -0
- package/dist/services/session-manager.d.ts +72 -0
- package/dist/services/session-manager.d.ts.map +1 -0
- package/dist/services/session-manager.js +199 -0
- package/dist/services/session-manager.js.map +1 -0
- package/dist/services/settings-resolver.d.ts +25 -0
- package/dist/services/settings-resolver.d.ts.map +1 -0
- package/dist/services/settings-resolver.js +55 -0
- package/dist/services/settings-resolver.js.map +1 -0
- package/dist/services/system-config-resolver.d.ts +25 -0
- package/dist/services/system-config-resolver.d.ts.map +1 -0
- package/dist/services/system-config-resolver.js +73 -0
- package/dist/services/system-config-resolver.js.map +1 -0
- package/dist/services/system-skills-service.d.ts +38 -0
- package/dist/services/system-skills-service.d.ts.map +1 -0
- package/dist/services/system-skills-service.js +186 -0
- package/dist/services/system-skills-service.js.map +1 -0
- package/dist/services/transcription-service.d.ts +91 -0
- package/dist/services/transcription-service.d.ts.map +1 -0
- package/dist/services/transcription-service.js +465 -0
- package/dist/services/transcription-service.js.map +1 -0
- package/dist/session.d.ts +75 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +19 -0
- package/dist/session.js.map +1 -0
- package/dist/spaces/index.d.ts +2 -0
- package/dist/spaces/index.d.ts.map +1 -0
- package/dist/spaces/index.js +18 -0
- package/dist/spaces/index.js.map +1 -0
- package/dist/spaces/space-resolver.d.ts +10 -0
- package/dist/spaces/space-resolver.d.ts.map +1 -0
- package/dist/spaces/space-resolver.js +17 -0
- package/dist/spaces/space-resolver.js.map +1 -0
- package/dist/stores/in-memory-agent-store.d.ts +57 -0
- package/dist/stores/in-memory-agent-store.d.ts.map +1 -0
- package/dist/stores/in-memory-agent-store.js +304 -0
- package/dist/stores/in-memory-agent-store.js.map +1 -0
- package/dist/stores/redis-agent-store.d.ts +57 -0
- package/dist/stores/redis-agent-store.d.ts.map +1 -0
- package/dist/stores/redis-agent-store.js +163 -0
- package/dist/stores/redis-agent-store.js.map +1 -0
- package/dist/utils/public-url.d.ts +6 -0
- package/dist/utils/public-url.d.ts.map +1 -0
- package/dist/utils/public-url.js +33 -0
- package/dist/utils/public-url.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts +32 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -0
- package/dist/utils/rate-limiter.js +56 -0
- package/dist/utils/rate-limiter.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,783 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.McpProxy = void 0;
|
|
40
|
+
const promises_1 = __importDefault(require("node:dns/promises"));
|
|
41
|
+
const core_1 = require("@lobu/core");
|
|
42
|
+
const hono_1 = require("hono");
|
|
43
|
+
const approval_policy_1 = require("../../permissions/approval-policy");
|
|
44
|
+
const device_auth_1 = require("../../routes/internal/device-auth");
|
|
45
|
+
const logger = (0, core_1.createLogger)("mcp-proxy");
|
|
46
|
+
const MAX_BODY_SIZE = 1024 * 1024; // 1MB
|
|
47
|
+
/**
|
|
48
|
+
* Check whether a resolved IP address belongs to a reserved/internal range.
|
|
49
|
+
*/
|
|
50
|
+
function isReservedIp(ip) {
|
|
51
|
+
// IPv6 loopback
|
|
52
|
+
if (ip === "::1")
|
|
53
|
+
return true;
|
|
54
|
+
// IPv6 unique local (fc00::/7)
|
|
55
|
+
if (/^f[cd]/i.test(ip))
|
|
56
|
+
return true;
|
|
57
|
+
// IPv4
|
|
58
|
+
const parts = ip.split(".").map(Number);
|
|
59
|
+
if (parts.length === 4) {
|
|
60
|
+
const [a, b] = parts;
|
|
61
|
+
// 127.0.0.0/8
|
|
62
|
+
if (a === 127)
|
|
63
|
+
return true;
|
|
64
|
+
// 10.0.0.0/8
|
|
65
|
+
if (a === 10)
|
|
66
|
+
return true;
|
|
67
|
+
// 172.16.0.0/12
|
|
68
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
69
|
+
return true;
|
|
70
|
+
// 192.168.0.0/16
|
|
71
|
+
if (a === 192 && b === 168)
|
|
72
|
+
return true;
|
|
73
|
+
// 169.254.0.0/16 (link-local)
|
|
74
|
+
if (a === 169 && b === 254)
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Resolve a URL's hostname and check whether it points to an internal/reserved network.
|
|
81
|
+
*/
|
|
82
|
+
async function isInternalUrl(url) {
|
|
83
|
+
try {
|
|
84
|
+
const parsed = new URL(url);
|
|
85
|
+
const hostname = parsed.hostname;
|
|
86
|
+
// Check if hostname is already an IP literal
|
|
87
|
+
if (isReservedIp(hostname))
|
|
88
|
+
return true;
|
|
89
|
+
// Resolve hostname to IP addresses
|
|
90
|
+
const addresses = await promises_1.default.resolve4(hostname).catch(() => []);
|
|
91
|
+
const addresses6 = await promises_1.default.resolve6(hostname).catch(() => []);
|
|
92
|
+
for (const addr of [...addresses, ...addresses6]) {
|
|
93
|
+
if (isReservedIp(addr))
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
catch (_a) {
|
|
99
|
+
// If URL parsing fails, block it
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function authenticateRequest(c) {
|
|
104
|
+
const sessionToken = extractSessionToken(c);
|
|
105
|
+
if (!sessionToken)
|
|
106
|
+
return null;
|
|
107
|
+
const tokenData = (0, core_1.verifyWorkerToken)(sessionToken);
|
|
108
|
+
if (!tokenData)
|
|
109
|
+
return null;
|
|
110
|
+
return { tokenData, token: sessionToken };
|
|
111
|
+
}
|
|
112
|
+
function extractSessionToken(c) {
|
|
113
|
+
const authHeader = c.req.header("authorization");
|
|
114
|
+
if (authHeader === null || authHeader === void 0 ? void 0 : authHeader.startsWith("Bearer ")) {
|
|
115
|
+
return authHeader.substring(7);
|
|
116
|
+
}
|
|
117
|
+
const tokenFromQuery = c.req.query("workerToken");
|
|
118
|
+
if (typeof tokenFromQuery === "string") {
|
|
119
|
+
return tokenFromQuery;
|
|
120
|
+
}
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
class McpProxy {
|
|
124
|
+
constructor(configService, queue, toolCache, grantStore) {
|
|
125
|
+
this.configService = configService;
|
|
126
|
+
this.grantStore = grantStore;
|
|
127
|
+
this.SESSION_TTL_SECONDS = 30 * 60; // 30 minutes
|
|
128
|
+
this.redisClient = queue.getRedisClient();
|
|
129
|
+
this.toolCache = toolCache;
|
|
130
|
+
this.app = new hono_1.Hono();
|
|
131
|
+
this.setupRoutes();
|
|
132
|
+
logger.debug("MCP proxy initialized");
|
|
133
|
+
}
|
|
134
|
+
getApp() {
|
|
135
|
+
return this.app;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Check if this request is an MCP proxy request (has X-Mcp-Id header)
|
|
139
|
+
* Used by gateway to determine if root path requests should be handled by MCP proxy
|
|
140
|
+
*/
|
|
141
|
+
isMcpRequest(c) {
|
|
142
|
+
return !!c.req.header("x-mcp-id");
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Fetch tools and instructions for a specific MCP server.
|
|
146
|
+
* Performs MCP initialize handshake first to capture server instructions,
|
|
147
|
+
* then fetches tool list.
|
|
148
|
+
*/
|
|
149
|
+
async fetchToolsForMcp(mcpId, agentId, tokenData) {
|
|
150
|
+
var _a, _b, _c;
|
|
151
|
+
if (this.toolCache) {
|
|
152
|
+
const cached = await this.toolCache.getServerInfo(mcpId, agentId);
|
|
153
|
+
if (cached)
|
|
154
|
+
return cached;
|
|
155
|
+
}
|
|
156
|
+
const httpServer = await this.configService.getHttpServer(mcpId, agentId);
|
|
157
|
+
if (!httpServer) {
|
|
158
|
+
return { tools: [] };
|
|
159
|
+
}
|
|
160
|
+
const userId = tokenData === null || tokenData === void 0 ? void 0 : tokenData.userId;
|
|
161
|
+
try {
|
|
162
|
+
// Clear any stale session before fresh tool discovery
|
|
163
|
+
const sessionKey = `mcp:session:${agentId}:${mcpId}`;
|
|
164
|
+
await this.redisClient.del(sessionKey).catch(() => {
|
|
165
|
+
/* noop */
|
|
166
|
+
});
|
|
167
|
+
// Step 1: Send initialize to capture server instructions
|
|
168
|
+
let instructions;
|
|
169
|
+
try {
|
|
170
|
+
const initBody = JSON.stringify({
|
|
171
|
+
jsonrpc: "2.0",
|
|
172
|
+
method: "initialize",
|
|
173
|
+
params: {
|
|
174
|
+
protocolVersion: "2024-11-05",
|
|
175
|
+
capabilities: {},
|
|
176
|
+
clientInfo: { name: "lobu-gateway", version: "1.0.0" },
|
|
177
|
+
},
|
|
178
|
+
id: 0,
|
|
179
|
+
});
|
|
180
|
+
const initResponse = await this.sendUpstreamRequest(httpServer, agentId, mcpId, "POST", initBody, userId);
|
|
181
|
+
const initData = (await initResponse.json());
|
|
182
|
+
if ((_a = initData === null || initData === void 0 ? void 0 : initData.result) === null || _a === void 0 ? void 0 : _a.instructions) {
|
|
183
|
+
instructions = initData.result.instructions;
|
|
184
|
+
logger.info("Captured MCP server instructions", {
|
|
185
|
+
mcpId,
|
|
186
|
+
length: instructions.length,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
// Step 2: Send initialized notification (required by MCP spec)
|
|
190
|
+
const notifyBody = JSON.stringify({
|
|
191
|
+
jsonrpc: "2.0",
|
|
192
|
+
method: "notifications/initialized",
|
|
193
|
+
});
|
|
194
|
+
await this.sendUpstreamRequest(httpServer, agentId, mcpId, "POST", notifyBody, userId).catch(() => {
|
|
195
|
+
/* noop */
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
catch (initError) {
|
|
199
|
+
logger.warn("MCP initialize failed (continuing with tools/list)", {
|
|
200
|
+
mcpId,
|
|
201
|
+
error: initError instanceof Error ? initError.message : String(initError),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
// Step 3: Fetch tools list
|
|
205
|
+
const jsonRpcBody = JSON.stringify({
|
|
206
|
+
jsonrpc: "2.0",
|
|
207
|
+
method: "tools/list",
|
|
208
|
+
params: {},
|
|
209
|
+
id: 1,
|
|
210
|
+
});
|
|
211
|
+
const response = await this.sendUpstreamRequest(httpServer, agentId, mcpId, "POST", jsonRpcBody, userId);
|
|
212
|
+
const data = (await response.json());
|
|
213
|
+
const tools = ((_b = data === null || data === void 0 ? void 0 : data.result) === null || _b === void 0 ? void 0 : _b.tools) || [];
|
|
214
|
+
const serverInfo = { tools, instructions };
|
|
215
|
+
if (this.toolCache && tools.length > 0) {
|
|
216
|
+
await this.toolCache.setServerInfo(mcpId, serverInfo, agentId);
|
|
217
|
+
}
|
|
218
|
+
return serverInfo;
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
logger.warn("Failed to fetch tools for MCP, retrying once", {
|
|
222
|
+
mcpId,
|
|
223
|
+
error: error instanceof Error ? error.message : String(error),
|
|
224
|
+
});
|
|
225
|
+
// Retry once after a short delay (upstream may still be starting)
|
|
226
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
227
|
+
try {
|
|
228
|
+
const retryBody = JSON.stringify({
|
|
229
|
+
jsonrpc: "2.0",
|
|
230
|
+
method: "tools/list",
|
|
231
|
+
params: {},
|
|
232
|
+
id: 1,
|
|
233
|
+
});
|
|
234
|
+
const retryResponse = await this.sendUpstreamRequest(httpServer, agentId, mcpId, "POST", retryBody, userId);
|
|
235
|
+
const retryData = (await retryResponse.json());
|
|
236
|
+
const retryTools = ((_c = retryData === null || retryData === void 0 ? void 0 : retryData.result) === null || _c === void 0 ? void 0 : _c.tools) || [];
|
|
237
|
+
if (retryTools.length > 0) {
|
|
238
|
+
const serverInfo = { tools: retryTools };
|
|
239
|
+
if (this.toolCache) {
|
|
240
|
+
await this.toolCache.setServerInfo(mcpId, serverInfo, agentId);
|
|
241
|
+
}
|
|
242
|
+
logger.info("Retry succeeded for MCP tool fetch", {
|
|
243
|
+
mcpId,
|
|
244
|
+
toolCount: retryTools.length,
|
|
245
|
+
});
|
|
246
|
+
return serverInfo;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch (retryError) {
|
|
250
|
+
logger.error("Retry also failed for MCP tool fetch", {
|
|
251
|
+
mcpId,
|
|
252
|
+
error: retryError instanceof Error
|
|
253
|
+
? retryError.message
|
|
254
|
+
: String(retryError),
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return { tools: [] };
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
setupRoutes() {
|
|
261
|
+
// REST API endpoints for curl-based tool access (registered BEFORE catch-all)
|
|
262
|
+
this.app.get("/tools", (c) => this.handleListAllTools(c));
|
|
263
|
+
this.app.get("/:mcpId/tools", (c) => this.handleListTools(c));
|
|
264
|
+
this.app.post("/:mcpId/tools/:toolName", (c) => this.handleCallTool(c));
|
|
265
|
+
// Legacy endpoints (if needed for other MCP transports)
|
|
266
|
+
this.app.all("/register", (c) => this.handleProxyRequest(c));
|
|
267
|
+
this.app.all("/message", (c) => this.handleProxyRequest(c));
|
|
268
|
+
// Path-based routes (for SSE or other transports)
|
|
269
|
+
this.app.all("/:mcpId", (c) => this.handleProxyRequest(c));
|
|
270
|
+
this.app.all("/:mcpId/*", (c) => this.handleProxyRequest(c));
|
|
271
|
+
}
|
|
272
|
+
async handleListTools(c) {
|
|
273
|
+
var _a;
|
|
274
|
+
const mcpId = c.req.param("mcpId");
|
|
275
|
+
if (!mcpId)
|
|
276
|
+
return c.json({ error: "Missing MCP server id" }, 400);
|
|
277
|
+
const auth = authenticateRequest(c);
|
|
278
|
+
if (!auth)
|
|
279
|
+
return c.json({ error: "Invalid authentication token" }, 401);
|
|
280
|
+
const agentId = auth.tokenData.agentId || auth.tokenData.userId;
|
|
281
|
+
const requesterUserId = auth.tokenData.userId;
|
|
282
|
+
if (!agentId || !requesterUserId) {
|
|
283
|
+
return c.json({ error: "Invalid authentication token" }, 401);
|
|
284
|
+
}
|
|
285
|
+
const httpServer = await this.configService.getHttpServer(mcpId, agentId);
|
|
286
|
+
if (!httpServer) {
|
|
287
|
+
return c.json({ error: `MCP server '${mcpId}' not found` }, 404);
|
|
288
|
+
}
|
|
289
|
+
// Check cache
|
|
290
|
+
if (this.toolCache) {
|
|
291
|
+
const cached = await this.toolCache.get(mcpId, agentId);
|
|
292
|
+
if (cached)
|
|
293
|
+
return c.json({ tools: cached });
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
const jsonRpcBody = JSON.stringify({
|
|
297
|
+
jsonrpc: "2.0",
|
|
298
|
+
method: "tools/list",
|
|
299
|
+
params: {},
|
|
300
|
+
id: 1,
|
|
301
|
+
});
|
|
302
|
+
const response = await this.sendUpstreamRequest(httpServer, agentId, mcpId, "POST", jsonRpcBody, requesterUserId);
|
|
303
|
+
const data = (await response.json());
|
|
304
|
+
if (data === null || data === void 0 ? void 0 : data.error) {
|
|
305
|
+
logger.error("Upstream returned JSON-RPC error", {
|
|
306
|
+
mcpId,
|
|
307
|
+
error: data.error,
|
|
308
|
+
});
|
|
309
|
+
return c.json({ error: data.error.message || "Upstream error" }, 502);
|
|
310
|
+
}
|
|
311
|
+
const tools = ((_a = data === null || data === void 0 ? void 0 : data.result) === null || _a === void 0 ? void 0 : _a.tools) || [];
|
|
312
|
+
// Cache result
|
|
313
|
+
if (this.toolCache && tools.length > 0) {
|
|
314
|
+
await this.toolCache.set(mcpId, tools, agentId);
|
|
315
|
+
}
|
|
316
|
+
return c.json({ tools });
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
logger.error("Failed to list tools", { mcpId, error });
|
|
320
|
+
return c.json({
|
|
321
|
+
error: `Failed to connect to MCP '${mcpId}': ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
322
|
+
}, 502);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
async handleCallTool(c) {
|
|
326
|
+
const mcpId = c.req.param("mcpId");
|
|
327
|
+
const toolName = c.req.param("toolName");
|
|
328
|
+
if (!mcpId || !toolName) {
|
|
329
|
+
return c.json({ error: "Missing MCP server id or tool name" }, 400);
|
|
330
|
+
}
|
|
331
|
+
const auth = authenticateRequest(c);
|
|
332
|
+
if (!auth)
|
|
333
|
+
return c.json({ error: "Invalid authentication token" }, 401);
|
|
334
|
+
const agentId = auth.tokenData.agentId || auth.tokenData.userId;
|
|
335
|
+
const requesterUserId = auth.tokenData.userId;
|
|
336
|
+
if (!agentId || !requesterUserId) {
|
|
337
|
+
return c.json({ error: "Invalid authentication token" }, 401);
|
|
338
|
+
}
|
|
339
|
+
const httpServer = await this.configService.getHttpServer(mcpId, agentId);
|
|
340
|
+
if (!httpServer) {
|
|
341
|
+
return c.json({ error: `MCP server '${mcpId}' not found` }, 404);
|
|
342
|
+
}
|
|
343
|
+
// Check tool approval based on annotations and grants.
|
|
344
|
+
if (this.grantStore) {
|
|
345
|
+
const { found, annotations } = await this.getToolAnnotations(mcpId, toolName, agentId, auth.tokenData);
|
|
346
|
+
if (found && (0, approval_policy_1.requiresToolApproval)(annotations)) {
|
|
347
|
+
const pattern = `/mcp/${mcpId}/tools/${toolName}`;
|
|
348
|
+
const hasGrant = await this.grantStore.hasGrant(agentId, pattern);
|
|
349
|
+
if (!hasGrant) {
|
|
350
|
+
logger.info("Tool call blocked: requires approval", {
|
|
351
|
+
agentId,
|
|
352
|
+
mcpId,
|
|
353
|
+
toolName,
|
|
354
|
+
pattern,
|
|
355
|
+
});
|
|
356
|
+
return c.json({
|
|
357
|
+
content: [
|
|
358
|
+
{
|
|
359
|
+
type: "text",
|
|
360
|
+
text: `Tool call requires approval. Request access approval in chat for: ${mcpId} → ${toolName}`,
|
|
361
|
+
},
|
|
362
|
+
],
|
|
363
|
+
isError: true,
|
|
364
|
+
}, 403);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
let toolArguments = {};
|
|
369
|
+
try {
|
|
370
|
+
const body = await c.req.text();
|
|
371
|
+
if (body) {
|
|
372
|
+
if (body.length > MAX_BODY_SIZE) {
|
|
373
|
+
return c.json({ error: "Request body too large" }, 413);
|
|
374
|
+
}
|
|
375
|
+
toolArguments = JSON.parse(body);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
catch (_a) {
|
|
379
|
+
return c.json({ error: "Invalid JSON body" }, 400);
|
|
380
|
+
}
|
|
381
|
+
try {
|
|
382
|
+
const jsonRpcBody = JSON.stringify({
|
|
383
|
+
jsonrpc: "2.0",
|
|
384
|
+
method: "tools/call",
|
|
385
|
+
params: { name: toolName, arguments: toolArguments },
|
|
386
|
+
id: 1,
|
|
387
|
+
});
|
|
388
|
+
let response = await this.sendUpstreamRequest(httpServer, agentId, mcpId, "POST", jsonRpcBody, requesterUserId);
|
|
389
|
+
let data = (await response.json());
|
|
390
|
+
// Re-initialize session and retry on "Server not initialized"
|
|
391
|
+
if ((data === null || data === void 0 ? void 0 : data.error) && /not initialized/i.test(data.error.message || "")) {
|
|
392
|
+
logger.info("MCP session expired, re-initializing before retry", {
|
|
393
|
+
mcpId,
|
|
394
|
+
toolName,
|
|
395
|
+
});
|
|
396
|
+
await this.reinitializeSession(httpServer, agentId, mcpId, requesterUserId);
|
|
397
|
+
response = await this.sendUpstreamRequest(httpServer, agentId, mcpId, "POST", jsonRpcBody, requesterUserId);
|
|
398
|
+
data = (await response.json());
|
|
399
|
+
}
|
|
400
|
+
if (data === null || data === void 0 ? void 0 : data.error) {
|
|
401
|
+
const errorMsg = data.error.message ||
|
|
402
|
+
(typeof data.error === "string" ? data.error : "Upstream error");
|
|
403
|
+
logger.error("Upstream returned JSON-RPC error on tool call", {
|
|
404
|
+
mcpId,
|
|
405
|
+
toolName,
|
|
406
|
+
error: data.error,
|
|
407
|
+
});
|
|
408
|
+
// Detect auth errors — auto-start device-code auth flow
|
|
409
|
+
if (/unauthorized|unauthenticated|forbidden/i.test(errorMsg)) {
|
|
410
|
+
const autoAuthResult = await this.tryAutoDeviceAuth(mcpId, agentId, requesterUserId);
|
|
411
|
+
if (autoAuthResult) {
|
|
412
|
+
return c.json({
|
|
413
|
+
content: [
|
|
414
|
+
{
|
|
415
|
+
type: "text",
|
|
416
|
+
text: autoAuthResult,
|
|
417
|
+
},
|
|
418
|
+
],
|
|
419
|
+
isError: true,
|
|
420
|
+
}, 200);
|
|
421
|
+
}
|
|
422
|
+
return c.json({
|
|
423
|
+
content: [
|
|
424
|
+
{
|
|
425
|
+
type: "text",
|
|
426
|
+
text: `Authentication required for ${mcpId}. Call owletto_login to authenticate.`,
|
|
427
|
+
},
|
|
428
|
+
],
|
|
429
|
+
isError: true,
|
|
430
|
+
}, 200);
|
|
431
|
+
}
|
|
432
|
+
return c.json({
|
|
433
|
+
content: [],
|
|
434
|
+
isError: true,
|
|
435
|
+
error: errorMsg,
|
|
436
|
+
}, 502);
|
|
437
|
+
}
|
|
438
|
+
const result = (data === null || data === void 0 ? void 0 : data.result) || {};
|
|
439
|
+
return c.json({
|
|
440
|
+
content: result.content || [],
|
|
441
|
+
isError: result.isError || false,
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
logger.error("Failed to call tool", { mcpId, toolName, error });
|
|
446
|
+
return c.json({
|
|
447
|
+
content: [],
|
|
448
|
+
isError: true,
|
|
449
|
+
error: `Failed to connect to MCP '${mcpId}': ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
450
|
+
}, 502);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
async handleListAllTools(c) {
|
|
454
|
+
const auth = authenticateRequest(c);
|
|
455
|
+
if (!auth)
|
|
456
|
+
return c.json({ error: "Invalid authentication token" }, 401);
|
|
457
|
+
const agentId = auth.tokenData.agentId || auth.tokenData.userId;
|
|
458
|
+
const allHttpServers = await this.configService.getAllHttpServers(agentId);
|
|
459
|
+
const allMcpIds = Array.from(allHttpServers.keys());
|
|
460
|
+
const mcpServers = {};
|
|
461
|
+
// Fetch tools in parallel, tolerate failures
|
|
462
|
+
const results = await Promise.allSettled(allMcpIds.map(async (mcpId) => {
|
|
463
|
+
const { tools } = await this.fetchToolsForMcp(mcpId, agentId, auth.tokenData);
|
|
464
|
+
return { mcpId, tools };
|
|
465
|
+
}));
|
|
466
|
+
for (const result of results) {
|
|
467
|
+
if (result.status === "fulfilled" && result.value.tools.length > 0) {
|
|
468
|
+
mcpServers[result.value.mcpId] = { tools: result.value.tools };
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return c.json({ mcpServers });
|
|
472
|
+
}
|
|
473
|
+
async handleProxyRequest(c) {
|
|
474
|
+
const mcpId = c.req.param("mcpId") || c.req.header("x-mcp-id");
|
|
475
|
+
const sessionToken = extractSessionToken(c);
|
|
476
|
+
logger.info("Handling MCP proxy request", {
|
|
477
|
+
method: c.req.method,
|
|
478
|
+
path: c.req.path,
|
|
479
|
+
mcpId,
|
|
480
|
+
hasSessionToken: !!sessionToken,
|
|
481
|
+
});
|
|
482
|
+
if (!mcpId) {
|
|
483
|
+
return this.sendJsonRpcError(c, -32600, "Missing MCP ID");
|
|
484
|
+
}
|
|
485
|
+
if (!sessionToken) {
|
|
486
|
+
return this.sendJsonRpcError(c, -32600, "Missing authentication token");
|
|
487
|
+
}
|
|
488
|
+
const tokenData = (0, core_1.verifyWorkerToken)(sessionToken);
|
|
489
|
+
if (!tokenData) {
|
|
490
|
+
return this.sendJsonRpcError(c, -32600, "Invalid authentication token");
|
|
491
|
+
}
|
|
492
|
+
const agentId = tokenData.agentId || tokenData.userId;
|
|
493
|
+
const httpServer = await this.configService.getHttpServer(mcpId, agentId);
|
|
494
|
+
if (!httpServer) {
|
|
495
|
+
return this.sendJsonRpcError(c, -32601, `MCP server '${mcpId}' not found`);
|
|
496
|
+
}
|
|
497
|
+
try {
|
|
498
|
+
return await this.forwardRequest(c, httpServer, agentId, mcpId, tokenData.userId);
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
logger.error("Failed to proxy MCP request", { error, mcpId });
|
|
502
|
+
return this.sendJsonRpcError(c, -32603, `Failed to connect to MCP '${mcpId}': ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
async getToolAnnotations(mcpId, toolName, agentId, tokenData) {
|
|
506
|
+
let tools = null;
|
|
507
|
+
if (this.toolCache) {
|
|
508
|
+
tools = await this.toolCache.get(mcpId, agentId);
|
|
509
|
+
}
|
|
510
|
+
if (!tools) {
|
|
511
|
+
const result = await this.fetchToolsForMcp(mcpId, agentId, tokenData);
|
|
512
|
+
tools = result.tools;
|
|
513
|
+
}
|
|
514
|
+
if (tools.length === 0) {
|
|
515
|
+
return { found: false };
|
|
516
|
+
}
|
|
517
|
+
const tool = tools.find((t) => t.name === toolName);
|
|
518
|
+
return { found: true, annotations: tool === null || tool === void 0 ? void 0 : tool.annotations };
|
|
519
|
+
}
|
|
520
|
+
buildUpstreamHeaders(sessionId, configHeaders, credentialToken) {
|
|
521
|
+
const headers = {
|
|
522
|
+
"Content-Type": "application/json",
|
|
523
|
+
Accept: "application/json",
|
|
524
|
+
};
|
|
525
|
+
// Merge custom headers from server config (e.g. static auth tokens)
|
|
526
|
+
if (configHeaders) {
|
|
527
|
+
for (const [key, value] of Object.entries(configHeaders)) {
|
|
528
|
+
headers[key] = value;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
// Per-user credential takes precedence over config headers for Authorization
|
|
532
|
+
if (credentialToken) {
|
|
533
|
+
headers.Authorization = `Bearer ${credentialToken}`;
|
|
534
|
+
}
|
|
535
|
+
if (sessionId) {
|
|
536
|
+
headers["Mcp-Session-Id"] = sessionId;
|
|
537
|
+
}
|
|
538
|
+
return headers;
|
|
539
|
+
}
|
|
540
|
+
async resolveCredentialToken(agentId, userId, mcpId) {
|
|
541
|
+
var _a;
|
|
542
|
+
const credential = await (0, device_auth_1.getStoredCredential)(this.redisClient, agentId, userId, mcpId);
|
|
543
|
+
if (!credential) {
|
|
544
|
+
// No stored credential — check if there's a pending device-auth to complete
|
|
545
|
+
return (0, device_auth_1.tryCompletePendingDeviceAuth)(this.redisClient, agentId, userId, mcpId);
|
|
546
|
+
}
|
|
547
|
+
// Check if token is still valid (5 minute buffer)
|
|
548
|
+
if (credential.expiresAt > Date.now() + 5 * 60 * 1000) {
|
|
549
|
+
return credential.accessToken;
|
|
550
|
+
}
|
|
551
|
+
// Token expired or expiring soon — refresh
|
|
552
|
+
const refreshed = await (0, device_auth_1.refreshCredential)(this.redisClient, agentId, userId, mcpId, credential);
|
|
553
|
+
return (_a = refreshed === null || refreshed === void 0 ? void 0 : refreshed.accessToken) !== null && _a !== void 0 ? _a : null;
|
|
554
|
+
}
|
|
555
|
+
async sendUpstreamRequest(httpServer, agentId, mcpId, method, body, userId) {
|
|
556
|
+
const sessionKey = `mcp:session:${agentId}:${mcpId}`;
|
|
557
|
+
const sessionId = await this.getSession(sessionKey);
|
|
558
|
+
// Look up per-user credential for this MCP
|
|
559
|
+
let credentialToken;
|
|
560
|
+
if (userId) {
|
|
561
|
+
const token = await this.resolveCredentialToken(agentId, userId, mcpId);
|
|
562
|
+
if (token)
|
|
563
|
+
credentialToken = token;
|
|
564
|
+
}
|
|
565
|
+
// SSRF protection: block requests to internal networks
|
|
566
|
+
if (await isInternalUrl(httpServer.upstreamUrl)) {
|
|
567
|
+
logger.warn("Blocked SSRF attempt to internal URL", {
|
|
568
|
+
url: httpServer.upstreamUrl,
|
|
569
|
+
mcpId,
|
|
570
|
+
agentId,
|
|
571
|
+
});
|
|
572
|
+
return new Response(JSON.stringify({
|
|
573
|
+
jsonrpc: "2.0",
|
|
574
|
+
id: null,
|
|
575
|
+
error: {
|
|
576
|
+
code: -32600,
|
|
577
|
+
message: "Upstream URL resolves to a blocked internal network",
|
|
578
|
+
},
|
|
579
|
+
}), { status: 403, headers: { "Content-Type": "application/json" } });
|
|
580
|
+
}
|
|
581
|
+
const headers = this.buildUpstreamHeaders(sessionId, httpServer.headers, credentialToken);
|
|
582
|
+
const response = await fetch(httpServer.upstreamUrl, {
|
|
583
|
+
method,
|
|
584
|
+
headers,
|
|
585
|
+
body: body || undefined,
|
|
586
|
+
});
|
|
587
|
+
// Track session
|
|
588
|
+
const newSessionId = response.headers.get("Mcp-Session-Id");
|
|
589
|
+
if (newSessionId) {
|
|
590
|
+
await this.setSession(sessionKey, newSessionId);
|
|
591
|
+
}
|
|
592
|
+
return response;
|
|
593
|
+
}
|
|
594
|
+
async forwardRequest(c, httpServer, agentId, mcpId, userId) {
|
|
595
|
+
// SSRF protection: block requests to internal networks
|
|
596
|
+
if (await isInternalUrl(httpServer.upstreamUrl)) {
|
|
597
|
+
logger.warn("Blocked SSRF attempt to internal URL", {
|
|
598
|
+
url: httpServer.upstreamUrl,
|
|
599
|
+
mcpId,
|
|
600
|
+
agentId,
|
|
601
|
+
});
|
|
602
|
+
return this.sendJsonRpcError(c, -32600, "Upstream URL resolves to a blocked internal network");
|
|
603
|
+
}
|
|
604
|
+
const sessionKey = `mcp:session:${agentId}:${mcpId}`;
|
|
605
|
+
let sessionId = await this.getSession(sessionKey);
|
|
606
|
+
const bodyText = await this.getRequestBodyAsText(c);
|
|
607
|
+
// Body size validation
|
|
608
|
+
if (bodyText.length > MAX_BODY_SIZE) {
|
|
609
|
+
logger.warn("Request body too large", {
|
|
610
|
+
mcpId,
|
|
611
|
+
agentId,
|
|
612
|
+
size: bodyText.length,
|
|
613
|
+
});
|
|
614
|
+
return new Response("Request body too large", { status: 413 });
|
|
615
|
+
}
|
|
616
|
+
// If no active session exists, re-initialize before forwarding
|
|
617
|
+
if (!sessionId && c.req.method === "POST") {
|
|
618
|
+
try {
|
|
619
|
+
await this.reinitializeSession(httpServer, agentId, mcpId, userId);
|
|
620
|
+
sessionId = await this.getSession(sessionKey);
|
|
621
|
+
}
|
|
622
|
+
catch (error) {
|
|
623
|
+
logger.warn("Pre-emptive MCP re-initialization failed", {
|
|
624
|
+
mcpId,
|
|
625
|
+
error: error instanceof Error ? error.message : String(error),
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
logger.info("Proxying MCP request", {
|
|
630
|
+
mcpId,
|
|
631
|
+
agentId,
|
|
632
|
+
method: c.req.method,
|
|
633
|
+
hasSession: !!sessionId,
|
|
634
|
+
bodyLength: bodyText.length,
|
|
635
|
+
});
|
|
636
|
+
// Look up per-user credential for this MCP
|
|
637
|
+
let credentialToken;
|
|
638
|
+
if (userId) {
|
|
639
|
+
const token = await this.resolveCredentialToken(agentId, userId, mcpId);
|
|
640
|
+
if (token)
|
|
641
|
+
credentialToken = token;
|
|
642
|
+
}
|
|
643
|
+
const headers = this.buildUpstreamHeaders(sessionId, httpServer.headers, credentialToken);
|
|
644
|
+
const response = await fetch(httpServer.upstreamUrl, {
|
|
645
|
+
method: c.req.method,
|
|
646
|
+
headers,
|
|
647
|
+
body: bodyText || undefined,
|
|
648
|
+
});
|
|
649
|
+
const newSessionId = response.headers.get("Mcp-Session-Id");
|
|
650
|
+
if (newSessionId) {
|
|
651
|
+
await this.setSession(sessionKey, newSessionId);
|
|
652
|
+
logger.debug("Stored MCP session ID", {
|
|
653
|
+
mcpId,
|
|
654
|
+
agentId,
|
|
655
|
+
sessionId: newSessionId,
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
const responseHeaders = new Headers();
|
|
659
|
+
const contentType = response.headers.get("content-type");
|
|
660
|
+
if (contentType) {
|
|
661
|
+
responseHeaders.set("Content-Type", contentType);
|
|
662
|
+
}
|
|
663
|
+
if (newSessionId) {
|
|
664
|
+
responseHeaders.set("Mcp-Session-Id", newSessionId);
|
|
665
|
+
}
|
|
666
|
+
return new Response(response.body, {
|
|
667
|
+
status: response.status,
|
|
668
|
+
headers: responseHeaders,
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
async getRequestBodyAsText(c) {
|
|
672
|
+
if (c.req.method === "GET" || c.req.method === "HEAD") {
|
|
673
|
+
return "";
|
|
674
|
+
}
|
|
675
|
+
try {
|
|
676
|
+
return await c.req.text();
|
|
677
|
+
}
|
|
678
|
+
catch (_a) {
|
|
679
|
+
return "";
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Re-initialize an MCP session by sending initialize + notifications/initialized.
|
|
684
|
+
* Called when upstream returns "Server not initialized" (stale session).
|
|
685
|
+
*/
|
|
686
|
+
async reinitializeSession(httpServer, agentId, mcpId, userId) {
|
|
687
|
+
// Clear stale session
|
|
688
|
+
const sessionKey = `mcp:session:${agentId}:${mcpId}`;
|
|
689
|
+
await this.redisClient.del(sessionKey).catch(() => {
|
|
690
|
+
/* noop */
|
|
691
|
+
});
|
|
692
|
+
// Send initialize
|
|
693
|
+
const initBody = JSON.stringify({
|
|
694
|
+
jsonrpc: "2.0",
|
|
695
|
+
method: "initialize",
|
|
696
|
+
params: {
|
|
697
|
+
protocolVersion: "2024-11-05",
|
|
698
|
+
capabilities: {},
|
|
699
|
+
clientInfo: { name: "lobu-gateway", version: "1.0.0" },
|
|
700
|
+
},
|
|
701
|
+
id: 0,
|
|
702
|
+
});
|
|
703
|
+
const initResponse = await this.sendUpstreamRequest(httpServer, agentId, mcpId, "POST", initBody, userId);
|
|
704
|
+
await initResponse.json(); // consume response
|
|
705
|
+
// Send notifications/initialized
|
|
706
|
+
const notifyBody = JSON.stringify({
|
|
707
|
+
jsonrpc: "2.0",
|
|
708
|
+
method: "notifications/initialized",
|
|
709
|
+
});
|
|
710
|
+
await this.sendUpstreamRequest(httpServer, agentId, mcpId, "POST", notifyBody, userId).catch(() => {
|
|
711
|
+
/* noop */
|
|
712
|
+
});
|
|
713
|
+
logger.info("Re-initialized MCP session", { mcpId, agentId });
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* Auto-start device-code auth when an MCP upstream returns an auth error.
|
|
717
|
+
* Returns a user-facing message with the verification URL, or null on failure.
|
|
718
|
+
*/
|
|
719
|
+
async tryAutoDeviceAuth(mcpId, agentId, userId) {
|
|
720
|
+
try {
|
|
721
|
+
const { startDeviceAuth } = await Promise.resolve().then(() => __importStar(require("../../routes/internal/device-auth")));
|
|
722
|
+
// Check if a device auth flow is already pending (avoid duplicate starts)
|
|
723
|
+
const pendingKey = `device-auth:${agentId}:${userId}:${mcpId}`;
|
|
724
|
+
const pending = await this.redisClient.get(pendingKey);
|
|
725
|
+
if (pending) {
|
|
726
|
+
// Return the existing pending flow's info instead of starting a new one
|
|
727
|
+
return JSON.stringify({
|
|
728
|
+
status: "login_required",
|
|
729
|
+
message: "Authentication is required. A login flow is already in progress. STOP calling tools and tell the user to complete login in their browser. Do NOT retry this tool call.",
|
|
730
|
+
note: "Do NOT call any owletto tools until the user completes login.",
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
const result = await startDeviceAuth(this.redisClient, this.configService, mcpId, agentId, userId);
|
|
734
|
+
if (!result)
|
|
735
|
+
return null;
|
|
736
|
+
const url = result.verificationUriComplete || result.verificationUri;
|
|
737
|
+
return JSON.stringify({
|
|
738
|
+
status: "login_required",
|
|
739
|
+
message: "Authentication is required. STOP calling tools and show the user this login link and code. Do NOT retry this tool call — wait for the user to complete login first.",
|
|
740
|
+
verification_url: url,
|
|
741
|
+
user_code: result.userCode,
|
|
742
|
+
expires_in_seconds: result.expiresIn,
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
catch (error) {
|
|
746
|
+
logger.warn("Auto device-auth failed", {
|
|
747
|
+
mcpId,
|
|
748
|
+
error: error instanceof Error ? error.message : String(error),
|
|
749
|
+
});
|
|
750
|
+
return null;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
async getSession(key) {
|
|
754
|
+
try {
|
|
755
|
+
const sessionId = await this.redisClient.get(key);
|
|
756
|
+
if (sessionId) {
|
|
757
|
+
await this.redisClient.expire(key, this.SESSION_TTL_SECONDS);
|
|
758
|
+
}
|
|
759
|
+
return sessionId;
|
|
760
|
+
}
|
|
761
|
+
catch (error) {
|
|
762
|
+
logger.error("Failed to get MCP session from Redis", { key, error });
|
|
763
|
+
return null;
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
async setSession(key, sessionId) {
|
|
767
|
+
try {
|
|
768
|
+
await this.redisClient.set(key, sessionId, "EX", this.SESSION_TTL_SECONDS);
|
|
769
|
+
}
|
|
770
|
+
catch (error) {
|
|
771
|
+
logger.error("Failed to store MCP session in Redis", { key, error });
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
sendJsonRpcError(c, code, message, id = null) {
|
|
775
|
+
return c.json({
|
|
776
|
+
jsonrpc: "2.0",
|
|
777
|
+
id,
|
|
778
|
+
error: { code, message },
|
|
779
|
+
}, 200);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
exports.McpProxy = McpProxy;
|
|
783
|
+
//# sourceMappingURL=proxy.js.map
|