gagelink
gagelink
AI 에이전트를 위한 수문 데이터. USGS, NOAA, SWOT에서 제공하는 하천 수위, 유량, 홍수 예보, 수질, 배수 유역, 위성 수면 표고. 모든 값은 단위, 측정 기준면, 시간대, 그리고 기록이 잠정인지 승인인지를 함께 지닙니다.
mcp-name: io.github.Adeniyikayodee/gagelink
프리 알파. API는 변경될 예정입니다.
MCP 서버로 실행하기
{
"mcpServers": {
"gagelink": {
"command": "uvx",
"args": ["--from", "gagelink", "gagelink-mcp"]
}
}
}시작하는 데 계정이 필요하지 않습니다. api.waterdata.usgs.gov/signup에서 받은 무료 키는 시간당 50회 요청 한도를 1,000회로 올려 줍니다. GAGELINK_API_KEY로 설정하세요.
또는 라이브러리로 사용:
pip install gagelinkRelated MCP server: Environment Agency Flood Monitoring MCP Server
답하는 질문
수위표에서 강의 수위는 얼마이며, 홍수위와 어떻게 비교됩니까?
수면과 측량된 제방 정상 사이의 여유고는 얼마입니까?
지금 유량은 얼마이며, 기록상 최대 유량의 몇 분율입니까?
향후 며칠 동안의 예보는 어떠하며, 홍수 등급을 넘어섭니까?
이 지점의 상류 또는 하류에는 강을 따라 무엇이 있습니까?
이 지점으로 배수되는 유역의 크기는 얼마입니까?
이 관측소는 특정 날짜 범위 동안 무엇을 기록했으며, 그 기록이 이후에 수정되었습니까?
수위표가 없는 강의 수면 표고는 얼마입니까?
측정값이 잠정인지 승인된 것인지, 그리고 얼마나 오래된 것입니까?
거부하는 것, 그리고 그것이 핵심인 이유
수위표 높이는 해수면이 아니라 관측소 자체의 기준면에서 측정됩니다. 측량된 표고에서 이를 빼면 여유고처럼 보이는 숫자가 나오지만, 수십 피트만큼 틀리며 제방이 안전하다고 판단하는 방향으로 틀립니다. 두 값 모두 피트 단위의 길이이므로 차원적으로 구분되지 않아 어떤 단위 라이브러리도 이를 잡아내지 못합니다.
이 패키지는 그 뺄셈에 답하는 대신 거부하며, describe_location은 그 뺄셈을 잘 정의되게 만드는 오프셋을 반환합니다. 지오이드 기준인 위성 표고와 그 뒤에 측정값이 없을 수 있는 모의 유량에도 동일하게 적용됩니다.
이유
수문 서비스는 데이터를 올바르게 사용하는 데 필요한 모든 것을 이미 공개합니다. 유량은 단위를 명시하고, 수위는 측정 기준면을 명시하며, 측정값은 잠정인지 승인인지 명시하고, 타임스탬프는 오프셋을 명시합니다. 클라이언트는 보통 숫자만 파싱하고 나머지는 버리며, 오류는 그로부터 발생합니다.
실패는 측정 가능합니다. 11개 모델에 걸친 4,288회 실행 벤치마크에서 quantity-guard는 컴퓨팅 도구에 도달한 모든 모델이 거의 모든 실행에서 초당 입방피트로 공개된 유량을 초당 입방미터로 선언된 매개변수에 변환 없이 보냈고, 출력에 이를 나타내는 아무것도 없이 35.3배나 큰 답을 냈다는 것을 발견했습니다. 11개 중 7개는 로컬 수위표 기준면의 수위를 NAVD88 표고와 차분하여 그 결과를 여유고로 보고했습니다.
gagelink는 메타데이터를 유지한 채 데이터를 검색하고, 에이전트의 도구가 호출되는 지점에서 quantity-guard를 사용하여 이를 강제합니다.
현재 API 표면
from gagelink import Service
service = Service(api_key="...") # free key, see below
page, retrieval = service.items(
"latest-continuous",
monitoring_location_id="USGS-07374000",
parameter_code="00060",
)
retrieval.record() # what a replay needs: url, params, time, status, sha256
retrieval.quota # Quota(limit=1000, remaining=999)items는 페이지 단독이 아니라 파싱된 페이지와 그것을 가져온 기록을 함께 반환합니다. 그 이유는 그것을 생성한 요청 없이 답에 도달한 숫자는 재생할 수 없고, 유일한 진입점에서 이 둘을 짝지어 두는 것이 기록하는 것을 기억하는 것보다 저렴하기 때문입니다.
페이로드는 자신의 기준 좌표계를 지니는 물리량이 됩니다:
from gagelink import location_from, readings_from
page, _ = service.items("monitoring-locations", id="USGS-06730500")
station = location_from(page["features"][0])
station.register() # its datum, and the offset where one is published
observations, _ = service.items("latest-continuous", monitoring_location_id=station.id)
readings = {r.parameter_code: r for r in readings_from(observations, station)}
readings["00060"].value # Q(1.35 ft³/s (provisional))
readings["00065"].value # Q(9.11 ft (GAGE:06730500, provisional))
readings["00065"].value.to_datum("NGVD29") # Q(4869.11 ft (NGVD29, provisional))
readings["00065"].value.to_datum("NAVD88") # DatumConversionUnavailable마지막 줄이 핵심입니다. Boulder Creek은 자체 고도를 NGVD29 기준으로 공개하므로, 그곳의 수위는 NGVD29로 해석되고 NAVD88을 거부합니다. 둘 사이의 오프셋은 위치에 따라 달라지며 여기에 공개되지 않기 때문입니다. 현대 기준면이기 때문에 현대 기준면을 가정하는 것은 누구나 찾는 오류보다 한 단계 앞선 여유고 오류입니다.
공개되지 않는 것과 그 처리 방법
altitude와 drainage_area는 단위 없는 숫자로 반환되며, 컬렉션 스키마는 둘 중 어느 것에도 단위를 명시하지 않습니다. 따라서 피트와 제곱마일이라는 USGS 관례가 normalise.py에서 적용되며, 그곳에서 눈에 보이게 되어 이후 단계에서 가정되지 않습니다.
매핑이 없는 단위는 추측하는 대신 거부됩니다. pint가 파싱할 수 있지만 이 패키지에 항목이 없는 단위는 경고와 함께 통과됩니다. 파싱 가능한 것이 이해된 것과 같지 않기 때문입니다. ppt는 pint에게는 조분율로 읽히지만 USGS에게는 천분율을 의미하며, 이는 차원적으로 동일한 두 측정값 사이에 10^9 배 차이입니다.
누락된 값은 WaterServices가 공개한 -999999 대신 여기서는 null이며, 누락된 상태로 유지됩니다. 한정자는 이유를 말해 주며, 장비 중단의 경우 ["EQUIP"]입니다.
승인 상태는 P 또는 A가 아니라 Provisional 또는 Approved로 제공되며, 조건 코드는 검토 상태보다 낮은 등급을 매기므로, 얼음의 영향을 받은 측정값의 승인된 기록은 승인됨이 아니라 미검증으로 등급이 매겨집니다.
관측소 시간대는 약어와 함께 일광 절약 시간 플래그로 결정됩니다. 일광 절약 시간이 없는 MST는 애리조나이고, 일광 절약 시간이 있는 MST는 콜로라도이며, 두 지역은 일 년 중 8개월 동안 한 시간 차이가 나기 때문입니다.
도구
세션은 하나의 질문에 대한 상태와 그에 답한 기록을 보관합니다. 도구는 예외를 발생시키는 대신 결과를 반환합니다. 수정 방법을 담은 실패는 모델이 스스로 수정할 수 있는 대화에 머물게 하지만, 발생된 예외는 턴을 끝내기 때문입니다.
from gagelink import Session, Toolkit
with Session(question="How high is the Potomac at Little Falls?") as work:
kit = Toolkit(work)
kit.describe_location("USGS-01646500")
kit.get_latest("USGS-01646500", parameters=["00060", "00065"], max_age_hours=6)
work.audit("The gage height is 3.02 ft and the discharge is 2960 ft3/s.")
work.manifest()모든 값은 자신의 기준 좌표계가 첨부된 채로 나가며, 모든 값은 원장에 기록되므로 답을 실제로 검색된 내용과 대조하여 확인할 수 있습니다:
[ok] 3.02 ft from get_latest.00065
[ok] 2960 ft3/s from get_latest.00060
[UNSOURCED] 116000 ft3/s no tool output produced this value세 번째 줄이 그 자리를 차지한 검증입니다. 그 수치는 그 강에 대해 그럴듯한 유량이며, 틀렸고, 그것을 포함한 문장에는 그 사실을 나타내는 아무것도 없습니다.
시계열은 포인트 자체가 아니라 요약과 20개 포인트 샘플이 포함된 핸들로 반환됩니다. 15분 간격 기록 1년은 35,000개 값이기 때문입니다. 핸들은 그것을 생성한 쿼리에서 파생되므로 동일한 세션을 재생하면 동일한 핸들이 생성됩니다. 결과에는 예산이 책정되며, 예산 안에 머물기 위해 버려진 모든 것은 결과에 명시됩니다. 조용한 절단은 완전한 커버리지로 읽히기 때문입니다.
도구 | 목적 |
| 주, 카운티, 수문 단위, 사이트 유형 또는 경계 상자로 검색 |
| 메타데이터, 기준면, 시간대, 수위에 필요한 오프셋 |
| 매개변수별 최신 값, 기간 및 품질 포함 |
| 날짜 범위, 핸들 및 요약으로 |
| 다시 가져오지 않고 저장된 시계열 좁히기 |
| 연간 최대 유량 기록 |
| 관측 및 예보 수위, 홍수 임계값 포함 |
| 강을 따라 상류 또는 하류의 모니터링 지점 |
| 한 지점으로 배수되는 면적 |
| 매개변수 코드 해석, 측정값에는 이름이 없으므로 |
MCP 서버로서
export GAGELINK_API_KEY=... # free, see below
gagelink-mcp{"mcpServers": {"gagelink": {"command": "gagelink-mcp"}}}도구는 열한 개, 그 이상은 없습니다. 모델은 도구 목록이 길어질수록 성능이 저하되므로, API 표면은 동사별로 구성되며 어떤 서비스가 답할지의 선택은 호출자에게 맡겨지지 않고 서버가 결정합니다.
도구 설명은 제품의 문서가 아니라 제품의 일부입니다. quantity-guard 평가에서 스키마에 물리적 메타데이터를 선언하기만 하고 강제하지 않았을 때도 기준선에서 실패한 실행의 3분의 1이 회복되었습니다. 따라서 설명이 기준면, 단위, 잠정 기록에 대해 말하는 내용은 어떤 검증이 실행되기 전에 실제로 효과가 있습니다.
도구 실패는 프로토콜 오류가 아니라 오류로 표시된 콘텐츠로 반환되며, 이는 턴을 끝내는 대신 수정 방법을 모델 앞에 유지합니다. 세션은 initialize에서 재설정되므로 한 대화의 물리량이 다른 대화의 매니페스트에 나타날 수 없습니다.
여유고, 위험이 만나는 지점
python demo/freeboard.py는 기록된 응답에서 전체를 오프라인으로 실행합니다:
stage 3.02 ft (GAGE:01646500)
crest 41 ft (NAVD88)
The two are both lengths, so nothing dimensional separates them:
refused: cannot difference an elevation on NAVD88 against one on GAGE:01646500
The gage's zero is at 37.04 ft NAVD88, so the stage is 40.06 ft (NAVD88).
freeboard = 0.94 ft
Ignoring the datum gives 37.98 ft of margin where 0.94 ft is correct,
overstating it by a factor of 40.수위와 측량된 표고는 모두 피트 단위의 길이이며, 하나에서 다른 하나를 빼면 여유고처럼 보이는 숫자가 나옵니다. 오류는 조용하며, 제방을 안전하다고 보고하는 방향으로 작용하고, 단위에 대해 틀린 것이 없기 때문에 어떤 단위 라이브러리도 이를 막지 못합니다.
예보
홍수 임계값은 NOAA National Water Prediction Service에서 제공됩니다. 수위는 강이 범람하는 수위와 대조되기 전에는 아무 의미가 없기 때문입니다. 그 페이로드에는 처리해야 할 세 가지가 있으며 어느 것도 표시되어 있지 않습니다:
유량은 홍수 범주에서는 cfs로, 같은 응답의 상태 블록에서는 kcfs로 나타납니다. 따라서 둘 다 읽고 동일하게 취급하는 호출자는 천 배 차이가 납니다.
설정된 적이 없는 임계값은 생략되지 않고 -9999로 공개됩니다. 이는 차원적으로 유효하고 부호만 그럴듯하며 이후의 모든 검사를 통과하므로, 그것이 바로 센티널로 읽힙니다.
수위는 국가 기준면이 아니라 수위표 자체의 기준면에 있습니다. 거기에 공개된 관측 수위는 같은 관측소와 시간의 USGS 매개변수 00065와 정확히 일치하며, 이것이 그 측정값의 증거이고, 홍수위가 측량된 표고가 아니라 수위표 높이와 차분되는 이유입니다.
하천 네트워크
탐색은 반경 내가 아니라 강을 따라 이루어지며, 이 구분이 답을 유용하게 만듭니다. 다음 유역에 2마일 떨어진 수위표는 여기서 아무것도 상류에 있지 않습니다. 방향은 인덱스의 두 글자 코드가 아니라 단어이므로, upstream은 지류를 포함하고 upstream_main은 본류만 따라갑니다.
유역은 수천 개의 좌표 쌍으로 이루어진 폴리곤으로 도착합니다. 그것은 지도 질문에 대한 답이자 에이전트가 묻는 모든 질문에 대한 틀린 답이므로, 폴리곤은 유지되고 그 면적, 범위, 꼭짓점 수가 보고됩니다. 면적은 구면 면적의 선적분 형태로 폴리곤에서 계산되며, 이는 투영이 필요 없으므로 선택하거나 틀릴 구역이 없습니다. 두 수치가 모두 존재하는 유일한 관측소에서 USGS가 공개하는 유역 면적과 0.06% 차이로 일치하며, 결과는 공개된 값이 아니라 계산된 값이라고 명시하므로 측량된 수치와 동일한 것처럼 인용되지 않습니다.
재현
테스트된 문헌에서 수문학은 1.6%의 재현율을 보입니다. 일반적인 설명은 데이터와 코드가 공개되지 않았다는 것이며, 그것은 더 흥미로운 실패를 숨깁니다. 라이브 서비스에 대항하는 공개된 파이프라인도 재현되지 않습니다. 서비스가 그 아래의 기록을 수정했기 때문입니다. 잠정 유량은 승인된 유량이 되고 숫자는 움직입니다.
세션은 자신의 매니페스트와 본 응답 본문의 번들을 저장합니다. 이를 재생하면 세 가지 모드로 실행되며, 그들 사이의 구분이 핵심입니다.
모드 | 절차 | 격리 대상 |
| 보관된 본문에서 다시 계산 | 코드 및 라이브러리 변경 |
| 다시 가져오고, 동일한 응답 요구 | 모든 드리프트 |
| 다시 가져오고, 차이를 비교하고, 각 차이에 대해 서비스에 설명 요청 | 데이터 수정 |
with Session(question="what was the discharge in mid May 2021?") as work:
Toolkit(work).get_series("USGS-02344872", "00060", "2021-05-16", "2021-05-20")
work.save("bundle.json")gagelink-replay bundle.json --mode strict
gagelink-replay bundle.json --mode revision_aware동일한 번들, 동일한 다시 가져오기, 그리고 두 가지 다른 판정:
strict replay: changed
changed daily
[changed] USGS-02344872 00060 at 2021-05-16: 702.1 -> 826.0 ft^3/s
revision_aware replay: reproduced
changed daily
[revised] USGS-02344872 00060 at 2021-05-16: 702.1 -> 826.0 ft^3/s,
Revisions: Discharge for the period May 16, 2021 to Oct. 27, 2021,
was revised on Aug. 16, 2024, based on changes to the estimated discharge.기관이 400개의 잠정 값을 수정하여 달라진 결과는 코드가 변경되어 달라진 결과와는 다른 과학적 사실에 관한 것이지만, 그 외에는 구분할 수 없다. 수정 기록은 서비스 자체의 time-series-revisions 컬렉션에서 가져오며, 판독값이 이미 가지고 있는 시계열 식별자로 조인되므로, 귀속은 추측이 아니라 조회이다. 게시된 수정 이력이 없는 차이는 설명되지 않은 채로 남아 있으며, 이것이 검사가 공허해지지 않도록 하는 이유이다.
본문은 무엇이든 비교하기 전에 해시로 검증된다. 아카이브가 일치하지 않는 번들은 재생되지 않고 거부되는데, 모든 판정이 세션이 실제로 본 아카이브에 의존하기 때문이다.
waterbench
bench/는 이 툴킷이 모델에게 얼마나 가치가 있는지 측정하는 벤치마크로, 한 관측소의 아홉 가지 작업을 다루며, 그 각각은 패키지가 빌드되는 동안 라이브 서비스 페이로드에서 관측된 아홉 가지 위험을 다룬다.
세 가지 조건이 동일한 데이터에서 비교되며, 모델과 바이트 사이의 인터페이스에서만 차이가 있다:
조건 | 모델이 받는 것 |
| 서비스 자체 JSON을 반환하는 하나의 가져오기 도구. 오늘날 개발자가 가진 것이다. |
| 결과가 단순한 크기로 축소되고 메모가 제거된 11개의 도구 |
| 단위, 기준면, 품질, 오래됨, 메모가 포함된 그대로의 도구 |
가운데 조건이 측정을 가치 있게 만드는 이유이다. 그것이 없으면 첫 번째와 마지막의 차이는 구조화된 검색이 원시 JSON을 이긴다는 것만 보여줄 뿐인데, 이는 누구도 의심하지 않는다. 마지막 두 개의 차이가 메타데이터가 그 자체로 얼마나 가치 있는지 보여준다.
python -m bench --dry-run # no provider, no spend
python -m bench --model anthropic/claude-opus-5 --replicates 4모든 기대 정답은 도구가 제공하는 것과 동일한 기록된 응답에서 파생되며, tests/test_bench.py는 그 응답들로 각 작업을 풀고 결과를 선언된 정답과 대조한다. 그렇게 도달할 수 없는 작업은 잘못된 작업이며, 그것이 드러나는 곳이다. 각 작업은 또한 수치가 어디서 왔는지 알려주는 근거를 기록하므로, 독자는 이 프로젝트의 말을 믿지 않고도 확인할 수 있다.
여유고(freeboard) 작업은 기관 자체의 산술로 확인할 수 있다. USGS는 수표고(water surface elevation)를 매개변수 63160으로 게시하며, 이는 40.07ft NAVD88로, 수위표 높이 3.03ft에 관측소의 기준면 오프셋 37.04ft를 더한 값이다.
점수 산정은 어떤 스윕이 실행되기 전에 작성되어 버전 관리에 있으므로, 불리한 결과를 본 후에 규칙을 조정할 수 없다.
첫 결과
gpt-oss-120b, 9개 작업, 3개 조건, 8회 반복, 216회 실행, $0.09.
조건 | 정답 |
| 61/72 |
| 63/72 |
| 70/72 |
정확도는 모든 실행을 세며, 전혀 답을 내지 못한 8개도 포함한다. 그중 7개는 원시 레코드가 42,000개와 50,000개의 프롬프트 토큰에 달하는 두 작업에서 http_only에 속하는데, 모델이 답하는 대신 숫자를 반복하는 것으로 퇴화한다. 이러한 실패는 조건 때문에 발생하므로, 이를 제외하면 자체 페이로드 크기로 인해 망가진 실행에 대해 원시 JSON을 인정하는 셈이다.
이 스위트는 9개 작업 중 6개에서 상한에 도달하는데, 이는 스위트 자체에 대한 발견이다. 차이가 나는 부분은 다음과 같다:
작업 |
|
|
|
| 3/8 | 8/8 | 8/8 |
| 6/8 | 8/8 | 8/8 |
| 8/8 | 1/8 | 7/8 |
두 개의 긴 레코드 작업에서 중앙값 프롬프트는 원시 JSON을 통해서는 49,864개와 42,006개 토큰이었지만, 툴킷을 통해서는 5,462개와 2,384개였다. 불투명한 단위 작업에서는 기준 프레임을 제거하자 8번의 실행 중 7번이 기록된 함정에 빠져 예보 서비스의 2.95kcfs 대신 USGS 유량인 3010ft³/s로 답했다.
툴킷은 일반적으로 정확도에서 원시 JSON을 이기지 못한다. 그 격차는 거의 전적으로 원시 페이로드가 들어맞지 않는 두 작업에 의해 주도된다. 27개 셀 중 8개가 반복으로 나뉘므로, 8회 중 약 2회 미만의 차이는 이 설계로 구분되지 않으며, 한 모델은 하나의 모델일 뿐이다.
API 키 및 속도 제한
이 서비스는 인증 없이 IP당 시간당 50개의 요청을 허용하고, 키를 사용하면 시간당 1,000개를 허용하며, 이는 api.waterdata.usgs.gov/signup에서 무료로 제공된다. 5개 지점의 조건을 비교하는 단일 에이전트 질문은 약 15~25개의 요청이 필요하므로, 캐싱은 최적화라기보다는 부하를 견디는 역할을 하며, 응답은 기본적으로 프로세스 수명 동안 캐시된다.
남은 허용량은 모든 응답의 X-RateLimit-Remaining에서 읽혀 검색에 전달되므로, 에이전트는 실패함으로써 한계를 발견하기보다는 남은 양을 알 수 있다.
키는 X-Api-Key 헤더로 전달되며 기록된 URL에는 절대 나타나지 않는데, 매니페스트는 게시 가능하도록 설계되었기 때문이다.
대상 서비스
USGS는 WaterServices API 제품군을 폐지하고 있으며, 2027년 1분기에 폐지가 예정되어 있고 2026년 하반기부터 성능 저하가 발생할 수 있다. gagelink는 api.waterdata.usgs.gov/ogcapi/v0의 대체 제품만을 대상으로 한다. 이름을 붙일 만한 한 가지 결과는 time-series-revisions 컬렉션으로, 승인된 기록에 대한 변경 및 삭제를 게시하며, 이를 통해 재생이 기관이 측정값을 수정했기 때문에 변경된 답과 코드가 변경되었기 때문에 변경된 답을 구분할 수 있게 해준다.
개발
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest네트워크 액세스는 교체 가능한 fetch를 거치므로, 스위트는 기록된 응답에 대해 실행되며 어떤 테스트도 네트워크를 필요로 하지 않는다.
라이선스
MIT
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides access to real-time water data from the USGS Water Services API, allowing users to fetch instantaneous measurements like stream flow, gage height, temperature, and water quality parameters from thousands of monitoring stations across the US.3
- AlicenseBqualityCmaintenanceProvides access to UK Environment Agency's real-time flood monitoring data, enabling users to check flood warnings, monitor water levels and flow rates, and access historical measurements from monitoring stations across the UK.1111MIT
- FlicenseNot gradedqualityDmaintenanceProvides real-time hydrological data from Korea's Flood Control Office via MCP protocol, optimized for AI assistants with features to prevent infinite loop calls and standardize data structures.
- AlicenseAqualityBmaintenanceEnables querying USGS water data including real-time and historical streamflow, gage height, and water temperature from USGS gauges across the United States.3MIT
Related MCP Connectors
US weather, alerts, earthquakes and elevation for AI agents, from NWS/NOAA and USGS. No API keys.
US weather & geo for AI agents: forecasts, alerts, earthquakes, elevation, geocoding. No keys.
Query real-time and historical USGS water data from ~8,000 stream gages and groundwater wells.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Adeniyikayodee/gagelink'
If you have feedback or need assistance with the MCP directory API, please join our Discord server