Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import os | |
| from mcp import StdioServerParameters | |
| from smolagents import InferenceClientModel, CodeAgent, MCPClient | |
| import pandas as pd | |
| import requests | |
| DEFAULT_MCP_URL = "https://agents-mcp-hackathon-mcp-drawittome.hf.space/gradio_api/mcp/sse" | |
| HF_TOKEN = os.getenv("HUGGINGFACE_API_TOKEN") | |
| def get_mcp_space_endpoints(): | |
| """Fetch MCP-compatible Spaces from the HF Hackathon org.""" | |
| try: | |
| resp = requests.get("https://huggingface.co/api/spaces?author=Agents-MCP-Hackathon") | |
| resp.raise_for_status() | |
| spaces = resp.json() | |
| except Exception as e: | |
| print(f"[Warning] Failed to fetch MCP spaces: {e}") | |
| return [DEFAULT_MCP_URL] | |
| endpoints = [DEFAULT_MCP_URL] | |
| for space in spaces: | |
| if "mcp-server" in space.get("tags", []): | |
| full_id = space["id"] | |
| slug = full_id.replace("/", "-").replace("_", "-").lower() | |
| endpoint = f"https://{slug}.hf.space/gradio_api/mcp/sse" | |
| if endpoint != DEFAULT_MCP_URL: | |
| endpoints.append(endpoint) | |
| return endpoints | |
| def reload_tools_from_url(mcp_url_input): | |
| global tools, agent, mcp_client, mcp_url | |
| mcp_url=mcp_url_input | |
| try: | |
| mcp_client = MCPClient({"url": mcp_url,"transport": "sse"}) # Might be deprecated soon but didnt find out the clean way | |
| tools = mcp_client.get_tools() | |
| model = InferenceClientModel(token=os.getenv("HUGGINGFACE_API_TOKEN")) | |
| agent = CodeAgent(tools=tools, model=model,) | |
| except Exception as e: | |
| print(f"[Warning] Failed to reach MCP server: {e}") | |
| # Tableau structuré : nom, description, inputs attendus | |
| rows = [] | |
| for tool in tools: | |
| input_fields = ", ".join(param for param in tool.inputs) | |
| rows.append({ | |
| "Tool name": tool.name, | |
| "Description": tool.description, | |
| "Params": input_fields | |
| }) | |
| df = pd.DataFrame(rows) | |
| return gr.DataFrame(value=df) | |
| with gr.Blocks() as demo: | |
| gr.HTML(""" | |
| <h1 style="text-align:center; font-size: 2em; margin-bottom: 0.5em;"> | |
| 🚀 MCP Explorer – Agents-MCP-Hackathon (June 2025) | |
| </h1> | |
| <p style="text-align:center; font-size: 1em; line-height: 1.5em; margin: 0 auto; max-width: 600px;"> | |
| 🔍 Query any MCP-compatible endpoint, 🛠️ browse available tools in a clean table view, and 🤖 test real-time interactions using a <code>smolagent</code> powered by <code>HuggingFace</code>.<br/> | |
| Perfect for 🧪 exploring fellow participants’ tools or 🧰 debugging your own MCP server during the event!<br/> | |
| 🍒 As a cherry on the cake, the list of the tools developed for the hackathon will be updated here from time to time (see <code>src/bonus.py</code>):<br/> | |
| <a href="https://huggingface.co/datasets/alihmaou/Agents_MCP_Hackathon_Tools_List" target="_blank" style="color: #4A90E2; text-decoration: underline;"> | |
| Ready to use hackathon MCP tools list | |
| </a> | |
| </p> | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.Markdown(""" | |
| <div align="center"> | |
| <h2>🛠️ Set an MCP server and discover its tools</h2> | |
| </div> | |
| """) | |
| source_selector = gr.Radio( | |
| choices=["Hackathon submissions", "Custom MCP URL"], | |
| label="🔀 Source", | |
| value="Hackathon submissions" | |
| ) | |
| hackathon_dropdown = gr.Dropdown( | |
| label="Select a MCP server from the Agent-MCP hackathon submissions", | |
| choices=get_mcp_space_endpoints(), | |
| value=DEFAULT_MCP_URL, | |
| interactive=True, | |
| visible=True | |
| ) | |
| custom_url_input = gr.Textbox( | |
| label="Enter custom MCP server URL", | |
| value="https://agents-mcp-hackathon-mcp-server-demo.hf.space/gradio_api/mcp/sse", | |
| visible=False | |
| ) | |
| def toggle_url_input(source): | |
| return ( | |
| gr.update(visible=(source == "Hackathon submissions")), | |
| gr.update(visible=(source == "Custom MCP URL")) | |
| ) | |
| def reload_tools_router(source, dropdown_val, custom_val): | |
| selected_url = dropdown_val if source == "Hackathon submissions" else custom_val | |
| return reload_tools_from_url(selected_url) | |
| source_selector.change(fn=toggle_url_input, inputs=source_selector, outputs=[hackathon_dropdown, custom_url_input]) | |
| #print("[MCP] Endpoints loaded:", get_mcp_space_endpoints()) | |
| tool_table = gr.DataFrame(headers=["Tool name", "Description", "Params"], interactive=False, label="🔧 MCP Tools availables", wrap=True) | |
| reload_btn = gr.Button("🔄 Refresh and set MCP tools list") | |
| reload_btn.click( | |
| fn=reload_tools_router, | |
| inputs=[source_selector, hackathon_dropdown, custom_url_input], | |
| outputs=tool_table | |
| ) | |
| hackathon_dropdown.change( | |
| fn=reload_tools_router, | |
| inputs=[source_selector, hackathon_dropdown, custom_url_input], | |
| outputs=tool_table | |
| ) | |
| custom_url_input.submit( | |
| fn=reload_tools_router, | |
| inputs=[source_selector, hackathon_dropdown, custom_url_input], | |
| outputs=tool_table | |
| ) | |
| with gr.Column(): | |
| gr.Markdown(""" | |
| <div align="center"> | |
| <h2>🔎 Test them with smolagents</h2> | |
| </div> | |
| """) | |
| chatbot = gr.ChatInterface( | |
| fn=lambda message, history: str(agent.run(message)), | |
| type="messages", | |
| ) | |
| demo.launch() | |
| try: | |
| if mcp_client: | |
| mcp_client.disconnect() | |
| except Exception as e: | |
| print(f"[Warning] Failed to disconnect MCP client: {e}") |