Skip to main content
Glama
JohnnyFoulds

markdown-for-agents-mcp

markdown-for-agents-mcp

npm version npm downloads Node.js codecov License: MIT

전체 JavaScript 렌더링을 통해 URL을 가져와 AI 에이전트를 위한 깔끔하고 토큰 효율적인 마크다운으로 변환하는 MCP(Model Context Protocol) 서버입니다.

대부분의 MCP 가져오기 도구는 일반 HTTP를 사용하므로 JavaScript를 실행하지 않고 서버가 보내는 내용만 확인합니다. 정적 사이트에는 효과적이지만, React, Vue, Angular, SPA 및 데이터를 동적으로 로드하는 모든 페이지에서는 내용이 비어 있거나 깨진 상태로 반환됩니다. 이 서버는 Playwright를 통해 실제 Chromium 브라우저를 실행하므로, 추출 전에 전체 페이지를 렌더링하여 사람이 보는 것과 동일한 콘텐츠를 가져옵니다.

Playwrightmarkdown-for-agents 라이브러리로 구동됩니다. 광고, 탐색 메뉴, 상용구(boilerplate)를 제거하여 원시 HTML 대비 최대 80% 적은 토큰을 제공합니다.


왜 Playwright인가?

기능

일반 HTTP 가져오기 도구

markdown-for-agents-mcp

정적 HTML 페이지

React / Vue / Angular 앱

JavaScript 렌더링 콘텐츠

단일 페이지 앱 경로

지연 로딩 / 무한 스크롤

원시 HTML 대비 토큰 효율성

보통

최대 80% 감소

봇 탐지 회피

없음

UA 회전, 웹드라이버 스푸핑

토큰 감소 예시: 일반적인 뉴스 기사 페이지는 약 150KB의 원시 HTML(약 40,000 토큰)입니다. Playwright 렌더링, DOM 정리 및 마크다운 변환 후 동일한 기사는 약 2,000 토큰이 되어 95% 감소합니다.


목차


기능

  • JavaScript 렌더링 — Playwright 기반 Chromium이 React, Vue, Angular 및 JS가 많이 사용되는 모든 페이지를 추출 전에 렌더링합니다.

  • 구조화된 출력 — 도구는 텍스트 응답과 함께 MCP SDK 1.11+와 호환되는 타입이 지정된 structuredContent(url, title, markdown, fetchedAt, contentSize)를 반환합니다.

  • 스마트 콘텐츠 추출 — 메인 콘텐츠 블록(main > article > #content > body)을 점수화하여 선택하고, 사이드바, 탐색 메뉴, 광고를 자동으로 제거합니다.

  • 토큰 효율성 — LLM에 적합한 압축된 마크다운을 생성하며, 벤치마크 결과 원시 HTML 대비 최대 80% 적은 토큰을 보여줍니다.

  • 웹 검색 — DuckDuckGo 검색 및 상위 결과에 대한 선택적 가져오기 및 변환 기능을 제공합니다.

  • LRU 캐시 — 15분 TTL이 적용된 50MB 메모리 내 캐시로 중복 가져오기를 방지합니다.

  • 도메인 필터링 — 추적기/소셜 도메인에 대한 내장 차단 목록; 요청별 허용/차단 목록 및 서버 수준 허용 목록 모드를 지원합니다.

  • 일괄 가져오기 — 구성 가능한 병렬 처리 기능을 갖춘 동시 다중 URL 가져오기.

  • HTTP 서버 모드 — HTTP 서버로 실행(--http [port] 또는 HTTP_PORT 환경 변수)하며 선택적으로 Bearer 토큰 인증을 지원합니다.

  • 프록시 지원PLAYWRIGHT_PROXY를 전달하여 Playwright 트래픽을 프록시를 통해 라우팅합니다.

  • 상태 모니터링health_check 도구가 캐시 및 가져오기 지표를 노출합니다.

  • 제로 구성 — 첫 실행 시 Chromium이 자동으로 설치됩니다.


설치

npm install -g markdown-for-agents-mcp

Chromium은 postinstall 스크립트를 통해 자동으로 다운로드됩니다. 실패할 경우 문제 해결을 참조하세요.

전역 설치 없이 npx를 사용하여 실행할 수도 있습니다:

npx markdown-for-agents-mcp

MCP 클라이언트 설정

MCP 클라이언트 구성에 서버를 추가하세요.

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json(macOS) 또는 %APPDATA%\Claude\claude_desktop_config.json(Windows)을 편집하세요:

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

VS Code (Copilot / Continue)

관련 MCP 확장 키 아래의 작업 공간 또는 사용자 settings.json에 추가하세요. 예:

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

Cursor / Windsurf / Zed

MCP 사양을 구현하는 모든 클라이언트는 이 서버를 사용할 수 있습니다. 명령 진입점은 markdown-mcp(전역 설치 후 PATH에서 사용 가능) 또는 로컬 빌드의 경우 dist/index.js의 전체 경로입니다.

환경 변수 재정의 사용

{
  "mcpServers": {
    "markdown": {
      "command": "markdown-mcp",
      "env": {
        "FETCH_TIMEOUT_MS": "60000",
        "LOG_LEVEL": "DEBUG"
      }
    }
  }
}

HTTP 서버 모드

stdio 대신 서버를 표준 HTTP 엔드포인트로 실행할 수 있습니다. 이는 공유 배포, Docker 또는 Streamable HTTP 전송을 선호하는 클라이언트에 유용합니다:

# Start on port 3456
markdown-mcp --http 3456

# Or use the env var
HTTP_PORT=3456 markdown-mcp

모든 MCP 트래픽은 POST|GET|DELETE /mcp에서 처리됩니다. Bearer 토큰을 요구하려면 MCP_AUTH_TOKEN을 설정하세요:

MCP_AUTH_TOKEN=mysecrettoken HTTP_PORT=3456 markdown-mcp

클라이언트는 모든 요청에 Authorization: Bearer mysecrettoken을 전달해야 합니다.


사용 가능한 도구

fetch_url

전체 JavaScript 렌더링을 통해 단일 URL을 가져와 깔끔한 마크다운을 반환합니다.

인수:

이름

타입

필수

설명

url

string

가져오고 변환할 URL

timeout

number

아니오

요청 시간 제한(ms) (FETCH_TIMEOUT_MS 재정의)

예시:

fetch_url(url="https://example.com/blog/post")

텍스트 출력 (항상 존재, 하위 호환성 유지):

# Blog Post Title

Source: https://example.com/blog/post

This is the main content of the article, stripped of navigation, ads, and boilerplate.

## Related Section

More content here...

---
*Converted by markdown-for-agents-mcp*

구조화된 출력 (MCP SDK 1.11+ 클라이언트에서 structuredContent를 통해 사용 가능):

{
  "url": "https://example.com/blog/post",
  "title": "Blog Post Title",
  "markdown": "# Blog Post Title\n\nSource: ...",
  "fetchedAt": "2026-04-06T17:00:00.000Z",
  "contentSize": 2048
}

fetch_urls

여러 URL을 동시에 가져와 URL당 하나의 섹션으로 결합된 마크다운을 반환합니다.

인수:

이름

타입

필수

설명

urls

string[]

가져올 URL들

timeout

number

아니오

요청당 시간 제한(ms)

예시:

fetch_urls(urls=[
  "https://example.com/post1",
  "https://example.com/post2"
])

텍스트 출력:

# Post 1 Title

Source: https://example.com/post1

...

---

# Post 2 Title

Source: https://example.com/post2

...

---

구조화된 출력 (structuredContent를 통해):

{
  "results": [
    {
      "url": "https://example.com/post1",
      "title": "Post 1 Title",
      "markdown": "...",
      "fetchedAt": "2026-04-06T17:00:00.000Z",
      "contentSize": 1820,
      "success": true
    },
    {
      "url": "https://example.com/post2",
      "title": "Post 2 Title",
      "markdown": "...",
      "fetchedAt": "2026-04-06T17:00:00.000Z",
      "contentSize": 2104,
      "success": true
    }
  ],
  "summary": { "total": 2, "succeeded": 2, "failed": 0 }
}

병렬 처리는 MAX_CONCURRENT_FETCHES(기본값: 5)에 의해 제어됩니다.


DuckDuckGo를 검색하고 선택적으로 상위 결과를 마크다운으로 가져옵니다. 봇 탐지를 피하기 위해 일반 HTTP 엔드포인트를 사용하며, 검색 자체에는 Playwright를 사용하지 않습니다.

인수:

이름

타입

필수

설명

query

string

검색 쿼리

maxResults

number

아니오

반환할 최대 결과 수 (기본값: 10)

allowedDomains

string[]

아니오

이 도메인의 결과만 포함

blockedDomains

string[]

아니오

이 도메인의 결과 제외

fetchResults

boolean

아니오

상위 결과 페이지를 가져와 마크다운으로 변환

timeout

number

아니오

요청 시간 제한(ms)

예시 — 검색만:

web_search(
  query="typescript tutorials",
  maxResults=5,
  allowedDomains=["typescriptlang.org", "github.com"]
)

예시 — 검색 및 가져오기:

web_search(
  query="react hooks guide",
  fetchResults=true,
  maxResults=3
)

텍스트 출력:

# Web Search Results

## Query: typescript tutorials
**Found 5 results in 1234ms**

### Results:

1. [TypeScript Handbook](https://www.typescriptlang.org/docs/)
   The TypeScript Handbook provides comprehensive documentation...

2. [Best TypeScript Tutorials](https://github.com/danistefanovic/build-your-own-typescript)
   Learn TypeScript by building your own compiler...

구조화된 출력 (structuredContent를 통해):

{
  "query": "typescript tutorials",
  "results": [
    { "title": "TypeScript Handbook", "url": "https://www.typescriptlang.org/docs/", "snippet": "...", "domain": "typescriptlang.org" }
  ],
  "fetchedContent": [
    { "url": "https://www.typescriptlang.org/docs/", "markdown": "..." }
  ],
  "durationMs": 1234
}

참고: allowedDomainsblockedDomains 인수는 검색 결과 필터링에만 적용됩니다. 결과가 이후에 가져와질 때는 서버 수준의 BLOCKLIST_DOMAINS / USE_ALLOWLIST_MODE 설정이 여전히 적용됩니다.


download_file

URL에서 바이너리 파일(PDF, 이미지, ZIP 등)을 다운로드하여 로컬 경로에 저장합니다. 일반 HTTP 클라이언트를 사용하며 Playwright는 필요하지 않습니다. SSRF 보호 및 도메인 차단 목록이 적용됩니다.

인수:

이름

타입

필수

설명

url

string

다운로드할 파일의 URL

outputPath

string

파일을 저장할 절대 로컬 경로 (상위 디렉토리가 존재해야 함)

예시:

download_file(
  url="https://example.com/report.pdf",
  outputPath="/tmp/report.pdf"
)

출력:

{
  "savedPath": "/tmp/report.pdf",
  "sizeBytes": 204800,
  "mimeType": "application/pdf",
  "filename": "report.pdf"
}

참고: /download/...와 같은 경로를 가진 URL은 fetch_url에서 차단되더라도 이 도구에서는 허용됩니다(바이너리 다운로드 체인 방지). HTML 페이지에는 fetch_url을 사용하세요. download_filetext/html 응답을 거부합니다.


health_check

현재 서버 상태, 캐시 지표 및 가져오기 통계를 반환합니다. 모니터링 및 디버깅에 유용합니다.

인수: 없음

출력 예시:

{
  "status": "healthy",
  "cache": {
    "hits": 47,
    "misses": 15,
    "currentSize": 12,
    "totalBytes": 4194304,
    "maxBytes": 52428800
  },
  "metrics": {
    "totalFetches": 62,
    "successCount": 59,
    "errorCount": 3,
    "avgDuration": 1840,
    "cacheUtilization": 76
  }
}

CLI 사용법

MCP 프로토콜 외부에서 사용할 수 있는 독립형 CLI(markdown-cli)가 포함되어 있습니다.

단일 URL

markdown-cli https://example.com

다중 URL (일괄 모드)

markdown-cli -b https://example.com https://example.org https://example.net

파일로 저장

markdown-cli https://example.com/article > article.md

바이너리 파일 다운로드

markdown-cli -d -o /tmp/report.pdf https://example.com/report.pdf

명령 참조

명령

설명

markdown-cli <url>

단일 URL을 가져와 마크다운 출력

markdown-cli -b <url1> <url2> ...

일괄 모드에서 여러 URL 가져오기

markdown-cli -d -o <path> <url>

바이너리 파일을 로컬 경로로 다운로드

markdown-cli --help

도움말 표시


구성

모든 설정은 시작 시 환경 변수에서 읽어오며 Zod로 검증됩니다. 잘못된 값은 설명적인 오류와 함께 0이 아닌 종료 코드를 발생시킵니다.

.env.example.env로 복사하여 시작하세요:

cp .env.example .env

참조

변수

기본값

설명

FETCH_TIMEOUT_MS

30000

가져오기 요청당 시간 제한(ms)

MAX_CONCURRENT_FETCHES

5

일괄 작업 시 최대 병렬 가져오기 수

MAX_REDIRECTS

10

오류 발생 전 최대 리디렉션 홉

MAX_CONTENT_LENGTH

100000

잘리기 전 최대 콘텐츠 크기(문자)

LOG_LEVEL

INFO

DEBUG, INFO, WARN 또는 ERROR

LOG_FORMAT

text

text(사람이 읽을 수 있음) 또는 json(구조화됨)

CACHE_MAX_BYTES

52428800

최대 LRU 캐시 크기 (50MB)

CACHE_TTL_MS

900000

캐시 항목 TTL (15분)

USE_ALLOWLIST_MODE

false

true일 경우 BLOCKLIST_DOMAINS에 있는 도메인만 허용

BLOCKLIST_DOMAINS

(비어 있음)

차단할(또는 허용 목록 모드에서 허용할) 쉼표로 구분된 도메인

BLOCKLIST_URL_PATTERNS

(비어 있음)

URL 경로별로 차단할 쉼표로 구분된 정규식 패턴

WEB_SEARCH_DEFAULT_TIMEOUT_MS

30000

검색 요청의 기본 시간 제한(ms)

DOWNLOAD_TIMEOUT_MS

60000

바이너리 파일 다운로드 시간 제한(ms)

HTTP_PORT

(설정 안 됨)

설정 시 stdio 대신 이 포트에서 HTTP 서버 시작

MCP_AUTH_TOKEN

(설정 안 됨)

모든 HTTP 요청에 필요한 Bearer 토큰 (HTTP 모드 전용)

PLAYWRIGHT_PROXY

(설정 안 됨)

Playwright용 프록시 서버 URL (예: http://proxy.example.com:8080)

PLAYWRIGHT_PROXY_BYPASS

(설정 안 됨)

프록시를 우회할 쉼표로 구분된 도메인

모든 로그는 MCP 프로토콜을 위해 `stdout

-
security - not tested
A
license - permissive license
-
quality - not tested

Latest Blog Posts

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/JohnnyFoulds/markdown-for-agents-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server