diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c7844b..ed5f815 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,21 @@ ## [Unreleased] +_변경 없음._ + + +## [0.1.0] - 2026-06-05 + - **airkorea**: 에어코리아(한국환경공단) 대기오염정보 읽기 서비스 추가 — 시도별·측정소별 실시간 측정정보와 대기질 예보통보 3개 GET 도구(`airkorea_realtime_by_region`/`airkorea_realtime_by_station`/`airkorea_forecast`), data.go.kr 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), `returnType=json` 명시, 봉투 `resultCode != "00"` 에러 매핑(서비스키/트래픽), 측정값은 문자열·결측 '-' 처리 - **airport**: 인천국제공항(IIAC) 여객편 운항현황 읽기 서비스 추가 — 기관코드 `B551177`의 운항현황 상세조회 서비스(`StatusOfPassengerFlightsDeOdp`)를 **하나의 data.go.kr 서비스키**로 커버하는 2개 GET 도구. `airport_arrivals`(여객편 도착현황 ⭐ — 편명·항공사·출발지·예정/변경시각·터미널·수하물수취대·출구·운항상태)·`airport_departures`(여객편 출발현황 ⭐ — 편명·항공사·목적지·예정/변경시각·터미널·체크인카운터·탑승구·운항상태). `searchday`(YYYYMMDD, D-3~D+6)·`from_time`/`to_time`(HHMM)·`airport_code`/`flight_id`(선택 필터)·`lang`(K/E)·페이지네이션 지원. 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), ⚠️ 인천공항은 `_type`이 아니라 **`type=json`** 명시. 봉투 `resultCode != "00"`(+게이트웨이 `cmmMsgHeader.returnReasonCode`) 에러 매핑, items quirk(`body.items`가 곧장 리스트/단일 객체/빈 문자열) 정규화, 편명·시각·터미널·게이트는 문자열 보존. ⚠️ 개발계정 일 500건 트래픽 제한. 범위: 인천공항 여객편만(화물편·주차/혼잡도·KAC 타 공항 제외) - **arxiv**: arXiv 학술 프리프린트 읽기 서비스 추가 — 검색·id 조회 2개 GET 도구(`arxiv_search`/`arxiv_get`), 무인증, **Atom 1.0 XML** 응답을 표준 라이브러리 `xml.etree.ElementTree`로 파싱(외부 의존 없음), HTTP 200 error-entry(title='Error') 감지·매핑, max_results 기본 10·총 ≤30000(초과 HTTP 400) - **core**: `get_text` HTTP 동사 추가 — 비-JSON 본문(arXiv Atom XML 등)을 raw str로 반환(get_json과 동형, 4xx/5xx UpstreamError 매핑) - **ci: Codex 소켓** — contract-drift 점검 + Codex PR 리뷰 워크플로 스켈레톤 추가. `OPENAI_API_KEY` 미설정 시 no-op(소켓만 준비), Codex for OSS 그랜트가 활성화한다. +- ci/test: 기여 파이프라인을 막던 자기모순 해소 — CHANGELOG drift 게이트가 규칙5(조각은 통합 단계에서만 합본)와 충돌해 신규 서비스/스킬 PR을 깨뜨리던 문제, provenance 테스트가 한국어 헤더를 하드코딩해 영어 정본 README를 막던 문제를 함께 수정. 배선 스모크를 전 서버 합성+불변식 검증으로 교체(하드코딩 6서비스/31도구 제거). +- core(http): 식별용 기본 User-Agent(`arcsolve/`)를 모든 요청에 주입 — UA 누락 시 403을 주는 API(NWS·Wikipedia 등)를 구조적으로 예방하고 서비스별 UA 하드코딩 drift를 제거. 호출자가 명시한 UA는 항상 우선. +- core(oauth): OAuth `state`를 생성만 하던 것을 저장·대조하도록 보강(CSRF·인가코드 주입 방어). `exchange_code(code, state=?)` + `arcsolve auth`가 redirect URL 전체 붙여넣기를 받아 code/state를 파싱. 토큰 저장을 `tempfile`+`os.replace` 원자적 교체로 변경해 쓰기 중단 시 credentials.json 손상 방지. 토큰 엔드포인트에도 기본 UA 전송. +- core(pkg): 패키지 버전을 `arcsolve/__init__.py` 단일 출처로 통일(hatch dynamic version) — pyproject 이중 기록 제거로 릴리스 시 버전·UA·PyPI 메타데이터 drift 차단. +- core(http): opt-in 재시도/백오프 + 전송계층 에러분류를 코어에 도입. 모든 동사가 `retry=Retry(attempts, statuses=(429,503), backoff, respect_retry_after)`를 받아 레이트리밋·일시장애·전송오류를 지수 백오프(또는 응답 `Retry-After`)로 재시도하고, 소진된 전송오류는 `NetworkError`로 분류. **기본값(retry 미지정)은 기존 동작 그대로** — 재시도 없음, 전송 예외는 원본 httpx 그대로 전파(기존 서비스의 `except httpx.ConnectError` 호환). 20개+ 서비스가 손으로 메우던 429/일시오류 처리를 코어 한 곳에서 옵트인으로 해결할 토대. - **core**: 레지스트리 지연·격리 로딩(한 서비스 오류가 전체를 죽이지 않음, 선택 서비스만 import) - **core**: auth 레지스트리 일반화(`Service.make_auth_client`) — 새 OAuth 서비스가 코어 수정 없이 인증 - **core**: OAuth PKCE(S256) + 토큰 파일 0600/디렉토리 0700 @@ -18,16 +28,20 @@ - **core**: 도구 런타임 기능 테스트(요청 조립·응답 파싱·에러 매핑) + MCP 배선 스모크 추가; tools/service의 fastmcp import를 TYPE_CHECKING으로 이동(도구 모듈 런타임 의존 제거) - **core**: LICENSE(Apache-2.0)·CONTRIBUTING 추가 - **crossref**: Crossref 학술 메타데이터 읽기 서비스 추가 — works/journals 검색·단건 조회 4개 GET 도구(`crossref_search_works`/`crossref_get_work`/`crossref_search_journals`/`crossref_get_journal`), 무인증·polite pool 이메일(`CROSSREF_MAILTO`)은 선택 쿼리 파라미터+User-Agent, 본문 message 기반 건수 안내(rows 0–1000·offset 0–10000) +- dist: end-user 설치/실행 경로를 README에 추가(`uvx arcsolve` 무설치 실행·`uv tool install`·호스트 설정의 uvx 변형, 양어). 패키징은 끝났으나 진입로가 없던 공백 해소. +- release: `arcsolve release ` 서브커맨드 추가 — `__version__`·server.json 버전 동기화 + changelog.d 조각을 `## [ver] - date` 섹션으로 확정하고 조각 소비. SemVer 검증. (release.yml의 태그↔버전 게이트와 짝) +- registry: MCP 레지스트리 등재용 `server.json`(공식 스키마 2025-12-11, PyPI 패키지 `arcsolve`·stdio·uvx) + README `` 소유권 마커. 발견성 채널 연결. - **discord**: Webhook 메시지 전송 MCP 추가 — `discord_send_message` - **discord**: 핵심 도구 확장 — Webhook 임베드/편집/삭제(`discord_send_embed`·`discord_edit_message`·`discord_delete_message`) + Bot 토큰 경로(`discord_create_message`·`discord_list_messages`, `DISCORD_BOT_TOKEN`) - **egen**: E-Gen(국립중앙의료원 중앙응급의료센터) 응급의료정보 읽기 서비스 추가 — 응급실 실시간 가용병상·중증질환자 수용가능·응급의료기관 목록 3개 GET 도구(`egen_realtime_beds`/`egen_severe_acceptance`/`egen_list`), data.go.kr 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), 응답은 **XML**이라 `get_text`+`xml.etree`로 파싱(arxiv 패턴), 봉투 `resultCode != "00"`/게이트웨이 `cmmMsgHeader` 에러 매핑(서비스키/트래픽), STAGE1/STAGE2는 한글 시도/시군구명, 병상수·가용여부는 문자열·결측 처리, 중증질환 수용가능은 `MKioskTy` 슬롯 수집(가이드 .hwp 의존이라 느슨히) -- **ev_charger**: 전기차 충전소(한국환경공단 EvCharger) 정보·실시간 상태 읽기 서비스 추가 — 충전기 실시간 상태·충전소 정보 2개 GET 도구(`evcharger_status`/`evcharger_info`, 폴더 `ev_charger`·prefix `evcharger_`), data.go.kr 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), airkorea·egen과 같은 기관(B552584), 응답은 **XML**이라 `get_text`+`xml.etree`로 파싱(egen 패턴), 봉투 `resultCode != "00"`/게이트웨이 `cmmMsgHeader` 에러 매핑(서비스키/트래픽), 지역코드 `zcode`(시도)·`zscode`(시군구) 선택 필터, `stat` 상태 코드(1통신이상·2충전대기·3충전중·4운영중지·5점검중·9상태미확인) 한글 표시, `chgerType` 타입 코드는 가이드 코드표로 라벨링(미상 코드는 원본 보존), `numOfRows`[10,9999]·`period`[1,10] 클램프, 좌표·상태·플래그는 문자열·결측 보존. ⚠️ 상태는 약 5분 주기 갱신(캐시 스냅샷) — 출력에 지연 명시 +- **ev_charger**: 전기차 충전소(한국환경공단 EvCharger) 정보·실시간 상태 읽기 서비스 추가 — 충전기 실시간 상태·충전소 정보 2개 GET 도구(`ev_charger_status`/`ev_charger_info`, 폴더 `ev_charger`·prefix `ev_charger_`), data.go.kr 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), airkorea·egen과 같은 기관(B552584), 응답은 **XML**이라 `get_text`+`xml.etree`로 파싱(egen 패턴), 봉투 `resultCode != "00"`/게이트웨이 `cmmMsgHeader` 에러 매핑(서비스키/트래픽), 지역코드 `zcode`(시도)·`zscode`(시군구) 선택 필터, `stat` 상태 코드(1통신이상·2충전대기·3충전중·4운영중지·5점검중·9상태미확인) 한글 표시, `chgerType` 타입 코드는 가이드 코드표로 라벨링(미상 코드는 원본 보존), `numOfRows`[10,9999]·`period`[1,10] 클램프, 좌표·상태·플래그는 문자열·결측 보존. ⚠️ 상태는 약 5분 주기 갱신(캐시 스냅샷) — 출력에 지연 명시 - **feeds**: RSS/Atom/RDF 피드 읽기 서비스 추가 — 임의 피드 URL을 받아 메타·최근 항목을 요약하는 1개 GET 도구(`feeds_fetch`), 무인증, RSS 2.0/Atom 1.0/RSS 1.0(RDF) 세 포맷을 루트 엘리먼트로 자동 감지해 표준 라이브러리 `xml.etree.ElementTree`로 파싱(외부 의존 없음), 로컬명 기반 탐색으로 `dc:`/`content:` 확장 흡수, HTML 스니펫 평문화·길이 제한. 코어 `get_text` 재사용(스크래핑 없이 웹 콘텐츠 수집) - **hackernews**: Hacker News 읽기 서비스 추가 — 4개 GET 도구(`hn_item`/`hn_top`/`hn_search`/`hn_user`), 무인증, 두 공식 API 합성(구조적 데이터=Firebase `/v0/*`, 전문 검색=Algolia HN Search `/api/v1/search`·`search_by_date`), 랭킹은 id 배열만 주므로 상위 N개를 `asyncio.gather`로 병렬 fetch(N+1·상한 50), title/text/about HTML 평문화, 코어 `get_json` 재사용 - **kakao**: '나에게 보내기' MCP 추가 — `kakao_send_text_to_me`, `kakao_send_link_to_me` - **line**: LINE Messaging API push 텍스트 MCP 추가 — `line_send_text`(전송 메시지 id 반환) - **line**: push 응답 계약을 공식 스펙(`sentMessages[]`)에 맞게 수정, text 길이를 UTF-16 코드 유닛으로 검증 - **line**: 코어 도구 확장 — `line_reply_text`(reply, sentMessages), `line_multicast_text`(userId 최대 500, 빈 응답), `line_broadcast_text`(빈 응답), `line_get_profile`(Profile 조회) 추가 +- ci(test): 라이브 계약 드리프트 nightly 추가 — 무인증 8서비스(openmeteo·hackernews·feeds·openalex·crossref·arxiv·usgs_quake·nws)의 대표 도구를 실제 엔드포인트로 호출해 상류 계약(엔드포인트·필드명) 변화를 사람 개입 전에 포착. 평소 PR/CI에선 skip(`ARCSOLVE_LIVE` 미설정·무네트워크 원칙 유지), nightly(`-m live`)·수동 디스패치로만 실행. PR 게이트가 아니라 알림 신호(상류 가용성에 flaky 가능). '검증된 능력' 약속을 실제로 지키는 게이트. - **notion**: Notion 워크스페이스 읽기 서비스 추가 — search·page·block children·database·data source 조회/쿼리 6개 도구(`notion_search`/`notion_get_page`/`notion_get_block_children`/`notion_get_database`/`notion_get_data_source`/`notion_query_data_source`), 필수 Bearer 토큰(`NOTION_TOKEN`), API 버전 2026-03-11 핀 고정(data source 모델) - **nws**: NWS(National Weather Service) 미국 날씨 읽기 서비스 추가 — 예보·시간별 예보·활성 기상특보 3개 GET 도구(`nws_forecast`/`nws_hourly_forecast`/`nws_alerts`), 무인증이나 **User-Agent 헤더 필수**(기본값 상수, `NWS_USER_AGENT`로 덮어씀), 좌표→예보는 NWS 특유의 **2단계 조회**(`/points` → `/gridpoints/.../forecast`), GeoJSON `properties.periods[]`/`features[]` 파싱, **미국 좌표만 유효**(해외 404 InvalidPoint → 안내 매핑) - **openalex**: OpenAlex 학술 그래프 읽기 서비스 추가 — works/authors 검색·단건 조회 4개 GET 도구(`openalex_search_works`/`openalex_get_work`/`openalex_search_authors`/`openalex_get_author`), API 키·mailto는 선택 쿼리 파라미터(키 없이도 동작), 본문 meta 기반 건수 안내 @@ -36,9 +50,14 @@ - **pubmed**: PubMed(NCBI E-utilities) 생의학 문헌 읽기 서비스 추가 — 검색·요약·초록 3개 GET 도구(`pubmed_search`/`pubmed_get_summary`/`pubmed_fetch_abstract`), API 키는 선택 **쿼리 파라미터**(`NCBI_API_KEY`·식별용 `tool`/`email`, 키 없이 3 req/s·키 있으면 10 req/s). esearch/esummary는 `retmode=json`으로 `get_json`, **efetch는 JSON 미지원이라 XML**을 `get_text` + 표준 라이브러리 `xml.etree.ElementTree`로 파싱(구조화 초록 `AbstractText@Label` 포함). esearch count/idlist 기반 건수 안내, retmax 기본 20·≤10000, id 1회 ≤200개, HTTP 200 ERROR 봉투 매핑 - **repo**: README 상단 배지(CI · License · Python) 추가, 저장소 public 공개 - **repo**: `arcsolve` → `ArcSolve-Kit`로 리네임(ArcSolve 본제품과 구분, MCP+Skill 아우르는 모음). UA 제품 토큰 `arcsolve`·CLI `arcsolve`·패키지 `arcsolve`는 유지, 레포 URL만 갱신 +- security(배포 전 하드닝): 7렌즈 보안·정확성 점검 결과 반영. SSRF 가드(feeds 임의 URL의 내부망/메타데이터 차단)·응답 스트리밍 크기 컷오프·기본 에러 마스킹(server `mask_error_details`, 토큰 박힌 URL 비노출)·retry 대기 상한·UpstreamError payload 절단; OAuth state 필수화(CSRF)·손상 토큰파일 복구·토큰 응답 검증·REFRESH_TOKEN 마스킹; PyPI sdist 시크릿 누출 차단(.gitignore `.claude/`·sdist exclude·release 게이트: 태그↔버전 일치·sdist 가드·clean build); data.go.kr 6종 HTTPS 전환·에러 원문 비노출(15종)·빈입력 차단(kakao/discord)·seoul KST 타임존; defusedxml로 신뢰불가 XML 파싱(XXE/billion-laughs 심층방어, 코어 `arcsolve/xml.py`). - **semanticscholar**: Semantic Scholar 학술 그래프 읽기 서비스 추가 — papers/authors 검색·단건 조회 4개 GET 도구(`s2_search_papers`/`s2_get_paper`/`s2_search_authors`/`s2_get_author`), API 키는 선택 `x-api-key` 헤더(키 없이 공유 풀로 동작·전용 풀 1 RPS), `fields` 콤마 구분 필드 선택, 본문 `total`/`offset`/`next` 기반 건수 안내(paper limit≤100·offset+limit<1000, author limit≤1000) - **seoul_transit**: 서울 실시간 교통 읽기 서비스 추가 — 지하철 실시간 도착·따릉이 대여소 2개 GET 도구(`seoul_subway_arrivals`/`seoul_bike_status`), 서울 열린데이터광장 인증키는 URL **path 세그먼트**(필수), `{TYPE}=json` 명시. ⚠️ **인증키 2종 분리**: 지하철 실시간은 전용 `SEOUL_SUBWAY_API_KEY`(호스트 `swopenAPI.seoul.go.kr`), 따릉이 등 일반은 `SEOUL_OPENDATA_API_KEY`(호스트 `openapi.seoul.go.kr:8088`). 봉투 결과코드 매핑(지하철 `errorMessage.code`·따릉이 `RESULT.CODE` — INFO-000 정상/INFO-100 인증키/INFO-200 없음/ERROR-336 1000건초과/ERROR-5xx 서버), 지하철 `recptnDt`(과거 생성시각)를 '현재로부터 N초 전'으로 보정, 따릉이 1회 **최대 1000건** 페이지네이션(초과는 HTTP 전 차단). 항목 값은 전부 문자열 - **academic-discovery** (skill): 학술 다중 출처(arXiv·Crossref·OpenAlex·PubMed·Semantic Scholar)를 가로지르는 탐색·교차검증 스킬 추가 — MCP 도구 오케스트레이션(계약 import 없음), 정적 테스트 + eval 시나리오. +- **skill-info-gathering**: 정보수집 교차서비스 스킬 추가 — 임의 RSS/Atom 피드 + 해커뉴스(랭킹·검색·스레드·사용자)를 링크 기준 중복제거해 날짜순 다이제스트로 통합. feeds·hackernews 도구 오케스트레이션(무인증·읽기 전용). SSRF는 feeds_fetch 코어 가드로 안전. 범용 웹검색·합성 아님. 📡 정보수집 번들 페어 스킬. +- **skill-journey-planning**: 한국 여정 계획 교차서비스 스킬 추가 — 지하철·버스 도착(seoul·tago)·고속/시외버스·열차·인천공항 운항·따릉이 + 목적지 주차 잔여·EV 충전을 한 문전 계획으로 오케스트레이션. 5개 서비스 도구를 contract 변경 없이 사용. 읽기 전용·예약/경로엔진 자처 안 함·한국 한정. +- **skill-messaging-routing**: 메시징 라우팅 교차서비스 스킬 추가 — Kakao(나에게)·Telegram·Discord·LINE을 청중 모델에 맞춰 고르고 플랫폼별 포맷(임베드·미디어·길이제한)으로 전송. 전송 행위라 사전 확인 필수·broadcast는 사용자 확인 후·스팸 금지. 기존 메시징 4종 도구를 contract 변경 없이 오케스트레이션. +- **skill-situational-awareness**: 교차서비스 상황인지 스킬 추가(한국) — 장소를 한 번 지오코딩한 뒤 날씨(openmeteo)·실시간 미세먼지(airkorea)·응급실 가용병상/중증수용/기관(egen)을 하나의 상황 readout으로 묶는 멀티서비스 오케스트레이션. 도구는 기존 3개 서비스(8개 도구)를 contract 변경 없이 그대로 오케스트레이션. 읽기 전용·정보 제공(의료 트리아지 금지·119 안내)·한국 한정·알림 전송은 메시징 스킬로 안내만. academic-discovery와 동형의 두 번째 멀티서비스 정본 예시. - **skill: wikipedia-lookup** — 위키백과 단일소스 조회 스킬(검색 → 요약 → 심화 + Wikidata 브리지 안내). `wikipedia` 서비스 도구를 오케스트레이션하는 미니멀 단일서비스 스킬 예시. - **tago_transit**: 국토교통부 TAGO 전국 대중교통 통합 읽기 서비스 추가 — 단일 네임스페이스 `1613000`의 6개 서비스(버스도착/정류소/노선·고속/시외버스·열차)를 **하나의 data.go.kr 서비스키**로 커버하는 7개 GET 도구. 시내버스: `tago_city_codes`(도시코드)·`tago_search_bus_stops`(정류소명 검색→nodeId)·`tago_bus_arrivals`(정류소별 실시간 도착예정 ⭐, 도착초→분 환산)·`tago_bus_route`(노선 경유정류소). 광역: `tago_express_bus`/`tago_intercity_bus`(터미널ID 기반 운행·등급·요금)·`tago_train`(역ID 기반 KTX/일반 열차). 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), `_type=json` 명시. 봉투 `resultCode != "00"`(+게이트웨이 `cmmMsgHeader.returnReasonCode`) 에러 매핑, data.go.kr JSON quirk(`body.items.item`이 빈 문자열/단일 객체/배열) 정규화, 코드·요금·시각은 문자열 보존. 코드 의존(도시코드+정류소ID/노선ID/터미널ID/역ID)은 보조 도구(`tago_city_codes`·`tago_search_bus_stops`)와 README 코드 확보 경로로 해결 - **telegram**: sendMessage 기반 telegram_send_message 추가 @@ -48,4 +67,3 @@ - **wikidata**: Wikidata 읽기 서비스 추가 — 엔티티 검색·단건·statements·SPARQL 4개 GET 도구(`wikidata_search`/`wikidata_entity`/`wikidata_statements`/`wikidata_sparql`), 무인증이나 **식별 가능한 User-Agent 필수**(기본값 상수, `WIKIDATA_USER_AGENT`로 덮어씀)에 (선택) `WIKIDATA_API_TOKEN` Bearer로 레이트리밋 완화, 세 상류 혼용(Action API `wbsearchentities`·Wikibase **REST v1**·WDQS SPARQL), Action API **200+error 봉투** 별도 처리, REST statements의 가변 `value.content`(string/item/time/quantity/monolingualtext) 렌더링(P/Q 라벨은 raw id), WDQS는 **timeout=60**·구문 오류 400 원문 비노출 - **wikipedia**: 위키백과 읽기 서비스 추가 — 검색·요약·본문·링크 4개 GET 도구(`wikipedia_search`/`wikipedia_summary`/`wikipedia_extract`/`wikipedia_links`), 무인증이나 **User-Agent 헤더 요구**(기본값 상수, `WIKIPEDIA_USER_AGENT`로 덮어씀) + (선택) `WIKIPEDIA_API_TOKEN` Bearer로 레이트리밋 완화, 세 엔드포인트 혼합(per-wiki REST 검색 `/w/rest.php/v1/search/page` · rest_v1 요약 `/api/rest_v1/page/summary/{title}`(Wikidata Q-id·좌표 노출) · Action API TextExtracts/links|categories `formatversion=2` 배열), 언어판별 호스트(`{lang}.wikipedia.org`)·**Action API HTTP 200+error 봉투** 매핑, ⚠️ deprecating `api.wikimedia.org/core/v1/*` 회피 - **zotero**: Zotero 라이브러리 읽기 서비스 추가(Web API v3 + 로컬 데스크톱 API 단일 서비스·백엔드 전환) — 검색/아이템/자식/컬렉션/컬렉션 아이템/태그/전문/헬스 8개 GET 도구, 응답 헤더 기반 페이지네이션 안내 - diff --git a/changelog.d/airkorea.md b/changelog.d/airkorea.md deleted file mode 100644 index 139108c..0000000 --- a/changelog.d/airkorea.md +++ /dev/null @@ -1 +0,0 @@ -- **airkorea**: 에어코리아(한국환경공단) 대기오염정보 읽기 서비스 추가 — 시도별·측정소별 실시간 측정정보와 대기질 예보통보 3개 GET 도구(`airkorea_realtime_by_region`/`airkorea_realtime_by_station`/`airkorea_forecast`), data.go.kr 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), `returnType=json` 명시, 봉투 `resultCode != "00"` 에러 매핑(서비스키/트래픽), 측정값은 문자열·결측 '-' 처리 diff --git a/changelog.d/airport.md b/changelog.d/airport.md deleted file mode 100644 index 111cd85..0000000 --- a/changelog.d/airport.md +++ /dev/null @@ -1 +0,0 @@ -- **airport**: 인천국제공항(IIAC) 여객편 운항현황 읽기 서비스 추가 — 기관코드 `B551177`의 운항현황 상세조회 서비스(`StatusOfPassengerFlightsDeOdp`)를 **하나의 data.go.kr 서비스키**로 커버하는 2개 GET 도구. `airport_arrivals`(여객편 도착현황 ⭐ — 편명·항공사·출발지·예정/변경시각·터미널·수하물수취대·출구·운항상태)·`airport_departures`(여객편 출발현황 ⭐ — 편명·항공사·목적지·예정/변경시각·터미널·체크인카운터·탑승구·운항상태). `searchday`(YYYYMMDD, D-3~D+6)·`from_time`/`to_time`(HHMM)·`airport_code`/`flight_id`(선택 필터)·`lang`(K/E)·페이지네이션 지원. 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), ⚠️ 인천공항은 `_type`이 아니라 **`type=json`** 명시. 봉투 `resultCode != "00"`(+게이트웨이 `cmmMsgHeader.returnReasonCode`) 에러 매핑, items quirk(`body.items`가 곧장 리스트/단일 객체/빈 문자열) 정규화, 편명·시각·터미널·게이트는 문자열 보존. ⚠️ 개발계정 일 500건 트래픽 제한. 범위: 인천공항 여객편만(화물편·주차/혼잡도·KAC 타 공항 제외) diff --git a/changelog.d/arxiv.md b/changelog.d/arxiv.md deleted file mode 100644 index 63a16b2..0000000 --- a/changelog.d/arxiv.md +++ /dev/null @@ -1,2 +0,0 @@ -- **arxiv**: arXiv 학술 프리프린트 읽기 서비스 추가 — 검색·id 조회 2개 GET 도구(`arxiv_search`/`arxiv_get`), 무인증, **Atom 1.0 XML** 응답을 표준 라이브러리 `xml.etree.ElementTree`로 파싱(외부 의존 없음), HTTP 200 error-entry(title='Error') 감지·매핑, max_results 기본 10·총 ≤30000(초과 HTTP 400) -- **core**: `get_text` HTTP 동사 추가 — 비-JSON 본문(arXiv Atom XML 등)을 raw str로 반환(get_json과 동형, 4xx/5xx UpstreamError 매핑) diff --git a/changelog.d/ci-codex-sockets.md b/changelog.d/ci-codex-sockets.md deleted file mode 100644 index 257726d..0000000 --- a/changelog.d/ci-codex-sockets.md +++ /dev/null @@ -1 +0,0 @@ -- **ci: Codex 소켓** — contract-drift 점검 + Codex PR 리뷰 워크플로 스켈레톤 추가. `OPENAI_API_KEY` 미설정 시 no-op(소켓만 준비), Codex for OSS 그랜트가 활성화한다. diff --git a/changelog.d/ci-contrib-pipeline.md b/changelog.d/ci-contrib-pipeline.md deleted file mode 100644 index 04b94e9..0000000 --- a/changelog.d/ci-contrib-pipeline.md +++ /dev/null @@ -1 +0,0 @@ -- ci/test: 기여 파이프라인을 막던 자기모순 해소 — CHANGELOG drift 게이트가 규칙5(조각은 통합 단계에서만 합본)와 충돌해 신규 서비스/스킬 PR을 깨뜨리던 문제, provenance 테스트가 한국어 헤더를 하드코딩해 영어 정본 README를 막던 문제를 함께 수정. 배선 스모크를 전 서버 합성+불변식 검증으로 교체(하드코딩 6서비스/31도구 제거). diff --git a/changelog.d/core-hardening.md b/changelog.d/core-hardening.md deleted file mode 100644 index 7b59ae6..0000000 --- a/changelog.d/core-hardening.md +++ /dev/null @@ -1,3 +0,0 @@ -- core(http): 식별용 기본 User-Agent(`arcsolve/`)를 모든 요청에 주입 — UA 누락 시 403을 주는 API(NWS·Wikipedia 등)를 구조적으로 예방하고 서비스별 UA 하드코딩 drift를 제거. 호출자가 명시한 UA는 항상 우선. -- core(oauth): OAuth `state`를 생성만 하던 것을 저장·대조하도록 보강(CSRF·인가코드 주입 방어). `exchange_code(code, state=?)` + `arcsolve auth`가 redirect URL 전체 붙여넣기를 받아 code/state를 파싱. 토큰 저장을 `tempfile`+`os.replace` 원자적 교체로 변경해 쓰기 중단 시 credentials.json 손상 방지. 토큰 엔드포인트에도 기본 UA 전송. -- core(pkg): 패키지 버전을 `arcsolve/__init__.py` 단일 출처로 통일(hatch dynamic version) — pyproject 이중 기록 제거로 릴리스 시 버전·UA·PyPI 메타데이터 drift 차단. diff --git a/changelog.d/core-http-resilience.md b/changelog.d/core-http-resilience.md deleted file mode 100644 index a04dc6c..0000000 --- a/changelog.d/core-http-resilience.md +++ /dev/null @@ -1 +0,0 @@ -- core(http): opt-in 재시도/백오프 + 전송계층 에러분류를 코어에 도입. 모든 동사가 `retry=Retry(attempts, statuses=(429,503), backoff, respect_retry_after)`를 받아 레이트리밋·일시장애·전송오류를 지수 백오프(또는 응답 `Retry-After`)로 재시도하고, 소진된 전송오류는 `NetworkError`로 분류. **기본값(retry 미지정)은 기존 동작 그대로** — 재시도 없음, 전송 예외는 원본 httpx 그대로 전파(기존 서비스의 `except httpx.ConnectError` 호환). 20개+ 서비스가 손으로 메우던 429/일시오류 처리를 코어 한 곳에서 옵트인으로 해결할 토대. diff --git a/changelog.d/core.md b/changelog.d/core.md deleted file mode 100644 index 8c5dfa7..0000000 --- a/changelog.d/core.md +++ /dev/null @@ -1,7 +0,0 @@ -- **core**: 레지스트리 지연·격리 로딩(한 서비스 오류가 전체를 죽이지 않음, 선택 서비스만 import) -- **core**: auth 레지스트리 일반화(`Service.make_auth_client`) — 새 OAuth 서비스가 코어 수정 없이 인증 -- **core**: OAuth PKCE(S256) + 토큰 파일 0600/디렉토리 0700 -- **core**: 공통 HTTP 동사 추가(`get_json`/`post_json`/`patch_json`/`delete_json`/`post_multipart`) + 의존성 격리 규칙 -- **core**: provenance 강제 테스트 + GitHub Actions CI(pytest·ruff·카탈로그/체인지로그 drift) -- **core**: 도구 런타임 기능 테스트(요청 조립·응답 파싱·에러 매핑) + MCP 배선 스모크 추가; tools/service의 fastmcp import를 TYPE_CHECKING으로 이동(도구 모듈 런타임 의존 제거) -- **core**: LICENSE(Apache-2.0)·CONTRIBUTING 추가 diff --git a/changelog.d/crossref.md b/changelog.d/crossref.md deleted file mode 100644 index b102166..0000000 --- a/changelog.d/crossref.md +++ /dev/null @@ -1 +0,0 @@ -- **crossref**: Crossref 학술 메타데이터 읽기 서비스 추가 — works/journals 검색·단건 조회 4개 GET 도구(`crossref_search_works`/`crossref_get_work`/`crossref_search_journals`/`crossref_get_journal`), 무인증·polite pool 이메일(`CROSSREF_MAILTO`)은 선택 쿼리 파라미터+User-Agent, 본문 message 기반 건수 안내(rows 0–1000·offset 0–10000) diff --git a/changelog.d/deploy-enablement.md b/changelog.d/deploy-enablement.md deleted file mode 100644 index 4acca9c..0000000 --- a/changelog.d/deploy-enablement.md +++ /dev/null @@ -1,3 +0,0 @@ -- dist: end-user 설치/실행 경로를 README에 추가(`uvx arcsolve` 무설치 실행·`uv tool install`·호스트 설정의 uvx 변형, 양어). 패키징은 끝났으나 진입로가 없던 공백 해소. -- release: `arcsolve release ` 서브커맨드 추가 — `__version__`·server.json 버전 동기화 + changelog.d 조각을 `## [ver] - date` 섹션으로 확정하고 조각 소비. SemVer 검증. (release.yml의 태그↔버전 게이트와 짝) -- registry: MCP 레지스트리 등재용 `server.json`(공식 스키마 2025-12-11, PyPI 패키지 `arcsolve`·stdio·uvx) + README `` 소유권 마커. 발견성 채널 연결. diff --git a/changelog.d/discord.md b/changelog.d/discord.md deleted file mode 100644 index 176ff0a..0000000 --- a/changelog.d/discord.md +++ /dev/null @@ -1,2 +0,0 @@ -- **discord**: Webhook 메시지 전송 MCP 추가 — `discord_send_message` -- **discord**: 핵심 도구 확장 — Webhook 임베드/편집/삭제(`discord_send_embed`·`discord_edit_message`·`discord_delete_message`) + Bot 토큰 경로(`discord_create_message`·`discord_list_messages`, `DISCORD_BOT_TOKEN`) diff --git a/changelog.d/egen.md b/changelog.d/egen.md deleted file mode 100644 index 6394cec..0000000 --- a/changelog.d/egen.md +++ /dev/null @@ -1 +0,0 @@ -- **egen**: E-Gen(국립중앙의료원 중앙응급의료센터) 응급의료정보 읽기 서비스 추가 — 응급실 실시간 가용병상·중증질환자 수용가능·응급의료기관 목록 3개 GET 도구(`egen_realtime_beds`/`egen_severe_acceptance`/`egen_list`), data.go.kr 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), 응답은 **XML**이라 `get_text`+`xml.etree`로 파싱(arxiv 패턴), 봉투 `resultCode != "00"`/게이트웨이 `cmmMsgHeader` 에러 매핑(서비스키/트래픽), STAGE1/STAGE2는 한글 시도/시군구명, 병상수·가용여부는 문자열·결측 처리, 중증질환 수용가능은 `MKioskTy` 슬롯 수집(가이드 .hwp 의존이라 느슨히) diff --git a/changelog.d/ev_charger.md b/changelog.d/ev_charger.md deleted file mode 100644 index 68f6eaa..0000000 --- a/changelog.d/ev_charger.md +++ /dev/null @@ -1 +0,0 @@ -- **ev_charger**: 전기차 충전소(한국환경공단 EvCharger) 정보·실시간 상태 읽기 서비스 추가 — 충전기 실시간 상태·충전소 정보 2개 GET 도구(`ev_charger_status`/`ev_charger_info`, 폴더 `ev_charger`·prefix `ev_charger_`), data.go.kr 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), airkorea·egen과 같은 기관(B552584), 응답은 **XML**이라 `get_text`+`xml.etree`로 파싱(egen 패턴), 봉투 `resultCode != "00"`/게이트웨이 `cmmMsgHeader` 에러 매핑(서비스키/트래픽), 지역코드 `zcode`(시도)·`zscode`(시군구) 선택 필터, `stat` 상태 코드(1통신이상·2충전대기·3충전중·4운영중지·5점검중·9상태미확인) 한글 표시, `chgerType` 타입 코드는 가이드 코드표로 라벨링(미상 코드는 원본 보존), `numOfRows`[10,9999]·`period`[1,10] 클램프, 좌표·상태·플래그는 문자열·결측 보존. ⚠️ 상태는 약 5분 주기 갱신(캐시 스냅샷) — 출력에 지연 명시 diff --git a/changelog.d/feeds.md b/changelog.d/feeds.md deleted file mode 100644 index 9a85235..0000000 --- a/changelog.d/feeds.md +++ /dev/null @@ -1 +0,0 @@ -- **feeds**: RSS/Atom/RDF 피드 읽기 서비스 추가 — 임의 피드 URL을 받아 메타·최근 항목을 요약하는 1개 GET 도구(`feeds_fetch`), 무인증, RSS 2.0/Atom 1.0/RSS 1.0(RDF) 세 포맷을 루트 엘리먼트로 자동 감지해 표준 라이브러리 `xml.etree.ElementTree`로 파싱(외부 의존 없음), 로컬명 기반 탐색으로 `dc:`/`content:` 확장 흡수, HTML 스니펫 평문화·길이 제한. 코어 `get_text` 재사용(스크래핑 없이 웹 콘텐츠 수집) diff --git a/changelog.d/hackernews.md b/changelog.d/hackernews.md deleted file mode 100644 index 705f9b6..0000000 --- a/changelog.d/hackernews.md +++ /dev/null @@ -1 +0,0 @@ -- **hackernews**: Hacker News 읽기 서비스 추가 — 4개 GET 도구(`hn_item`/`hn_top`/`hn_search`/`hn_user`), 무인증, 두 공식 API 합성(구조적 데이터=Firebase `/v0/*`, 전문 검색=Algolia HN Search `/api/v1/search`·`search_by_date`), 랭킹은 id 배열만 주므로 상위 N개를 `asyncio.gather`로 병렬 fetch(N+1·상한 50), title/text/about HTML 평문화, 코어 `get_json` 재사용 diff --git a/changelog.d/kakao.md b/changelog.d/kakao.md deleted file mode 100644 index b733137..0000000 --- a/changelog.d/kakao.md +++ /dev/null @@ -1 +0,0 @@ -- **kakao**: '나에게 보내기' MCP 추가 — `kakao_send_text_to_me`, `kakao_send_link_to_me` diff --git a/changelog.d/line.md b/changelog.d/line.md deleted file mode 100644 index 4014b70..0000000 --- a/changelog.d/line.md +++ /dev/null @@ -1,3 +0,0 @@ -- **line**: LINE Messaging API push 텍스트 MCP 추가 — `line_send_text`(전송 메시지 id 반환) -- **line**: push 응답 계약을 공식 스펙(`sentMessages[]`)에 맞게 수정, text 길이를 UTF-16 코드 유닛으로 검증 -- **line**: 코어 도구 확장 — `line_reply_text`(reply, sentMessages), `line_multicast_text`(userId 최대 500, 빈 응답), `line_broadcast_text`(빈 응답), `line_get_profile`(Profile 조회) 추가 diff --git a/changelog.d/live-drift-nightly.md b/changelog.d/live-drift-nightly.md deleted file mode 100644 index 76addf9..0000000 --- a/changelog.d/live-drift-nightly.md +++ /dev/null @@ -1 +0,0 @@ -- ci(test): 라이브 계약 드리프트 nightly 추가 — 무인증 8서비스(openmeteo·hackernews·feeds·openalex·crossref·arxiv·usgs_quake·nws)의 대표 도구를 실제 엔드포인트로 호출해 상류 계약(엔드포인트·필드명) 변화를 사람 개입 전에 포착. 평소 PR/CI에선 skip(`ARCSOLVE_LIVE` 미설정·무네트워크 원칙 유지), nightly(`-m live`)·수동 디스패치로만 실행. PR 게이트가 아니라 알림 신호(상류 가용성에 flaky 가능). '검증된 능력' 약속을 실제로 지키는 게이트. diff --git a/changelog.d/notion.md b/changelog.d/notion.md deleted file mode 100644 index 129e34a..0000000 --- a/changelog.d/notion.md +++ /dev/null @@ -1 +0,0 @@ -- **notion**: Notion 워크스페이스 읽기 서비스 추가 — search·page·block children·database·data source 조회/쿼리 6개 도구(`notion_search`/`notion_get_page`/`notion_get_block_children`/`notion_get_database`/`notion_get_data_source`/`notion_query_data_source`), 필수 Bearer 토큰(`NOTION_TOKEN`), API 버전 2026-03-11 핀 고정(data source 모델) diff --git a/changelog.d/nws.md b/changelog.d/nws.md deleted file mode 100644 index d2d229d..0000000 --- a/changelog.d/nws.md +++ /dev/null @@ -1 +0,0 @@ -- **nws**: NWS(National Weather Service) 미국 날씨 읽기 서비스 추가 — 예보·시간별 예보·활성 기상특보 3개 GET 도구(`nws_forecast`/`nws_hourly_forecast`/`nws_alerts`), 무인증이나 **User-Agent 헤더 필수**(기본값 상수, `NWS_USER_AGENT`로 덮어씀), 좌표→예보는 NWS 특유의 **2단계 조회**(`/points` → `/gridpoints/.../forecast`), GeoJSON `properties.periods[]`/`features[]` 파싱, **미국 좌표만 유효**(해외 404 InvalidPoint → 안내 매핑) diff --git a/changelog.d/openalex.md b/changelog.d/openalex.md deleted file mode 100644 index 592edca..0000000 --- a/changelog.d/openalex.md +++ /dev/null @@ -1 +0,0 @@ -- **openalex**: OpenAlex 학술 그래프 읽기 서비스 추가 — works/authors 검색·단건 조회 4개 GET 도구(`openalex_search_works`/`openalex_get_work`/`openalex_search_authors`/`openalex_get_author`), API 키·mailto는 선택 쿼리 파라미터(키 없이도 동작), 본문 meta 기반 건수 안내 diff --git a/changelog.d/openmeteo.md b/changelog.d/openmeteo.md deleted file mode 100644 index 7393a69..0000000 --- a/changelog.d/openmeteo.md +++ /dev/null @@ -1 +0,0 @@ -- **openmeteo**: Open-Meteo 날씨·기후 읽기 서비스 추가 — 예보·지오코딩 2개 GET 도구(`openmeteo_geocode`/`openmeteo_forecast`), 무인증(키·env 불필요·식별 User-Agent만), hourly/daily/current는 콤마 구분 변수명 문자열 그대로 전달(검증 상류 위임), 동적 변수 블록은 dict로 수신(`forecast_days` 0–16·`count` 1–100), 지오코딩 무매칭 시 `results` 키 부재 안전 처리, 에러 봉투 `{error,reason}`(400) 매핑 diff --git a/changelog.d/parking.md b/changelog.d/parking.md deleted file mode 100644 index 0ccdea0..0000000 --- a/changelog.d/parking.md +++ /dev/null @@ -1 +0,0 @@ -- **parking**: 한국교통안전공단(KOTSA) 전국 주차정보 읽기 서비스 추가 — 단일 base `B553881/Parking`의 3개 오퍼레이션(시설/운영/실시간)을 **하나의 data.go.kr 서비스키**로 커버하는 3개 GET 도구. `parking_search`(전국 주차장 시설정보 — 주차장명·도로명주소·위경도·총 주차구획 수·PK)·`parking_operation`(운영정보 — 운영시간·기본/추가 요금·무료회차)·`parking_realtime`(실시간 잔여 주차면 ⭐ — 현재/총 주차가능 구획 수). 모든 응답은 **주차장관리번호 `prk_center_id`를 PK**로 공유. ⚠️ **실시간 잔여면은 시스템 연동 주차장 한정**(공식 안내상 운영·실시간 정보는 시설정보보다 데이터 수가 적음) — 도구 설명·README에 커버리지 한계 명시. 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), `format=2`(JSON) 명시. 봉투 `resultCode != "00"`(+게이트웨이 `cmmMsgHeader.returnReasonCode`) 에러 매핑. B553881 고유 quirk: 항목 배열이 표준 `response.body.items.item`이 아니라 **오퍼레이션명 키 아래**에 실리고 1건이면 단일 객체·0건이면 키 누락 → `normalize_items`가 흡수. 좌표·요금·시각·면수는 문자열 보존(잔여 0면도 보존) diff --git a/changelog.d/pubmed.md b/changelog.d/pubmed.md deleted file mode 100644 index 1ef3e65..0000000 --- a/changelog.d/pubmed.md +++ /dev/null @@ -1 +0,0 @@ -- **pubmed**: PubMed(NCBI E-utilities) 생의학 문헌 읽기 서비스 추가 — 검색·요약·초록 3개 GET 도구(`pubmed_search`/`pubmed_get_summary`/`pubmed_fetch_abstract`), API 키는 선택 **쿼리 파라미터**(`NCBI_API_KEY`·식별용 `tool`/`email`, 키 없이 3 req/s·키 있으면 10 req/s). esearch/esummary는 `retmode=json`으로 `get_json`, **efetch는 JSON 미지원이라 XML**을 `get_text` + 표준 라이브러리 `xml.etree.ElementTree`로 파싱(구조화 초록 `AbstractText@Label` 포함). esearch count/idlist 기반 건수 안내, retmax 기본 20·≤10000, id 1회 ≤200개, HTTP 200 ERROR 봉투 매핑 diff --git a/changelog.d/repo.md b/changelog.d/repo.md deleted file mode 100644 index 09f7a1f..0000000 --- a/changelog.d/repo.md +++ /dev/null @@ -1,2 +0,0 @@ -- **repo**: README 상단 배지(CI · License · Python) 추가, 저장소 public 공개 -- **repo**: `arcsolve` → `ArcSolve-Kit`로 리네임(ArcSolve 본제품과 구분, MCP+Skill 아우르는 모음). UA 제품 토큰 `arcsolve`·CLI `arcsolve`·패키지 `arcsolve`는 유지, 레포 URL만 갱신 diff --git a/changelog.d/security-hardening.md b/changelog.d/security-hardening.md deleted file mode 100644 index fd9eabd..0000000 --- a/changelog.d/security-hardening.md +++ /dev/null @@ -1 +0,0 @@ -- security(배포 전 하드닝): 7렌즈 보안·정확성 점검 결과 반영. SSRF 가드(feeds 임의 URL의 내부망/메타데이터 차단)·응답 스트리밍 크기 컷오프·기본 에러 마스킹(server `mask_error_details`, 토큰 박힌 URL 비노출)·retry 대기 상한·UpstreamError payload 절단; OAuth state 필수화(CSRF)·손상 토큰파일 복구·토큰 응답 검증·REFRESH_TOKEN 마스킹; PyPI sdist 시크릿 누출 차단(.gitignore `.claude/`·sdist exclude·release 게이트: 태그↔버전 일치·sdist 가드·clean build); data.go.kr 6종 HTTPS 전환·에러 원문 비노출(15종)·빈입력 차단(kakao/discord)·seoul KST 타임존; defusedxml로 신뢰불가 XML 파싱(XXE/billion-laughs 심층방어, 코어 `arcsolve/xml.py`). diff --git a/changelog.d/semanticscholar.md b/changelog.d/semanticscholar.md deleted file mode 100644 index 18aa778..0000000 --- a/changelog.d/semanticscholar.md +++ /dev/null @@ -1 +0,0 @@ -- **semanticscholar**: Semantic Scholar 학술 그래프 읽기 서비스 추가 — papers/authors 검색·단건 조회 4개 GET 도구(`s2_search_papers`/`s2_get_paper`/`s2_search_authors`/`s2_get_author`), API 키는 선택 `x-api-key` 헤더(키 없이 공유 풀로 동작·전용 풀 1 RPS), `fields` 콤마 구분 필드 선택, 본문 `total`/`offset`/`next` 기반 건수 안내(paper limit≤100·offset+limit<1000, author limit≤1000) diff --git a/changelog.d/seoul_transit.md b/changelog.d/seoul_transit.md deleted file mode 100644 index 28eb2a2..0000000 --- a/changelog.d/seoul_transit.md +++ /dev/null @@ -1 +0,0 @@ -- **seoul_transit**: 서울 실시간 교통 읽기 서비스 추가 — 지하철 실시간 도착·따릉이 대여소 2개 GET 도구(`seoul_subway_arrivals`/`seoul_bike_status`), 서울 열린데이터광장 인증키는 URL **path 세그먼트**(필수), `{TYPE}=json` 명시. ⚠️ **인증키 2종 분리**: 지하철 실시간은 전용 `SEOUL_SUBWAY_API_KEY`(호스트 `swopenAPI.seoul.go.kr`), 따릉이 등 일반은 `SEOUL_OPENDATA_API_KEY`(호스트 `openapi.seoul.go.kr:8088`). 봉투 결과코드 매핑(지하철 `errorMessage.code`·따릉이 `RESULT.CODE` — INFO-000 정상/INFO-100 인증키/INFO-200 없음/ERROR-336 1000건초과/ERROR-5xx 서버), 지하철 `recptnDt`(과거 생성시각)를 '현재로부터 N초 전'으로 보정, 따릉이 1회 **최대 1000건** 페이지네이션(초과는 HTTP 전 차단). 항목 값은 전부 문자열 diff --git a/changelog.d/skill-academic-discovery.md b/changelog.d/skill-academic-discovery.md deleted file mode 100644 index a315787..0000000 --- a/changelog.d/skill-academic-discovery.md +++ /dev/null @@ -1 +0,0 @@ -- **academic-discovery** (skill): 학술 다중 출처(arXiv·Crossref·OpenAlex·PubMed·Semantic Scholar)를 가로지르는 탐색·교차검증 스킬 추가 — MCP 도구 오케스트레이션(계약 import 없음), 정적 테스트 + eval 시나리오. diff --git a/changelog.d/skill-info-gathering.md b/changelog.d/skill-info-gathering.md deleted file mode 100644 index a11ef32..0000000 --- a/changelog.d/skill-info-gathering.md +++ /dev/null @@ -1 +0,0 @@ -- **skill-info-gathering**: 정보수집 교차서비스 스킬 추가 — 임의 RSS/Atom 피드 + 해커뉴스(랭킹·검색·스레드·사용자)를 링크 기준 중복제거해 날짜순 다이제스트로 통합. feeds·hackernews 도구 오케스트레이션(무인증·읽기 전용). SSRF는 feeds_fetch 코어 가드로 안전. 범용 웹검색·합성 아님. 📡 정보수집 번들 페어 스킬. diff --git a/changelog.d/skill-journey-planning.md b/changelog.d/skill-journey-planning.md deleted file mode 100644 index 8e8d933..0000000 --- a/changelog.d/skill-journey-planning.md +++ /dev/null @@ -1 +0,0 @@ -- **skill-journey-planning**: 한국 여정 계획 교차서비스 스킬 추가 — 지하철·버스 도착(seoul·tago)·고속/시외버스·열차·인천공항 운항·따릉이 + 목적지 주차 잔여·EV 충전을 한 문전 계획으로 오케스트레이션. 5개 서비스 도구를 contract 변경 없이 사용. 읽기 전용·예약/경로엔진 자처 안 함·한국 한정. diff --git a/changelog.d/skill-messaging-routing.md b/changelog.d/skill-messaging-routing.md deleted file mode 100644 index 2c9b120..0000000 --- a/changelog.d/skill-messaging-routing.md +++ /dev/null @@ -1 +0,0 @@ -- **skill-messaging-routing**: 메시징 라우팅 교차서비스 스킬 추가 — Kakao(나에게)·Telegram·Discord·LINE을 청중 모델에 맞춰 고르고 플랫폼별 포맷(임베드·미디어·길이제한)으로 전송. 전송 행위라 사전 확인 필수·broadcast는 사용자 확인 후·스팸 금지. 기존 메시징 4종 도구를 contract 변경 없이 오케스트레이션. diff --git a/changelog.d/skill-situational-awareness.md b/changelog.d/skill-situational-awareness.md deleted file mode 100644 index f10b4ab..0000000 --- a/changelog.d/skill-situational-awareness.md +++ /dev/null @@ -1 +0,0 @@ -- **skill-situational-awareness**: 교차서비스 상황인지 스킬 추가(한국) — 장소를 한 번 지오코딩한 뒤 날씨(openmeteo)·실시간 미세먼지(airkorea)·응급실 가용병상/중증수용/기관(egen)을 하나의 상황 readout으로 묶는 멀티서비스 오케스트레이션. 도구는 기존 3개 서비스(8개 도구)를 contract 변경 없이 그대로 오케스트레이션. 읽기 전용·정보 제공(의료 트리아지 금지·119 안내)·한국 한정·알림 전송은 메시징 스킬로 안내만. academic-discovery와 동형의 두 번째 멀티서비스 정본 예시. diff --git a/changelog.d/skill-wikipedia-lookup.md b/changelog.d/skill-wikipedia-lookup.md deleted file mode 100644 index c5e50da..0000000 --- a/changelog.d/skill-wikipedia-lookup.md +++ /dev/null @@ -1 +0,0 @@ -- **skill: wikipedia-lookup** — 위키백과 단일소스 조회 스킬(검색 → 요약 → 심화 + Wikidata 브리지 안내). `wikipedia` 서비스 도구를 오케스트레이션하는 미니멀 단일서비스 스킬 예시. diff --git a/changelog.d/tago_transit.md b/changelog.d/tago_transit.md deleted file mode 100644 index 2fbbb61..0000000 --- a/changelog.d/tago_transit.md +++ /dev/null @@ -1 +0,0 @@ -- **tago_transit**: 국토교통부 TAGO 전국 대중교통 통합 읽기 서비스 추가 — 단일 네임스페이스 `1613000`의 6개 서비스(버스도착/정류소/노선·고속/시외버스·열차)를 **하나의 data.go.kr 서비스키**로 커버하는 7개 GET 도구. 시내버스: `tago_city_codes`(도시코드)·`tago_search_bus_stops`(정류소명 검색→nodeId)·`tago_bus_arrivals`(정류소별 실시간 도착예정 ⭐, 도착초→분 환산)·`tago_bus_route`(노선 경유정류소). 광역: `tago_express_bus`/`tago_intercity_bus`(터미널ID 기반 운행·등급·요금)·`tago_train`(역ID 기반 KTX/일반 열차). 서비스키는 쿼리 파라미터 `serviceKey`(필수, **Decoding 키** — 이중 인코딩 방지), `_type=json` 명시. 봉투 `resultCode != "00"`(+게이트웨이 `cmmMsgHeader.returnReasonCode`) 에러 매핑, data.go.kr JSON quirk(`body.items.item`이 빈 문자열/단일 객체/배열) 정규화, 코드·요금·시각은 문자열 보존. 코드 의존(도시코드+정류소ID/노선ID/터미널ID/역ID)은 보조 도구(`tago_city_codes`·`tago_search_bus_stops`)와 README 코드 확보 경로로 해결 diff --git a/changelog.d/telegram.md b/changelog.d/telegram.md deleted file mode 100644 index 2de118e..0000000 --- a/changelog.d/telegram.md +++ /dev/null @@ -1,3 +0,0 @@ -- **telegram**: sendMessage 기반 telegram_send_message 추가 -- **telegram**: 코어 도구 확장 — getMe(헬스체크)/sendPhoto/sendDocument/editMessageText/deleteMessage 추가 -- **telegram**: sendPhoto/sendDocument 로컬 파일 multipart 업로드 지원(사진≤10MB·파일≤50MB), editMessageText inline_message_id 경로 추가 diff --git a/changelog.d/usgs_quake.md b/changelog.d/usgs_quake.md deleted file mode 100644 index 26ba9c6..0000000 --- a/changelog.d/usgs_quake.md +++ /dev/null @@ -1 +0,0 @@ -- **usgs_quake**: USGS 지진 정보 읽기 서비스 추가 — FDSN Event API 검색·건수 2개 GET 도구(`usgs_search_earthquakes`/`usgs_count_earthquakes`), 무인증·`format=geojson` 고정, 시간 ISO8601·`orderby`(time/magnitude)·원형 위치(`latitude`+`longitude`+`maxradiuskm`)·`limit` 1–20000(기본 20), GeoJSON FeatureCollection 파싱(time ms→UTC, coordinates[lon,lat,depth])·`{count,maxAllowed}` 건수 diff --git a/changelog.d/wikidata.md b/changelog.d/wikidata.md deleted file mode 100644 index 67ea7e9..0000000 --- a/changelog.d/wikidata.md +++ /dev/null @@ -1 +0,0 @@ -- **wikidata**: Wikidata 읽기 서비스 추가 — 엔티티 검색·단건·statements·SPARQL 4개 GET 도구(`wikidata_search`/`wikidata_entity`/`wikidata_statements`/`wikidata_sparql`), 무인증이나 **식별 가능한 User-Agent 필수**(기본값 상수, `WIKIDATA_USER_AGENT`로 덮어씀)에 (선택) `WIKIDATA_API_TOKEN` Bearer로 레이트리밋 완화, 세 상류 혼용(Action API `wbsearchentities`·Wikibase **REST v1**·WDQS SPARQL), Action API **200+error 봉투** 별도 처리, REST statements의 가변 `value.content`(string/item/time/quantity/monolingualtext) 렌더링(P/Q 라벨은 raw id), WDQS는 **timeout=60**·구문 오류 400 원문 비노출 diff --git a/changelog.d/wikipedia.md b/changelog.d/wikipedia.md deleted file mode 100644 index 6738cf3..0000000 --- a/changelog.d/wikipedia.md +++ /dev/null @@ -1 +0,0 @@ -- **wikipedia**: 위키백과 읽기 서비스 추가 — 검색·요약·본문·링크 4개 GET 도구(`wikipedia_search`/`wikipedia_summary`/`wikipedia_extract`/`wikipedia_links`), 무인증이나 **User-Agent 헤더 요구**(기본값 상수, `WIKIPEDIA_USER_AGENT`로 덮어씀) + (선택) `WIKIPEDIA_API_TOKEN` Bearer로 레이트리밋 완화, 세 엔드포인트 혼합(per-wiki REST 검색 `/w/rest.php/v1/search/page` · rest_v1 요약 `/api/rest_v1/page/summary/{title}`(Wikidata Q-id·좌표 노출) · Action API TextExtracts/links|categories `formatversion=2` 배열), 언어판별 호스트(`{lang}.wikipedia.org`)·**Action API HTTP 200+error 봉투** 매핑, ⚠️ deprecating `api.wikimedia.org/core/v1/*` 회피 diff --git a/changelog.d/zotero.md b/changelog.d/zotero.md deleted file mode 100644 index 66f547d..0000000 --- a/changelog.d/zotero.md +++ /dev/null @@ -1 +0,0 @@ -- **zotero**: Zotero 라이브러리 읽기 서비스 추가(Web API v3 + 로컬 데스크톱 API 단일 서비스·백엔드 전환) — 검색/아이템/자식/컬렉션/컬렉션 아이템/태그/전문/헬스 8개 GET 도구, 응답 헤더 기반 페이지네이션 안내