Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat: added validation visual indicator to mcp server list #849

Merged
gastoner merged 13 commits intokortex-hub:mainfrom
gastoner:validation_visual_indicator
Jan 12, 2026
Merged

feat: added validation visual indicator to mcp server list #849
gastoner merged 13 commits intokortex-hub:mainfrom
gastoner:validation_visual_indicator

Conversation

@gastoner
Copy link
Contributor

@gastoner gastoner commented Dec 16, 2025

Adds red visual indicator to mcp server list to those servers that does not pass validation

image

Closes #852

Needs rebase after #609

Copy link
Contributor

@vancura vancura left a comment

Choose a reason for hiding this comment

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

I commented on a wrong ticket, see my nitpicking at #609 (comment).

@gastoner gastoner force-pushed the validation_visual_indicator branch 2 times, most recently from 56b4214 to 38b6df0 Compare December 18, 2025 10:21
@gastoner gastoner marked this pull request as ready for review December 18, 2025 10:22
@gastoner gastoner requested a review from a team as a code owner December 18, 2025 10:22
@gastoner gastoner requested review from SoniaSandler, axel7083, benoitf and vancura and removed request for a team December 18, 2025 10:22
@coderabbitai
Copy link

coderabbitai bot commented Dec 18, 2025

📝 Walkthrough

Walkthrough

Adds 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

Cohort / File(s) Summary
API types
packages/api/src/mcp/mcp-server-info.ts
Added ValidatedServerDetail, ValidatedServerResponse, ValidatedServerList; MCPServerDetail now extends ValidatedServerDetail; MCPRemoteServerInfo gains optional isValidSchema?: boolean.
Registry implementation & tests
packages/main/src/plugin/mcp/mcp-registry.ts, packages/main/src/plugin/mcp/mcp-registry.spec.ts
Compute and attach per-server isValidSchema when listing/merging registries; enhanceServerDetail signature updated to accept isValidSchema; tests refactored to use shared mocks and add assertions for invalid-schema marking.
Manager
packages/main/src/plugin/mcp/mcp-manager.ts
registerMCPClient(...) gains optional isValidSchema parameter and stores it on MCPRemoteServerInfo.
Schema validator & tests
packages/main/src/plugin/mcp/mcp-schema-validator.ts, packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts
Minor JSDoc wording change; added tests for per-ServerResponse validation detecting multiple invalid servers.
Renderer / UI
packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte, packages/renderer/src/lib/mcp/...
New MCPValidServerIndicatorIcon Svelte component that shows a red dot when isValidSchema === false; updated UI components to use the component and pass server objects; targets array extended to include remotes and packages.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a visual indicator to the MCP server list for validation purposes.
Description check ✅ Passed The description clearly relates to the changeset by explaining the feature (red visual indicator for servers that fail validation) and linking to issue #852.
Linked Issues check ✅ Passed The PR implements the primary objective from issue #852: adding a visual indicator to mark MCP servers that did not pass validation.
Out of Scope Changes check ✅ Passed All changes are in scope: type extensions for schema validation tracking, test coverage for validation logic, and UI components to display validation status indicators.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eab584c and 101c84f.

📒 Files selected for processing (1)
  • packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • 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: macOS
  • GitHub Check: unit tests / macos-15
  • GitHub Check: smoke e2e tests (production)
  • GitHub Check: unit tests / windows-2025
  • GitHub Check: Windows
  • GitHub Check: unit tests / ubuntu-24.04
  • GitHub Check: Linux
  • GitHub Check: typecheck
  • GitHub Check: linter, formatters
  • GitHub Check: smoke e2e tests (development)

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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 validateSchemaDataMock is configured at module level with a default return value, then overridden with mockImplementation in the second test. Without resetting in beforeEach, 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 resetting globalFetch mock in beforeEach for robustness.

Using mockResolvedValueOnce queues 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 duplicate hasInvalidSchema extraction logic.

The same pattern for safely extracting hasInvalidSchema from 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 augmented hasInvalidSchema property.

The method returns servers with an added hasInvalidSchema property, but the return type components['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

📥 Commits

Reviewing files that changed from the base of the PR and between f1d6054 and 38b6df0.

📒 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 setupSecurityRestrictionsOnLinks security 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 via ipcHandle() in the main process
Use apiSender.send() in the main process to send real-time event updates to the renderer
Container operations must include the engineId parameter to identify the container engine when using ContainerProviderRegistry methods like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, and removePod
Long-running operations should use TaskManager.createTask() to create tasks with title, action name, and execute callback, then set task.status to 'success' or task.error on completion
Use SafeStorageRegistry for storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g., gemini.factory.apiKey) when stored and retrieved via ConfigurationRegistry
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

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
  • packages/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.ts files

Unit 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.ts
  • packages/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 serverId and optional hasInvalidSchema flag to the base ServerDetail schema. 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 title for tooltip and aria-label for 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 hasInvalidSchema is 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 hasInvalidSchema flag into the returned MCPServerDetail.


556-579: Validation logic is well-implemented.

Good approach to validate each ServerResponse individually with silent mode to avoid log flooding, while still validating the overall ServerList structure. The recursive pagination correctly preserves validation flags.

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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-commenter
Copy link

codecov-commenter commented Dec 18, 2025

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 82.05128% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/main/src/plugin/mcp/mcp-registry.ts 82.14% 5 Missing ⚠️
packages/main/src/plugin/mcp/mcp-manager.ts 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@gastoner gastoner force-pushed the validation_visual_indicator branch from 38b6df0 to 68ee80f Compare December 18, 2025 10:51
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 38b6df0 and 68ee80f.

📒 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 via ipcHandle() in the main process
Use apiSender.send() in the main process to send real-time event updates to the renderer
Container operations must include the engineId parameter to identify the container engine when using ContainerProviderRegistry methods like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, and removePod
Long-running operations should use TaskManager.createTask() to create tasks with title, action name, and execute callback, then set task.status to 'success' or task.error on completion
Use SafeStorageRegistry for storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g., gemini.factory.apiKey) when stored and retrieved via ConfigurationRegistry
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

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
  • packages/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.ts files

Unit 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.ts
  • packages/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 hasInvalidSchema flag 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 hasInvalidSchema parameter is properly propagated to the returned MCPServerDetail object.


566-580: LGTM! Validation results correctly propagated in both paths.

Both the paginated and non-paginated return paths now use validatedServers, ensuring the hasInvalidSchema flag is consistently propagated.


611-619: LGTM! Correct extraction and propagation logic.

The hasInvalidSchema flag is properly extracted from each server and passed to enhanceServerDetail. Note: The duplication mentioned in the earlier comment also applies here.


556-563: The validateSchemaData method correctly supports the 4th parameter (suppressWarnings: boolean = false). Passing true as 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.

@simonrey1
Copy link
Contributor

It is working for me but I was expecting to find the same icon when I click on the "+" icon:

Screenshot 2025-12-18 at 16 35 28

Copy link
Contributor

Choose a reason for hiding this comment

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

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
packages/renderer/src/lib/ui/ListItemButtonIcon.svelte (1)

15-16: Clarify the purpose and lifecycle of the fontAwesomeIcon prop.

The Icon component from @podman-desktop/ui-svelte supports both IconDefinition and string-based icons, so there is no type incompatibility. However, clarify whether fontAwesomeIcon is a legacy fallback or an intended API:

  • If legacy, add a JSDoc @deprecated comment documenting the migration path to using icon exclusively
  • If intentional, document the distinction between icon and fontAwesomeIcon and when each should be used
packages/main/src/plugin/mcp/mcp-registry.spec.ts (1)

48-78: Consider resetting mocks in beforeEach to prevent test pollution.

The validateSchemaDataMock is shared across tests. While the current tests manage it correctly, adding vi.clearAllMocks() or validateSchemaDataMock.mockReset() in beforeEach would 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 boolean type can be inferred from the default value.

🔎 Suggested fix
-    suppressWarnings: boolean = false,
+    suppressWarnings = false,

61-76: Use Number.parseInt instead of global parseInt.

ES2015 moved parseInt into the Number namespace 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

📥 Commits

Reviewing files that changed from the base of the PR and between 68ee80f and 495b7ba.

📒 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 via ipcHandle() in the main process
Use apiSender.send() in the main process to send real-time event updates to the renderer
Container operations must include the engineId parameter to identify the container engine when using ContainerProviderRegistry methods like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, and removePod
Long-running operations should use TaskManager.createTask() to create tasks with title, action name, and execute callback, then set task.status to 'success' or task.error on completion
Use SafeStorageRegistry for storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g., gemini.factory.apiKey) when stored and retrieved via ConfigurationRegistry
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

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.ts
  • packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts
  • packages/main/src/plugin/mcp/mcp-registry.ts
  • 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.ts files

Unit 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
  • 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 setupSecurityRestrictionsOnLinks security handler

Files:

  • packages/renderer/src/lib/ui/ListItemButtonIcon.svelte
  • 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/ui/ListItemButtonIcon.svelte
  • packages/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.ts
  • 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/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-svelte properly handles both string-based icons and FontAwesome IconDefinition objects using the isFontAwesomeIcon() type guard, which checks for FontAwesome-specific properties (iconName, prefix). All actual usages of ListItemButtonIcon pass FontAwesome IconDefinitions, and the fallback icon ?? fontAwesomeIcon is 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 $derived reactive 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 hasInvalidSchema property 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 SchemaValidationResult structure with both isValid and invalidServerNames properties.


281-431: Excellent test coverage for invalid server extraction.

The new test suite comprehensively validates the invalidServerNames extraction 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 hasInvalidSchema flag based on validation results.

packages/main/src/plugin/mcp/mcp-schema-validator.ts (2)

22-26: LGTM!

The SchemaValidationResult interface is well-designed with clear documentation about when invalidServerNames is populated.


78-82: LGTM!

The return value correctly implements the SchemaValidationResult interface.

packages/main/src/plugin/mcp/mcp-registry.ts (3)

142-144: LGTM!

The enhanceServerDetail function correctly propagates the hasInvalidSchema flag to the server detail object.


162-166: LGTM!

Safe extraction of hasInvalidSchema with proper type guards and sensible default value.


610-618: LGTM!

The server mapping correctly extracts and propagates the hasInvalidSchema flag, consistent with the pattern used elsewhere in the codebase.

@gastoner
Copy link
Contributor Author

gastoner commented Dec 19, 2025

@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)

@gastoner
Copy link
Contributor Author

@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:
"Root cause: The createValidator from @kortex-hub/mcp-registry-types uses AJV with default settings (allErrors: false), which means it stops at the first validation error. This is a limitation of the external package."

Copy link
Contributor

@vancura vancura left a comment

Choose a reason for hiding this comment

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

Looks great!

@simonrey1
Copy link
Contributor

@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

I am ok to test that setting 👍

@simonrey1 simonrey1 self-requested a review December 22, 2025 09:38
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 495b7ba and 4388cb9.

📒 Files selected for processing (2)
  • packages/renderer/src/lib/ui/ListItemButtonIcon.svelte
  • packages/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 setupSecurityRestrictionsOnLinks security handler

Files:

  • packages/renderer/src/lib/ui/LoadingIcon.svelte
  • packages/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.svelte
  • packages/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 onDestroy and LoadingIcon aligns with the refactoring to centralize icon rendering logic.


123-126: Prop compatibility with LoadingIcon verified.

The refactoring correctly:

  • Maps inProgress to LoadingIcon's loading prop
  • Passes icon (IconDefinition | string) to LoadingIcon, which supports both types plus Component
packages/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/2 for 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/icons successfully accepts the size prop with IconSize from svelte-fa. This pattern is consistently used across the codebase (e.g., NotificationCardItem.svelte uses <Icon size="1.5x" ... />), and LoadingIcon.svelte follows the same working approach.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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 suppressWarnings is 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

📥 Commits

Reviewing files that changed from the base of the PR and between 4388cb9 and 1c714c5.

📒 Files selected for processing (4)
  • packages/main/src/plugin/mcp/mcp-registry.spec.ts
  • packages/main/src/plugin/mcp/mcp-registry.ts
  • packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts
  • packages/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 via ipcHandle() in the main process
Use apiSender.send() in the main process to send real-time event updates to the renderer
Container operations must include the engineId parameter to identify the container engine when using ContainerProviderRegistry methods like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, and removePod
Long-running operations should use TaskManager.createTask() to create tasks with title, action name, and execute callback, then set task.status to 'success' or task.error on completion
Use SafeStorageRegistry for storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g., gemini.factory.apiKey) when stored and retrieved via ConfigurationRegistry
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

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.ts
  • packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts
  • packages/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.ts files

Unit 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 of suppressWarnings: true in 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 enhanceServerDetail function properly threads the hasInvalidSchema flag through to the MCPServerDetail type, enabling UI components to display validation indicators.

Comment on lines 553 to 565
// 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,
};
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 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 3

Repository: 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 2

Repository: 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 2

Repository: 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 3

Repository: 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 5

Repository: 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 2

Repository: 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 3

Repository: 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 2

Repository: 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.ts

Repository: 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 2

Repository: 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 8

Repository: 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 -100

Repository: 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.

@gastoner gastoner force-pushed the validation_visual_indicator branch from 2f10660 to 0ae1ef3 Compare January 8, 2026 13:51
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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.

  1. No exceptions thrown: validateSchemaData() returns a SchemaValidationResult object rather than throwing exceptions, so validation errors are safely handled without try-catch.

  2. The false parameter is correct: It sets suppressWarnings: false, meaning warnings ARE logged when validation fails. The approach gracefully degrades by marking invalid servers with isValidSchema: false while continuing to process all servers from the registry.

  3. Clarify the PR description discrepancy: The actual implementation validates individual ServerResponse objects (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-label attribute on a non-interactive div is not semantically correct. For a purely visual indicator, consider one of these approaches:

  • Add role="img" alongside the aria-label to make it an accessible image
  • Remove aria-label and rely on the title attribute for tooltips
  • Use aria-describedby if 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

📥 Commits

Reviewing files that changed from the base of the PR and between f30bea5 and 0ae1ef3.

📒 Files selected for processing (8)
  • packages/api/src/mcp/mcp-server-info.ts
  • packages/main/src/plugin/mcp/mcp-manager.ts
  • packages/main/src/plugin/mcp/mcp-registry.ts
  • packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
  • packages/renderer/src/lib/mcp/MCPDetails.svelte
  • packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
  • packages/renderer/src/lib/mcp/MCPServerListRegistryInstall.svelte
  • packages/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 via ipcHandle() in the main process
Use apiSender.send() in the main process to send real-time event updates to the renderer
Container operations must include the engineId parameter to identify the container engine when using ContainerProviderRegistry methods like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, and removePod
Long-running operations should use TaskManager.createTask() to create tasks with title, action name, and execute callback, then set task.status to 'success' or task.error on completion
Use SafeStorageRegistry for storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g., gemini.factory.apiKey) when stored and retrieved via ConfigurationRegistry
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

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.ts
  • packages/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 setupSecurityRestrictionsOnLinks security handler

Files:

  • packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
  • packages/renderer/src/lib/mcp/MCPServerListRemoteReady.svelte
  • packages/renderer/src/lib/mcp/MCPDetails.svelte
  • packages/renderer/src/lib/mcp/MCPServerListRegistryInstall.svelte
  • 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/mcp/MCPRegistryCreateFromRegistryForm.svelte
  • packages/renderer/src/lib/mcp/MCPServerListRemoteReady.svelte
  • packages/renderer/src/lib/mcp/MCPDetails.svelte
  • packages/renderer/src/lib/mcp/MCPServerListRegistryInstall.svelte
  • packages/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.ts
  • packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
  • packages/renderer/src/lib/mcp/MCPServerListRegistryInstall.svelte
  • packages/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
  • packages/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.svelte
  • packages/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 isValidSchema parameter and its storage in MCPRemoteServerInfo is 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 isValidSchema to 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 isValidSchema flag is correctly threaded through both remote and package setup paths when restoring saved configurations. The validation state from the server detail is properly passed to registerMCPClient.


361-458: LGTM! Validation state properly propagated in MCP server setup.

The isValidSchema flag is correctly destructured from the server detail and passed to registerMCPClient, 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 isValidSchema flag through enhanceServerDetail.

packages/renderer/src/lib/mcp/MCPServerListRemoteReady.svelte (1)

35-38: LGTM! Status indicator updated correctly.

The status column now uses MCPValidServerIndicatorIcon to display validation state. The component will receive MCPRemoteServerInfo objects that include the isValidSchema property, 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 MCPValidServerIndicatorIcon to display validation state for registry servers. The component will receive MCPServerDetail objects that include the isValidSchema property.

packages/renderer/src/lib/mcp/MCPDetails.svelte (1)

47-50: No action needed. MCPValidServerIndicatorIcon explicitly accepts undefined for the object prop (line 7 of the component signature) and safely handles it through conditional checks (line 15). Passing mcpServer without 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 showInvalidIndicator derived value safely checks for the presence of isValidSchema property 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 MCPValidServerIndicatorIcon component.


22-22: Verify the intentional removal of explicit type annotation.

The explicit type annotation was removed, relying instead on type inference from the $mcpRegistriesServerInfos store. 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 MCPValidServerIndicatorIcon is correctly used with appropriate props, and the undefined case is properly guarded by the surrounding {#if mcpRegistryServerDetail} block.

@gastoner
Copy link
Contributor Author

gastoner commented Jan 8, 2026

@simonrey1 updated

Signed-off-by: Evzen Gasta <[email protected]>
@gastoner gastoner force-pushed the validation_visual_indicator branch from 2adea03 to d9a4a27 Compare January 8, 2026 19:21
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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 object prop for clarity

The prop name object is quite generic. Consider renaming it to server or serverDetail for 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 validateSchemaDataMock is shared across tests, and mockImplementation calls 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.fetch in tests is generally acceptable, restoring it in afterEach would 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

📥 Commits

Reviewing files that changed from the base of the PR and between 2adea03 and d9a4a27.

📒 Files selected for processing (3)
  • packages/main/src/plugin/mcp/mcp-registry.spec.ts
  • packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
  • packages/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 via ipcHandle() in the main process
Use apiSender.send() in the main process to send real-time event updates to the renderer
Container operations must include the engineId parameter to identify the container engine when using ContainerProviderRegistry methods like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, and removePod
Long-running operations should use TaskManager.createTask() to create tasks with title, action name, and execute callback, then set task.status to 'success' or task.error on completion
Use SafeStorageRegistry for storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g., gemini.factory.apiKey) when stored and retrieved via ConfigurationRegistry
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

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.ts files

Unit 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 setupSecurityRestrictionsOnLinks security 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 globalFetch and console.error mocks 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.

Copy link
Contributor

Choose a reason for hiding this comment

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

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).

Copy link
Contributor

@simonrey1 simonrey1 left a comment

Choose a reason for hiding this comment

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

Image

I was able to display the list of MCP with the icon of warning:

  • the invalid icon is a bit hard to see (I'm colorblind)
  • left some nitpicks in the code
  • it seems laggy but I think was already the case, to fix it we should implement pagination (different issue)

LGTM

@vancura
Copy link
Contributor

vancura commented Jan 9, 2026

Would something like this work better @simonrey1?

image

@vancura
Copy link
Contributor

vancura commented Jan 9, 2026

@gastoner I can't find the source for this icon. What asset do you need? Is the dot just an overlay?

@gastoner
Copy link
Contributor Author

gastoner commented Jan 9, 2026

@gastoner I can't find the source for this icon. What asset do you need? Is the dot just an overlay?

https://github.com/kortex-hub/kortex/pull/849/changes#diff-3dc9fddc9006c44904af6da3a854fe944634248a2e12fee35c42ba2bc616605bR19

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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 now content.json() is trusted as ServerList; if a registry returns a malformed payload (or servers isn’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 validate ServerList once) 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: serverId generation via encodeURI(server.name) is fragile (reserved chars + potential collisions).
encodeURI won’t escape /, ?, #, etc., which can lead to surprising IDs and harder-to-debug collisions. If name is 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

📥 Commits

Reviewing files that changed from the base of the PR and between d9a4a27 and 3a9355b.

📒 Files selected for processing (5)
  • packages/main/src/plugin/mcp/mcp-registry.spec.ts
  • packages/main/src/plugin/mcp/mcp-registry.ts
  • packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts
  • packages/main/src/plugin/mcp/mcp-schema-validator.ts
  • packages/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 via ipcHandle() in the main process
Use apiSender.send() in the main process to send real-time event updates to the renderer
Container operations must include the engineId parameter to identify the container engine when using ContainerProviderRegistry methods like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, and removePod
Long-running operations should use TaskManager.createTask() to create tasks with title, action name, and execute callback, then set task.status to 'success' or task.error on completion
Use SafeStorageRegistry for storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g., gemini.factory.apiKey) when stored and retrieved via ConfigurationRegistry
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

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.ts
  • packages/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.ts files

Unit 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=true throughout these tests is appropriate for cleaner test output.

packages/main/src/plugin/mcp/mcp-registry.ts (3)

35-37: Import/type wiring looks consistent.
Using ValidatedServerList / ValidatedServerResponse here matches the new “per-server validity” model.


161-165: Verify isValidSchema semantics end-to-end (especially undefined).
You’re correctly threading isValidSchema into registerMCPClient, but please confirm:

  • MCPManager.registerMCPClient accepts boolean | undefined
  • the renderer treats undefined as “valid/unknown” (not invalid), e.g. checks isValidSchema === false rather than !isValidSchema

Also applies to: 194-205, 226-236, 441-454


609-616: Aggregation change is clean and keeps validity attached.
The enhanceServerDetail(rawServer.server, rawServer.isValidSchema) mapping matches the intended UI behavior.

Signed-off-by: Evzen Gasta <[email protected]>
@gastoner gastoner force-pushed the validation_visual_indicator branch from 3a9355b to e8dfad1 Compare January 9, 2026 13:04
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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 that targets merges remotes + packages, relying on a structural check ('url' in ...) is a bit fragile if either schema evolves. A kind: '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 in beforeEach to prevent test pollution.

The validateSchemaDataMock default implementation is overridden in the second test via mockImplementation. 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3a9355b and e8dfad1.

📒 Files selected for processing (6)
  • packages/main/src/plugin/mcp/mcp-registry.spec.ts
  • packages/main/src/plugin/mcp/mcp-registry.ts
  • packages/main/src/plugin/mcp/mcp-schema-validator.spec.ts
  • packages/main/src/plugin/mcp/mcp-schema-validator.ts
  • packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
  • packages/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 via ipcHandle() in the main process
Use apiSender.send() in the main process to send real-time event updates to the renderer
Container operations must include the engineId parameter to identify the container engine when using ContainerProviderRegistry methods like listContainers, startContainer, stopContainer, deleteContainer, pullImage, buildImage, deleteImage, createPod, startPod, stopPod, and removePod
Long-running operations should use TaskManager.createTask() to create tasks with title, action name, and execute callback, then set task.status to 'success' or task.error on completion
Use SafeStorageRegistry for storing and retrieving sensitive credentials and authentication data
Configuration values should use dot notation (e.g., gemini.factory.apiKey) when stored and retrieved via ConfigurationRegistry
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

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
  • packages/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.ts files

Unit 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 setupSecurityRestrictionsOnLinks security 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.ts
  • packages/renderer/src/lib/mcp/MCPRegistryCreateFromRegistryForm.svelte
  • packages/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 whole server, ensure MCPValidServerIndicatorIcon won’t misrender or throw if server.isValidSchema is 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 listMCPServersFromRegistries marks individual servers with their validation status based on validateSchemaData results. The mock implementation distinguishes valid vs invalid servers by name, and assertions check both isValidSchema: true and isValidSchema: false cases.


56-57: Global fetch mock setup is appropriate.

Assigning to global.fetch once at module level and using mockResolvedValueOnce per-test provides clean sequential response mocking.


61-78: Lifecycle hooks properly manage test isolation.

Preserving and restoring console.error ensures no side effects leak between tests, and initializing mcpRegistry in beforeEach guarantees 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 isValidSchema parameter 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 isValidSchema property throughout.


609-621: Aggregation correctly propagates validation status to consumers.

The listMCPServersFromRegistries method now passes rawServer.isValidSchema to enhanceServerDetail, ensuring the UI receives the validation state for each server.


440-454: Validation status correctly forwarded during MCP server setup.

The destructuring of isValidSchema from serverDetail and its propagation to registerMCPClient ensures 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));
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
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).

@gastoner
Copy link
Contributor Author

gastoner commented Jan 9, 2026

@simonrey1 not sure if I can switch to server instead of object at the end... Seems like in the Table there is object prop as a default one and the svelte check fails due to it

Signed-off-by: Evzen Gasta <[email protected]>
@gastoner
Copy link
Contributor Author

@simonrey1 FYI I was forced to go back to object property from server prop due to linter ^^ see comment above

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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 the size prop 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

📥 Commits

Reviewing files that changed from the base of the PR and between e8dfad1 and 104e37e.

📒 Files selected for processing (2)
  • packages/renderer/src/lib/images/MCPValidServerIndicatorIcon.svelte
  • packages/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 setupSecurityRestrictionsOnLinks security 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 === false correctly 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.

@vancura
Copy link
Contributor

vancura commented Jan 12, 2026

The icon update is in gastoner#3

@gastoner
Copy link
Contributor Author

@simonrey1 @vancura updated

);

const { servers } = await this.listMCPServersFromRegistry(registry.serverUrl);
for (const rawServer of servers) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: rawServer is a bit misleading because it now has validation data included

Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: missing newline at EOF

Signed-off-by: Evzen Gasta <[email protected]>
@gastoner gastoner merged commit 3189a61 into kortex-hub:main Jan 12, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add visual indicator to mcp server list when validation fails

4 participants

Comments