Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
作者による説明(英語の原文)
Real shortest sea routes between ports: distance, canals/straits, GeoJSON. UN/LOCODE aware.
この3つを1つのスコアにまとめることはしません。意見、測定、人気はそれぞれ別のものだからです。
このサーバーのやさしい解説はまだ書いていません。以下はレジストリから読み取った事実です。
使っているAIアプリを選んで、設定をコピーしてください。
必要なもの
どのアプリを使っていますか?
上でアプリを選んでください。選んだアプリを覚えておくので、次からはボタンに「…にインストール」と表示されます。
Claude Desktop → Settings → Developer → Edit Config を開き、claude_desktop_config.json にこれを貼り付けます
{
"mcpServers": {
"searoute": {
"command": "npx",
"args": [
"-y",
"@searoute-ts/mcp"
]
}
}
}ターミナルでこれを実行します
claude mcp add searoute -- npx -y @searoute-ts/mcpプロジェクトの .cursor/mcp.json、または ~/.cursor/mcp.json に貼り付けます
{
"mcpServers": {
"searoute": {
"command": "npx",
"args": [
"-y",
"@searoute-ts/mcp"
]
}
}
}ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。
プロジェクトの .vscode/mcp.json に貼り付けます
{
"servers": {
"searoute": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@searoute-ts/mcp"
]
}
}
}ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。
これはパソコンで動くサーバーですが、ChatGPTがつなげるのはインターネット上のサーバーだけです。ほかのアプリを選んでください。
選んだアプリは、この端末のCookieに保存されます。アカウントは不要です。
この設定は、作者のレジストリ登録情報から作成しています。READMEと違う場合は、READMEに従ってください。
パソコンで動くサーバーです。インストールすると、ツール一覧がAIアプリに表示されます。
誰でも見られる情報をチェックしており、コードは読んでいません。当てはまらない項目は数に入れていません。 · 2026年11月7日にチェック
レジストリ名は、リポジトリを所有するGitHubアカウント mayurrawte で確認済みです
このリポジトリはまだGitHubから読み取っていません
このリポジトリはまだGitHubから読み取っていません
これはパソコンで動くため、インターネット上のエンドポイントはありません
パソコンで動き、代わりにローカルの設定を使います
パソコンで動くサーバーです。ツール一覧を読み取れるのは、インターネット上のエンドポイントがある場合だけです
レジストリでこのカテゴリにある有効なすべてのサーバーと比較しています。スターは、公開者がリポジトリの所有者である場合だけ数えます。
当てはまる基本チェック1項目のうち1項目に合格しました。コードは読んでいません。キーやトークンを追加する前に、サーバーがどんなアクセスを求めているかを確認し、必要な権限だけを持つキーを使ってください。
レジストリには必須のキーは載っていません。ただし、最初に使うときにサインインを求めるサーバーもあります。
あなたのパソコンで動きます。必要なときにAIアプリが起動し、データは作者のサーバーを通りません(サーバー自体がオンラインサービスを呼び出す場合を除きます)。
GitHubリポジトリの最終更新は–、最新バージョン(0.1.1)がレジストリに届いたのは2 か月前です。
Claude Desktop、Claude Code、Cursor、VS CodeなどのMCP対応アプリで使えます。パソコンにNode.jsも必要です。
同じカテゴリには:Spec Driven Development, Remote Desktop Commander, Detailing Manager
同じカテゴリで、ほかの作者が作ったサーバー。スターの多い順。
カードの見方:★ GitHubスターi3つの柱:レビュー · チェック · 利用状況i更新=最新バージョンをレジストリに公開した日i
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Connect your auto detailing studio's tasks, cars, clients and revenue to Claude or ChatGPT.
作者のリポジトリから書かれたとおりにコピーしたものです。PopNx MCPは内容を確認・推奨していません。HTML、画像、スクリプトは取り除いています。リンクはこのサイトの外へ移動します。
Shortest sea route between any two points on Earth. A TypeScript / JavaScript
library for maritime route planning, port-to-port distance, ETA estimation, and
shipping-lane visualisation — powered by the 2025 Eurostat maritime network.
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
🗺️ [Try the interactive demo](https://mayurrawte.github.io/searoute-ts/) — click two points on a map and see the route, with all options live. (source)
📏 [Port-to-port sea distances](https://mayurrawte.is-a.dev/searoute-ts/routes/) — distance, sailing time and canal passages for common routes between major ports.
Works from plain JavaScript too — the package ships compiled
.jsplus
.d.tsdeclarations. The-tsin the name is for searchability, not a
language requirement.
seaRouteAlternatives returns the baseline plus up to N realistic alternatives.seaRouteMulti for port rotations and itineraries.speedKnots → durationHours.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
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
The ~1 600-port dataset lives behind the searoute-ts/ports subpath so the core stays lean — importing it registers the resolver. You can also resolve codes yourself:
import { lookupPort, resolvePort } from 'searoute-ts/ports';
lookupPort('SGSIN'); // → { code, name: 'Singapore', country, coordinates: [lon, lat] } resolvePort('SGSIN'); // → [103.85, 1.28]
Unknown codes throw UnknownPortError. See Port codes below for provenance.
Don't want to bundle the ~135 KB dataset? Fetch it at runtime with loadPorts — the analog of loadNetwork. The dataset also ships as a raw dist/ports.json, so jsDelivr/unpkg serve it versioned for free:
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@ /dist/ports.json # frozen/immutable
(dist/ports.json ships from the release that adds port codes onward — pin any version at or after it for reproducibility.)
loadPorts registers the fetched dataset (so code strings resolve) and returns it. It uses the global fetch (Node ≥18 / browsers); pass { fetch } to override.
import { seaRouteMulti } from 'searoute-ts';
seaRouteMulti( [shanghai, singapore, mumbai, rotterdam], { units: 'kilometers', returnPassages: true }, ); // → one concatenated LineString, total length, union of passages
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)
The network is bundled by default, so seaRoute works offline with zero setup. If you'd rather not ship the ~1 MB network (e.g. to trim a browser bundle, or to use an updated network without upgrading the package), fetch it at runtime and pass it via the existing network option:
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 });
Only the fetch is async — seaRoute itself stays synchronous. loadNetwork uses the global fetch (Node ≥18 and all browsers); pass { fetch } to supply your own. This is purely opt-in; nothing changes if you don't use it.
| Approach | How | Data version | Works offline | Best for |
|---|---|---|---|---|
| Bundled (default) | seaRoute(a, b) — no network | pinned to your installed package | ✅ | Most users; zero config, deterministic |
| Latest via URL | loadNetwork('…/marnet.json') | always the newest hosted | ❌ needs network | Always-current data without upgrading |
| Pinned via CDN | loadNetwork('https://cdn.jsdelivr.net/npm/searoute-ts@2.0.1/…') | frozen (immutable) | ❌ needs network | Reproducible builds |
You choose the version by choosing the 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/searoute-ts@2.0.1/dist/marnet.json # frozen
A pinned URL never changes, so your routes stay reproducible. (These standalone-JSON CDN paths land with the package once the network ships as a separate asset — see issue #10; until then, use the GitHub Pages URL.)
For production, prefer a pinned URL (or just the bundled default) so your distances don't shift when the network is updated.
The bundled network is Eurostat's 100 km marnet_plus. Eurostat also publishes finer resolutions, which give more accurate coastal routing and shorter-hop fidelity at the cost of a larger download and slightly slower first-route graph construction. Two moderate resolutions ship as subpath exports so you only pay for them if you import them:
import { DEFAULT_MARNET } from 'searoute-ts/marnet-20km'; // or 'searoute-ts/marnet-50km'
import { seaRoute } from 'searoute-ts';
seaRoute(origin, destination, { network: DEFAULT_MARNET });
Like the bundled default, each variant ships once as a shared dist/data/marnet- .cjs asset that both the CJS and ESM builds load at runtime, so importing a variant doesn't duplicate the network across builds.
| Import | Resolution | Segments | JSON size | gzipped | Coastal accuracy |
|---|---|---|---|---|---|
searoute-ts (bundled default) | 100 km | 9,847 | ~1.3 MB | ~0.18 MB | Baseline — good for global routing |
searoute-ts/marnet-50km | 50 km | 15,498 | ~1.9 MB | ~0.27 MB | Modest step up |
searoute-ts/marnet-20km | 20 km | 29,581 | ~3.6 MB | ~0.51 MB | Noticeably finer coastal hops |
via loadNetwork (see below) | 10 km | 48,301 | ~5.9 MB | ~0.84 MB | High — larger download |
via loadNetwork (see below) | 5 km | 72,478 | ~9.0 MB | ~1.24 MB | Highest — largest download |
The 10 km and 5 km networks are large enough that bundling them would dominate the install, so they are not shipped in the package. Generate them from the Eurostat source with scripts/build-marnet.cjs (the script header documents the GDAL conversion), host the resulting JSON, and load it with loadNetwork — or pass any FeatureCollection to the network option directly.
{
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 runs between the two snapped network vertices. It does not include the legs from your inputs to the network (originSnapKm, destinationSnapKm, always in km), even with appendOriginDestination: true, which only adds the raw points to the line. For a door-to-door figure, add them yourself:
const { length, originSnapKm, destinationSnapKm } = seaRoute(a, b, { units: 'kilometers' }).properties;
const doorToDoorKm = originSnapKm + length + destinationSnapKm;
On hops shorter than the network resolution (~100 km by default, ~20 km with searoute-ts/marnet-20km), the snapped vertices can sit closer together than the inputs, so length can come out below greatCircleLength (detourRatio < 1). If both inputs snap to the same vertex, `NoRouteErro
冒頭だけを表示しています。続きはリポジトリで読めます