気象庁アメダスの観測値JSON(公式APIではない)の使い方:最新時刻・観測所番号・品質フラグの読み方
要点
- 最新時刻を先に読む。
https://www.jma.go.jp/bosai/amedas/data/latest_time.txtに、取得できる最新の観測時刻が入っています。 - 全国なら map、1地点なら point。
map/20261020100000.jsonは10分ごとの全国1,286地点、point/44132/20261020_09.jsonは1地点の3時間分です。 - 値は
[値, 品質]の2要素。 品質が0か1以外の値は使いません。東京の1時間降雪量は値が0、品質が6(欠測)でした。 - 観測所表の緯度経度は
[度, 分]。 東京の[35, 41.5]は北緯35.69167度です。 - 最高・最低気温の時刻は、実測ではUTCと読むと整合しました(推定)。
{"hour":0,"minute":5}は日本時間の9時5分でした。
気温や降水量の「いまの値」をプログラムやAIエージェントから引くなら、最新時刻を latest_time.txt で確かめ、全国なら map/、1地点なら point/ のJSONをキーなしでGETします。 どちらも気象庁ホームページのアメダスの画面が読み込むファイルで、API仕様書は見つかりませんでした。値ごとに付く品質の番号を見ずに数字だけを取ると、欠測を0として扱ってしまいます。
2026年10月20日の10時17分から10時30分にかけて、Node.js(依存なし)とcurlから合計17回リクエストし、構造と件数を確かめました。天気予報のJSONは気象庁の天気予報JSONの使い方で扱っています。予報JSONの気温の地点は、この記事のアメダスの観測所番号と同じでした(後述)。
取得した4つのファイル
| 用途 | URL | 実測サイズ | Last-Modified(日本時間) |
|---|---|---|---|
| 最新の観測時刻 | https://www.jma.go.jp/bosai/amedas/data/latest_time.txt | 25 bytes | 2026-10-20 10:06:40 |
| 観測所表 | https://www.jma.go.jp/bosai/amedas/const/amedastable.json | 187,742 bytes | 2026-10-15 13:09:52 |
| 全国の10分値 | https://www.jma.go.jp/bosai/amedas/data/map/20261020100000.json | 349,082 bytes | 2026-10-20 10:13:25 |
| 1地点の3時間分 | https://www.jma.go.jp/bosai/amedas/data/point/44132/20261020_09.json | 4,176 bytes | 2026-10-20 10:16:30 |
4つとも Cache-Control: max-age=60、Access-Control-Allow-Origin: * で、キーなしのGETで返りました。latest_time.txt の中身は 2026-10-20T10:00:00+09:00 の1行です。ファイル名の時刻は、map/ が YYYYMMDDhhmmss、point/ が YYYYMMDD_hh で、どちらも日本時間でした。point/ は3時間ごとのファイルで、10時台の値は _09 のファイルに入っていました。
最新時刻を先に読む
latest_time.txt を2回取得しました。
10:17:08 取得 -> 2026-10-20T10:00:00+09:00(Last-Modified 10:06:40)10:25:11 取得 -> 2026-10-20T10:10:00+09:00(Last-Modified 10:16:40)10時00分の値が latest_time.txt に反映されたのは10時06分40秒で、6分40秒ほど後でした。一方、10時17分に取得した東京の point/ には、latest_time.txt がまだ指していない10時10分の値が入っていました。地点のファイルは、全国の時刻表示より先に更新されることがあります。
全国の map/20261020100000.json は、Last-Modified が10時13分25秒で、latest_time.txt が10時00分を指し始めた10時06分40秒より後でした。同じ時刻のファイルが後から書き直されることがある、と読めます。10時17分と10時25分に取得した中身は同じで、何が書き直されたのかは確かめていません。
時刻を自分で計算して、まだないファイルを取りに行かないでください。 存在しない観測所番号(point/99999/20261020_09.json)を取得すると、HTTP 404 の text/html(2,203 bytes)が返りました。このときの Age ヘッダーは43,516秒で、404の応答が12時間ほど中継サーバーに保持されていたことになります。まだ作られていない時刻のファイルで同じことが起きるかは試していませんが、latest_time.txt の時刻だけを使えば避けられます。
観測所表 amedastable.json
観測所表は、5桁の観測所番号をキーにしたオブジェクトです。東京のエントリです。
"44132": { "type": "A", "elems": "11111111", "lat": [35, 41.5], "lon": [139, 45], "alt": 25, "kjName": "東京", "knName": "トウキョウ", "enName": "Tokyo"}type の名前は、ページのスクリプトにある凡例から読みました。A は気象台、B は測候所・特別地域気象観測所、C は地域気象観測所(アメダス)、D は父島気象観測所、E は南鳥島気象観測所、F は富士山特別地域気象観測所、G はその他の気象観測所です。D〜G は1地点ずつでした。
elems は8桁で、左から気温、降水量、風向、風速、日照時間、積雪深、湿度、気圧の有無です。凡例の組み合わせ(気象台の 11111011 が「気温・降水量・風向風速・日照時間・湿度・気圧」など)から並びを読みました。最も多いのは 11112010(487地点)で、5桁目に 2 が入るのは種類C(687地点)とG(1地点)だけでした。アメダスの解説ページには、2021年3月2日から気象台と特別地域気象観測所以外の観測所で日照時間を推計値で提供しているとあり、それと合います。2 の意味を定義した資料は見つけていません。
降水量だけを観測する 01000000 は351地点です。解説ページの「降水量は約1,300か所」「風・気温・湿度は約840か所」「積雪深は約330か所」に対し、10時00分の map/ で各要素のキーを持つ地点は、降水量1,281、湿度839、積雪深333でした。
値は [値, 品質] の2要素
map/ の東京(44132)の10時00分の値です。
{ "pressure": [1015.6, 0], "normalPressure": [1018.4, 0], "temp": [22.7, 0], "humidity": [75, 0], "snow": [null, 5], "snow1h": [0, 6], "snow6h": [0, 6], "snow12h": [0, 6], "snow24h": [0, 6], "sun10m": [0, 0], "sun1h": [0, 0], "precipitation10m": [0, 0], "precipitation1h": [0, 0], "precipitation3h": [0, 0], "precipitation24h": [0, 0], "windDirection": [14, 0], "wind": [2.1, 0]}2番目の数字が品質です。ページのスクリプトは次の記号で表示していました。記号の意味は、気象庁の過去の気象データ検索「値欄の記号の説明」によります。
| 品質 | 画面の記号 | 意味 | 10時00分の全国で見つかった例 |
|---|---|---|---|
| 0 | なし | 正常 | ほとんどの値 |
| 1 | ) | 準正常値。統計の対象資料が許容範囲内で欠けている | 巻の24時間降水量 [89, 1] など12地点 |
| 2、3 | # | 疑問値。値にかなり疑問がある | 見つからず |
| 4 | ] | 資料不足値。値そのものは信用できない | 静岡空港の24時間降水量 [41.5, 4] |
| 5 | 休止中 | 観測を休止している | 積雪深の333地点すべて、別海の気温 [null, 5] |
| 6 | × | 欠測 | 東京の1時間降雪量 [0, 6](336地点) |
| null | 空白 | その要素を観測していない | 宗谷岬の1時間降雪量 [0, null](950地点) |
ページのスクリプトは、品質が0か1で値が null でないときだけを有効な値として扱っていました。値が0でも品質が6なら欠測です。 数字だけを取り出すと、欠測の降雪量を「0cm」と答えてしまいます。積雪深は10月20日時点で全地点が休止中でした。
単位も同じスクリプトにありました。temp は℃、humidity は%、precipitation10m などは mm、wind は m/s、windDirection は16方位(1が北北東、16が北、0が静穏)、sun10m は分、sun1h は時間、snow 系は cm、pressure(現地気圧)と normalPressure(海面気圧)は hPa、visibility は km です。
地点ファイル point/ の構造
point/44132/20261020_09.json は、20261020090000 から 20261020101000 までの8件を持っていました。10分ごとの値に加えて、maxTemp・minTemp・gust(最大瞬間風速)とその時刻が入ります。積雪のキー(snow、snow1h など)は毎正時の09:00と10:00にだけありました。
時刻のキーは日本時間ですが、maxTempTime などの hour と minute は、今回の実測からUTCと推定しています。 公式資料では確認できていないので、値の推移から判断した根拠を書きます。
09:00 temp 23.3 maxTemp 23.3 maxTempTime {"hour":0,"minute":0}09:10 temp 23.3 maxTemp 23.6 maxTempTime {"hour":0,"minute":5}(minTempTime はどちらも {"hour":20,"minute":46}、minTemp 18.6)09:10の時点で、その日の最高気温が23.3から23.6に上がり、時刻が「0時5分」になりました。日本時間の0時5分なら、09:00の時点ですでに23.6が最高気温になっていたはずです。UTCの0時5分、つまり日本時間の9時5分なら、09:00と09:10のあいだに23.6を記録したことになり、値の動きと合います。最低気温の「20時46分」は、同じ読み方で日本時間の5時46分です。
予報JSONの気温の地点はアメダスの番号
天気予報のJSONでは、気温の地点コードが area.json に存在しないことを予報JSONの記事で書きました。10月20日5時発表の forecast/130000.json を取得して照合すると、その4地点はすべてアメダスの観測所表にありました。
44132 東京 -> amedastable の「東京」(種類A)44172 大島 -> 「大島」(種類B)44263 八丈島 -> 「八丈島」(種類B)44301 父島 -> 「父島」(種類D)予報の気温と、同じ地点の観測値を並べたいときは、この番号でつなげます。東京都以外の府県では照合していません。
Node.jsで1地点の最新値を取る
観測所の名前から候補を探し、1件に決まったときだけ最新値を取得します。観測所表は1日キャッシュします。
// amedas-latest.mjs — 依存なし(Node.js 18 以降の組み込み fetch)// 使い方: node amedas-latest.mjs 東京import { readFile, writeFile, mkdir, stat } from 'node:fs/promises';
const UA = 'amedas-example/0.1 (+https://codeagent.jp/)';const BASE = 'https://www.jma.go.jp/bosai/amedas';const TABLE_URL = `${BASE}/const/amedastable.json`;const TABLE_CACHE = './cache/amedastable.json';const DAY = 24 * 60 * 60 * 1000;// 画面のスクリプトにある品質の記号。0 と 1 以外は値として使わないconst AQC = { 0: '', 1: ')', 2: '#', 3: '#', 4: ']', 5: '休止中', 6: '×' };const UNITS = { temp: '℃', humidity: '%', precipitation10m: 'mm', precipitation1h: 'mm', wind: 'm/s', windDirection: '16方位', sun1h: 'h', snow: 'cm', pressure: 'hPa' };
async function get(url, kind) { const res = await fetch(url, { headers: { 'User-Agent': UA } }); const type = res.headers.get('content-type') ?? ''; // 存在しない観測所は 404 の HTML が返る if (!res.ok || (kind === 'json' && !type.includes('json'))) { throw new Error(`取得失敗: ${url} -> HTTP ${res.status} (${type})`); } return kind === 'json' ? res.json() : (await res.text()).trim();}
async function loadTable() { try { if (Date.now() - (await stat(TABLE_CACHE)).mtimeMs < DAY) return JSON.parse(await readFile(TABLE_CACHE, 'utf8')); } catch { /* キャッシュなし */ } const table = await get(TABLE_URL, 'json'); await mkdir('./cache', { recursive: true }); await writeFile(TABLE_CACHE, JSON.stringify(table)); return table;}
const toDeg = ([d, m]) => Math.round((d + m / 60) * 1e5) / 1e5; // [度, 分] → 十進の度
// [値, 品質] を { value, aqc, mark } に。品質が 0・1 以外なら値を捨てるfunction reading([value, aqc] = []) { if (aqc === undefined) return undefined; // その要素を観測していない const usable = (aqc === 0 || aqc === 1) && value !== null; return { value: usable ? value : null, aqc, mark: aqc === null ? '観測なし' : AQC[aqc] ?? `不明(${aqc})` };}
// 今回の実測からUTCと推定(公式仕様は未確認)。観測時刻以前で最も近い日時として日本時間に直すfunction jstTime(observedAt, t) { if (!t) return null; const obs = new Date(observedAt); const at = new Date(Date.UTC(obs.getUTCFullYear(), obs.getUTCMonth(), obs.getUTCDate(), t.hour, t.minute)); if (at > obs) at.setUTCDate(at.getUTCDate() - 1); return new Date(at.getTime() + 9 * 3600e3).toISOString().slice(0, 16) + '+09:00';}
// 風向は 1〜16 が北北東から時計回り、0 は静穏const WDR = ['静穏', '北北東', '北東', '東北東', '東', '東南東', '南東', '南南東', '南', '南南西', '南西', '西南西', '西', '西北西', '北西', '北北西', '北'];
async function main(name) { const table = await loadTable(); const candidates = Object.entries(table) .filter(([, s]) => s.kjName === name) .map(([code, s]) => ({ code, name: s.kjName, type: s.type, lat: toDeg(s.lat), lon: toDeg(s.lon), alt: s.alt })); if (candidates.length !== 1) { console.log(JSON.stringify({ status: candidates.length ? 'ambiguous' : 'not_found', input: name, candidates }, null, 2)); return; } const station = candidates[0];
// 最新時刻を先に読む。時刻を自分で計算して先回りしない const latest = await get(`${BASE}/data/latest_time.txt`, 'text'); // 例 2026-10-20T10:10:00+09:00 const ymd = latest.slice(0, 10).replaceAll('-', ''); const block = String(Math.floor(Number(latest.slice(11, 13)) / 3) * 3).padStart(2, '0'); const pointUrl = `${BASE}/data/point/${station.code}/${ymd}_${block}.json`; const series = await get(pointUrl, 'json'); const obsKey = latest.slice(0, 19).replace(/[-T:]/g, ''); const row = series[obsKey]; if (!row) throw new Error(`${pointUrl} に ${obsKey} がない`);
const values = Object.fromEntries(Object.keys(UNITS).map((k) => [k, reading(row[k])]).filter(([, v]) => v)); console.log(JSON.stringify({ status: 'ok', station, observedAt: latest, values, windDirectionLabel: values.windDirection?.value == null ? null : WDR[values.windDirection.value], units: UNITS, maxTemp: { ...reading(row.maxTemp), at: jstTime(latest, row.maxTempTime) }, minTemp: { ...reading(row.minTemp), at: jstTime(latest, row.minTempTime) }, newerKeysInFile: Object.keys(series).filter((k) => k > obsKey), provenance: { sources: [`${BASE}/data/latest_time.txt`, pointUrl, TABLE_URL], retrievedAt: new Date().toISOString(), attribution: '出典:気象庁ホームページ(https://www.jma.go.jp/bosai/amedas/)を加工して作成', warnings: ['気象庁ホームページが内部で使うJSON。API仕様としては公開されておらず、予告なく変わりうる', '品質が0・1以外の値は value を null にしている'], }, }, null, 2));}
await main(process.argv[2]);筆者のWindows環境(Node.js 24.8.0)では、fetch の後に process.exit() を呼ぶと libuv のアサーションで異常終了したため、関数から return で抜ける形にしています。
「金山」では観測所表だけを使い、4件の候補を返して止まりました(2件目以降は抜粋)。
$ node amedas-latest.mjs 金山{ "status": "ambiguous", "input": "金山", "candidates": [ { "code": "12686", "name": "金山", "type": "C", "lat": 43.13833, "lon": 142.41667, "alt": 284 }, { "code": "35116", ... "lat": 38.87833 }, { "code": "36342", ... "lat": 37.47333 }, { "code": "52406", ... "lat": 35.66167 } ] }「東京」は10時30分に実行し、latest_time.txt と point/ の2回だけ取得しました(抜粋)。
$ node amedas-latest.mjs 東京"station": { "code": "44132", "name": "東京", "type": "A", "lat": 35.69167, "lon": 139.75, "alt": 25 }"observedAt": "2026-10-20T10:20:00+09:00""values": { "temp": { "value": 22.1, "aqc": 0, "mark": "" }, "humidity": { "value": 81, "aqc": 0, "mark": "" }, "precipitation1h": { "value": 0, "aqc": 0, "mark": "" }, "wind": { "value": 2, "aqc": 0, "mark": "" }, "windDirection": { "value": 15, "aqc": 0, "mark": "" }, ... }"windDirectionLabel": "北北西""maxTemp": { "value": 23.6, "aqc": 0, "mark": "", "at": "2026-10-20T09:05+09:00" }"minTemp": { "value": 18.6, "aqc": 0, "mark": "", "at": "2026-10-20T05:46+09:00" }"newerKeysInFile": []newerKeysInFile は、latest_time.txt より新しい時刻が地点ファイルにあったときに、その時刻を並べる欄です。前述のように地点ファイルが先に更新されることがあるため、最新値として何を返したかを結果に残します。
AIエージェント・MCPツールにするときの設計
- ツールを2つに分ける。
find_amedas_station(name)は候補だけを返し、get_amedas_latest(code)は観測所番号だけを受け付けます。同名の37組をモデルの推測で1件に決めさせないためです。 - 品質の番号を落とさない。 値と一緒に
aqcと記号を返し、0と1以外はnullにします。降雪量の[0, 6]を「0cm」と答えさせないためです。 - 観測時刻と出典を返す。
observedAt、取得元URL、取得日時を別フィールドにします。型はMCPの出典情報を欠落させないoutputSchema設計に合わせられます。 - 取得の間隔はサーバー側で決める。 観測所表は日単位、観測値は
max-age=60の間は取り直しません。時刻を推測して先のファイルを取らず、404が返ったら再試行せずに止めます。共通の考え方は公共データAPIをMCP化する設計パターンにあります。 - 観測値の範囲だけを答えさせる。 観測値から天気の予想や警戒の呼びかけを作らせません。気象庁ホームページについてのページは、気象業務法第17条(予報業務の許可)と第23条(警報の制限)による制約に注意を促しています。予報が必要なら予報JSONを出典付きで返します。
- 観測値の回答は get_amedas_latest の結果だけを根拠にし、observedAt と出典を併記する- value が null の要素は、mark(休止中・×など)を添えて「値なし」と書く。0 で補わない- 観測所の候補が複数なら候補を示して止まる- 観測値から予報や警戒の呼びかけを作らない- 出典は「出典:気象庁ホームページ(URL)を加工して作成」の形で残すまとめ
- 最新時刻は
latest_time.txt。全国はmap/YYYYMMDDhhmmss.json、1地点はpoint/番号/YYYYMMDD_hh.json。キー不要でGETのみ - 10時00分の値が最新時刻に反映されたのは6分40秒後。地点ファイルはそれより先に新しい時刻を持つことがあった
- 値は
[値, 品質]。0と1以外は使わない。値が0でも品質6は欠測 - 観測所表は1,286地点、緯度経度は
[度, 分]、同名が37組。予報JSONの気温の地点コードはアメダスの番号 - 最高・最低気温の時刻はUTCとして読むと値の推移と合う。公式資料では確認していない
予報の取得は天気予報JSONの使い方、地震の情報は気象庁の地震情報JSONの読み方にあります。ほかの公共データとの使い分けは公共データAPIのガイドを参照してください。
この記事の情報・検証メモ
- 公開日
- 情報確認
- 参考リンク
- 5件
- 更新性
- 定期更新
仕様・料金・提供範囲が変わりやすいテーマは、公開日・更新日・情報確認日を分けて管理します。 導入前には必ず記事末尾の一次情報と公式ドキュメントで最新状況を確認してください。
一次情報・参考リンク
- 気象庁: アメダス(観測値のページ。2026-10-20にページと各JSONを取得) https://www.jma.go.jp/bosai/amedas/
- 気象庁: 地域気象観測システム(アメダス)の解説(観測所数・観測要素・日照時間の推計) https://www.jma.go.jp/jma/kishou/know/amedas/kaisetsu.html
- 気象庁: 過去の気象データ検索「値欄の記号の説明」 https://www.data.jma.go.jp/stats/data/mdrr/man/remark.html
- 気象庁ホームページについて(利用規約・リンク・利用上の注意) https://www.jma.go.jp/jma/kishou/info/coment.html
- デジタル庁: 公共データ利用規約(第1.0版) https://www.digital.go.jp/resources/open_data/public_data_license_v1.0