Fetch 도구

Fetch 도구 (Fetch Tool)

에이전트가 하나 이상의 HTTP/HTTPS URL에서 내용을 가져오는 방법을 설명해요. 읽기 전용이라 GET 요청만 지원하고 SSRF 보호도 기본 제공돼요.

출처: 문서

본문

fetch 도구는 에이전트가 하나 이상의 HTTP/HTTPS URL에서 내용을 가져오게 해 줘요. 읽기 전용이에요 — GET 요청만 지원해요. robots.txt를 존중하고, 응답 크기를 제한하며(URL당 1MB), 내용을 일반 텍스트, Markdown(HTML에서 변환), 원시 HTML로 반환할 수 있어요.

참고 GET 전용 fetch 도구는 POST, PUT, DELETE 등 다른 메서드를 지원하지 않아요. 요청 본문이나 호출별 커스텀 헤더도 노출하지 않아요(도구셋은 여전히 모든 요청에 정적 자격 증명 헤더를 붙일 수 있어요). 다른 동사로 REST 엔드포인트를 호출하려면 API 도구나 OpenAPI 도구셋을 사용하세요.

구성

toolsets:
  - type: fetch

옵션

속성 타입 기본값 설명
timeout int 30 기본 요청 타임아웃(초, 도구 호출별로 덮어쓰기 가능)
allowed_domains array[string] 없음 도구가 fetch할 수 있는 호스트의 허용 목록. 설정하면 목록에 없는 호스트의 모든 URL은 네트워크 호출 전에 거부됨. blocked_domains와 상호 배타적
blocked_domains array[string] 없음 도구가 fetch하면 안 되는 호스트의 거부 목록. 이 패턴 중 하나와 일치하는 호스트의 URL은 네트워크 호출(robots.txt 포함) 전에 거부됨. allowed_domains와 상호 배타적
allow_private_ips boolean false 비공개 IP 주소(루프백, RFC1918, 링크로컬 — 169.254.169.254의 클라우드 메타데이터 엔드포인트 포함 — 멀티캐스트, 미지정 주소)로 다이얼링을 허용. localhost/내부 서비스에 도달하려면 필요. 아래 SSRF 보호 참고
headers map[string]string 없음 도구셋이 발행하는 모든 요청(robots.txt 포함)에 붙는 정적 HTTP 헤더. 값은 시크릿용 ${env.VAR}를 지원. 호출자가 제공한 항목이 기본 User-Agent와 형식 기반 Accept 헤더를 덮어씀. 자격 증명이 타사 호스트로 새지 않도록 크로스 호스트 리다이렉트에서 헤더는 제거됨. 아래 커스텀 헤더 참고

도메인 매칭

allowed_domains와 blocked_domains의 도메인 패턴은 다음 규칙을 사용해요(대소문자 구분 안 함):

  • 베어 도메인 — example.com은 호스트 example.com과 docs.example.com 같은 모든 하위 도메인과 매칭. 접미사를 공유하는 무관한 호스트(예: badexample.com)와는 매칭 안 함
  • 선행 점 — .example.com은 엄격한 하위 도메인(docs.example.com, a.b.example.com)만 매칭하고 정점 example.com은 매칭 안 함
  • 와일드카드 글로브 — .example.com은 선행 점 형태의 별칭이고, 정점은 제외. *는 선행 *. 토큰으로만 유효(foo., ..example.com, 베어 * 같은 항목은 구성 로드 시 거부)
  • IP 리터럴 — IP 주소는 정확히 매칭(169.254.169.254)
  • CIDR 범위 — 169.254.0.0/16, 10.0.0.0/8, ::1/128, fc00::/7. URL의 호스트가 네트워크 안의 IP로 파싱되면 매칭. 호스트명 호스트는 CIDR 패턴과 절대 매칭 안 함. 잘못된 CIDR은 구성 로드 시 거부
  • FQDN 형식 URL(http://example.com./)의 끝 점은 매칭 전에 제거되므로 거부 목록 항목을 우회할 수 없음

두 목록은 상호 배타적이에요: 하나의 fetch 도구셋은 allowed_domains 또는 blocked_domains 중 하나만 설정할 수 있어요.

목록이 설정되면 모든 리다이렉트 대상이 같은 목록을 다시 확인돼요. 허용된 오리진에서 금지된 호스트로 리다이렉트되는 요청은 리다이렉트에서 어떤 데이터도 읽기 전에 거부돼요.

경고 한계 매칭은 URL 호스트에 대한 순수 문자열 기반이에요. DNS 해석을 수행하지 않고 대체 IP 인코딩(십진수 2852039166, 16진수 0xa9.0xfe.0xa9.0xfe, 8진수 등)을 정규화하지 않아요. IPv4-매핑 IPv6 주소는 IPv4 형태로 정규화돼요. 특정 IP에 대한 접근을 거부해야 한다면 대체 인코딩도 함께 나열하거나 네트워크 계층에서 차단하세요.

커스텀 타임아웃

toolsets:
  - type: fetch
    timeout: 60

커스텀 헤더

모든 요청에 정적 헤더 — 보통 자격 증명 — 를 붙여요. 값은 ${env.VAR} 보간을 지원해서 시크릿을 YAML 밖에 두고, 크로스 호스트 리다이렉트에서는 헤더가 제거되므로 리다이렉트 체인이 타사 호스트로 새지 않아요:

toolsets:
  - type: fetch
    allowed_domains:
      - docs.internal.example.com
    headers:
      Authorization: "Bearer ${env.INTERNAL_DOCS_TOKEN}"
      X-Internal-Client: "docker-agent"

경고 자격 증명 헤더는 허용 목록과 함께 쓰세요 headers가 자격 증명(예: Authorization)을 담을 때는 그것을 받을 특정 호스트로 allowed_domains를 설정하세요. Stdlib은 이미 크로스 도메인 리다이렉트에서 작은 허용 목록(Authorization, Cookie, WWW-Authenticate)을 제거하고, fetch 도구는 추가로 모든 운영자 제공 헤더를 크로스 호스트 리다이렉트에서 제거해요 — 하지만 허용 목록이 우발적 유출에 대한 가장 강한 보장이에요.

특정 도메인으로 제한

toolsets:
  - type: fetch
    allowed_domains:
      - docker.com          # docker.com 및 *.docker.com
      - github.com          # github.com 및 *.github.com
      - .githubusercontent.com  # 하위 도메인만, 예: raw.githubusercontent.com

민감 호스트 차단

toolsets:
  - type: fetch
    blocked_domains:
      - 169.254.169.254       # 클라우드 메타데이터 엔드포인트 (리터럴 IP)
      - 169.254.0.0/16        # 전체 링크로컬 범위 (CIDR)
      - 10.0.0.0/8            # RFC1918 사설 범위
      - "*.internal.example.com"  # 모든 하위 도메인 (와일드카드)
      - internal.example.com  # 내부 기업 호스트명

참고 기본으로 이미 차단돼요 안전을 위해 루프백, RFC1918, 링크로컬(169.254.169.254 포함), 멀티캐스트, 미지정 주소를 blocked_domains에 추가할 필요는 없어요 — fetch 도구는 DNS 해석 후 다이얼 시점에 이미 그 범위로의 연결을 거부해요. 위 예시는 네트워크 호출 전에 그런 호스트를 거부하고 싶거나(그리고 에이전트에 더 명확한 오류 메시지를 보여주고 싶거나), allow_private_ips: true를 설정한 뒤 특정 하위 집합을 거부하고 싶을 때만 유용해요.

SSRF 보호와 localhost 도달

기본적으로 fetch 도구는 비공개 IP 주소로의 연결을 거부해요 — 공개 호스트에 대한 DNS가 그중 하나로 해석될 때조차요(그래서 DNS 리바인딩도 차단돼요). 검사는 DNS 해석 후 다이얼 시점에 일어나고, 다음을 거부해요:

  • 루프백 — 127.0.0.0/8, ::1(http://localhost/...와 http://127.0.0.1/...를 막는 것)
  • RFC1918 사설 범위 — 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
  • 링크로컬 — 169.254.0.0/16(IPv4, 클라우드 메타데이터 엔드포인트 169.254.169.254 포함) 및 fe80::/10(IPv6)
  • 멀티캐스트와 미지정 주소(0.0.0.0, ::)
  • IPv4-매핑 IPv6 — ::ffff:127.0.0.1이나 ::ffff:169.254.169.254 같은 주소는 IPv4 형태로 정규화되어 그에 따라 차단

이것이 기본인 이유는 LLM 기반 fetch가 전형적인 SSRF(Server-Side Request Forgery) 벡터이기 때문이에요. 프롬프트 주입 URL이 그 외에는 에이전트를 실행하는 호스트의 내부 서비스, 클라우드 메타데이터, 관리자 인터페이스에 도달할 수 있어요.

에이전트가 정당하게 localhost나 내부 서비스를 호출해야 한다면 allow_private_ips: true로 옵트인하세요:

toolsets:
  - type: fetch
    allow_private_ips: true
    allowed_domains:
      - localhost
      - 127.0.0.1
      - 10.0.0.0/8            # 내부 기업 범위

경고 허용 목록과 함께 쓰세요 allow_private_ips: true만 설정하면 SSRF 표면이 다시 드러나요. 에이전트가 실제로 필요한 특정 내부 호스트나 CIDR(예: localhost, 127.0.0.1, 내부 CIDR)로 도구를 제한하는 allowed_domains 항목과 함께 쓰기를 강력히 권장해요.

참고 allowed_domains는 DNS 해석 전에 확인되고(호스트명 기반 문자열), SSRF 검사는 DNS 해석 후에 일어나요(해석된 IP 기반). 즉 allowed_domains와 blocked_domains는 allow_private_ips와 무관하게 독립적으로 평가되고 계속 적용돼요. allowed_domains의 공개 호스트명이 사설 IP로 해석되면 allow_private_ips: true가 설정되지 않는 한 여전히 차단돼요.

도구 인터페이스

도구셋은 fetch 도구 하나를 노출하며 파라미터는 다음과 같아요:

파라미터 타입 필수 설명
urls array[string] ✓ fetch할 하나 이상의 HTTP/HTTPS URL(모두 GET으로)
format string ✓ 출력 형식: text, markdown, html. 요청 시 HTML 응답은 text/markdown으로 변환됨
timeout integer ✗ 호출별 요청 타임아웃(초). 도구셋 기본값을 덮어씀. 유효 범위: 1–300

응답은 URL당 1MB로 제한돼요. robots.txt를 통해 에이전트의 user-agent를 허용하지 않는 호스트는 명확한 오류와 함께 건너뛰어져요.

팁 Fetch vs API 도구 에이전트가 런타임에 임의 공개 URL을 읽어야 할 때는 fetch를 사용하세요. 명명된 도구로 특정 구조화 HTTP 엔드포인트(비-GET 동사 포함)를 노출하려면 API 도구를 사용하세요.

도메인 필터링

allowed_domains, blocked_domains, allow_private_ips 옵션으로 fetch 도구가 도달할 수 있는 호스트를 제어할 수 있어요. 전체 참조는 위 옵션 표와 도메인 매칭 섹션에 있어요.

핵심 요점:

  • allowed_domains — 허용 목록; 나열된 호스트만(베어 도메인 항목은 하위 도메인 포함) 도달 가능
  • blocked_domains — 거부 목록; allowed_domains와 상호 배타적(둘 다 설정하면 구성 오류)
  • allow_private_ips — 기본 false; 루프백/RFC-1918/링크로컬 주소에 도달하려면 true로 설정
  • 같은 allow_private_ips 플래그는 api, openapi, a2a, 원격 mcp 도구셋에서도 지원돼요

examples/fetch_domain_filtering.yaml에서 완전한 필터링 예시를, examples/remote_mcp_allow_private_ips.yaml에서 원격 MCP 도구셋의 동등한 패턴을 확인하세요.

더 알아보기 (Learn more)