首頁 / Skills / 開發提效 / MCP 建置指南 MCP Builder
開發提效

MCP 建置指南 MCP Builder

AnthropicApache-2.0Skill 語言: 英文
授權已核對含腳本依賴外部服務需要金鑰
演示真實執行紀錄 · claude-sonnet-5-5 · 2026年10月
I want to build an MCP server for a weather forecast REST API. Plan the tool design for me: server name, tool names, input parameters, pagination and error handling. Give me the plan, not the full code.
Skill: mcp-builder

Weather Forecast MCP Server: Tool Design Plan

I haven't seen your API's docs, so this assumes a typical weather REST API with geocoding, current conditions, hourly and daily forecasts, and alerts. Send me the real endpoints and I'll adjust the plan.

1. Server basics

Item Choice
Server name weather-mcp-server (TypeScript convention: {service}-mcp-server; Python would be weather_mcp)
Language TypeScript with the MCP SDK and Zod
Transport stdio for local use. Use stateless JSON streamable HTTP if you host it remotely.
Auth API key from an env var (WEATHER_API_KEY). It never appears as a tool parameter.
Tool prefix weather_ on every tool, so they stay discoverable next to other servers

2. Tools

All tools are read-only, so each gets the annotations readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true.

weather_search_locations

Resolves a place name to coordinates. Forecast tools depend on this, since LLMs are bad at guessing lat/lon.

  • query (string, 2–100 chars): e.g. "Paris" or "Portland, Oregon".
  • country_code (optional string, ISO-3166 alpha-2): disambiguates results.
  • limit (int, 1–50, default 10) and offset (int, default 0).
  • Returns: location_id, name, admin_region, country, latitude, longitude, timezone, plus pagination metadata.

weather_get_current_conditions

  • location: a shared location input (see below).
  • units: metric or imperial (default metric).
  • response_format: markdown or json (default markdown).
  • Returns: temperature, feels-like, humidity, wind speed and direction, precipitation, condition text, observation time and the location's timezone.

weather_get_hourly_forecast

  • location, units and response_format, as above.
  • start_hour_offset (int, default 0) and limit (int, 1–48, default 24). These act as the pagination window.
  • fields (optional enum array, e.g. temperature, precipitation_probability, wind). This trims the output, since hourly data is large.

weather_get_daily_forecast

  • location, units and response_format, as above.
  • days (int, 1–16, default 7), with offset for paging past the first window if the API supports it.
  • Returns: high/low, precipitation total and probability, wind, UV index, sunrise/sunset, and a condition summary.

weather_get_alerts

  • location.
  • severity (optional enum: minor, moderate, severe, extreme).
  • limit and offset.
  • Returns: event, severity, onset/expiry, affected area, and description. An empty list is a valid result, reported as "no active alerts".

Optional, if the API supports them

  • weather_get_historical_weather: location, start_date and end_date (ISO YYYY-MM-DD, with a max range), plus limit and offset.
  • weather_get_air_quality: AQI and pollutants.

Shared location input

Every forecast tool accepts one of two forms, validated with a Zod union:

  • { latitude: number (-90..90), longitude: number (-180..180) }
  • { location_id: string } from weather_search_locations

I'd also consider letting forecast tools take a plain place_name and geocode internally. That saves the model a round trip, but it can silently pick the wrong "Springfield", so the response would have to echo the resolved place. My recommendation is to require explicit coordinates or an ID, because ambiguity is the most common failure here.

3. Pagination

Most weather data is small, so pagination only matters for location search, alerts, hourly data and history.

  • Style: limit plus offset as inputs, even if the upstream API uses cursors or page numbers. The server translates between them. If the API is cursor-only, return an opaque next_cursor instead.
  • Defaults: keep them small (10 for search, 24 hours for hourly) and enforce hard maximums in the schema.
  • Response metadata, included in both text and structuredContent:
    { "total": 87, "count": 20, "offset": 0, "has_more": true, "next_offset": 20 }
    
  • Truncation: cap output at about 25k characters. If exceeded, cut the result and add a note like "Truncated; use limit/fields or a smaller range."

4. Error handling

Errors are returned as tool results with isError: true, not as protocol errors. Each message should say what happened and what to do next.

Upstream condition Message to the model
400 / invalid params "Invalid latitude 123. Must be between -90 and 90."
401 / 403 "API key missing or rejected. Check WEATHER_API_KEY on the server." This one is for the user, so don't tell the model to retry.
404 / no location found "No location matched 'Xyzzy'. Try weather_search_locations with a broader query or a country_code."
429 "Rate limited. Retry after N seconds." (taken from the Retry-After header)
5xx / timeout / network "Weather service temporarily unavailable. Retry shortly."
Empty result A normal success: "No alerts active for this location."

Implementation notes:

  • Use one shared handleApiError() helper that maps status codes to these messages. Never leak raw stack traces or the API key.
  • Use a request timeout (about 10s). Retry once on 5xx or network errors with a short backoff, and never retry 4xx.
  • Add a small in-memory cache (TTL of about 5–10 minutes for forecasts, 24 hours for geocoding) to cut rate-limit pressure.
  • Validate inputs with Zod .strict() schemas, so bad inputs fail before any HTTP call.

5. Output conventions

  • Each tool defines an outputSchema and returns structuredContent, plus a text rendering in the requested response_format.
  • Always include units and the location's timezone in output, because "18°" and "3 pm" are ambiguous without them.
  • Markdown output is human-readable (dates and place names, not raw IDs). JSON output is complete and meant for programmatic use.

6. Suggested project layout

weather-mcp-server/
├── src/
│   ├── index.ts            # server init, transport
│   ├── constants.ts        # base URL, CHARACTER_LIMIT, defaults
│   ├── schemas/            # shared Zod: location, units, pagination
│   ├── services/
│   │   └── weatherClient.ts  # HTTP, auth, retry, cache, handleApiError
│   ├── formatters.ts       # markdown/json rendering, truncation
│   └── tools/              # one file per tool group
└── package.json, tsconfig.json

7. Next steps

  1. Send me the API docs or the name of the provider, and I'll finalize the tool list and field mappings.
  2. Build the API client and shared helpers first, then the tools.
  3. Test with npx @modelcontextprotocol/inspector.
  4. Write about 10 read-only evaluation questions, such as "Which of Lisbon or Madrid has the higher forecast high on Friday?", to check that a model can chain search_locations into a forecast tool.

Questions that would change the plan:

  • Which weather provider are you using?
  • Is this server local or remote?
  • Do you need history or air quality, or just forecasts and alerts?

Real run recorded with claude-code / claude-sonnet-5-5. Output is shown verbatim, unmodified.

它做什麼

引導模型建置 MCP(Model Context Protocol)伺服器,讓 AI 代理透過設計良好的工具使用外部服務。它把一些實用慣例寫了進去:伺服器與工具如何命名、何時同時提供 JSON 與 Markdown 輸出、如何分頁、如何寫出會告訴代理下一步該怎麼做的錯誤訊息,以及如何選擇傳輸方式。

運作方式

  1. 調研與規劃:閱讀 MCP 規範與 SDK 文件,選定工具,規劃較完整的 API 涵蓋範圍。
  2. 實作:建立專案、共用的 API 用戶端與錯誤處理,再以具型別的輸入結構(Zod 或 Pydantic)與註解註冊每個工具。
  3. 審查與測試:檢查程式碼品質、建置,並用 MCP Inspector 試跑伺服器。
  4. 評估:撰寫約 10 個真實、唯讀、可驗證的問題,檢驗模型能否真的用好你的工具。內附的兩個 Python 腳本可以對你的伺服器執行這些評估。

適合:為 REST API 或 SaaS 產品開發 MCP 伺服器的開發者,語言可選 TypeScript(建議)或 Python。

說明與風險

包含指令、參考指南與 2 個 Python 腳本(scripts/connections.py、scripts/evaluation.py),我們逐行讀過,沒有發現隱藏行為。執行 evaluation.py 需要你自己的 Anthropic API 金鑰(讀取環境變數 ANTHROPIC_API_KEY),會呼叫收費的 API;stdio 模式下它會執行你指定的伺服器指令。此外,如果你的代理能連網,這個 Skill 會讓模型從網路取得 MCP 規範與 SDK 文件。程式碼範例僅供參考,使用前請自行審查(例如其中的檔案資源範例沒有驗證路徑)。