feat: added validation visual indicator to mcp server list #849
feat: added validation visual indicator to mcp server list #849gastoner merged 13 commits intokortex-hub:mainfrom
Conversation
vancura
left a comment
There was a problem hiding this comment.
I commented on a wrong ticket, see my nitpicking at #609 (comment).
56b4214 to
38b6df0
Compare
📝 WalkthroughWalkthroughAdds per-server schema validity (isValidSchema) across API types, registry flows, manager storage, tests, and renderer UI; introduces a validation-aware icon component and updates registry/validator interactions to compute, propagate, and render per-server validation state. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Registry as MCP Registry
participant Validator as MCPSchemaValidator
participant Manager as MCP Manager
participant UI as Renderer
User->>Registry: request list or add MCP servers
Registry->>Validator: validateSchemaData(server(s))
Validator-->>Registry: per-server validation results (isValidSchema)
Registry->>Registry: enhanceServerDetail(server, isValidSchema)
Registry-->>Manager: registerMCPClient(..., isValidSchema)
Manager->>Manager: store MCPRemoteServerInfo with isValidSchema
Manager-->>UI: expose server list
UI->>UI: render MCPValidServerIndicatorIcon(server)
alt server.isValidSchema === false
UI->>User: show invalid indicator
else
UI->>User: show normal icon
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
packages/main/src/plugin/mcp/mcp-registry.spec.ts (2)
48-52: Reset mock between tests to ensure test isolation.The
validateSchemaDataMockis configured at module level with a default return value, then overridden withmockImplementationin the second test. Without resetting inbeforeEach, tests may affect each other if run in different orders or if more tests are added.🔎 Apply this diff to reset the mock:
beforeEach(() => { console.error = vi.fn(); + validateSchemaDataMock.mockReset(); + validateSchemaDataMock.mockReturnValue(true); mcpRegistry = new MCPRegistry(
56-57: Consider resettingglobalFetchmock inbeforeEachfor robustness.Using
mockResolvedValueOncequeues responses that persist across tests. If a test fails partway through, leftover queued responses could affect subsequent tests.🔎 Apply this diff:
beforeEach(() => { console.error = vi.fn(); + globalFetch.mockReset(); mcpRegistry = new MCPRegistry(packages/main/src/plugin/mcp/mcp-registry.ts (2)
162-166: Consider extracting duplicatehasInvalidSchemaextraction logic.The same pattern for safely extracting
hasInvalidSchemafrom raw server data appears twice (lines 162-166 and 613-617). A small helper would reduce duplication and ensure consistency.🔎 Example helper:
private extractHasInvalidSchema(rawServer: unknown): boolean { return typeof rawServer === 'object' && rawServer !== null && 'hasInvalidSchema' in rawServer && typeof (rawServer as { hasInvalidSchema: unknown }).hasInvalidSchema === 'boolean' ? (rawServer as { hasInvalidSchema: boolean }).hasInvalidSchema : false; }Also applies to: 611-618
529-532: Return type doesn't reflect the augmentedhasInvalidSchemaproperty.The method returns servers with an added
hasInvalidSchemaproperty, but the return typecomponents['schemas']['ServerList']doesn't declare this. While TypeScript allows extra properties, this could cause confusion for callers.Consider defining an augmented return type:
type AugmentedServerResponse = components['schemas']['ServerResponse'] & { hasInvalidSchema: boolean }; type AugmentedServerList = Omit<components['schemas']['ServerList'], 'servers'> & { servers: AugmentedServerResponse[] };
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/api/src/mcp/mcp-server-info.ts(1 hunks)packages/main/src/plugin/mcp/mcp-registry.spec.ts(6 hunks)packages/main/src/plugin/mcp/mcp-registry.ts(4 hunks)packages/renderer/src/lib/images/MCPIcon.svelte(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
packages/renderer/src/**/*.{ts,tsx,svelte}
📄 CodeRabbit inference engine (CLAUDE.md)
Require user confirmation for external URLs through
setupSecurityRestrictionsOnLinkssecurity handler
Files:
packages/renderer/src/lib/images/MCPIcon.svelte
packages/renderer/src/**/*.svelte
📄 CodeRabbit inference engine (CLAUDE.md)
Renderer components should be built with Svelte and import UI APIs from preload bridges
Use renderer process for Svelte-based UI implementation
Files:
packages/renderer/src/lib/images/MCPIcon.svelte
packages/main/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
packages/main/src/**/*.ts: IPC communication handlers should follow the naming convention<registry-name>:<action>(e.g.,container-provider-registry:listContainers) when exposed viaipcHandle()in the main process
UseapiSender.send()in the main process to send real-time event updates to the renderer
Container operations must include theengineIdparameter to identify the container engine when usingContainerProviderRegistrymethods likelistContainers,startContainer,stopContainer,deleteContainer,pullImage,buildImage,deleteImage,createPod,startPod,stopPod, andremovePod
Long-running operations should useTaskManager.createTask()to create tasks with title, action name, and execute callback, then settask.statusto 'success' ortask.erroron completion
UseSafeStorageRegistryfor storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g.,gemini.factory.apiKey) when stored and retrieved viaConfigurationRegistry
Main process types should use TypeScript and import from@kortex-app/apifor provider registration, configuration management, command and menu contributions, and UI component definitions
packages/main/src/**/*.ts: Configuration values should be retrieved and stored with dot notation (e.g., gemini.factory.apiKey)
Long-running operations should use TaskManager to create tasks with title, action, and status management
Container operations should use ContainerProviderRegistry with engineId parameter to identify the container engine, supporting operations like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, removePod
Kubernetes operations should use KubernetesClient for context management, resource CRUD operations, port forwarding, exec into containers, and applying YAML resources
External URLs should require user confirmation, handled through setupSecurityRest...
Files:
packages/main/src/plugin/mcp/mcp-registry.spec.tspackages/main/src/plugin/mcp/mcp-registry.ts
**/*.spec.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests should be co-located with source code as
*.spec.tsfilesUnit tests should be co-located with source code using the *.spec.ts naming convention
Files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
🧠 Learnings (2)
📚 Learning: 2025-11-25T14:41:44.065Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: MCPRegistry should manage MCP registry sources like mcp-get.com, and MCPManager should handle remote MCP server connections and lifecycle
Applied to files:
packages/api/src/mcp/mcp-server-info.tspackages/main/src/plugin/mcp/mcp-registry.spec.ts
📚 Learning: 2025-11-08T14:36:17.423Z
Learnt from: benoitf
Repo: kortex-hub/kortex PR: 692
File: extensions/ramalama/src/inject/inversify-binding.spec.ts:38-38
Timestamp: 2025-11-08T14:36:17.423Z
Learning: In the kortex repository, tests use `vi.mock(import('module-path'))` syntax instead of `vi.mock('module-path')` to ensure TypeScript validates the module path at compile time, providing refactoring safety if modules are moved or removed.
Applied to files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
🧬 Code graph analysis (3)
packages/api/src/mcp/mcp-server-info.ts (1)
packages/extension-api/src/extension-api.d.ts (1)
MCPServerDetail(679-679)
packages/main/src/plugin/mcp/mcp-registry.spec.ts (2)
__mocks__/@kortex-app/api.js (1)
mcpRegistry(23-25)packages/extension-api/src/extension-api.d.ts (1)
MCPRegistry(1502-1506)
packages/main/src/plugin/mcp/mcp-registry.ts (2)
packages/api/src/mcp/mcp-server-info.ts (1)
MCPServerDetail(4-7)packages/extension-api/src/extension-api.d.ts (1)
MCPServerDetail(679-679)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: linter, formatters
- GitHub Check: unit tests / windows-2025
- GitHub Check: smoke e2e tests (development)
- GitHub Check: unit tests / macos-15
- GitHub Check: unit tests / ubuntu-24.04
- GitHub Check: typecheck
- GitHub Check: smoke e2e tests (production)
- GitHub Check: macOS
- GitHub Check: Windows
- GitHub Check: Linux
🔇 Additional comments (5)
packages/api/src/mcp/mcp-server-info.ts (1)
4-7: LGTM!The type extension cleanly adds the required
serverIdand optionalhasInvalidSchemaflag to the baseServerDetailschema. Using an optional boolean for the validation status is appropriate since servers may not always have been validated.packages/renderer/src/lib/images/MCPIcon.svelte (1)
25-29: Good accessibility implementation.The badge correctly includes both
titlefor tooltip andaria-labelfor screen reader support. Using CSS variables for colors ensures proper theming.packages/main/src/plugin/mcp/mcp-registry.spec.ts (1)
120-155: Well-structured test for schema validation flagging.The test properly verifies that
hasInvalidSchemais correctly set based on validation results, covering both valid and invalid server scenarios.packages/main/src/plugin/mcp/mcp-registry.ts (2)
142-144: LGTM!Clean signature update that properly propagates the optional
hasInvalidSchemaflag into the returnedMCPServerDetail.
556-579: Validation logic is well-implemented.Good approach to validate each
ServerResponseindividually with silent mode to avoid log flooding, while still validating the overallServerListstructure. The recursive pagination correctly preserves validation flags.
There was a problem hiding this comment.
Reactivity issue: showInvalidIndicator won't update if object prop changes.
The current assignment runs only once at component initialization. If the object prop is updated after mount, the indicator state will be stale.
🔎 Apply this diff to make it reactive:
-const showInvalidIndicator = object?.hasInvalidSchema;
+$: showInvalidIndicator = object?.hasInvalidSchema;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const showInvalidIndicator = object?.hasInvalidSchema; | |
| $: showInvalidIndicator = object?.hasInvalidSchema; |
🤖 Prompt for AI Agents
In packages/renderer/src/lib/images/MCPIcon.svelte around line 7, the code
currently assigns showInvalidIndicator once with "const showInvalidIndicator =
object?.hasInvalidSchema;" which will not update when the object prop changes;
replace the const with a Svelte reactive declaration so the value re-evaluates
whenever object changes (use "$: showInvalidIndicator =
object?.hasInvalidSchema;"), and remove the old const declaration so the
component UI correctly reflects updates to object.hasInvalidSchema.
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
38b6df0 to
68ee80f
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/main/src/plugin/mcp/mcp-registry.ts (1)
162-166: Consider extracting the hasInvalidSchema extraction logic.This extraction pattern (lines 162-165) is duplicated at lines 613-616. Consider creating a small helper function to reduce duplication:
private extractHasInvalidSchema(rawServer: unknown): boolean { return 'hasInvalidSchema' in rawServer && typeof rawServer.hasInvalidSchema === 'boolean' ? rawServer.hasInvalidSchema : false; }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/api/src/mcp/mcp-server-info.ts(1 hunks)packages/main/src/plugin/mcp/mcp-registry.spec.ts(6 hunks)packages/main/src/plugin/mcp/mcp-registry.ts(4 hunks)packages/renderer/src/lib/images/MCPIcon.svelte(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/renderer/src/lib/images/MCPIcon.svelte
🧰 Additional context used
📓 Path-based instructions (2)
packages/main/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
packages/main/src/**/*.ts: IPC communication handlers should follow the naming convention<registry-name>:<action>(e.g.,container-provider-registry:listContainers) when exposed viaipcHandle()in the main process
UseapiSender.send()in the main process to send real-time event updates to the renderer
Container operations must include theengineIdparameter to identify the container engine when usingContainerProviderRegistrymethods likelistContainers,startContainer,stopContainer,deleteContainer,pullImage,buildImage,deleteImage,createPod,startPod,stopPod, andremovePod
Long-running operations should useTaskManager.createTask()to create tasks with title, action name, and execute callback, then settask.statusto 'success' ortask.erroron completion
UseSafeStorageRegistryfor storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g.,gemini.factory.apiKey) when stored and retrieved viaConfigurationRegistry
Main process types should use TypeScript and import from@kortex-app/apifor provider registration, configuration management, command and menu contributions, and UI component definitions
packages/main/src/**/*.ts: Configuration values should be retrieved and stored with dot notation (e.g., gemini.factory.apiKey)
Long-running operations should use TaskManager to create tasks with title, action, and status management
Container operations should use ContainerProviderRegistry with engineId parameter to identify the container engine, supporting operations like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, removePod
Kubernetes operations should use KubernetesClient for context management, resource CRUD operations, port forwarding, exec into containers, and applying YAML resources
External URLs should require user confirmation, handled through setupSecurityRest...
Files:
packages/main/src/plugin/mcp/mcp-registry.spec.tspackages/main/src/plugin/mcp/mcp-registry.ts
**/*.spec.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests should be co-located with source code as
*.spec.tsfilesUnit tests should be co-located with source code using the *.spec.ts naming convention
Files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
🧠 Learnings (3)
📚 Learning: 2025-11-25T14:41:44.065Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: MCPRegistry should manage MCP registry sources like mcp-get.com, and MCPManager should handle remote MCP server connections and lifecycle
Applied to files:
packages/api/src/mcp/mcp-server-info.tspackages/main/src/plugin/mcp/mcp-registry.spec.ts
📚 Learning: 2025-11-08T14:36:17.423Z
Learnt from: benoitf
Repo: kortex-hub/kortex PR: 692
File: extensions/ramalama/src/inject/inversify-binding.spec.ts:38-38
Timestamp: 2025-11-08T14:36:17.423Z
Learning: In the kortex repository, tests use `vi.mock(import('module-path'))` syntax instead of `vi.mock('module-path')` to ensure TypeScript validates the module path at compile time, providing refactoring safety if modules are moved or removed.
Applied to files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
📚 Learning: 2025-11-25T14:41:20.640Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T14:41:20.640Z
Learning: Use Inversify dependency injection container in `packages/main/src/plugin/index.ts` to register all major services (ProviderRegistry, ContainerProviderRegistry, KubernetesClient, MCPManager, FlowManager, ChatManager, ConfigurationRegistry) as singletons
Applied to files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
🧬 Code graph analysis (1)
packages/api/src/mcp/mcp-server-info.ts (1)
packages/extension-api/src/extension-api.d.ts (1)
MCPServerDetail(679-679)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: unit tests / macos-15
- GitHub Check: typecheck
- GitHub Check: macOS
- GitHub Check: unit tests / ubuntu-24.04
- GitHub Check: Linux
- GitHub Check: smoke e2e tests (production)
- GitHub Check: Windows
- GitHub Check: smoke e2e tests (development)
- GitHub Check: linter, formatters
- GitHub Check: unit tests / windows-2025
🔇 Additional comments (8)
packages/api/src/mcp/mcp-server-info.ts (1)
4-7: LGTM! Clean type extension.The optional
hasInvalidSchemaflag is properly typed and will allow backward compatibility while enabling the visual indicator feature.packages/main/src/plugin/mcp/mcp-registry.spec.ts (3)
19-19: LGTM! Improved test infrastructure.The centralized mocks and per-test setup/teardown enhance test isolation and maintainability.
Also applies to: 48-78
80-118: LGTM! Test correctly migrated to centralized fetch mock.The existing test logic is preserved while aligning with the new mock infrastructure.
120-155: LGTM! Comprehensive test for invalid schema marking.The test correctly validates that servers failing schema validation are marked with
hasInvalidSchema: true, covering the core functionality of this PR.packages/main/src/plugin/mcp/mcp-registry.ts (4)
142-144: LGTM! Clean signature extension.The optional
hasInvalidSchemaparameter is properly propagated to the returnedMCPServerDetailobject.
566-580: LGTM! Validation results correctly propagated in both paths.Both the paginated and non-paginated return paths now use
validatedServers, ensuring thehasInvalidSchemaflag is consistently propagated.
611-619: LGTM! Correct extraction and propagation logic.The
hasInvalidSchemaflag is properly extracted from each server and passed toenhanceServerDetail. Note: The duplication mentioned in the earlier comment also applies here.
556-563: ThevalidateSchemaDatamethod correctly supports the 4th parameter (suppressWarnings: boolean = false). Passingtrueas shown in the code properly suppresses warnings during per-server validation, allowing batch validation to proceed without cluttering logs with individual server-level validation failures. The implementation is sound.
There was a problem hiding this comment.
isssue(blocking): I think this is causing performance issue, the interface looks laggy at start.
For example with the https://registry.modelcontextprotocol.io/,
we call validateSchemaData:
- ServerList: 151 times
- ServerResponse: 4441
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
packages/renderer/src/lib/ui/ListItemButtonIcon.svelte (1)
15-16: Clarify the purpose and lifecycle of thefontAwesomeIconprop.The Icon component from @podman-desktop/ui-svelte supports both IconDefinition and string-based icons, so there is no type incompatibility. However, clarify whether
fontAwesomeIconis a legacy fallback or an intended API:
- If legacy, add a JSDoc
@deprecatedcomment documenting the migration path to usingiconexclusively- If intentional, document the distinction between
iconandfontAwesomeIconand when each should be usedpackages/main/src/plugin/mcp/mcp-registry.spec.ts (1)
48-78: Consider resetting mocks inbeforeEachto prevent test pollution.The
validateSchemaDataMockis shared across tests. While the current tests manage it correctly, addingvi.clearAllMocks()orvalidateSchemaDataMock.mockReset()inbeforeEachwould prevent future test pollution if additional tests are added.🔎 Suggested improvement
beforeEach(() => { console.error = vi.fn(); + validateSchemaDataMock.mockReset().mockReturnValue({ isValid: true, invalidServerNames: new Set<string>() }); mcpRegistry = new MCPRegistry(packages/main/src/plugin/mcp/mcp-schema-validator.ts (2)
47-47: Remove trivial type annotation.The
booleantype can be inferred from the default value.🔎 Suggested fix
- suppressWarnings: boolean = false, + suppressWarnings = false,
61-76: UseNumber.parseIntinstead of globalparseInt.ES2015 moved
parseIntinto theNumbernamespace for consistency. The extraction logic itself is sound and correctly handles edge cases.🔎 Suggested fix
- const serverIndex = parseInt(match[1], 10); + const serverIndex = Number.parseInt(match[1], 10);
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/main/src/plugin/mcp/mcp-registry.spec.ts(6 hunks)packages/main/src/plugin/mcp/mcp-registry.ts(4 hunks)packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts(11 hunks)packages/main/src/plugin/mcp/mcp-schema-validator.ts(3 hunks)packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte(2 hunks)packages/renderer/src/lib/ui/ListItemButtonIcon.svelte(2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
packages/main/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
packages/main/src/**/*.ts: IPC communication handlers should follow the naming convention<registry-name>:<action>(e.g.,container-provider-registry:listContainers) when exposed viaipcHandle()in the main process
UseapiSender.send()in the main process to send real-time event updates to the renderer
Container operations must include theengineIdparameter to identify the container engine when usingContainerProviderRegistrymethods likelistContainers,startContainer,stopContainer,deleteContainer,pullImage,buildImage,deleteImage,createPod,startPod,stopPod, andremovePod
Long-running operations should useTaskManager.createTask()to create tasks with title, action name, and execute callback, then settask.statusto 'success' ortask.erroron completion
UseSafeStorageRegistryfor storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g.,gemini.factory.apiKey) when stored and retrieved viaConfigurationRegistry
Main process types should use TypeScript and import from@kortex-app/apifor provider registration, configuration management, command and menu contributions, and UI component definitions
packages/main/src/**/*.ts: Configuration values should be retrieved and stored with dot notation (e.g., gemini.factory.apiKey)
Long-running operations should use TaskManager to create tasks with title, action, and status management
Container operations should use ContainerProviderRegistry with engineId parameter to identify the container engine, supporting operations like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, removePod
Kubernetes operations should use KubernetesClient for context management, resource CRUD operations, port forwarding, exec into containers, and applying YAML resources
External URLs should require user confirmation, handled through setupSecurityRest...
Files:
packages/main/src/plugin/mcp/mcp-schema-validator.tspackages/main/src/plugin/mcp/mcp-schema-validator.spec.tspackages/main/src/plugin/mcp/mcp-registry.tspackages/main/src/plugin/mcp/mcp-registry.spec.ts
**/*.spec.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests should be co-located with source code as
*.spec.tsfilesUnit tests should be co-located with source code using the *.spec.ts naming convention
Files:
packages/main/src/plugin/mcp/mcp-schema-validator.spec.tspackages/main/src/plugin/mcp/mcp-registry.spec.ts
packages/renderer/src/**/*.{ts,tsx,svelte}
📄 CodeRabbit inference engine (CLAUDE.md)
Require user confirmation for external URLs through
setupSecurityRestrictionsOnLinkssecurity handler
Files:
packages/renderer/src/lib/ui/ListItemButtonIcon.sveltepackages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
packages/renderer/src/**/*.svelte
📄 CodeRabbit inference engine (CLAUDE.md)
Renderer components should be built with Svelte and import UI APIs from preload bridges
Use renderer process for Svelte-based UI implementation
Files:
packages/renderer/src/lib/ui/ListItemButtonIcon.sveltepackages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
🧠 Learnings (3)
📚 Learning: 2025-11-08T14:36:17.423Z
Learnt from: benoitf
Repo: kortex-hub/kortex PR: 692
File: extensions/ramalama/src/inject/inversify-binding.spec.ts:38-38
Timestamp: 2025-11-08T14:36:17.423Z
Learning: In the kortex repository, tests use `vi.mock(import('module-path'))` syntax instead of `vi.mock('module-path')` to ensure TypeScript validates the module path at compile time, providing refactoring safety if modules are moved or removed.
Applied to files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
📚 Learning: 2025-11-25T14:41:44.065Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: MCPRegistry should manage MCP registry sources like mcp-get.com, and MCPManager should handle remote MCP server connections and lifecycle
Applied to files:
packages/main/src/plugin/mcp/mcp-registry.spec.tspackages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
📚 Learning: 2025-11-25T14:41:20.640Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T14:41:20.640Z
Learning: Applies to packages/main/src/**/*.ts : Main process types should use TypeScript and import from `kortex-app/api` for provider registration, configuration management, command and menu contributions, and UI component definitions
Applied to files:
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
🪛 Biome (2.1.2)
packages/main/src/plugin/mcp/mcp-schema-validator.ts
[error] 47-47: This type annotation is trivially inferred from its initialization.
Safe fix: Remove the type annotation.
(lint/style/noInferrableTypes)
[error] 69-69: Use Number.parseInt instead of the equivalent global.
ES2015 moved some globals into the Number namespace for consistency.
Safe fix: Use Number.parseInt instead.
(lint/style/useNumberNamespace)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: unit tests / macos-15
- GitHub Check: unit tests / ubuntu-24.04
- GitHub Check: smoke e2e tests (development)
- GitHub Check: macOS
- GitHub Check: typecheck
- GitHub Check: smoke e2e tests (production)
- GitHub Check: unit tests / windows-2025
- GitHub Check: Windows
- GitHub Check: Linux
- GitHub Check: linter, formatters
🔇 Additional comments (13)
packages/renderer/src/lib/ui/ListItemButtonIcon.svelte (1)
132-132: No action required. The Icon component from@podman-desktop/ui-svelteproperly handles both string-based icons and FontAwesomeIconDefinitionobjects using theisFontAwesomeIcon()type guard, which checks for FontAwesome-specific properties (iconName,prefix). All actual usages of ListItemButtonIcon pass FontAwesome IconDefinitions, and the fallbackicon ?? fontAwesomeIconis type-safe because it produces values compatible with Icon's multi-branch rendering logic.packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte (3)
22-22: LGTM!Type inference from the
$derivedreactive variable is appropriate here and simplifies the code.
24-27: LGTM!The targets array now correctly includes both remotes and packages, providing comprehensive MCP server options to users.
61-61: LGTM!Passing the server detail object enables the icon component to access the
hasInvalidSchemaproperty for visual indication, which aligns with the PR objectives.packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts (2)
53-56: LGTM!Test assertions correctly validate the new
SchemaValidationResultstructure with bothisValidandinvalidServerNamesproperties.
281-431: Excellent test coverage for invalid server extraction.The new test suite comprehensively validates the
invalidServerNamesextraction logic, covering valid servers, missing fields, multiple invalids, and pattern violations.packages/main/src/plugin/mcp/mcp-registry.spec.ts (2)
80-118: LGTM!The test correctly uses the global fetch mock and validates error handling and server listing functionality.
120-151: LGTM!The test effectively validates that servers with invalid schemas are correctly marked with the
hasInvalidSchemaflag based on validation results.packages/main/src/plugin/mcp/mcp-schema-validator.ts (2)
22-26: LGTM!The
SchemaValidationResultinterface is well-designed with clear documentation about wheninvalidServerNamesis populated.
78-82: LGTM!The return value correctly implements the
SchemaValidationResultinterface.packages/main/src/plugin/mcp/mcp-registry.ts (3)
142-144: LGTM!The
enhanceServerDetailfunction correctly propagates thehasInvalidSchemaflag to the server detail object.
162-166: LGTM!Safe extraction of
hasInvalidSchemawith proper type guards and sensible default value.
610-618: LGTM!The server mapping correctly extracts and propagates the
hasInvalidSchemaflag, consistent with the pattern used elsewhere in the codebase.
|
@simonrey1 I've changed the logic slightly, now only the ServerList is validated and the list of invalid servers are used, so no ServerResponse validation ✔️ but I'm afraid that the lagging persists, since we are fetching the mcp servers + validating them every time we open the mcp install tab :( so we need to probably fetch the mcp servers only once during the startup ? but it would be a separate issue (also happens on the main) |
|
@simonrey1 Looking at the error in the unit tests, I think we need to update the mcp-server-registry with allErrors: true settings in AJV, it is set to false accordingly, and we should check all servers and not just stop in first one AI: |
I am ok to test that setting 👍 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @packages/renderer/src/lib/ui/LoadingIcon.svelte:
- Around line 7-13: The Props interface in LoadingIcon.svelte declares icon:
IconDefinition | Component | string but Component is unused and incompatible
with the Icon component; update the Props interface to remove Component from the
union so icon is typed as IconDefinition | string, and ensure any references
(e.g., LoadingIconButton which passes IconDefinition and the Icon from
@podman-desktop/ui-svelte/icons) still compile; if a future Svelte component
icon is intended, add a clear TODO comment instead of the Component union.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/renderer/src/lib/ui/ListItemButtonIcon.sveltepackages/renderer/src/lib/ui/LoadingIcon.svelte
🧰 Additional context used
📓 Path-based instructions (2)
packages/renderer/src/**/*.{ts,tsx,svelte}
📄 CodeRabbit inference engine (CLAUDE.md)
Require user confirmation for external URLs through
setupSecurityRestrictionsOnLinkssecurity handler
Files:
packages/renderer/src/lib/ui/LoadingIcon.sveltepackages/renderer/src/lib/ui/ListItemButtonIcon.svelte
packages/renderer/src/**/*.svelte
📄 CodeRabbit inference engine (CLAUDE.md)
Renderer components should be built with Svelte and import UI APIs from preload bridges
Use renderer process for Svelte-based UI implementation
Files:
packages/renderer/src/lib/ui/LoadingIcon.sveltepackages/renderer/src/lib/ui/ListItemButtonIcon.svelte
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: unit tests / ubuntu-24.04
- GitHub Check: unit tests / windows-2025
- GitHub Check: unit tests / macos-15
- GitHub Check: smoke e2e tests (development)
- GitHub Check: linter, formatters
- GitHub Check: smoke e2e tests (production)
- GitHub Check: typecheck
- GitHub Check: macOS
- GitHub Check: Windows
- GitHub Check: Linux
🔇 Additional comments (4)
packages/renderer/src/lib/ui/ListItemButtonIcon.svelte (2)
3-11: LGTM!The import reorganization is clean. The addition of
onDestroyandLoadingIconaligns with the refactoring to centralize icon rendering logic.
123-126: Prop compatibility with LoadingIcon verified.The refactoring correctly:
- Maps
inProgressto LoadingIcon'sloadingprop- Passes
icon(IconDefinition | string) to LoadingIcon, which supports both types plus Componentpackages/renderer/src/lib/ui/LoadingIcon.svelte (2)
24-32: LGTM! Simplified spinner positioning.The change to use
left-1/2 top-1/2 -translate-1/2for centering is a standard Tailwind pattern that simplifies the previous dynamic positioning logic. This should work correctly for all icon sizes.
3-5: No changes required. The Icon component from@podman-desktop/ui-svelte/iconssuccessfully accepts thesizeprop withIconSizefromsvelte-fa. This pattern is consistently used across the codebase (e.g.,NotificationCardItem.svelteuses<Icon size="1.5x" ... />), and LoadingIcon.svelte follows the same working approach.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @packages/main/src/plugin/mcp/mcp-registry.ts:
- Around line 553-565: The code always passes suppressWarnings=false to
schemaValidator.validateSchemaData inside the data.servers.map, causing warnings
on every paginated page; change the call in the validatedServers creation to
pass suppressWarnings as (cursor !== undefined) so warnings are suppressed for
paginated requests and only emitted on the initial page—update the
validateSchemaData invocation (the call site inside validatedServers map) to use
the cursor variable to determine the boolean and return hasInvalidSchema as
before.
In @packages/main/src/plugin/mcp/mcp-schema-validator.ts:
- Line 39: Update the outdated JSDoc in mcp-schema-validator.ts: the @returns
line currently references "invalidServerNames (for ServerList)" but the actual
SchemaValidationResult type only contains isValid: boolean; edit the comment for
the function that returns SchemaValidationResult to either remove the
"invalidServerNames" mention or change the @returns description to state it
returns a SchemaValidationResult with only isValid: boolean, and ensure the
referenced type name SchemaValidationResult is used so the doc matches the
implementation.
🧹 Nitpick comments (1)
packages/main/src/plugin/mcp/mcp-schema-validator.ts (1)
45-45: Remove trivially inferred type annotation.The type annotation for
suppressWarningsis unnecessary as TypeScript can infer it from the default value.As per static analysis hints from Biome.
♻️ Proposed fix
jsonData: unknown, schemaName: keyof components['schemas'], contextName?: string, - suppressWarnings: boolean = false, + suppressWarnings = false, ): SchemaValidationResult {
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/main/src/plugin/mcp/mcp-registry.spec.tspackages/main/src/plugin/mcp/mcp-registry.tspackages/main/src/plugin/mcp/mcp-schema-validator.spec.tspackages/main/src/plugin/mcp/mcp-schema-validator.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/main/src/plugin/mcp/mcp-registry.spec.ts
🧰 Additional context used
📓 Path-based instructions (2)
packages/main/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
packages/main/src/**/*.ts: IPC communication handlers should follow the naming convention<registry-name>:<action>(e.g.,container-provider-registry:listContainers) when exposed viaipcHandle()in the main process
UseapiSender.send()in the main process to send real-time event updates to the renderer
Container operations must include theengineIdparameter to identify the container engine when usingContainerProviderRegistrymethods likelistContainers,startContainer,stopContainer,deleteContainer,pullImage,buildImage,deleteImage,createPod,startPod,stopPod, andremovePod
Long-running operations should useTaskManager.createTask()to create tasks with title, action name, and execute callback, then settask.statusto 'success' ortask.erroron completion
UseSafeStorageRegistryfor storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g.,gemini.factory.apiKey) when stored and retrieved viaConfigurationRegistry
Main process types should use TypeScript and import from@kortex-app/apifor provider registration, configuration management, command and menu contributions, and UI component definitions
packages/main/src/**/*.ts: Configuration values should be retrieved and stored with dot notation (e.g., gemini.factory.apiKey)
Long-running operations should use TaskManager to create tasks with title, action, and status management
Container operations should use ContainerProviderRegistry with engineId parameter to identify the container engine, supporting operations like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, removePod
Kubernetes operations should use KubernetesClient for context management, resource CRUD operations, port forwarding, exec into containers, and applying YAML resources
External URLs should require user confirmation, handled through setupSecurityRest...
Files:
packages/main/src/plugin/mcp/mcp-registry.tspackages/main/src/plugin/mcp/mcp-schema-validator.spec.tspackages/main/src/plugin/mcp/mcp-schema-validator.ts
**/*.spec.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests should be co-located with source code as
*.spec.tsfilesUnit tests should be co-located with source code using the *.spec.ts naming convention
Files:
packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts
🧬 Code graph analysis (1)
packages/main/src/plugin/mcp/mcp-registry.ts (2)
packages/api/src/mcp/mcp-server-info.ts (1)
MCPServerDetail(4-7)packages/extension-api/src/extension-api.d.ts (1)
MCPServerDetail(679-679)
🪛 Biome (2.1.2)
packages/main/src/plugin/mcp/mcp-schema-validator.ts
[error] 45-45: This type annotation is trivially inferred from its initialization.
Safe fix: Remove the type annotation.
(lint/style/noInferrableTypes)
🔇 Additional comments (2)
packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts (1)
281-366: LGTM! Comprehensive test coverage for individual server validation.The new test block properly validates the per-server validation pattern used in
mcp-registry.ts. Good coverage of edge cases including multiple invalid servers, pattern validation failures, and all-valid scenarios. The use ofsuppressWarnings: truein tests is appropriate to prevent console noise during test execution.packages/main/src/plugin/mcp/mcp-registry.ts (1)
142-143: LGTM! Clean propagation of schema validation status.The
enhanceServerDetailfunction properly threads thehasInvalidSchemaflag through to theMCPServerDetailtype, enabling UI components to display validation indicators.
| // Validate each server individually to catch all invalid servers | ||
| const validatedServers = data.servers.map(serverResponse => { | ||
| const validationResult = this.schemaValidator.validateSchemaData( | ||
| serverResponse, | ||
| 'ServerResponse', | ||
| registryURL, | ||
| false, | ||
| ); | ||
| return { | ||
| ...serverResponse, | ||
| hasInvalidSchema: !validationResult.isValid, | ||
| }; | ||
| }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find and examine the mcp-registry.ts file
fd -t f "mcp-registry.ts" packages/main/src/Repository: kortex-hub/kortex
Length of output: 105
🏁 Script executed:
# Read the specific lines mentioned in the review (553-565)
cat -n packages/main/src/plugin/mcp/mcp-registry.ts | sed -n '540,580p'Repository: kortex-hub/kortex
Length of output: 1586
🏁 Script executed:
# Check the full context around the validation logic
cat -n packages/main/src/plugin/mcp/mcp-registry.ts | sed -n '550,600p'Repository: kortex-hub/kortex
Length of output: 1972
🏁 Script executed:
# Find all calls to listMCPServersFromRegistry to see how often it's invoked
rg "listMCPServersFromRegistry" packages/main/src/ -A 3 -B 3Repository: kortex-hub/kortex
Length of output: 2544
🏁 Script executed:
# Search for references to MCP install tab or calls from UI
rg "mcp.*install|MCP.*install" packages/ -i --type ts --type tsx -B 2 -A 2Repository: kortex-hub/kortex
Length of output: 88
🏁 Script executed:
# Check if there's any caching mechanism already in place
rg "cache|Cache|memoize|Memoize" packages/main/src/plugin/mcp/ -B 2 -A 2Repository: kortex-hub/kortex
Length of output: 43
🏁 Script executed:
# Look at the function signature to understand parameters, especially around line 500
cat -n packages/main/src/plugin/mcp/mcp-registry.ts | sed -n '500,560p'Repository: kortex-hub/kortex
Length of output: 2653
🏁 Script executed:
# Find where listMCPServersFromRegistries is called from
rg "listMCPServersFromRegistries" packages/ -B 3 -A 3Repository: kortex-hub/kortex
Length of output: 4112
🏁 Script executed:
# Check the listMCPServersFromRegistries function
cat -n packages/main/src/plugin/mcp/mcp-registry.ts | sed -n '600,650p'Repository: kortex-hub/kortex
Length of output: 2443
🏁 Script executed:
# Look for any IPC handlers related to MCP
rg "ipcHandle.*mcp|mcp.*ipcHandle" packages/main/src/ -i -B 2 -A 5Repository: kortex-hub/kortex
Length of output: 5673
🏁 Script executed:
# Check if there are any MCP-related IPC calls from renderer
rg "mcp-registry|listMCP" packages/renderer/ -B 2 -A 2Repository: kortex-hub/kortex
Length of output: 8392
🏁 Script executed:
# Look for any caching utilities in the codebase
fd "cache" packages/main/src -type f -name "*.ts"Repository: kortex-hub/kortex
Length of output: 231
🏁 Script executed:
# Check class members for caching fields
cat -n packages/main/src/plugin/mcp/mcp-registry.ts | sed -n '1,100p'Repository: kortex-hub/kortex
Length of output: 5113
🏁 Script executed:
# Check if there's any caching already implemented in the MCPRegistry class
cat -n packages/main/src/plugin/mcp/mcp-registry.ts | sed -n '70,120p'Repository: kortex-hub/kortex
Length of output: 2436
🏁 Script executed:
# Look for where fetchMcpRegistryServers is called from the renderer
rg "fetchMcpRegistryServers" packages/renderer/src -B 5 -A 3Repository: kortex-hub/kortex
Length of output: 3385
🏁 Script executed:
# Check how often the MCP install tab loads or interacts with the registry
rg "MCPServerListRegistry|mcp.*install|install.*mcp" packages/renderer/src -i -B 2 -A 2Repository: kortex-hub/kortex
Length of output: 7363
🏁 Script executed:
# Look at the full mcp-registry-servers.ts store to understand how often it fetches
cat -n packages/renderer/src/stores/mcp-registry-servers.tsRepository: kortex-hub/kortex
Length of output: 3345
🏁 Script executed:
# Check if there's any mechanism in place to debounce or cache the fetches
rg "debounce|throttle|cache|memoize" packages/main/src/plugin/mcp/ -B 2 -A 2Repository: kortex-hub/kortex
Length of output: 43
🏁 Script executed:
# Check the suppressWarnings parameter signature to confirm it exists
ast-grep --pattern 'validateSchemaData($$$suppressWarnings$$$)' packages/main/src/plugin/mcp/Repository: kortex-hub/kortex
Length of output: 43
🏁 Script executed:
# Find and examine the validateSchemaData method signature
rg "validateSchemaData" packages/main/src/plugin/mcp/ -B 2 -A 8Repository: kortex-hub/kortex
Length of output: 21505
🏁 Script executed:
# Check the MCPSchemaValidator class
cat -n packages/main/src/plugin/mcp/mcp-schema-validator.ts | head -100Repository: kortex-hub/kortex
Length of output: 2717
Optimize validation during paginated registry fetches to reduce console overhead.
The validation logic correctly validates each server individually across all pagination pages. However, suppressWarnings is hardcoded to false, causing console warnings to be logged for every invalid server on every paginated page. Since pagination can span multiple requests, this creates unnecessary console overhead.
The suppressWarnings parameter is already available—use cursor !== undefined to suppress warnings on paginated pages and only warn on the initial page:
Example optimization
const validatedServers = data.servers.map(serverResponse => {
const validationResult = this.schemaValidator.validateSchemaData(
serverResponse,
'ServerResponse',
registryURL,
- false,
+ cursor !== undefined, // suppress warnings for paginated calls only
);
return {
...serverResponse,
hasInvalidSchema: !validationResult.isValid,
};
});This quick fix reduces console spam during pagination without changing validation behavior. A more comprehensive solution would add application-level caching to avoid re-fetching and re-validating the same registries on subsequent calls.
🤖 Prompt for AI Agents
In @packages/main/src/plugin/mcp/mcp-registry.ts around lines 553 - 565, The
code always passes suppressWarnings=false to schemaValidator.validateSchemaData
inside the data.servers.map, causing warnings on every paginated page; change
the call in the validatedServers creation to pass suppressWarnings as (cursor
!== undefined) so warnings are suppressed for paginated requests and only
emitted on the initial page—update the validateSchemaData invocation (the call
site inside validatedServers map) to use the cursor variable to determine the
boolean and return hasInvalidSchema as before.
2f10660 to
0ae1ef3
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/main/src/plugin/mcp/mcp-registry.ts (1)
529-582: The validation approach is sound, but clarify the discrepancy with PR description and improve parameter documentation.Good news: The validation implementation is robust and requires no error handling changes.
No exceptions thrown:
validateSchemaData()returns aSchemaValidationResultobject rather than throwing exceptions, so validation errors are safely handled without try-catch.The
falseparameter is correct: It setssuppressWarnings: false, meaning warnings ARE logged when validation fails. The approach gracefully degrades by marking invalid servers withisValidSchema: falsewhile continuing to process all servers from the registry.Clarify the PR description discrepancy: The actual implementation validates individual
ServerResponseobjects (as shown in the comment on line 553 and the test suite), allowing partial success. If the PR description states "only the ServerList is validated and ServerResponse validation removed," this contradicts the current code. Verify whether the implementation or the PR description needs updating.
🧹 Nitpick comments (1)
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte (1)
21-24: Improve accessibility semantics for the indicator.The
aria-labelattribute on a non-interactivedivis not semantically correct. For a purely visual indicator, consider one of these approaches:
- Add
role="img"alongside thearia-labelto make it an accessible image- Remove
aria-labeland rely on thetitleattribute for tooltips- Use
aria-describedbyif the indicator relates to a nearby labeled element♻️ Recommended fix: Add role="img"
<div class="absolute top-0 right-0 w-2 h-2 bg-[var(--pd-state-error)] rounded-full border border-[var(--pd-content-card-bg)]" title="Invalid schema detected" + role="img" aria-label="Invalid schema detected"></div>
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
packages/api/src/mcp/mcp-server-info.tspackages/main/src/plugin/mcp/mcp-manager.tspackages/main/src/plugin/mcp/mcp-registry.tspackages/renderer/src/lib/images/MCPValidServerIndicatorIcon.sveltepackages/renderer/src/lib/mcp/MCPDetails.sveltepackages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.sveltepackages/renderer/src/lib/mcp/MCPServerListRegistryInstall.sveltepackages/renderer/src/lib/mcp/MCPServerListRemoteReady.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/api/src/mcp/mcp-server-info.ts
🧰 Additional context used
📓 Path-based instructions (3)
packages/main/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
packages/main/src/**/*.ts: IPC communication handlers should follow the naming convention<registry-name>:<action>(e.g.,container-provider-registry:listContainers) when exposed viaipcHandle()in the main process
UseapiSender.send()in the main process to send real-time event updates to the renderer
Container operations must include theengineIdparameter to identify the container engine when usingContainerProviderRegistrymethods likelistContainers,startContainer,stopContainer,deleteContainer,pullImage,buildImage,deleteImage,createPod,startPod,stopPod, andremovePod
Long-running operations should useTaskManager.createTask()to create tasks with title, action name, and execute callback, then settask.statusto 'success' ortask.erroron completion
UseSafeStorageRegistryfor storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g.,gemini.factory.apiKey) when stored and retrieved viaConfigurationRegistry
Main process types should use TypeScript and import from@kortex-app/apifor provider registration, configuration management, command and menu contributions, and UI component definitions
packages/main/src/**/*.ts: Configuration values should be retrieved and stored with dot notation (e.g., gemini.factory.apiKey)
Long-running operations should use TaskManager to create tasks with title, action, and status management
Container operations should use ContainerProviderRegistry with engineId parameter to identify the container engine, supporting operations like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, removePod
Kubernetes operations should use KubernetesClient for context management, resource CRUD operations, port forwarding, exec into containers, and applying YAML resources
External URLs should require user confirmation, handled through setupSecurityRest...
Files:
packages/main/src/plugin/mcp/mcp-manager.tspackages/main/src/plugin/mcp/mcp-registry.ts
packages/renderer/src/**/*.{ts,tsx,svelte}
📄 CodeRabbit inference engine (CLAUDE.md)
Require user confirmation for external URLs through
setupSecurityRestrictionsOnLinkssecurity handler
Files:
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.sveltepackages/renderer/src/lib/mcp/MCPServerListRemoteReady.sveltepackages/renderer/src/lib/mcp/MCPDetails.sveltepackages/renderer/src/lib/mcp/MCPServerListRegistryInstall.sveltepackages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
packages/renderer/src/**/*.svelte
📄 CodeRabbit inference engine (CLAUDE.md)
Renderer components should be built with Svelte and import UI APIs from preload bridges
Use renderer process for Svelte-based UI implementation
Files:
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.sveltepackages/renderer/src/lib/mcp/MCPServerListRemoteReady.sveltepackages/renderer/src/lib/mcp/MCPDetails.sveltepackages/renderer/src/lib/mcp/MCPServerListRegistryInstall.sveltepackages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
🧠 Learnings (4)
📚 Learning: 2025-11-25T14:41:44.065Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: MCPRegistry should manage MCP registry sources like mcp-get.com, and MCPManager should handle remote MCP server connections and lifecycle
Applied to files:
packages/main/src/plugin/mcp/mcp-manager.tspackages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.sveltepackages/renderer/src/lib/mcp/MCPServerListRegistryInstall.sveltepackages/main/src/plugin/mcp/mcp-registry.ts
📚 Learning: 2025-11-25T14:41:20.640Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T14:41:20.640Z
Learning: Applies to packages/main/src/**/*.ts : Main process types should use TypeScript and import from `kortex-app/api` for provider registration, configuration management, command and menu contributions, and UI component definitions
Applied to files:
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
📚 Learning: 2025-11-25T14:41:20.640Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T14:41:20.640Z
Learning: Applies to packages/renderer/src/**/*.svelte : Renderer components should be built with Svelte and import UI APIs from preload bridges
Applied to files:
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.sveltepackages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
📚 Learning: 2025-11-25T14:41:44.065Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: Applies to packages/renderer/src/**/*.svelte : Use renderer process for Svelte-based UI implementation
Applied to files:
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.sveltepackages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
🔇 Additional comments (12)
packages/main/src/plugin/mcp/mcp-manager.ts (1)
114-157: LGTM! Clean parameter propagation.The addition of the optional
isValidSchemaparameter and its storage inMCPRemoteServerInfois straightforward and correctly implemented. The validation state will now be accessible to consumers of the MCP manager.packages/main/src/plugin/mcp/mcp-registry.ts (4)
143-145: LGTM! Clean server detail enhancement.The addition of
isValidSchemato the enhanced server detail is properly implemented and aligns with the broader validation state tracking.
152-239: LGTM! Validation state properly propagated during registry initialization.The
isValidSchemaflag is correctly threaded through both remote and package setup paths when restoring saved configurations. The validation state from the server detail is properly passed toregisterMCPClient.
361-458: LGTM! Validation state properly propagated in MCP server setup.The
isValidSchemaflag is correctly destructured from the server detail and passed toregisterMCPClient, ensuring consistency across both remote and package setup flows.
600-621: LGTM! Server aggregation properly handles validated data.The aggregation correctly uses the validated server list and maps the validated servers with their
isValidSchemaflag throughenhanceServerDetail.packages/renderer/src/lib/mcp/MCPServerListRemoteReady.svelte (1)
35-38: LGTM! Status indicator updated correctly.The status column now uses
MCPValidServerIndicatorIconto display validation state. The component will receiveMCPRemoteServerInfoobjects that include theisValidSchemaproperty, enabling proper visual indication of schema validation status.packages/renderer/src/lib/mcp/MCPServerListRegistryInstall.svelte (1)
44-47: LGTM! Status indicator updated correctly.The status column properly uses
MCPValidServerIndicatorIconto display validation state for registry servers. The component will receiveMCPServerDetailobjects that include theisValidSchemaproperty.packages/renderer/src/lib/mcp/MCPDetails.svelte (1)
47-50: No action needed.MCPValidServerIndicatorIconexplicitly acceptsundefinedfor theobjectprop (line 7 of the component signature) and safely handles it through conditional checks (line 15). PassingmcpServerwithout an additional null check is correct and follows the component's contract.Likely an incorrect or invalid review comment.
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte (1)
1-16: LGTM! Clean type-safe implementation.The props interface and derived logic correctly handle the union type and undefined case. The
showInvalidIndicatorderived value safely checks for the presence ofisValidSchemaproperty and its value.packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte (3)
5-5: LGTM! Correct import for the new validation indicator component.The import properly references the new
MCPValidServerIndicatorIconcomponent.
22-22: Verify the intentional removal of explicit type annotation.The explicit type annotation was removed, relying instead on type inference from the
$mcpRegistriesServerInfosstore. While the type should be correctly inferred, explicit type annotations improve code maintainability, documentation, and early error detection.Was this removal intentional to reduce coupling to
@kortex-hub/mcp-registry-types? If so, consider documenting this architectural decision.
61-61: LGTM! Proper integration of the validation indicator component.The
MCPValidServerIndicatorIconis correctly used with appropriate props, and the undefined case is properly guarded by the surrounding{#if mcpRegistryServerDetail}block.
|
@simonrey1 updated |
Signed-off-by: Evzen Gasta <[email protected]>
2adea03 to
d9a4a27
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte (1)
1-24: LGTM! Component correctly implements validation indicator.The component properly displays a visual indicator for servers that fail validation, following Svelte patterns and including accessibility attributes. The strict equality check (
isValidSchema === false) ensures the indicator only appears for explicitly invalid servers.💡 Optional: Consider renaming the
objectprop for clarityThe prop name
objectis quite generic. Consider renaming it toserverorserverDetailfor better code readability:interface Props { - object: MCPServerDetail; + server: MCPServerDetail; size?: number; } -const { object, size = 20 }: Props = $props(); +const { server, size = 20 }: Props = $props(); -const showInvalidIndicator = $derived(object.isValidSchema === false); +const showInvalidIndicator = $derived(server.isValidSchema === false);packages/main/src/plugin/mcp/mcp-registry.spec.ts (2)
48-52: Consider resetting the mock in beforeEach to prevent test pollution.The
validateSchemaDataMockis shared across tests, andmockImplementationcalls in individual tests will persist. While this works with the current two tests, future tests could be affected by lingering mock implementations.♻️ Proposed refactor to reset the mock
beforeEach(() => { console.error = vi.fn(); + validateSchemaDataMock.mockReset().mockReturnValue({ isValid: true }); mcpRegistry = new MCPRegistry(
56-57: Consider restoring global.fetch in afterEach for completeness.While modifying
global.fetchin tests is generally acceptable, restoring it inafterEachwould make the cleanup more complete and prevent potential issues if other test files depend on the original fetch behavior.♻️ Proposed refactor
+const originalFetch = global.fetch; const globalFetch = vi.fn(); global.fetch = globalFetch; const originalConsoleError = console.error; beforeEach(() => { console.error = vi.fn(); mcpRegistry = new MCPRegistry( apiSender, {} as Telemetry, {} as Certificates, proxy, {} as MCPManager, {} as SafeStorageRegistry, configurationRegistry, schemaValidator, ); }); afterEach(() => { console.error = originalConsoleError; + global.fetch = originalFetch; });
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/main/src/plugin/mcp/mcp-registry.spec.tspackages/renderer/src/lib/images/MCPValidServerIndicatorIcon.sveltepackages/renderer/src/lib/mcp/MCPDetails.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/renderer/src/lib/mcp/MCPDetails.svelte
🧰 Additional context used
📓 Path-based instructions (4)
packages/main/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
packages/main/src/**/*.ts: IPC communication handlers should follow the naming convention<registry-name>:<action>(e.g.,container-provider-registry:listContainers) when exposed viaipcHandle()in the main process
UseapiSender.send()in the main process to send real-time event updates to the renderer
Container operations must include theengineIdparameter to identify the container engine when usingContainerProviderRegistrymethods likelistContainers,startContainer,stopContainer,deleteContainer,pullImage,buildImage,deleteImage,createPod,startPod,stopPod, andremovePod
Long-running operations should useTaskManager.createTask()to create tasks with title, action name, and execute callback, then settask.statusto 'success' ortask.erroron completion
UseSafeStorageRegistryfor storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g.,gemini.factory.apiKey) when stored and retrieved viaConfigurationRegistry
Main process types should use TypeScript and import from@kortex-app/apifor provider registration, configuration management, command and menu contributions, and UI component definitions
packages/main/src/**/*.ts: Configuration values should be retrieved and stored with dot notation (e.g., gemini.factory.apiKey)
Long-running operations should use TaskManager to create tasks with title, action, and status management
Container operations should use ContainerProviderRegistry with engineId parameter to identify the container engine, supporting operations like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, removePod
Kubernetes operations should use KubernetesClient for context management, resource CRUD operations, port forwarding, exec into containers, and applying YAML resources
External URLs should require user confirmation, handled through setupSecurityRest...
Files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
**/*.spec.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests should be co-located with source code as
*.spec.tsfilesUnit tests should be co-located with source code using the *.spec.ts naming convention
Files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
packages/renderer/src/**/*.{ts,tsx,svelte}
📄 CodeRabbit inference engine (CLAUDE.md)
Require user confirmation for external URLs through
setupSecurityRestrictionsOnLinkssecurity handler
Files:
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
packages/renderer/src/**/*.svelte
📄 CodeRabbit inference engine (CLAUDE.md)
Renderer components should be built with Svelte and import UI APIs from preload bridges
Use renderer process for Svelte-based UI implementation
Files:
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: MCPRegistry should manage MCP registry sources like mcp-get.com, and MCPManager should handle remote MCP server connections and lifecycle
📚 Learning: 2025-11-08T14:36:17.423Z
Learnt from: benoitf
Repo: kortex-hub/kortex PR: 692
File: extensions/ramalama/src/inject/inversify-binding.spec.ts:38-38
Timestamp: 2025-11-08T14:36:17.423Z
Learning: In the kortex repository, tests use `vi.mock(import('module-path'))` syntax instead of `vi.mock('module-path')` to ensure TypeScript validates the module path at compile time, providing refactoring safety if modules are moved or removed.
Applied to files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
📚 Learning: 2025-11-25T14:41:44.065Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: MCPRegistry should manage MCP registry sources like mcp-get.com, and MCPManager should handle remote MCP server connections and lifecycle
Applied to files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
📚 Learning: 2025-11-25T14:41:44.065Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: Applies to packages/renderer/src/**/*.svelte : Use renderer process for Svelte-based UI implementation
Applied to files:
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
📚 Learning: 2025-11-25T14:41:20.640Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T14:41:20.640Z
Learning: Applies to packages/renderer/src/**/*.svelte : Renderer components should be built with Svelte and import UI APIs from preload bridges
Applied to files:
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: typecheck
- GitHub Check: Windows
- GitHub Check: unit tests / macos-15
- GitHub Check: smoke e2e tests (development)
- GitHub Check: smoke e2e tests (production)
- GitHub Check: linter, formatters
- GitHub Check: unit tests / ubuntu-24.04
- GitHub Check: unit tests / windows-2025
- GitHub Check: Linux
- GitHub Check: macOS
🔇 Additional comments (2)
packages/main/src/plugin/mcp/mcp-registry.spec.ts (2)
80-118: LGTM! Clean refactor to shared mocks.The test successfully migrates to the shared
globalFetchandconsole.errormocks while maintaining the original test logic and coverage.
120-152: Excellent test coverage for the validation marking feature!This test effectively validates that servers with invalid schemas are correctly marked with
isValidSchema: false, directly supporting the PR objective to add visual indicators for validation failures.
There was a problem hiding this comment.
remark: I think this interface was introduced when the property invalidServerNames existed. Now it could be rollbacked to boolean I think. (Do no forget to update comment above).
|
Would something like this work better @simonrey1? |
|
@gastoner I can't find the source for this icon. What asset do you need? Is the dot just an overlay? |
|
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/main/src/plugin/mcp/mcp-registry.ts (1)
529-582: Guard against malformed registry payloads before iterating (data.servers.map).
Right nowcontent.json()is trusted asServerList; if a registry returns a malformed payload (orserversisn’t an array), this will throw before you even get to per-item validation. Since this is remote input, add minimal runtime checks (and optionally validateServerListonce) before mapping.Proposed hardening (minimal guards + skip unrecoverable entries)
- const data: components['schemas']['ServerList'] = await content.json(); + const raw: unknown = await content.json(); + // Validate the list shape enough to safely iterate + if ( + !raw || + typeof raw !== 'object' || + !('servers' in raw) || + !Array.isArray((raw as { servers?: unknown }).servers) + ) { + throw new Error(`Invalid MCP registry response from ${registryURL}: expected { servers: [] }`); + } + const data = raw as components['schemas']['ServerList']; // Validate each server individually to catch all invalid servers - const validatedServers: ValidatedServerResponse[] = data.servers.map(serverResponse => { + const validatedServers: ValidatedServerResponse[] = data.servers + .map(serverResponse => { const validationResult = this.schemaValidator.validateSchemaData( serverResponse, 'ServerResponse', registryURL, false, ); + // If the entry is too broken to even have a `server` block, it can’t be rendered/installed anyway. + if (!serverResponse || typeof serverResponse !== 'object' || !('server' in serverResponse)) { + console.warn(`[MCPRegistry] Skipping malformed server entry from ${registryURL}`); + return undefined; + } return { ...serverResponse, isValidSchema: validationResult, }; - }); + }) + .filter((x): x is ValidatedServerResponse => Boolean(x));
🧹 Nitpick comments (2)
packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts (1)
312-318: Consider extracting validation logic for potential reuse.The server validation loop is clear, but if this pattern is needed in other tests, consider extracting it into a test helper function.
♻️ Optional refactor to reduce duplication
function getInvalidServerNames( servers: unknown[], validator: MCPSchemaValidator, contextName?: string ): Set<string> { const invalidServerNames = new Set<string>(); for (const serverResponse of servers) { const result = validator.validateSchemaData(serverResponse, 'ServerResponse', contextName, true); if (!result) { invalidServerNames.add((serverResponse as any).server.name); } } return invalidServerNames; }Then use it in the test:
- const invalidServerNames = new Set<string>(); - for (const serverResponse of servers) { - const result = validator.validateSchemaData(serverResponse, 'ServerResponse', 'test-registry', true); - if (!result) { - invalidServerNames.add(serverResponse.server.name); - } - } + const invalidServerNames = getInvalidServerNames(servers, validator, 'test-registry');packages/main/src/plugin/mcp/mcp-registry.ts (1)
143-145:serverIdgeneration viaencodeURI(server.name)is fragile (reserved chars + potential collisions).
encodeURIwon’t escape/,?,#, etc., which can lead to surprising IDs and harder-to-debug collisions. Ifnameis ever missing at runtime (invalid payload), it also risks producing"undefined"IDs.Proposed tweak (safer encoding)
- enhanceServerDetail(server: components['schemas']['ServerDetail'], isValidSchema?: boolean): MCPServerDetail { - return { ...server, serverId: encodeURI(server.name), isValidSchema }; - } + enhanceServerDetail(server: components['schemas']['ServerDetail'], isValidSchema?: boolean): MCPServerDetail { + // encodeURIComponent is safer for “identifier” usage than encodeURI + return { ...server, serverId: encodeURIComponent(server.name), isValidSchema }; + }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
packages/main/src/plugin/mcp/mcp-registry.spec.tspackages/main/src/plugin/mcp/mcp-registry.tspackages/main/src/plugin/mcp/mcp-schema-validator.spec.tspackages/main/src/plugin/mcp/mcp-schema-validator.tspackages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
✅ Files skipped from review due to trivial changes (1)
- packages/main/src/plugin/mcp/mcp-schema-validator.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
- packages/main/src/plugin/mcp/mcp-registry.spec.ts
🧰 Additional context used
📓 Path-based instructions (2)
packages/main/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
packages/main/src/**/*.ts: IPC communication handlers should follow the naming convention<registry-name>:<action>(e.g.,container-provider-registry:listContainers) when exposed viaipcHandle()in the main process
UseapiSender.send()in the main process to send real-time event updates to the renderer
Container operations must include theengineIdparameter to identify the container engine when usingContainerProviderRegistrymethods likelistContainers,startContainer,stopContainer,deleteContainer,pullImage,buildImage,deleteImage,createPod,startPod,stopPod, andremovePod
Long-running operations should useTaskManager.createTask()to create tasks with title, action name, and execute callback, then settask.statusto 'success' ortask.erroron completion
UseSafeStorageRegistryfor storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g.,gemini.factory.apiKey) when stored and retrieved viaConfigurationRegistry
Main process types should use TypeScript and import from@kortex-app/apifor provider registration, configuration management, command and menu contributions, and UI component definitions
packages/main/src/**/*.ts: Configuration values should be retrieved and stored with dot notation (e.g., gemini.factory.apiKey)
Long-running operations should use TaskManager to create tasks with title, action, and status management
Container operations should use ContainerProviderRegistry with engineId parameter to identify the container engine, supporting operations like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, removePod
Kubernetes operations should use KubernetesClient for context management, resource CRUD operations, port forwarding, exec into containers, and applying YAML resources
External URLs should require user confirmation, handled through setupSecurityRest...
Files:
packages/main/src/plugin/mcp/mcp-schema-validator.spec.tspackages/main/src/plugin/mcp/mcp-registry.ts
**/*.spec.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests should be co-located with source code as
*.spec.tsfilesUnit tests should be co-located with source code using the *.spec.ts naming convention
Files:
packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts
🧠 Learnings (1)
📚 Learning: 2025-11-25T14:41:44.065Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: MCPRegistry should manage MCP registry sources like mcp-get.com, and MCPManager should handle remote MCP server connections and lifecycle
Applied to files:
packages/main/src/plugin/mcp/mcp-registry.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: unit tests / macos-15
- GitHub Check: Linux
- GitHub Check: smoke e2e tests (production)
- GitHub Check: linter, formatters
- GitHub Check: unit tests / windows-2025
- GitHub Check: macOS
- GitHub Check: unit tests / ubuntu-24.04
- GitHub Check: smoke e2e tests (development)
- GitHub Check: Windows
- GitHub Check: typecheck
🔇 Additional comments (4)
packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts (1)
280-366: LGTM! Well-structured test suite for individual server validation.The new test suite effectively validates per-server validation logic, which aligns with the PR objective of adding visual indicators for invalid servers. The tests correctly:
- Detect multiple invalid servers when validated individually
- Verify name pattern validation
- Confirm all valid servers pass validation
The use of
suppressWarnings=truethroughout these tests is appropriate for cleaner test output.packages/main/src/plugin/mcp/mcp-registry.ts (3)
35-37: Import/type wiring looks consistent.
UsingValidatedServerList/ValidatedServerResponsehere matches the new “per-server validity” model.
161-165: VerifyisValidSchemasemantics end-to-end (especiallyundefined).
You’re correctly threadingisValidSchemaintoregisterMCPClient, but please confirm:
MCPManager.registerMCPClientacceptsboolean | undefined- the renderer treats
undefinedas “valid/unknown” (not invalid), e.g. checksisValidSchema === falserather than!isValidSchemaAlso applies to: 194-205, 226-236, 441-454
609-616: Aggregation change is clean and keeps validity attached.
TheenhanceServerDetail(rawServer.server, rawServer.isValidSchema)mapping matches the intended UI behavior.
Signed-off-by: Evzen Gasta <[email protected]>
3a9355b to
e8dfad1
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte:
- Line 22: The derived expression can throw if $mcpRegistriesServerInfos is
undefined/null; update the computation used to create mcpRegistryServerDetail to
defensively handle that by using optional chaining or a fallback empty array
when calling .find (e.g., reference $mcpRegistriesServerInfos and serverId and
ensure you call ($mcpRegistriesServerInfos ?? []) or
$mcpRegistriesServerInfos?.find(...) so the derived store never throws during
init).
🧹 Nitpick comments (2)
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte (1)
24-27: Mixed target shapes: consider an explicit discriminant instead of'url' in mcpTarget.
Now thattargetsmerges remotes + packages, relying on a structural check ('url' in ...) is a bit fragile if either schema evolves. Akind: 'remote' | 'package'(added here when mapping) makes downstream rendering more robust/readable.packages/main/src/plugin/mcp/mcp-registry.spec.ts (1)
48-52: Consider resetting the mock inbeforeEachto prevent test pollution.The
validateSchemaDataMockdefault implementation is overridden in the second test viamockImplementation. If additional tests are added later, they may inherit the modified behavior unexpectedly.🔧 Suggested improvement
beforeEach(() => { console.error = vi.fn(); + validateSchemaDataMock.mockReset().mockReturnValue(true); mcpRegistry = new MCPRegistry(
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/main/src/plugin/mcp/mcp-registry.spec.tspackages/main/src/plugin/mcp/mcp-registry.tspackages/main/src/plugin/mcp/mcp-schema-validator.spec.tspackages/main/src/plugin/mcp/mcp-schema-validator.tspackages/renderer/src/lib/images/MCPValidServerIndicatorIcon.sveltepackages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/main/src/plugin/mcp/mcp-schema-validator.ts
- packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts
- packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
🧰 Additional context used
📓 Path-based instructions (4)
packages/main/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
packages/main/src/**/*.ts: IPC communication handlers should follow the naming convention<registry-name>:<action>(e.g.,container-provider-registry:listContainers) when exposed viaipcHandle()in the main process
UseapiSender.send()in the main process to send real-time event updates to the renderer
Container operations must include theengineIdparameter to identify the container engine when usingContainerProviderRegistrymethods likelistContainers,startContainer,stopContainer,deleteContainer,pullImage,buildImage,deleteImage,createPod,startPod,stopPod, andremovePod
Long-running operations should useTaskManager.createTask()to create tasks with title, action name, and execute callback, then settask.statusto 'success' ortask.erroron completion
UseSafeStorageRegistryfor storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g.,gemini.factory.apiKey) when stored and retrieved viaConfigurationRegistry
Main process types should use TypeScript and import from@kortex-app/apifor provider registration, configuration management, command and menu contributions, and UI component definitions
packages/main/src/**/*.ts: Configuration values should be retrieved and stored with dot notation (e.g., gemini.factory.apiKey)
Long-running operations should use TaskManager to create tasks with title, action, and status management
Container operations should use ContainerProviderRegistry with engineId parameter to identify the container engine, supporting operations like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, removePod
Kubernetes operations should use KubernetesClient for context management, resource CRUD operations, port forwarding, exec into containers, and applying YAML resources
External URLs should require user confirmation, handled through setupSecurityRest...
Files:
packages/main/src/plugin/mcp/mcp-registry.spec.tspackages/main/src/plugin/mcp/mcp-registry.ts
**/*.spec.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests should be co-located with source code as
*.spec.tsfilesUnit tests should be co-located with source code using the *.spec.ts naming convention
Files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
packages/renderer/src/**/*.{ts,tsx,svelte}
📄 CodeRabbit inference engine (CLAUDE.md)
Require user confirmation for external URLs through
setupSecurityRestrictionsOnLinkssecurity handler
Files:
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
packages/renderer/src/**/*.svelte
📄 CodeRabbit inference engine (CLAUDE.md)
Renderer components should be built with Svelte and import UI APIs from preload bridges
Use renderer process for Svelte-based UI implementation
Files:
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
🧠 Learnings (5)
📚 Learning: 2025-11-08T14:36:17.423Z
Learnt from: benoitf
Repo: kortex-hub/kortex PR: 692
File: extensions/ramalama/src/inject/inversify-binding.spec.ts:38-38
Timestamp: 2025-11-08T14:36:17.423Z
Learning: In the kortex repository, tests use `vi.mock(import('module-path'))` syntax instead of `vi.mock('module-path')` to ensure TypeScript validates the module path at compile time, providing refactoring safety if modules are moved or removed.
Applied to files:
packages/main/src/plugin/mcp/mcp-registry.spec.ts
📚 Learning: 2025-11-25T14:41:44.065Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: MCPRegistry should manage MCP registry sources like mcp-get.com, and MCPManager should handle remote MCP server connections and lifecycle
Applied to files:
packages/main/src/plugin/mcp/mcp-registry.spec.tspackages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.sveltepackages/main/src/plugin/mcp/mcp-registry.ts
📚 Learning: 2025-11-25T14:41:20.640Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T14:41:20.640Z
Learning: Applies to packages/main/src/**/*.ts : Main process types should use TypeScript and import from `kortex-app/api` for provider registration, configuration management, command and menu contributions, and UI component definitions
Applied to files:
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
📚 Learning: 2025-11-25T14:41:20.640Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T14:41:20.640Z
Learning: Applies to packages/renderer/src/**/*.svelte : Renderer components should be built with Svelte and import UI APIs from preload bridges
Applied to files:
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
📚 Learning: 2025-11-25T14:41:44.065Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: Applies to packages/renderer/src/**/*.svelte : Use renderer process for Svelte-based UI implementation
Applied to files:
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
🧬 Code graph analysis (2)
packages/main/src/plugin/mcp/mcp-registry.spec.ts (2)
__mocks__/@kortex-app/api.js (1)
mcpRegistry(23-25)packages/extension-api/src/extension-api.d.ts (1)
MCPRegistry(1502-1506)
packages/main/src/plugin/mcp/mcp-registry.ts (2)
packages/api/src/mcp/mcp-server-info.ts (3)
MCPServerDetail(14-17)ValidatedServerList(9-11)ValidatedServerResponse(4-6)packages/extension-api/src/extension-api.d.ts (1)
MCPServerDetail(679-679)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: macOS
- GitHub Check: unit tests / ubuntu-24.04
- GitHub Check: smoke e2e tests (production)
- GitHub Check: smoke e2e tests (development)
- GitHub Check: linter, formatters
- GitHub Check: unit tests / windows-2025
- GitHub Check: Linux
- GitHub Check: unit tests / macos-15
- GitHub Check: Windows
- GitHub Check: typecheck
🔇 Additional comments (10)
packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte (2)
5-5: Good: using a dedicated “valid/invalid” indicator component in the “+ / create from registry” flow.
This looks aligned with the issue/request to show the same indicator when opening the create form.
61-61: Make sure the indicator component handles “unknown validity”.
Since this passes the wholeserver, ensureMCPValidServerIndicatorIconwon’t misrender or throw ifserver.isValidSchemais missing (e.g., older cached data / partial loads).packages/main/src/plugin/mcp/mcp-registry.spec.ts (3)
120-151: Good test coverage for per-server schema validation.The test correctly verifies that
listMCPServersFromRegistriesmarks individual servers with their validation status based onvalidateSchemaDataresults. The mock implementation distinguishes valid vs invalid servers by name, and assertions check bothisValidSchema: trueandisValidSchema: falsecases.
56-57: Global fetch mock setup is appropriate.Assigning to
global.fetchonce at module level and usingmockResolvedValueOnceper-test provides clean sequential response mocking.
61-78: Lifecycle hooks properly manage test isolation.Preserving and restoring
console.errorensures no side effects leak between tests, and initializingmcpRegistryinbeforeEachguarantees a fresh instance per test.packages/main/src/plugin/mcp/mcp-registry.ts (5)
143-145: Clean enhancement to support per-server validation status.The optional
isValidSchemaparameter with spread assignment maintains backward compatibility while enabling the validation indicator feature.
553-565: Per-server validation logic is correctly implemented.Each server is individually validated against the schema, and the validation result is attached as
isValidSchema. This aligns with the PR objective to mark servers that fail validation.
568-581: Pagination handling correctly merges validated servers.The recursive call properly combines validated servers from the current page with subsequent pages, preserving the
isValidSchemaproperty throughout.
609-621: Aggregation correctly propagates validation status to consumers.The
listMCPServersFromRegistriesmethod now passesrawServer.isValidSchematoenhanceServerDetail, ensuring the UI receives the validation state for each server.
440-454: Validation status correctly forwarded during MCP server setup.The destructuring of
isValidSchemafromserverDetailand its propagation toregisterMCPClientensures the validation state is preserved when setting up individual servers.
| const mcpRegistryServerDetail: components['schemas']['ServerDetail'] | undefined = $derived( | ||
| $mcpRegistriesServerInfos.find(server => server.serverId === serverId), | ||
| ); | ||
| const mcpRegistryServerDetail = $derived($mcpRegistriesServerInfos.find(server => server.serverId === serverId)); |
There was a problem hiding this comment.
Avoid a possible crash if $mcpRegistriesServerInfos is ever undefined/null during init.
If the store isn’t guaranteed to be [] initially, .$find(...) will throw and you’ll render a blank page.
Proposed defensive tweak
-const mcpRegistryServerDetail = $derived($mcpRegistriesServerInfos.find(server => server.serverId === serverId));
+const mcpRegistryServerDetail = $derived(
+ ($mcpRegistriesServerInfos ?? []).find(server => server.serverId === serverId),
+);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const mcpRegistryServerDetail = $derived($mcpRegistriesServerInfos.find(server => server.serverId === serverId)); | |
| const mcpRegistryServerDetail = $derived( | |
| ($mcpRegistriesServerInfos ?? []).find(server => server.serverId === serverId), | |
| ); |
🤖 Prompt for AI Agents
In @packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte at
line 22, The derived expression can throw if $mcpRegistriesServerInfos is
undefined/null; update the computation used to create mcpRegistryServerDetail to
defensively handle that by using optional chaining or a fallback empty array
when calling .find (e.g., reference $mcpRegistriesServerInfos and serverId and
ensure you call ($mcpRegistriesServerInfos ?? []) or
$mcpRegistriesServerInfos?.find(...) so the derived store never throws during
init).
|
@simonrey1 not sure if I can switch to |
Signed-off-by: Evzen Gasta <[email protected]>
|
@simonrey1 FYI I was forced to go back to |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte (1)
16-24: Consider scaling the indicator proportionally to the icon size.The indicator dot uses a fixed size (
w-2 h-2) regardless of thesizeprop passed to the icon. For the default size of 20, this works well. If this component will be used with varying icon sizes, consider making the indicator size proportional.♻️ Optional: Dynamic indicator sizing
<script lang="ts"> import type { MCPServerDetail } from '/@api/mcp/mcp-server-info'; import MCPIcon from './MCPIcon.svelte'; interface Props { object: MCPServerDetail; size?: number; } const { object, size = 20 }: Props = $props(); const showInvalidIndicator = $derived(object?.isValidSchema === false); +const indicatorSize = $derived(Math.max(6, Math.round(size * 0.4))); </script> <div class="relative"> <MCPIcon {size} /> {#if showInvalidIndicator} <div - class="absolute top-0 right-0 w-2 h-2 bg-[var(--pd-state-error)] rounded-full border border-[var(--pd-content-card-bg)]" + class="absolute top-0 right-0 bg-[var(--pd-state-error)] rounded-full border border-[var(--pd-content-card-bg)]" + style="width: {indicatorSize}px; height: {indicatorSize}px;" title="Invalid schema detected" aria-label="Invalid schema detected"></div> {/if} </div>
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.sveltepackages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
🧰 Additional context used
📓 Path-based instructions (2)
packages/renderer/src/**/*.{ts,tsx,svelte}
📄 CodeRabbit inference engine (CLAUDE.md)
Require user confirmation for external URLs through
setupSecurityRestrictionsOnLinkssecurity handler
Files:
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
packages/renderer/src/**/*.svelte
📄 CodeRabbit inference engine (CLAUDE.md)
Renderer components should be built with Svelte and import UI APIs from preload bridges
Use renderer process for Svelte-based UI implementation
Files:
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
🧠 Learnings (2)
📚 Learning: 2025-11-25T14:41:44.065Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:41:44.065Z
Learning: Applies to packages/renderer/src/**/*.svelte : Use renderer process for Svelte-based UI implementation
Applied to files:
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
📚 Learning: 2025-11-25T14:41:20.640Z
Learnt from: CR
Repo: kortex-hub/kortex PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T14:41:20.640Z
Learning: Applies to packages/renderer/src/**/*.svelte : Renderer components should be built with Svelte and import UI APIs from preload bridges
Applied to files:
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: Windows
- GitHub Check: smoke e2e tests (production)
- GitHub Check: Linux
- GitHub Check: macOS
- GitHub Check: unit tests / windows-2025
- GitHub Check: smoke e2e tests (development)
- GitHub Check: unit tests / ubuntu-24.04
- GitHub Check: unit tests / macos-15
- GitHub Check: typecheck
- GitHub Check: linter, formatters
🔇 Additional comments (1)
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte (1)
1-14: LGTM on the script logic.The strict equality check
object?.isValidSchema === falsecorrectly distinguishes between "not validated" (undefined) and "validation failed" (false), ensuring the indicator only appears when validation has explicitly failed. The Svelte 5 runes usage and preload bridge import pattern are appropriate.
|
The icon update is in gastoner#3 |
Signed-off-by: Evzen Gasta <[email protected]>
|
@simonrey1 @vancura updated |
| ); | ||
|
|
||
| const { servers } = await this.listMCPServersFromRegistry(registry.serverUrl); | ||
| for (const rawServer of servers) { |
There was a problem hiding this comment.
nitpick: rawServer is a bit misleading because it now has validation data included
Signed-off-by: Simon Rey <[email protected]>
There was a problem hiding this comment.
nitpick: missing newline at EOF
Signed-off-by: Evzen Gasta <[email protected]>
Adds red visual indicator to mcp server list to those servers that does not pass validation
Closes #852
Needs rebase after #609