forked from zereight/gitlab-mcp
-
Notifications
You must be signed in to change notification settings - Fork 1
Permalink
Choose a base ref
{{ refName }}
default
Choose a head ref
{{ refName }}
default
Comparing changes
Choose two branches to see what’s changed or to start a new pull request.
If you need to, you can also or
learn more about diff comparisons.
Open a pull request
Create a new pull request by comparing changes across two branches. If you need to, you can also .
Learn more about diff comparisons here.
base repository: structured-world/gitlab-mcp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v6.54.0
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
...
head repository: structured-world/gitlab-mcp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v6.55.0
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
- 3 commits
- 51 files changed
- 3 contributors
Commits on Feb 4, 2026
-
feat(multi-instance): Multi-Instance OAuth Federation with per-sessio…
…n introspection (#277) * feat(oauth): add multi-instance OAuth federation infrastructure - Add InstanceRegistry service for managing multiple GitLab instances - Add InstanceRateLimiter for per-instance concurrent request limiting - Add instance configuration schema and loader (YAML/JSON/env var support) - Extend TokenContext with apiUrl for per-request instance routing - Extend OAuthSession with gitlabApiUrl for session-to-instance binding - Update enhancedFetch to use context URL with rate limiting integration - Update ConnectionManager for per-instance introspection caching - Add gitlabApiUrl field to Prisma schema for PostgreSQL storage - Add unit tests for InstanceRateLimiter and instance config schemas This lays the foundation for #274 multi-instance support. Users can now configure multiple GitLab instances via GITLAB_INSTANCES env var or GITLAB_INSTANCES_FILE config file. Per-session instance routing and rate limiting are handled automatically. Related to #274 * test(multi-instance): add comprehensive tests for instance infrastructure - Add unit tests for instances-loader (config loading from file/env/legacy) - Add unit tests for InstanceRegistry (singleton, registration, rate limiting) - Add integration tests for InstanceRegistry (real GitLab interaction) These tests verify the multi-instance OAuth federation infrastructure introduced in the previous commit: - Configuration loading from YAML/JSON files and environment variables - Instance registration and URL normalization - Per-instance rate limiting with slot acquisition - Introspection caching with TTL - Connection status tracking - Integration with ConnectionManager Related to #274 * feat(multi-instance): add namespace tier detection, CLI commands, and context switching - Add NamespaceTierDetector service with per-session caching (5-min TTL) - GraphQL query for namespace plan detection - Feature availability mapping per tier (free/premium/ultimate) - CRITICAL: tier is per-NAMESPACE, not per-instance (gitlab.com users may have mixed) - Add CLI instance management commands (instances-command.ts) - list: show configured instances - add: interactive instance configuration - remove: guidance for removal - test: connection testing with version info - info: detailed instance information - sample-config: generate yaml/json templates - Extend OAuth flow with instance selection - AuthCodeFlowState/DeviceFlowState now carry selectedInstance/selectedInstanceLabel - callback.ts and authorize.ts use selectedInstance for session gitlabApiUrl - Add context switching support (blocked in OAuth mode) - ContextManager.switchInstance() for static token mode - Clears namespace tier cache on switch - Re-initializes ConnectionManager for new instance - Sends tools/list_changed notification to clients - Extend ConnectionManager with reinitialize() for instance switching Related to #274 * docs(multi-instance): add comprehensive documentation for multi-instance support - Add docs/guide/multi-instance.md - getting started guide - Add docs/advanced/federation.md - architecture deep dive - Add docs/advanced/tier-detection.md - namespace tier detection explanation - Add docs/advanced/context-switching.md - instance switching behavior - Add docs/configuration/instances.md - instance configuration reference - Add docs/configuration/rate-limiting.md - rate limiting reference - Add docs/cli/instances.md - CLI commands reference - Update README.md with multi-instance section - Update sidebar navigation in vitepress config Related to #274 * fix(multi-instance): improve security and URL parsing robustness - Mask OAuth clientSecret when displaying instance configuration - Use password prompt instead of text for OAuth secret input - Fix npm -> yarn in YAML package install message - Add isExpired field to InstanceSummary introspection for TTL awareness - Fix port vs OAuth client ID parsing (use valid port range 1-65535) - Strip paths/query/fragments from GitLab URLs in schema - Add space-separated URL support in GITLAB_INSTANCES parsing - Document rate limit slot retention during retries - Document per-instance TLS limitation - Clarify reinitialize() URL handling in ConnectionManager Related to #274 * test(tier-detector): add unit tests for NamespaceTierDetector - Add comprehensive unit tests for getFeaturesForTier() - Add tests for clearNamespaceTierCache() with session-specific clearing - Add tests for getNamespaceTier() including GraphQL queries - Add tests for cache TTL expiration (5 min) - Add tests for plan name normalization (gold/silver/bronze) - Add tests for isFeatureAvailable() and cache metrics - Coverage: 97.64% statements, 93.02% branches, 100% functions * fix(cli): enumerate safe fields in config display Replace spread operator with explicit field list when showing instance configuration to user. Displays url, label, oauth.clientId, oauth.scopes, and hasSecret flag without exposing actual secrets. * fix(cli): remove oauth field access from config logging Show only oauthConfigured boolean flag instead of accessing oauth object fields. Satisfies CodeQL sensitive data rule. * test(cli): instances-command and instances-loader unit tests - instances-command: list, add, remove, test, info, sample-config - instances-loader: YAML loading, space-separated URLs parsing - addInstance: OAuth flow, cancel handling at each prompt step - testInstance: HTTP responses, network errors, registry init - showInstanceInfo: full info display, missing optional fields * fix(config): support subpath GitLab deployments and improve URL parsing - instances-schema: preserve pathname in GitLabUrlSchema for subpath deployments - instances-schema: rewrite parseInstanceUrlString with right-to-left parsing - instances-schema: distinguish port numbers (1-65535) from OAuth clientIds - instances-loader: handle both MODULE_NOT_FOUND and ERR_MODULE_NOT_FOUND - ConnectionManager: document multi-instance GraphQL endpoint limitation - fetch: document extractBaseUrl subpath limitation * test(rate-limiter): queue timeout rejection scenario Add test for queued request timeout after queueTimeout expires. Validates that requests waiting in queue are properly rejected with timing out error when the configured timeout is reached. * test(multi-instance): add OAuth mode and instance switching tests - Add OAuth unauthenticated version detection tests - Add ensureIntrospected caching path tests - Add reinitialize method tests - Add switchInstance tests (OAuth blocked, static mode) - Add invalid scope configuration tests - Add reset without initial context test * test(config): add module export tests for index files - Add tests for cli/instances/index.ts exports - Add tests for config/index.ts exports * test(context-manager): add switchInstance success path test - Add mocks for ConnectionManager.reinitialize and clearNamespaceTierCache - Add test verifying successful instance switch completes correctly - Validates scope clearing, notification sending, and return values * fix(multi-instance): dynamic GraphQL endpoint selection for OAuth - Add setEndpoint() method to GraphQLClient for runtime endpoint switching - Update ensureIntrospected() to derive endpoint from token context apiUrl - Update initialize() to accept optional instanceUrl parameter - Fix extractBaseUrl() to preserve subpath for GitLab deployments - Add rateLimitBaseUrl parameter in NamespaceTierDetector - Fix sessionId parsing with lastIndexOf for cache metrics * fix(security): mask sensitive OAuth data in CLI output - Remove clientId from instance info display (show only "configured") - Mask clientSecret in JSON sample config output * test(cli): verify OAuth data masking in instances command - Add test for clientSecret masking in JSON sample config - Add test for invalid JSON fallback behavior - Verify clientId is not exposed in instance info output * fix(multi-instance): subpath support and instance URL tracking - Fix extractBaseUrl to handle API suffix in middle of path (indexOf vs endsWith) - Preserve subpath in GraphQL endpoint derivation (e.g., /gitlab/api/v4 -> /gitlab/api/graphql) - Add getCurrentInstanceUrl() method to ConnectionManager - Fix previousUrl in switchInstance to use actual current instance - Update test comment to reflect lastIndexOf usage * test(ConnectionManager): add getCurrentInstanceUrl tests - Test null return before initialization - Test instance URL return after initialization - Test null return after reset * test(multi-instance): add OAuth endpoint derivation and cache tests - Add tests for OAuth GraphQL endpoint transformation (/api/v4 -> /api/graphql) - Add tests for InstanceRegistry introspection cache path - Add tests for extractBaseUrl function with subpath handling - Fix GraphQLClient mock to include endpoint property - Export extractBaseUrl for direct unit testing * fix(multi-instance): registry init check and cross-platform path handling - Add InstanceRegistry.isInitialized() guard in switchInstance() - Replace process.env.HOME with os.homedir() in instances-loader - Sync docs OAuth display format with actual CLI output - Correct env var name in instances-loader module docstring - Add explanatory notes on endpoint mutation and rate limit semantics * feat(multi-instance): add per-instance connection pool with HTTP/2 support - Add InstanceConnectionPool service managing per-instance HTTP connections - Implement Undici Pool with keepalive and connection multiplexing - Add getGraphQLClient() to InstanceRegistry for thread-safe client access - Add getInstanceClient() to ConnectionManager for per-instance clients - Remove singleton endpoint mutation in favor of per-instance clients - Support per-instance TLS configuration (insecureSkipVerify) * test(connection-pool): add unit tests for InstanceConnectionPool - Test singleton pattern and configuration - Test getGraphQLClient with auth headers and reuse - Test getDispatcher for pool access - Test getStats and getInstanceStats - Test destroyPool and destroyAll cleanup - Test URL normalization (trailing slash, /api/v4, /api/graphql) - Test TLS configuration (insecureSkipVerify) - 31 tests covering all public methods * docs(cli): clarify non-sensitive data in console output - logConfigPreview explicitly excludes OAuth credentials - sample-config outputs placeholder values, not real data * fix(registry): add /api/graphql suffix stripping to normalizeUrl Align InstanceRegistry.normalizeUrl() with InstanceConnectionPool to handle GraphQL endpoint URLs consistently across both services. * docs(multi-instance): clarify design decisions in code - Explain scope clearing order in switchInstance() - Document setHeaders thread-safety in connection pool - Note pool stats availability for future HTTP/2 integration * fix(multi-instance): use per-instance detectors in ensureIntrospected - Create GitLabVersionDetector with per-instance client when URL differs - Create SchemaIntrospector with per-instance client when URL differs - Ensures introspection targets correct GitLab instance in OAuth mode * test(multi-instance): verify ensureIntrospected and normalizeUrl - Test ensureIntrospected early return when already introspected - Test InstanceRegistry URL normalization for /api/graphql suffix * fix(pool): use Proxy pattern for thread-safe auth header injection - Replace setHeaders mutation with request-level header injection - Avoid cross-session header leakage in concurrent OAuth scenarios - Base GraphQL client remains headerless (shared per instance) - Proxy intercepts request/rawRequest calls to merge auth headers * test(context): assert scope cleared after failed switchInstance - Verify hasScope() returns false after switch attempt fails - Complete test coverage for switchInstance error path * fix(pool): add explicit return types to Proxy handler - Satisfy @typescript-eslint/no-unsafe-return rule - Add RequestFn type alias for cleaner code * fix(pool): correct Proxy header injection for graphql-request API - Only merge headers when 3+ args (last arg is requestHeaders) - For 1-2 args, append headers as new argument - Add tests for request/rawRequest header injection scenarios - Verify headers don't pollute variables object * fix(config): normalize URL and cache key consistency - Add /api/graphql suffix stripping to getInstanceByUrl and GitLabUrlSchema - Support whitespace-separated URLs (space, tab, newline) in env var - Use instanceUrl as introspection cache key for multi-instance consistency * test(registry): verify pool stats and GraphQL client retrieval - Test getGraphQLClient returns client for registered instances - Test getConnectionPoolStats and getInstancePoolStats methods - Test resetWithPools destroys connection pools - Test /api/graphql URL normalization in getInstanceByUrl * fix(rate-limiter): make release() idempotent to prevent counter corruption - Wrap release function with guard to ignore duplicate calls - Add /api/graphql suffix stripping to legacy GITLAB_API_URL normalization - Add tests verifying double-release is safely ignored * fix(connection): track introspected instance URL for multi-instance safety - Add introspectedInstanceUrl field to track which instance is cached - Only return early from ensureIntrospected() if same instance - Prevents using wrong instance's schema data in multi-instance OAuth * test(loader): verify /api/graphql stripping from GITLAB_API_URL * test(instances-schema): add edge case tests for URL normalization - Add test for /api/graphql suffix stripping - Add test for subpath with trailing slash normalization - Add test for subpath preservation with API suffix removal - Add test for double-slash edge case that normalizes to origin - Add test for invalid URL with protocol but malformed structure Improves line coverage to 100% for instances-schema.ts. * fix: address Copilot review threads - Fix cache key mismatch between initialize() and ensureIntrospected() by adding fallback lookup for legacy endpoint-keyed cache entries - Fix extractBaseUrl() to validate API suffix is complete path segment preventing false matches on paths like /api/v4foo - Fix RateLimitMetrics docs to match actual interface (no instanceUrl) - Fix test to assert successful switch instead of expecting failure * feat(fetch): integrate per-instance HTTP/2 connection pooling Wire InstanceConnectionPool's Undici dispatchers into enhancedFetch: - Add getDispatcher() to InstanceRegistry for encapsulated access - Modify doFetch() to accept optional instanceDispatcher parameter - Get per-instance dispatcher in enhancedFetch before making requests - Fall back to global dispatcher if instance not yet registered Also fixes Copilot review issues: - Fix extractBaseUrl() to scan for all occurrences of API suffixes - Set introspectedInstanceUrl in initialize() to avoid re-introspection - Clear introspectedInstanceUrl in reset() to prevent stale cache This enables true HTTP/2 multiplexing and connection reuse per-instance, with per-instance TLS configuration support. * test(fetch): add per-instance dispatcher tests and document connection pool - Add static import of InstanceRegistry for test isolation - Add getDispatcher tests for registered/unregistered instances - Add rate limit slot acquisition test with registry initialized - Document InstanceConnectionPool architecture in federation.md - Update request flow diagram with HTTP/2 connection pool layer * fix(multi-instance): correct introspected instance URL tracking and lazy pool creation - Use baseUrl instead of GITLAB_BASE_URL for introspectedInstanceUrl in initialize() - Add lazy pool creation in getDispatcher() for registered instances - Ensures per-instance TLS settings are applied for REST-only calls - Add test for lazy pool creation behavior * fix(multi-instance): use origin for Undici Pool and reduce log noise - Extract origin from normalized URL for Undici Pool creation - Fixes subpath-deployed GitLab instances (e.g., https://example.com/gitlab) - Change unregistered instance rate limit log from warn to debug level * fix(cli): mask clientSecret in sample config output and deprecate setEndpoint - Mask clientSecret in both JSON and YAML sample config formats - Use allowlist pattern for config preview logging - Deprecate GraphQLClient.setEndpoint() for per-instance clients * fix(rate-limiter): add bounds check to prevent negative activeRequests - Add Math.max(0, ...) guard in release() to handle edge cases - Expand extractBaseUrl comment explaining nested loop necessity * docs: clarify security and design decisions in code comments - instances-command.ts: note that config with secrets never reaches logging - instances-schema.ts: explain multi-strategy parsing rationale - fetch.ts: add thundering herd note for slot retention during backoff * docs(fetch): clarify global vs per-instance dispatcher TLS handling - Update createDispatcher JSDoc to explain fallback-only role - Add security note about non-sensitive fields in CLI output * docs: expand inline explanations for regex masking and loop exit - instances-command.ts: document YAML regex pattern coverage - fetch.ts: clarify labeled break exits both loops on match * docs: clarify sessionId format and URL parsing rationale - NamespaceTierDetector: note that sessionId is UUID (no colons) - fetch.ts: explain why endsWith won't work for mid-path suffixes - instances-command.ts: note regex won't re-match masked values * docs(cli): explain why clientId is shown in output User just entered the clientId and needs the exact value for their config.
Configuration menu - View commit details
-
Copy full SHA for 1fc0a8f - Browse repository at this point
Copy the full SHA 1fc0a8fView commit details -
chore(deps): bump npm from 11.7.0 to 11.9.0 (#280)
Bumps [npm](https://github.com/npm/cli) from 11.7.0 to 11.9.0. - [Release notes](https://github.com/npm/cli/releases) - [Changelog](https://github.com/npm/cli/blob/latest/CHANGELOG.md) - [Commits](npm/cli@v11.7.0...v11.9.0) --- updated-dependencies: - dependency-name: npm dependency-version: 11.9.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dmitry Prudnikov <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 9244d69 - Browse repository at this point
Copy the full SHA 9244d69View commit details -
Configuration menu - View commit details
-
Copy full SHA for 22b5a72 - Browse repository at this point
Copy the full SHA 22b5a72View commit details
Loading
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff v6.54.0...v6.55.0