alihmaou commited on
Commit
6b920de
·
1 Parent(s): fca1ef2

Added the hackathon results exploration

Browse files
Files changed (4) hide show
  1. app.py +71 -11
  2. data/hackathon_mcp_tools.parquet +3 -0
  3. requirements.txt +3 -1
  4. src/bonus.py +71 -0
app.py CHANGED
@@ -3,19 +3,44 @@ import os
3
  from mcp import StdioServerParameters
4
  from smolagents import InferenceClientModel, CodeAgent, MCPClient
5
  import pandas as pd
 
6
 
7
  DEFAULT_MCP_URL = "https://alihmaou-mcp-tools.hf.space/gradio_api/mcp/sse"
8
  HF_TOKEN = os.getenv("HUGGINGFACE_API_TOKEN")
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  def reload_tools_from_url(mcp_url_input):
11
  global tools, agent, mcp_client, mcp_url
12
 
13
  mcp_url=mcp_url_input
14
- mcp_client = MCPClient({"url": mcp_url,"transport": "sse"}) # Might be deprecated soon but didnt find out the clean way
15
- tools = mcp_client.get_tools()
16
 
17
- model = InferenceClientModel(token=os.getenv("HUGGINGFACE_API_TOKEN"))
18
- agent = CodeAgent(tools=tools, model=model)
 
 
 
 
 
 
19
 
20
  # Tableau structuré : nom, description, inputs attendus
21
  rows = []
@@ -34,8 +59,9 @@ with gr.Blocks() as demo:
34
  <div align="center">
35
  <h1>🚀 MCP Tools Explorer – Agents-MCP-Hackathon (June 2025)</h1>
36
  <p>
37
- 🔍 Query any MCP-compatible endpoint, 🛠️ browse available tools in a clean table view, and 🤖 test real-time interactions using a `smolagent` powered by `HuggingFace`.
38
- Perfect for 🧪 exploring fellow participants’ tools or 🧰 debugging your own MCP server during the event!
 
39
  </p>
40
  </div>
41
  """,)
@@ -45,15 +71,49 @@ with gr.Blocks() as demo:
45
  with gr.Column(scale=1):
46
  gr.Markdown("""
47
  <div align="center">
48
- <h2>🛠️ Set an MCP server and discover the tools</h2>
49
  </div>
50
  """)
51
- mcp_url_input = gr.Textbox(label="🧩 MCP Tools server endpoint", value=DEFAULT_MCP_URL)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  tool_table = gr.DataFrame(headers=["Tool name", "Description", "Params"], interactive=False, label="🔧 MCP Tools availables", wrap=True)
53
  reload_btn = gr.Button("🔄 Refresh and set MCP tools list")
54
- reload_btn.click(fn=reload_tools_from_url, inputs=[mcp_url_input], outputs=tool_table)
55
- mcp_url_input.change(fn=reload_tools_from_url, inputs=[mcp_url_input], outputs=tool_table)
56
- mcp_url_input.submit(fn=reload_tools_from_url, inputs=[mcp_url_input], outputs=tool_table)
 
 
57
 
58
  with gr.Column(scale=2):
59
  gr.Markdown("""
 
3
  from mcp import StdioServerParameters
4
  from smolagents import InferenceClientModel, CodeAgent, MCPClient
5
  import pandas as pd
6
+ import requests
7
 
8
  DEFAULT_MCP_URL = "https://alihmaou-mcp-tools.hf.space/gradio_api/mcp/sse"
9
  HF_TOKEN = os.getenv("HUGGINGFACE_API_TOKEN")
10
 
11
+ def get_mcp_space_endpoints():
12
+ """Fetch MCP-compatible Spaces from the HF Hackathon org."""
13
+ try:
14
+ resp = requests.get("https://huggingface.co/api/spaces?author=Agents-MCP-Hackathon")
15
+ resp.raise_for_status()
16
+ spaces = resp.json()
17
+ except Exception as e:
18
+ print(f"[Warning] Failed to fetch MCP spaces: {e}")
19
+ return [DEFAULT_MCP_URL]
20
+
21
+ endpoints = [DEFAULT_MCP_URL]
22
+ for space in spaces:
23
+ if "mcp-server" in space.get("tags", []):
24
+ full_id = space["id"]
25
+ slug = full_id.replace("/", "-").replace("_", "-").lower()
26
+ endpoint = f"https://{slug}.hf.space/gradio_api/mcp/sse"
27
+ if endpoint != DEFAULT_MCP_URL:
28
+ endpoints.append(endpoint)
29
+ return endpoints
30
+
31
  def reload_tools_from_url(mcp_url_input):
32
  global tools, agent, mcp_client, mcp_url
33
 
34
  mcp_url=mcp_url_input
 
 
35
 
36
+ try:
37
+ mcp_client = MCPClient({"url": mcp_url,"transport": "sse"}) # Might be deprecated soon but didnt find out the clean way
38
+ tools = mcp_client.get_tools()
39
+
40
+ model = InferenceClientModel(token=os.getenv("HUGGINGFACE_API_TOKEN"))
41
+ agent = CodeAgent(tools=tools, model=model,)
42
+ except Exception as e:
43
+ print(f"[Warning] Failed to reach MCP server: {e}")
44
 
45
  # Tableau structuré : nom, description, inputs attendus
46
  rows = []
 
59
  <div align="center">
60
  <h1>🚀 MCP Tools Explorer – Agents-MCP-Hackathon (June 2025)</h1>
61
  <p>
62
+ 🔍 Query any MCP-compatible endpoint, 🛠️ browse available tools in a clean table view, and 🤖 test real-time interactions using a `smolagent` powered by `HuggingFace`. <br/>
63
+ Perfect for 🧪 exploring fellow participants’ tools or 🧰 debugging your own MCP server during the event! </br>
64
+ 🍒 As a cherry on the cake, the list of the tools developed for the hackathon will be updated here from time to time (see src/bonus.py) : <a href="https://huggingface.co/datasets/alihmaou/Agents_MCP_Hackathon_Tools_List/blob/main/hackathon_mcp_tools.parquet">Ready to use hackathon MCP tools list</a>
65
  </p>
66
  </div>
67
  """,)
 
71
  with gr.Column(scale=1):
72
  gr.Markdown("""
73
  <div align="center">
74
+ <h2>🛠️ Set an MCP server and discover its tools</h2>
75
  </div>
76
  """)
77
+ source_selector = gr.Radio(
78
+ choices=["Hackathon candidates", "Custom MCP URL"],
79
+ label="🔀 Source",
80
+ value="Hackathon candidates"
81
+ )
82
+
83
+ hackathon_dropdown = gr.Dropdown(
84
+ label="Select a MCP server from the hackathon organisation",
85
+ choices=get_mcp_space_endpoints(),
86
+ value=DEFAULT_MCP_URL,
87
+ interactive=True,
88
+ visible=True
89
+ )
90
+
91
+ custom_url_input = gr.Textbox(
92
+ label="Enter custom MCP server URL",
93
+ value="https://abidlabs-mcp-tool-http.hf.space/gradio_api/mcp/sse",
94
+ visible=False
95
+ )
96
+
97
+ def toggle_url_input(source):
98
+ return (
99
+ gr.update(visible=(source == "Hackathon candidates")),
100
+ gr.update(visible=(source == "Custom MCP URL"))
101
+ )
102
+
103
+ def reload_tools_router(source, dropdown_val, custom_val):
104
+ selected_url = dropdown_val if source == "Hackathon candidates" else custom_val
105
+ return reload_tools_from_url(selected_url)
106
+
107
+ source_selector.change(fn=toggle_url_input, inputs=source_selector, outputs=[hackathon_dropdown, custom_url_input])
108
+
109
+ #print("[MCP] Endpoints loaded:", get_mcp_space_endpoints())
110
  tool_table = gr.DataFrame(headers=["Tool name", "Description", "Params"], interactive=False, label="🔧 MCP Tools availables", wrap=True)
111
  reload_btn = gr.Button("🔄 Refresh and set MCP tools list")
112
+ reload_btn.click(
113
+ fn=reload_tools_router,
114
+ inputs=[source_selector, hackathon_dropdown, custom_url_input],
115
+ outputs=tool_table
116
+ )
117
 
118
  with gr.Column(scale=2):
119
  gr.Markdown("""
data/hackathon_mcp_tools.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:68e00574e01656199f29d490355f2adc9486ff07a97105ab0b44c823ba59e0d9
3
+ size 40653
requirements.txt CHANGED
@@ -3,4 +3,6 @@ gradio [mcp]
3
  mcp
4
  fastmcp
5
  python-dotenv
6
- pandas
 
 
 
3
  mcp
4
  fastmcp
5
  python-dotenv
6
+ pandas
7
+ pyarrow
8
+ fastparquet
src/bonus.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import pandas as pd
3
+ from smolagents import MCPClient
4
+
5
+
6
+
7
+ def extracthackathontools():
8
+ """Scrape all MCP tools from hackathon Spaces and return as a pandas DataFrame to allow download as a bonus feature of the MCP Explorer."""
9
+ HF_API = "https://huggingface.co/api/spaces?author=Agents-MCP-Hackathon"
10
+
11
+ try:
12
+ resp = requests.get(HF_API)
13
+ resp.raise_for_status()
14
+ except Exception as e:
15
+ raise RuntimeError(f"Failed to fetch Spaces list: {e}")
16
+
17
+ spaces = resp.json()
18
+ rows = []
19
+
20
+ for space in spaces:
21
+ tags = space.get("tags", [])
22
+ if "mcp-server" not in tags:
23
+ continue
24
+
25
+ space_id = space["id"]
26
+ space_slug = space_id.replace("/", "-").replace("_", "-").lower()
27
+ mcp_base_url = f"https://{space_slug}.hf.space/gradio_api/mcp/sse"
28
+
29
+
30
+ try:
31
+ print(mcp_base_url)
32
+ #mcp_status = requests.get(mcp_base_url, timeout=5)
33
+ #print(mcp_status.status_code)
34
+ #if mcp_status.status_code != 200:
35
+ # print(f"[Skip] Space in error: {mcp_base_url}")
36
+ # continue
37
+
38
+ mcp_client = MCPClient({"url": mcp_base_url,"transport": "sse"}) # Might be deprecated soon but didnt find out the clean way
39
+ tools = mcp_client.get_tools()
40
+ print(len(tools))
41
+ mcp_client.disconnect()
42
+ except Exception as e:
43
+ print(f"[Warning] Could not fetch tools from {mcp_base_url}: {e}")
44
+ continue
45
+
46
+ # Infos générales du Space
47
+ author, name = space_id.split("/")
48
+ hf_url = f"https://huggingface.co/spaces/{space_id}"
49
+ created_at = space.get("createdAt", "")
50
+ n_likes = space.get("likes", 0)
51
+
52
+ for tool in tools:
53
+ input_fields = ", ".join(param for param in tool.inputs)
54
+ rows.append({
55
+ "Gradio MCP endpoint": f"{mcp_base_url}",
56
+ "Tool name": tool.name,
57
+ "Tool description": tool.description,
58
+ "Tool inputs": input_fields,
59
+ "Space name": name,
60
+ "HF Space URL": hf_url,
61
+ "Likes": n_likes,
62
+ "Created at": created_at,
63
+ "Tags": ", ".join(tags)
64
+ })
65
+
66
+ df = pd.DataFrame(rows)
67
+ return df
68
+
69
+ df=extracthackathontools()
70
+
71
+ df.to_parquet("./data/hackathon_mcp_tools.parquet", index=False)