@structured-world/gitlab-mcp 6.62.1 → 6.62.2
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 +1 -1
- 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/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 +17 -17
- 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 +65 -65
- 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 +4 -4
- package/dist/src/config.js +89 -89
- 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 +1 -1
- 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 +1 -1
- package/dist/src/handlers.js +55 -55
- 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/main.js +28 -28
- package/dist/src/middleware/index.d.ts +2 -2
- 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/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 +46 -46
- 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 +1 -1
- package/dist/src/registry-manager.js +64 -64
- package/dist/src/registry-manager.js.map +1 -1
- package/dist/src/server.js +136 -136
- package/dist/src/server.js.map +1 -1
- package/dist/src/services/ConnectionManager.d.ts +5 -5
- package/dist/src/services/ConnectionManager.js +45 -45
- 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/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 -4
- package/dist/src/services/InstanceRegistry.js +23 -23
- 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 +1 -1
- package/dist/src/services/SchemaIntrospector.js +42 -42
- package/dist/src/services/SchemaIntrospector.js.map +1 -1
- package/dist/src/services/TokenScopeDetector.d.ts +2 -2
- package/dist/src/services/TokenScopeDetector.js +80 -80
- package/dist/src/services/TokenScopeDetector.js.map +1 -1
- package/dist/src/services/ToolAvailability.d.ts +6 -6
- package/dist/src/services/ToolAvailability.js +122 -122
- package/dist/src/services/ToolAvailability.js.map +1 -1
- package/dist/src/services/WidgetAvailability.d.ts +2 -2
- package/dist/src/services/WidgetAvailability.js +34 -34
- 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 +9 -9
- package/dist/src/utils/error-handler.js +187 -187
- package/dist/src/utils/error-handler.js.map +1 -1
- package/dist/src/utils/fetch.js +85 -85
- 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 +24 -24
- 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/version.js +1 -1
- package/dist/structured-world-gitlab-mcp-6.62.2.tgz +0 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +18 -21
- package/dist/structured-world-gitlab-mcp-6.62.1.tgz +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RequestStack } from
|
|
1
|
+
import type { RequestStack } from './types.js';
|
|
2
2
|
export interface RequestContext {
|
|
3
3
|
requestId: string;
|
|
4
4
|
}
|
|
@@ -14,7 +14,7 @@ export declare class RequestTracker {
|
|
|
14
14
|
openStack(requestId: string, clientIp: string, method: string, path: string, sessionId?: string): void;
|
|
15
15
|
getStack(requestId: string): RequestStack | undefined;
|
|
16
16
|
setTool(requestId: string, tool: string, action?: string): void;
|
|
17
|
-
setGitLabResponse(requestId: string, status: number |
|
|
17
|
+
setGitLabResponse(requestId: string, status: number | 'timeout' | 'error', durationMs?: number): void;
|
|
18
18
|
addDetail(requestId: string, key: string, value: string | number | boolean): void;
|
|
19
19
|
addDetails(requestId: string, details: Record<string, string | number | boolean>): void;
|
|
20
20
|
setError(requestId: string, error: string): void;
|
|
@@ -27,7 +27,7 @@ export declare class RequestTracker {
|
|
|
27
27
|
getOpenStackCount(): number;
|
|
28
28
|
clear(): void;
|
|
29
29
|
setToolForCurrentRequest(tool: string, action?: string): void;
|
|
30
|
-
setGitLabResponseForCurrentRequest(status: number |
|
|
30
|
+
setGitLabResponseForCurrentRequest(status: number | 'timeout' | 'error', durationMs?: number): void;
|
|
31
31
|
addDetailForCurrentRequest(key: string, value: string | number | boolean): void;
|
|
32
32
|
addDetailsForCurrentRequest(details: Record<string, string | number | boolean>): void;
|
|
33
33
|
setErrorForCurrentRequest(error: string): void;
|
|
@@ -43,7 +43,7 @@ class RequestTracker {
|
|
|
43
43
|
details: {},
|
|
44
44
|
};
|
|
45
45
|
this.stacks.set(requestId, stack);
|
|
46
|
-
(0, logger_js_1.logDebug)(
|
|
46
|
+
(0, logger_js_1.logDebug)('Request stack opened', { requestId, clientIp, method, path });
|
|
47
47
|
}
|
|
48
48
|
getStack(requestId) {
|
|
49
49
|
return this.stacks.get(requestId);
|
|
@@ -56,7 +56,7 @@ class RequestTracker {
|
|
|
56
56
|
if (action) {
|
|
57
57
|
stack.action = action;
|
|
58
58
|
}
|
|
59
|
-
(0, logger_js_1.logDebug)(
|
|
59
|
+
(0, logger_js_1.logDebug)('Tool set on request stack', { requestId, tool, action });
|
|
60
60
|
}
|
|
61
61
|
setGitLabResponse(requestId, status, durationMs) {
|
|
62
62
|
const stack = this.stacks.get(requestId);
|
|
@@ -66,7 +66,7 @@ class RequestTracker {
|
|
|
66
66
|
if (durationMs !== undefined) {
|
|
67
67
|
stack.gitlabDuration = durationMs;
|
|
68
68
|
}
|
|
69
|
-
(0, logger_js_1.logDebug)(
|
|
69
|
+
(0, logger_js_1.logDebug)('GitLab response set on request stack', {
|
|
70
70
|
requestId,
|
|
71
71
|
gitlabStatus: status,
|
|
72
72
|
gitlabDuration: durationMs,
|
|
@@ -112,7 +112,7 @@ class RequestTracker {
|
|
|
112
112
|
closeStack(requestId, status) {
|
|
113
113
|
const stack = this.stacks.get(requestId);
|
|
114
114
|
if (!stack) {
|
|
115
|
-
(0, logger_js_1.logDebug)(
|
|
115
|
+
(0, logger_js_1.logDebug)('Request stack not found on close', { requestId });
|
|
116
116
|
return undefined;
|
|
117
117
|
}
|
|
118
118
|
this.stacks.delete(requestId);
|
|
@@ -8,13 +8,13 @@ export interface RequestStack {
|
|
|
8
8
|
path: string;
|
|
9
9
|
tool?: string;
|
|
10
10
|
action?: string;
|
|
11
|
-
gitlabStatus?: number |
|
|
11
|
+
gitlabStatus?: number | 'timeout' | 'error';
|
|
12
12
|
gitlabDuration?: number;
|
|
13
13
|
details: Record<string, string | number | boolean>;
|
|
14
14
|
status?: number;
|
|
15
15
|
error?: string;
|
|
16
16
|
}
|
|
17
|
-
export type ConnectionCloseReason =
|
|
17
|
+
export type ConnectionCloseReason = 'client_disconnect' | 'idle_timeout' | 'server_shutdown' | 'transport_error' | 'auth_expired' | 'session_closed' | 'destroyed' | 'normal_close' | 'heartbeat_failed' | `peer_reset:${string}`;
|
|
18
18
|
export interface ConnectionStats {
|
|
19
19
|
connectedAt: number;
|
|
20
20
|
clientIp: string;
|
|
@@ -51,5 +51,5 @@ export interface ConnectionCloseEntry {
|
|
|
51
51
|
errors: number;
|
|
52
52
|
lastError?: string;
|
|
53
53
|
}
|
|
54
|
-
export type LogFormat =
|
|
54
|
+
export type LogFormat = 'condensed' | 'verbose';
|
|
55
55
|
export declare const DEFAULT_LOG_FORMAT: LogFormat;
|
package/dist/src/main.js
CHANGED
|
@@ -44,30 +44,30 @@ const namespace_1 = require("./utils/namespace");
|
|
|
44
44
|
async function main() {
|
|
45
45
|
const cliArgs = (0, cli_utils_1.parseCliArgs)();
|
|
46
46
|
if (cliArgs.setup) {
|
|
47
|
-
const { runSetupWizard } = await Promise.resolve().then(() => __importStar(require(
|
|
47
|
+
const { runSetupWizard } = await Promise.resolve().then(() => __importStar(require('./cli/setup')));
|
|
48
48
|
const result = await runSetupWizard({ mode: cliArgs.setupMode });
|
|
49
49
|
process.exit(result.success ? 0 : 1);
|
|
50
50
|
}
|
|
51
51
|
if (cliArgs.init) {
|
|
52
|
-
const { runSetupWizard } = await Promise.resolve().then(() => __importStar(require(
|
|
53
|
-
const result = await runSetupWizard({ mode:
|
|
52
|
+
const { runSetupWizard } = await Promise.resolve().then(() => __importStar(require('./cli/setup')));
|
|
53
|
+
const result = await runSetupWizard({ mode: 'local' });
|
|
54
54
|
process.exit(result.success ? 0 : 1);
|
|
55
55
|
}
|
|
56
56
|
if (cliArgs.install) {
|
|
57
|
-
const { runInstallCommand, parseInstallFlags, buildServerConfigFromEnv } = await Promise.resolve().then(() => __importStar(require(
|
|
57
|
+
const { runInstallCommand, parseInstallFlags, buildServerConfigFromEnv } = await Promise.resolve().then(() => __importStar(require('./cli/install')));
|
|
58
58
|
const flags = parseInstallFlags(cliArgs.installArgs);
|
|
59
59
|
const serverConfig = buildServerConfigFromEnv();
|
|
60
60
|
await runInstallCommand(serverConfig, flags);
|
|
61
61
|
process.exit(0);
|
|
62
62
|
}
|
|
63
63
|
if (cliArgs.docker) {
|
|
64
|
-
if (cliArgs.dockerArgs[0] ===
|
|
65
|
-
const { runSetupWizard } = await Promise.resolve().then(() => __importStar(require(
|
|
66
|
-
const result = await runSetupWizard({ mode:
|
|
64
|
+
if (cliArgs.dockerArgs[0] === 'init') {
|
|
65
|
+
const { runSetupWizard } = await Promise.resolve().then(() => __importStar(require('./cli/setup')));
|
|
66
|
+
const result = await runSetupWizard({ mode: 'server' });
|
|
67
67
|
process.exit(result.success ? 0 : 1);
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
|
-
const { runDockerCommand } = await Promise.resolve().then(() => __importStar(require(
|
|
70
|
+
const { runDockerCommand } = await Promise.resolve().then(() => __importStar(require('./cli/docker')));
|
|
71
71
|
await runDockerCommand(cliArgs.dockerArgs);
|
|
72
72
|
process.exit(0);
|
|
73
73
|
}
|
|
@@ -79,7 +79,7 @@ async function main() {
|
|
|
79
79
|
}
|
|
80
80
|
catch (error) {
|
|
81
81
|
const message = error instanceof Error ? error.message : String(error);
|
|
82
|
-
(0, logger_1.logError)(
|
|
82
|
+
(0, logger_1.logError)('Failed to load project config', { error: message });
|
|
83
83
|
process.exit(1);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -97,19 +97,19 @@ async function main() {
|
|
|
97
97
|
console.log((0, discovery_1.formatDiscoveryResult)(autoDiscoveryResult));
|
|
98
98
|
process.exit(0);
|
|
99
99
|
}
|
|
100
|
-
(0, logger_1.logInfo)(
|
|
100
|
+
(0, logger_1.logInfo)('Auto-discovery detected GitLab configuration', {
|
|
101
101
|
host: autoDiscoveryResult.host,
|
|
102
102
|
project: autoDiscoveryResult.projectPath,
|
|
103
103
|
profile: autoDiscoveryResult.matchedProfile?.profileName,
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
else {
|
|
107
|
-
(0, logger_1.logWarn)(
|
|
107
|
+
(0, logger_1.logWarn)('Auto-discovery failed: not in a git repository or no remote found');
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
catch (error) {
|
|
111
111
|
const message = error instanceof Error ? error.message : String(error);
|
|
112
|
-
(0, logger_1.logError)(
|
|
112
|
+
(0, logger_1.logError)('Auto-discovery failed', { error: message });
|
|
113
113
|
process.exit(1);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
@@ -117,18 +117,18 @@ async function main() {
|
|
|
117
117
|
try {
|
|
118
118
|
const result = await (0, profiles_1.tryApplyProfileFromEnv)(cliArgs.profileName);
|
|
119
119
|
if (result) {
|
|
120
|
-
if (
|
|
121
|
-
(0, logger_1.logInfo)(
|
|
120
|
+
if ('profileName' in result) {
|
|
121
|
+
(0, logger_1.logInfo)('Using CLI-specified profile', {
|
|
122
122
|
profile: result.profileName,
|
|
123
123
|
host: result.host,
|
|
124
124
|
});
|
|
125
125
|
}
|
|
126
126
|
else {
|
|
127
|
-
(0, logger_1.logInfo)(
|
|
127
|
+
(0, logger_1.logInfo)('Using CLI-specified preset', { preset: result.presetName });
|
|
128
128
|
}
|
|
129
129
|
if (autoDiscoveryResult?.matchedProfile &&
|
|
130
130
|
autoDiscoveryResult.matchedProfile.profileName !== cliArgs.profileName) {
|
|
131
|
-
(0, logger_1.logWarn)(
|
|
131
|
+
(0, logger_1.logWarn)('Auto-discovered profile ignored: --profile takes precedence', {
|
|
132
132
|
cliProfile: cliArgs.profileName,
|
|
133
133
|
autoProfile: autoDiscoveryResult.matchedProfile.profileName,
|
|
134
134
|
});
|
|
@@ -137,15 +137,15 @@ async function main() {
|
|
|
137
137
|
}
|
|
138
138
|
catch (error) {
|
|
139
139
|
const message = error instanceof Error ? error.message : String(error);
|
|
140
|
-
(0, logger_1.logError)(
|
|
140
|
+
(0, logger_1.logError)('Failed to load profile', { error: message });
|
|
141
141
|
process.exit(1);
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
else if (autoDiscoveryResult?.matchedProfile) {
|
|
145
145
|
try {
|
|
146
146
|
const result = await (0, profiles_1.tryApplyProfileFromEnv)(autoDiscoveryResult.matchedProfile.profileName);
|
|
147
|
-
if (result &&
|
|
148
|
-
(0, logger_1.logInfo)(
|
|
147
|
+
if (result && 'profileName' in result) {
|
|
148
|
+
(0, logger_1.logInfo)('Using auto-discovered profile', {
|
|
149
149
|
profile: result.profileName,
|
|
150
150
|
host: result.host,
|
|
151
151
|
});
|
|
@@ -153,27 +153,27 @@ async function main() {
|
|
|
153
153
|
}
|
|
154
154
|
catch (error) {
|
|
155
155
|
const message = error instanceof Error ? error.message : String(error);
|
|
156
|
-
(0, logger_1.logWarn)(
|
|
156
|
+
(0, logger_1.logWarn)('Failed to apply auto-discovered profile', { error: message });
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
else {
|
|
160
160
|
try {
|
|
161
161
|
const result = await (0, profiles_1.tryApplyProfileFromEnv)();
|
|
162
162
|
if (result) {
|
|
163
|
-
if (
|
|
164
|
-
(0, logger_1.logInfo)(
|
|
163
|
+
if ('profileName' in result) {
|
|
164
|
+
(0, logger_1.logInfo)('Using configuration profile', {
|
|
165
165
|
profile: result.profileName,
|
|
166
166
|
host: result.host,
|
|
167
167
|
});
|
|
168
168
|
}
|
|
169
169
|
else {
|
|
170
|
-
(0, logger_1.logInfo)(
|
|
170
|
+
(0, logger_1.logInfo)('Using configuration preset', { preset: result.presetName });
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
catch (error) {
|
|
175
175
|
const message = error instanceof Error ? error.message : String(error);
|
|
176
|
-
(0, logger_1.logError)(
|
|
176
|
+
(0, logger_1.logError)('Failed to load profile', { error: message });
|
|
177
177
|
process.exit(1);
|
|
178
178
|
}
|
|
179
179
|
}
|
|
@@ -182,7 +182,7 @@ async function main() {
|
|
|
182
182
|
const projectConfig = await (0, profiles_1.findProjectConfig)(process.cwd());
|
|
183
183
|
if (projectConfig) {
|
|
184
184
|
const summary = (0, profiles_1.getProjectConfigSummary)(projectConfig);
|
|
185
|
-
(0, logger_1.logInfo)(
|
|
185
|
+
(0, logger_1.logInfo)('Loaded project configuration (restrictions applied)', {
|
|
186
186
|
path: projectConfig.configPath,
|
|
187
187
|
preset: summary.presetSummary,
|
|
188
188
|
profile: summary.profileSummary,
|
|
@@ -191,7 +191,7 @@ async function main() {
|
|
|
191
191
|
}
|
|
192
192
|
catch (error) {
|
|
193
193
|
const message = error instanceof Error ? error.message : String(error);
|
|
194
|
-
(0, logger_1.logWarn)(
|
|
194
|
+
(0, logger_1.logWarn)('Failed to load project config, continuing without it', { error: message });
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
if (autoDiscoveryResult) {
|
|
@@ -200,7 +200,7 @@ async function main() {
|
|
|
200
200
|
if (namespace) {
|
|
201
201
|
process.env.GITLAB_DEFAULT_NAMESPACE ??= namespace;
|
|
202
202
|
}
|
|
203
|
-
(0, logger_1.logDebug)(
|
|
203
|
+
(0, logger_1.logDebug)('Default context set from auto-discovery', {
|
|
204
204
|
defaultProject: process.env.GITLAB_DEFAULT_PROJECT,
|
|
205
205
|
defaultNamespace: process.env.GITLAB_DEFAULT_NAMESPACE,
|
|
206
206
|
});
|
|
@@ -212,7 +212,7 @@ main().catch((error) => {
|
|
|
212
212
|
console.error(error.guidance);
|
|
213
213
|
}
|
|
214
214
|
else {
|
|
215
|
-
(0, logger_1.logError)(
|
|
215
|
+
(0, logger_1.logError)('Failed to start GitLab MCP Server', { error: String(error) });
|
|
216
216
|
}
|
|
217
217
|
process.exit(1);
|
|
218
218
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { oauthAuthMiddleware, createOAuthMiddleware, optionalOAuthMiddleware } from
|
|
2
|
-
export { rateLimiterMiddleware, stopCleanup as stopRateLimitCleanup, getRateLimitStats, } from
|
|
1
|
+
export { oauthAuthMiddleware, createOAuthMiddleware, optionalOAuthMiddleware } from './oauth-auth';
|
|
2
|
+
export { rateLimiterMiddleware, stopCleanup as stopRateLimitCleanup, getRateLimitStats, } from './rate-limiter';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Request, Response, NextFunction } from
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
2
|
export declare function oauthAuthMiddleware(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
3
3
|
export declare function createOAuthMiddleware(): typeof oauthAuthMiddleware;
|
|
4
4
|
export declare function optionalOAuthMiddleware(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
@@ -14,36 +14,36 @@ const config_2 = require("../config");
|
|
|
14
14
|
async function oauthAuthMiddleware(req, res, next) {
|
|
15
15
|
const config = (0, config_1.loadOAuthConfig)();
|
|
16
16
|
if (!config) {
|
|
17
|
-
sendUnauthorized(req, res,
|
|
17
|
+
sendUnauthorized(req, res, 'server_error', 'OAuth not configured');
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
20
|
const authHeader = req.headers.authorization;
|
|
21
21
|
if (!authHeader) {
|
|
22
|
-
sendUnauthorized(req, res,
|
|
22
|
+
sendUnauthorized(req, res, 'unauthorized', 'Missing Authorization header');
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
|
-
if (!authHeader.startsWith(
|
|
26
|
-
sendUnauthorized(req, res,
|
|
25
|
+
if (!authHeader.startsWith('Bearer ')) {
|
|
26
|
+
sendUnauthorized(req, res, 'unauthorized', 'Invalid Authorization header format. Expected: Bearer <token>');
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
const token = authHeader.slice(7);
|
|
30
30
|
if (!token) {
|
|
31
|
-
sendUnauthorized(req, res,
|
|
31
|
+
sendUnauthorized(req, res, 'unauthorized', 'Empty Bearer token');
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
const payload = (0, token_utils_1.verifyMCPToken)(token, config.sessionSecret);
|
|
35
35
|
if (!payload) {
|
|
36
|
-
sendUnauthorized(req, res,
|
|
36
|
+
sendUnauthorized(req, res, 'invalid_token', 'Token is invalid or expired');
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
39
|
const sessionId = payload.sid;
|
|
40
40
|
const session = session_store_1.sessionStore.getSession(sessionId);
|
|
41
41
|
if (!session) {
|
|
42
|
-
sendUnauthorized(req, res,
|
|
42
|
+
sendUnauthorized(req, res, 'invalid_token', 'Session not found or expired');
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
if (session.mcpAccessToken !== token) {
|
|
46
|
-
sendUnauthorized(req, res,
|
|
46
|
+
sendUnauthorized(req, res, 'invalid_token', 'Token has been superseded');
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
49
|
if ((0, token_utils_1.isTokenExpiringSoon)(session.gitlabTokenExpiry)) {
|
|
@@ -54,19 +54,19 @@ async function oauthAuthMiddleware(req, res, next) {
|
|
|
54
54
|
gitlabRefreshToken: newTokens.refresh_token,
|
|
55
55
|
gitlabTokenExpiry: (0, token_utils_1.calculateTokenExpiry)(newTokens.expires_in),
|
|
56
56
|
});
|
|
57
|
-
(0, logger_1.logDebug)(
|
|
57
|
+
(0, logger_1.logDebug)('GitLab token refreshed during request', {
|
|
58
58
|
sessionId: (0, logger_1.truncateId)(sessionId),
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
61
|
catch (error) {
|
|
62
|
-
(0, logger_1.logError)(
|
|
63
|
-
sendUnauthorized(req, res,
|
|
62
|
+
(0, logger_1.logError)('Failed to refresh GitLab token during request', { err: error });
|
|
63
|
+
sendUnauthorized(req, res, 'invalid_token', 'GitLab token refresh failed. Please re-authenticate.');
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
const updatedSession = session_store_1.sessionStore.getSession(sessionId);
|
|
68
68
|
if (!updatedSession) {
|
|
69
|
-
sendUnauthorized(req, res,
|
|
69
|
+
sendUnauthorized(req, res, 'invalid_token', 'Session lost during token refresh');
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
res.locals.oauthSessionId = updatedSession.id;
|
|
@@ -75,7 +75,7 @@ async function oauthAuthMiddleware(req, res, next) {
|
|
|
75
75
|
res.locals.gitlabUsername = updatedSession.gitlabUsername;
|
|
76
76
|
res.locals.gitlabApiUrl = updatedSession.gitlabApiUrl ?? config_2.GITLAB_BASE_URL;
|
|
77
77
|
res.locals.instanceLabel = updatedSession.instanceLabel;
|
|
78
|
-
(0, logger_1.logDebug)(
|
|
78
|
+
(0, logger_1.logDebug)('OAuth session validated, passing to route handler', {
|
|
79
79
|
sessionId: (0, logger_1.truncateId)(updatedSession.id),
|
|
80
80
|
method: req.method,
|
|
81
81
|
path: req.path,
|
|
@@ -92,7 +92,7 @@ async function optionalOAuthMiddleware(req, res, next) {
|
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
94
|
const authHeader = req.headers.authorization;
|
|
95
|
-
if (!authHeader?.startsWith(
|
|
95
|
+
if (!authHeader?.startsWith('Bearer ')) {
|
|
96
96
|
next();
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
@@ -120,8 +120,8 @@ async function optionalOAuthMiddleware(req, res, next) {
|
|
|
120
120
|
next();
|
|
121
121
|
}
|
|
122
122
|
function sendUnauthorized(req, res, error, description) {
|
|
123
|
-
(0, logger_1.logWarn)(
|
|
124
|
-
event:
|
|
123
|
+
(0, logger_1.logWarn)('Authentication rejected', {
|
|
124
|
+
event: 'auth_rejected',
|
|
125
125
|
...(0, request_logger_1.getMinimalRequestContext)(req),
|
|
126
126
|
reason: error,
|
|
127
127
|
description,
|
|
@@ -131,7 +131,7 @@ function sendUnauthorized(req, res, error, description) {
|
|
|
131
131
|
error_description: description,
|
|
132
132
|
};
|
|
133
133
|
const baseUrl = (0, metadata_1.getBaseUrl)(req);
|
|
134
|
-
res.setHeader(
|
|
134
|
+
res.setHeader('WWW-Authenticate', `Bearer realm="gitlab-mcp", resource_metadata="${baseUrl}/.well-known/oauth-protected-resource"`);
|
|
135
135
|
res.status(401).json(response);
|
|
136
136
|
}
|
|
137
137
|
//# sourceMappingURL=oauth-auth.js.map
|
|
@@ -22,7 +22,7 @@ function startCleanup() {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
if (cleaned > 0) {
|
|
25
|
-
(0, logger_1.logDebug)(
|
|
25
|
+
(0, logger_1.logDebug)('Rate limiter cleanup: removed expired entries', { cleaned });
|
|
26
26
|
}
|
|
27
27
|
}, CLEANUP_INTERVAL_MS);
|
|
28
28
|
cleanupInterval.unref();
|
|
@@ -34,14 +34,14 @@ function stopCleanup() {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
function getIpAddress(req) {
|
|
37
|
-
return req.ip ?? req.socket.remoteAddress ??
|
|
37
|
+
return req.ip ?? req.socket.remoteAddress ?? 'unknown';
|
|
38
38
|
}
|
|
39
39
|
function isAuthenticated(req, res) {
|
|
40
40
|
const oauthSessionId = res.locals.oauthSessionId;
|
|
41
41
|
if (oauthSessionId) {
|
|
42
42
|
return true;
|
|
43
43
|
}
|
|
44
|
-
const mcpSessionId = req.headers[
|
|
44
|
+
const mcpSessionId = req.headers['mcp-session-id'];
|
|
45
45
|
if (mcpSessionId) {
|
|
46
46
|
return true;
|
|
47
47
|
}
|
|
@@ -70,14 +70,14 @@ function checkRateLimit(key, windowMs, maxRequests) {
|
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
function setRateLimitHeaders(res, info) {
|
|
73
|
-
res.set(
|
|
74
|
-
res.set(
|
|
75
|
-
res.set(
|
|
73
|
+
res.set('X-RateLimit-Limit', info.total.toString());
|
|
74
|
+
res.set('X-RateLimit-Remaining', info.remaining.toString());
|
|
75
|
+
res.set('X-RateLimit-Reset', Math.ceil(info.resetAt / 1000).toString());
|
|
76
76
|
}
|
|
77
77
|
function rateLimiterMiddleware() {
|
|
78
78
|
startCleanup();
|
|
79
79
|
return (req, res, next) => {
|
|
80
|
-
if (req.path ===
|
|
80
|
+
if (req.path === '/health') {
|
|
81
81
|
next();
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
@@ -87,33 +87,33 @@ function rateLimiterMiddleware() {
|
|
|
87
87
|
next();
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
|
-
const sessionId = res.locals.oauthSessionId || req.headers[
|
|
90
|
+
const sessionId = res.locals.oauthSessionId || req.headers['mcp-session-id'];
|
|
91
91
|
const key = `session:${sessionId}`;
|
|
92
92
|
const info = checkRateLimit(key, config_1.RATE_LIMIT_SESSION_WINDOW_MS, config_1.RATE_LIMIT_SESSION_MAX_REQUESTS);
|
|
93
93
|
setRateLimitHeaders(res, info);
|
|
94
94
|
const usagePercent = (info.used / info.total) * 100;
|
|
95
95
|
if (info.allowed && usagePercent >= 80) {
|
|
96
|
-
const rateLimitInfo = (0, request_logger_1.buildRateLimitInfo)(
|
|
97
|
-
(0, logger_1.logDebug)(
|
|
98
|
-
event:
|
|
96
|
+
const rateLimitInfo = (0, request_logger_1.buildRateLimitInfo)('session', sessionId, info.used, info.total, info.resetAt);
|
|
97
|
+
(0, logger_1.logDebug)('Approaching session rate limit threshold', {
|
|
98
|
+
event: 'rate_limit_warning',
|
|
99
99
|
...(0, request_logger_1.getMinimalRequestContext)(req),
|
|
100
100
|
rateLimit: rateLimitInfo,
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
103
|
if (!info.allowed) {
|
|
104
104
|
const retryAfter = Math.ceil((info.resetAt - Date.now()) / 1000);
|
|
105
|
-
const rateLimitInfo = (0, request_logger_1.buildRateLimitInfo)(
|
|
106
|
-
(0, logger_1.logWarn)(
|
|
107
|
-
event:
|
|
105
|
+
const rateLimitInfo = (0, request_logger_1.buildRateLimitInfo)('session', sessionId, info.used, info.total, info.resetAt);
|
|
106
|
+
(0, logger_1.logWarn)('Session rate limit exceeded', {
|
|
107
|
+
event: 'rate_limit_exceeded',
|
|
108
108
|
...(0, request_logger_1.getMinimalRequestContext)(req),
|
|
109
109
|
rateLimit: rateLimitInfo,
|
|
110
110
|
hasOAuthSession: !!res.locals.oauthSessionId,
|
|
111
|
-
hasMcpSessionHeader: !!req.headers[
|
|
111
|
+
hasMcpSessionHeader: !!req.headers['mcp-session-id'],
|
|
112
112
|
});
|
|
113
|
-
res.set(
|
|
113
|
+
res.set('Retry-After', retryAfter.toString());
|
|
114
114
|
res.status(429).json({
|
|
115
|
-
error:
|
|
116
|
-
message:
|
|
115
|
+
error: 'Too Many Requests',
|
|
116
|
+
message: 'Session rate limit exceeded. Please slow down your requests.',
|
|
117
117
|
retryAfter,
|
|
118
118
|
limit: info.total,
|
|
119
119
|
remaining: info.remaining,
|
|
@@ -134,31 +134,31 @@ function rateLimiterMiddleware() {
|
|
|
134
134
|
setRateLimitHeaders(res, info);
|
|
135
135
|
const usagePercent = (info.used / info.total) * 100;
|
|
136
136
|
if (info.allowed && usagePercent >= 80) {
|
|
137
|
-
const rateLimitInfo = (0, request_logger_1.buildRateLimitInfo)(
|
|
138
|
-
(0, logger_1.logDebug)(
|
|
139
|
-
event:
|
|
137
|
+
const rateLimitInfo = (0, request_logger_1.buildRateLimitInfo)('ip', ip, info.used, info.total, info.resetAt);
|
|
138
|
+
(0, logger_1.logDebug)('Approaching IP rate limit threshold', {
|
|
139
|
+
event: 'rate_limit_warning',
|
|
140
140
|
...(0, request_logger_1.getMinimalRequestContext)(req),
|
|
141
141
|
rateLimit: rateLimitInfo,
|
|
142
|
-
authClassification:
|
|
143
|
-
authReason:
|
|
142
|
+
authClassification: 'anonymous',
|
|
143
|
+
authReason: 'no OAuth session and no MCP-Session-Id header',
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
146
|
if (!info.allowed) {
|
|
147
147
|
const retryAfter = Math.ceil((info.resetAt - Date.now()) / 1000);
|
|
148
|
-
const rateLimitInfo = (0, request_logger_1.buildRateLimitInfo)(
|
|
149
|
-
const mcpSessionHeader = req.headers[
|
|
150
|
-
(0, logger_1.logWarn)(
|
|
151
|
-
event:
|
|
148
|
+
const rateLimitInfo = (0, request_logger_1.buildRateLimitInfo)('ip', ip, info.used, info.total, info.resetAt);
|
|
149
|
+
const mcpSessionHeader = req.headers['mcp-session-id'];
|
|
150
|
+
(0, logger_1.logWarn)('IP rate limit exceeded', {
|
|
151
|
+
event: 'rate_limit_exceeded',
|
|
152
152
|
...(0, request_logger_1.getMinimalRequestContext)(req),
|
|
153
153
|
rateLimit: rateLimitInfo,
|
|
154
|
-
authClassification:
|
|
155
|
-
authReason:
|
|
154
|
+
authClassification: 'anonymous',
|
|
155
|
+
authReason: 'no OAuth session and no MCP-Session-Id header',
|
|
156
156
|
mcpSessionId: (0, request_logger_1.truncateId)(mcpSessionHeader),
|
|
157
157
|
});
|
|
158
|
-
res.set(
|
|
158
|
+
res.set('Retry-After', retryAfter.toString());
|
|
159
159
|
res.status(429).json({
|
|
160
|
-
error:
|
|
161
|
-
message:
|
|
160
|
+
error: 'Too Many Requests',
|
|
161
|
+
message: 'Rate limit exceeded. Please authenticate or slow down your requests.',
|
|
162
162
|
retryAfter,
|
|
163
163
|
limit: info.total,
|
|
164
164
|
remaining: info.remaining,
|
package/dist/src/oauth/config.js
CHANGED
|
@@ -12,10 +12,10 @@ const zod_1 = require("zod");
|
|
|
12
12
|
const logger_1 = require("../logger");
|
|
13
13
|
const OAuthConfigSchema = zod_1.z.object({
|
|
14
14
|
enabled: zod_1.z.literal(true),
|
|
15
|
-
sessionSecret: zod_1.z.string().min(32,
|
|
16
|
-
gitlabClientId: zod_1.z.string().min(1,
|
|
15
|
+
sessionSecret: zod_1.z.string().min(32, 'OAUTH_SESSION_SECRET must be at least 32 characters'),
|
|
16
|
+
gitlabClientId: zod_1.z.string().min(1, 'GITLAB_OAUTH_CLIENT_ID is required'),
|
|
17
17
|
gitlabClientSecret: zod_1.z.string().optional(),
|
|
18
|
-
gitlabScopes: zod_1.z.string().default(
|
|
18
|
+
gitlabScopes: zod_1.z.string().default('api,read_user'),
|
|
19
19
|
tokenTtl: zod_1.z.number().positive().default(3600),
|
|
20
20
|
refreshTokenTtl: zod_1.z.number().positive().default(604800),
|
|
21
21
|
devicePollInterval: zod_1.z.number().positive().default(5),
|
|
@@ -26,7 +26,7 @@ function loadOAuthConfig() {
|
|
|
26
26
|
if (cachedOAuthConfig !== undefined) {
|
|
27
27
|
return cachedOAuthConfig;
|
|
28
28
|
}
|
|
29
|
-
if (process.env.OAUTH_ENABLED !==
|
|
29
|
+
if (process.env.OAUTH_ENABLED !== 'true') {
|
|
30
30
|
cachedOAuthConfig = null;
|
|
31
31
|
(0, logger_1.logDebug)("OAuth mode disabled (OAUTH_ENABLED !== 'true')");
|
|
32
32
|
return null;
|
|
@@ -36,27 +36,27 @@ function loadOAuthConfig() {
|
|
|
36
36
|
sessionSecret: process.env.OAUTH_SESSION_SECRET,
|
|
37
37
|
gitlabClientId: process.env.GITLAB_OAUTH_CLIENT_ID,
|
|
38
38
|
gitlabClientSecret: process.env.GITLAB_OAUTH_CLIENT_SECRET,
|
|
39
|
-
gitlabScopes: process.env.GITLAB_OAUTH_SCOPES ??
|
|
40
|
-
tokenTtl: parseInt(process.env.OAUTH_TOKEN_TTL ??
|
|
41
|
-
refreshTokenTtl: parseInt(process.env.OAUTH_REFRESH_TOKEN_TTL ??
|
|
42
|
-
devicePollInterval: parseInt(process.env.OAUTH_DEVICE_POLL_INTERVAL ??
|
|
43
|
-
deviceTimeout: parseInt(process.env.OAUTH_DEVICE_TIMEOUT ??
|
|
39
|
+
gitlabScopes: process.env.GITLAB_OAUTH_SCOPES ?? 'api,read_user',
|
|
40
|
+
tokenTtl: parseInt(process.env.OAUTH_TOKEN_TTL ?? '3600', 10),
|
|
41
|
+
refreshTokenTtl: parseInt(process.env.OAUTH_REFRESH_TOKEN_TTL ?? '604800', 10),
|
|
42
|
+
devicePollInterval: parseInt(process.env.OAUTH_DEVICE_POLL_INTERVAL ?? '5', 10),
|
|
43
|
+
deviceTimeout: parseInt(process.env.OAUTH_DEVICE_TIMEOUT ?? '300', 10),
|
|
44
44
|
});
|
|
45
45
|
if (!result.success) {
|
|
46
46
|
const errorMessages = result.error.issues
|
|
47
|
-
.map(e => `${e.path.join(
|
|
48
|
-
.join(
|
|
47
|
+
.map((e) => `${e.path.join('.')}: ${e.message}`)
|
|
48
|
+
.join(', ');
|
|
49
49
|
throw new Error(`Invalid OAuth configuration: ${errorMessages}`);
|
|
50
50
|
}
|
|
51
51
|
cachedOAuthConfig = result.data;
|
|
52
|
-
(0, logger_1.logInfo)(
|
|
52
|
+
(0, logger_1.logInfo)('OAuth mode enabled with valid configuration');
|
|
53
53
|
return result.data;
|
|
54
54
|
}
|
|
55
55
|
class ConfigurationError extends Error {
|
|
56
56
|
guidance;
|
|
57
57
|
constructor(guidance) {
|
|
58
|
-
super(
|
|
59
|
-
this.name =
|
|
58
|
+
super('Missing required configuration');
|
|
59
|
+
this.name = 'ConfigurationError';
|
|
60
60
|
this.guidance = guidance;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -83,7 +83,7 @@ function validateStaticConfig() {
|
|
|
83
83
|
if (!process.env.GITLAB_TOKEN) {
|
|
84
84
|
throw new ConfigurationError(MISSING_TOKEN_GUIDANCE);
|
|
85
85
|
}
|
|
86
|
-
(0, logger_1.logDebug)(
|
|
86
|
+
(0, logger_1.logDebug)('Static token mode: GITLAB_TOKEN configured');
|
|
87
87
|
}
|
|
88
88
|
function isOAuthEnabled() {
|
|
89
89
|
return loadOAuthConfig() !== null;
|
|
@@ -93,12 +93,12 @@ function resetOAuthConfigCache() {
|
|
|
93
93
|
}
|
|
94
94
|
function getAuthModeDescription() {
|
|
95
95
|
if (isOAuthEnabled()) {
|
|
96
|
-
return
|
|
96
|
+
return 'OAuth mode (per-user authentication via GitLab Device Flow)';
|
|
97
97
|
}
|
|
98
98
|
if (process.env.GITLAB_TOKEN) {
|
|
99
|
-
return
|
|
99
|
+
return 'Static token mode (shared GITLAB_TOKEN)';
|
|
100
100
|
}
|
|
101
|
-
return
|
|
101
|
+
return 'Unauthenticated mode (tools/list only, tool calls require GITLAB_TOKEN)';
|
|
102
102
|
}
|
|
103
103
|
function isStaticTokenConfigured() {
|
|
104
104
|
return !!process.env.GITLAB_TOKEN;
|