Skip to content

Conversation

@sazap10
Copy link
Contributor

@sazap10 sazap10 commented Oct 9, 2025

Goal

Moves auth requirements to within clients and make client initialization into a separate module.

Design

Moving auth to within the client makes it easier to identify what configuration is required for each client. Also this is a precursor to adding support for http/sse.

Changeset

  • Adds client registry to handle client initialization
  • Moves env config to within clients

Testing

  • Local testing to ensure clients still start correctly

Copilot AI review requested due to automatic review settings October 9, 2025 09:32
@sazap10 sazap10 requested review from a team as code owners October 9, 2025 09:32
@github-actions
Copy link
Contributor

github-actions bot commented Oct 9, 2025

🎯 Coverage Target Met!

📈 Coverage Metrics

Metric Coverage Target Status
Lines 85.5% 80%
Functions 83.2% 80%
Branches 86.4% 80%
Statements 85.5% 80%

📊 Test Statistics

  • Total Lines: 6,006 / 7,026
  • Total Functions: 134 / 161
  • Total Branches: 546 / 632
  • Total Statements: 6006 / 7026

🔍 Files Needing Coverage

File Coverage
src/bugsnag/client/api/CurrentUser.ts 0.0%
src/bugsnag/client/api/Error.ts 0.0%
src/bugsnag/client/api/Project.ts 0.0%
src/bugsnag/client/api/index.ts 0.0%
src/common/client-factory.ts 0.0%

📝 Report generated on Node.js v24.10.0 • View workflow • Coverage by Vitest + v8

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the MCP client architecture by moving authentication handling into individual client classes and introducing a centralized client registry system. The changes eliminate hardcoded client initialization in the main entry point and make the system more extensible for future client additions.

  • Implements a client registry pattern for dynamic client discovery and initialization
  • Adds standardized authentication configuration methods to all client classes
  • Centralizes client setup logic into a factory function with consistent error handling

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/index.ts Replaces manual client initialization with registry-based setup
src/common/types.ts Adds authentication configuration interfaces
src/common/client-registry.ts Implements central client registry system
src/common/client-factory.ts Creates factory for environment-based client initialization
src/common/register-clients.ts Registers all available clients with the registry
src/zephyr/client.ts Adds authentication config and fromEnv method
src/reflect/client.ts Adds authentication config and fromEnv method
src/qmetry/client.ts Adds authentication config and fromEnv method
src/pactflow/client.ts Adds authentication config and fromEnv method
src/bugsnag/client.ts Adds authentication config and fromEnv method
src/api-hub/client.ts Adds authentication config and fromEnv method

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +84 to +86
if (!token) {
return null;
}
Copy link

Copilot AI Oct 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is redundant since the same validation is performed in the loop above (lines 73-80). The loop already ensures all required auth values are present, making this additional check unnecessary.

Suggested change
if (!token) {
return null;
}

Copilot uses AI. Check for mistakes.
"initialize" in client &&
typeof client.initialize === "function"
) {
await (client as any).initialize();
Copy link

Copilot AI Oct 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using 'any' type assertion bypasses TypeScript's type safety. Consider casting to a more specific interface that defines the initialize method, or create a proper interface for clients that support async initialization.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +18
if ("getAuthConfig" in entry.clientClass) {
const config = (entry.clientClass as any).getAuthConfig();
Copy link

Copilot AI Oct 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using 'any' type assertion bypasses TypeScript's type safety. Consider extending the ClientClass interface to include an optional getAuthConfig method, or create a separate interface for clients that support auth configuration.

Copilot uses AI. Check for mistakes.
// Perform async initialization if needed
if (
entry.asyncInit &&
"initialize" in client &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we add initialize to the interface as an optional method and just call it asynchronously (if non-null) anyway?

Similarly, passing a reference to the server in each client constructor seems reasonable, without the complication of making it only on some clients.

for (const entry of clientRegistry.getAll()) {
try {
// Create client from environment variables
const client = entry.needsMcpServer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it better to push the env-reading outside the client so that it can be agnostic to where the config values come from – then the entry point main or a webserver init can loop through the expected config (from getAuthConfig) and get it from env or headers in a map to init clients with.

Perhaps the new ClientRegistry is where that should live and it can be subclassed to fetch from the appropriate store (e.g. StdioCientRegistry).

What if we zod-typed the config requirements and the client expects to have an object of that type passed into its constructor?

@sazap10 sazap10 marked this pull request as draft October 9, 2025 12:27
@sazap10
Copy link
Contributor Author

sazap10 commented Oct 9, 2025

Needs a bit more thinking about how auth would work for http/sse

@sazap10
Copy link
Contributor Author

sazap10 commented Oct 22, 2025

closing in favour of the #196 pr which adds hosted server support and builds on top of this. Most the comments have been addressed via a refactor

@sazap10 sazap10 closed this Oct 22, 2025
@sazap10 sazap10 deleted the refactor_client_initialization_auth branch October 22, 2025 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants