File size: 4,109 Bytes
dd325fe
1
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: mcp_letter_counter_app"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "\n", "@gr.mcp.tool(\n", "    _meta={\n", "        \"openai/outputTemplate\": \"ui://widget/app.html\",\n", "        \"openai/resultCanProduceWidget\": True,\n", "        \"openai/widgetAccessible\": True,\n", "    }\n", ")\n", "def letter_counter(word: str, letter: str) -> int:\n", "    \"\"\"\n", "    Count the number of letters in a word or phrase.\n", "\n", "    Parameters:\n", "        word (str): The word or phrase to count the letters of.\n", "        letter (str): The letter to count the occurrences of.\n", "    \"\"\"\n", "    return word.count(letter)\n", "\n", "\n", "@gr.mcp.resource(\"ui://widget/app.html\", mime_type=\"text/html+skybridge\")\n", "def app_html():\n", "    visual = \"\"\"\n", "    <div id=\"letter-card-container\"></div>\n", "    <script>\n", "        const container = document.getElementById('letter-card-container');\n", "\n", "        function render() {\n", "            const word = window.openai?.toolInput?.word || \"strawberry\";\n", "            const letter = window.openai?.toolInput?.letter || \"r\";\n", "\n", "            let letterHTML = '';\n", "            for (let i = 0; i < word.length; i++) {\n", "                const char = word[i];\n", "                const color = char.toLowerCase() === letter.toLowerCase() ? '#b8860b' : '#000000';\n", "                letterHTML += `<span style=\"color: ${color};\">${char}</span>`;\n", "            }\n", "\n", "            container.innerHTML = `\n", "                <div style=\"\n", "                    background: linear-gradient(135deg, #f5f5dc 0%, #e8e4d0 100%);\n", "                    background-image:\n", "                        repeating-linear-gradient(45deg, transparent, transparent 2px, rgba(139, 121, 94, 0.03) 2px, rgba(139, 121, 94, 0.03) 4px),\n", "                        linear-gradient(135deg, #f5f5dc 0%, #e8e4d0 100%);\n", "                    border-radius: 16px;\n", "                    padding: 40px;\n", "                    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n", "                    max-width: 600px;\n", "                    margin: 20px auto;\n", "                    font-family: 'Georgia', serif;\n", "                    text-align: center;\n", "                \">\n", "                    <div style=\"\n", "                        font-size: 48px;\n", "                        font-weight: bold;\n", "                        letter-spacing: 8px;\n", "                        line-height: 1.5;\n", "                    \">\n", "                        ${letterHTML}\n", "                    </div>\n", "                </div>\n", "            `;\n", "        }\n", "        render();\n", "        window.addEventListener(\"openai:set_globals\", (event) => {\n", "            if (event.detail?.globals?.toolInput) {\n", "                render();\n", "            }\n", "        }, { passive: true });\n", "    </script>\n", "    \"\"\"\n", "    return visual\n", "\n", "\n", "with gr.Blocks() as demo:\n", "    with gr.Row():\n", "        with gr.Column():\n", "            word = gr.Textbox(label=\"Word\")\n", "            letter = gr.Textbox(label=\"Letter\")\n", "            btn = gr.Button(\"Count Letters\")\n", "        with gr.Column():\n", "            count = gr.Number(label=\"Count\")\n", "            html = gr.Code(language=\"html\", max_lines=20)\n", "\n", "    btn.click(letter_counter, inputs=[word, letter], outputs=count)\n", "    btn.click(app_html, outputs=html)\n", "\n", "if __name__ == \"__main__\":\n", "    demo.launch(mcp_server=True, share=True)\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}