GFiaMon commited on
Commit
c23f78d
Β·
1 Parent(s): b0547d6

fix readme

Browse files
Files changed (2) hide show
  1. README.md +78 -32
  2. STEP_BY_STEP_GUIDE.md +93 -273
README.md CHANGED
@@ -10,63 +10,109 @@ pinned: false
10
  short_description: A minimal Gradio MCP server that provides timezone-aware dat
11
  ---
12
 
13
- # Berlin Time MCP Server
14
 
15
- A simple MCP (Model Context Protocol) server built with Gradio that provides current Berlin time to AI agents.
16
 
17
- ## What is this?
18
 
19
- This is a demonstration MCP server that exposes a single tool: `get_berlin_time`. AI agents can connect to this server and call this tool when they need to know the current time in Berlin, Germany.
 
 
 
 
20
 
21
- ## Local Testing
 
 
 
 
 
 
 
 
22
 
23
  1. Install dependencies:
24
  ```bash
25
  pip install -r requirements.txt
26
  ```
27
 
28
- 2. Run the server:
 
 
29
  ```bash
30
  python app_time_mcp_server.py
 
 
 
 
 
 
 
31
  ```
32
 
33
- 3. Open your browser to `http://localhost:7860` to test the tool manually.
 
 
34
 
35
- ## Deploying to HuggingFace Spaces
36
 
37
  1. Create a new Space at [huggingface.co/spaces](https://huggingface.co/spaces)
38
- 2. Choose "Gradio" as the SDK
39
- 3. Upload these files:
40
- - `app_time_mcp_server.py` (rename to `app.py` for HF Spaces)
41
- - `requirements.txt`
42
- 4. Your Space will automatically deploy!
43
 
44
- ## Using with AI Agents
45
 
46
- Once deployed, AI agents can connect to this MCP server and use the `get_berlin_time` tool.
 
47
 
48
- ### Example with LangGraph
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
- See the main guide for detailed integration instructions.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
- ## Tool Details
53
 
54
- **Function:** `get_berlin_time()`
55
 
56
- **Returns:**
57
- ```json
58
- {
59
- "time": "2025-12-04 17:00:57 CET",
60
- "timezone": "Europe/Berlin",
61
- "timestamp": "2025-12-04T17:00:57+01:00",
62
- "utc_offset": "+0100",
63
- "day_of_week": "Wednesday",
64
- "is_dst": false
65
  }
66
  ```
67
 
68
- ## Future Improvements
 
 
69
 
70
- - Add support for multiple timezones
71
- - Add time conversion tools
72
- - Add timezone difference calculator
 
10
  short_description: A minimal Gradio MCP server that provides timezone-aware dat
11
  ---
12
 
13
+ # Berlin Time & World Time MCP Servers
14
 
15
+ This directory contains two example MCP (Model Context Protocol) servers built with Gradio.
16
 
17
+ ## πŸ“‚ Available Servers
18
 
19
+ ### 1. Simple Berlin Time (`app_time_mcp_server.py`)
20
+ - **Function:** Returns current time in Berlin.
21
+ - **Complexity:** Simple, no parameters.
22
+ - **Port:** 7860
23
+ - **Best for:** Learning the basics of MCP.
24
 
25
+ ### 2. World Time (`app_world_time_mcp_server.py`)
26
+ - **Function:** Returns current time for 25+ major cities.
27
+ - **Complexity:** Takes a `city` parameter (e.g., "Tokyo", "New York").
28
+ - **Port:** 7860 (when deployed) / 7861 (local dev).
29
+ - **Best for:** Demonstrating tool arguments and dynamic responses.
30
+
31
+ ---
32
+
33
+ ## πŸš€ Local Testing
34
 
35
  1. Install dependencies:
36
  ```bash
37
  pip install -r requirements.txt
38
  ```
39
 
40
+ 2. Run the server of your choice:
41
+
42
+ **Option A: Berlin Time**
43
  ```bash
44
  python app_time_mcp_server.py
45
+ # Runs on http://localhost:7860
46
+ ```
47
+
48
+ **Option B: World Time**
49
+ ```bash
50
+ python app_world_time_mcp_server.py
51
+ # Runs on http://localhost:7861 (to avoid conflict)
52
  ```
53
 
54
+ 3. Open the URL in your browser to test the UI manually.
55
+
56
+ ---
57
 
58
+ ## ☁️ Deploying to HuggingFace Spaces
59
 
60
  1. Create a new Space at [huggingface.co/spaces](https://huggingface.co/spaces)
61
+ 2. Choose **Gradio** as the SDK.
62
+ 3. Upload your files.
 
 
 
63
 
64
+ ### ⚠️ IMPORTANT: Deployment Checklist
65
 
66
+ #### 1. Configure the Entry File (The "Pro" Way)
67
+ Instead of renaming your file to `app.py`, you can tell HuggingFace which file to run by editing the **YAML Header** at the very top of your `README.md` in the Space.
68
 
69
+ **For Berlin Time:**
70
+ ```yaml
71
+ ---
72
+ title: Berlin Time MCP
73
+ emoji: πŸ•
74
+ colorFrom: blue
75
+ colorTo: indigo
76
+ sdk: gradio
77
+ sdk_version: 5.0.0
78
+ app_file: app_time_mcp_server.py <-- CHANGE THIS
79
+ pinned: false
80
+ ---
81
+ ```
82
 
83
+ **For World Time:**
84
+ ```yaml
85
+ ---
86
+ title: World Time MCP
87
+ emoji: 🌍
88
+ colorFrom: green
89
+ colorTo: blue
90
+ sdk: gradio
91
+ sdk_version: 5.0.0
92
+ app_file: app_world_time_mcp_server.py <-- CHANGE THIS
93
+ pinned: false
94
+ ---
95
+ ```
96
+
97
+ #### 2. Check the Port
98
+ HuggingFace Spaces **REQUIRES** the app to run on port **7860**.
99
+ - If you use `app_world_time_mcp_server.py`, **change `server_port=7861` to `server_port=7860`** in the code before deploying.
100
+ - If you don't do this, you will get an `OSError: Cannot find empty port`.
101
 
102
+ ### Configuration for Your Agent
103
 
104
+ Once deployed, update your `src/config/settings.py`:
105
 
106
+ ```python
107
+ servers["berlin_time"] = {
108
+ "url": "https://huggingface.co/spaces/YOUR_USERNAME/YOUR_SPACE_NAME/gradio_api/mcp/",
109
+ "transport": "sse"
 
 
 
 
 
110
  }
111
  ```
112
 
113
+ ---
114
+
115
+ ## πŸ“š Documentation
116
 
117
+ - [Step-by-Step Guide](STEP_BY_STEP_GUIDE.md): Detailed teaching guide.
118
+ - [MCP Connection Flow](../.gemini/antigravity/brain/26cb67ea-9995-44cc-8251-52a912873dc8/mcp_connection_flow.md): Visual diagram of how it works.
 
STEP_BY_STEP_GUIDE.md CHANGED
@@ -1,339 +1,159 @@
1
- # Step-by-Step Guide: Berlin Time MCP Server
2
 
3
  ## βœ… What We've Built
4
 
5
- You now have a complete, working MCP server in `external_mcp_servers/` with:
6
- - `app_time_mcp_server.py` - The main server application
7
- - `requirements.txt` - Dependencies (gradio, pytz)
8
- - `README.md` - Documentation
9
- - `.gitignore` - Git configuration
10
 
11
- ## 🎯 Current Status
 
 
 
12
 
13
- **Server is running at:** http://localhost:7860
14
-
15
- The server is now:
16
- 1. βœ… Providing a web UI for manual testing
17
- 2. βœ… Exposing an MCP endpoint at: `http://localhost:7860/gradio_api/mcp/`
18
- 3. βœ… Ready to be called by AI agents
19
 
20
  ---
21
 
22
- ## πŸ“š Understanding Each Component
23
 
24
- ### 1. The Core Function: `get_berlin_time()`
25
 
 
26
  ```python
27
  def get_berlin_time():
28
- berlin_tz = pytz.timezone('Europe/Berlin')
29
- current_time = datetime.now(berlin_tz)
30
- # ... returns structured data
31
  ```
32
 
33
- **What it does:**
34
- - Creates a timezone object for Berlin
35
- - Gets the current time in that timezone
36
- - Returns a dictionary with multiple time formats
37
-
38
- **Why return a dictionary?**
39
- - AI agents can choose which format they need
40
- - Includes both human-readable and machine-readable formats
41
- - Provides extra context (day of week, DST status)
42
 
43
  ### 2. The Gradio Interface
44
 
45
  ```python
46
  demo = gr.Interface(
47
- fn=get_berlin_time,
48
- inputs=None,
49
- outputs=gr.JSON(label="Berlin Time Information"),
50
- ...
51
  )
52
  ```
53
 
54
- **What this does:**
55
- - `fn=get_berlin_time` - The function to expose
56
- - `inputs=None` - No parameters needed (simple tool)
57
- - `outputs=gr.JSON()` - Returns JSON data
58
- - Creates both a UI and an API endpoint
59
-
60
- ### 3. The MCP Magic: `mcp_server=True`
61
 
62
  ```python
63
  demo.launch(mcp_server=True)
64
  ```
65
-
66
- **This single parameter:**
67
- - Starts the normal Gradio UI (for testing)
68
- - **ALSO** starts an MCP protocol server
69
- - Automatically creates MCP tool definitions
70
- - Handles all MCP communication
71
-
72
- **What happens behind the scenes:**
73
- 1. Gradio analyzes your function signature
74
- 2. Creates an MCP tool definition with:
75
- - Tool name: `get_berlin_time`
76
- - Input schema: (none in this case)
77
- - Output schema: (JSON object)
78
- 3. Exposes an MCP endpoint that AI agents can connect to
79
-
80
- ---
81
-
82
- ## πŸ§ͺ Testing Locally
83
-
84
- ### Method 1: Web UI (Manual Testing)
85
-
86
- 1. **Server is already running** at http://localhost:7860
87
- 2. Open your browser to that URL
88
- 3. Click the "Submit" button
89
- 4. You'll see JSON output like:
90
- ```json
91
- {
92
- "time": "2025-12-04 17:00:57 CET",
93
- "timezone": "Europe/Berlin",
94
- "timestamp": "2025-12-04T17:00:57+01:00",
95
- "utc_offset": "+0100",
96
- "day_of_week": "Wednesday",
97
- "is_dst": false
98
- }
99
- ```
100
-
101
- ### Method 2: MCP Protocol (AI Agent Testing)
102
-
103
- The MCP endpoint is at: `http://localhost:7860/gradio_api/mcp/`
104
-
105
- AI agents can connect to this endpoint and:
106
- 1. Discover available tools
107
- 2. Call `get_berlin_time`
108
- 3. Receive the structured response
109
 
110
  ---
111
 
112
- ## πŸš€ Deploying to HuggingFace Spaces
113
 
114
- ### Step 1: Prepare Files
115
 
116
- When deploying to HF Spaces, you need to rename `app_time_mcp_server.py` to `app.py`:
117
 
118
- ```bash
119
- # In the external_mcp_servers directory
120
- cp app_time_mcp_server.py app.py
121
- ```
122
-
123
- ### Step 2: Create a HuggingFace Space
124
-
125
- 1. Go to https://huggingface.co/spaces
126
- 2. Click "Create new Space"
127
- 3. Fill in:
128
- - **Name:** `berlin-time-mcp` (or your choice)
129
- - **License:** Choose one (e.g., MIT)
130
- - **SDK:** Select **Gradio**
131
- - **Visibility:** Public or Private
132
-
133
- ### Step 3: Upload Files
134
 
135
- You have two options:
 
 
 
136
 
137
- **Option A: Git Push (Recommended)**
138
- ```bash
139
- cd external_mcp_servers
140
- git init
141
- git add app.py requirements.txt README.md
142
- git commit -m "Initial MCP server"
143
- git remote add hf https://huggingface.co/spaces/YOUR_USERNAME/berlin-time-mcp
144
- git push hf main
145
  ```
146
 
147
- **Option B: Web Upload**
148
- 1. In your Space, click "Files" tab
149
- 2. Upload:
150
- - `app.py` (renamed from app_time_mcp_server.py)
151
- - `requirements.txt`
152
- - `README.md` (optional)
153
-
154
- ### Step 4: Automatic Deployment
155
-
156
- HuggingFace will:
157
- 1. Detect it's a Gradio app (from `requirements.txt`)
158
- 2. Install dependencies
159
- 3. Run `app.py`
160
- 4. Provide a public URL: `https://huggingface.co/spaces/YOUR_USERNAME/berlin-time-mcp`
161
-
162
- ### Step 5: Verify Deployment
163
-
164
- Once deployed, you'll see:
165
- - The Gradio UI at the Space URL
166
- - MCP endpoint at: `https://huggingface.co/spaces/YOUR_USERNAME/berlin-time-mcp/gradio_api/mcp/`
167
-
168
- ---
169
-
170
- ## πŸ”— Integrating with Your LangGraph Agent
171
-
172
- ### Prerequisites
173
-
174
- ```bash
175
- pip install mcp langchain-mcp
176
  ```
177
 
178
- ### Step 1: Create MCP Client Connection
179
 
180
- Create a new file in your project: `src/tools/mcp_tools.py`
181
 
182
- ```python
183
- from mcp import ClientSession, StdioServerParameters
184
- from mcp.client.stdio import stdio_client
185
- from langchain.tools import Tool
186
- import asyncio
187
 
188
- async def connect_to_berlin_time_mcp():
189
- """Connect to the Berlin Time MCP server"""
190
-
191
- # For local testing
192
- server_params = StdioServerParameters(
193
- command="python",
194
- args=["external_mcp_servers/app_time_mcp_server.py"]
195
- )
196
-
197
- # Or for deployed version:
198
- # server_params = HttpServerParameters(
199
- # url="https://huggingface.co/spaces/YOUR_USERNAME/berlin-time-mcp/gradio_api/mcp/"
200
- # )
201
-
202
- async with stdio_client(server_params) as (read, write):
203
- async with ClientSession(read, write) as session:
204
- await session.initialize()
205
- tools = await session.list_tools()
206
- return session, tools
207
-
208
- def create_berlin_time_tool():
209
- """Create a LangChain tool from the MCP server"""
210
-
211
- async def get_time():
212
- session, _ = await connect_to_berlin_time_mcp()
213
- result = await session.call_tool("get_berlin_time", {})
214
- return result
215
-
216
- return Tool(
217
- name="get_berlin_time",
218
- func=lambda: asyncio.run(get_time()),
219
- description="Get the current date and time in Berlin, Germany. "
220
- "Returns time in multiple formats including ISO 8601."
221
- )
222
- ```
223
 
224
- ### Step 2: Add to Your Agent
 
225
 
226
- In your main agent file (e.g., `app_v4.py`):
227
 
228
  ```python
229
- from src.tools.mcp_tools import create_berlin_time_tool
230
-
231
- # Add to your existing tools
232
- berlin_time_tool = create_berlin_time_tool()
233
 
234
- # Include in your agent's tool list
235
- tools = [
236
- # ... your existing tools ...
237
- berlin_time_tool
238
- ]
239
  ```
240
 
241
- ### Step 3: Test the Integration
242
 
243
- Ask your agent:
244
- - "What time is it in Berlin?"
245
- - "What's the current date and time in Berlin?"
246
- - "Is it daytime in Berlin right now?"
247
 
248
- The agent will:
249
- 1. Recognize it needs Berlin time
250
- 2. Call the MCP tool
251
- 3. Receive the structured response
252
- 4. Format it nicely for the user
253
 
254
  ---
255
 
256
- ## πŸŽ“ Teaching This to Colleagues
257
-
258
- ### Key Points to Emphasize:
259
 
260
- 1. **MCP is a Protocol, Not a Library**
261
- - It's a standard way for AI to talk to tools
262
- - Like HTTP for web, MCP for AI tools
263
 
264
- 2. **Gradio Makes It Easy**
265
- - One parameter: `mcp_server=True`
266
- - Handles all the protocol complexity
267
- - Provides both UI and API
268
 
269
- 3. **Deployment is Simple**
270
- - Works locally for development
271
- - Deploy to HF Spaces for production
272
- - No server management needed
273
-
274
- 4. **Reusable Across AI Systems**
275
- - Write once, use in any MCP-compatible AI
276
- - Not locked to one framework
277
- - Easy to share and discover
 
278
 
279
- ### Demo Flow for Colleagues:
280
 
281
- 1. **Show the code** - Point out how simple it is
282
- 2. **Run locally** - Demonstrate the UI
283
- 3. **Explain MCP endpoint** - Show the protocol URL
284
- 4. **Deploy to HF** - Show the public version
285
- 5. **Integrate with AI** - Demonstrate agent using it
 
286
 
287
  ---
288
 
289
- ## πŸ”„ Next Steps & Improvements
290
-
291
- ### Immediate Next Steps:
292
- 1. βœ… Test the local server (currently running)
293
- 2. ⏭️ Deploy to HuggingFace Spaces
294
- 3. ⏭️ Integrate with your LangGraph agent
295
- 4. ⏭️ Test end-to-end with your agent
296
 
297
- ### Future Enhancements:
298
 
299
- **1. Multiple Timezones**
300
- ```python
301
- def get_time_for_timezone(timezone_name: str = "Europe/Berlin"):
302
- # Allow AI to specify any timezone
303
- ```
304
 
305
- **2. Time Conversions**
306
- ```python
307
- def convert_time(time_str: str, from_tz: str, to_tz: str):
308
- # Convert between timezones
309
- ```
310
 
311
- **3. Business Hours Check**
312
- ```python
313
- def is_business_hours(timezone: str = "Europe/Berlin"):
314
- # Check if it's business hours (9-5)
315
- ```
316
-
317
- **4. Multiple Tools in One Server**
318
- ```python
319
- # Create multiple gr.Interface instances
320
- # Combine them with gr.TabbedInterface
321
- ```
322
-
323
- ---
324
 
325
- ## πŸ“ Summary
326
-
327
- You now have:
328
- - βœ… A working MCP server with Berlin time tool
329
- - βœ… Complete understanding of how MCP works
330
- - βœ… Local testing capability
331
- - βœ… Deployment instructions for HF Spaces
332
- - βœ… Integration guide for LangGraph
333
- - βœ… Teaching materials for colleagues
334
-
335
- **The beauty of this approach:**
336
- - Simple Python function β†’ Gradio interface β†’ MCP server
337
- - One line (`mcp_server=True`) enables AI integration
338
- - Deploy anywhere Gradio runs
339
- - Use with any MCP-compatible AI system
 
1
+ # Step-by-Step Guide: Building & Deploying MCP Servers
2
 
3
  ## βœ… What We've Built
4
 
5
+ You now have **two** working MCP server examples in `external_mcp_servers/`:
 
 
 
 
6
 
7
+ 1. **`app_time_mcp_server.py`** (Original)
8
+ - Simple, parameter-less tool.
9
+ - Returns Berlin time only.
10
+ - Great for first-time understanding.
11
 
12
+ 2. **`app_world_time_mcp_server.py`** (Upgraded)
13
+ - Accepts a `city` parameter.
14
+ - Returns time for 25+ cities.
15
+ - Demonstrates how LLMs pass arguments to tools.
 
 
16
 
17
  ---
18
 
19
+ ## πŸ“š Understanding the Components
20
 
21
+ ### 1. The Core Function
22
 
23
+ **Simple (Berlin):**
24
  ```python
25
  def get_berlin_time():
26
+ # No arguments needed
27
+ return {"time": "..."}
 
28
  ```
29
 
30
+ **Advanced (World):**
31
+ ```python
32
+ def get_time_for_city(city: str = "Berlin"):
33
+ # Takes an argument!
34
+ # LLM will send: {"city": "Tokyo"}
35
+ return {"city": "Tokyo", "time": "..."}
36
+ ```
 
 
37
 
38
  ### 2. The Gradio Interface
39
 
40
  ```python
41
  demo = gr.Interface(
42
+ fn=get_time_for_city,
43
+ inputs=gr.Textbox(...), # Defines input schema for MCP
44
+ outputs=gr.JSON(...),
45
+ api_name="get_time_for_city"
46
  )
47
  ```
48
 
49
+ ### 3. The MCP Magic
 
 
 
 
 
 
50
 
51
  ```python
52
  demo.launch(mcp_server=True)
53
  ```
54
+ This single line turns your web app into an AI tool server!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  ---
57
 
58
+ ## πŸš€ Deploying to HuggingFace Spaces (Critical Details)
59
 
60
+ Deploying is easy, but there are **two common pitfalls** to watch out for.
61
 
62
+ ### Step 1: Configure the Entry File
63
 
64
+ You don't need to rename your file to `app.py`! You can tell HuggingFace which file to run.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
+ 1. Go to your Space's **Files** tab.
67
+ 2. Click on `README.md` to edit it.
68
+ 3. Look at the **YAML Header** (the metadata at the top between `---`).
69
+ 4. Change the `app_file` line:
70
 
71
+ **For Berlin Time:**
72
+ ```yaml
73
+ app_file: app_time_mcp_server.py
 
 
 
 
 
74
  ```
75
 
76
+ **For World Time:**
77
+ ```yaml
78
+ app_file: app_world_time_mcp_server.py
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  ```
80
 
81
+ This is much cleaner than renaming files!
82
 
83
+ ### Step 2: ⚠️ Check the Port Number
84
 
85
+ **This is the most common error!**
 
 
 
 
86
 
87
+ HuggingFace Spaces **must** run on port **7860**.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
+ - `app_time_mcp_server.py` is already set to 7860. βœ…
90
+ - `app_world_time_mcp_server.py` is set to **7861** (for local testing). ❌
91
 
92
+ **You MUST change this line in `app.py` before deploying:**
93
 
94
  ```python
95
+ # CHANGE THIS:
96
+ server_port=7861
 
 
97
 
98
+ # TO THIS:
99
+ server_port=7860
 
 
 
100
  ```
101
 
102
+ If you forget this, you will see: `OSError: Cannot find empty port`.
103
 
104
+ ### Step 3: Upload to Spaces
 
 
 
105
 
106
+ 1. Create a new Space (SDK: **Gradio**).
107
+ 2. Upload:
108
+ - `app.py` (your chosen server)
109
+ - `requirements.txt`
110
+ 3. Wait for "Running" status.
111
 
112
  ---
113
 
114
+ ## πŸ”— Connecting Your Agent
 
 
115
 
116
+ Once deployed, your agent needs to know where to look.
 
 
117
 
118
+ ### Update `src/config/settings.py`
 
 
 
119
 
120
+ ```python
121
+ servers["berlin_time"] = {
122
+ # 1. Use your Space URL
123
+ # Format: https://huggingface.co/spaces/USERNAME/SPACE_NAME/gradio_api/mcp/
124
+ "url": "https://gfiamon-date-time-mpc-server-tool.hf.space/gradio_api/mcp/",
125
+
126
+ # 2. Use 'sse' transport (Server-Sent Events)
127
+ "transport": "sse"
128
+ }
129
+ ```
130
 
131
+ ### How It Works
132
 
133
+ 1. **Agent Starts:** Connects to that URL via SSE.
134
+ 2. **Discovery:** Asks "What tools do you have?"
135
+ 3. **World Time:** Server replies "I have `get_time_for_city` which takes a `city` string".
136
+ 4. **User Asks:** "Time in Tokyo?"
137
+ 5. **LLM:** "Call `get_time_for_city(city='Tokyo')`"
138
+ 6. **Agent:** Sends command to HF Space -> Gets result -> Shows user.
139
 
140
  ---
141
 
142
+ ## πŸŽ“ Teaching This to Colleagues
 
 
 
 
 
 
143
 
144
+ **Key Teaching Points:**
145
 
146
+ 1. **One Codebase, Two Interfaces:**
147
+ - **Humans** use the Web UI (click buttons).
148
+ - **AI Agents** use the MCP API (hidden endpoint).
149
+ - Both are powered by the *same Python function*.
 
150
 
151
+ 2. **Deployment Simplicity:**
152
+ - No Docker, no Nginx, no complex config.
153
+ - Just `app.py` + `requirements.txt` on HF Spaces.
 
 
154
 
155
+ 3. **The "Port Trap":**
156
+ - Remind them: Local dev can use any port, but HF Spaces enforces port 7860.
 
 
 
 
 
 
 
 
 
 
 
157
 
158
+ 4. **Dynamic Discovery:**
159
+ - Show them how you can update the tool on HF (e.g., add "Mars Time"), restart the agent, and it *instantly* knows about the new feature without changing agent code.