Skip to content

Commit 828f433

Browse files
committed
Add MCP management to the Template page
1 parent a536794 commit 828f433

File tree

38 files changed

+629
-345
lines changed

38 files changed

+629
-345
lines changed

README.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,24 @@ Build of the package will be in the `./dist` directory
4646

4747
To set environment variables use .env file
4848

49-
| Name | Type | Default | Description |
50-
| ------------------------------- | ------- | ------- | --------------------------------------------------------- |
51-
| PORT | number | 3000 | Port (for dev server) |
52-
| UI_BASE_URL | string | - | Base URL to proxy requests to ingress (for dev server) |
53-
| JAEGER_API_PATH | string | - | URL path to proxy requests to Jaeger UI (for dev server ) |
54-
| API_BASE_URL | string | - | Base URL to proxy Digma API requests (for dev server) |
55-
| AUTH_API_BASE_URL | string | - | Base URL to proxy auth API requests (for dev server) |
56-
| API_TOKEN | string | - | API token (for dev server) |
57-
| USERNAME | string | - | User login (for dev server) |
58-
| PASSWORD | string | - | User password (for dev server) |
59-
| IS_JAEGER_ENABLED | boolean | false | Enable links to Jaeger |
60-
| JAEGER_UI_PATH | string | - | Path to custom Jaeger UI build |
61-
| IS_SANDBOX_ENABLED | boolean | false | Enable Sandbox (demo) mode |
62-
| ARE_INSIGHT_SUGGESTIONS_ENABLED | boolean | false | Enable insight suggestions |
63-
| GOOGLE_CLIENT_ID | string | - | Google client ID |
64-
| POSTHOG_API_KEY | string | - | PostHog API key |
65-
| POSTHOG_URL | string | - | PostHog URL |
66-
| PRODUCT_FRUITS_WORKSPACE_CODE | string | - | Product Fruits workspace code |
49+
| Name | Type | Default | Description |
50+
| ------------------------------- | ------- | ------- | -------------------------------------------------------- |
51+
| PORT | number | 3000 | Port (for dev server) |
52+
| UI_BASE_URL | string | - | Base URL to proxy requests to ingress (for dev server) |
53+
| JAEGER_API_PATH | string | - | URL path to proxy requests to Jaeger UI (for dev server) |
54+
| API_BASE_URL | string | - | Base URL to proxy Digma API requests (for dev server) |
55+
| AUTH_API_BASE_URL | string | - | Base URL to proxy auth API requests (for dev server) |
56+
| API_TOKEN | string | - | API token (for dev server) |
57+
| USERNAME | string | - | User login (for dev server) |
58+
| PASSWORD | string | - | User password (for dev server) |
59+
| IS_JAEGER_ENABLED | boolean | false | Enable links to Jaeger |
60+
| JAEGER_UI_PATH | string | - | Path to custom Jaeger UI build |
61+
| IS_SANDBOX_ENABLED | boolean | false | Enable Sandbox (demo) mode |
62+
| ARE_INSIGHT_SUGGESTIONS_ENABLED | boolean | false | Enable insight suggestions |
63+
| GOOGLE_CLIENT_ID | string | - | Google client ID |
64+
| POSTHOG_API_KEY | string | - | PostHog API key |
65+
| POSTHOG_URL | string | - | PostHog URL |
66+
| PRODUCT_FRUITS_WORKSPACE_CODE | string | - | Product Fruits workspace code |
6767

6868
## Jaeger UI
6969

src/components/Agentic/IncidentDetails/AgentFlowChart/AgentFlowChartNodeToolbar/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const AgentFlowChartNodeToolbar = ({
1111
isEditMode,
1212
onAddMCPServer,
1313
onEditMCPServer,
14+
onDeleteMCPServer,
1415
showPlusButton
1516
}: AgentFlowChartNodeToolbarProps) => {
1617
const handleAddMCPServer = () => {
@@ -21,13 +22,18 @@ export const AgentFlowChartNodeToolbar = ({
2122
onEditMCPServer(server, position);
2223
};
2324

25+
const handleDeleteMCPServer = (server: string) => {
26+
onDeleteMCPServer(server, position);
27+
};
28+
2429
const toolbarItems = [
2530
...(servers.length > 0
2631
? [
2732
<MCPServersToolbar
2833
key={"mcp-servers-toolbar"}
2934
servers={servers}
3035
onEditMCPServer={handleEditMCPServer}
36+
onDeleteMCPServer={handleDeleteMCPServer}
3137
/>
3238
]
3339
: []),

src/components/Agentic/IncidentDetails/AgentFlowChart/AgentFlowChartNodeToolbar/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ export interface AgentFlowChartNodeToolbarProps {
77
servers: ExtendedAgentMCPServer[];
88
onAddMCPServer: (position: Position) => void;
99
onEditMCPServer: (server: string, position: Position) => void;
10+
onDeleteMCPServer: (server: string, position: Position) => void;
1011
showPlusButton?: boolean;
1112
}

src/components/Agentic/IncidentDetails/AgentFlowChart/MCPServerIcon/index.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ export const MCPServerIcon = ({
2727
themeKind={isActive ? "light" : "dark"}
2828
/>
2929
);
30-
case "mcp":
31-
return <MCPLogoIcon size={size} color={"currentColor"} />;
3230
default:
33-
return null;
31+
return <MCPLogoIcon size={size} color={"currentColor"} />;
3432
}
3533
};

src/components/Agentic/IncidentDetails/AgentFlowChart/MCPServersSideContainer/index.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useViewport } from "@xyflow/react";
2+
import { Tooltip } from "../../../../common/v3/Tooltip";
23
import { MCPServerIcon } from "../MCPServerIcon";
34
import * as s from "./styles";
45
import type { MCPServersSideContainerProps } from "./types";
@@ -18,17 +19,15 @@ export const MCPServersSideContainer = ({
1819
return (
1920
<s.Container $zoomLevel={zoomLevel}>
2021
{servers?.map((x) => (
21-
<s.MCPServerBlock
22-
key={x.name}
23-
$isActive={x.active}
24-
$zoomLevel={viewport.zoom}
25-
>
26-
<MCPServerIcon
27-
type={x.name}
28-
isActive={x.active}
29-
size={DEFAULT_ICON_SIZE * viewport.zoom}
30-
/>
31-
</s.MCPServerBlock>
22+
<Tooltip title={x.display_name} key={x.name}>
23+
<s.MCPServerBlock $isActive={x.active} $zoomLevel={viewport.zoom}>
24+
<MCPServerIcon
25+
type={x.name}
26+
isActive={x.active}
27+
size={DEFAULT_ICON_SIZE * viewport.zoom}
28+
/>
29+
</s.MCPServerBlock>
30+
</Tooltip>
3231
))}
3332
</s.Container>
3433
);

src/components/Agentic/IncidentDetails/AgentFlowChart/MCPServersToolbar/index.tsx

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { useNodeId, useViewport } from "@xyflow/react";
22
import { useState } from "react";
33
import { sendUserActionTrackingEvent } from "../../../../../utils/actions/sendUserActionTrackingEvent";
4+
import { TrashBinIcon } from "../../../../common/icons/16px/TrashBinIcon";
45
import { WrenchIcon } from "../../../../common/icons/16px/WrenchIcon";
56
import { NewPopover } from "../../../../common/NewPopover";
7+
import { Tooltip } from "../../../../common/v3/Tooltip";
68
import { MenuList } from "../../../../Navigation/common/MenuList";
79
import type { MenuItem } from "../../../../Navigation/common/MenuList/types";
810
import { Popup } from "../../../../Navigation/common/Popup";
@@ -13,7 +15,8 @@ import type { MCPServersToolbarProps } from "./types";
1315

1416
export const MCPServersToolbar = ({
1517
servers,
16-
onEditMCPServer
18+
onEditMCPServer,
19+
onDeleteMCPServer
1720
}: MCPServersToolbarProps) => {
1821
const [isKebabMenuOpen, setIsKebabMenuOpen] = useState(false);
1922
const [selectedMCPServer, setSelectedMCPServer] = useState<string>();
@@ -51,6 +54,12 @@ export const MCPServersToolbar = ({
5154
}
5255
break;
5356
}
57+
case "delete": {
58+
if (selectedMCPServer) {
59+
onDeleteMCPServer(selectedMCPServer);
60+
}
61+
break;
62+
}
5463
}
5564

5665
setIsKebabMenuOpen(false);
@@ -62,6 +71,12 @@ export const MCPServersToolbar = ({
6271
icon: <WrenchIcon size={16} color={"currentColor"} />,
6372
label: "Edit",
6473
onClick: () => handleKebabMenuItemClick("edit")
74+
},
75+
{
76+
id: "delete",
77+
icon: <TrashBinIcon size={16} color={"currentColor"} />,
78+
label: "Delete",
79+
onClick: () => handleKebabMenuItemClick("delete")
6580
}
6681
];
6782

@@ -76,12 +91,18 @@ export const MCPServersToolbar = ({
7691
<MenuList items={kebabMenuItems} />
7792
</Popup>
7893
}
79-
isOpen={isKebabMenuOpen && selectedMCPServer === x.name}
94+
isOpen={Boolean(
95+
isKebabMenuOpen && selectedMCPServer === x.name && x.isEditable
96+
)}
8097
onOpenChange={handleKebabMenuOpenChange(x.name)}
8198
>
82-
<s.MCPServerIconContainer>
83-
<MCPServerIcon type={x.name} isActive={x.active} size={17} />
84-
</s.MCPServerIconContainer>
99+
<div>
100+
<Tooltip title={x.display_name}>
101+
<s.MCPServerIconContainer $isEditable={x.isEditable}>
102+
<MCPServerIcon type={x.name} isActive={x.active} size={17} />
103+
</s.MCPServerIconContainer>
104+
</Tooltip>
105+
</div>
85106
</NewPopover>
86107
))}
87108
</s.Container>

src/components/Agentic/IncidentDetails/AgentFlowChart/MCPServersToolbar/styles.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import styled from "styled-components";
2-
import type { ContainerProps } from "./types";
2+
import type { ContainerProps, MCPServerIconContainerProps } from "./types";
33

44
export const Container = styled.div<ContainerProps>`
55
display: flex;
@@ -18,10 +18,11 @@ export const Container = styled.div<ContainerProps>`
1818
);
1919
`;
2020

21-
export const MCPServerIconContainer = styled.div`
21+
export const MCPServerIconContainer = styled.div<MCPServerIconContainerProps>`
2222
display: flex;
2323
align-items: center;
2424
justify-content: center;
25+
cursor: ${({ $isEditable }) => ($isEditable ? "pointer" : "default")};
2526
`;
2627

2728
export const KebabMenuButton = styled.button`

src/components/Agentic/IncidentDetails/AgentFlowChart/MCPServersToolbar/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ import type { ExtendedAgentMCPServer } from "../types";
33
export interface MCPServersToolbarProps {
44
servers: ExtendedAgentMCPServer[];
55
onEditMCPServer: (server: string) => void;
6+
onDeleteMCPServer: (server: string) => void;
67
}
78

89
export interface ContainerProps {
910
$zoomLevel?: number;
1011
}
12+
13+
export interface MCPServerIconContainerProps {
14+
$isEditable?: boolean;
15+
}

src/components/Agentic/IncidentDetails/AgentFlowChart/index.tsx

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ const getFlowChartNodeData = ({
1616
isInteractive,
1717
isEditMode,
1818
onAddMCPServer,
19-
onEditMCPServer
19+
onEditMCPServer,
20+
onDeleteMCPServer
2021
}: {
2122
agent?: ExtendedAgent;
2223
isInteractive?: boolean;
@@ -28,6 +29,11 @@ const getFlowChartNodeData = ({
2829
server: string,
2930
position: Position
3031
) => void;
32+
onDeleteMCPServer?: (
33+
agentName: string,
34+
server: string,
35+
position: Position
36+
) => void;
3137
}): Partial<FlowChartNodeData> => {
3238
const handleAddMCPServer = (position: Position) => () => {
3339
sendUserActionTrackingEvent(
@@ -53,6 +59,14 @@ const getFlowChartNodeData = ({
5359
onEditMCPServer?.(agent.name, server, position);
5460
};
5561

62+
const handleDeleteMCPServer = (position: Position) => (server: string) => {
63+
if (!agent) {
64+
return;
65+
}
66+
67+
onDeleteMCPServer?.(agent.name, server, position);
68+
};
69+
5670
const serverGroups = groupBy(
5771
agent?.mcp_servers ?? [],
5872
(server) => server.position ?? Position.Top
@@ -63,6 +77,7 @@ const getFlowChartNodeData = ({
6377
label: agent.display_name,
6478
isActive: isSelected,
6579
isRunning: agent.running,
80+
isPending: agent.status === "pending",
6681
isInteractive,
6782
isDisabled: agent.status === "inactive",
6883
sideContainers: Object.values(Position).map((position) => ({
@@ -78,6 +93,7 @@ const getFlowChartNodeData = ({
7893
servers={serverGroups[position] ?? []}
7994
onAddMCPServer={handleAddMCPServer(position)}
8095
onEditMCPServer={handleEditMCPServer(position)}
96+
onDeleteMCPServer={handleDeleteMCPServer(position)}
8197
showPlusButton={
8298
isEditMode &&
8399
(["watchman", "triager"].includes(agent.name) ||
@@ -101,7 +117,8 @@ export const AgentFlowChart = ({
101117
className,
102118
isEditMode,
103119
onAddMCPServer,
104-
onEditMCPServer
120+
onEditMCPServer,
121+
onDeleteMCPServer
105122
}: AgentFlowChartProps) => {
106123
const extendedAgents: ExtendedAgent[] = [
107124
{
@@ -186,7 +203,8 @@ export const AgentFlowChart = ({
186203
"inactive",
187204
isEditMode,
188205
onAddMCPServer,
189-
onEditMCPServer
206+
onEditMCPServer,
207+
onDeleteMCPServer
190208
})
191209
}
192210
},
@@ -202,7 +220,8 @@ export const AgentFlowChart = ({
202220
"inactive",
203221
isEditMode,
204222
onAddMCPServer,
205-
onEditMCPServer
223+
onEditMCPServer,
224+
onDeleteMCPServer
206225
})
207226
}
208227
},
@@ -218,7 +237,8 @@ export const AgentFlowChart = ({
218237
"inactive",
219238
isEditMode,
220239
onAddMCPServer,
221-
onEditMCPServer
240+
onEditMCPServer,
241+
onDeleteMCPServer
222242
})
223243
}
224244
},
@@ -234,7 +254,8 @@ export const AgentFlowChart = ({
234254
"inactive",
235255
isEditMode,
236256
onAddMCPServer,
237-
onEditMCPServer
257+
onEditMCPServer,
258+
onDeleteMCPServer
238259
})
239260
}
240261
},

src/components/Agentic/IncidentDetails/AgentFlowChart/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,16 @@ export interface AgentFlowChartProps {
1313
server: string,
1414
position: Position
1515
) => void;
16+
onDeleteMCPServer?: (
17+
agentId: string,
18+
server: string,
19+
position: Position
20+
) => void;
1621
}
1722

1823
export interface ExtendedAgentMCPServer extends AgentMCPServer {
1924
position?: Position;
25+
isEditable?: boolean;
2026
}
2127

2228
export interface ExtendedAgent extends Agent {

0 commit comments

Comments
 (0)