Skip to content
Console

MCP server

The DPIP MCP server is a read-only MCP (Model Context Protocol) server. It wraps ExpTech earthquake, weather, rainfall, lightning, typhoon, tsunami, and disaster-event data as 25 tools. After you add it to an MCP client such as Claude Code or Claude Desktop, the model can query live and historical data directly, without handling each API’s format itself.

  • Per tool: tools that return TREM-net data are non-commercial; the others follow the API they wrap.

Where to show it, examples and commercial-use requests: Data licensing and attribution.

No API Token is required. Every tool is read-only and does not modify any data.

POSThttps://api.core.exptech.dev/mcp
Headers
  • Content-TypeRequired

    application/json

  • AcceptRequired

    application/json, text/event-stream

Request body
  • bodyJSON-RPC 2.0Required

    An MCP message, for example initialize, tools/list, or tools/call

Request
curl "https://api.core.exptech.dev/mcp" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
--data '{"jsonrpc":"2.0","id":1,"method":"<method>","params":{}}'
Response

Success (a tools/call response)

{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "與 structuredContent 相同內容的 JSON 字串"
}
],
"structuredContent": {
"fetched_at": "2026-11-14T14:00:05+08:00",
"data": {
"updateTime": 1794636120000,
"forecast": [
{
"time": "15:00",
"temperature": 24,
"apparentTemp": 26,
"humidity": 75,
"weather": "多雲",
"weatherCode": 200,
"pop": 20,
"wind": {
"direction": "NE",
"speed": 3,
"beaufort": 2
}
}
]
}
}
}
}

A cross-origin request from a browser was rejectedNo response body

Item Value
URL https://api.core.exptech.dev/mcp. You can also pick a node: https://api.core-tnn1.exptech.dev/mcp, https://api.core-tyo1.exptech.dev/mcp
Transport Streamable HTTP (MCP spec from 2025-03-26). The same URL also supports legacy HTTP + SSE (spec 2024-11-05)
Session Streamable HTTP does not use a session (stateless). The server does not send Mcp-Session-Id. Each request is handled on its own
Server name dpip (display name “DPIP 防災資訊”)
Authentication None
Connection timeout 3600 seconds

Streamable HTTP: send JSON-RPC messages with POST /mcp. Accept must accept both application/json and text/event-stream. The response may be JSON, or it may be SSE (the JSON-RPC message is in a data: line). Ordinary MCP clients and SDKs handle this.

Legacy HTTP + SSE: open the event stream with GET /mcp (the request omits the Mcp-Session-Id and MCP-Protocol-Version headers). The stream tells you the URL for later POST requests, /mcp?sessionid=.... A session in this mode lives on a single node, while DNS assigns api.core.exptech.dev to a node, so a later request can land on a different node. When you use legacy SSE, pick api.core-tnn1 or api.core-tyo1. New integrations should use Streamable HTTP.

終端機視窗
claude mcp add --transport http dpip https://api.core.exptech.dev/mcp

Add --scope user to use it in every project. After adding it, run claude mcp list to check the connection.

Open Settings, then Connectors, then add a custom connector. Set the name to DPIP and the URL to https://api.core.exptech.dev/mcp. Whether a custom connector is available depends on the Claude plan.

Clients that support remote MCP (for example Cursor, or a Claude Code project’s .mcp.json) usually accept the following. Field names depend on the client:

{
"mcpServers": {
"dpip": {
"type": "http",
"url": "https://api.core.exptech.dev/mcp"
}
}
}

A client that supports only stdio can bridge through mcp-remote:

{
"mcpServers": {
"dpip": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://api.core.exptech.dev/mcp"]
}
}
}

For a client that supports only legacy SSE, pick a node:

{
"mcpServers": {
"dpip": {
"type": "sse",
"url": "https://api.core-tnn1.exptech.dev/mcp"
}
}
}

Each tool’s result is placed both in structuredContent and in a JSON text block with the same contents. The shape is fixed:

Field Description
source Which ExpTech API URL the data came from. Offline tools (township_lookup) omit this field
fetched_at When the data was fetched, RFC 3339, Taiwan time (+08:00)
note Optional. Set when the upstream is temporarily unavailable and a cached copy is returned instead
data The data the tool returned
{
"source": "https://api.core-tnn1.exptech.dev/api/v5/meteor/weather/realtime/25.033,121.5654",
"fetched_at": "2026-11-14T14:00:05+08:00",
"data": {
"id": "C0A9C0",
"station": { "name": "信義", "lat": 25.0378, "lon": 121.5646, "altitude": 26, "distance": 0.55 },
"time": 1794636000,
"data": {
"weather": "多雲",
"weatherCode": 200,
"temperature": 24.6,
"humidity": 72,
"rain": 0,
"wind": { "direction": "東北", "speed": 2.1, "beaufort": 2 },
"gust": { "speed": null, "beaufort": null },
"visibility": null,
"visibility_text": "無觀測",
"pressure": null,
"sunshine": null
}
}
}

Shared conventions (the server also sends these notes to the client during initialization):

  • Times are Unix seconds, unless a field says otherwise: ts on earthquake reports, tsunami information, and RTS is Unix milliseconds, and a TREM detection is an RFC 3339 string.
  • A township code is a 3-digit postal code (for example 100 for Zhongzheng District, Taipei City). township_lookup can resolve one from a place name or coordinates.
  • Seismic intensity is a number from 0 to 9: 5 is 5-weak, 6 is 5-strong, 7 is 6-weak, 8 is 6-strong, and 9 is 7. Results also include a _label field (for example int_label). Use that when you display the value.
  • The weather missing value -99 is converted to null. Delta-encoded times are expanded to real times. Columnar snapshots are turned into one row per station, with the station name, county or city, township, and coordinates.
  • Tools that take a specific time use the at parameter (Unix seconds). Use timeline for the times you can query.

Parameters other than those marked required are optional. The License column is the class of the data each tool returns. See Data license.

Tool License Purpose Parameters
cwa_links Non-commercial Links between earthquake reports and TREM detections cwa_id, cwa_event_id, trem_event_id, limit (1–500)
earthquake_reports Commercial OK A list of earthquake reports, filtered and sorted by intensity, magnitude, depth, date, and county or city limit (1–100, default 20), page, min_intensity, max_intensity, min_magnitude, max_magnitude, min_depth, max_depth, start_date, end_date (YYYY-MM-DD), sort (time, intensity, magnitude, depth), order (desc, asc), city, city_min_intensity, city_max_intensity
earthquake_report Commercial OK One earthquake report, including intensity for each county or city and each township id (required)
gdms Commercial OK Strong-motion station records for one earthquake report: PGA, PGV, instrumental intensity, and station coordinates id (required), min_intensity, min_pga, limit (1–500, default 40)
tsunami_reports Commercial OK A list of CWA tsunami information none
tsunami_report Commercial OK One tsunami information message id (required)

TREM data are unofficial observations; the Central Weather Administration's releases always prevail. Under the Meteorological Act, they must not be used to predict earthquakes or to issue earthquake warnings. Read the full notice

Tool License Purpose Parameters
rts Non-commercial Real-time station shaking, about one frame per second, sorted by strength, with station location and township at, min_intensity, limit (1–1000, default 30)
trem_reports Non-commercial A list of TREM earthquake detections month, year, alert, limit (1–500, default 30)
trem_report Non-commercial Each report in one detection id (required, 14 digits)
trem_shakes Non-commercial A list of intensity reports month, year, limit (1–500)
trem_shake Non-commercial One intensity report, including instrumental intensity for each township id (required), min_intensity, town_limit (1–400, default 120)
trem_triggers Non-commercial Stations that triggered during one detection id (required), min_intensity, limit (1–500, default 50)
trem_trust Non-commercial Trust tier of each station tier (NO_EVIDENCE, MISFIRING, BLOCKED, SEMI, FAST), station, limit (1–500)
trem_noise Non-commercial Noise multiplier of each station status (adjusted, normal, insufficient), station, limit (1–500)
trem_picks Non-commercial Recent P-wave and S-wave picks range (24h, 7d, default 24h), station, phase (P, S), limit (default 40)
trem_debug_triggers Non-commercial Recent station triggers, including ones that did not become an earthquake range (24h, 7d, default 24h), station, coinc_result, event_id, limit (1–200, default 40)
Tool License Purpose Parameters
weather_realtime Commercial OK Current weather at the station nearest a coordinate. See current weather lat (required), lng (required)
weather_forecast Commercial OK Hourly township forecast. See township hourly forecast code (required, 3 digits)
rain_hour_forecast Commercial OK A minute-by-minute rainfall forecast for the next 1 hour for a township code (required, 3 digits)
meteor_snapshot Commercial OK A weather, rainfall, or lightning snapshot for every station, one row per station, with filtering and sorting family (required: weather, rain, lightning), at, station_ids, city, town, sort_by, order (desc, asc), limit (1–5000, default 50)
meteor_trend Commercial OK The last 24 hours or 7 days for one weather or rainfall station family (required: weather, rain), station_id (required), range (24h, 7d, default 24h)
typhoon Commercial OK Typhoon index, track, potential track, strike probability, or warnings. See Typhoons kind (cyclones, track, potential, probability, warning; default cyclones), at (not supported for cyclones)
timeline Varies Times you can query for each dataset. Radar, satellite, QPESUMS, and wind also include a tile URL template source (required: weather, rain, lightning, typhoon_track, typhoon_potential, typhoon_probability, typhoon_warning, radar, satellite, qpesums, wind), channel, style (normal, jma, bd), model (gfs, ecmwf, default gfs), limit (1–1000, default 24)
Tool License Purpose Parameters
dpip_events Commercial OK Active or recent disaster events, nationwide or for one township, newest first. text.content and text.description in the response are split by township code state (active, history; default active), code (3 digits; omit for nationwide)
township_lookup N/A Look up a township code, name, and center from a place name, a township code, or coordinates. No network call query, lat, lng, limit (1–400, default 10)

Send JSON-RPC messages without an MCP client: initialize first, then tools/call for a tool. A real integration should use an MCP SDK.

終端機視窗
curl https://api.core.exptech.dev/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
curl https://api.core.exptech.dev/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"weather_forecast","arguments":{"code":"105"}}}'

The official SDK (@modelcontextprotocol/sdk) handles the transport and the response format:

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://api.core.exptech.dev/mcp")));
const { tools } = await client.listTools();
const result = await client.callTool({ name: "weather_forecast", arguments: { code: "105" } });
console.log(result.structuredContent.data);
  • The server caches upstream data. Identical queries at the same time share one upstream request. Cache time depends on the data: 1 second for live RTS; 30 seconds for lists; 1 minute for observations, typhoons, and time lists; 10 minutes for forecasts and earthquake-report bodies; 1 hour for historical data at a chosen time or id, and for the station catalog.
  • When the upstream is temporarily unavailable (429, 5xx, or a timeout), the server returns older data from at most 10 times the cache time and explains that in note. fetched_at is when that copy was actually fetched.
  • When a parameter is invalid or the query fails, the tool call returns an error message. It does not return empty data.
  • A browser cannot call this cross-origin. A cross-origin request is rejected (403). Connect from an MCP client or from a server.
  • Streamable HTTP does not keep a session. The server does not push notifications or send requests to the client.