UNPKG

clinicaltrialsgov-mcp-server

Version:

Search ClinicalTrials.gov trials, retrieve study details and results, and match patients to eligible trials via MCP. STDIO or Streamable HTTP.

37 lines 1.61 kB
/** * @fileoverview Geographic helpers shared by location-aware tools — great-circle * distance and parsing of the `geoFilter` center coordinates. * @module mcp-server/tools/utils/geo-helpers */ /** Mean Earth radius in miles, used by the Haversine formula. */ export const EARTH_RADIUS_MI = 3958.7613; /** Great-circle distance in miles between two lat/lon points (Haversine). */ export function haversineMi(a, b) { const toRad = (d) => (d * Math.PI) / 180; const dLat = toRad(b.lat - a.lat); const dLon = toRad(b.lon - a.lon); const lat1 = toRad(a.lat); const lat2 = toRad(b.lat); const h = Math.sin(dLat / 2) ** 2 + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) ** 2; return 2 * EARTH_RADIUS_MI * Math.asin(Math.min(1, Math.sqrt(h))); } /** * Extract the center coordinates from a `geoFilter` value of the form * `distance(lat, lon, radius)`. The radius (with an optional `mi`/`km` suffix) is * already applied by the upstream query, so only lat/lon are returned here — used * to re-rank a study's locations by proximity. Tolerates surrounding whitespace. * Returns undefined when the value isn't a parseable distance expression. */ export function parseGeoFilterCenter(geoFilter) { if (!geoFilter) return; const match = geoFilter.match(/distance\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*,/i); if (!match) return; const lat = Number(match[1]); const lon = Number(match[2]); if (!Number.isFinite(lat) || !Number.isFinite(lon)) return; return { lat, lon }; } //# sourceMappingURL=geo-helpers.js.map