Skip to main content
Glama

Sora (空)

일본 웹을 AI 에이전트에서 이용하기 위한 Self-hosted MCP / REST 통합 서버
All-in-One, Zero-Middleware Web Scraping & Japanese Life Infrastructure Engine for AI Agents

Sora는 LLM이나 AI 에이전트(Claude Desktop, Cursor, Cline, OpenCodeInterpreter, Dify 등)가 일본의 웹 공간과 일상 인프라를 자유롭고 안전하게 탐색·조작하기 위한 All-in-One MCP / REST 서버입니다.

외부 DB(Redis / PostgreSQL)나 메시지 큐를 전혀 필요로 하지 않고, 헤드리스 Chromium과 일본어 CJK 폰트를 내장한 단일 컨테이너 / 단일 바이너리만으로 월 800엔 VPS에서 즉시 가동합니다.

flowchart LR
    subgraph Clients["AI Clients / Agents"]
        Claude["Claude Desktop / Cursor"]
        Agents["LangChain / AutoGen / Dify"]
    end

    subgraph Sora["Sora All-in-One (Distroless / Bun)"]
        direction TB
        MCP["MCP Server (Streamable HTTP / SSE)"]
        REST["Hono REST API (OpenAPI 3.0)"]
        Auth["Timing-Safe Auth & SSRF Guard"]
        LRU["True LRU In-Memory Cache"]
        
        subgraph Engine["Dual Scrape Engine"]
            Fast["Static Fetch + Readability + AI Chunker"]
            Browser["Stealth Chromium + Browser DSL (Tabs/Clicks)"]
        end

        subgraph JP["Japan Life Infrastructure"]
            JMA["気象庁 1,805自治体 天気予報"]
            Transit["Yahoo! 路線乗換・IC運賃"]
            Yahoo["Yahoo! リアルタイム(X)/知恵袋/ニュース/画像/動画"]
        end
    end

    subgraph Web["Public Internet"]
        Sites["Web Sites / PDFs / SPAs"]
        PublicData["気象庁 / Yahoo / X"]
    end

    Clients <-->|MCP / REST| Sora
    Fast --> Sites
    Browser --> Sites
    JP --> PublicData

⚡ 5초 만에 연결되는 Quickstart (Claude Desktop / Cursor / Cline)

사용 중인 AI 에이전트의 설정 파일(claude_desktop_config.json 등)에 아래 내용을 추가하기만 하면 16종의 강력한 도구 모음이 즉시 활성화됩니다.

① Remote MCP (HTTP / SSE) 연결

Sora 컨테이너를 기동한 상태에서 URL을 지정합니다:

{
  "mcpServers": {
    "sora": {
      "url": "http://localhost:3016/mcp"
    }
  }
}

② Docker / Podman에서 1 커맨드 기동

docker run -d -p 3016:8000 --name sora ghcr.io/ikenokazuki/sora:latest

Related MCP server: Agent Toolbox

🌟 주요 특징과 강점 (Why Sora?)

  1. 🗾 일본 일상 인프라 & 웹 탐색의 완전 포괄:

    • 해외제 도구(Firecrawl / Tavily)로는 대응할 수 없는 「Yahoo! 지식백과」「X (Twitter) 실시간 속보」「기상청 공식 오픈데이터 직결(전국 1,805개 시구정촌 자동 선정)」「전철 환승 안내」를 단일 MCP로 제공.

  2. ⚡ 압도적인 밀리초 응답 & 초저전력 메모리:

    • Bun 네이티브 컴파일로 API 응답 1.5ms, 상주 메모리 JS 힙 ~32MB / 전체 ~140MB. AI 에이전트의 대기 시간을 극한까지 단축.

  3. 📦 완전 올인원 & 제로 미들웨어:

    • Redis, PostgreSQL, 외부 워커 큐 등은 전혀 불필요. 단일 바이너리 / 단일 컨테이너만으로 즉시 완결.

  4. 🛡️ Distroless(셸 없음) & 엄격한 보안:

    • 베이스 이미지에 gcr.io/distroless/cc-debian12를 채택. 컨테이너 내에 /bin/sh, bash, curl 등이 존재하지 않아 RCE(임의 코드 실행) 공격을 무력화.

    • SSRF / DNS Rebinding 차단, 상수 시간 비교에 의한 Timing Attack 방지, 브라우저 세션 소유권 분리, DoS 방어(Body Limit 10MB)를 표준 장비.

  5. 🕹️ 스테이트풀 브라우저 조작 DSL:

    • openfillclickscreenshotevaluate의 복수 턴 대화형 브라우저 세션을 API / MCP에서 직접 제어.


📊 성능 & 아키텍처 비교

항목

Sora (본 도구)

Firecrawl (셀프호스트)

일반적인 Node/Python 제 MCP

API / 헬스체크 응답

1.5 ms (0.0015s)

20〜50 ms

30〜100 ms

기동 시간 (콜드 스타트)

< 10 ms

10〜30 초 (복수 서비스)

1〜3 초

상주 메모리 소비 (RSS)

약 140 MB (JS 힙 ~32MB)

2GB〜4GB+

250MB〜800MB

이미지 크기 (Total)

약 1.18 GB (Chromium+일본어 폰트 내장)

4GB〜6GB+ (복수 이미지 합계)

800MB〜2.5GB

필요한 컨테이너 구성

단일 컨테이너 (All-in-One)

5〜6 개 (Redis/PG/Workers)

복수 MCP 프로세스가 난립

보안 설계

Distroless (셸 없음·비root)

일반 Debian/Alpine

일반 Debian/Ubuntu

일본 로컬 정보

완전 대응 (날씨·환승·지혜백과·X)

비대응 (Web만)

플러그인 개별 도입 필요


⏱️ 각 엔드포인트의 실측 응답 속도 (Measured Latency: Cold vs Cached)

실기 로컬 서버에서의 「최초 취득(비캐시 시)」과 「캐시 히트 시」의 실측 레이턴시 목록입니다. AI 에이전트가 사고·생성하는 시간(1〜3초)과 비교해 압도적으로 빠르게 응답합니다.

엔드포인트

최초 취득 (비캐시 시)

캐시 시 (2회째 이후)

처리 내용·기술 특징

GET /health

0.2 〜 1.8 ms

API 생사 감시·헬스체크(Bun 최적화)

GET /weather (기상청 날씨)

약 38 ms

0.4 〜 0.7 ms

기상청 공식 CDN(jma.go.jp) 직결 파스+1,805 자치체 자동 선정

POST /scrape (정적 최속 모드)

약 79 ms

0.5 〜 1.0 ms

Web 페이지의 고속 페치+Markdown 본문 추출

POST /scrape (SPA 자동 승격 / 브라우저 묘화)

약 1.2 〜 1.6 초

0.5 〜 1.0 ms

정적 취득에서 공백/Bot 화면 검출 시 자동으로 Stealth Chromium으로 승격해 Markdown 추출

POST /transit/route (환승 안내)

약 390 ms

0.6 〜 7.0 ms

Yahoo! 노선 정보 스크레이프(최적 경로·IC 운임 계산)

POST /search/realtime (X속보)

약 440 ms

0.6 ms

Yahoo! 실시간 검색(X 트윗&이미지 추출)

POST /search/news (뉴스)

약 480 ms

0.6 ms

Yahoo! 뉴스 최신 기사 검색

POST /search/image / video

450 〜 550 ms

0.6 ms

Yahoo! 이미지·동영상 검색

POST /search/chiebukuro (지혜백)

420 〜 500 ms

0.6 ms

Yahoo! 지혜백 Q&A 검색

POST /search/suggest (서제스트)

약 820 ms

0.5 ms

Yahoo! 오토컴플리트 관련어 보완

POST /browser/action (최초 실행)

약 1.4 초

Stealth Chromium 기동+묘화+클릭+대기+스크린샷+Markdown 추출

POST /browser/action (세션 계속)

약 0.5 〜 0.8 초

기존 탭(sessionId)에서의 추가 액션 실행

⚡ 내부 엔리치먼트·AI 최적화 처리의 실측 속도 (In-Memory Latency)

외부 LLM API를 거치지 않고, 모든 Bun 네이티브 및 최적화 알고리즘으로 1밀리초 미만(< 1ms) 으로 완결됩니다.

처리·기능

처리 시간 (1회당 실측치)

특징·알고리즘

독서 시간·문자 통계 계산 (calculateContentStats)

0.03 ms (31 µs)

CJK/영단어의 고속 카운트&추정 독서 시간 산출

출처·인용 링크 추출 (extractCitationsFromMarkdown)

0.06 ms (62 µs)

정규 표현+문맥 컨텍스트 슬라이싱

RAG 시맨틱·청킹 (chunkMarkdownContent)

0.13 ms (138 µs)

제목·코드 블록 경계를 고려한 시맨틱 분할

검색 결과의 중복·유사 제외 (dedupSearchResults)

0.33 ms (335 µs)

50건의 N-gram Jaccard 유사도 판정

PII 개인정보 자동 마스킹 (maskPiiInText)

0.55 ms (557 µs)

메일·전화·Luhn 크레딧 카드 판정&치환

초고속 추출형 자동 요약 (TL;DR) (generateExtractiveSummary)

0.97 ms (970 µs)

TF-IDF 유사 중요 문장 추출 알고리즘

검색어 Markdown 강조 하이라이트 (highlightMatches)

9.1 ms

정규 표현에 의한 구문 안전한 <mark> 태그 삽입


🏛️ 설계 사상 (Design Philosophy & Principles)

Sora는 다음 4가지 코어 설계 원칙에 기반해 구축되었습니다:

  1. ✂️ 오컴의 면도날(Occam's Razor & Zero-Middleware):

    • "필요가 없다면 많은 것을 정립해서는 안 된다. 요건을 충족하는 가장 단순한 구성이 최선의 구성이다."

    • Redis, PostgreSQL, 외부 큐, 중후한 마이크로서비스군을 전부 배제. 「단일 컨테이너·단일 바이너리」 만으로 동작하며, 월 800원 VPS나 Raspberry Pi에서 수만 리퀘스트 클라우드까지 고장 없이 상주합니다.

  2. 🛡️ 스텔스와 생환율의 파레토 최적(Stealth & Pareto Optimum):

    • 단순히 「0ms로 기계적 액세스」를 하면 상대 서버의 WAF나 Cloudflare에 즉시 IP가 BAN되어 성공률은 0%로 떨어집니다.

    • 동일 도메인에 연속 액세스 시 150ms + Jitter(0〜100ms 요동) 을 자동 삽입하고, 타이핑에도 15〜40ms의 인간적 지연을 부여. AI에서 본 체감 속도를 손상시키지 않으면서 확실히 데이터를 가져오는 생환율을 최우선으로 합니다.

  3. 🔒 디스트로레스에 의한 견고한 보안(Distroless by Design):

    • 컨테이너 내에 /bin/sh, bash, curl, apt가 존재하지 않으므로, 만에 하나 미지의 취약성이 있어도 공격자가 셸을 탈취할 여지(RCE: 임의 코드 실행)가 원리적으로 없습니다. 비root 실행 및 엄격한 SSRF 차단을 표준 장착.

  4. 🗾 공적 오픈데이터 직결·지속 가능성(Sustainable & Autonomous):

    • 날씨 예보는 기상청 공식 오픈데이터 CDN(jma.go.jp)에 직접 액세스. 전국 1,805개 시구촌명의 제로 밀리초 자동 해결과 30분 LRU 캐시로 상대 서버에 대한 부하를 최소화하면서 영구히 자율 가동합니다.


1. 퀵스타트

1.1 컨테이너 기동 (Docker / Podman)

GitHub Container Registry (GHCR)에서 1 커맨드로 즉시 기동할 수 있습니다:

docker run -d \
  --name sora \
  -p 3016:8000 \
  -e API_KEY="your-secret-api-key" \
  -e ENABLED_MODULES="all" \
  ghcr.io/ikenokazuki/sora:latest

1.2 MCP 클라이언트 설정(Claude Desktop / Cursor / Cline / Windsurf 등)

Streamable HTTP 연결(권장·표준)

설정 파일(예: claude_desktop_config.json이나 Cursor의 MCP 설정)에 다음을 추가합니다:

{
  "mcpServers": {
    "sora": {
      "url": "http://localhost:3016/mcp",
      "headers": {
        "Authorization": "Bearer your-secret-api-key"
      }
    }
  }
}

SSE 연결(레거시 SSE 클라이언트용)

{
  "mcpServers": {
    "sora": {
      "url": "http://localhost:3016/sse",
      "headers": {
        "Authorization": "Bearer your-secret-api-key"
      }
    }
  }
}

(※ API 키가 미설정인 경우 headers는 생략 가능합니다)


2. 제공 MCP 도구 목록 (전 16 도구 / 4개 모듈)

Sora는 목적에 따라 4개의 논리 모듈로 구성되어 있습니다. 환경 변수 ENABLED_MODULES(기본값: all, 또는 web,browser,yahoo,life)로 활성화할 카테고리를 자유롭게 커스터마이즈할 수 있습니다.

┌──────────────────────────────────────────────────────────────────────────┐
│                         Sora - Modular MCP                               │
├─────────────────┬───────────────────┬──────────────────┬─────────────────┤
│ 🌐 Core Web     │ 🤖 Browser Action │ 🇯🇵 Yahoo Services │ 🗾 Daily Life   │
│ (`web`)         │ (`browser`)       │ (`yahoo`)        │ (`life`)        │
│ ・search_web    │ ・browser_action  │ ・search_image   │ ・search_route  │
│ ・scrape        │   (クリック/入力/ │ ・search_video   │   (乗換案内)    │
│ ・scrape_batch  │    スクショ/JS実行│ ・search_news    │ ・get_weather   │
│ ・search_deep   │    セッション保持)│ ・search_chiebukuro│ (気象庁天気)  │
│ ・map_site      │                   │ ・search_realtime│                 │
│ ・crawl_site    │                   │ ・search_trend   │                 │
│                 │                   │ ・suggest_keywords│                │
└─────────────────┴───────────────────┴──────────────────┴─────────────────┘

🌐 Module 1: Core Web & Crawling (ENABLED_MODULES=web)

Web 검색과 본문 스크레이핑, 일괄 병행 취득, 심층 통합 검색, 사이트맵 분석, 재귀 크롤링.

도구 이름

설명

식별 속성

주요 인자

search_web

웹 검색을 실행하고, 검색 상위의 제목·요약 스니펫·URL을 가져옵니다. 도메인 필터링·제외·기간 지정을 지원합니다.

각 항목에 source: "web"

- query (string, 필수): 검색 키워드- includeDomains (string[], 선택): 필터링할 도메인- excludeDomains (string[], 선택): 제외할 도메인- updated (string, 선택): 기간 지정 ("all", "day", "week", "year")

scrape

지정한 URL의 웹 페이지 또는 PDF를 스크레이핑하고, 본문을 Markdown 형식으로 추출합니다. SPA 사이트나 Bot 차단 화면은 자동으로 Chromium 렌더링합니다. RAG 청킹·출처 추출·읽기 시간·개인정보 보호·테이블 JSON 추출·요약 생성 지원.

source: "web"

- url (string, 필수): 대상 URL / PDF- maxChars (number, 선택): 최대 문자 수 (기본값: 10000)- mode (string, 선택): "auto" (스마트 자동 판정, 기본값), "fast" (정적 최속), "browser" (Stealth Chromium)- formats (string[: 선택): ["markdown", "html", "rawHtml", "links", "screenshot", "jsonLd", "images", "tables"]- chunkMarkdown (boolean, 선택): RAG용 시맨틱 청킹 수행 여부- chunkSize (number, 선택): 청크 문자 수 기준 (기본값: 1000)- extractCitations (boolean, 선택): 출처·인용 링크 목록 추출 여부- validateLinks (boolean, 선택): 링크 도달 가능성·상태 병렬 검증 여부- extractSummary (boolean, 선택): 요약형 자동 요약(TL;DR) 생성 여부- maskPii (boolean, 선택): 이메일·전화번호·신용카드 등 개인정보 자동 마스킹 여부- formatAsPrompt (boolean, 선택): LLM용 표준 XML 래퍼 형식 생성 여부- highlightMatches (boolean, 선택): 검색 일치 단어 하이라이트 여부- webhookUrl (string, 선택): 완료 알림 대상 Webhook URL- onlyMainContent (boolean, 선택): 기사 본문만 추출 여부 (기본값: true)- selectors (object, 선택): 정밀 추출용 CSS 선택자 연상 배열- clipSelector (string, 선택): 요소 클립 스크린샷용 CSS 선택자- headers / cookies (object/array, 선택): 커스텀 헤더 / Cookie- removeSelectors (string[], 선택): 제거 대상 노이즈 선택자- retries (number, 선택): 재시도 횟수 (0~3)- proxyUrl (string, 선택): 경유할 프록시 URL

scrape_batch

여러 웹 페이지 URL을 지정하고, 도메인 스로틀링을 유지하면서 빠르게 병렬 스크레이핑하여 한 번에 반환합니다.

각 결과에 source: "web"

- urls (string[], 필수): 스크레이핑 대상 URL 배열 (최대 20건)- concurrency (number, 선택): 병렬 워커 수 (기본값: 3, 최대: 5)- (기타 scrape와 동일한 모든 옵션 지원)

search_deep

Firecrawl / Tavily 호환 통합 심층 검색. 웹 검색 + 상위 사이트 본문 자동 스크레이핑 + 실시간 검색을 한 번에 종합합니다.

웹 결과: source: "web"X 결과: source: "x"

- query (string, 필수): 검색 키워드- limit (number, 선택): 본문 획득 건수 (기본값: 5, 최대: 20)- scrapeContent (boolean, 선택): 본문 포함 여부 (기본값: true)- includeRealtime (boolean, 선택): 실시간 검색 포함 여부 (기본값: true)- formats (string[, 선택): ["markdown", "html", "rawHtml", "links", "screenshot"]- onlyMainContent (boolean, 선택): 기사 본문만 추출 여부 (기본값: true)- extractHighlights (boolean, 선택): 각 페이지에서 쿼리 관련 하이라이트 추출 여부 (기본값: false)- includeDomains / excludeDomains (string[, 선택)- updated (string, 선택): 기간 지정 ("all", "day", "week", "year")- proxyUrl (string, 선택): 사용할 프록시 URL

map_site

지정한 웹 사이트의 sitemap.xml이나 내부 링크를 탐색하여, 사이트 내 전체 URL 목록(사이트맵)을 고속으로 추출합니다.

-

- url (string, 필수): 대상 베이스 URL- limit (number, 선택): 획득 건수 (기본값: 200, 최대: 1000)- includeSubdomains (boolean, 선택)- proxyUrl (string, 선택): 사용할 프록시 URL

crawl_site

지정한 URL 하위의 페이지를 재귀적으로 크롤링하고, 여러 페이지 본문을 한 번에 수집합니다.

각 결과: source: "web"

- url (string, 필수): 크롤링 시작 URL- maxPages (number, 선택): 최대 획득 페이지 수 (기본값: 10, 최대: 50)- maxDepth (number, 선택): 최대 링크 깊이 (기본값: 2)- formats (string[, 선택): ["markdown", "html", "rawHtml", "links", "screenshot"]- webhookUrl (string, 선택): 크롤링 완료 알림 대상 Webhook URL- proxyUrl (string, 선택): 사용할 프록시 URL


💡 LLM / Agent 연동 시 모범 사례 & limit 조정 가이드

에이전트나 RAG 애플리케이션에서 웹 검색·스크레이핑·크롤링을 활용할 때, 획득 건수(limit)의 설정에 따라 레이텐시와 응답 품질이 크게 달라집니다.

1. 획득 건수를 늘렸을 때의 장점과 단점

항목

이점

단점·리스크

권장 설정

통합 심층 검색 (/search)

더 넓은 소스에서 정보를 망라할 수 있음.

레이턴시 증가: 1020개 사이트를 병렬로 가져오면 응답 시간이 515초로 지연.LLM 컨텍스트 비대화: 대량의 전문을 전달하면 토큰 소비가 증가하고 중요 정보가 묻힘(Lost in the Middle 현상).

기본값 5(최대 20)

사이트 내 크롤링 (/crawl)

문서 전체의 망라적 지식 수집이 가능.

시간·리소스 소비: 페이지 수에 비례하여 처리 시간이 증가.

기본값 10(최대 50)

사이트맵 탐색 (/map)

사이트 전체 구조를 즉시 파악 가능.

・텍스트 처리만으로 부하가 극히 작음.

기본값 200(최대 1000)

2. 가장 정확도 높은 LLM 활용 베스트 프랙티스

[!TIP] 더 효과적인 접근법:

  1. 스니펫과 전문의 구분 사용: 검색 스니펫(search_web) 자체는 10~20건 반환하여 개요를 넓게 파악하면서, 전문 스크레이프 대상(search_deeplimit)은 상위 3~5건으로 한정하는 것이 가장 빠르고 정확도가 높습니다.

  2. 하이라이트 추출 병용: extractHighlights: true(query 지정)를 활성화하면, Structure & Proximity-Aware BM25+ 엔진(제목 문맥 계승·구문 완전 일치·근접도 스코어링·KWIC 스니펫 생성)에 의해 LLM이 긴 페이지 전체를 읽는 대신 쿼리와 관련된 가장 중요한 단락·문장만 집중적으로 읽을 수 있어, 환각을 방지하면서 토큰 소비를 70~90% 절감할 수 있습니다(외부 LLM 불필요, 0.3ms로 로컬 동작).

  3. 전 엔드포인트 공통 메타데이터(Firecrawl / Tavily 호환): publishedTime(게시일/갱신일), author(저자명), siteName(사이트명)을 OGP / JSON-LD / HTML 메타태그에서 자동 추출하여 Frontmatter 및 JSON 응답에 첨부. LLM이 정보의 신선도(팩트체크)를 즉시 판별 가능.

  4. GFM 신택스 하이라이트 언어 보존: <pre><code class="language-python"> 등에서 프로그래밍 언어명을 정확히 식별하여 Markdown 출력 시 ```python으로 재현.

  5. 자동 토큰 압축 & 노이즈 제거: 빈 링크, 무효한 JavaScript 링크, 불필요한 중복 빈 줄을 자동 클렌징(cleanMarkdownTokens)하고, 쿠키 동의 배너(OneTrust / Cookiebot 등)도 완전히 제거하여 LLM 컨텍스트를 항상 깨끗하게 유지.

  6. robots.txt 사이트맵 자동 발견: /robots.txt에서 변칙 배치된 Sitemap URL을 자동 감지하고, Sitemap Index를 최대 1,000건까지 재귀 탐색.

  7. 크롤링 시 스트리밍: 다수 페이지를 순회할 때는 POST /crawl/stream(SSE)을 이용하여 1페이지 획득 완료 시마다 순차 수신·처리함으로써, 전체 완료를 기다리지 않고 즉시 사용자나 LLM에게 중간 응답을 반환할 수 있습니다.

3. 실측 벤치마크와 확장성 특성(로컬 실측값)

처리

건수·페이지 수

평균 레이턴시(ms)

스루풋

특성·비고

사이트 내 크롤링 (/crawl)

maxPages: 5(구 기본값)

358 ms

13.9 pages/sec

3중 병렬 페치로 극히 고속

maxPages: 10(신 기본값)

341 ms

29.3 pages/sec

병렬 큐 효율화로 구 기본값과 동등한 소요 시간

maxPages: 20

2,046 ms

9.8 pages/sec

20페이지 전문 수집을 약 2초에 완료

maxPages: 50(신 상한)

4,685 ms

10.7 pages/sec

50페이지 순회도 5초 미만으로 안정 동작

사이트맵 탐색 (/map)

limit: 100(구 기본값)

826 ms

-

XML/HTML 파싱만으로 극히 경량

limit: 200(신 기본값)

882 ms

-

100건 시와 거의 동일한 응답 속도(+56ms)

limit: 1000(신 상한)

808 ms

-

1,000건 탐색에도 오버헤드 거의 없음

통합 심층 검색 (/search)

limit: 3(구 기본값)

약 1.4초

-

Web 검색 + 상위 3건 병렬 스크레이프

limit: 5(신 기본값)

약 2.0~3.4초

-

Web 검색 + 상위 5건 병렬 스크레이프

limit: 20(신 상한)

약 4~8초

-

광범위 소스의 딥 조사용


🤖 Module 2: Browser Actions & Automation (ENABLED_MODULES=browser)

폼 입력, 버튼 클릭, 화면 스크롤, JavaScript 실행, 스크린샷 촬영, 멀티턴 대화 세션.

도구명

설명

식별 속성

주요 인자

browser_action

Web 페이지를 열고 지정된 일련의 액션 시퀀스(클릭·문자 입력·키 입력·스크롤·대기·스크린샷·JS 실행·페이지 이동)를 실행하여 최종 화면의 Markdown이나 Base64 스크린샷을 반환. 버튼의 「표시 텍스트 지정 클릭」이나 sessionId에 의한 멀티턴 대화 세션 유지에 대응.

source: "browser"

- url(string, 임의): 시작/이동 URL- sessionId(string, 임의): 기존 세션 ID- createSession(boolean, 임의): 세션을 생성·유지할지 여부- closeSession(boolean, 임의): 세션을 종료할지 여부- actions(array, 임의): 실행 액션 목록(click, fill, press, select, scroll, wait, evaluate, navigate)- extract(object, 임의): { markdown: true, screenshot: true, html: false }- timeout(number, 임의): 타임아웃 ms


🇯🇵 Module 3: Yahoo! JAPAN Services (ENABLED_MODULES=yahoo)

일본 미디어·Q&A·트렌드·실시간 정보에 완전 특화된 검색군.

도구명

설명

식별 속성

주요 인자

search_image

Yahoo! JAPAN 이미지 검색을 실행하여 이미지 제목·이미지 URL·썸네일·이미지 크기·소스 원본 페이지를 획득.

각 아이템에 source: "image"

- query(string, 필수): 검색 키워드- limit(number, 임의): 획득 건수(기본값: 20, 최대: 50)

search_video

Yahoo! JAPAN 동영상 검색을 실행하여 동영상 제목·동영상 URL·재생 시간·배포처·썸네일을 획득.

각 아이템에 source: "video"

- query(string, 필수): 검색 키워드- limit(number, 임의): 획득 건수(기본값: 20, 최대: 50)

search_news

Yahoo!뉴스 검색을 실행하여 최신 뉴스 기사의 제목·개요·배포사·게시 일시·기사 URL을 획득.

각 아이템에 source: "news"

- query(string, 필수): 검색 키워드- limit(number, 임의): 획득 건수(기본값: 10, 최대: 50)

search_chiebukuro

Yahoo!지식인 Q&A 검색을 실행하여 질문 제목·답변 수·해결 상태·본문 스니펫을 획득.

각 아이템에 source: "chiebukuro"

- query(string, 필수): 검색 키워드- limit(number, 임의): 획득 건수(기본값: 10, 최대: 50)

suggest_keywords

Yahoo! JAPAN 오토컴플리트 제안을 획득하여 관련 검색어·보완 후보를 반환.

source: "suggest"

- query(string, 필수): 보완 키워드- limit(number, 임의): 획득 건수(기본값: 10, 최대: 30)

search_realtime

Yahoo! 실시간 검색을 실행하여 X(구 Twitter)의 최신 포스트(게시자·본문·게시 일시·미디어·URL)를 획득. 최신순(recent)과 화제순(popular) 전환에 대응.

각 아이템에 source: "x"

- query(string, 필수): 검색 키워드- sort(string, 임의): "recent"(최신순, 기본값) 또는 "popular"(화제순)- limit(number, 임의): 획득 건수(기본값: 20, 최대: 40)- page(number, 임의): 페이지 번호(기본값: 1)

search_trend

Yahoo 실시간 검색의 최신 트렌드(급상승 키워드 랭킹 20건)를 획득.

각 아이템에 source: "x"

- limit(number, 임의): 획득 건수(기본값: 20)


🗾 Module 4: Japan Daily Life & Transit (ENABLED_MODULES=life)

일본 대중교통·기상청 공식 오픈데이터에 직결된 생활 인프라 기능.

도구명

설명

식별 속성

주요 인자

search_route

일본 국내 전철 환승 안내. 역 간 최적 경로·소요 시간·환승 횟수·IC/티켓 운임을 탐색. 경유역 지정(최대 3개역), 일시 지정, 특급/신칸센 이용 플래그에 대응.

source: "transit"

- from(string, 필수): 출발역 이름(예 「도쿄」)- to(string, 필수): 도착역 이름(예 「신주쿠」)- via(string[], 임의): 경유역(최대 3개역)- timeType(string, 임의): "departure", "arrival", "first_train", "last_train"- ticket(string, 임의): "ic", "cash"- sortBy(string, 임의): "time", "transfer", "fare"

get_weather

기상청 공식 오픈데이터 직결에 의한 일본 전국 각지의 오늘·내일·모레 날씨 예보, 예상 기온, 강수 확률, 날씨 개황, 바람·파도 정보를 획득. 전국 1,805개 시구정촌명의 자동 해결에 대응.

source: "weather"

- city(string, 필수): 시구정촌명(예 「텐도시」「카루이자와」「하코네」「우라야스」「도쿄」) 또는 지점 ID(예 「130010」)- days(number, 임의): 예보 일수(1~3일, 기본값: 3)


3. REST API 사양

베이스 URL: http://localhost:3016(또는 배포처 도메인 URL)

3.1 헬스체크 & 메트릭스

GET /health

{
  "status": "ok",
  "service": "sora",
  "cachedEntries": 0,
  "chromiumAvailable": true,
  "yahooMcpAvailable": true,
  "mcpConnected": true,
  "timestamp": "2026-08-21T05:54:26.782Z"
}

GET /metrics(운영 통계·캐시 히트율·리소스 사용량)

{
  "status": "ok",
  "service": "sora",
  "uptimeSeconds": 1420,
  "cache": {
    "size": 42,
    "maxSize": 3000,
    "hits": 156,
    "misses": 48,
    "hitRatio": 0.7647
  },
  "activeSessions": 2,
  "chromium": {
    "available": true,
    "sharedConnected": true
  },
  "memory": {
    "rssMb": 86,
    "heapUsedMb": 34,
    "heapTotalMb": 58
  },
  "timestamp": "2026-08-22T04:20:00.000Z"
}

GET /metrics?format=prometheus 또는 Accept: text/plain(Prometheus 모니터링용 메트릭스)

Grafana / Prometheus 모니터링 스택에 그대로 도입할 수 있는 표준 텍스트 형식으로 출력합니다.

# HELP sora_uptime_seconds Process uptime in seconds
# TYPE sora_uptime_seconds gauge
sora_uptime_seconds 1420
# HELP sora_memory_rss_bytes Resident set size in bytes
# TYPE sora_memory_rss_bytes gauge
sora_memory_rss_bytes 90177536
# HELP sora_cache_hits_total Total cache hits
# TYPE sora_cache_hits_total counter
sora_cache_hits_total 156
# HELP sora_cache_hit_rate Cache hit rate
# TYPE sora_cache_hit_rate gauge
sora_cache_hit_rate 0.7647
# HELP sora_active_browser_sessions Active browser sessions count
# TYPE sora_active_browser_sessions gauge
sora_active_browser_sessions 2

3.2 단일 URL / PDF 스크레이프 (POST /scrape)

  • 요청:

{
  "url": "https://example.com/article",
  "maxChars": 30000,
  "mode": "auto",
  "formats": ["markdown", "jsonLd", "images", "links"],
  "onlyMainContent": true,
  "selectors": {
    "productName": "h1.product-title",
    "price": ".price-value",
    "buyLink": "a.btn-buy@href",
    "thumbnail": "img.main-photo@src"
  },
  "extractHighlights": true,
  "query": "新機能 リリース"
}
  • 응답 예:

{
  "url": "https://example.com/article",
  "title": "最新アップデートのお知らせ",
  "content": "---\ntitle: \"最新アップデートのお知らせ\"\nurl: \"https://example.com/article\"\npublishedTime: \"2026-08-22T10:00:00Z\"\nauthor: \"開発チーム\"\nsiteName: \"Tech Blog\"\n---\n\n...",
  "isTruncated": false,
  "contentType": "text/html",
  "source": "web",
  "renderedWithBrowser": false,
  "publishedTime": "2026-08-22T10:00:00Z",
  "author": "開発チーム",
  "siteName": "Tech Blog",
  "extracted": {
    "productName": "Sora プレミアムキーボード",
    "price": "¥24,800",
    "buyLink": "https://example.com/cart/add?id=123",
    "thumbnail": "https://example.com/images/feature.png"
  },
  "jsonLd": [
    {
      "@context": "https://schema.org",
      "@type": "NewsArticle",
      "headline": "最新アップデートのお知らせ"
    }
  ],
  "images": [
    {
      "url": "https://example.com/images/feature.png",
      "alt": "新機能の画面イメージ"
    }
  ],
  "highlights": [
    "本日より新機能の提供を開始いたします。"
  ]
}

[!TIP] 🇯🇵 일본어 레거시 사이트 자동 대응: Shift_JIS (CP932)EUC-JP 웹 사이트도 문자 코드를 자동 판정하여 디코딩합니다. 글자가 깨질 걱정이 없습니다.

📄 PDF 추출 강화: 여러 페이지의 PDF 문서는 <!-- Page 1 -->\n## Page 1처럼 페이지 번호 구분으로 구조화된 Markdown 출력되며, totalPages나 작성자 등의 메타데이터도 자동 추출됩니다.

✂️ 구문 안전 트리밍 & 토큰 견적: maxChars로 문자 수가 제한된 경우에도 열린 코드 블록(```)이나 테이블을 자동으로 안전하게 보정·폐쇄합니다. 또한 응답에는 추정 LLM 토큰 수 estimatedTokens가 부여됩니다.

🧩 RAG 최적화 시맨틱 청킹 (chunkMarkdown: true): 제목 계층(H1~H4)이나 문단·코드 블록을 깨지 않게 적절히 분할된 chunks: [{ index, heading, content, estimatedTokens }]를 자동 생성하여 벡터 검색이나 RAG에 즉시 투입할 수 있습니다.

🖼️ 이미지 메타데이터 & 캡션 추출 (formats: ["images"]): 각 이미지에 대해 URL 외에 <figcaption> 설명문(caption), width/height, 아이캐치 판정(isMainImage)을 자동 추출합니다.

🔗 페이지 내 링크의 건전성·도달성 판정 (validateLinks: true): 페이지 내 링크에 대해 경량 병렬 검증을 수행하고 HTTP 상태와 유효성 linksWithStatus: [{ url, status, ok }]를 반환합니다.

📚 출처·인용 링크 구조화 추출 (extractCitations: true): 본문 중의 외부 링크나 참고 문헌을 컨텍스트 문장과 함께 citations: [{ text, url, context }]로 자동 추출합니다.

⏱️ 읽는 시간 & 문자·단어 수 통계: 본문에서 characterCount, wordCount, 언어 특성에 따른 추정 읽는 시간 readingTimeMin(분)을 자동 산출하여 부여합니다.

🔔 비동기 Webhook 콜백 (webhookUrl): 장시간 배치 처리나 대규모 크롤링 완료 시 지정한 엔드포인트로 비동기적으로 결과 페이로드를 HTTP POST로 알립니다.

🛡️ PII 자동 마스킹 (maskPii: true): 이메일 주소, 일본 전화번호, 신용카드 번호(Luhn 검증) 등의 민감 정보를 자동으로 [EMAIL], [PHONE], [CREDIT_CARD]로 비식별화하여 LLM으로의 전송을 보호합니다.

📡 진행 상황 실시간 SSE 스트리밍 (POST /scrape/stream): startfetchrenderenrichdone 각 스테이지 진행 이벤트를 실시간으로 Server-Sent Events로 수신할 수 있습니다.

🎬 YouTube / 동영상 미디어 메타데이터 & 챕터 추출 (media): 동영상 페이지에서 재생 시간, 썸네일, 챕터 목록(타임스탬프 포함 목차)을 자동 구조화 추출합니다.

🤖 LLM 최적화 프롬프트 XML 자동 생성 (formatAsPrompt: true): Claude / GPT / Gemini가 가장 이해하기 쉬운 표준 <web_page url="..." title="...">...</web_page> 형식의 컨텍스트 래퍼 promptContext를 자동 생성합니다.

🖍️ 검색 키워드 본문 자동 강조 (highlightMatches: true): 지정한 query의 키워드를 본문 Markdown 내에서 <mark>키워드</mark>로 강조 표시한 highlightedContent를 얻을 수 있습니다.

📊 테이블 구조화 JSON 추출 (formats: ["tables"]): 페이지 내 표(<table>)를 { caption, headers, rows }의 구조화 JSON 배열로 직접 획득할 수 있습니다.

⚡ 초고속 추출형 자동 요약 (extractSummary: true): 외부 LLM API를 호출하지 않고 내부 알고리즘으로 밀리초 단위로 중요 문장(TL;DR 요약) summary: string[]을 자동 생성합니다.

🎯 검색 결과 중복 제거 (dedup: true): 뉴스 검색이나 실시간 검색에서 복사 붙여넣기 게시물이나 전재 기사를 유사도 판정으로 자동 제외하고 고유한 정보만 엄선합니다.

🔄 자동 재시도 정책 (retries & retryDelayMs): 연결 실패나 429/503 오류 시 지수 백오프로 자동 재시도하여 내결함성을 향상시킵니다.

📸 요소 지정 스크린샷 (clipSelector): 특정 요소(예: clipSelector: "#stock-chart")를 지정하여 해당 요소만 잘라낸 Base64 PNG를 획득할 수 있습니다.

🍪 커스텀 헤더 & Cookie 주입 (headers / cookies): 회원 사이트나 언어 지정(Accept-Language), 연령 인증 Cookie 등을 투과적으로 전송할 수 있습니다.

🧹 사용자 지정 노이즈 셀렉터 제거 (removeSelectors): removeSelectors: [".ad", ".comments", "#related-articles"]를 지정하고 특정 블록을 Markdown 변환 전에 철저히 제거할 수 있습니다.

📖 대화형 API 문서 (GET /docs): 브라우저에서 http://localhost:3016/docs에 접속하면 Swagger UI에서 전체 API를 직접 테스트 실행(Try it out)할 수 있습니다.


3.2.1 복수 URL 일괄 병렬 스크레이프 (POST /scrape/batch)

복수의 웹 페이지 URL을 지정하고 도메인별 스로틀링을 유지하면서 고속으로 서버 측에서 병렬 페치하여 일괄 획득합니다.

  • 요청 (POST):

{
  "urls": [
    "https://example.com/page1",
    "https://example.com/page2",
    "https://example.com/page3"
  ],
  "concurrency": 3,
  "maxChars": 10000,
  "mode": "auto",
  "formats": ["markdown", "jsonLd"]
}
  • 응답 예:

{
  "total": 3,
  "successful": 3,
  "failed": 0,
  "results": [
    {
      "url": "https://example.com/page1",
      "title": "Page 1 Title",
      "content": "...",
      "estimatedTokens": 450
    }
  ],
  "errors": []
}

3.3 대화형 브라우저 자동 조작 (POST /browser/action 또는 POST /action)

웹 페이지를 열고 클릭·텍스트 입력·스크롤·대기·스크린샷 촬영 등의 일련의 액션을 순차 실행하여 최종 결과를 획득합니다. 원샷 실행과 채팅으로 대화하면서 조작을 진행하는 스테이트풀·멀티턴 대화 세션 (sessionId) 모두 지원합니다.

① 원샷 실행(1회 완결)

  • 요청 (POST):

{
  "url": "https://example.com/search",
  "actions": [
    { "type": "fill", "selector": "input[name='q']", "text": "Sora" },
    { "type": "click", "text": "検索" },
    { "type": "wait", "selector": ".results-container", "ms": 5000 },
    { "type": "scroll", "direction": "down", "distance": 1000 }
  ],
  "extract": {
    "markdown": true,
    "screenshot": true,
    "html": false
  },
  "timeout": 30000
}
  • 응답 예:

{
  "source": "browser",
  "url": "https://example.com/search?q=Sora",
  "title": "検索結果 - Sora",
  "content": "---\ntitle: \"検索結果 - Sora\"\nurl: \"https://example.com/search?q=Sora\"\n---\n\n# 検索結果\n...",
  "screenshot": "iVBORw0KGgoAAAANSUhEUgA...",
  "actionLogs": [
    { "step": 1, "type": "fill", "target": "input[name='q']", "success": true, "elapsedMs": 42 },
    { "step": 2, "type": "click", "target": "検索", "success": true, "elapsedMs": 115 },
    { "step": 3, "type": "wait", "target": ".results-container", "success": true, "elapsedMs": 620 },
    { "step": 4, "type": "scroll", "target": undefined, "success": true, "elapsedMs": 510 }
  ],
  "renderedWithBrowser": true
}

② 스테이트풀·멀티턴 대화 세션(대화형 채팅용)

  • Turn 1 (세션 생성 & 화면 오픈):

{
  "url": "https://example.com/login",
  "createSession": true,
  "actions": [
    { "type": "fill", "selector": "#username", "text": "myuser" }
  ],
  "extract": { "screenshot": true }
}

(응답에서 "sessionId": "sess_a1b2c3d4"가 반환됩니다)

  • Turn 2 (열린 화면에서 계속 조작):

{
  "sessionId": "sess_a1b2c3d4",
  "actions": [
    { "type": "fill", "selector": "#password", "text": "mypassword" },
    { "type": "click", "text": "ログイン" },
    { "type": "wait", "selector": "#dashboard" }
  ],
  "extract": { "markdown": true }
}
  • Turn 3 (세션 종료 & 클린업):

{
  "sessionId": "sess_a1b2c3d4",
  "closeSession": true
}

(※ 조작이 5분간 끊긴 경우에도 자동 타임아웃으로 안전하게 메모리가 해제됩니다)


3.4 통합 심층 검색 (POST /search) & Web 검색 (POST /search/web)

  • 심층 검색 요청 (POST /search):

{
  "query": "2026年 AI 最新トレンド",
  "limit": 5,
  "scrapeContent": true,
  "includeRealtime": true,
  "updated": "week",
  "formats": ["markdown"]
}
  • HTML 형식으로 획득하는 경우:

{
  "query": "React 19 新機能",
  "formats": ["html"]
}
  • 중요 하이라이트만 추출하는 경우 (토큰 절약 모드):

{
  "query": "React 19 新機能 変更点",
  "extractHighlights": true
}
  • Web 검색 요청 (POST /search/web):

{
  "query": "新商品 発売情報",
  "includeDomains": ["example.com", "news.example.org"],
  "excludeDomains": ["spam.example.com"],
  "updated": "week"
}

3.4.1 사이트맵 탐색 (POST /map)

지정 도메인의 sitemap.xml이나 내부 링크를 탐색하여 사이트 내 전체 URL 목록을 추출합니다.

  • 요청:

{
  "url": "https://example.com",
  "limit": 200,
  "includeSubdomains": false
}

3.4.2 하위 페이지 재귀 크롤링 (POST /crawl & POST /crawl/stream)

지정 URL에서 하위 페이지를 재귀적으로 순회하여 복수 페이지의 Markdown/HTML/이미지/구조화 데이터를 일괄 수집합니다. includePatterns / excludePatterns에 의한 Glob 와일드카드 필터링을 지원합니다.

  • 요청 (일괄 획득):

{
  "url": "https://example.com/docs",
  "maxPages": 20,
  "maxDepth": 2,
  "includePatterns": ["/docs/**", "/guide/*"],
  "excludePatterns": ["/tag/**", "*.pdf"],
  "formats": ["markdown", "jsonLd", "images"]
}
  • SSE 스트리밍 (POST /crawl/stream): 페이지가 획득될 때마다 실시간으로 Server-Sent Events(start -> page -> done)를 배포.


3.5 이미지·동영상·뉴스·지식인·추천 검색

  • 이미지 검색 (POST /search/image): { "query": "富士山", "limit": 10 }

  • 동영상 검색 (POST /search/video): { "query": "簡単 レシピ", "limit": 10 }

  • 뉴스 검색 (POST /search/news): { "query": "AI ロボット", "limit": 10 }

  • 지식인 Q&A (POST /search/chiebukuro): { "query": "プログラミング 初心者", "limit": 10, "status": "solved" }

  • 키워드 보완 (POST /search/suggest): { "query": "天気", "limit": 10 }


3.6 전철 환승 안내 (POST /transit/route)

  • 요청:

{
  "from": "東京",
  "to": "新宿",
  "sortBy": "time"
}
  • 응답 예:

{
  "source": "transit",
  "from": "東京",
  "to": "新宿",
  "count": 3,
  "routes": [
    {
      "rank": 1,
      "summary": {
        "departureTime": "09:30",
        "arrivalTime": "09:44",
        "durationMinutes": 14,
        "transferCount": 0,
        "fare": {
          "ic": 209,
          "ticket": 210
        },
        "flags": {
          "isFastest": true,
          "isCheapest": true,
          "isEasiest": true
        }
      },
      "sections": [
        {
          "type": "move",
          "line": "JR中央線快速・高尾行",
          "from": "東京",
          "departureTime": "09:30",
          "to": "新宿",
          "arrivalTime": "09:44"
        }
      ]
    }
  ]
}

3.7 일본 전국 날씨 예보 (POST /weather / GET /weather / GET /weather/:city)

기상청 공식 오픈데이터 API(및 livedoor 날씨 호환 형식)를 직접 해석하여 일본 전국의 오늘·내일·모레 상세 기상 데이터를 완전 자율로 획득합니다.

본 기능의 장점 (Features & Advantages)

  • 완전 자율·공식 직결(제로 의존): 기상청 공식 CDN(jma.go.jp)에서 직접 기상 데이터를 획득·파싱.

  • 전국 1,805개 시구정촌 스마트 자동 해결: 기상청 공식 에어리어 정의(area.json)를 내장. "天童市""軽井沢""箱根""浦安""別府" 등의 시구정촌명·유명 지명에서 담당 기상대의 지점 ID를 0ms로 자동 선정. 현명 없는 입력에도 대응.

  • AI 에이전트 친화적 구조화 데이터: 3일간 날씨 자막, 바람·파도, 예상 최고/최저 기온(℃), 시간대별 강수 확률(0-6시, 6-12시, 12-18시, 18-24시), 기상대 발표 날씨 개황문(제목·본문)을 깨끗한 JSON으로 일괄 획득.

  • LRU 캐시에 의한 초고속 응답: 30분간 인메모리 LRU 캐시를 기본 탑재하여 기상청 서버로의 불필요한 중복 액세스를 자동 방지.

  • 요청 (POST):

{
  "city": "天童市",
  "days": 3
}
  • GET 요청: GET /weather?city=軽井沢&days=2 또는 GET /weather/箱根

  • 응답 예:

{
  "source": "weather",
  "cityId": "060010",
  "title": "村山 の天気",
  "publishedTime": "2026-08-21T17:00:00+09:00",
  "publicTime": "2026-08-21T17:00:00+09:00",
  "publishingOffice": "山形地方気象台",
  "location": {
    "area": "東北",
    "prefecture": "山形県",
    "city": "天童市"
  },
  "overview": "前線が、日本海から東北地方を通って、日本の東にのびています。村山地方では、夜遅くにかけて雷を伴い激しい雨が降る所がある見込みです。",
  "description": {
    "headline": "",
    "body": "前線が、日本海から東北地方を通って、日本の東にのびています...",
    "text": "..."
  },
  "forecasts": [
    {
      "date": "2026-08-21",
      "dateLabel": "今日",
      "telop": "曇り",
      "detail": {
        "weather": "くもり 所により 夕方 雨 で 雷を伴い 激しく 降る",
        "wind": "北の風 後 南東の風",
        "wave": null
      },
      "temperature": {
        "min": "22℃",
        "max": "31℃"
      },
      "chanceOfRain": {
        "T00_06": "30%",
        "T06_12": "0%",
        "T12_18": "0%",
        "T18_24": "30%"
      },
      "image": "https://www.jma.go.jp/bosai/forecast/img/200.svg"
    }
  ]
}

3.8 Yahoo 실시간 검색 & 트렌드 (POST /search/realtime / POST /search/trend)

  • 실시간 검색 (POST /search/realtime): { "query": "イベント名", "sort": "popular", "limit": 20, "page": 1 }

    • sort: "recent" (최신순, 기본값) 또는 "popular" (화제순 / 참여도순)

    • 각 포스트에 publishedTime (ISO 8601 문자열), author (사용자명 + @계정명), siteName: "X (Twitter)"가 통일 형식으로 자동 부여됩니다.

  • 급상승 트렌드 (POST /search/trend): { "limit": 20 }


3.9 사이트맵 & 크롤링 (POST /map / POST /crawl)

  • 사이트맵 (POST /map): { "url": "https://example.com", "limit": 200 }

  • 재귀 크롤링 (POST /crawl): { "url": "https://example.com/docs", "maxPages": 10 }


4. 보안 & 아키텍처

4.1 디스트롤레스(Distroless) 컨테이너 설계

  • 베이스 이미지: gcr.io/distroless/cc-debian12

  • 셸 없음·패키지 매니저 없음: 컨테이너 내에 /bin/shapt, curl은 전혀 존재하지 않아 공격자가 셸을 탈취할 여지가 없습니다.

  • 최소 권한 설계: 비 root 실행을 지원하며 Docker / Podman / Kubernetes 등의 표준 컨테이너 환경에서 안전하게 격리·실행 가능.

4.2 보안 & 성능 기능

  • 🛡️ 다중 SSRF & DNS Rebinding 방어:

    • 프라이빗 IP(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8 등), CGNAT(100.64.0.0/10), IPv6 특수 주소, 클라우드 메타데이터 IP(169.254.169.254)로의 내부 액세스를 차단.

    • dns.promises.lookup에 의한 사전 이름 해석을 수행하여 도메인 위장에 의한 DNS Rebinding 공격도 접속 전에 즉시 차단.

  • ⚡ Single-Flight Cache (In-flight Deduplication):

    • 동일 URL로의 병렬 요청 발생 시 Promise를 공유하여 1회의 외부 통신으로 집약. Thundering Herd(캐시 스탬피드)를 방지하고 외부 서버와 로컬 리소스를 보호.

  • 🚦 브라우저 동시 실행 제한 (Concurrency Control):

    • SimpleSemaphore로 Chromium 프로세스의 동시 실행 수(MAX_CONCURRENT_BROWSERS, 기본값 5)를 안전하게 제어. 서버의 CPU/메모리 고갈을 방지.

  • 🔒 Timing-Safe 인증 & Browser Session 소유권 연결:

    • API 키 대조에는 crypto.timingSafeEqual + SHA-256(상수 시간 비교)을 채택하여 Timing Attack을 방어.

    • Multi-turn 브라우저 세션(sessionId)을 작성자 토큰과 암호학적으로 연결하여 타인의 세션 탈취를 방지.

  • 🛡️ 임의 JavaScript 실행의 안전 제어 스위치 (ALLOW_BROWSER_EVALUATE):

    • 환경 변수 ALLOW_BROWSER_EVALUATE=false 또는 SAFE_BROWSER_MODE=true/browser/action에서의 evaluate 스크립트 실행을 즉시 무효화·락다운 가능.

  • 📐 공통 Zod 스키마 & OpenAPI 3.0 완전 자동 생성:

    • REST / MCP 양쪽에서 Zod 스키마에 의한 입력 검증을 통일.

    • /openapi.json은 코드 측 Zod 스키마에서 OpenAPI 3.0 사양을 100% 동적으로 자동 생성하여 문서의 괴리를 완전 방지.

    • 오류 응답은 { "error": "...", "code": "SSRF_BLOCKED", "status": 403, "retryable": false }처럼 AI 에이전트가 자기 수복·자율 판단하기 쉬운 구조를 제공.

  • ⏱️ Jitter 스로틀링 & 진정한 LRU 캐시:

    • 동일 도메인으로의 과도한 연속 액세스를 150ms + Jitter(0~100ms 변동)로 자동 억제.

    • 15~30분간의 진정한 LRU(액세스 시 최신화) 캐시와 10분마다의 정기 TTL 스윕으로 메모리 누수를 완전 방지.


5. 감사의 말·크레딧 (Acknowledgments)

Sora는 아래의 훌륭한 오픈소스 프로젝트, 공개 서비스, 공공 오픈데이터, 그리고 라이브러리 작성자 여러분의 훌륭한 기여에 힘입어 있습니다. 진심으로 감사드립니다.

🗾 데이터 소스 & 착상원 (Data Sources & Inspirations)

  • 기상청(JMA) 오픈데이터: jma.go.jp

    • 일본 전국의 고정밀 기상 예보·방재 데이터 및 전국 1,800개 이상의 에어리어 정의 데이터의 공개에 깊이 감사드립니다.

  • 날씨 예보 API(livedoor 날씨 호환) 설계 착상: tsukumijima/weather-api / weather.tsukumijima.net

    • livedoor 날씨 호환 포맷의 알기 쉬운 스키마 설계와 오랜 커뮤니티 기여에 감사드립니다.

  • Yahoo Japan Search MCP: mouseos/Yahoo-Japan-Search-MCP

    • Yahoo! JAPAN의 이미지·동영상·뉴스·지식인·추천 검색의 MCP 구현에 감사드립니다.

  • norikae-mcp: tysonwu/norikae-mcp

    • Yahoo! 노선 정보 스크레이핑에 의한 환승 안내 로직의 설계·구현에 감사드립니다.

🛠️ 기반 오픈소스·라이브러리 (Core Libraries & Ecosystem)


6. 면책 조항 (Disclaimer)

  • 비공식 서드파티 제작 도구:

    • 본 소프트웨어는 개인 개발·학술 연구·자사 내 이용을 목적으로 개발된 비공식(서드파티 제작) 도구입니다.

  • 상표에 대하여:

    • "Yahoo!" "Yahoo! JAPAN" 및 각 서비스명은 LINE 야후 주식회사의 상표 또는 등록 상표입니다. 본 프로젝트는 LINE 야후 주식회사와 일절 관계가 없습니다.

  • 이용 약관·법령의 준수:

    • 각 외부 서비스(Yahoo! JAPAN, 기상청 등)에 대한 액세스 시 상대방 서비스의 이용 약관, 가이드라인, robots.txt, 및 적용 법령을 준수하고 과도한 부하를 걸지 않도록 이용자 자신의 책임 하에 이용해 주십시오.

  • 책임의 한정:

    • 본 소프트웨어 이용으로 발생한 어떠한 손해(상대방 서비스로부터의 액세스 제한, 데이터의 완전성·정확성·최신성 등을 포함)에 대해 본 프로젝트의 개발자는 일절 책임을 지지 않습니다.


7. 라이선스 (License)

본 소프트웨어는 Business Source License 1.1 (BSL 1.1 / BUSL-1.1) 하에 공개되어 있습니다.

  • 자유·무료로 이용하실 수 있는 용도:

    • 개인 개발, 학술 연구, 비상업적 이용

    • 기업·조직 내 자사 시스템용 셀프호스트 이용(자사 제품이나 사내 도구를 지탱하는 내부 백엔드로 동작시키는 것)

    • 소스 코드의 수정·포크·내부 공유

  • 금지 사항 (Restriction):

    • 본 소프트웨어(또는 그 파생물)를 제3자용 "유료 클라우드 서비스" "유료 스크레이핑 / 검색 API 서비스" "매니지드 서비스"로 제공·재판매하는 것.

  • Change Date (오픈소스 전환일):

    • 2030년 8월 1일(또는 그 이전)에 자동으로 완전한 MIT License로 전환됩니다.

자세한 내용은 LICENSE를 확인해 주십시오.

Copyright (c) 2026 ikeno

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
3Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides comprehensive search capabilities including web search, content extraction, news search, academic search, and AI-powered multi-source research. Enables natural language access to web content and research through a production-ready MCP server.
  • A
    license
    Not graded
    quality
    C
    maintenance
    Production-ready MCP server for AI agents — web search, content extraction, screenshots, weather, finance, email validation, translation, and IP geolocation.
    10
    6
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A comprehensive MCP server providing 15 web tools including search, scraping, screenshots, SEO audits, and DNS/SSL checks through a single installation. It delivers clean, LLM-optimized outputs so AI agents can focus on reasoning rather than parsing raw HTML.
    15
    20
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    An APAC-native web scraping API for AI agents that provides tools for scraping, crawling, searching, and extracting structured data from websites, directly usable from MCP-compatible clients like Claude Desktop, Cursor, and Windsurf.
    7
    12
    MIT

View all related MCP servers

Related MCP Connectors

  • Hosted MCP with 91 agent tools: X, domains, SEO, Maps, Trends, Search, YouTube, TikTok, and more.

  • MCP server for Japan geodata: cadastral lot numbers (chiban) and reverse geocoding, for AI agents.

  • LLM-ready web search + instant answers + URL-to-clean-text fetch for agents and RAG.

View all MCP Connectors

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/ikenokazuki/Sora'

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