Spaces:
Runtime error
Runtime error
# Connecting to Your MCP Server on Hugging Face Spaces | |
This guide explains how to connect to your Gradio MCP server deployed on Hugging Face Spaces, based on real-world testing and troubleshooting. | |
**β οΈ Important:** This guide reflects actual testing results and working solutions, not just theoretical approaches. | |
--- | |
## 1. Find Your MCP Endpoint | |
After deploying your Gradio app to Hugging Face Spaces, your MCP endpoint will be: | |
``` | |
https://YOUR_USERNAME-YOUR_SPACE_NAME.hf.space/gradio_api/mcp/sse | |
``` | |
**Example:** | |
If your username is `freemansel` and your space is `mcp-sentiment`, your endpoint is: | |
``` | |
https://freemansel-mcp-sentiment.hf.space/gradio_api/mcp/sse | |
``` | |
**Testing the endpoint:** You can verify the SSE stream is working by visiting the URL in a browser - you should see periodic ping messages every 15 seconds. | |
--- | |
## 2. β Working Solutions (Tested & Verified) | |
### A. smolagents MCPClient β **RECOMMENDED** | |
**Performance:** ~0.11 seconds per request (fastest!) | |
**Status:** β Works perfectly | |
**Protocol:** Native MCP via smolagents | |
Based on the [Hugging Face MCP Course](https://huggingface.co/learn/mcp-course/unit2/gradio-client), this is the proper way to use MCP. | |
#### Installation | |
```bash | |
pdm add "smolagents[mcp]" | |
# or | |
pip install "smolagents[mcp]" | |
``` | |
#### Python Code | |
```python | |
#!/usr/bin/env python3 | |
""" | |
Working MCP client using smolagents. | |
Performance: ~0.11 seconds per request | |
""" | |
import time | |
from smolagents.mcp_client import MCPClient | |
def analyze_sentiment_mcp(text): | |
"""Analyze sentiment using MCP protocol.""" | |
mcp_client = None | |
try: | |
mcp_client = MCPClient( | |
{"url": "https://freemansel-mcp-sentiment.hf.space/gradio_api/mcp/sse"} | |
) | |
tools = mcp_client.get_tools() | |
sentiment_tool = tools[0] # The sentiment analysis tool | |
result = sentiment_tool(text=text) | |
return result | |
finally: | |
if mcp_client: | |
mcp_client.disconnect() | |
# Example usage | |
result = analyze_sentiment_mcp("I love this product!") | |
print(f"Polarity: {result['polarity']}") | |
print(f"Assessment: {result['assessment']}") | |
# Output: Polarity: 0.69, Assessment: positive | |
``` | |
**Why this works:** smolagents handles all the MCP protocol complexity automatically, including the SSE connection and handshake. | |
--- | |
### B. Gradio Client π **BACKUP SOLUTION** | |
**Performance:** ~1.3 seconds per request | |
**Status:** β Very reliable backup | |
**Protocol:** Direct Gradio API access | |
This bypasses MCP entirely and connects directly to the Gradio API. | |
#### Installation | |
```bash | |
pdm add gradio_client | |
# or | |
pip install gradio_client | |
``` | |
#### Python Code | |
```python | |
#!/usr/bin/env python3 | |
""" | |
Backup solution using Gradio client. | |
Performance: ~1.3 seconds per request | |
""" | |
import time | |
from gradio_client import Client | |
def analyze_sentiment_gradio(text): | |
"""Analyze sentiment using Gradio client.""" | |
client = Client("https://freemansel-mcp-sentiment.hf.space") | |
result = client.predict(text, api_name="/predict") | |
return result | |
# Example usage | |
result = analyze_sentiment_gradio("I love this product!") | |
print(f"Polarity: {result['polarity']}") | |
print(f"Assessment: {result['assessment']}") | |
# Output: Polarity: 0.69, Assessment: positive | |
``` | |
**Why this works:** Direct API access to Gradio's built-in endpoints, no MCP protocol involved. | |
--- | |
## 3. β Known Issues & Failed Approaches | |
### A. Low-Level MCP Clients (Don't Use) | |
**β Problem:** The following approach causes `session.initialize()` to hang indefinitely: | |
```python | |
# β THIS HANGS - DON'T USE | |
import asyncio | |
from mcp import ClientSession, StdioServerParameters | |
from mcp.client.stdio import stdio_client | |
async def broken_mcp_approach(): | |
server_params = StdioServerParameters( | |
command="npx", | |
args=["mcp-remote", "https://freemansel-mcp-sentiment.hf.space/gradio_api/mcp/sse"] | |
) | |
async with stdio_client(server_params) as (read, write): | |
async with ClientSession(read, write) as session: | |
# β This line hangs forever (tested timeout: 45+ seconds) | |
await session.initialize() | |
``` | |
**Root Cause:** | |
- The low-level MCP client requires manual protocol handling | |
- `session.initialize()` times out during MCP handshake | |
- Even though `mcp-remote` connects successfully, the protocol negotiation fails | |
**Evidence:** | |
- STDIO client connects instantly (0.0s) | |
- Session creation works fine | |
- Failure occurs specifically in `session.initialize()` | |
- Error: "unhandled errors in a TaskGroup (1 sub-exception)" | |
--- | |
### B. Direct HTTP Requests (Don't Work) | |
**β Problem:** MCP endpoints don't accept standard HTTP POST requests: | |
```python | |
# β THIS FAILS - DON'T USE | |
import requests | |
url = "https://freemansel-mcp-sentiment.hf.space/gradio_api/call/sentiment_analysis" | |
payload = {"data": ["I love this product!"]} | |
response = requests.post(url, json=payload) | |
# Result: 500 Internal Server Error or 405 Method Not Allowed | |
``` | |
**Why it fails:** | |
- MCP servers use Server-Sent Events (SSE) protocol | |
- Standard REST API endpoints are not exposed when `mcp_server=True` | |
- The `/gradio_api/mcp/sse` endpoint only accepts SSE connections | |
--- | |
### C. mcp-remote with Manual Clients (Problematic) | |
**β οΈ Partial Success:** `mcp-remote` proxy connects but has protocol issues: | |
```bash | |
# This establishes SSE connection but MCP protocol still fails | |
npx mcp-remote https://freemansel-mcp-sentiment.hf.space/gradio_api/mcp/sse | |
``` | |
**What happens:** | |
1. β HTTP attempt fails (405 Method Not Allowed) - expected | |
2. β SSE fallback succeeds - connection established | |
3. β MCP protocol handshake fails - timeout in client | |
**Evidence from testing:** | |
``` | |
[8216] Using transport strategy: http-first | |
[8216] Received error: Error POSTing to endpoint (HTTP 405): Method Not Allowed | |
[8216] Recursively reconnecting for reason: falling-back-to-alternate-transport | |
[8216] Using transport strategy: sse-only | |
[8216] Connected to remote server using SSEClientTransport | |
[8216] Local STDIO server running | |
[8216] Proxy established successfully | |
``` | |
--- | |
## 4. Performance Comparison | |
| Method | Speed | Reliability | Protocol | Status | | |
|--------|-------|-------------|----------|---------| | |
| **smolagents MCP** | **0.11s** | β Excellent | Native MCP | β Best | | |
| **Gradio Client** | 1.3s | β Very Good | Direct API | β Backup | | |
| Low-level MCP | β Timeout | β Broken | Manual MCP | β Don't use | | |
| HTTP Requests | β 405 Error | β Broken | REST | β Don't use | | |
--- | |
## 5. Real-World Troubleshooting | |
### A. Import Debugging | |
If you have import issues, create this debugging script: | |
```python | |
#!/usr/bin/env python3 | |
"""Debug MCP imports""" | |
def check_imports(): | |
try: | |
import smolagents.mcp_client | |
print("β smolagents available - use smolagents approach") | |
return True | |
except ImportError: | |
print("β Install: pip install 'smolagents[mcp]'") | |
try: | |
import gradio_client | |
print("β gradio_client available - use backup approach") | |
return True | |
except ImportError: | |
print("β Install: pip install gradio_client") | |
return False | |
check_imports() | |
``` | |
### B. Connection Testing | |
Test the SSE endpoint directly in your browser: | |
``` | |
https://freemansel-mcp-sentiment.hf.space/gradio_api/mcp/sse | |
``` | |
You should see: | |
``` | |
: ping - 2025-05-23 18:36:12.808434+00:00 | |
: ping - 2025-05-23 18:36:27.809481+00:00 | |
``` | |
If you don't see pings, the Hugging Face Space might be sleeping. | |
### C. Common Error Messages | |
**"unhandled errors in a TaskGroup"** β Use smolagents instead of low-level MCP | |
**"HTTP 405 Method Not Allowed"** β Use Gradio client instead of HTTP requests | |
**"Connection timeout"** β Check if HF Space is running, try Gradio client | |
**"Import error: smolagents"** β Install with `pip install "smolagents[mcp]"` | |
--- | |
## 6. Ready-to-Use Scripts | |
Complete, tested scripts are available in the `usage/` folder: | |
```bash | |
# Primary solution (fastest) | |
pdm run python usage/sentiment_mcp.py | |
# Backup solution (reliable) | |
pdm run python usage/sentiment_gradio.py | |
# Debug imports if needed | |
pdm run python usage/debug_imports.py | |
``` | |
--- | |
## 7. Cursor AI Integration | |
For Cursor AI, use the working smolagents approach: | |
```json | |
{ | |
"mcpServers": { | |
"sentiment-analysis": { | |
"command": "python", | |
"args": [ | |
"-c", | |
"from smolagents.mcp_client import MCPClient; client = MCPClient({'url': 'https://freemansel-mcp-sentiment.hf.space/gradio_api/mcp/sse'}); tools = client.get_tools(); result = tools[0](text=input('Text: ')); print(f'Sentiment: {result}')" | |
] | |
} | |
} | |
} | |
``` | |
**Note:** This is a simplified example. For production use, create a proper MCP server script. | |
--- | |
## 8. Key Learnings from Real Testing | |
1. **Always use high-level clients** - `smolagents.MCPClient` works, low-level `mcp.ClientSession` doesn't | |
2. **Follow official documentation** - The [Hugging Face MCP Course](https://huggingface.co/learn/mcp-course/unit2/gradio-client) shows the right approach | |
3. **Have a backup plan** - Gradio client provides reliable fallback when MCP has issues | |
4. **Test everything** - Theoretical solutions often don't work in practice | |
5. **Performance varies dramatically** - smolagents (0.11s) vs Gradio (1.3s) vs broken approaches (timeout) | |
--- | |
## 9. References | |
- [Hugging Face MCP Course](https://huggingface.co/learn/mcp-course/unit2/gradio-client) - **Use this approach** | |
- [smolagents Documentation](https://huggingface.co/docs/smolagents) - High-level MCP client | |
- [Gradio Client Documentation](https://gradio.app/guides/getting-started-with-the-python-client/) - Backup approach | |
- [MCP Protocol Documentation](https://modelcontextprotocol.io/) - Low-level details | |
--- | |
**β This guide is based on extensive real-world testing and provides only verified, working solutions!** |