- {items.map((item, idx) => {
+ {safeItems.map((item, idx) => {
return (
-
{item.name}
- {item.description && (
+
{item?.name ?? "Unknown"}
+ {item?.description && (
{item.description}
@@ -337,7 +338,7 @@ function MCPServerPreview({
allToolsOff={allToolsOff}
duplicateDetection={duplicateDetection}
/>
- {server.prompts.length > 0 && (
+ {Array.isArray(server.prompts) && server.prompts.length > 0 && (
)}
- {(server.resources.length > 0 ||
- server.resourceTemplates.length > 0) && (
+ {(Array.isArray(server.resources) && server.resources.length > 0) ||
+ (Array.isArray(server.resourceTemplates) &&
+ server.resourceTemplates.length > 0) ? (
}
sectionKey={`${server.id}-resources`}
/>
- )}
+ ) : null}
{/* Error display below expandable section */}
@@ -447,10 +452,26 @@ export function ToolsSection() {
.map((server) => [server.name, server]) ?? [],
);
- return (servers ?? []).map((doc: MCPServerStatus) => ({
- block: doc,
- blockFromYaml: yamlServersByName.get(doc.name),
- }));
+ // Filter out any invalid servers and ensure they have required properties
+ return (servers ?? [])
+ .filter((doc: MCPServerStatus) => {
+ // Ensure server has required properties to prevent render issues
+ return (
+ doc &&
+ typeof doc.id === "string" &&
+ typeof doc.name === "string" &&
+ doc.name.length > 0 &&
+ Array.isArray(doc.prompts) &&
+ Array.isArray(doc.resources) &&
+ Array.isArray(doc.resourceTemplates) &&
+ Array.isArray(doc.errors) &&
+ Array.isArray(doc.infos)
+ );
+ })
+ .map((doc: MCPServerStatus) => ({
+ block: doc,
+ blockFromYaml: yamlServersByName.get(doc.name),
+ }));
}, [servers, selectedProfile]);
const handleAddMcpServer = () => {
@@ -524,7 +545,7 @@ export function ToolsSection() {
{mergedBlocks.length > 0 ? (
mergedBlocks.map(({ block, blockFromYaml }) => (
{
+ // Filter out invalid servers that could cause render loops
+ return (
+ server &&
+ typeof server === "object" &&
+ typeof server.id === "string" &&
+ server.id.length > 0 &&
+ typeof server.name === "string" &&
+ server.name.length > 0 &&
+ // Ensure arrays exist even if empty
+ Array.isArray(server.prompts) &&
+ Array.isArray(server.resources) &&
+ Array.isArray(server.resourceTemplates) &&
+ Array.isArray(server.errors) &&
+ Array.isArray(server.infos)
+ );
+ });
+}
+
export const INITIAL_CONFIG_SLICE: ConfigState = {
configError: undefined,
config: EMPTY_CONFIG,
@@ -66,7 +96,13 @@ export const configSlice = createSlice({
if (!config) {
state.config = EMPTY_CONFIG;
} else {
- state.config = config;
+ // Sanitize MCP server statuses to prevent render issues
+ state.config = {
+ ...config,
+ mcpServerStatuses: sanitizeMcpServerStatuses(
+ config.mcpServerStatuses,
+ ),
+ };
}
state.loading = false;
},
@@ -74,7 +110,11 @@ export const configSlice = createSlice({
state,
{ payload: config }: PayloadAction,
) => {
- state.config = config;
+ // Sanitize MCP server statuses when updating config
+ state.config = {
+ ...config,
+ mcpServerStatuses: sanitizeMcpServerStatuses(config.mcpServerStatuses),
+ };
},
setConfigLoading: (state, { payload: loading }: PayloadAction) => {
state.loading = loading;