table-mountain-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@table-mountain-mcpShould I hike Table Mountain today, or is another day this week better?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
table-mountain-mcp
An MCP server that lets an agent answer "should I go up Table Mountain today?" and "which day this week is best?" using tablemountainweather.com, which I built.
It ships with an eval suite, because a tool description is the agent's only documentation and the only way to know whether it works is to watch agents use it.
Tools
Tool | Use it for | Returns |
| Today or right now: going up, hiking, the cable car, wind on top | Go/no-go verdict, reasons, warnings, summit conditions, cable car status and hours, a better day if there is one |
| "Which day is best?", "Is Saturday any good?" | The 7-day forecast ranked best first, dates outside the forecast, and a cable car note if it's closed |
Both are read-only and call one public endpoint, GET https://tablemountainweather.com/api/verdict, cached for five minutes (the site refreshes every ten).
Related MCP server: bergauf
Design decisions
Freshness is part of the answer. Every result has a
freshnessblock: when the data was observed, its age, the Cape Town date it was made for, andstale: truewith a plain-language note if it's old or from another day. While building this, the live endpoint served a verdict observed the previous day. An agent reading "verdict: no" without that context would give the wrong advice with full confidence."Today" means today in Cape Town, not on the agent's server. Cape Town is UTC+2, so at 23:30 UTC it is already tomorrow there. There's a test for that.
Say what's missing instead of dropping it. Dates past the 7-day forecast come back in
notInForecast, so the agent says "no forecast yet" rather than silently answering about other days.Errors tell the agent what to do. When the site is down the tool returns an error that says not to estimate the weather and where the user can check.
Weather and the cable car are separate questions. A good-weather day while the cableway is closed for maintenance gets a
cablewayNote.Defensive parsing. The response is validated with Zod and unknown fields pass through, so a site change produces a clear error rather than wrong numbers.
Install
Requires Node 20+.
git clone https://github.com/cobus-meyer/table-mountain-mcp && cd table-mountain-mcp
npm install && npm run buildClaude Code:
claude mcp add table-mountain -- node /absolute/path/to/table-mountain-mcp/dist/index.jsClaude Desktop, Cursor or any stdio MCP client:
{
"mcpServers": {
"table-mountain": { "command": "node", "args": ["/absolute/path/to/table-mountain-mcp/dist/index.js"] }
}
}Tests
npm testTests drive the server through a real MCP client over an in-memory transport: ranking, stale data, the Cape Town midnight edge, out-of-range dates, a closed cableway, a site outage, bad input, caching and a changed response shape.
Evals
evals/cases.ts holds 12 questions a real user would ask, each run against a frozen API response and a frozen clock:
Case | What it checks |
today-no, today-yes | Gives the verdict and a better day |
wind, last-car | Reads conditions and cable car hours correctly |
best-this-week, saturday, weekend | Converts weekday names to dates, ranks, reports a poor day honestly |
out-of-range | Says a date is beyond the forecast instead of guessing |
stale | Notices the verdict is from yesterday |
cableway-closed | Good weather, but mentions the closure |
site-down | Admits it couldn't check, invents no numbers |
wrong-place | Doesn't use Table Mountain data for Johannesburg |
Each case starts a fresh agent with the server attached and grades the transcript: were the right tools called, does the answer contain the facts that matter, and does it avoid the mistakes that matter. Grading is rule-based on purpose so it's cheap, repeatable and easy to dispute.
npm run eval:check # offline: cases, fixtures and tools are valid
ANTHROPIC_API_KEY=... npm run eval # run all cases once
npm run eval -- --runs 3 --model claude-haiku-5-5 # repeat to see variance
npm run eval -- --descriptions baseline # compare one-line tool descriptions--descriptions baseline swaps in the one-line tool descriptions most servers ship, so the effect of writing descriptions for agents can be measured instead of assumed. Results are written to evals/results/.
Results
12 cases, 3 runs each, on claude-haiku-5-5, run on 2026-11-03.
Description set | Pass rate | Avg tool calls |
| 100% (36/36) | 1.0 |
| 92% (33/36) | 0.9 |
The only failure was last-car on baseline, in all 3 runs: the agent said it had no access to the cable car schedule and never called a tool, because the one-line description only mentions a weather verdict. v1 names cable car status and hours in its description and passed all 3 runs. With no v1 failures, nothing changed after these runs.
Fixtures
fixtures/windy-monday.json is a real response from the live API. calm-monday.json and cableway-closed.json are edited copies of it for cases the live API wasn't showing at the time.
License
MIT
Available Tools
2 toolsfind_best_dayBest day to go up Table MountainARead-onlyIdempotent
Rank the days in tablemountainweather.com's 7-day Table Mountain forecast, best first.
Each day has a quality rating (best to worst: excellent, good, grey, poor, blocked) and goodHours, the number of hours that day rated good for going up.
Use for 'which day is best', 'is Saturday any good', or planning a trip this week. Pass dates for specific days, or from/to for a range; with no arguments it ranks every remaining day.
Convert weekday names to YYYY-MM-DD using freshness.todayInCapeTown from any earlier result, or call with no arguments and read the weekday field.
Dates outside the forecast come back in notInForecast: say there's no forecast for them yet instead of guessing. If cablewayNote is set, mention it.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Last date to include, YYYY-MM-DD (Cape Town). | |
| from | No | First date to include, YYYY-MM-DD (Cape Town). Defaults to today. | |
| dates | No | Specific dates to rate, YYYY-MM-DD (Cape Town). Overrides from/to. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover safety (readOnly, idempotent, openWorld); the description adds substantial behavior beyond them: the rating scale, `goodHours`, the `notInForecast` fallback for out-of-range dates, the `cablewayNote` caveat, and the dependency on `freshness.todayInCapeTown` for weekday-to-date conversion.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and rating scale, then argument guidance, then edge-case handling; nearly every sentence carries instructions the agent needs at call time. It runs a bit long, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by naming every meaningful return field (quality, goodHours, notInForecast, cablewayNote, weekday) and telling the agent how to phrase results. Nothing needed to call or interpret it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, and the description adds real meaning on top: precedence between `dates` and `from`/`to` and the no-argument default of ranking every remaining day. The weekday-name conversion workflow is value the schema cannot express.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Rank the days ... 7-day Table Mountain forecast, best first') and enumerates the rating vocabulary up front. The 7-day ranking scope implicitly separates it from the today-only sibling, so an agent can pick correctly without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete triggering phrasings ('which day is best', 'is Saturday any good') plus explicit argument-selection rules: use `dates` for specific days, `from`/`to` for a range, nothing to rank all remaining days. It never names the sibling `get_table_mountain_today` as the alternative for today's conditions, so the when-not guidance is incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_table_mountain_todayTable Mountain todayARead-onlyIdempotent
Should someone go up Table Mountain (Cape Town) TODAY? Returns tablemountainweather.com's go/no-go verdict with reasons, warnings, current summit conditions (wind, gusts, cloud, rain, temperature), cable car status and hours, and a better day this week if there is one. Use for questions about today or right now: going up, hiking, the cable car, wind or cloud on top. For a specific day other than today, or 'which day is best', use find_best_day instead. Only covers Table Mountain. Don't use it for other places. Times are Cape Town local time (UTC+2). Check freshness.stale: if true, follow freshness.note and don't present the data as current. If cableway.running is false, cableway.closedUntil is the date it reopens, not its last closed day.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnly/idempotent/openWorld, so the description carries the real burden and does so: it enumerates the returned fields (verdict, reasons, warnings, summit wind/gusts/cloud/rain/temperature, cable car status and hours), pins the timezone (UTC+2), and defines a data-freshness contract (check freshness.stale, follow freshness.note, don't present as current). It also disambiguates cableway.closedUntil as a reopen date rather than a last-closed date, which is exactly the kind of trap a naive reader would fall into.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core question and the verdict payload, then usage, then scope, then caveats — a sensible ordering with no filler sentences. It runs slightly long and the freshness/cableway caveats are dense, but each clause encodes a distinct rule an agent would otherwise get wrong.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description takes responsibility for describing the return payload, including conditional fields ('a better day this week if there is one'). Combined with the freshness and closedUntil semantics, an agent has everything needed to call it and interpret the result without further documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the baseline this sits at 4; there is no parameter meaning left to add. The description does not waste words restating an empty schema, which is the right call.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific question-shaped verb ('Should someone go up Table Mountain TODAY?') plus the resource, verdict type, and the exact site the data comes from. It explicitly distinguishes itself from the sibling by naming find_best_day for other days, and scopes itself geographically ('Only covers Table Mountain').
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('questions about today or right now: going up, hiking, the cable car, wind or cloud on top'), explicit routing to the alternative ('For a specific day other than today, or "which day is best", use find_best_day'), and explicit exclusions ('Don't use it for other places'). All three routing decisions an agent needs are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.0- First observed
find_best_day - First observed
get_table_mountain_today
TDQS
Scored across 2 tools
The two tools split cleanly along a temporal axis: get_table_mountain_today answers 'right now / today' while find_best_day ranks the 7-day forecast. Each description explicitly tells the agent when to use the other tool, leaving essentially no room for misselection.
Both names are snake_case verb_phrase constructions that describe their output, but the verbs differ (get_ vs find_) and only one carries the domain prefix (table_mountain). Still highly predictable once the pair is seen together.
Two tools is thin by generic standards, but the domain is deliberately narrow — a single site's daily go/no-go verdict — and the today/forecast split covers it without padding. Nothing here feels like filler, though a third tool would not have room to exist.
Today's verdict (with conditions, cableway status, warnings, staleness) plus a ranked 7-day outlook with date filtering covers the realistic user intents for this niche. Remaining gaps — hourly breakdowns, historical trends, other trailheads — are minor or explicitly out of scope.
Maintenance
Related MCP Connectors
NOAA weather for AI agents: conditions, forecasts, observed history. 4 tools, free, no key.
US weather & geo for AI agents: forecasts, alerts, earthquakes, elevation, geocoding. No keys.
US weather & geo for AI agents: forecasts, alerts, earthquakes, elevation, geocoding. No keys.
77 public tools: agent runs, handoffs, one-time secrets, semantic search, queues and webhooks.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to access real-time and historical weather data through multiple weather APIs including OpenMeteo, Tomorrow.io, and OpenWeatherMap. Provides comprehensive meteorological information including current conditions, forecasts, historical data, and weather alerts.-
- FlicenseNot gradedqualityDmaintenanceLets an LLM plan hikes anywhere in Switzerland by combining named routes, elevation profiles, weather forecasts, and public transport.7-
- AlicenseNot gradedqualityDmaintenanceProvides weather intelligence as MCP tools (current weather, forecast, air quality, UV index, alerts) with agentic orchestration, memory, and citation-grounded RAG.MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to explore Swiss hiking routes with real-time closures, weather, public transport, and POIs, including GPX generation.1MIT