mcpField
S
searoute

searoute

ローカル
github.com/mayurrawte地図・旅行102 週間前に更新

searoute について

searoute-tsは、座標やUN/LOCODEの港を使って海上ルートを計画するTypeScript/JavaScriptライブラリです。GeoJSONの航路を出力し、通過制限、喫水条件、代替ルート、複数区間の行程、所要時間の推定に対応します。

主な機能

  1. 01海上距離の計算とGeoJSON出力
  2. 02運河・海峡の制限または指定
  3. 03喫水に応じた運河の通過制御
  4. 04代替ルートと複数区間の経路
  5. 05船速に基づく所要時間の推定
  6. 06座標とUN/LOCODEによる入力

活用シーン

  1. 01港間の航行距離と所要時間の比較
  2. 02運河や海峡の通行不可時の迂回
  3. 03船舶の喫水に合った航路の計画

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"mayurrawte-searoute": {
"command": "npx",
"args": [
"-y",
"@searoute-ts/mcp"
]
}
}
}
起動コマンドnpx -y @searoute-ts/mcp

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npm@searoute-ts/mcp0.1.1

ツール

2

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
unitsenumいいえ返される距離の単位。nauticalmiles | kilometers | miles
originanyはいUN/LOCODE 港湾コード文字列、または [longitude, latitude] 座標のペア。
speedKnotsnumberいいえ船舶の速度(ノット単位)。指定すると、時間単位の推定所要時間が返されます。
allowArcticbooleanいいえ氷で閉ざされた北西航路/北東航路の通航を許可します(デフォルトでは禁止)。
destinationanyはい
restrictionsarrayいいえ航路で回避する必要がある指定の海峡。例:["suez","babelmandeb"] を指定すると、紅海の航行が途絶した際に喜望峰経由の航路になります。
includeGeometrybooleanいいえ結果に航路の LineString GeoJSON を含めます。
maxSnapDistanceKmnumberいいえ海上ネットワークからこの距離(km)を超える入力を拒否します。
vesselDraftMetersnumberいいえ船舶の喫水(メートル)。水深が足りない運河は自動的に回避されます。

詳細

searoute-ts

地球上の任意の2地点間の最短海路。 TypeScript / JavaScript 用の海上ルート計画、港間距離、到着予定時刻の推定、航路の可視化を行うライブラリです。2025 年版 Eurostat の海上ネットワークを利用しています。

npm バージョン npm ダウンロード数 CI ライセンス 型定義

npm install searoute-ts
import { seaRoute } from 'searoute-ts';

const route = seaRoute([121.5, 31.0], [4.4, 51.9]);
// Shanghai → Rotterdam → GeoJSON LineString, ~10,664 nm via Suez Canal

🗺️ インタラクティブデモを試す — 地図上の2地点をクリックすると、すべてのオプションをリアルタイムで反映したルートを確認できます。 (ソース)

📏 港間の海上距離 — 主要港間の一般的なルートについて、距離、航行時間、運河の通過情報を確認できます。

通常の JavaScript でも動作します。パッケージにはコンパイル済みの .js と .d.ts 宣言が含まれています。名前の -ts は検索しやすくするためのもので、 TypeScript の使用は必須ではありません。


searoute-ts を選ぶ理由

  • 🚢 現実的な航路。ユーラシア大陸を横切る大圏航路ではありません。
  • 🗺️ GeoJSON を返します。Leaflet、Mapbox、deck.gl、MapLibre にそのまま取り込めます。
  • 🌊 2025 年版 Eurostat marnet。スエズ、パナマ、バブ・エル・マンデブ、 マラッカ、ジブラルタル、ドーバー、キール、コリントス、ベーリング、マゼラン、 北西/北東航路のラベルを明示しています。
  • 🚫 運河と海峡の通航制限。オプションを1つ指定するだけで、紅海の航行障害時に喜望峰経由を強制できます。
  • 📦 船舶喫水に応じた制限。船舶が運河の制限を超える場合、パナマ(15.2 m)、スエズ(20.1 m)、キール (7 m)、コリントス(7.3 m)を自動的に通航不可にします。
  • 🛤️ K 個の最短代替ルート。seaRouteAlternatives は、基準ルートに加えて最大 N 個の現実的な代替ルートを返します。
  • 🧭 複数区間の経由地。港を巡るローテーションや行程には seaRouteMulti を使用できます。
  • ⏱️ 速度から到着予定時刻を計算。speedKnots → durationHours。
  • 🛠️ 最新のツールチェーン。TypeScript 5、ESM + CJS のデュアルビルド、型定義を同梱、Node 18 以上、peer dependency は不要です。

簡単な使用例

基本 — 最短ルート
import { seaRoute } from 'searoute-ts';

const route = seaRoute([-74.04, 40.69], [-0.13, 51.5]); // NYC → London
// route.properties.length  // ≈ 3 362 nm
// route.properties.units   // 'nauticalmiles'
到着予定時刻と単位を指定
seaRoute(shanghai, rotterdam, {
  units: 'kilometers',
  speedKnots: 22,
});
// → 19 753 km, properties.durationHours ≈ 485 h (≈ 20 days)
紅海/スエズの航行障害 — 喜望峰経由を強制
seaRoute(shanghai, rotterdam, {
  restrictions: ['suez', 'babelmandeb'],
});
// → routes via Cape of Good Hope, ~25 800 km
船舶を考慮 — 超大型コンテナ船
seaRoute(shanghai, newYork, {
  vesselDraftMeters: 16,  // exceeds Panama's 15.2 m TFW
});
// → Panama auto-blocked, route goes via Suez
港コード(UN/LOCODE)
import 'searoute-ts/ports'; // enables UN/LOCODE strings on the core API
import { seaRoute } from 'searoute-ts';

seaRoute('CNSHA', 'NLRTM'); // Shanghai → Rotterdam
seaRoute('CNSHA', [4.4, 51.9]); // mixing a code and coordinates is fine too

約 1,600 港のデータセットは searoute-ts/ports サブパスに格納されているため、コア部分を軽量に保てます。インポートするとリゾルバーが登録されます。コードを自分で解決することもできます。

import { lookupPort, resolvePort } from 'searoute-ts/ports';

lookupPort('SGSIN'); // → { code, name: 'Singapore', country, coordinates: [lon, lat] }
resolvePort('SGSIN'); // → [103.85, 1.28]

不明なコードを指定すると UnknownPortError がスローされます。データの出典については、以下の港コードをご覧ください。

バンドルする代わりに CDN から港データセットを読み込む

約 135 KB のデータセットをバンドルしたくない場合は、loadPorts を使って実行時に取得できます。 これは loadNetwork に相当します。 データセットは生の dist/ports.json としても配布されているため、jsDelivr/unpkg からバージョン指定で無料配信できます。

import { seaRoute, loadPorts } from 'searoute-ts';

// Pin a version for reproducibility, or use @latest to always get the newest.
await loadPorts('https://cdn.jsdelivr.net/npm/searoute-ts@latest/dist/ports.json');

seaRoute('CNSHA', 'NLRTM'); // works — the fetched dataset is now registered
https://cdn.jsdelivr.net/npm/searoute-ts@latest/dist/ports.json      # newest
https://cdn.jsdelivr.net/npm/searoute-ts@<version>/dist/ports.json   # frozen/immutable

(dist/ports.json は港コードが追加されたリリース以降に含まれています。再現性を確保するには、そのバージョン以降に固定してください。)

loadPorts は取得したデータセットを登録するため、コード文字列を解決できるようになり、データセットを返します。グローバルの fetch(Node ≥18/ブラウザー)を使用します。上書きするには { fetch } を渡してください。

複数区間/港のローテーション
import { seaRouteMulti } from 'searoute-ts';

seaRouteMulti(
  [shanghai, singapore, mumbai, rotterdam],
  { units: 'kilometers', returnPassages: true },
);
// → one concatenated LineString, total length, union of passages
代替ルート(Yen 方式の運河の組み合わせ)
import { seaRouteAlternatives } from 'searoute-ts';

const alts = seaRouteAlternatives(shanghai, rotterdam, { k: 4 });
//  baseline           19 753 km via Suez
//  no-malacca         20 759 km
//  no-suez            25 315 km (via Panama)
//  no-suez-no-panama  25 845 km (via Cape of Good Hope)
ネットワークを同梱せず、URL から取得する(任意)

ネットワークはデフォルトで同梱されるため、設定なしで seaRoute をオフラインで動作させられます。 約 1 MB のネットワークを同梱したくない場合(たとえば、ブラウザーのバンドルサイズを抑えたい場合や、パッケージをアップグレードせずに更新されたネットワークを使いたい場合)は、実行時に取得し、既存の network オプションに渡してください。

import { seaRoute, loadNetwork } from 'searoute-ts';

// CORS-enabled, served from GitHub Pages (or point at your own host / a CDN).
const network = await loadNetwork('https://mayurrawte.github.io/searoute-ts/marnet.json');

const route = seaRoute(shanghai, rotterdam, { network });

非同期なのは取得処理だけで、seaRoute 自体は同期処理のままです。loadNetwork はグローバルの fetch を使用します(Node ≥18 およびすべてのブラウザー)。独自のものを指定するには { fetch } を渡してください。これは完全にオプトイン方式なので、使わなければ何も変わりません。

どの方法を使えばよいですか?
方法使用方法データのバージョンオフラインで動作最適な用途
同梱(デフォルト)seaRoute(a, b) — network は不要インストール済みパッケージのバージョンに固定✅ほとんどのユーザー。設定不要で、決定論的
URL から最新バージョンを取得loadNetwork('…/marnet.json')常にホストされている最新バージョン❌ ネットワーク接続が必要アップグレードせずに常に最新のデータを利用
CDN から特定バージョンを取得loadNetwork('https://cdn.jsdelivr.net/npm/[email protected]/…')固定(不変)❌ ネットワーク接続が必要再現可能なビルド
ホストされているネットワークのバージョン管理

バージョンはURLを選んで指定します。

  • @latest / ローリング — 上記の GitHub Pages URL では、常に最新のネットワークが配信されます。便利ですが、予告なく内容が変わる場合があります。

  • 固定・不変 — パッケージは npm 上にあるため、jsDelivr と unpkg では、公開済みのすべてのバージョンが自動的に配信され、バージョンごとに不変の URL が使えます。

    https://cdn.jsdelivr.net/npm/searoute-ts@latest/dist/marnet.json   # newest
    https://cdn.jsdelivr.net/npm/searoute-ts@2/dist/marnet.json        # newest 2.x
    https://cdn.jsdelivr.net/npm/[email protected]/dist/marnet.json    # frozen
    

固定 URL は変わらないため、ルートの再現性を保てます。(ネットワークが独立したアセットとして公開されると、これらのスタンドアロン JSON CDN パスがパッケージとともに利用可能になります。issue #10 を参照してください。それまでは GitHub Pages URL を使用してください。)

本番環境では、ネットワークが更新されたときに距離が変わらないよう、固定 URL(またはデフォルトの同梱ネットワーク)の使用をおすすめします。

より高解像度のネットワーク(任意)

同梱ネットワークは、Eurostat の 100 km marnet_plus です。Eurostat はさらに高解像度のデータも公開しており、ダウンロードサイズが大きくなり、最初のルート検索時のグラフ構築がわずかに遅くなる代わりに、沿岸ルートの精度と短い区間の忠実度が向上します。中程度の解像度のうち 2 種類はサブパスエクスポートとして提供されるため、インポートした場合にのみその分のデータを読み込みます。

import { DEFAULT_MARNET } from 'searoute-ts/marnet-20km'; // or 'searoute-ts/marnet-50km'
import { seaRoute } from 'searoute-ts';

seaRoute(origin, destination, { network: DEFAULT_MARNET });

同梱のデフォルトと同様に、各バリエーションは共有 dist/data/marnet-<res>.cjs アセットとして一度だけ提供され、CJS と ESM のビルドの両方が実行時にこれを読み込みます。そのため、バリエーションをインポートしても、ビルド間でネットワークが重複することはありません。

インポート解像度セグメント数JSON サイズgzip 圧縮後沿岸精度
searoute-ts(同梱のデフォルト)100 km9,847約 1.3 MB約 0.18 MB基準 — グローバルなルート検索に適しています
searoute-ts/marnet-50km50 km15,498約 1.9 MB約 0.27 MB適度に精度が向上
searoute-ts/marnet-20km20 km29,581約 3.6 MB約 0.51 MB沿岸の区間が目に見えて細かくなります
loadNetwork 経由(下記参照)10 km48,301約 5.9 MB約 0.84 MB高精度 — ダウンロードサイズは大きめ
loadNetwork 経由(下記参照)5 km72,478約 9.0 MB約 1.24 MB最高精度 — ダウンロードサイズは最大

10 km と 5 km のネットワークは、同梱するとインストールサイズの大部分を占めるほど大きいため、パッケージには含まれていません。Eurostat のソースから scripts/build-marnet.cjs を使って生成し(GDAL による変換方法はスクリプトのヘッダーに記載されています)、生成した JSON をホストして、loadNetwork で読み込んでください。または、任意の FeatureCollection<LineString> を network オプションに直接渡すこともできます。

出力形式

{
  type: 'Feature',
  geometry: { type: 'LineString', coordinates: [[lon, lat], ...] },
  properties: {
    length: number,                    // in `units`, in-water only
    units: 'nauticalmiles' | 'kilometers' | 'miles' | ...,
    bbox: [minLon, minLat, maxLon, maxLat],
    greatCircleLength: number,         // haversine between inputs, same units
    detourRatio: number,               // routeKm / greatCircleKm
    originSnapKm: number,              // input → network distance
    destinationSnapKm: number,
    durationHours?: number,            // if `speedKnots` set
    passages?: ('suez' | 'panama' | ...)[],  // if `returnPassages: true`
    ecaKm?: number,                    // if `emissions` + `searoute-ts/eca` imported
    ecaFraction?: number,              // ecaKm / length (0–1)
    co2eTonnes?: number,               // if `emissions` + `vesselClass`/factor
  }
}

length は、スナップされたネットワーク頂点間の距離です。入力地点からネットワークまでの区間(originSnapKm、destinationSnapKm。いずれも常に km 単位)は含まれません。appendOriginDestination: true を指定しても同様で、このオプションはラインに元の地点を追加するだけです。出発地から目的地までの距離を求めるには、自分で加算してください。

const { length, originSnapKm, destinationSnapKm } = seaRoute(a, b, { units: 'kilometers' }).properties;
const doorToDoorKm = originSnapKm + length + destinationSnapKm;

ネットワークの解像度(デフォルトでは約 100 km、searoute-ts/marnet-20km では約 20 km)より短い区間では、スナップされた頂点が入力地点より近くに位置する場合があり、length が greatCircleLength を下回ることがあります(detourRatio < 1)。両方の入力が同じ頂点にスナップされた場合は、NoRouteError がスローされます。

全オプション

seaRoute(origin, destination, {
  units:                   'nauticalmiles',          // any Turf unit
  restrictions:            ['suez', 'babelmandeb'],  // block passages (see table below)
  via:                     ['panama'],               // require passages (inverse of restrictions)
  allowArctic:             false,                    // default — blocks NWP & NEP
  vesselDraftMeters:       15,                       // auto-restrict canals
  speedKnots:              22,                       // → properties.durationHours
  appendOriginDestination: false,                    // prepend/append raw inputs
  returnPassages:          true,                     // populate properties.passages
  maxSnapDistanceKm:       50,                       // SnapFailedError if exceeded
  network:                 customMarnet,             // BYO FeatureCollection
  antimeridian:            'split',                  // 'unwrap' | 'split' dateline handling
  emissions:               true,                     // → properties.ecaKm / co2eTonnes
  vesselClass:             'panamax',                // CO₂e estimate class
  co2eFactorKgPerKm:       225,                      // override the class factor
  glecInflation:           0.15,                     // +15% distance for CO₂e (GLEC)
});

入力には、[lon, lat] 配列、GeoJSON の Feature<Point>、単独の Point オブジェクト、または searoute-ts/ports をインポートした後の UN/LOCODE 文字列(例:'CNSHA')を使用できます。

日付変更線の処理

±180°の子午線を横切るルート(例:横浜 → LA)は、デフォルトでは [-180, 180] の範囲に折り返されるため、多くの地図レンダラーでは地図全体を横切る直線として描画されます。地図表示に適したジオメトリを取得するには、antimeridian を指定します。

seaRoute(yokohama, la, { antimeridian: 'unwrap' }); // continuous LineString (may exceed ±180)
seaRoute(yokohama, la, { antimeridian: 'split' });  // MultiLineString cut at ±180 (RFC 7946)

'unwrap' は経度を 360° の倍数だけずらし、ラインが日付変更線をまたいで飛ばないようにします(MapLibre/Leaflet/Deck.gl に最適です)。'split' はルートを ±180° の位置で分割して MultiLineString にし、すべての座標を範囲内に保ちます。どちらも seaRoute と seaRouteMulti に適用されます。どちらを指定しても properties.length は変わりません。

海峡を経由するルートの指定(via)

restrictions は海峡を通行禁止にし、via はその逆で、海峡の通過を必須にします。明示的なルートを比較する場合(例:「スエズ運河経由」と「喜望峰経由」)、またはアジアとヨーロッパの間で太平洋とパナマ運河を経由するルートを強制する場合に使用します。

seaRoute('CNSHA', 'NLRTM', { via: ['suez'] });   // through Suez (the default)
seaRoute('CNSHA', 'NLRTM', { via: ['panama'] });  // across the Pacific + Panama instead

via には restrictions と同じ海峡名を指定でき、複数の海峡を指定した場合は指定順に通過します。マルチレッグ処理を使って各海峡の位置を経由する 出発地 → 海峡 → 目的地 のルートを計算するため、ほかのオプションと組み合わせて使用できます。via に指定した海峡が通行禁止になることはありません(via: ['northeast'] は、allowArctic を別途指定しなくても北東航路を通過します)。同じ海峡を via と restrictions の両方に指定すると矛盾が生じ、NoRouteError がスローされます。

排出量と ECA/SECA レポート

emissions: true を指定すると、properties に概算値が 2 つ追加されます。

import 'searoute-ts/eca';                 // load the ECA/SECA zones (enables ecaKm)
import { seaRoute } from 'searoute-ts';

const r = seaRoute('CNSHA', 'NLRTM', {
  emissions: true,
  vesselClass: 'panamax',                 // → co2eTonnes
});
r.properties.ecaKm;        // km of the route inside emission-control zones
r.properties.ecaFraction;  // that as a fraction of route length (0–1)
r.properties.co2eTonnes;   // rough CO₂e estimate for the voyage
  • ecaKm — ECA/SECA 排出規制区域(バルト海、北海、地中海、北米、米国カリブ海)のルート距離です。燃料の種類やコストに影響します。ゾーンはコアを軽量に保つため、searoute-ts/eca サブパスのエクスポートに含まれており、インポートすると登録されます。これらは IMO MARPOL 附属書 VI の区域をバウンディングボックスで近似したもので、概算には適していますが、規制への準拠確認には使えません。registerEcaZones を使って、より精度の高いポリゴンに置き換えてください。
  • co2eTonnes — 距離 × 船舶クラス係数 による意図的に単純化された推定値で、認証済みの数値ではありません。係数は代表的な燃料消費量と IMO の HFO CO₂ 換算係数から透明性をもって算出しています(VESSEL_CLASSES を参照)。co2eFactorKgPerKm で上書きできます。GLEC は、実際の経路との差異を考慮して最短経路の距離を約 15 % 増やすことを推奨しています。glecInflation: 0.15 を指定してください。

制限可能な海峡

最初の12か所は、Eurostat marnetでネイティブにラベル付けされています(フィーチャーのpass属性と完全一致)。残りの4か所はバウンディングボックスを使って検出されます。

名前種類備考
suezネイティブスエズ運河
panamaネイティブパナマ運河
gibraltarネイティブジブラルタル海峡
babelmandebネイティブバブ・エル・マンデブ(別名 babalmandab)
malaccaネイティブマラッカ海峡
doverネイティブドーバー海峡
kielネイティブキール運河
corinthネイティブコリントス運河
beringネイティブベーリング海峡
magellanネイティブマゼラン海峡
northwestネイティブ北西航路(デフォルトで通行不可)
northeastネイティブ北東航路(デフォルトで通行不可)
bosporusバウンディングボックスボスポラス海峡
ormuzバウンディングボックスホルムズ海峡
sundaバウンディングボックススンダ海峡
cape_hornバウンディングボックスホーン岬地域

北西航路と北東航路は、多くのアジア ↔ ヨーロッパ航路で数学的には最短経路ですが、年間の大半は氷に阻まれるため、デフォルトで通行不可です。allowArctic: trueで有効にできます。

業界の距離データと照合済み

実際の航路12件について、公開されているSearoutes / Sea-Distancesの数値との差は±10%以内です。

航路searoute-ts業界参考値
上海 → ロッテルダム(スエズ)19 753 km~19 300 km
シンガポール → ロッテルダム(スエズ)15 630 km~15 500 km
ムンバイ → ロッテルダム(スエズ)11 918 km~11 800 km
NY → ロッテルダム6 227 km~6 200 km
NY → LA(パナマ)9 154 km~9 100 km
横浜 → LA9 145 km~8 800 km
シンガポール → LA(太平洋横断)14 364 km~14 300 km
カルデラ(CL)→ バイアブランカ(AR)4 810 km~5 180 km

すべてのチェックはテストスイートで成功します。

エラー

  • SnapFailedError — 入力をmaxSnapDistanceKm以内でネットワークに投影できません。.side: 'origin' | 'destination'および.distanceKm: numberを持ちます。
  • NoRouteError — スナップされた出発地と目的地の間に経路がありません(例:通行可能な運河がすべて通行止め)。

APIリファレンス

import {
  seaRoute,                  // single shortest route
  seaRouteMulti,             // ordered waypoints (multi-leg)
  seaRouteAlternatives,      // K-shortest alternatives
  loadNetwork,               // optional: fetch a network from a URL/CDN
  CANAL_MAX_DRAFT_M,         // { panama: 15.2, suez: 20.1, kiel: 7, corinth: 7.3 }
  DEFAULT_MARNET,            // bundled FeatureCollection<LineString>
  PASSAGE_BBOXES,            // passage bbox lookup
  clearFinderCache,          // drop the PathFinder cache (tests / hot reload)
  SnapFailedError,
  NoRouteError,
  UnknownPortError,          // thrown for unresolved UN/LOCODE strings
  registerPortResolver,      // plug in a custom port dataset
  // types
  type Passage,
  type Antimeridian,
  type SeaRouteOptions,
  type SeaRouteFeature,
  type SeaRouteMultiFeature,
  type SeaRouteProperties,
  type LoadNetworkOptions,
  type MarnetNetwork,
  type MarnetProperties,
} from 'searoute-ts';

import {
  lookupPort,                // UN/LOCODE → { code, name, country, coordinates }
  resolvePort,               // UN/LOCODE → [lon, lat]
  PORTS,                     // the raw dataset (Record<code, PortRecord>)
  PORT_COUNT,
  type Port,
  type PortRecord,
} from 'searoute-ts/ports';

港コード(UN/LOCODE)

出発地と目的地には、座標の代わりにUN/LOCODE文字列(例:'CNSHA')を指定できます。港データセットはsearoute-ts/portsサブパスのエクスポートとして提供されるため、利用する場合にのみ読み込まれます。このサブパスをインポートすると(エクスポートの利用の有無にかかわらず、副作用のみを目的とする場合も含めて)、リゾルバーがコアに登録され、seaRoute('CNSHA', 'NLRTM')が動作します。

  • 約1,600の港。UN/LOCODE(主要コードと別名)をキーとして登録されています。
  • ソース: marchah/sea-ports(MIT)。このデータ自体はUN/LOCODEを基にしています。scripts/build-ports.cjsで再生成できます。
  • 座標は概算です(港のある都市単位)。ルーティングエンジンがネットワーク上にスナップするため、距離や可視化には十分です。
  • 不明または形式が不正なコードを指定すると、UnknownPortErrorがスローされます。

AI エージェント(MCP)から使用する

付属のModel Context Protocolサーバー、 @searoute-ts/mcp(ソース) を使うと、AI エージェント(Claude Desktop、claude CLI など)が推測ではなく実際の海路を計算できます。「上海からロッテルダムまで海路でどれくらいの距離ですか。スエズ運河を避けると?」と尋ねると、ライブラリが直接呼び出されます。sea_route と sea_route_alternatives の2つのツールを公開し、港コード('CNSHA')または座標を受け付けます。

claude mcp add searoute -- npx -y @searoute-ts/mcp

任意の MCP クライアントの設定に追加することもできます。

{
  "mcpServers": {
    "searoute": {
      "command": "npx",
      "args": ["-y", "@searoute-ts/mcp"]
    }
  }
}

ツールの詳細については、サーバーの READMEをご覧ください。鉄道区間には、@railroute-ts/mcpを併せて追加してください(claude mcp add railroute -- npx -y @railroute-ts/mcp)。

マルチモーダル:鉄道区間を追加する(railroute-ts)

海上距離だけで貨物輸送全体を表せることはほとんどありません。関連ライブラリのrailroute-tsは、OpenStreetMap の鉄道ネットワーク(ヨーロッパ分を同梱、同じ API 形式、同じ GeoJSON 出力)を使って経路を計算します。そのため、港から内陸への見積もりや、GLEC/CountEmissions 形式のレポートも、呼び出しを1回追加するだけで作成できます。

import 'searoute-ts/ports';
import { seaRoute } from 'searoute-ts';
import { railRoute } from 'railroute-ts';
import { EUROPE_NETWORK } from 'railroute-ts/networks/europe';

const sea  = seaRoute('CNSHA', 'NLRTM', { units: 'kilometers', emissions: true, vesselClass: 'panamax' });
const rail = railRoute([4.47, 51.92], [8.92, 44.41], { network: EUROPE_NETWORK, speedKmh: 60 }); // Rotterdam → Genoa

sea.properties.length;        // ≈ 19,753 km  Shanghai → Rotterdam via Suez
sea.properties.co2eTonnes;    // ≈ 4448 t CO₂e (rough, see Emissions above)
rail.properties.length;       // ≈ 1,180 km  Rotterdam → Genoa via the Gotthard base tunnel
rail.properties.gaugeChanges; // 0 — standard gauge all the way

npm install railroute-ts — ドキュメントとインタラクティブデモをご覧ください。どちらのライブラリにも MCP サーバーが用意されているため、AI エージェントはsea_route → rail_routeを連携させて、戸口から戸口までの距離を計算できます(以下を参照)。

仕組み

グラフデータ、スナップ処理、Dijkstra、通行制限、日付変更線への対応、喫水のロジック、代替ルートについて詳しく解説する2ページの資料をDOCS.mdでご覧いただけます。

FAQ

これは航海用ですか? いいえ。このルートは可視化や距離・所要時間の概算に適したネットワーク経路であり、船舶の操船用ではありません。

気象を考慮したルート設定に対応していますか? いいえ。気象を考慮したルート設定については、VISIR-2をご覧ください。

アジアからヨーロッパへのルートがベーリング海峡を通るのはなぜですか? デフォルトでは通りません。北西航路と北東航路は通行止めになっています。これらを有効にするには、allowArctic: trueを渡してください。

独自のネットワークを使えますか? はい。seaRoute(origin, destination, { network })を使います。内陸水路や AIS 由来のカスタムグラフに便利です。より高解像度の Eurostat データ(5/10/20/50 km)については、高解像度ネットワーク(オプション)をご覧ください。20 km と 50 km のデータはサブパスエクスポートとして提供されています。

紅海/スエズ危機に対応していますか? はい。喜望峰経由のルートを強制するには、restrictions: ['suez', 'babelmandeb']を渡してください。

1.x でCannot find module '…/searoute-ts/dist/lib/utils'が発生します。 1.x(1.2.1 まで)では、"main"に拡張子のないインポートを含む ESM ビルドが同梱されていたため、パッチを適用しないと通常の Node では読み込めませんでした。2.0 で修正されています。^1の範囲指定ではこのバージョンが選ばれないため、searoute-ts@^2をインストールしてください。アップグレード時は、名前付きインポートのimport { seaRoute }を使用してください。エラー時はnullを返すのではなく、NoRouteError/SnapFailedErrorがスローされるようになりました。また、1.x では海里の長さが過大に計算されていたため、値が約24%小さくなっています。CHANGELOGにある2.0.0の移行に関する注記をご覧ください。

大円距離は日付変更線を越える場合も正確ですか? はい。marnet は太平洋が連結グラフになるよう正規化されており、すべての距離は内部で haversine を使って計算されます。

バンドルサイズはどれくらいですか? 実行時にインポートするものは小さく、コアと同梱の100 km marnet(約1.1 MB の JSON。各ビルドにインライン化されるのではなく、両方のビルドで読み込まれる共有アセットdist/data/marnet.cjsとして一度だけ同梱)で構成されます。ツリーシェイキングに対応しているため、オプションのsearoute-ts/marnet-20km/marnet-50kmネットワークはインポートした場合にのみ読み込まれます。ただし、npm の tarball のサイズには追加されます。これらを含めると、パッケージのサイズは圧縮時で約1.1 MB、展開時で約7 MBです(各バリアントは共有アセット1つであり、ビルドごとに重複しません)。インストールサイズを増やさずにより高解像度のネットワークを使いたい場合は、それらを生成してホストし、代わりにloadNetworkを使用してください。

クレジット

  • 海上ネットワーク — Eurostat searoute v3.5 (EUPL-1.2)。Oak Ridge National Labs の Global Shipping Lane Network に ヨーロッパの AIS データを追加したものです。
  • Dijkstra — Per Liedman による geojson-path-finder@2。
  • searoute-py(Apache-2.0)に着想を得ています。
  • JavaScript への最初の移植 — @johnx25bd。
  • 地理空間プリミティブ — Turf.js。

ライセンス

MIT © Mayur Rawte

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。