import { useCallback, useEffect, useRef, useState, useTransition } from "react"; import { getClient, getTemplate } from "./utils"; import { useMcpStore } from "./state"; import { AppShell } from "ui/layouts/AppShell"; import { TbHistory, TbHistoryOff, TbRefresh } from "react-icons/tb"; import { IconButton } from "ui/components/buttons/IconButton"; import { JsonViewer, JsonViewerTabs, type JsonViewerTabsRef } from "ui/components/code/JsonViewer"; import { twMerge } from "ui/elements/mocks/tailwind-merge"; import { Field, Form } from "ui/components/form/json-schema-form"; import { Button } from "ui/components/buttons/Button"; import * as Formy from "ui/components/form/Formy"; import { appShellStore } from "ui/store"; export function Sidebar({ open, toggle }) { const client = getClient(); const closeSidebar = appShellStore((store) => store.closeSidebar("default")); const tools = useMcpStore((state) => state.tools); const setTools = useMcpStore((state) => state.setTools); const setContent = useMcpStore((state) => state.setContent); const content = useMcpStore((state) => state.content); const [loading, setLoading] = useState(false); const [query, setQuery] = useState(""); const handleRefresh = useCallback(async () => { setLoading(true); const res = await client.listTools(); if (res) setTools(res.tools); setLoading(false); }, []); useEffect(() => { handleRefresh(); }, []); return ( (
{tools.length}
)} >
setQuery(e.target.value)} autoCapitalize="none" />
); } export function Content() { const content = useMcpStore((state) => state.content); const addHistory = useMcpStore((state) => state.addHistory); const [payload, setPayload] = useState(getTemplate(content?.inputSchema)); const [result, setResult] = useState(null); const historyVisible = useMcpStore((state) => state.historyVisible); const setHistoryVisible = useMcpStore((state) => state.setHistoryVisible); const client = getClient(); const jsonViewerTabsRef = useRef(null); const hasInputSchema = content?.inputSchema && Object.keys(content.inputSchema.properties ?? {}).length > 0; const [isPending, startTransition] = useTransition(); useEffect(() => { setPayload(getTemplate(content?.inputSchema)); setResult(null); }, [content]); const handleSubmit = useCallback(async () => { if (!content?.name) return; const request = { name: content.name, arguments: payload, }; startTransition(async () => { addHistory("request", request); const res = await client.callTool(request); if (res) { setResult(res); addHistory("response", res); jsonViewerTabsRef.current?.setSelected("Result"); } }); }, [payload]); if (!content) return null; let readableResult = result; try { readableResult = result ? (result as any).content?.[0].text ? JSON.parse((result as any).content[0].text) : result : null; } catch (e) {} return (
{ setPayload(value); }} onSubmit={handleSubmit} > setHistoryVisible(!historyVisible)} /> } > Tools / {" "} {content?.name}

{content?.description}

{hasInputSchema && }
{historyVisible && ( )}
); } const History = () => { const history = useMcpStore((state) => state.history.slice(0, 50)); return ( <> History
{history.map((item, i) => ( ))}
); };