Spaces:
Sleeping
Sleeping
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 | |
) |