# Tool Design Analysis: Should get_current_temperature and get_current_conditions be Merged?
## Current Architecture
### get_current_temperature
- **Purpose**: Quick temperature checks
- **API Call**: `client.get_current(city)` (with fallback to `get_today`)
- **Returns**: Temperature + Swiss German + suggestions (11 fields)
- **Target Questions**: Categories 1, 9 (~20 questions)
- "What's the Aare temperature?"
- "How cold is the water?"
- "Is it warm enough to swim?"
### get_current_conditions
- **Purpose**: Comprehensive swimming assessment
- **API Call**: `client.get_current(city)`
- **Returns**: Temperature + flow + height + weather + forecast (full nested
data)
- **Target Questions**: Categories 2, 3, 8 (~30 questions)
- "Is it safe to swim?"
- "How are conditions today?"
- "Should I go swimming now?"
## Key Observation: Both Use Same API Endpoint
```python
# get_current_temperature
await client.get_current(city) # Fetches full data, extracts temperature
# get_current_conditions
await client.get_current(city) # Fetches full data, returns everything
```
**They call the same cached endpoint**, so there's no performance benefit to
having separate tools.
---
## Arguments FOR Merging
### 1. **Eliminates Redundancy**
- Same API call, different data extraction
- 50% fewer tools to maintain
- Simpler codebase
### 2. **DRY Principle**
- Don't repeat the same API logic
- Single source of truth for current data
### 3. **Fewer Choices**
- AI assistants have fewer tools to choose from
- Reduces decision fatigue
### 4. **Simpler API Surface**
- 5 tools instead of 6
- "One tool to rule them all" for current data
### Merged Tool Design
```python
@mcp.tool(name="get_current_data")
async def get_current_data(
city: str = "Bern",
include_weather: bool = True,
include_forecast: bool = True
) -> CurrentDataResponse:
"""Get current river data with optional weather/forecast."""
# Single implementation, optional fields
```
---
## Arguments AGAINST Merging (Keep Separate)
### 1. **Clear Use Case Separation** ✅
The documentation explicitly separates use cases:
| Question Type | Tool to Use |
| ------------------------- | ------------------------- |
| "What's the temperature?" | `get_current_temperature` |
| "Is it safe to swim?" | `get_current_conditions` |
This makes tool selection **95%+ accurate** for AI assistants.
### 2. **Cognitive Load & Simplicity** ✅
**Focused tools are easier to understand:**
- Temperature tool: "I need temperature? Use temperature tool."
- Conditions tool: "I need full assessment? Use conditions tool."
**Merged tool requires conditional logic:**
- "Do I need weather? Do I need forecast? Which flags should I set?"
### 3. **LLM Context Window Efficiency** ✅
**Token consumption matters:**
- `get_current_temperature`: ~200 tokens (11 fields)
- `get_current_conditions`: ~500+ tokens (25+ fields with nested data)
**Why this matters:**
1. **Context Window Pressure**
- Tool responses consume valuable context space
- Smaller responses = more conversation history fits
- 2.5x token savings per temperature query
2. **Cost Efficiency**
- Many LLM APIs charge per token
- Unnecessary data = wasted money
- 300 extra tokens × 100 queries = 30,000 wasted tokens
3. **Processing Speed**
- LLMs process fewer tokens faster
- Simpler responses = quicker user experience
- Less data for LLM to parse and understand
4. **Conversation Longevity**
- Context windows have limits (100k-200k tokens)
- Every tool call consumes budget
- Efficient responses = longer conversations before truncation
**Real Impact:**
```
Scenario: 1000 temperature queries per day
Current (separate tools):
- 1000 × 200 tokens = 200,000 tokens
Merged tool approach:
- 1000 × 500 tokens = 500,000 tokens
Difference: 300,000 wasted tokens daily (60% overhead)
```
For simple questions, why return 500 tokens when 200 suffice?
### 4. **API Design Best Practices** ✅
Follows **Interface Segregation Principle**:
> "Clients should not be forced to depend on interfaces they don't use."
Users asking "What's the temperature?" don't need flow, height, weather,
forecast data cluttering the response.
### 5. **Tool Selection Accuracy** ✅
From CLAUDE.md:
> "This annotation strategy ensures Claude selects the correct tool 95%+ of the
> time"
Descriptive tool names improve accuracy:
- `get_current_temperature` → obvious for temperature queries
- `get_current_conditions` → obvious for comprehensive queries
Vs. merged:
- `get_current_data` → ambiguous, requires reading full docs
### 6. **User Experience Patterns** ✅
From the 130 user questions:
- **20 questions** (15%) want ONLY temperature
- **30 questions** (23%) want comprehensive data
- Clear distinction in user intent
### 7. **Zero Performance Cost** ✅
Since both call the same **cached** endpoint:
- No extra API requests
- No performance penalty
- The "redundancy" is conceptual, not computational
---
## Real-World Usage Patterns
### Simple Temperature Query
```
User: "What's the Aare temperature?"
AI: [calls get_current_temperature]
Response: 17.2°C - geil aber chli chalt ✅
```
Clean, focused, exactly what user asked for.
### With Merged Tool
```
User: "What's the Aare temperature?"
AI: [calls get_current_data with defaults]
Response: {
temperature: 17.2°C,
flow: 156 m³/s,
height: 1.2m,
weather: {...},
forecast: {...}
}
```
Overwhelming for a simple question. User didn't ask for flow/weather/forecast.
---
## Recommendation: **Keep Separate** ✅
### Why?
1. **User-Centric Design**
- Different questions need different data depth
- Simple questions deserve simple answers
2. **Tool Selection Quality**
- Descriptive names improve AI accuracy
- Clear use cases reduce confusion
3. **No Performance Cost**
- Same cached API call
- "Redundancy" is implementation detail, not UX problem
4. **Proven Pattern**
- Extensively documented in project
- Aligned with 130 user question analysis
- 95%+ tool selection accuracy
5. **Maintainability**
- Each tool has single responsibility
- Easy to test independently
- Clear documentation boundaries
### The "Redundancy" Isn't a Problem Because:
- Both tools call the same **cached** endpoint
- No duplicate network requests
- Code duplication is minimal (~30 lines each)
- Clear separation of concerns
---
## Alternative: If You Must Merge
If you still want to merge, here's the optimal approach:
### Option A: Single Tool with Response Levels
```python
@mcp.tool(name="get_current_data")
async def get_current_data(
city: str = "Bern",
detail: Literal["minimal", "standard", "full"] = "standard"
) -> CurrentDataResponse:
"""Get current river data with configurable detail level.
- minimal: Temperature only
- standard: Temperature + flow + Swiss German (default)
- full: Everything including weather and forecast
"""
```
**Pros**: Single tool, flexible **Cons**: AI must choose detail level (adds
complexity)
### Option B: Deprecate Temperature Tool
Keep only `get_current_conditions`, let AI extract temperature from full
response.
**Pros**: One tool **Cons**:
- Wastes tokens on simple queries
- Less clear tool naming
- Lower AI selection accuracy
---
## Conclusion
**Keep the tools separate.** The "redundancy" is a deliberate design choice that
optimizes for:
### UX Benefits
- ✅ Improves tool selection accuracy (95%+)
- ✅ Clear, focused responses match user intent
- ✅ Follows API design best practices (Interface Segregation)
### LLM Efficiency Benefits
- ✅ **60% token savings** on temperature queries (200 vs 500 tokens)
- ✅ **Longer conversations** before context window limits
- ✅ **Lower costs** for API-based LLM usage
- ✅ **Faster processing** - less data for LLM to parse
### Technical Benefits
- ✅ Costs nothing (same cached API call)
- ✅ Single responsibility per tool
- ✅ Aligns with documented user question patterns
The key insights:
1. **What looks like code redundancy is actually UX clarity**
2. **Smaller tool responses = more efficient LLM conversations**
3. **Context window efficiency is a first-class design concern**