Skip to main content
Glama
BruceWilliamChen

ChatGPT Apps MCP Server

index.tsx5.46 kB
import React, { useState } from "react"; import { createRoot } from "react-dom/client"; import { useOpenAiGlobal } from "../use-openai-global"; import { useWidgetState } from "../use-widget-state"; type CalculatorState = { history: Array<{ expression: string; result: string }>; }; function App() { const toolOutput = useOpenAiGlobal("toolOutput") as any; const theme = useOpenAiGlobal("theme"); const [widgetState, setWidgetState] = useWidgetState<CalculatorState>({ history: [], }); const [display, setDisplay] = useState("0"); const [expression, setExpression] = useState(""); // Add result from tool output to history React.useEffect(() => { if (toolOutput?.expression && toolOutput?.result) { const newHistory = [ ...(widgetState?.history || []), { expression: toolOutput.expression, result: toolOutput.result }, ]; setWidgetState({ history: newHistory.slice(-5) }); // Keep last 5 } }, [toolOutput]); const handleNumber = (num: string) => { if (display === "0") { setDisplay(num); setExpression(num); } else { setDisplay(display + num); setExpression(expression + num); } }; const handleOperator = (op: string) => { setDisplay(display + " " + op + " "); setExpression(expression + op); }; const handleClear = () => { setDisplay("0"); setExpression(""); }; const handleEquals = async () => { try { const result = String(eval(expression)); setDisplay(result); // Call the MCP server tool to log the calculation if (window.openai?.callTool) { await window.openai.callTool("calculator", { expression }); } } catch (error) { setDisplay("Error"); } }; const isDark = theme === "dark"; const bgClass = isDark ? "bg-gray-900" : "bg-white"; const textClass = isDark ? "text-white" : "text-gray-900"; const buttonClass = isDark ? "bg-gray-700 hover:bg-gray-600" : "bg-gray-200 hover:bg-gray-300"; const operatorClass = isDark ? "bg-blue-600 hover:bg-blue-500" : "bg-blue-500 hover:bg-blue-600"; return ( <div className={"w-full max-w-sm mx-auto p-4 rounded-2xl " + bgClass + " " + textClass}> <div className="mb-4"> <div className="text-2xl font-bold mb-2">Calculator</div> <div className={"text-right text-3xl font-mono p-4 rounded-lg " + (isDark ? "bg-gray-800" : "bg-gray-100")}> {display} </div> </div> <div className="grid grid-cols-4 gap-2 mb-4"> {["7", "8", "9"].map((num) => ( <button key={num} onClick={() => handleNumber(num)} className={"p-4 rounded-lg font-semibold " + buttonClass} > {num} </button> ))} <button onClick={() => handleOperator("/")} className={"p-4 rounded-lg font-semibold text-white " + operatorClass} > ÷ </button> {["4", "5", "6"].map((num) => ( <button key={num} onClick={() => handleNumber(num)} className={"p-4 rounded-lg font-semibold " + buttonClass} > {num} </button> ))} <button onClick={() => handleOperator("*")} className={"p-4 rounded-lg font-semibold text-white " + operatorClass} > × </button> {["1", "2", "3"].map((num) => ( <button key={num} onClick={() => handleNumber(num)} className={"p-4 rounded-lg font-semibold " + buttonClass} > {num} </button> ))} <button onClick={() => handleOperator("-")} className={"p-4 rounded-lg font-semibold text-white " + operatorClass} > − </button> {["0", "."].map((num) => ( <button key={num} onClick={() => handleNumber(num)} className={"p-4 rounded-lg font-semibold " + buttonClass} > {num} </button> ))} <button onClick={handleClear} className={"p-4 rounded-lg font-semibold " + (isDark ? "bg-red-600 hover:bg-red-500" : "bg-red-500 hover:bg-red-600") + " text-white"} > C </button> <button onClick={() => handleOperator("+")} className={"p-4 rounded-lg font-semibold text-white " + operatorClass} > + </button> <button onClick={handleEquals} className={"col-span-4 p-4 rounded-lg font-semibold text-white " + (isDark ? "bg-green-600 hover:bg-green-500" : "bg-green-500 hover:bg-green-600")} > = </button> </div> {widgetState?.history && widgetState.history.length > 0 && ( <div className="mt-4"> <div className="text-sm font-semibold mb-2">History</div> <div className="space-y-1"> {widgetState.history.slice().reverse().map((item, i) => ( <div key={i} className={"text-sm p-2 rounded " + (isDark ? "bg-gray-800" : "bg-gray-100")} > {item.expression} = {item.result} </div> ))} </div> </div> )} </div> ); } const root = document.getElementById("calculator-root"); if (root) { createRoot(root).render(<App />); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/BruceWilliamChen/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server