Skip to main content
Glama

webcheck-mcp

AI 에이전트가 웹페이지를 브라우저로 열어 본문을 직접 읽고 판단하는 대신, 순수 계산으로 끝낼 수 있는 작업은 코드로 처리해서 토큰 사용량을 줄이는 범용 MCP 서버입니다.

특정 업무(홈페이지 점검 등)에 종속되지 않습니다. "여러 URL의 상태를 확인하고 싶다", "페이지의 특정 값이 최근에 갱신됐는지 알고 싶다", "URL을 키로 하는 마크다운 표를 갱신하고 싶다" — 이 세 가지가 필요한 어떤 업무에서든 쓸 수 있습니다.

왜 필요한가

AI 에이전트에게 "이 URL 200개가 다 정상인지 확인해줘"라고 시키면, 에이전트는 브라우저로 200번 페이지를 열어 본문을 읽습니다. 페이지당 수천수만 토큰이 들어가므로 전체로는 수십만수백만 토큰이 소요됩니다.

반면 HTTP 상태 확인이나 날짜 비교 같은 작업은 원래 결정적(deterministic) 계산입니다. 코드가 몇 초 만에 끝내는 일을 AI에게 "읽고 판단"하게 시키는 건 비용도 크고, 특히 날짜 계산 같은 건 AI가 오히려 실수하기 쉬운 영역입니다.

이 서버는 그 결정적 계산 부분만 떼어내 MCP 도구로 제공합니다. 판단이 필요한 작업(문구 검토, 맥락 파악 등)은 여전히 에이전트가 직접 합니다.

Related MCP server: mcp-universal-crawler

설치

pip install git+https://github.com/deinteger/webcheck-mcp.git

또는 격리된 환경을 원하면 pipx를 권장합니다.

pipx install git+https://github.com/deinteger/webcheck-mcp.git

설치하면 webcheck-mcp 명령이 생깁니다.

MCP 클라이언트에 등록

Claude Code

프로젝트 루트에 .mcp.json을 만듭니다.

{
  "mcpServers": {
    "webcheck": {
      "command": "webcheck-mcp"
    }
  }
}

pipx 대신 프로젝트 전용 venv에 설치했다면 command를 그 venv의 bin/webcheck-mcp 절대/상대 경로로 지정합니다.

Antigravity 등 다른 MCP 클라이언트

MCP를 지원하는 도구라면 필요한 건 실행 커맨드 하나뿐입니다.

  • command: webcheck-mcp (또는 설치 경로의 절대 경로)

해당 클라이언트의 "로컬 MCP 서버 추가" 메뉴/설정에 이 커맨드를 등록하면 됩니다.

제공 도구

discover_urls(start_url, explicit_urls=None, allowed_domains=None, max_pages=200, max_depth=3, exclude_patterns=None, timeout=10, ...)

점검 대상 URL 목록을 상황에 맞게 유연하게 수집합니다. 사이트마다 사정이 다르므로(sitemap이 있는 곳, 없는 곳, 이미 점검 대상이 정해진 곳) 우선순위를 두고 자동으로 전환합니다.

  1. explicit_urls가 있으면 그대로 사용 — 점검 대상이 이미 정해져 있는 경우.

  2. sitemap.xml(또는 robots.txtSitemap: 위치)이 있으면 파싱 — sitemap index(하위 sitemap 여러 개)도 재귀적으로 처리합니다. 일부 CMS는 존재하지 않는 경로도 HTTP 200으로 응답하므로(check_links가 다루는 문제와 동일), 실제 XML sitemap 형식이 아니거나 에러 문구가 감지되면 "sitemap 없음"으로 취급하고 다음 단계로 넘어갑니다.

  3. 둘 다 없으면 start_url에서부터 같은 도메인 링크(<a href>)를 BFS로 크롤링합니다. document.location.href="..." 같은 JS 리다이렉트 스텁 페이지(HTTP 리다이렉트가 아니라 크롤러가 못 따라가는 패턴)도 감지해서 따라갑니다.

한계: 메뉴나 목록이 JavaScript로만 렌더링되는 사이트(SPA)는 sitemap도 없고 크롤링으로도 못 찾을 수 있습니다. 그런 경우 에이전트가 브라우저로 직접 메뉴를 열어 URL을 수집해야 합니다 — 이 도구는 그 수고를 줄여주는 용도이지 항상 대체하지는 못합니다.

반환: {"method": "explicit" | "sitemap" | "crawl", "urls": [...],
        "count": int, "truncated": bool, "sitemap_url": str (있는 경우)}

실제 사이트 검증 (2026-09-16): 대상 사이트는 sitemap.xml 요청 시 CMS가 커스텀 "페이지 없음" 화면을 HTTP 200으로 반환 — sitemap 없음으로 정확히 판정하고 크롤링으로 전환됨. 홈페이지 자체는 JS 리다이렉트 스텁 (document.location.href="/usr/main/mainPage.do")이었는데, 이를 따라가서 실제 메뉴 15개(전체메뉴 페이지 포함)를 정상적으로 찾아냄.

URL 목록의 접속 가능 여부를 병렬로 확인합니다.

일부 CMS(특히 한국 공공기관 사이트에서 흔함)는 존재하지 않는 경로에도 HTTP 200을 반환하고 본문에 커스텀 에러 이미지만 표시합니다. 그래서 상태코드만으로는 부족할 수 있어, 본문에서 알려진 에러 문구도 함께 검사합니다.

  • use_default_indicators=False로 한국 공공기관용 기본 문구를 끌 수 있습니다 (다른 도메인/업무에서 오탐이 날 경우).

  • error_indicators로 사이트·업무별 에러 문구를 추가할 수 있습니다.

반환: [{"url": ..., "status_code": ..., "ok": bool, "error": str | None}]

discover_selector(url, timeout=15, min_group_size=3, top_n=3)

목록형 페이지에서 최신 항목의 CSS 선택자를 자동으로 추정합니다. 표의 행 (tr), 목록의 항목(li) 등 3개 이상 반복되는 형제 요소 중 첫 항목의 텍스트에서 날짜 패턴이 발견되는 그룹을 찾아 선택자 후보를 만듭니다.

새 게시판을 온보딩할 때(=아직 추출셀렉터가 없을 때), 브라우저를 열어 직접 선택자를 찾는 대신 이 도구로 먼저 시도해볼 수 있습니다. 여러 기관/여러 게시판을 등록해야 하는 경우 이 단계가 반복적으로 드는 비용을 크게 줄여줍니다.

단, 이 도구는 휴리스틱이며 항상 맞지는 않습니다. 목록이 날짜순 정렬이 아니거나 상단 고정글이 있으면 자동으로 뽑힌 "첫 항목"이 실제 최신글이 아닐 수 있습니다. 반환된 sample_textextracted_date가 그럴듯한지 확인한 뒤 update_page_cache로 반영하는 것을 권장합니다. confidence가 낮거나 후보가 비어 있으면 브라우저로 직접 확인합니다.

반환: {"url": ..., "candidates": [
    {"selector": ..., "extracted_date": "YYYY-MM-DD",
     "sample_text": ..., "group_size": int, "confidence": float},
    ...
]}

실제 사이트 검증 (2026-09-15): 서로 다른 구조의 게시판 3곳 (테이블형 공지사항, 테이블형 보도자료, li 그리드형 포토 갤러리)에서 모두 정확한 선택자와 날짜를 신뢰도 1.0으로 찾아냄.

check_recency(cache_file, timeout=15, stale_after_months=3)

URL과 CSS 선택자를 담은 마크다운 표 파일을 읽어, 각 URL에서 선택자로 뽑은 텍스트를 날짜로 해석하고 stale_after_months 기준(달력 기준 개월 수)으로 "최근에 갱신됐는지"를 판정합니다.

표 파일은 파이프(|) 마크다운 표여야 하며, 최소 다음 두 컬럼이 필요합니다 (대소문자 무시, 국문/영문 모두 허용):

  • URL 컬럼: URL 또는 url

  • 선택자 컬럼: 추출셀렉터 또는 selector

선택자는 브라우저 document.querySelector와 동일한 CSS 선택자 문법을 씁니다. 값이 비어 있으면 실제 접속 없이 수동확인필요(선택자없음)를 반환합니다 — 이 경우 에이전트가 한 번 브라우저로 열어 선택자를 찾아 update_page_cache로 기록해야 합니다.

반환: [{"콘텐츠영역": ..., "URL": ..., "최신게시일": "YYYY-MM-DD" | None,
        "판정": "정상" | "최신성 지연" | "수동확인필요(...)" | "접속오류",
        "경과일": int | None, "비고": str}]

예시 표 (targets.md)

| 콘텐츠영역 | URL | 추출셀렉터 |
| --- | --- | --- |
| 공지사항 | https://example.go.kr/notice | table.BoardTable tbody tr:first-child td:nth-child(5) |
| 채용공고 | https://example.go.kr/jobs | .job-list li:first-child .date |

update_page_cache(cache_file, updates)

URL을 키로 하는 마크다운 파이프 표 파일을 갱신합니다. 특정 업무에 종속되지 않은 범용 도구라, 헤더가 있는 파이프 표라면 무엇이든 이 방식으로 갱신할 수 있습니다 (점검 결과 캐시, 진행 상황 표, 담당자 배정 표 등).

updates의 각 항목은 URL(또는 url)을 반드시 포함해야 하며, 그 외 키는 테이블 헤더의 컬럼명과 정확히 일치할 때만 갱신됩니다.

반환: {"applied": [...], "not_found": [...]}

설계 원칙

  • 이 서버는 판단이 아니라 계산만 합니다. 문구 개선, 맥락 판단이 필요한 항목은 여전히 에이전트가 직접 확인해야 합니다.

  • 특정 조직·업무·언어에 종속되지 않도록 컬럼명·기준(개월 수)·에러 문구를 모두 매개변수로 조정할 수 있게 설계했습니다.

  • 별도 인프라(호스팅, 상시 구동)가 필요 없습니다. MCP 클라이언트가 필요할 때 자식 프로세스로 실행하고 세션이 끝나면 종료합니다.

유래

이 프로젝트는 국립원예특작과학원 홈페이지 현행화 점검 도구 (website_monitoring_md)에서 쓰던 로직을 다른 기관/업무에서도 쓸 수 있도록 일반화해 분리한 것입니다.

라이선스

MIT

Available Tools

3 tools
check_recencyA

URL과 CSS 선택자를 담은 마크다운 표 파일을 읽어, 각 URL에서 선택자로 뽑은 텍스트를 날짜로 해석하고 stale_after_months 기준으로 판정한다.

표 파일은 파이프(|) 마크다운 표여야 하며, 최소한 다음 두 컬럼이 필요하다 (대소문자 무시, 영문/국문 모두 허용):

  • URL 컬럼: "URL" 또는 "url"

  • 선택자 컬럼: "추출셀렉터" 또는 "selector"

선택자는 브라우저의 document.querySelector와 동일한 CSS 선택자 문법을 쓴다. 값이 비어 있으면 실제 접속을 시도하지 않고 '수동확인필요(선택자없음)'을 반환한다 — 목록이 JS로 렌더링되어 정적 요청으로 못 읽는 경우도 마찬가지다. 이런 경우는 에이전트가 브라우저로 한 번 열어 선택자를 찾아 update_page_cache로 기록해야 한다.

반환: [{콘텐츠영역, URL, 최신게시일, 판정, 경과일, 비고}]

ParametersJSON Schema
NameRequiredDescriptionDefault
timeoutNo
cache_fileYes
stale_after_monthsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It discloses the markdown table format requirements, CSS selector syntax, the behavior when selector is empty (returns a specific string without network attempt), and the JS-rendered case. It also mentions the return format, making behavior transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a few sentences, front-loaded with the core purpose, and includes necessary operational details without excessive length. It is well-structured and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool that reads a file and checks recency, the description covers input format, edge cases (empty selector, JS-rendered), and return structure. However, it leaves parameter semantics for timeout and stale_after_months unexplained, and does not describe possible values of '판정' (judgment) field, though an output schema may cover that. Slightly incomplete but adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so description must compensate. It explains cache_file format in detail (markdown table with URL and selector columns, case-insensitive, Korean/English allowed). However, it does not explain timeout or stale_after_months beyond their names, leaving ambiguity about meaning and units. Partial compensation only.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reads a markdown table file containing URLs and CSS selectors, extracts text from each URL via the selector, interprets it as a date, and judges recency based on stale_after_months. This is a specific verb+resource and distinguishes from siblings like check_links and update_page_cache.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly explains when the tool cannot be used (empty selector or JS-rendered content) and instructs the agent to use update_page_cache after browser inspection. It doesn't explicitly compare with check_links, but the distinct purpose makes usage clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_page_cacheA

URL을 키로 하는 마크다운 파이프 표 파일을 갱신한다. 특정 업무에 종속되지 않은 범용 도구로, 헤더가 있는 파이프 표라면 무엇이든 이 방식으로 갱신할 수 있다 (점검 결과 캐시, 진행 상황 표, 담당자 배정 표 등).

updates 각 항목은 반드시 'URL'(또는 'url')을 포함해야 하며, 그 외 키는 테이블 헤더에 있는 컬럼명과 정확히 일치할 때만 갱신된다. URL이 일치하는 행이 없으면 해당 항목은 건너뛰고 'not_found' 목록에 보고한다.

ParametersJSON Schema
NameRequiredDescriptionDefault
updatesYes
cache_fileYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses that the tool updates a file, that keys must match column names exactly, and that unmatched URLs are skipped and reported in a 'not_found' list. However, it does not mention whether the operation is destructive (overwrites the file), whether it is idempotent, or what happens if the file or table format is invalid. These gaps are notable for a mutation tool without annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is moderately long but each sentence serves a purpose: defining the action, establishing generality, and detailing matching and error behavior. It is front-loaded with the core action and avoids filler. A slight trim could improve conciseness, but it remains efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (matching rules, multiple potential file types) and the presence of an output schema (not shown but indicated), the description covers the essential behavioral contract: how updates are applied, key matching, and not_found handling. It does not address edge cases like file existence or malformed tables, but for a general-purpose updater, it is reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It effectively explains the 'updates' parameter: each item must contain 'URL' (or 'url'), and other keys correspond to table column names, with exact-match semantics. It also clarifies the 'not_found' reporting. The 'cache_file' parameter is only implied as the target file, which is adequate given its self-explanatory name.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb (갱신한다, updates) and the resource (markdown pipe table file keyed by URL). It also provides examples of use cases (cache, progress table, assignment table), making the tool's purpose unambiguous. While it doesn't explicitly contrast with siblings (check_links, check_recency), those are clearly different actions, so differentiation is implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description identifies the tool as a general-purpose utility ('범용 도구') and specifies conditions for use: updates must include 'URL', and other keys must exactly match column headers. It also explains the behavior when a URL is not found. However, it does not explicitly state when NOT to use it or recommend an alternative tool, though siblings are clearly different functions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedcheck_links
    • First observedcheck_recency
    • First observedupdate_page_cache

TDQS

A4.1/5.0

Scored across 3 tools

Disambiguation4/5

The three tools have distinct purposes: checking link availability, checking content recency, and updating a cache table. However, check_links and check_recency both involve URL checking, which could cause slight confusion, though their descriptions clarify the different intents.

Naming Consistency4/5

Tool names follow a consistent verb_noun pattern: check_links, check_recency, update_page_cache. The verbs 'check' and 'update' are clear, and the nouns are descriptive. Minor inconsistency: 'page_cache' is more specific than the actual generic table update capability, but the naming pattern is consistent.

Tool Count4/5

Three tools is a reasonable, focused set for a web monitoring/checking server. It is slightly on the smaller side but each tool serves a distinct, necessary function for the apparent purpose of link checking, recency monitoring, and cache management.

Completeness4/5

The tool set covers the core workflow: checking links, checking recency, and updating a cache table. A minor gap is the lack of a tool to read/retrieve the cache table or manage error indicators directly, but the described workflow is mostly complete for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers