feat: implement multi-client API key support for MCP server#41
feat: implement multi-client API key support for MCP server#41Patrick-Ehimen merged 1 commit intomainfrom
Conversation
Reviewer's GuideIntroduces per-request API key authentication and service isolation by integrating AuthManager and LighthouseServiceFactory into the MCP server, extends the registry for context-aware tool execution, enhances key validation and error handling, and maintains backward compatibility with single-key deployments. Sequence diagram for per-request API key authentication and tool executionsequenceDiagram
actor Client
participant Server as "LighthouseMCPServer"
participant Auth as "AuthManager"
participant Factory as "LighthouseServiceFactory"
participant Registry as "ToolRegistry"
participant Tool as "Tool Instance"
Client->>Server: CallTool request (with optional apiKey)
Server->>Auth: authenticate(apiKey)
Auth-->>Server: authResult (success/failure, keyHash, fallback)
alt Authentication success
Server->>Auth: getEffectiveApiKey(apiKey)
Auth-->>Server: effectiveApiKey
Server->>Factory: getService(effectiveApiKey)
Factory-->>Server: service instance
Server->>Registry: executeToolWithContext(toolName, args, context)
Registry->>Tool: execute(args)
Tool-->>Registry: result
Registry-->>Server: result
Server-->>Client: tool execution result
else Authentication failure
Server-->>Client: AuthenticationError (MCP-compliant)
end
Class diagram for new and updated authentication and error handling classesclassDiagram
class LighthouseMCPServer {
-authManager: AuthManager
-serviceFactory: LighthouseServiceFactory
+handleCallTool(request)
+routeToolCall(toolName, params, context)
+getAuthManager()
+getServiceFactory()
+getAuthStats()
+invalidateApiKey(apiKey)
}
class AuthManager {
+authenticate(apiKey)
+getEffectiveApiKey(apiKey)
+invalidateKey(apiKey)
+getCacheStats()
+destroy()
}
class LighthouseServiceFactory {
+getService(apiKey)
+removeService(apiKey)
+getStats()
+destroy()
}
class ToolRegistry {
+executeToolWithContext(name, args, context)
-executeToolWithService(name, args, context)
}
class RequestContext {
+apiKey: string
+keyHash: string
+service
+toolName: string
+toLogContext()
}
class AuthenticationError {
+type: AuthErrorType
+keyHash: string
+retryAfter: number
+toMcpError()
+static missingApiKey()
+static invalidApiKey(keyHash)
+static expiredApiKey(keyHash)
+static rateLimited(keyHash, retryAfter)
+static validationFailed(keyHash, reason)
}
class AuthErrorType
class ToolInstance
LighthouseMCPServer --> AuthManager
LighthouseMCPServer --> LighthouseServiceFactory
LighthouseMCPServer --> ToolRegistry
ToolRegistry --> RequestContext
ToolRegistry --> ToolInstance
AuthManager --> AuthenticationError
AuthenticationError --> AuthErrorType
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey there - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `apps/mcp-server/src/server.ts:236` </location>
<code_context>
+ text: string;
+ }>;
+ }> {
+ // Remove apiKey from params before passing to tool
+ const { apiKey: _apiKey, ...toolParams } = params;
+
</code_context>
<issue_to_address>
**issue (bug_risk):** Removing apiKey from tool parameters may break tools expecting it.
Verify that all tools used with `executeToolWithContext` do not depend on the `apiKey` parameter, or update them as needed to prevent unexpected failures.
</issue_to_address>
### Comment 2
<location> `apps/mcp-server/src/auth/AuthManager.ts:187-196` </location>
<code_context>
+ return false;
+ }
+
+ // For testing, accept keys that match the default key or start with "test-api-key"
+ if (this.config.defaultApiKey && apiKey === this.config.defaultApiKey) {
+ return true;
+ }
+
+ // Accept test keys for testing
+ if (apiKey.startsWith("test-api-key") || apiKey.startsWith("key-")) {
+ return true;
+ }
+
+ // Reject other keys (in production, this would call Lighthouse API)
+ return false;
}
</code_context>
<issue_to_address>
**🚨 issue (security):** Key validation logic is hardcoded for testing.
Make sure this test key acceptance logic is excluded from production, or strictly controlled by environment settings, to avoid security risks.
</issue_to_address>
### Comment 3
<location> `apps/mcp-server/src/tests/integration/server-authentication.test.ts:4` </location>
<code_context>
+ if (!SecureKeyHandler.isValidFormat(apiKey)) {
+ return false;
+ }
+
+ // For testing, accept keys that match the default key or start with "test-api-key"
+ if (this.config.defaultApiKey && apiKey === this.config.defaultApiKey) {
</code_context>
<issue_to_address>
**suggestion (testing):** Missing test coverage for rate limiting and service pool eviction edge cases.
Add integration tests for scenarios where an API key exceeds its rate limit and when the service pool evicts the oldest service upon reaching maximum capacity.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| text: string; | ||
| }>; | ||
| }> { | ||
| // Remove apiKey from params before passing to tool |
There was a problem hiding this comment.
issue (bug_risk): Removing apiKey from tool parameters may break tools expecting it.
Verify that all tools used with executeToolWithContext do not depend on the apiKey parameter, or update them as needed to prevent unexpected failures.
| // For testing, accept keys that match the default key or start with "test-api-key" | ||
| if (this.config.defaultApiKey && apiKey === this.config.defaultApiKey) { | ||
| return true; | ||
| } | ||
|
|
||
| // Accept test keys for testing | ||
| if (apiKey.startsWith("test-api-key") || apiKey.startsWith("key-")) { | ||
| return true; | ||
| } | ||
|
|
There was a problem hiding this comment.
🚨 issue (security): Key validation logic is hardcoded for testing.
Make sure this test key acceptance logic is excluded from production, or strictly controlled by environment settings, to avoid security risks.
Overview
This PR implements comprehensive multi-client API key support for the Lighthouse MCP server, enabling multiple clients to use different API keys while maintaining backward compatibility with existing single-key deployments.
🚀 Key Features
Per-Request Authentication
apiKeyparameterService Isolation
Security & Error Handling
AuthenticationErrorclass with MCP-compliant error formattingBackward Compatibility
Summary by Sourcery
Enable robust multi-client API key support on the MCP server by adding request-level authentication, per-key service pooling, standardized error handling, and retaining compatibility with existing single-key setups.
New Features:
Enhancements:
Tests: