Conversation
- 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
…ture - 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
… 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
…nce 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
Test Coverage ReportOverall Coverage: 95.74%
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
Implements multi-instance GitLab support (OAuth + config + CLI) by introducing an instance registry with per-instance rate limiting and introspection caching, and by extending OAuth session/context data to carry the selected instance.
Changes:
- Added
InstanceRegistry+InstanceRateLimiterservices and wired rate-limit acquisition intoenhancedFetch. - Added multi-instance configuration system (Zod schema + loader) and new
instancesCLI commands. - Added namespace-tier detection service + extensive documentation and test coverage for the new components.
Reviewed changes
Copilot reviewed 35 out of 35 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/services/InstanceRegistry.test.ts | Unit tests for registry behavior (singleton, URL normalization, caching, rate limits). |
| tests/unit/services/InstanceRateLimiter.test.ts | Unit tests for concurrency + queueing rate limiter behavior and metrics. |
| tests/unit/oauth/token-context.test.ts | Tests for new token-context accessors (apiUrl, instanceLabel). |
| tests/unit/config/instances-schema.test.ts | Tests for instance config schema parsing/defaulting and URL parsing helper. |
| tests/unit/config/instances-loader.test.ts | Tests for instance config loading precedence (file/env/legacy/default) and helpers. |
| tests/integration/services/InstanceRegistry.test.ts | Integration tests exercising registry initialization/caching/metrics with real env. |
| src/utils/fetch.ts | Adds base-URL helper and per-instance rate-limit slot acquisition to enhancedFetch. |
| src/services/NamespaceTierDetector.ts | New per-session namespace tier detection + caching via GraphQL. |
| src/services/InstanceRegistry.ts | New singleton registry managing instance config/state, rate limiters, and introspection cache. |
| src/services/InstanceRateLimiter.ts | New per-instance concurrent rate limiter with queueing and metrics. |
| src/services/ConnectionManager.ts | Initializes registry and adds per-instance introspection caching + reinitialize hook. |
| src/server.ts | Extends token context setup to include apiUrl and instanceLabel. |
| src/oauth/types.ts | Extends OAuth session/state and token context types for multi-instance support. |
| src/oauth/token-context.ts | Adds accessors for apiUrl and instanceLabel from AsyncLocalStorage. |
| src/oauth/storage/postgresql.ts | Persists gitlabApiUrl and instanceLabel in PostgreSQL session storage. |
| src/oauth/index.ts | Re-exports the new token-context helpers. |
| src/oauth/endpoints/callback.ts | Stores selected instance URL/label into the created OAuth session. |
| src/oauth/endpoints/authorize.ts | Stores selected instance URL/label into the created OAuth session (device flow poll). |
| src/middleware/oauth-auth.ts | Exposes session instance URL/label through res.locals for request context. |
| src/entities/context/context-manager.ts | Adds static-token instance switching entrypoint (blocked in OAuth mode). |
| src/config/instances-schema.ts | New Zod schemas/types + URL string parsing helper for instance config formats. |
| src/config/instances-loader.ts | New loader supporting file/env/legacy/default instance configuration sources. |
| src/config/index.ts | New barrel export for instance config modules. |
| src/cli/instances/instances-command.ts | New instances CLI (list/add/remove/test/info/sample-config). |
| src/cli/instances/index.ts | CLI module export for instances commands. |
| prisma/schema.prisma | Adds gitlab_api_url and instance_label fields to OAuthSession. |
| docs/guide/multi-instance.md | New guide explaining setup and behavior for multi-instance mode. |
| docs/configuration/rate-limiting.md | New configuration reference for per-instance concurrency/queue settings. |
| docs/configuration/instances.md | New configuration reference for multi-instance file/env formats. |
| docs/cli/instances.md | New CLI reference for instance management commands. |
| docs/advanced/tier-detection.md | New deep-dive on per-namespace tier detection and caching. |
| docs/advanced/federation.md | New architecture doc for federation/caching layers and request flow. |
| docs/advanced/context-switching.md | New doc explaining instance switching rules/behavior by auth mode. |
| docs/.vitepress/config.mts | Adds navigation entries for new multi-instance docs and CLI/config pages. |
| README.md | Adds a multi-instance section and links to the new documentation. |
- 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
- 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
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.
Show only oauthConfigured boolean flag instead of accessing oauth object fields. Satisfies CodeQL sensitive data rule.
- 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
- 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
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.
- 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
- Add tests for cli/instances/index.ts exports - Add tests for config/index.ts exports
- Add Math.max(0, ...) guard in release() to handle edge cases - Expand extractBaseUrl comment explaining nested loop necessity
- 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
- Update createDispatcher JSDoc to explain fallback-only role - Add security note about non-sensitive fields in CLI output
- instances-command.ts: document YAML regex pattern coverage - fetch.ts: clarify labeled break exits both loops on match
- 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
User just entered the clientId and needs the exact value for their config.
|
🎉 This PR is included in version 6.55.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements full multi-instance GitLab support with OAuth, allowing one MCP server to serve users connecting to different GitLab instances simultaneously. Each user session maintains its own GitLab instance context with proper caching at correct levels.
Closes #274
Changes
Core Infrastructure (Phase 1)
apiUrlfor per-request instance routinggitlabApiUrlandselectedInstancePer-Instance Connection Pooling (NEW)
InstanceRegistry.getDispatcher()provides per-instance Undici dispatcherInstanceRegistry.getGraphQLClient()Configuration System (Phase 2)
os.homedir()CLI Commands (Phase 3)
instances list- List configured instancesinstances add- Interactive instance additioninstances remove- Guidance for removalinstances test- Connection testing with version infoinstances info- Detailed instance informationinstances sample-config- Generate YAML/JSON templatesFeature Availability (Phase 4)
Rate Limiting (Phase 5)
OAuth Flow (Phase 6)
Context Switching (Phase 7)
tools/list_changednotificationDocumentation (Phase 8)
docs/guide/multi-instance.md- Getting started guidedocs/advanced/federation.md- Architecture deep divedocs/advanced/tier-detection.md- Tier detection explanationdocs/advanced/context-switching.md- Instance switching behaviordocs/configuration/instances.md- Configuration referencedocs/configuration/rate-limiting.md- Rate limiting referencedocs/cli/instances.md- CLI commands referenceTest Plan
Architecture Highlights
Thread-Safe Multi-Instance Access
Each instance gets:
Breaking Changes
None - fully backward compatible with existing single-instance configuration.