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", theme=gr.themes.Soft(), css=""" .tab-nav button { font-size: 16px !important; } """ ) as demo: gr.Markdown(""" # 🚀 Gradio Streamable HTTP MCP デモアプリ このアプリは、Gradio の新しい **Streamable HTTP Transport for MCP server** 機能のデモです。 ## 🔗 MCP エンドポイント アプリ起動後、以下のエンドポイントでMCPツールにアクセスできます: - **HTTP Transport**: `{APP_URL}/gradio_api/mcp/http/` - **SSE Transport**: `{APP_URL}/gradio_api/mcp/sse` ## 🛠️ 利用可能なツール """) 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 クライアントでの使用方法 1. **MCP Inspector** でテスト: ``` https://your-app-url/gradio_api/mcp/http/ ``` 2. **Claude Desktop** での設定例: ```json { "mcpServers": { "gradio-demo": { "command": "curl", "args": ["-X", "POST", "https://your-app-url/gradio_api/mcp/http/"] } } } ``` 3. **利用可能なツール**: - `calculator`: 数学計算 - `image_processor`: 画像処理 - `text_analyzer`: テキスト分析 ## 🔧 技術詳細 - **Transport**: Streamable HTTP - **Protocol**: MCP (Model Context Protocol) - **Endpoints**: `/gradio_api/mcp/http/` (HTTP), `/gradio_api/mcp/sse` (SSE) - **Features**: ファイル入出力、状態管理、リアルタイム処理 """) # アプリケーションの設定 if __name__ == "__main__": demo.launch( server_name="0.0.0.0", server_port=7860, share=False, show_error=True, mcp_server=True, # MCP server を有効化 inbrowser=False )