import gradio as gr import math import PIL.Image import PIL.ImageFilter import PIL.ImageEnhance import numpy as np from typing import Optional def calculator(operation: str, a: float, b: float) -> str: """ 基本的な計算機能を提供します。 Args: operation: 実行する演算 (add, subtract, multiply, divide, power, sqrt) a: 最初の数値 b: 二番目の数値(sqrt以外で必要) Returns: str: 計算結果 """ try: if operation == "add": result = a + b elif operation == "subtract": result = a - b elif operation == "multiply": result = a * b elif operation == "divide": if b == 0: return "エラー: ゼロで割ることはできません" result = a / b elif operation == "power": result = a ** b elif operation == "sqrt": if a < 0: return "エラー: 負の数の平方根は計算できません" result = math.sqrt(a) else: return f"エラー: 未対応の演算 '{operation}'" return f"結果: {result}" except Exception as e: return f"計算エラー: {str(e)}" def image_processor(image: PIL.Image.Image, effect: str = "blur", intensity: float = 1.0) -> PIL.Image.Image: """ 画像にエフェクトを適用します。 Args: image: 入力画像 effect: 適用するエフェクト (blur, sharpen, brightness, contrast) intensity: エフェクトの強度 (0.1-3.0) Returns: PIL.Image.Image: 処理済み画像 """ if image is None: return None try: # intensityを適切な範囲に制限 intensity = max(0.1, min(3.0, intensity)) if effect == "blur": return image.filter(PIL.ImageFilter.GaussianBlur(radius=intensity)) elif effect == "sharpen": return image.filter(PIL.ImageFilter.UnsharpMask(radius=intensity)) elif effect == "brightness": enhancer = PIL.ImageEnhance.Brightness(image) return enhancer.enhance(intensity) elif effect == "contrast": enhancer = PIL.ImageEnhance.Contrast(image) return enhancer.enhance(intensity) else: return image except Exception as e: print(f"画像処理エラー: {e}") return image def text_analyzer(text: str) -> str: """ テキストを分析して統計情報を返します。 Args: text: 分析するテキスト Returns: str: テキスト分析結果 """ if not text: return "テキストが入力されていません。" try: # 基本統計 char_count = len(text) word_count = len(text.split()) line_count = len(text.split('\n')) # 文字種別カウント alpha_count = sum(1 for c in text if c.isalpha()) digit_count = sum(1 for c in text if c.isdigit()) space_count = sum(1 for c in text if c.isspace()) analysis = f"""📊 テキスト分析結果: 📏 基本統計: • 文字数: {char_count} • 単語数: {word_count} • 行数: {line_count} 🔤 文字種別: • 英字: {alpha_count} • 数字: {digit_count} • 空白: {space_count} 📈 密度: • 平均単語長: {char_count/word_count:.1f}文字 (単語数 > 0の場合) • 英字比率: {alpha_count/char_count*100:.1f}% """ return analysis except Exception as e: return f"分析エラー: {str(e)}" # メインアプリケーションの作成 with gr.Blocks( title="Gradio Streamable HTTP MCP Demo - MakiAi", theme=gr.themes.Soft(), css=""" .tab-nav button { font-size: 16px !important; } .markdown-body h2 { color: #2563eb !important; } """ ) as demo: gr.Markdown(""" # 🚀 Gradio Streamable HTTP MCP デモアプリ このアプリは、Gradio の新しい **Streamable HTTP Transport for MCP server** 機能のデモです。 ## 🔗 ライブ MCP エンドポイント 以下のエンドポイントで**MCP Inspector**や対応クライアントからMCPツールにアクセスできます: - **HTTP Transport**: `https://makiai-gradio-streamable-mcp-demo.hf.space/gradio_api/mcp/http/` - **SSE Transport**: `https://makiai-gradio-streamable-mcp-demo.hf.space/gradio_api/mcp/sse` **⚠️ 注意**: Claude Desktop は現在 HTTP transport に対応していません。MCP Inspector での動作確認をお勧めします。 ## 🛠️ 利用可能なツール """) with gr.Tabs(): # Calculator Tab with gr.Tab("🧮 Calculator", id="calculator"): gr.Markdown("### 数学計算ツール") with gr.Row(): with gr.Column(): calc_operation = gr.Dropdown( choices=["add", "subtract", "multiply", "divide", "power", "sqrt"], value="add", label="演算" ) calc_a = gr.Number(value=10, label="数値 A") calc_b = gr.Number(value=5, label="数値 B (sqrt以外で使用)") with gr.Column(): calc_result = gr.Textbox(label="計算結果", interactive=False) calc_btn = gr.Button("計算実行", variant="primary") calc_btn.click( fn=calculator, inputs=[calc_operation, calc_a, calc_b], outputs=calc_result ) # Image Processor Tab with gr.Tab("🖼️ Image Processor", id="image_processor"): gr.Markdown("### 画像処理ツール") with gr.Row(): with gr.Column(): input_image = gr.Image( label="入力画像", type="pil", height=300 ) effect_type = gr.Dropdown( choices=["blur", "sharpen", "brightness", "contrast"], value="blur", label="エフェクト" ) effect_intensity = gr.Slider( minimum=0.1, maximum=3.0, value=1.0, step=0.1, label="強度" ) with gr.Column(): output_image = gr.Image( label="処理済み画像", height=300 ) process_btn = gr.Button("画像処理実行", variant="primary") process_btn.click( fn=image_processor, inputs=[input_image, effect_type, effect_intensity], outputs=output_image ) # Text Analyzer Tab with gr.Tab("📝 Text Analyzer", id="text_analyzer"): gr.Markdown("### テキスト分析ツール") with gr.Row(): with gr.Column(): input_text = gr.Textbox( label="分析対象テキスト", placeholder="ここにテキストを入力してください...", lines=8, value="Hello World! これはサンプルテキストです。\n日本語と英語が混在しています。" ) with gr.Column(): analysis_result = gr.Textbox( label="分析結果", lines=15, interactive=False ) analyze_btn = gr.Button("テキスト分析実行", variant="primary") analyze_btn.click( fn=text_analyzer, inputs=input_text, outputs=analysis_result ) gr.Markdown(""" ## 📋 MCP クライアントでの使用方法 ### 🧪 **動作確認済みの方法** **✅ MCP Inspector(最推奨)**: ```bash npx @modelcontextprotocol/inspector https://makiai-gradio-streamable-mcp-demo.hf.space/gradio_api/mcp/http/ ``` **✅ cURL でのテスト**: ```bash curl -X POST https://makiai-gradio-streamable-mcp-demo.hf.space/gradio_api/mcp/http/ \ -H "Content-Type: application/json" \ -d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}' ``` ### 🖥️ **Claude Desktop での制限と代替手段** **⚠️ 重要**: Claude Desktop は現在 HTTP transport を直接サポートしていません。STDIO transport のみがサポートされています。 **🔧 代替解決策**: **1. MCP Inspector での直接テスト(推奨)**: ```bash npx @modelcontextprotocol/inspector https://makiai-gradio-streamable-mcp-demo.hf.space/gradio_api/mcp/http/ ``` **2. 他のMCPクライアントでの使用**: - **Cursor IDE**: HTTP transport をサポート - **LibreChat**: HTTP transport をサポート - **VSCode 拡張**: 各種MCP拡張で利用可能 **3. STDIO-HTTP Proxy を使用**: ```bash # proxy サーバーを作成してClaude Desktopで使用 # 詳細: https://github.com/boilingdata/mcp-server-and-gw ``` ### 🛠️ **利用可能なツール** - **`calculator`**: 基本的な数学計算(加算、減算、乗算、除算、べき乗、平方根) - **`image_processor`**: 画像エフェクト処理(ぼかし、シャープ化、明度、コントラスト調整) - **`text_analyzer`**: テキスト統計分析(文字数、単語数、文字種別分析) ## 🔧 技術詳細 - **🌐 Space URL**: [Hugging Face Space](https://huggingface.co/spaces/MakiAi/gradio-streamable-mcp-demo) - **🚀 Transport**: Streamable HTTP (**最新機能!**) - **📡 Protocol**: MCP (Model Context Protocol) - **🔗 HTTP Endpoint**: `https://makiai-gradio-streamable-mcp-demo.hf.space/gradio_api/mcp/http/` - **📺 SSE Endpoint**: `https://makiai-gradio-streamable-mcp-demo.hf.space/gradio_api/mcp/sse` - **✨ Features**: ファイル入出力対応、リアルタイム処理、状態管理 ## 🎯 デモの特徴と現在の対応状況 このアプリは **Gradio PR #11300** で実装された最新の Streamable HTTP Transport 機能を使用しています。 **📦 必要な Dependencies**: ```text # Gradio with MCP support (特定のプレビューバージョン) https://gradio-pypi-previews.s3.amazonaws.com/5bf3a9365e945803ba3b30ec470058c0d1aea03a/gradio-5.31.0-py3-none-any.whl Pillow>=10.0.0 numpy>=1.21.0 ``` **✅ 動作確認済み**: - MCP Inspector での直接アクセス - Cursor IDE での HTTP transport - LibreChat での HTTP transport - cURL/HTTPクライアントでの直接API呼び出し **⚠️ 制限事項**: - Claude Desktop は現在 STDIO transport のみサポート - HTTP transport は Claude Desktop で直接使用不可 **🔮 今後の展望**: - Claude Desktop での HTTP transport サポート予定 - より多くのMCPクライアントでの対応拡大 **🔗 関連リンク**: - [Original PR #11300](https://github.com/gradio-app/gradio/pull/11300) - [MCP Protocol](https://modelcontextprotocol.io/) - [MCP Community Discussion](https://github.com/orgs/modelcontextprotocol/discussions/16) - [Reference Space by abidlabs](https://huggingface.co/spaces/abidlabs/mcp-tool-http) - [Gradio MCP Documentation](https://gradio.app/docs/mcp) """) # アプリケーションの設定とデプロイ # Live Demo: https://huggingface.co/spaces/MakiAi/gradio-streamable-mcp-demo # MCP HTTP Endpoint: https://makiai-gradio-streamable-mcp-demo.hf.space/gradio_api/mcp/http/ # # 📋 IMPORTANT: Hugging Face Space デプロイ用 requirements.txt: # https://gradio-pypi-previews.s3.amazonaws.com/5bf3a9365e945803ba3b30ec470058c0d1aea03a/gradio-5.31.0-py3-none-any.whl # Pillow>=10.0.0 # numpy>=1.21.0 # # このプレビューバージョンには PR #11300 のStreamable HTTP Transport機能が含まれています if __name__ == "__main__": demo.launch( server_name="0.0.0.0", server_port=7860, share=False, show_error=True, mcp_server=True, # 🚀 Streamable HTTP Transport for MCP を有効化! inbrowser=False )