diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/McpTab.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/McpTab.tsx new file mode 100644 index 0000000..5f42af6 --- /dev/null +++ b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/McpTab.tsx @@ -0,0 +1,96 @@ +"use client"; + +import { useQuery, useQueryClient } from "@tanstack/react-query"; +import { RefreshCwIcon } from "lucide-react"; +import type { FC } from "react"; +import { Button } from "@/components/ui/button"; +import { honoClient } from "@/lib/api/client"; + +export const McpTab: FC = () => { + const queryClient = useQueryClient(); + + const { + data: mcpData, + isLoading, + error, + } = useQuery({ + queryKey: ["mcp", "list"], + queryFn: async () => { + const response = await honoClient.api.mcp.list.$get(); + if (!response.ok) { + throw new Error("Failed to fetch MCP servers"); + } + return response.json(); + }, + }); + + const handleReload = () => { + queryClient.invalidateQueries({ queryKey: ["mcp", "list"] }); + }; + + return ( +
+
+
+

+ MCP Servers +

+ +
+
+ +
+ {isLoading && ( +
+
Loading...
+
+ )} + + {error && ( +
+ Failed to load MCP servers: {(error as Error).message} +
+ )} + + {mcpData && mcpData.servers.length === 0 && ( +
+ No MCP servers found +
+ )} + + {mcpData && mcpData.servers.length > 0 && ( +
+ {mcpData.servers.map((server) => ( +
+
+
+

+ {server.name} +

+

+ {server.command} +

+
+
+
+ ))} +
+ )} +
+
+ ); +}; diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx index f9ce644..94df668 100644 --- a/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx +++ b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx @@ -1,10 +1,11 @@ "use client"; -import { MessageSquareIcon, SettingsIcon } from "lucide-react"; +import { MessageSquareIcon, PlugIcon, SettingsIcon } from "lucide-react"; import { type FC, useState } from "react"; import { Dialog, DialogContent } from "@/components/ui/dialog"; import { cn } from "@/lib/utils"; import { useProject } from "../../../../hooks/useProject"; +import { McpTab } from "./McpTab"; import { SessionsTab } from "./SessionsTab"; import { SettingsTab } from "./SettingsTab"; @@ -24,12 +25,12 @@ export const SessionSidebar: FC<{ const { data: { sessions }, } = useProject(projectId); - const [activeTab, setActiveTab] = useState<"sessions" | "settings">( + const [activeTab, setActiveTab] = useState<"sessions" | "mcp" | "settings">( "sessions", ); const [isExpanded, setIsExpanded] = useState(true); - const handleTabClick = (tab: "sessions" | "settings") => { + const handleTabClick = (tab: "sessions" | "mcp" | "settings") => { if (activeTab === tab && isExpanded) { // If clicking the active tab while expanded, collapse setIsExpanded(false); @@ -50,6 +51,8 @@ export const SessionSidebar: FC<{ projectId={projectId} /> ); + case "mcp": + return ; case "settings": return ; default: @@ -82,6 +85,21 @@ export const SessionSidebar: FC<{ + +