
Subway Lost Property
- 2.8k installs
- 6.5k repo stars
- Updated July 27, 2026
- nomadamas/k-skill
subway-lost-property guides Korean subway lost item lookup via LOST112 and Seoul Metro official pages with structured search payloads.
About
The subway-lost-property skill structures official Korean subway lost-and-found lookup via LOST112 and Seoul Metro lost property center pages. Version one is guidance and hybrid: it prepares LOST112 search conditions with SITE=V for non-police agencies, station name, item name, and date range, plus Seoul Metro center entry links. It asks for minimum clues first including station, item type, approximate date, and whether Seoul Metro lines one through eight apply. A python helper generates LOST112 form payloads and runnable curl examples with referer and sixty second timeout saving HTML to lost112-search-result.html. Optional --verify-live checks page reachability without guaranteeing automated results due to slow official responses and missing public API. The skill explains manual fallback when station names differ from storage location labels and does not promise full automation until captcha and session stability are verified.
- Structures LOST112 SITE=V search for subway lost items plus Seoul Metro center link.
- Asks station, item, date, and operator before generating search payload.
- Helper outputs LOST112 form payload and runnable curl with 60s timeout.
- v1 is guidance hybrid; does not guarantee automated result parsing.
- Manual fallback when station keyword variants fail on LOST112.
Subway Lost Property by the numbers
- 2,772 all-time installs (skills.sh)
- +122 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #191 of 3,301 Productivity & Planning skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
subway-lost-property capabilities & compatibility
- Capabilities
- minimum clue interview before search generation · lost112 form payload and curl example generation · seoul metro lost property center link guidance · optional live reachability verification · conservative manual fallback when automation fai
- Use cases
- research · planning
What subway-lost-property says it does
완전 자동 조회형으로 확장하려면 캡차/세션/동적 요청 안정성 재검증이 먼저 필요하다.
npx skills add https://github.com/nomadamas/k-skill --skill subway-lost-propertyAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2.8k |
|---|---|
| repo stars | ★ 6.5k |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 27, 2026 |
| Repository | nomadamas/k-skill ↗ |
How do I look up items lost on Seoul subway using official LOST112 and metro lost property sites?
Guide users through official LOST112 and Seoul Metro lost property lookup with structured search payloads and conservative manual fallback.
Who is it for?
Korean subway riders needing official lost property search parameters and entry URLs.
Skip if: Skip for non-subway lost items, guaranteed automated retrieval, or non-Korean transit systems.
When should I use this skill?
User asks about 지하철 분실물, subway lost property, LOST112 search, or Seoul metro lost items.
What you get
LOST112 search conditions, curl example, Seoul Metro center link, and manual fallback guidance.
Files
Subway Lost Property
What this skill does
지하철에서 잃어버린 물건을 찾기 위해 공식 경로를 구조화한다.
- LOST112
습득물 목록 조회에 넣을 검색 조건을 정리한다. - 서울교통공사 유실물센터 진입점을 함께 안내한다.
- 공개 API가 명확하지 않은 상태라 v1은 안내형/하이브리드 범위로 유지한다.
When to use
- "강남역에서 지갑 잃어버렸는데 어디서 찾아?"
- "2호선 지하철 분실물 조회 방법 알려줘"
- "서울 지하철 유실물 공식 사이트로 바로 찾게 도와줘"
Inputs
- 필수: 역명 또는 보관장소 키워드
- 선택: 물품명, 호선, 분실/습득 추정 기간
Official surfaces
- LOST112 습득물 목록:
https://www.lost112.go.kr/find/findList.do - 서울교통공사 유실물센터:
https://www.seoulmetro.co.kr/kr/page.do?menuIdx=541
LOST112 검색 폼에서 확인되는 핵심 필드는 아래와 같다.
SITE=V: 경찰 이외 기관(지하철, 공항 등)DEP_PLACE: 보관장소PRDT_NM: 습득물명START_YMD,END_YMD: 검색 기간
Workflow
1) Ask for the minimum clues first
바로 추정하지 말고 아래 정보를 먼저 받는다.
- 어느 역/어느 구간인지
- 물건 종류가 무엇인지
- 대략 언제 잃어버렸는지
- 서울교통공사(1~8호선) 범위인지, 다른 운영사인지
2) Generate the official LOST112 search payload
repo helper를 그대로 써도 된다.
python3 scripts/subway_lost_property.py \
--station 강남역 \
--item 지갑 \
--days 14helper는 기본적으로 SITE=V 를 사용하고, 역명/물품명/기간을 LOST112 form payload와 referer까지 포함한 runnable `curl` 예시로 정리해 준다. 예시 curl 은 느린 공식 응답을 감안해 --max-time 60 을 포함하고, 응답 HTML을 lost112-search-result.html 로 저장한다.
3) Optionally verify live reachability
python3 scripts/subway_lost_property.py \
--station 강남역 \
--item 지갑 \
--days 14 \
--verify-live--verify-live 는 공식 페이지 접근 가능 여부만 보수적으로 확인한다. 사이트가 느리면 timeout을 그대로 보고하고 manual open으로 전환한다.
4) Guide the user conservatively
- 먼저 LOST112에서 역명 그대로 검색
- 결과가 없으면
강남처럼역없는 키워드로 재검색 - 필요하면 호선명도 추가 검색
- 서울교통공사 유실물센터 페이지를 함께 열어 후속 안내 확인
Done when
- 사용자가 공식 조회 경로를 바로 열 수 있다.
- LOST112 검색 조건(
SITE=V, 역명, 물품명, 기간)을 받았다. - 자동 조회 보장 범위와 manual fallback을 분명히 설명했다.
Failure modes
- 공식 사이트 응답이 느리거나 timeout 발생
- 역명이 실제 보관장소 표기와 달라 검색 결과가 비는 경우
- 공개 API 부재로 자동 결과 수집이 안정적이지 않은 경우
Notes
- v1은 공식 웹 흐름을 안전하게 안내하는 범위다.
- 완전 자동 조회형으로 확장하려면 캡차/세션/동적 요청 안정성 재검증이 먼저 필요하다.
- helper는 공식 HTTPS 진입점만 사용한다.
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import shlex
import subprocess
from dataclasses import asdict, dataclass
from datetime import date, timedelta
from typing import Callable
LOST112_LIST_URL = "https://www.lost112.go.kr/find/findList.do"
LOST112_REFERER_URL = "https://www.lost112.go.kr/"
LOST112_OUTPUT_FILE = "lost112-search-result.html"
LOST112_CURL_MAX_TIME = 60
SEOUL_METRO_LOST_CENTER_URL = "https://www.seoulmetro.co.kr/kr/page.do?menuIdx=541"
CURL_USER_AGENT = "Mozilla/5.0"
Runner = Callable[..., subprocess.CompletedProcess[str]]
@dataclass(frozen=True)
class SearchQuery:
station: str
item: str | None = None
line: str | None = None
start_date: date | None = None
end_date: date | None = None
@dataclass(frozen=True)
class SearchPlan:
query: SearchQuery
payload: dict[str, str]
suggested_keywords: list[str]
official_sources: list[dict[str, str]]
guidance: list[str]
cautions: list[str]
curl_example: str
def to_dict(self) -> dict[str, object]:
return {
"query": {
**asdict(self.query),
"start_date": self.query.start_date.isoformat() if self.query.start_date else None,
"end_date": self.query.end_date.isoformat() if self.query.end_date else None,
},
"payload": self.payload,
"suggested_keywords": self.suggested_keywords,
"official_sources": self.official_sources,
"guidance": self.guidance,
"cautions": self.cautions,
"curl_example": self.curl_example,
}
def normalize_station(station: str) -> str:
normalized = " ".join(station.split())
if not normalized:
raise ValueError("station is required")
return normalized
def expand_station_keywords(station: str) -> list[str]:
normalized = normalize_station(station)
keywords = [normalized]
if normalized.endswith("역") and len(normalized) > 1:
keywords.append(normalized[:-1])
return list(dict.fromkeys(keyword for keyword in keywords if keyword))
def build_search_payload(query: SearchQuery) -> dict[str, str]:
station = normalize_station(query.station)
if not query.start_date or not query.end_date:
raise ValueError("start_date and end_date are required")
payload = {
"pageIndex": "1",
"START_YMD": query.start_date.strftime("%Y%m%d"),
"END_YMD": query.end_date.strftime("%Y%m%d"),
"PRDT_NM": (query.item or "").strip(),
"DEP_PLACE": station,
"SITE": "V",
"PLACE_SE_CD": "",
"FD_LCT_CD": "",
"FD_SIGUNGU": "",
"IN_NM": "",
"ATC_ID": "",
"F_ATC_ID": "",
"PRDT_CL_CD01": "",
"PRDT_CL_CD02": "",
"PRDT_CL_NM": "",
"MENU_NO": "",
}
return payload
def _base_curl_command(url: str | None, max_time: int, *, follow_redirects: bool = True) -> list[str]:
command = [
"curl",
"-fsS",
"--http1.1",
"--tls-max",
"1.2",
"--retry",
"1",
"--max-time",
str(max_time),
"-A",
CURL_USER_AGENT,
]
if follow_redirects:
command.insert(2, "-L")
if url:
command.append(url)
return command
def build_curl_command(payload: dict[str, str]) -> str:
command = _base_curl_command("", LOST112_CURL_MAX_TIME, follow_redirects=False)
command.extend(["--referer", LOST112_REFERER_URL])
for key, value in payload.items():
if value:
command.extend(["--data-urlencode", f"{key}={value}"])
command.extend(["--output", LOST112_OUTPUT_FILE])
command.append(LOST112_LIST_URL)
return " ".join(shlex.quote(part) for part in command)
def probe_source(name: str, url: str, runner: Runner = subprocess.run) -> dict[str, str]:
command = _base_curl_command(url, 15)
try:
completed = runner(command, capture_output=True, text=True, check=True)
return {
"name": name,
"url": url,
"status": "reachable",
"detail": f"fetched {len(completed.stdout)} bytes",
}
except subprocess.CalledProcessError as error:
detail = (error.stderr or error.stdout or str(error)).strip() or "unknown error"
status = "timeout" if error.returncode == 28 or "timed out" in detail.lower() else "error"
return {"name": name, "url": url, "status": status, "detail": detail}
def build_search_plan(
station: str,
item: str | None = None,
line: str | None = None,
days: int = 30,
today: date | None = None,
verify_live: bool = False,
probe: Callable[[str, str], dict[str, str]] | None = None,
) -> SearchPlan:
normalized_station = normalize_station(station)
if days <= 0:
raise ValueError("days must be positive")
today = today or date.today()
end_date = today
start_date = today - timedelta(days=days)
query = SearchQuery(
station=normalized_station,
item=(item or "").strip() or None,
line=(line or "").strip() or None,
start_date=start_date,
end_date=end_date,
)
payload = build_search_payload(query)
suggested_keywords = expand_station_keywords(normalized_station)
if query.line:
suggested_keywords.append(query.line)
suggested_keywords = list(dict.fromkeys(suggested_keywords))
default_sources = [
{
"name": "LOST112 습득물 목록",
"url": LOST112_LIST_URL,
"purpose": "경찰 이외 기관(지하철·공항 등) 습득물 검색",
"status": "not_checked",
},
{
"name": "서울교통공사 유실물센터",
"url": SEOUL_METRO_LOST_CENTER_URL,
"purpose": "서울 지하철 공식 유실물 진입점/추가 안내",
"status": "not_checked",
},
]
if verify_live:
probe = probe or probe_source
default_sources = [
{**probe(source["name"], source["url"]), "purpose": source["purpose"]}
for source in default_sources
]
item_hint = query.item or "분실물"
guidance = [
f"먼저 LOST112에서 보관장소를 '{normalized_station}' 로, 물품명은 '{item_hint}' 로 검색합니다.",
"검색 폼에서는 SITE=V(경찰이외의기관) 기준으로 지하철/공항 등 기관 습득물을 우선 좁힙니다.",
"결과가 없으면 역명에서 '역'을 뺀 키워드나 호선명을 추가로 검색합니다.",
"서울교통공사 안내 페이지를 함께 열어 운영사 유실물센터/후속 절차를 확인합니다.",
]
cautions = [
"v1은 공식 웹 조회 경로를 구조화하는 안내형/하이브리드 스킬이다.",
"공개 API가 확인되지 않아 자동 결과 수집은 보장하지 않는다.",
"공식 사이트 응답 속도가 느리면 manual open으로 전환한다.",
]
return SearchPlan(
query=query,
payload=payload,
suggested_keywords=suggested_keywords,
official_sources=default_sources,
guidance=guidance,
cautions=cautions,
curl_example=build_curl_command(payload),
)
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Generate official subway lost-property search guidance.")
parser.add_argument("--station", required=True, help="역명 또는 보관장소 키워드")
parser.add_argument("--item", help="예: 지갑, 이어폰")
parser.add_argument("--line", help="예: 2호선")
parser.add_argument("--days", type=int, default=30, help="검색 기간(일), 기본값 30")
parser.add_argument("--verify-live", action="store_true", help="공식 페이지 reachability를 curl로 확인")
return parser.parse_args(argv)
def main(argv: list[str] | None = None) -> None:
args = parse_args(argv)
plan = build_search_plan(
station=args.station,
item=args.item,
line=args.line,
days=args.days,
verify_live=args.verify_live,
)
print(json.dumps(plan.to_dict(), ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
Related skills
FAQ
Does v1 automatically return found items?
No. v1 prepares official search conditions and curl examples; full automation awaits API stability verification.
What LOST112 SITE value is used?
SITE=V for non-police agencies including subway and airport storage locations.
What if station name search returns nothing?
Retry without 역 suffix, add line name, and open Seoul Metro lost property center for follow-up.
Is Subway Lost Property safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.