@structured-world/gitlab-mcp 6.62.1 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -1
- package/README.md.in +21 -0
- package/dist/generated/prisma/client.js.map +1 -1
- package/dist/generated/prisma/internal/class.js +2 -2
- package/dist/generated/prisma/internal/class.js.map +1 -1
- package/dist/generated/prisma/internal/prismaNamespace.js +2 -2
- package/dist/generated/prisma/models/AuthCodeFlowState.d.ts +1 -2
- package/dist/generated/prisma/models/AuthorizationCode.d.ts +1 -2
- package/dist/generated/prisma/models/DeviceFlowState.d.ts +1 -2
- package/dist/generated/prisma/models/McpSessionMapping.d.ts +1 -2
- package/dist/generated/prisma/models/OAuthSession.d.ts +1 -2
- package/dist/src/cli/docker/container-runtime.d.ts +1 -1
- package/dist/src/cli/docker/container-runtime.js +14 -14
- package/dist/src/cli/docker/docker-command.d.ts +1 -1
- package/dist/src/cli/docker/docker-command.js +113 -113
- package/dist/src/cli/docker/docker-command.js.map +1 -1
- package/dist/src/cli/docker/docker-utils.d.ts +3 -3
- package/dist/src/cli/docker/docker-utils.js +74 -74
- package/dist/src/cli/docker/docker-utils.js.map +1 -1
- package/dist/src/cli/docker/index.d.ts +4 -4
- package/dist/src/cli/docker/types.d.ts +3 -3
- package/dist/src/cli/docker/types.js +5 -5
- package/dist/src/cli/init/browser.js +2 -2
- package/dist/src/cli/init/config-generator.d.ts +2 -2
- package/dist/src/cli/init/config-generator.js +22 -22
- package/dist/src/cli/init/connection.d.ts +1 -1
- package/dist/src/cli/init/connection.js +27 -27
- package/dist/src/cli/init/connection.js.map +1 -1
- package/dist/src/cli/init/index.d.ts +4 -4
- package/dist/src/cli/init/types.d.ts +3 -3
- package/dist/src/cli/init/types.js +36 -36
- package/dist/src/cli/init/wizard.js +80 -80
- package/dist/src/cli/init/wizard.js.map +1 -1
- package/dist/src/cli/inject-tool-refs.js +47 -47
- package/dist/src/cli/inject-tool-refs.js.map +1 -1
- package/dist/src/cli/install/backup.d.ts +1 -1
- package/dist/src/cli/install/backup.js +3 -3
- package/dist/src/cli/install/detector.d.ts +2 -2
- package/dist/src/cli/install/detector.js +18 -18
- package/dist/src/cli/install/detector.js.map +1 -1
- package/dist/src/cli/install/index.d.ts +5 -5
- package/dist/src/cli/install/install-command.d.ts +2 -2
- package/dist/src/cli/install/install-command.js +68 -68
- package/dist/src/cli/install/install-command.js.map +1 -1
- package/dist/src/cli/install/installers.d.ts +2 -2
- package/dist/src/cli/install/installers.js +55 -55
- package/dist/src/cli/install/installers.js.map +1 -1
- package/dist/src/cli/install/types.d.ts +4 -4
- package/dist/src/cli/install/types.js +48 -48
- package/dist/src/cli/instances/index.d.ts +2 -2
- package/dist/src/cli/instances/instances-command.d.ts +1 -1
- package/dist/src/cli/instances/instances-command.js +70 -66
- package/dist/src/cli/instances/instances-command.js.map +1 -1
- package/dist/src/cli/list-tools.js +396 -396
- package/dist/src/cli/list-tools.js.map +1 -1
- package/dist/src/cli/setup/discovery.d.ts +1 -1
- package/dist/src/cli/setup/discovery.js +10 -10
- package/dist/src/cli/setup/discovery.js.map +1 -1
- package/dist/src/cli/setup/flows/configure-existing.d.ts +1 -1
- package/dist/src/cli/setup/flows/configure-existing.js +57 -57
- package/dist/src/cli/setup/flows/configure-existing.js.map +1 -1
- package/dist/src/cli/setup/flows/local-setup.d.ts +1 -1
- package/dist/src/cli/setup/flows/local-setup.js +51 -51
- package/dist/src/cli/setup/flows/local-setup.js.map +1 -1
- package/dist/src/cli/setup/flows/server-setup.d.ts +1 -1
- package/dist/src/cli/setup/flows/server-setup.js +50 -50
- package/dist/src/cli/setup/flows/server-setup.js.map +1 -1
- package/dist/src/cli/setup/flows/tool-selection.d.ts +1 -1
- package/dist/src/cli/setup/flows/tool-selection.js +94 -94
- package/dist/src/cli/setup/flows/tool-selection.js.map +1 -1
- package/dist/src/cli/setup/index.d.ts +4 -4
- package/dist/src/cli/setup/presets.d.ts +1 -1
- package/dist/src/cli/setup/presets.js +157 -157
- package/dist/src/cli/setup/presets.js.map +1 -1
- package/dist/src/cli/setup/types.d.ts +7 -7
- package/dist/src/cli/setup/wizard.d.ts +1 -1
- package/dist/src/cli/setup/wizard.js +25 -25
- package/dist/src/cli/utils/index.d.ts +1 -1
- package/dist/src/cli/utils/path-utils.js +3 -3
- package/dist/src/cli-utils.d.ts +2 -2
- package/dist/src/cli-utils.js +46 -46
- package/dist/src/config/index.d.ts +4 -4
- package/dist/src/config/instances-loader.d.ts +3 -3
- package/dist/src/config/instances-loader.js +53 -53
- package/dist/src/config/instances-loader.js.map +1 -1
- package/dist/src/config/instances-schema.d.ts +1 -1
- package/dist/src/config/instances-schema.js +33 -33
- package/dist/src/config/instances-schema.js.map +1 -1
- package/dist/src/config.d.ts +11 -4
- package/dist/src/config.js +112 -111
- package/dist/src/config.js.map +1 -1
- package/dist/src/dashboard/handler.d.ts +2 -2
- package/dist/src/dashboard/handler.js +7 -7
- package/dist/src/dashboard/html-template.d.ts +1 -1
- package/dist/src/dashboard/html-template.js +44 -44
- package/dist/src/dashboard/html-template.js.map +1 -1
- package/dist/src/dashboard/index.d.ts +4 -4
- package/dist/src/dashboard/metrics.d.ts +3 -3
- package/dist/src/dashboard/metrics.js +42 -42
- package/dist/src/discovery/auto.d.ts +3 -3
- package/dist/src/discovery/auto.js +28 -28
- package/dist/src/discovery/git-remote.d.ts +2 -2
- package/dist/src/discovery/git-remote.js +18 -18
- package/dist/src/discovery/index.d.ts +3 -3
- package/dist/src/discovery/profile-matcher.d.ts +2 -2
- package/dist/src/discovery/profile-matcher.js +8 -8
- package/dist/src/discovery/profile-matcher.js.map +1 -1
- package/dist/src/entities/context/context-manager.d.ts +3 -3
- package/dist/src/entities/context/context-manager.js +34 -34
- package/dist/src/entities/context/context-manager.js.map +1 -1
- package/dist/src/entities/context/handlers.d.ts +2 -2
- package/dist/src/entities/context/handlers.js +8 -8
- package/dist/src/entities/context/index.d.ts +8 -8
- package/dist/src/entities/context/index.js +1 -1
- package/dist/src/entities/context/registry.d.ts +1 -1
- package/dist/src/entities/context/registry.js +4 -4
- package/dist/src/entities/context/schema.d.ts +1 -1
- package/dist/src/entities/context/schema.js +19 -19
- package/dist/src/entities/context/types.d.ts +9 -9
- package/dist/src/entities/context/whoami.d.ts +1 -1
- package/dist/src/entities/context/whoami.js +31 -31
- package/dist/src/entities/context/whoami.js.map +1 -1
- package/dist/src/entities/core/index.d.ts +5 -5
- package/dist/src/entities/core/index.js +1 -1
- package/dist/src/entities/core/registry.d.ts +1 -1
- package/dist/src/entities/core/registry.js +194 -194
- package/dist/src/entities/core/registry.js.map +1 -1
- package/dist/src/entities/core/schema-readonly.d.ts +1 -1
- package/dist/src/entities/core/schema-readonly.js +117 -117
- package/dist/src/entities/core/schema.d.ts +1 -1
- package/dist/src/entities/core/schema.js +67 -67
- package/dist/src/entities/files/index.d.ts +5 -5
- package/dist/src/entities/files/index.js +1 -1
- package/dist/src/entities/files/registry.d.ts +1 -1
- package/dist/src/entities/files/registry.js +45 -45
- package/dist/src/entities/files/registry.js.map +1 -1
- package/dist/src/entities/files/schema-readonly.d.ts +1 -1
- package/dist/src/entities/files/schema-readonly.js +13 -13
- package/dist/src/entities/files/schema.d.ts +1 -1
- package/dist/src/entities/files/schema.js +29 -29
- package/dist/src/entities/index.d.ts +17 -17
- package/dist/src/entities/integrations/index.d.ts +4 -4
- package/dist/src/entities/integrations/registry.d.ts +1 -1
- package/dist/src/entities/integrations/registry.js +17 -17
- package/dist/src/entities/integrations/registry.js.map +1 -1
- package/dist/src/entities/integrations/schema-readonly.d.ts +1 -1
- package/dist/src/entities/integrations/schema-readonly.js +5 -5
- package/dist/src/entities/integrations/schema.d.ts +1 -1
- package/dist/src/entities/integrations/schema.js +69 -69
- package/dist/src/entities/iterations/index.d.ts +2 -2
- package/dist/src/entities/iterations/registry.d.ts +1 -1
- package/dist/src/entities/iterations/registry.js +13 -13
- package/dist/src/entities/iterations/registry.js.map +1 -1
- package/dist/src/entities/iterations/schema-readonly.d.ts +1 -1
- package/dist/src/entities/iterations/schema-readonly.js +9 -9
- package/dist/src/entities/labels/index.d.ts +5 -5
- package/dist/src/entities/labels/index.js +1 -1
- package/dist/src/entities/labels/registry.d.ts +1 -1
- package/dist/src/entities/labels/registry.js +19 -19
- package/dist/src/entities/labels/registry.js.map +1 -1
- package/dist/src/entities/labels/schema-readonly.d.ts +1 -1
- package/dist/src/entities/labels/schema-readonly.js +8 -8
- package/dist/src/entities/labels/schema.d.ts +1 -1
- package/dist/src/entities/labels/schema.js +11 -11
- package/dist/src/entities/members/index.d.ts +3 -3
- package/dist/src/entities/members/registry.d.ts +1 -1
- package/dist/src/entities/members/registry.js +26 -26
- package/dist/src/entities/members/registry.js.map +1 -1
- package/dist/src/entities/members/schema-readonly.d.ts +1 -1
- package/dist/src/entities/members/schema-readonly.js +32 -32
- package/dist/src/entities/members/schema-readonly.js.map +1 -1
- package/dist/src/entities/members/schema.d.ts +1 -1
- package/dist/src/entities/members/schema.js +28 -28
- package/dist/src/entities/milestones/index.d.ts +5 -5
- package/dist/src/entities/milestones/index.js +1 -1
- package/dist/src/entities/milestones/registry.d.ts +1 -1
- package/dist/src/entities/milestones/registry.js +25 -25
- package/dist/src/entities/milestones/registry.js.map +1 -1
- package/dist/src/entities/milestones/schema-readonly.d.ts +2 -2
- package/dist/src/entities/milestones/schema-readonly.js +15 -15
- package/dist/src/entities/milestones/schema.d.ts +1 -1
- package/dist/src/entities/milestones/schema.js +16 -16
- package/dist/src/entities/milestones/schema.js.map +1 -1
- package/dist/src/entities/mrs/index.d.ts +5 -5
- package/dist/src/entities/mrs/index.js +1 -1
- package/dist/src/entities/mrs/registry.d.ts +1 -1
- package/dist/src/entities/mrs/registry.js +102 -102
- package/dist/src/entities/mrs/registry.js.map +1 -1
- package/dist/src/entities/mrs/schema-readonly.d.ts +1 -1
- package/dist/src/entities/mrs/schema-readonly.js +126 -126
- package/dist/src/entities/mrs/schema-readonly.js.map +1 -1
- package/dist/src/entities/mrs/schema.d.ts +1 -1
- package/dist/src/entities/mrs/schema.js +111 -111
- package/dist/src/entities/mrs/schema.js.map +1 -1
- package/dist/src/entities/pipelines/index.d.ts +5 -5
- package/dist/src/entities/pipelines/index.js +1 -1
- package/dist/src/entities/pipelines/registry.d.ts +1 -1
- package/dist/src/entities/pipelines/registry.js +45 -45
- package/dist/src/entities/pipelines/registry.js.map +1 -1
- package/dist/src/entities/pipelines/schema-readonly.d.ts +2 -2
- package/dist/src/entities/pipelines/schema-readonly.js +73 -73
- package/dist/src/entities/pipelines/schema.d.ts +1 -1
- package/dist/src/entities/pipelines/schema.js +21 -21
- package/dist/src/entities/refs/index.d.ts +3 -3
- package/dist/src/entities/refs/registry.d.ts +1 -1
- package/dist/src/entities/refs/registry.js +31 -31
- package/dist/src/entities/refs/registry.js.map +1 -1
- package/dist/src/entities/refs/schema-readonly.d.ts +1 -1
- package/dist/src/entities/refs/schema-readonly.js +21 -21
- package/dist/src/entities/refs/schema.d.ts +1 -1
- package/dist/src/entities/refs/schema.js +56 -56
- package/dist/src/entities/releases/index.d.ts +3 -3
- package/dist/src/entities/releases/registry.d.ts +1 -1
- package/dist/src/entities/releases/registry.js +21 -21
- package/dist/src/entities/releases/registry.js.map +1 -1
- package/dist/src/entities/releases/schema-readonly.d.ts +1 -1
- package/dist/src/entities/releases/schema-readonly.js +13 -13
- package/dist/src/entities/releases/schema.d.ts +1 -1
- package/dist/src/entities/releases/schema.js +21 -21
- package/dist/src/entities/search/index.d.ts +2 -2
- package/dist/src/entities/search/registry.d.ts +1 -1
- package/dist/src/entities/search/registry.js +13 -13
- package/dist/src/entities/search/schema-readonly.d.ts +1 -1
- package/dist/src/entities/search/schema-readonly.js +23 -23
- package/dist/src/entities/shared.d.ts +1 -1
- package/dist/src/entities/shared.js +5 -5
- package/dist/src/entities/snippets/index.d.ts +5 -5
- package/dist/src/entities/snippets/index.js +1 -1
- package/dist/src/entities/snippets/registry.d.ts +1 -1
- package/dist/src/entities/snippets/registry.js +24 -24
- package/dist/src/entities/snippets/registry.js.map +1 -1
- package/dist/src/entities/snippets/schema-readonly.d.ts +1 -1
- package/dist/src/entities/snippets/schema-readonly.js +11 -11
- package/dist/src/entities/snippets/schema.d.ts +1 -1
- package/dist/src/entities/snippets/schema.js +27 -27
- package/dist/src/entities/snippets/schema.js.map +1 -1
- package/dist/src/entities/utils.d.ts +2 -2
- package/dist/src/entities/utils.js +8 -8
- package/dist/src/entities/utils.js.map +1 -1
- package/dist/src/entities/variables/index.d.ts +5 -5
- package/dist/src/entities/variables/index.js +1 -1
- package/dist/src/entities/variables/registry.d.ts +1 -1
- package/dist/src/entities/variables/registry.js +22 -22
- package/dist/src/entities/variables/registry.js.map +1 -1
- package/dist/src/entities/variables/schema-readonly.d.ts +1 -1
- package/dist/src/entities/variables/schema-readonly.js +6 -6
- package/dist/src/entities/variables/schema.d.ts +1 -1
- package/dist/src/entities/variables/schema.js +21 -21
- package/dist/src/entities/variables/schema.js.map +1 -1
- package/dist/src/entities/webhooks/index.d.ts +4 -4
- package/dist/src/entities/webhooks/registry.d.ts +1 -1
- package/dist/src/entities/webhooks/registry.js +29 -29
- package/dist/src/entities/webhooks/registry.js.map +1 -1
- package/dist/src/entities/webhooks/schema-readonly.d.ts +1 -1
- package/dist/src/entities/webhooks/schema-readonly.js +9 -9
- package/dist/src/entities/webhooks/schema.d.ts +1 -1
- package/dist/src/entities/webhooks/schema.js +59 -59
- package/dist/src/entities/wiki/index.d.ts +5 -5
- package/dist/src/entities/wiki/index.js +1 -1
- package/dist/src/entities/wiki/registry.d.ts +1 -1
- package/dist/src/entities/wiki/registry.js +19 -19
- package/dist/src/entities/wiki/registry.js.map +1 -1
- package/dist/src/entities/wiki/schema-readonly.d.ts +1 -1
- package/dist/src/entities/wiki/schema-readonly.js +6 -6
- package/dist/src/entities/wiki/schema.d.ts +1 -1
- package/dist/src/entities/wiki/schema.js +12 -12
- package/dist/src/entities/workitems/index.d.ts +5 -5
- package/dist/src/entities/workitems/index.js +1 -1
- package/dist/src/entities/workitems/registry.d.ts +1 -1
- package/dist/src/entities/workitems/registry.js +101 -101
- package/dist/src/entities/workitems/registry.js.map +1 -1
- package/dist/src/entities/workitems/schema-readonly.d.ts +1 -1
- package/dist/src/entities/workitems/schema-readonly.js +27 -27
- package/dist/src/entities/workitems/schema-readonly.js.map +1 -1
- package/dist/src/entities/workitems/schema.d.ts +1 -1
- package/dist/src/entities/workitems/schema.js +58 -58
- package/dist/src/graphql/DynamicWorkItemsQuery.d.ts +2 -2
- package/dist/src/graphql/DynamicWorkItemsQuery.js +47 -47
- package/dist/src/graphql/DynamicWorkItemsQuery.js.map +1 -1
- package/dist/src/graphql/client.d.ts +1 -1
- package/dist/src/graphql/client.js +4 -4
- package/dist/src/graphql/client.js.map +1 -1
- package/dist/src/graphql/index.d.ts +2 -2
- package/dist/src/graphql/workItems.d.ts +38 -38
- package/dist/src/graphql/workItems.js +30 -30
- package/dist/src/handlers.d.ts +2 -1
- package/dist/src/handlers.js +258 -86
- package/dist/src/handlers.js.map +1 -1
- package/dist/src/http-client.js +3 -3
- package/dist/src/logger.js +25 -25
- package/dist/src/logging/access-log.d.ts +2 -2
- package/dist/src/logging/access-log.js +25 -25
- package/dist/src/logging/connection-tracker.d.ts +1 -1
- package/dist/src/logging/connection-tracker.js +3 -3
- package/dist/src/logging/index.d.ts +5 -5
- package/dist/src/logging/request-tracker.d.ts +3 -3
- package/dist/src/logging/request-tracker.js +4 -4
- package/dist/src/logging/types.d.ts +3 -3
- package/dist/src/logging/types.js +1 -1
- package/dist/src/logging/types.js.map +1 -1
- package/dist/src/main.js +28 -28
- package/dist/src/middleware/index.d.ts +3 -2
- package/dist/src/middleware/index.js +3 -1
- package/dist/src/middleware/index.js.map +1 -1
- package/dist/src/middleware/oauth-auth.d.ts +1 -1
- package/dist/src/middleware/oauth-auth.js +17 -17
- package/dist/src/middleware/rate-limiter.d.ts +1 -1
- package/dist/src/middleware/rate-limiter.js +32 -32
- package/dist/src/middleware/response-write-timeout.d.ts +2 -0
- package/dist/src/middleware/response-write-timeout.js +62 -0
- package/dist/src/middleware/response-write-timeout.js.map +1 -0
- package/dist/src/oauth/config.d.ts +1 -1
- package/dist/src/oauth/config.js +18 -18
- package/dist/src/oauth/config.js.map +1 -1
- package/dist/src/oauth/endpoints/authorize.d.ts +1 -1
- package/dist/src/oauth/endpoints/authorize.js +32 -32
- package/dist/src/oauth/endpoints/callback.d.ts +1 -1
- package/dist/src/oauth/endpoints/callback.js +26 -26
- package/dist/src/oauth/endpoints/index.d.ts +5 -5
- package/dist/src/oauth/endpoints/metadata.d.ts +1 -1
- package/dist/src/oauth/endpoints/metadata.js +12 -12
- package/dist/src/oauth/endpoints/register.d.ts +1 -1
- package/dist/src/oauth/endpoints/register.js +9 -9
- package/dist/src/oauth/endpoints/token.d.ts +1 -1
- package/dist/src/oauth/endpoints/token.js +28 -28
- package/dist/src/oauth/gitlab-device-flow.d.ts +2 -2
- package/dist/src/oauth/gitlab-device-flow.js +73 -68
- package/dist/src/oauth/gitlab-device-flow.js.map +1 -1
- package/dist/src/oauth/index.d.ts +10 -10
- package/dist/src/oauth/session-store.d.ts +2 -2
- package/dist/src/oauth/session-store.js +40 -40
- package/dist/src/oauth/session-store.js.map +1 -1
- package/dist/src/oauth/storage/factory.d.ts +2 -2
- package/dist/src/oauth/storage/factory.js +16 -16
- package/dist/src/oauth/storage/file.d.ts +2 -2
- package/dist/src/oauth/storage/file.js +22 -22
- package/dist/src/oauth/storage/file.js.map +1 -1
- package/dist/src/oauth/storage/index.d.ts +5 -5
- package/dist/src/oauth/storage/memory.d.ts +2 -2
- package/dist/src/oauth/storage/memory.js +18 -18
- package/dist/src/oauth/storage/memory.js.map +1 -1
- package/dist/src/oauth/storage/postgresql.d.ts +2 -2
- package/dist/src/oauth/storage/postgresql.js +11 -11
- package/dist/src/oauth/storage/postgresql.js.map +1 -1
- package/dist/src/oauth/storage/types.d.ts +3 -3
- package/dist/src/oauth/token-context.d.ts +1 -1
- package/dist/src/oauth/token-context.js +1 -1
- package/dist/src/oauth/token-utils.d.ts +1 -1
- package/dist/src/oauth/token-utils.js +20 -20
- package/dist/src/oauth/types.d.ts +3 -3
- package/dist/src/profiles/applicator.d.ts +1 -1
- package/dist/src/profiles/applicator.js +48 -48
- package/dist/src/profiles/index.d.ts +5 -5
- package/dist/src/profiles/loader.d.ts +3 -3
- package/dist/src/profiles/loader.js +25 -25
- package/dist/src/profiles/loader.js.map +1 -1
- package/dist/src/profiles/project-loader.d.ts +1 -1
- package/dist/src/profiles/project-loader.js +23 -23
- package/dist/src/profiles/project-loader.js.map +1 -1
- package/dist/src/profiles/scope-enforcer.d.ts +2 -2
- package/dist/src/profiles/scope-enforcer.js +25 -25
- package/dist/src/profiles/scope-enforcer.js.map +1 -1
- package/dist/src/profiles/types.d.ts +2 -2
- package/dist/src/profiles/types.js +50 -48
- package/dist/src/profiles/types.js.map +1 -1
- package/dist/src/registry-manager.d.ts +19 -11
- package/dist/src/registry-manager.js +257 -172
- package/dist/src/registry-manager.js.map +1 -1
- package/dist/src/server.js +165 -149
- package/dist/src/server.js.map +1 -1
- package/dist/src/services/ConnectionManager.d.ts +33 -24
- package/dist/src/services/ConnectionManager.js +304 -179
- package/dist/src/services/ConnectionManager.js.map +1 -1
- package/dist/src/services/GitLabVersionDetector.d.ts +2 -2
- package/dist/src/services/GitLabVersionDetector.js +45 -45
- package/dist/src/services/GitLabVersionDetector.js.map +1 -1
- package/dist/src/services/HealthMonitor.d.ts +42 -0
- package/dist/src/services/HealthMonitor.js +544 -0
- package/dist/src/services/HealthMonitor.js.map +1 -0
- package/dist/src/services/InstanceConnectionPool.d.ts +2 -2
- package/dist/src/services/InstanceConnectionPool.js +13 -13
- package/dist/src/services/InstanceConnectionPool.js.map +1 -1
- package/dist/src/services/InstanceRateLimiter.js +6 -6
- package/dist/src/services/InstanceRateLimiter.js.map +1 -1
- package/dist/src/services/InstanceRegistry.d.ts +4 -5
- package/dist/src/services/InstanceRegistry.js +29 -41
- package/dist/src/services/InstanceRegistry.js.map +1 -1
- package/dist/src/services/NamespaceTierDetector.d.ts +2 -2
- package/dist/src/services/NamespaceTierDetector.js +30 -30
- package/dist/src/services/NamespaceTierDetector.js.map +1 -1
- package/dist/src/services/SchemaIntrospector.d.ts +2 -1
- package/dist/src/services/SchemaIntrospector.js +45 -42
- package/dist/src/services/SchemaIntrospector.js.map +1 -1
- package/dist/src/services/TokenScopeDetector.d.ts +4 -4
- package/dist/src/services/TokenScopeDetector.js +133 -110
- package/dist/src/services/TokenScopeDetector.js.map +1 -1
- package/dist/src/services/ToolAvailability.d.ts +15 -11
- package/dist/src/services/ToolAvailability.js +150 -130
- package/dist/src/services/ToolAvailability.js.map +1 -1
- package/dist/src/services/WidgetAvailability.d.ts +5 -5
- package/dist/src/services/WidgetAvailability.js +40 -39
- package/dist/src/services/WidgetAvailability.js.map +1 -1
- package/dist/src/session-manager.d.ts +3 -2
- package/dist/src/session-manager.js +17 -14
- package/dist/src/session-manager.js.map +1 -1
- package/dist/src/types.js +4 -4
- package/dist/src/utils/description-utils.js +4 -4
- package/dist/src/utils/description-utils.js.map +1 -1
- package/dist/src/utils/error-handler.d.ts +19 -10
- package/dist/src/utils/error-handler.js +272 -187
- package/dist/src/utils/error-handler.js.map +1 -1
- package/dist/src/utils/fetch.d.ts +7 -0
- package/dist/src/utils/fetch.js +136 -122
- package/dist/src/utils/fetch.js.map +1 -1
- package/dist/src/utils/gitlab-api.d.ts +1 -1
- package/dist/src/utils/gitlab-api.js +29 -26
- package/dist/src/utils/gitlab-api.js.map +1 -1
- package/dist/src/utils/idConversion.js +47 -47
- package/dist/src/utils/idConversion.js.map +1 -1
- package/dist/src/utils/namespace.d.ts +2 -2
- package/dist/src/utils/namespace.js +15 -15
- package/dist/src/utils/projectIdentifier.js +4 -4
- package/dist/src/utils/request-logger.d.ts +4 -4
- package/dist/src/utils/request-logger.js +5 -5
- package/dist/src/utils/schema-utils.js +24 -24
- package/dist/src/utils/schema-utils.js.map +1 -1
- package/dist/src/utils/smart-user-search.d.ts +1 -1
- package/dist/src/utils/smart-user-search.js +10 -10
- package/dist/src/utils/url.d.ts +1 -0
- package/dist/src/utils/url.js +38 -0
- package/dist/src/utils/url.js.map +1 -0
- package/dist/src/utils/version.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +22 -31
- package/dist/structured-world-gitlab-mcp-6.62.1.tgz +0 -0
package/dist/src/server.js
CHANGED
|
@@ -54,24 +54,38 @@ const index_2 = require("./middleware/index");
|
|
|
54
54
|
const index_js_1 = require("./dashboard/index.js");
|
|
55
55
|
const request_logger_1 = require("./utils/request-logger");
|
|
56
56
|
const index_3 = require("./logging/index");
|
|
57
|
+
function resolveCloseReason(socketError, res) {
|
|
58
|
+
if (socketError)
|
|
59
|
+
return `peer_reset:${socketError}`;
|
|
60
|
+
if (res.writableFinished)
|
|
61
|
+
return 'normal_close';
|
|
62
|
+
if (res.locals?.writeTimedOut)
|
|
63
|
+
return 'write_timeout';
|
|
64
|
+
if (res.locals?.heartbeatFailed)
|
|
65
|
+
return 'heartbeat_failed';
|
|
66
|
+
if (res.destroyed)
|
|
67
|
+
return 'destroyed';
|
|
68
|
+
return 'client_disconnect';
|
|
69
|
+
}
|
|
70
|
+
const KEEP_ALIVE_TIMEOUT_MS = Math.min(config_1.HTTP_KEEPALIVE_TIMEOUT_MS, config_1.MAX_SAFE_TIMEOUT_MS - 5000);
|
|
57
71
|
async function sendToolsListChangedNotification() {
|
|
58
72
|
try {
|
|
59
73
|
const sessionManager = (0, session_manager_1.getSessionManager)();
|
|
60
74
|
await sessionManager.broadcastToolsListChanged();
|
|
61
75
|
}
|
|
62
76
|
catch (error) {
|
|
63
|
-
(0, logger_1.logError)(
|
|
77
|
+
(0, logger_1.logError)('Failed to broadcast tools/list_changed notification', { err: error });
|
|
64
78
|
}
|
|
65
79
|
}
|
|
66
80
|
function registerOAuthEndpoints(app) {
|
|
67
|
-
app.get(
|
|
68
|
-
app.get(
|
|
69
|
-
app.get(
|
|
70
|
-
app.get(
|
|
71
|
-
app.get(
|
|
72
|
-
app.post(
|
|
73
|
-
app.post(
|
|
74
|
-
(0, logger_1.logInfo)(
|
|
81
|
+
app.get('/.well-known/oauth-authorization-server', index_1.metadataHandler);
|
|
82
|
+
app.get('/.well-known/oauth-protected-resource', index_1.protectedResourceHandler);
|
|
83
|
+
app.get('/authorize', index_1.authorizeHandler);
|
|
84
|
+
app.get('/oauth/poll', index_1.pollHandler);
|
|
85
|
+
app.get('/oauth/callback', index_1.callbackHandler);
|
|
86
|
+
app.post('/token', express_1.default.urlencoded({ extended: true }), index_1.tokenHandler);
|
|
87
|
+
app.post('/register', express_1.default.json(), index_1.registerHandler);
|
|
88
|
+
(0, logger_1.logInfo)('OAuth endpoints registered');
|
|
75
89
|
}
|
|
76
90
|
function isTLSEnabled() {
|
|
77
91
|
return !!(config_1.SSL_CERT_PATH && config_1.SSL_KEY_PATH);
|
|
@@ -87,16 +101,16 @@ function loadTLSOptions() {
|
|
|
87
101
|
};
|
|
88
102
|
if (config_1.SSL_CA_PATH) {
|
|
89
103
|
options.ca = fs.readFileSync(config_1.SSL_CA_PATH);
|
|
90
|
-
(0, logger_1.logInfo)(
|
|
104
|
+
(0, logger_1.logInfo)('CA certificate loaded', { path: config_1.SSL_CA_PATH });
|
|
91
105
|
}
|
|
92
106
|
if (config_1.SSL_PASSPHRASE) {
|
|
93
107
|
options.passphrase = config_1.SSL_PASSPHRASE;
|
|
94
108
|
}
|
|
95
|
-
(0, logger_1.logInfo)(
|
|
109
|
+
(0, logger_1.logInfo)('TLS certificates loaded', { path: config_1.SSL_CERT_PATH });
|
|
96
110
|
return options;
|
|
97
111
|
}
|
|
98
112
|
catch (error) {
|
|
99
|
-
(0, logger_1.logError)(
|
|
113
|
+
(0, logger_1.logError)('Failed to load TLS certificates', { err: error });
|
|
100
114
|
throw new Error(`Failed to load TLS certificates: ${String(error)}`, { cause: error });
|
|
101
115
|
}
|
|
102
116
|
}
|
|
@@ -105,27 +119,27 @@ function configureTrustProxy(app) {
|
|
|
105
119
|
return;
|
|
106
120
|
}
|
|
107
121
|
let trustValue = config_1.TRUST_PROXY;
|
|
108
|
-
if (config_1.TRUST_PROXY ===
|
|
122
|
+
if (config_1.TRUST_PROXY === 'true' || config_1.TRUST_PROXY === '1') {
|
|
109
123
|
trustValue = true;
|
|
110
124
|
}
|
|
111
|
-
else if (config_1.TRUST_PROXY ===
|
|
125
|
+
else if (config_1.TRUST_PROXY === 'false' || config_1.TRUST_PROXY === '0') {
|
|
112
126
|
trustValue = false;
|
|
113
127
|
}
|
|
114
128
|
else if (!isNaN(Number(config_1.TRUST_PROXY))) {
|
|
115
129
|
trustValue = Number(config_1.TRUST_PROXY);
|
|
116
130
|
}
|
|
117
|
-
app.set(
|
|
118
|
-
(0, logger_1.logInfo)(
|
|
131
|
+
app.set('trust proxy', trustValue);
|
|
132
|
+
(0, logger_1.logInfo)('Trust proxy configured', { trustValue: String(trustValue) });
|
|
119
133
|
}
|
|
120
134
|
function configureServerTimeouts(server) {
|
|
121
|
-
server.keepAliveTimeout =
|
|
122
|
-
server.headersTimeout =
|
|
135
|
+
server.keepAliveTimeout = KEEP_ALIVE_TIMEOUT_MS;
|
|
136
|
+
server.headersTimeout = KEEP_ALIVE_TIMEOUT_MS + 5000;
|
|
123
137
|
server.timeout = 0;
|
|
124
|
-
server.on(
|
|
138
|
+
server.on('connection', (socket) => {
|
|
125
139
|
socket.setKeepAlive(true, 30000);
|
|
126
140
|
socket.setNoDelay(true);
|
|
127
141
|
});
|
|
128
|
-
(0, logger_1.logInfo)(
|
|
142
|
+
(0, logger_1.logInfo)('HTTP server timeouts configured for SSE streaming', {
|
|
129
143
|
keepAliveTimeout: server.keepAliveTimeout,
|
|
130
144
|
headersTimeout: server.headersTimeout,
|
|
131
145
|
timeout: server.timeout,
|
|
@@ -145,7 +159,7 @@ function startHttpServer(app, callback) {
|
|
|
145
159
|
}
|
|
146
160
|
}
|
|
147
161
|
function getProtocol() {
|
|
148
|
-
return isTLSEnabled() ?
|
|
162
|
+
return isTLSEnabled() ? 'https' : 'http';
|
|
149
163
|
}
|
|
150
164
|
const HEARTBEAT_DRAIN_TIMEOUT_MS = 10000;
|
|
151
165
|
function startSseHeartbeat(res, sessionId) {
|
|
@@ -157,7 +171,7 @@ function startSseHeartbeat(res, sessionId) {
|
|
|
157
171
|
pendingDrainTimeout = undefined;
|
|
158
172
|
}
|
|
159
173
|
waitingForDrain = false;
|
|
160
|
-
(0, logger_1.logDebug)(
|
|
174
|
+
(0, logger_1.logDebug)('SSE heartbeat drain recovered', { sessionId });
|
|
161
175
|
};
|
|
162
176
|
const interval = setInterval(() => {
|
|
163
177
|
if (waitingForDrain)
|
|
@@ -169,20 +183,20 @@ function startSseHeartbeat(res, sessionId) {
|
|
|
169
183
|
clearTimeout(pendingDrainTimeout);
|
|
170
184
|
pendingDrainTimeout = undefined;
|
|
171
185
|
}
|
|
172
|
-
res.removeListener(
|
|
186
|
+
res.removeListener('drain', drainListener);
|
|
173
187
|
return;
|
|
174
188
|
}
|
|
175
|
-
const ok = res.write(
|
|
189
|
+
const ok = res.write(': ping\n\n');
|
|
176
190
|
if (!ok) {
|
|
177
191
|
waitingForDrain = true;
|
|
178
192
|
pendingDrainTimeout = setTimeout(() => {
|
|
179
193
|
pendingDrainTimeout = undefined;
|
|
180
194
|
waitingForDrain = false;
|
|
181
|
-
res.removeListener(
|
|
182
|
-
(0, logger_1.logWarn)(
|
|
195
|
+
res.removeListener('drain', drainListener);
|
|
196
|
+
(0, logger_1.logWarn)('SSE heartbeat drain timeout — destroying dead connection', {
|
|
183
197
|
sessionId,
|
|
184
198
|
drainTimeoutMs: HEARTBEAT_DRAIN_TIMEOUT_MS,
|
|
185
|
-
reason:
|
|
199
|
+
reason: 'heartbeat_drain_timeout',
|
|
186
200
|
});
|
|
187
201
|
clearInterval(interval);
|
|
188
202
|
res.locals = res.locals ?? {};
|
|
@@ -191,62 +205,62 @@ function startSseHeartbeat(res, sessionId) {
|
|
|
191
205
|
res.destroy();
|
|
192
206
|
}
|
|
193
207
|
}, HEARTBEAT_DRAIN_TIMEOUT_MS);
|
|
194
|
-
res.once(
|
|
208
|
+
res.once('drain', drainListener);
|
|
195
209
|
}
|
|
196
210
|
}
|
|
197
211
|
catch (err) {
|
|
198
212
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
199
|
-
(0, logger_1.logWarn)(
|
|
213
|
+
(0, logger_1.logWarn)('SSE heartbeat write error — connection likely dead', {
|
|
200
214
|
sessionId,
|
|
201
215
|
error: errMsg,
|
|
202
|
-
reason:
|
|
216
|
+
reason: 'heartbeat_write_error',
|
|
203
217
|
});
|
|
204
218
|
clearInterval(interval);
|
|
205
219
|
if (pendingDrainTimeout) {
|
|
206
220
|
clearTimeout(pendingDrainTimeout);
|
|
207
221
|
pendingDrainTimeout = undefined;
|
|
208
222
|
}
|
|
209
|
-
res.removeListener(
|
|
223
|
+
res.removeListener('drain', drainListener);
|
|
210
224
|
}
|
|
211
225
|
}, config_1.SSE_HEARTBEAT_MS);
|
|
212
|
-
(0, logger_1.logDebug)(
|
|
226
|
+
(0, logger_1.logDebug)('SSE heartbeat started', { sessionId, intervalMs: config_1.SSE_HEARTBEAT_MS });
|
|
213
227
|
return () => {
|
|
214
228
|
clearInterval(interval);
|
|
215
229
|
if (pendingDrainTimeout) {
|
|
216
230
|
clearTimeout(pendingDrainTimeout);
|
|
217
231
|
pendingDrainTimeout = undefined;
|
|
218
232
|
}
|
|
219
|
-
res.removeListener(
|
|
220
|
-
(0, logger_1.logDebug)(
|
|
233
|
+
res.removeListener('drain', drainListener);
|
|
234
|
+
(0, logger_1.logDebug)('SSE heartbeat stopped', { sessionId });
|
|
221
235
|
};
|
|
222
236
|
}
|
|
223
237
|
function determineTransportMode() {
|
|
224
238
|
const args = process.argv.slice(2);
|
|
225
|
-
(0, logger_1.logInfo)(
|
|
226
|
-
if (args.includes(
|
|
227
|
-
(0, logger_1.logInfo)(
|
|
228
|
-
return
|
|
239
|
+
(0, logger_1.logInfo)('Transport mode detection', { args, PORT: config_1.PORT });
|
|
240
|
+
if (args.includes('stdio')) {
|
|
241
|
+
(0, logger_1.logInfo)('Selected stdio mode (explicit argument)');
|
|
242
|
+
return 'stdio';
|
|
229
243
|
}
|
|
230
244
|
if (process.env.PORT) {
|
|
231
|
-
(0, logger_1.logInfo)(
|
|
232
|
-
return
|
|
245
|
+
(0, logger_1.logInfo)('Selected dual transport mode (SSE + StreamableHTTP) - PORT environment variable detected');
|
|
246
|
+
return 'dual';
|
|
233
247
|
}
|
|
234
|
-
(0, logger_1.logInfo)(
|
|
235
|
-
return
|
|
248
|
+
(0, logger_1.logInfo)('Selected stdio mode (no PORT environment variable)');
|
|
249
|
+
return 'stdio';
|
|
236
250
|
}
|
|
237
251
|
async function startServer() {
|
|
238
252
|
const oauthConfig = (0, index_1.loadOAuthConfig)();
|
|
239
253
|
if (oauthConfig) {
|
|
240
|
-
(0, logger_1.logInfo)(
|
|
241
|
-
(0, logger_1.logInfo)(
|
|
254
|
+
(0, logger_1.logInfo)('Starting in OAuth mode (per-user authentication)');
|
|
255
|
+
(0, logger_1.logInfo)('OAuth client ID configured', { clientId: oauthConfig.gitlabClientId });
|
|
242
256
|
}
|
|
243
257
|
else if (process.env.GITLAB_TOKEN) {
|
|
244
|
-
(0, logger_1.logInfo)(
|
|
258
|
+
(0, logger_1.logInfo)('Starting in static token mode (shared GITLAB_TOKEN)');
|
|
245
259
|
}
|
|
246
260
|
else {
|
|
247
|
-
(0, logger_1.logInfo)(
|
|
261
|
+
(0, logger_1.logInfo)('Starting without authentication - tools/list will work, but tool calls require GITLAB_TOKEN');
|
|
248
262
|
}
|
|
249
|
-
(0, logger_1.logInfo)(
|
|
263
|
+
(0, logger_1.logInfo)('Authentication mode', { mode: (0, index_1.getAuthModeDescription)() });
|
|
250
264
|
if (oauthConfig) {
|
|
251
265
|
await index_1.sessionStore.initialize();
|
|
252
266
|
}
|
|
@@ -254,28 +268,29 @@ async function startServer() {
|
|
|
254
268
|
sessionManager.start();
|
|
255
269
|
const requestTracker = (0, index_3.getRequestTracker)();
|
|
256
270
|
const connectionTracker = (0, index_3.getConnectionTracker)();
|
|
257
|
-
const useCondensedLogging = config_1.LOG_FORMAT ===
|
|
271
|
+
const useCondensedLogging = config_1.LOG_FORMAT === 'condensed';
|
|
258
272
|
requestTracker.setEnabled(useCondensedLogging);
|
|
259
273
|
connectionTracker.setEnabled(useCondensedLogging);
|
|
260
|
-
(0, logger_1.logInfo)(
|
|
274
|
+
(0, logger_1.logInfo)('Access log format', { logFormat: config_1.LOG_FORMAT });
|
|
261
275
|
if (config_1.LOG_FILTER.length > 0) {
|
|
262
|
-
(0, logger_1.logInfo)(
|
|
276
|
+
(0, logger_1.logInfo)('Access log filter rules active', { count: config_1.LOG_FILTER.length });
|
|
263
277
|
}
|
|
264
278
|
const transportMode = determineTransportMode();
|
|
265
279
|
switch (transportMode) {
|
|
266
|
-
case
|
|
280
|
+
case 'stdio': {
|
|
267
281
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
268
|
-
await sessionManager.createSession(
|
|
269
|
-
(0, logger_1.logInfo)(
|
|
282
|
+
await sessionManager.createSession(session_manager_1.STDIO_SESSION_ID, transport);
|
|
283
|
+
(0, logger_1.logInfo)('GitLab MCP Server running on stdio');
|
|
270
284
|
break;
|
|
271
285
|
}
|
|
272
|
-
case
|
|
273
|
-
(0, logger_1.logInfo)(
|
|
286
|
+
case 'dual': {
|
|
287
|
+
(0, logger_1.logInfo)('Setting up dual transport mode (SSE + StreamableHTTP)...');
|
|
274
288
|
const app = (0, express_1.default)();
|
|
289
|
+
app.use((0, index_2.responseWriteTimeoutMiddleware)());
|
|
275
290
|
app.use(express_1.default.json());
|
|
276
291
|
configureTrustProxy(app);
|
|
277
|
-
app.get(
|
|
278
|
-
res.status(200).json({ status:
|
|
292
|
+
app.get('/health', (_req, res) => {
|
|
293
|
+
res.status(200).json({ status: 'ok' });
|
|
279
294
|
});
|
|
280
295
|
app.use((req, res, next) => {
|
|
281
296
|
if (!useCondensedLogging) {
|
|
@@ -288,18 +303,22 @@ async function startServer() {
|
|
|
288
303
|
}
|
|
289
304
|
const requestId = crypto.randomUUID();
|
|
290
305
|
const clientIp = (0, request_logger_1.getIpAddress)(req);
|
|
291
|
-
const sessionId = req.headers[
|
|
306
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
292
307
|
res.locals.accessLogRequestId = requestId;
|
|
293
308
|
requestTracker.openStack(requestId, clientIp, req.method, req.path, sessionId);
|
|
294
|
-
res.on(
|
|
309
|
+
res.on('finish', () => {
|
|
295
310
|
requestTracker.closeStack(requestId, res.statusCode);
|
|
296
311
|
});
|
|
297
|
-
res.on(
|
|
312
|
+
res.on('close', () => {
|
|
298
313
|
if (res.writableFinished) {
|
|
299
314
|
return;
|
|
300
315
|
}
|
|
301
316
|
if (!res.headersSent) {
|
|
302
|
-
requestTracker.closeStackWithError(requestId,
|
|
317
|
+
requestTracker.closeStackWithError(requestId, 'connection_closed');
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (res.locals?.writeTimedOut) {
|
|
321
|
+
requestTracker.closeStackWithError(requestId, 'write_timeout');
|
|
303
322
|
return;
|
|
304
323
|
}
|
|
305
324
|
requestTracker.closeStack(requestId, res.statusCode);
|
|
@@ -311,16 +330,16 @@ async function startServer() {
|
|
|
311
330
|
registerOAuthEndpoints(app);
|
|
312
331
|
}
|
|
313
332
|
if (config_1.DASHBOARD_ENABLED) {
|
|
314
|
-
app.get(
|
|
315
|
-
(0, logger_1.logInfo)(
|
|
333
|
+
app.get('/', index_js_1.dashboardHandler);
|
|
334
|
+
(0, logger_1.logInfo)('Dashboard enabled at GET /');
|
|
316
335
|
}
|
|
317
|
-
app.use([
|
|
318
|
-
const accept = req.headers.accept ??
|
|
319
|
-
if (req.method ===
|
|
336
|
+
app.use(['/', '/mcp'], (req, res, next) => {
|
|
337
|
+
const accept = req.headers.accept ?? '';
|
|
338
|
+
if (req.method === 'POST' && !accept.includes('text/event-stream')) {
|
|
320
339
|
req.headers.accept = accept
|
|
321
340
|
? `${accept}, text/event-stream`
|
|
322
|
-
:
|
|
323
|
-
(0, logger_1.logDebug)(
|
|
341
|
+
: 'application/json, text/event-stream';
|
|
342
|
+
(0, logger_1.logDebug)('Modified Accept header for MCP compatibility', {
|
|
324
343
|
originalAccept: accept,
|
|
325
344
|
newAccept: req.headers.accept,
|
|
326
345
|
});
|
|
@@ -328,13 +347,13 @@ async function startServer() {
|
|
|
328
347
|
next();
|
|
329
348
|
});
|
|
330
349
|
if ((0, index_1.isOAuthEnabled)()) {
|
|
331
|
-
app.use([
|
|
350
|
+
app.use(['/', '/mcp'], index_2.oauthAuthMiddleware);
|
|
332
351
|
}
|
|
333
352
|
const sseTransports = {};
|
|
334
353
|
const streamableTransports = {};
|
|
335
|
-
app.get(
|
|
336
|
-
(0, logger_1.logDebug)(
|
|
337
|
-
const transport = new sse_js_1.SSEServerTransport(
|
|
354
|
+
app.get('/sse', async (req, res) => {
|
|
355
|
+
(0, logger_1.logDebug)('SSE endpoint hit!');
|
|
356
|
+
const transport = new sse_js_1.SSEServerTransport('/messages', res);
|
|
338
357
|
const sessionId = transport.sessionId;
|
|
339
358
|
const clientIp = (0, request_logger_1.getIpAddress)(req);
|
|
340
359
|
const accessLogRequestId = res.locals?.accessLogRequestId;
|
|
@@ -344,12 +363,12 @@ async function startServer() {
|
|
|
344
363
|
try {
|
|
345
364
|
await sessionManager.createSession(sessionId, transport);
|
|
346
365
|
sseTransports[sessionId] = transport;
|
|
347
|
-
(0, logger_1.logDebug)(
|
|
366
|
+
(0, logger_1.logDebug)('SSE transport created with session', { sessionId });
|
|
348
367
|
connectionTracker.openConnection(sessionId, clientIp);
|
|
349
368
|
connectionTracker.incrementRequests(sessionId);
|
|
350
369
|
}
|
|
351
370
|
catch (error) {
|
|
352
|
-
(0, logger_1.logError)(
|
|
371
|
+
(0, logger_1.logError)('Failed to create SSE session', { err: error, sessionId });
|
|
353
372
|
if (!res.headersSent) {
|
|
354
373
|
res.status(500).end();
|
|
355
374
|
}
|
|
@@ -359,40 +378,32 @@ async function startServer() {
|
|
|
359
378
|
let socketError;
|
|
360
379
|
const socket = res.socket;
|
|
361
380
|
if (socket) {
|
|
362
|
-
socket.on(
|
|
381
|
+
socket.on('error', (err) => {
|
|
363
382
|
socketError = err.code ?? err.message;
|
|
364
|
-
(0, logger_1.logWarn)(
|
|
383
|
+
(0, logger_1.logWarn)('SSE socket error', {
|
|
365
384
|
sessionId,
|
|
366
385
|
error: err.message,
|
|
367
386
|
code: err.code,
|
|
368
|
-
reason:
|
|
387
|
+
reason: 'socket_error',
|
|
369
388
|
});
|
|
370
389
|
});
|
|
371
390
|
}
|
|
372
|
-
res.on(
|
|
391
|
+
res.on('close', () => {
|
|
373
392
|
stopHeartbeat();
|
|
374
393
|
delete sseTransports[sessionId];
|
|
375
|
-
const reason = socketError
|
|
376
|
-
|
|
377
|
-
: res.writableFinished
|
|
378
|
-
? "normal_close"
|
|
379
|
-
: res.locals?.heartbeatFailed
|
|
380
|
-
? "heartbeat_failed"
|
|
381
|
-
: res.destroyed
|
|
382
|
-
? "destroyed"
|
|
383
|
-
: "client_disconnect";
|
|
384
|
-
(0, logger_1.logInfo)("SSE session disconnected", { sessionId, reason });
|
|
394
|
+
const reason = resolveCloseReason(socketError, res);
|
|
395
|
+
(0, logger_1.logInfo)('SSE session disconnected', { sessionId, reason });
|
|
385
396
|
connectionTracker.closeConnection(sessionId, reason);
|
|
386
397
|
sessionManager.removeSession(sessionId).catch((error) => {
|
|
387
|
-
(0, logger_1.logDebug)(
|
|
398
|
+
(0, logger_1.logDebug)('Error removing SSE session on disconnect', { err: error, sessionId });
|
|
388
399
|
});
|
|
389
400
|
});
|
|
390
401
|
});
|
|
391
|
-
app.post(
|
|
392
|
-
(0, logger_1.logDebug)(
|
|
402
|
+
app.post('/messages', async (req, res) => {
|
|
403
|
+
(0, logger_1.logDebug)('SSE messages endpoint hit!');
|
|
393
404
|
const sessionId = req.query.sessionId;
|
|
394
405
|
if (!sessionId || !sseTransports[sessionId]) {
|
|
395
|
-
res.status(404).json({ error:
|
|
406
|
+
res.status(404).json({ error: 'Session not found' });
|
|
396
407
|
return;
|
|
397
408
|
}
|
|
398
409
|
connectionTracker.incrementRequests(sessionId);
|
|
@@ -414,14 +425,14 @@ async function startServer() {
|
|
|
414
425
|
}
|
|
415
426
|
}
|
|
416
427
|
catch (error) {
|
|
417
|
-
(0, logger_1.logError)(
|
|
428
|
+
(0, logger_1.logError)('Error handling SSE message', { err: error });
|
|
418
429
|
if (!res.headersSent) {
|
|
419
|
-
res.status(500).json({ error:
|
|
430
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
420
431
|
}
|
|
421
432
|
}
|
|
422
433
|
});
|
|
423
|
-
app.all([
|
|
424
|
-
const sessionId = req.headers[
|
|
434
|
+
app.all(['/', '/mcp'], async (req, res) => {
|
|
435
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
425
436
|
const accessLogRequestId = res.locals.accessLogRequestId;
|
|
426
437
|
const clientIp = (0, request_logger_1.getIpAddress)(req);
|
|
427
438
|
const oauthSessionId = res.locals.oauthSessionId;
|
|
@@ -432,8 +443,8 @@ async function startServer() {
|
|
|
432
443
|
const instanceLabel = res.locals.instanceLabel;
|
|
433
444
|
if (!useCondensedLogging) {
|
|
434
445
|
const requestContext = (0, request_logger_1.getRequestContext)(req, res);
|
|
435
|
-
(0, logger_1.logInfo)(
|
|
436
|
-
event:
|
|
446
|
+
(0, logger_1.logInfo)('MCP endpoint request received', {
|
|
447
|
+
event: 'mcp_request',
|
|
437
448
|
...requestContext,
|
|
438
449
|
hasToken: !!gitlabToken,
|
|
439
450
|
});
|
|
@@ -476,8 +487,8 @@ async function startServer() {
|
|
|
476
487
|
else {
|
|
477
488
|
if (sessionId) {
|
|
478
489
|
res.status(404).json({
|
|
479
|
-
error:
|
|
480
|
-
message:
|
|
490
|
+
error: 'Session not found',
|
|
491
|
+
message: 'Your session has expired. Please reconnect.',
|
|
481
492
|
});
|
|
482
493
|
return;
|
|
483
494
|
}
|
|
@@ -487,7 +498,7 @@ async function startServer() {
|
|
|
487
498
|
sessionIdGenerator: () => newSessionId,
|
|
488
499
|
onsessioninitialized: (initializedSessionId) => {
|
|
489
500
|
streamableTransports[initializedSessionId] = transport;
|
|
490
|
-
(0, logger_1.logInfo)(
|
|
501
|
+
(0, logger_1.logInfo)('MCP session initialized', {
|
|
491
502
|
sessionId: initializedSessionId,
|
|
492
503
|
method: req.method,
|
|
493
504
|
});
|
|
@@ -501,46 +512,38 @@ async function startServer() {
|
|
|
501
512
|
onsessionclosed: (closedSessionId) => {
|
|
502
513
|
delete streamableTransports[closedSessionId];
|
|
503
514
|
index_1.sessionStore.removeMcpSessionAssociation(closedSessionId);
|
|
504
|
-
connectionTracker.closeConnection(closedSessionId,
|
|
515
|
+
connectionTracker.closeConnection(closedSessionId, 'session_closed');
|
|
505
516
|
sessionManager.removeSession(closedSessionId).catch((err) => {
|
|
506
|
-
(0, logger_1.logDebug)(
|
|
517
|
+
(0, logger_1.logDebug)('Error removing closed session', { err, sessionId: closedSessionId });
|
|
507
518
|
});
|
|
508
|
-
(0, logger_1.logInfo)(
|
|
519
|
+
(0, logger_1.logInfo)('StreamableHTTP session closed', {
|
|
509
520
|
sessionId: closedSessionId,
|
|
510
|
-
reason:
|
|
521
|
+
reason: 'session_closed',
|
|
511
522
|
});
|
|
512
523
|
},
|
|
513
524
|
});
|
|
514
525
|
await sessionManager.createSession(newSessionId, transport);
|
|
515
526
|
await handleWithContext(transport);
|
|
516
527
|
}
|
|
517
|
-
if (req.method ===
|
|
528
|
+
if (req.method === 'GET' && !res.writableEnded) {
|
|
518
529
|
const stopHeartbeat = startSseHeartbeat(res, effectiveSessionId);
|
|
519
530
|
let socketError;
|
|
520
531
|
const socket = res.socket;
|
|
521
532
|
if (socket) {
|
|
522
|
-
socket.on(
|
|
533
|
+
socket.on('error', (err) => {
|
|
523
534
|
socketError = err.code ?? err.message;
|
|
524
|
-
(0, logger_1.logWarn)(
|
|
535
|
+
(0, logger_1.logWarn)('StreamableHTTP GET socket error', {
|
|
525
536
|
sessionId: effectiveSessionId,
|
|
526
537
|
error: err.message,
|
|
527
538
|
code: err.code,
|
|
528
|
-
reason:
|
|
539
|
+
reason: 'socket_error',
|
|
529
540
|
});
|
|
530
541
|
});
|
|
531
542
|
}
|
|
532
|
-
res.on(
|
|
543
|
+
res.on('close', () => {
|
|
533
544
|
stopHeartbeat();
|
|
534
|
-
const reason = socketError
|
|
535
|
-
|
|
536
|
-
: res.writableFinished
|
|
537
|
-
? "normal_close"
|
|
538
|
-
: res.locals?.heartbeatFailed
|
|
539
|
-
? "heartbeat_failed"
|
|
540
|
-
: res.destroyed
|
|
541
|
-
? "destroyed"
|
|
542
|
-
: "client_disconnect";
|
|
543
|
-
(0, logger_1.logInfo)("StreamableHTTP GET stream disconnected", {
|
|
545
|
+
const reason = resolveCloseReason(socketError, res);
|
|
546
|
+
(0, logger_1.logInfo)('StreamableHTTP GET stream disconnected', {
|
|
544
547
|
sessionId: effectiveSessionId,
|
|
545
548
|
reason,
|
|
546
549
|
});
|
|
@@ -548,76 +551,89 @@ async function startServer() {
|
|
|
548
551
|
}
|
|
549
552
|
}
|
|
550
553
|
catch (error) {
|
|
551
|
-
(0, logger_1.logError)(
|
|
554
|
+
(0, logger_1.logError)('Error in StreamableHTTP transport', { err: error });
|
|
552
555
|
if (!res.headersSent) {
|
|
553
|
-
res.status(500).json({ error:
|
|
556
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
554
557
|
}
|
|
555
558
|
}
|
|
556
559
|
});
|
|
557
560
|
startHttpServer(app, () => {
|
|
558
561
|
const url = `${getProtocol()}://${config_1.HOST}:${config_1.PORT}`;
|
|
559
|
-
(0, logger_1.logInfo)(
|
|
562
|
+
(0, logger_1.logInfo)('GitLab MCP Server running', { url });
|
|
560
563
|
if (isTLSEnabled()) {
|
|
561
|
-
(0, logger_1.logInfo)(
|
|
564
|
+
(0, logger_1.logInfo)('TLS/HTTPS enabled');
|
|
562
565
|
}
|
|
563
|
-
(0, logger_1.logInfo)(
|
|
564
|
-
(0, logger_1.logInfo)(
|
|
565
|
-
(0, logger_1.logInfo)(
|
|
566
|
+
(0, logger_1.logInfo)('Dual Transport Mode Active');
|
|
567
|
+
(0, logger_1.logInfo)('SSE endpoint', { endpoint: `${url}/sse`, note: 'backwards compatibility' });
|
|
568
|
+
(0, logger_1.logInfo)('StreamableHTTP endpoint', {
|
|
566
569
|
endpoint: `${url}/mcp`,
|
|
567
|
-
note:
|
|
570
|
+
note: 'modern, supports SSE + JSON-RPC',
|
|
568
571
|
});
|
|
569
572
|
if ((0, index_1.isOAuthEnabled)()) {
|
|
570
|
-
(0, logger_1.logInfo)(
|
|
571
|
-
(0, logger_1.logInfo)(
|
|
572
|
-
(0, logger_1.logInfo)(
|
|
573
|
-
(0, logger_1.logInfo)(
|
|
573
|
+
(0, logger_1.logInfo)('OAuth Mode Active');
|
|
574
|
+
(0, logger_1.logInfo)('OAuth metadata', { endpoint: `${url}/.well-known/oauth-authorization-server` });
|
|
575
|
+
(0, logger_1.logInfo)('Authorization endpoint', { endpoint: `${url}/authorize` });
|
|
576
|
+
(0, logger_1.logInfo)('Token exchange endpoint', { endpoint: `${url}/token` });
|
|
574
577
|
}
|
|
575
|
-
(0, logger_1.logInfo)(
|
|
578
|
+
(0, logger_1.logInfo)('SSE keepalive configured for proxy chain compatibility', {
|
|
576
579
|
heartbeatMs: config_1.SSE_HEARTBEAT_MS,
|
|
577
|
-
keepAliveTimeoutMs:
|
|
580
|
+
keepAliveTimeoutMs: KEEP_ALIVE_TIMEOUT_MS,
|
|
578
581
|
});
|
|
579
|
-
(
|
|
582
|
+
if (config_1.RESPONSE_WRITE_TIMEOUT_MS > 0) {
|
|
583
|
+
(0, logger_1.logInfo)('Response write timeout enabled (zombie connection detection)', {
|
|
584
|
+
responseWriteTimeoutMs: config_1.RESPONSE_WRITE_TIMEOUT_MS,
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
(0, logger_1.logInfo)('Clients can use either transport as needed');
|
|
580
588
|
});
|
|
581
589
|
break;
|
|
582
590
|
}
|
|
583
591
|
}
|
|
584
592
|
}
|
|
585
593
|
async function gracefulShutdown(signal) {
|
|
586
|
-
(0, logger_1.logInfo)(
|
|
594
|
+
(0, logger_1.logInfo)('Shutting down GitLab MCP Server...', { signal });
|
|
587
595
|
try {
|
|
588
596
|
const connTracker = (0, index_3.getConnectionTracker)();
|
|
589
|
-
connTracker.closeAllConnections(
|
|
590
|
-
(0, logger_1.logInfo)(
|
|
597
|
+
connTracker.closeAllConnections('server_shutdown');
|
|
598
|
+
(0, logger_1.logInfo)('All connections closed for shutdown');
|
|
599
|
+
}
|
|
600
|
+
catch (error) {
|
|
601
|
+
(0, logger_1.logError)('Error closing connections', { err: error });
|
|
602
|
+
}
|
|
603
|
+
try {
|
|
604
|
+
const { HealthMonitor } = await Promise.resolve().then(() => __importStar(require('./services/HealthMonitor')));
|
|
605
|
+
HealthMonitor.getInstance().shutdown();
|
|
606
|
+
(0, logger_1.logInfo)('Health monitor shut down successfully');
|
|
591
607
|
}
|
|
592
608
|
catch (error) {
|
|
593
|
-
(0, logger_1.logError)(
|
|
609
|
+
(0, logger_1.logError)('Error shutting down health monitor', { err: error });
|
|
594
610
|
}
|
|
595
611
|
try {
|
|
596
612
|
const sm = (0, session_manager_1.getSessionManager)();
|
|
597
613
|
await sm.shutdown();
|
|
598
|
-
(0, logger_1.logInfo)(
|
|
614
|
+
(0, logger_1.logInfo)('Session manager shut down successfully');
|
|
599
615
|
}
|
|
600
616
|
catch (error) {
|
|
601
|
-
(0, logger_1.logError)(
|
|
617
|
+
(0, logger_1.logError)('Error shutting down session manager', { err: error });
|
|
602
618
|
}
|
|
603
619
|
try {
|
|
604
620
|
await index_1.sessionStore.close();
|
|
605
|
-
(0, logger_1.logInfo)(
|
|
621
|
+
(0, logger_1.logInfo)('Session store closed successfully');
|
|
606
622
|
}
|
|
607
623
|
catch (error) {
|
|
608
|
-
(0, logger_1.logError)(
|
|
624
|
+
(0, logger_1.logError)('Error closing session store', { err: error });
|
|
609
625
|
}
|
|
610
626
|
process.exit(0);
|
|
611
627
|
}
|
|
612
|
-
process.on(
|
|
613
|
-
gracefulShutdown(
|
|
614
|
-
(0, logger_1.logError)(
|
|
628
|
+
process.on('SIGINT', () => {
|
|
629
|
+
gracefulShutdown('SIGINT').catch((err) => {
|
|
630
|
+
(0, logger_1.logError)('Error during graceful shutdown', { err });
|
|
615
631
|
process.exit(1);
|
|
616
632
|
});
|
|
617
633
|
});
|
|
618
|
-
process.on(
|
|
619
|
-
gracefulShutdown(
|
|
620
|
-
(0, logger_1.logError)(
|
|
634
|
+
process.on('SIGTERM', () => {
|
|
635
|
+
gracefulShutdown('SIGTERM').catch((err) => {
|
|
636
|
+
(0, logger_1.logError)('Error during graceful shutdown', { err });
|
|
621
637
|
process.exit(1);
|
|
622
638
|
});
|
|
623
639
|
});
|