Skip to main content
Glama
dupletime-wq

Earnings Call MCP

by dupletime-wq

Earnings Call MCP

MarketBeat의 실적발표(어닝콜) 트랜스크립트를 검색·조회·본문 검색·번역할 수 있는 MCP 서버입니다. Cloudflare Workers 위에서 동작하며, 서버 상태를 따로 두지 않는(stateless) MCP HTTP 엔드포인트로 배포합니다.

제공하는 도구

도구

설명

search_earnings_calls

회사명 또는 티커로 트랜스크립트를 검색 (query, limit?)

get_earnings_call_transcript

URL 또는 티커(+분기)로 트랜스크립트 전문을 조회 (url?, ticker?, quarter?)

find_in_transcript

특정 트랜스크립트 내에서 키워드/문구로 본문 검색 (url?/ticker?+quarter?, query, maxMatches?)

translate_text

Workers AI(@cf/meta/m2m100-1.2b)로 텍스트 번역 (text, targetLanguage, sourceLanguage?)

get_earnings_call_transcript로 얻은 본문이나 find_in_transcript의 발췌문을 translate_text에 넘겨서 원하는 언어(예: 한국어)로 번역하는 흐름으로 사용하면 됩니다.

Related MCP server: sec-edgar-mcp

아키텍처

  • Worker 엔트리: src/index.ts/mcp 경로에서 @modelcontextprotocol/servercreateMcpHandler로 Streamable HTTP 트랜스포트를 처리합니다. (구 agents 패키지의 McpAgent는 feature-frozen 상태로 표시되어 있어, 최신 stateless McpServer + createMcpHandler 조합으로 구현했습니다.)

  • 스크레이핑/파싱: src/marketbeat/parser.ts — Workers 런타임 내장 HTMLRewriter로 스크립트/스타일/네비/푸터 등을 제거하고 본문 텍스트만 추출한 뒤, 발언자: 내용 패턴으로 화자 세그먼트를 분리합니다. 목록 페이지(/earnings/transcripts/, /stocks/{EXCHANGE}/{TICKER}/earnings/)에서는 /earnings/reports/{date}-{slug}-stock/ 형태의 링크를 파싱합니다.

  • 클라이언트: src/marketbeat/client.ts — 검색/티커 조회/캐싱을 담당. 대상 호스트가 설정된 MarketBeat 호스트와 다르면 요청을 거부합니다(SSRF 방지). 파싱된 결과는 Workers KV(TRANSCRIPT_CACHE)에 캐싱합니다 (트랜스크립트 14일, 최신 목록 30분).

  • 번역: src/translate.tsenv.AI 바인딩을 통해 Workers AI 번역 모델을 호출하는 얇은 래퍼.

로컬 개발 · 테스트

npm install
npm run typecheck   # tsc --noEmit
npm test            # vitest run (실제 workerd/HTMLRewriter 런타임에서 실행)
npm run dev          # wrangler dev (로컬 개발 서버, http://localhost:8787)

test/ 아래에 세 종류의 테스트가 있습니다.

  • parser.test.ts, client.test.ts: MarketBeat HTML 파서와 클라이언트(캐싱, 티커 탐색, SSRF 가드, 에러 처리)를 fixture HTML(test/fixtures/*.html)로 검증하는 유닛 테스트.

  • mcp.test.ts: @modelcontextprotocol/clientClient + InMemoryTransport로 실제 MCP 프로토콜(tools/list, tools/call)을 통해 4개 도구를 종단 검증하는 테스트. fetch와 Workers AI 바인딩은 테스트에서 주입한 가짜 구현으로 대체합니다.

  • worker.test.ts: Worker의 /mcp HTTP 엔드포인트가 실제로 initialize/tools/list JSON-RPC 요청에 응답하는지 확인하는 스모크 테스트.

37개 테스트가 모두 통과하며, wrangler dev --local로 실제 로컬 서버를 띄워 initializetools/listtools/call 전 과정도 curl로 직접 확인했습니다.

⚠️ 알려진 제한 사항

이 코드는 개발 샌드박스에서 marketbeat.com으로의 아웃바운드 네트워크가 차단된 상태로 작성되었습니다. 즉, 파서의 CSS/텍스트 추출 로직은 검색 결과로 확인한 실제 URL 패턴(/earnings/reports/{date}-{slug}-stock/)과 일반적인 실적발표 트랜스크립트 페이지 구조(제목 "{회사명} ({거래소}: {티커}) Q{n} {연도} Earnings Call Transcript", 본문의 발언자: 문장 반복 패턴)를 근거로 한 방어적 구현입니다. 실제 마켓비트 페이지의 마크업과 100% 동일하다고 보장할 수 없으므로, 배포 후 반드시 실제 사이트로 한 번 스모크 테스트를 해보시고, 결과가 이상하면 아래 두 파일만 고치면 됩니다.

  • src/marketbeat/parser.tsparseTranscriptTitle(제목 파싱 정규식), segmentTranscript(화자 분리 정규식) — 필요시 실제 페이지의 <h1> 텍스트나 문단 마크업에 맞춰 정규식/선택자만 조정하면 됩니다.

  • test/fixtures/*.html — 실제 페이지 구조로 교체하면 회귀 테스트가 그대로 유지됩니다.

배포하기

이 세션에서는 Cloudflare API/계정 접근이 차단되어 있어 실제 배포는 사용자가 직접 진행해야 합니다.

npx wrangler login

# KV 네임스페이스 생성 후, 출력된 id를 wrangler.jsonc의
# kv_namespaces[0].id ("REPLACE_WITH_YOUR_KV_NAMESPACE_ID")에 붙여넣으세요.
npx wrangler kv namespace create TRANSCRIPT_CACHE

npm run deploy   # wrangler deploy

배포되면 https://<worker-name>.<subdomain>.workers.dev/mcp가 MCP 엔드포인트입니다. Claude Desktop/Code 등에서 원격 MCP 서버로 연결하거나, mcp-remote를 통해 로컬 stdio 클라이언트와 연결할 수 있습니다.

Workers AI 요금 관련

translate_text 도구는 Workers AI(@cf/meta/m2m100-1.2b)를 호출합니다. Workers AI는 로컬 개발 중에도 항상 원격 리소스를 사용하므로(wrangler dev가 경고를 출력합니다) 실제 호출 시 사용량 과금이 발생할 수 있습니다.

Related MCP Connectors

Related MCP Servers