File size: 4,209 Bytes
9a9156e 2e8b534 9a9156e 3e4b08a bcfd645 3e4b08a 9a9156e 3e4b08a 9a9156e bcfd645 8eff04a bcfd645 8eff04a 2e8b534 9a9156e 2e8b534 9a9156e 2e8b534 9a9156e 2e8b534 9a9156e 2e8b534 9a9156e 132d45b 8eff04a 132d45b 9a9156e 132d45b 9a9156e 2e8b534 9a9156e 2e8b534 9a9156e 2e8b534 9a9156e 2e8b534 9a9156e 132d45b 8eff04a 9a9156e 132d45b 9a9156e 132d45b 9a9156e 2e8b534 9a9156e bcfd645 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# hf_spaces_mcp_server.py
from mcp.server.fastmcp import FastMCP
from gradio_client import Client
import os
import sys
import asyncio
import logging
import uvicorn # Correctly imported
# Configure basic logging to see server activity
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
logger = logging.getLogger(__name__)
# The port that Hugging Face Spaces expects our app to listen on.
# It injects this as an environment variable 'PORT'.
# Default to 7860 if PORT is not set (e.g., for local testing outside HF Spaces).
HOST_PORT = int(os.getenv("PORT", 7860))
HOST_ADDRESS = os.getenv("HOST", "0.0.0.0") # Bind to all interfaces
# Initialize FastMCP. The host/port settings passed here will be used by
# mcp.streamable_http_app() to configure its internal server if not mounted to FastAPI.
# However, when passed to uvicorn.run(), uvicorn's host/port will take precedence.
# It's good practice to keep them consistent or omit from here if uvicorn dictates.
# For simplicity, we'll keep them here as they are also part of MCP server's self-description.
mcp = FastMCP(
name="GradioSpacesTools",
host=HOST_ADDRESS,
port=HOST_PORT
)
clients = {}
def get_client(space_id: str) -> Client:
"""Get or create a Gradio client for the specified space."""
if space_id not in clients:
logger.info(f"Creating Gradio client for Space ID: {space_id}")
clients[space_id] = Client(space_id)
return clients[space_id]
@mcp.tool()
async def generate_image(prompt: str, space_id: str = "ysharma/SanaSprint") -> str:
"""Generate an image using Flux.
Args:
prompt (str): Text prompt describing the image to generate
space_id (str): HuggingFace Space ID to use
Returns:
str: The URL of the generated image.
"""
logger.info(f"Generating image for prompt: '{prompt}' using Space: '{space_id}'")
client = get_client(space_id)
try:
result = await client.predict(
prompt=prompt,
model_size="1.6B",
seed=0,
randomize_seed=True,
width=1024,
height=1024,
guidance_scale=4.5,
num_inference_steps=2,
api_name="/infer"
)
logger.info(f"Image generation successful. Result: {result}")
return result
except Exception as e:
logger.error(f"Error generating image: {e}")
return f"Error generating image: {e}"
@mcp.tool()
async def run_dia_tts(prompt: str, space_id: str = "ysharma/Dia-1.6B") -> str:
"""Text-to-Speech Synthesis.
Args:
prompt (str): Text prompt describing the conversation between speakers S1, S2
space_id (str): HuggingFace Space ID to use
Returns:
str: The URL of the generated audio.
"""
logger.info(f"Performing TTS for prompt: '{prompt}' using Space: '{space_id}'")
client = get_client(space_id)
try:
result = await client.predict(
text_input=f"""{prompt}""",
audio_prompt_input=None,
max_new_tokens=3072,
cfg_scale=3,
temperature=1.3,
top_p=0.95,
cfg_filter_top_k=30,
speed_factor=0.94,
api_name="/generate_audio"
)
logger.info(f"TTS successful. Result: {result}")
return result
except Exception as e:
logger.error(f"Error performing TTS: {e}")
return f"Error performing TTS: {e}"
if __name__ == "__main__":
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1)
logger.info(f"Starting GradioSpacesTools MCP server via Uvicorn on http://{HOST_ADDRESS}:{HOST_PORT}")
# The correct way to get the FastMCP ASGI application for streamable-http
# as indicated by the article and FastMCP's internal structure.
# Uvicorn will then run this ASGI application.
uvicorn.run(
mcp.streamable_http_app(), # <-- Use this method! It returns the ASGI app.
host=HOST_ADDRESS,
port=HOST_PORT,
log_level="info", # Set logging level for Uvicorn itself
loop="asyncio" # Ensure Uvicorn uses the asyncio event loop
)
logger.info("GradioSpacesTools MCP server stopped.") |