webcheck-mcp
This server is a general-purpose MCP tool that lets AI agents perform deterministic web checks with code instead of reading pages in a browser, saving tokens.
discover_urls: Collect a list of URLs to check via explicit list, sitemap/robots.txt parsing, or BFS crawling of same-domain links (with JS redirect stub detection).
check_links: Check whether URLs are accessible in parallel, using status codes and known error-page indicators to catch false HTTP 200 responses.
discover_selector: Automatically guess CSS selectors for the latest items on list-style pages by finding repeated elements whose text contains dates.
check_recency: Read a markdown table of URLs and CSS selectors, extract dates, and report whether each page has been updated within a configurable number of months.
update_page_cache: Update markdown pipe-table files keyed by URL, useful for caching check results, progress trackers, assignment tables, etc.
Designed to be domain-independent: column names, error phrases, and staleness thresholds are configurable, and it requires no persistent infrastructure.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@webcheck-mcpCheck whether the URLs in targets.md are accessible and update the cache table."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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이 있는 곳, 없는 곳, 이미 점검 대상이 정해진 곳) 우선순위를 두고 자동으로 전환합니다.
explicit_urls가 있으면 그대로 사용 — 점검 대상이 이미 정해져 있는 경우.sitemap.xml(또는robots.txt의Sitemap:위치)이 있으면 파싱 — sitemap index(하위 sitemap 여러 개)도 재귀적으로 처리합니다. 일부 CMS는 존재하지 않는 경로도 HTTP 200으로 응답하므로(check_links가 다루는 문제와 동일), 실제 XML sitemap 형식이 아니거나 에러 문구가 감지되면 "sitemap 없음"으로 취급하고 다음 단계로 넘어갑니다.둘 다 없으면
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개(전체메뉴 페이지 포함)를 정상적으로 찾아냄.
check_links(urls, timeout=10, max_workers=10, error_indicators=None, use_default_indicators=True)
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_text와 extracted_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 toolscheck_linksA
URL 목록의 접속 가능 여부를 병렬로 확인한다.
일부 CMS는 존재하지 않는 경로도 HTTP 200으로 응답하고 본문에 커스텀 에러 이미지/문구만 표시한다 (HTTP 상태코드만으로는 404를 못 잡음). 이를 보완하기 위해 본문에서 알려진 에러 문구를 함께 검사한다.
use_default_indicators=False로 하면 한국 공공기관 CMS용 기본 문구를 끄고 error_indicators만 사용한다 (다른 도메인/업무에서 오탐을 피하고 싶을 때).
error_indicators로 사이트나 업무별 에러 문구를 추가할 수 있다.
반환: [{url, status_code, ok, error}]
| Name | Required | Description | Default |
|---|---|---|---|
| urls | Yes | ||
| timeout | No | ||
| max_workers | No | ||
| error_indicators | No | ||
| use_default_indicators | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure, and it delivers substantial insight: the tool runs in parallel, performs body-content analysis in addition to status-code checks, and explains the default Korean public-institution error indicators and how to customize them. It does not explicitly define edge-case behavior such as what counts as 'ok' on network errors or how timeout/max_workers affect results, but the core non-obvious algorithm is well exposed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and economical: a one-line summary, a brief explanation of the underlying problem (fake 200s), a short bullet list for two key parameters, and a one-line return format. Every sentence earns its place and the main action is front-loaded before the explanatory paragraphs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is highly complete for a read-only link-checking tool: it explains the true behavior, gives configuration guidance for error indicators, and provides the return shape. It does not further define the meaning of each return field (e.g., what 'ok' and 'error' represent) nor describe timeout/max_workers semantics, but the output shape and defaults are visible in the schema, leaving only minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 does so for the two most nuanced parameters: use_default_indicators (toggle off to avoid cross-domain false positives) and error_indicators (add site/task-specific phrases). The urls parameter is implied by the phrase "URL 목록". However, timeout and max_workers are left entirely to the schema, and no explicit behavior is described for them, though their names and defaults are reasonably self-explanatory.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action: "URL 목록의 접속 가능 여부를 병렬로 확인한다" (checks the accessibility of a URL list in parallel). It further clarifies the purpose by explaining that it not only uses HTTP status codes but also inspects page content for known error phrases, distinguishing it from a naive link checker. This clearly differentiates it from sibling tools like check_recency 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when this tool is appropriate: checking URL accessibility, especially when a CMS falsely returns HTTP 200 for nonexistent paths. It also gives usage guidance for the indicator knobs, such as setting use_default_indicators=False to avoid false positives in other domains, and adding error_indicators for site-specific phrases. However, it does not explicitly mention when to prefer check_links over check_recency or update_page_cache, so it stops short of a full exclusions statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_recencyA
URL과 CSS 선택자를 담은 마크다운 표 파일을 읽어, 각 URL에서 선택자로 뽑은 텍스트를 날짜로 해석하고 stale_after_months 기준으로 판정한다.
표 파일은 파이프(|) 마크다운 표여야 하며, 최소한 다음 두 컬럼이 필요하다 (대소문자 무시, 영문/국문 모두 허용):
URL 컬럼: "URL" 또는 "url"
선택자 컬럼: "추출셀렉터" 또는 "selector"
선택자는 브라우저의 document.querySelector와 동일한 CSS 선택자 문법을 쓴다. 값이 비어 있으면 실제 접속을 시도하지 않고 '수동확인필요(선택자없음)'을 반환한다 — 목록이 JS로 렌더링되어 정적 요청으로 못 읽는 경우도 마찬가지다. 이런 경우는 에이전트가 브라우저로 한 번 열어 선택자를 찾아 update_page_cache로 기록해야 한다.
반환: [{콘텐츠영역, URL, 최신게시일, 판정, 경과일, 비고}]
| Name | Required | Description | Default |
|---|---|---|---|
| timeout | No | ||
| cache_file | Yes | ||
| stale_after_months | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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' 목록에 보고한다.
| Name | Required | Description | Default |
|---|---|---|---|
| updates | Yes | ||
| cache_file | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
3 tool updates
v0.1.0- First observed
check_links - First observed
check_recency - First observed
update_page_cache
TDQS
Scored across 3 tools
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.
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.
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.
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
Related MCP Connectors
MCP tools for AI agents: render URLs to image/PDF, check link health, convert HTML/CSV/JSON.
Web tools for AI agents: scrape pages to Markdown, audit SEO, detect tech stacks, check sitemaps
- mcpOAuthcom.screenshotink
Screenshot, diff, audit and sitemap-capture any web page — 5 MCP tools for AI agents.
Read a URL as clean markdown, screenshot a website, url to PDF. Web access for agents, no signup.
Related MCP Servers
- AlicenseCqualityCmaintenanceMCP server for safely reading public URLs for AI agents, providing tools to fetch, extract, cache, and inspect web content as evidence.15MIT
- AlicenseNot gradedqualityDmaintenanceExposes Futurepedia AI tool crawling and universal web page parsing as MCP tools for assistants.MIT
- FlicenseNot gradedqualityDmaintenanceProvides a versatile set of utility tools for LLMs, including text processing, web fetching, and search capabilities, all accessible via MCP.-
- FlicenseNot gradedqualityCmaintenanceEnables AI assistants to fetch webpages, convert them to Markdown, index into SQLite FTS5, and query the knowledge base through MCP tools.-