MCP 서버 - 개발자 통합
이 가이드는 finlight MCP 서버와의 프로그래밍 방식 통합을 다룹니다. 사용자 지정 AI 애플리케이션을 구축하거나, 뉴스 검색을 자동화하거나, 기존 시스템에 금융 뉴스를 통합하는 데 사용하세요.
서버 정보
| 환경 | URL |
|---|---|
| 프로덕션 | https://mcp.finlight.me |
서버는 HTTP를 통한 JSON-RPC 2.0으로 **MCP(Model Context Protocol)**를 구현합니다.
인증
모든 도구 호출에는 Bearer 토큰을 통한 인증이 필요합니다. finlight API 키가 액세스 토큰 역할을 합니다.
Authorization: Bearer YOUR_API_KEY
자동화된 OAuth 흐름(예: Claude Desktop)의 경우, 서버는 PKCE가 포함된 OAuth 2.0을 구현합니다. 자세한 내용은 OAuth 흐름을 참조하세요.
빠른 시작
cURL 사용
사용 가능한 도구 나열:
curl -X POST https://mcp.finlight.me \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}'
기사 검색:
curl -X POST https://mcp.finlight.me \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_articles",
"arguments": {
"query": "NVIDIA earnings",
"tickers": ["NVDA"],
"pageSize": 10
}
}
}'
TypeScript 사용
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(
new URL("https://mcp.finlight.me"),
{
requestInit: {
headers: {
Authorization: `Bearer ${process.env.FINLIGHT_API_KEY}`,
},
},
}
);
const client = new Client({
name: "my-app",
version: "1.0.0",
});
await client.connect(transport);
// List available tools
const tools = await client.listTools();
console.log("Available tools:", tools);
// Search articles
const result = await client.callTool({
name: "search_articles",
arguments: {
query: "Federal Reserve interest rates",
from: "2024-01-01",
pageSize: 5,
},
});
console.log("Articles:", result);
Python 사용
import requests
import json
API_KEY = "your-api-key"
MCP_URL = "https://mcp.finlight.me"
def mcp_request(method: str, params: dict = None):
response = requests.post(
MCP_URL,
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}",
},
json={
"jsonrpc": "2.0",
"id": 1,
"method": method,
"params": params or {},
},
)
return response.json()
# List available tools
tools = mcp_request("tools/list")
print("Available tools:", json.dumps(tools, indent=2))
# Search articles
articles = mcp_request("tools/call", {
"name": "search_articles",
"arguments": {
"query": "Tesla Model 3",
"tickers": ["TSLA"],
"from": "2024-01-01",
"pageSize": 10,
},
})
print("Articles:", json.dumps(articles, indent=2))
사용 가능한 도구
search_articles
고급 필터링과 감성 분석으로 금융 뉴스 기사를 검색합니다.
매개변수:
| 매개변수 | 유형 | 설명 |
|---|---|---|
query | string | 불리언 연산자(AND, OR, NOT)와 필드 필터(ticker:AAPL, source:reuters.com)가 포함된 검색 쿼리 |
tickers | string[] | 티커 심볼로 필터링(예: ["AAPL", "NVDA"]) |
sources | string[] | 특정 뉴스 출처 도메인으로 제한 |
optInSources | string[] | 기본 세트에 출처 추가(대체가 아님) |
excludeSources | string[] | 결과에서 특정 출처 제외 |
countries | string[] | ISO 3166-1 alpha-2 국가 코드로 필터링 |
from | string | 시작 날짜(YYYY-MM-DD 또는 ISO 8601) |
to | string | 종료 날짜(YYYY-MM-DD 또는 ISO 8601) |
language | string | 언어 코드(기본값: "en") |
includeContent | boolean | 기사 전체 텍스트 포함(구독 필요) |
includeEntities | boolean | 태그된 회사 엔티티 포함 |
excludeEmptyContent | boolean | 콘텐츠가 없는 기사 건너뛰기 |
order | "ASC" | "DESC" | 정렬 순서(기본값: DESC = 최신순) |
orderBy | "publishDate" | "createdAt" | "revisedDate" | 정렬 필드 — revisedDate는 가장 최근 수정 날짜순으로 정렬 |
pageSize | number | 페이지당 결과 수(1-100, 기본값: 20) |
page | number | 페이지 번호(기본값: 1) |
요청 예시:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_articles",
"arguments": {
"query": "earnings report",
"tickers": ["AAPL", "MSFT"],
"from": "2024-01-01",
"to": "2024-03-31",
"language": "en",
"pageSize": 20
}
}
}
응답 예시:
{
"jsonrpc": "2.0",
"result": {
"content": [{
"type": "text",
"text": "{\"articles\":[{\"title\":\"Apple Reports Record Q1...\",\"summary\":\"...\",\"link\":\"https://...\",\"publishDate\":\"2024-02-01T16:30:00Z\",\"source\":\"www.reuters.com\",\"sentiment\":\"positive\",\"sentimentConfidence\":0.92}],\"totalResults\":847,\"page\":1,\"pageSize\":20}"
}]
},
"id": 1
}
get_article_by_link
URL로 특정 기사를 가져옵니다.
매개변수:
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
link | string | 예 | 기사의 전체 URL |
includeContent | boolean | 아니요 | 기사 전체 텍스트 포함 |
includeEntities | boolean | 아니요 | 태그된 회사 엔티티 포함 |
요청 예시:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_article_by_link",
"arguments": {
"link": "https://www.reuters.com/technology/example-article",
"includeContent": true,
"includeEntities": true
}
}
}
list_sources
사용 가능한 모든 뉴스 출처를 메타데이터와 함께 가져옵니다.
매개변수: 없음
요청 예시:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_sources",
"arguments": {}
}
}
응답에 포함되는 것:
domain- 출처 웹사이트 도메인isDefaultSource- 기본 검색에 포함되는지 여부isContentAvailable- 전체 콘텐츠 검색이 지원되는지 여부
MCP 프로토콜 메서드
서버는 다음 MCP 프로토콜 메서드를 구현합니다:
| 메서드 | 설명 |
|---|---|
initialize | MCP 세션 초기화 |
notifications/initialized | 초기화 완료 확인 |
tools/list | 사용 가능한 도구와 스키마 나열 |
tools/call | 인수로 도구 실행 |
ping | 상태 확인 |
Initialize 예시:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "my-client",
"version": "1.0.0"
}
}
}
응답:
{
"jsonrpc": "2.0",
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {}
},
"serverInfo": {
"name": "finlight-news-api",
"version": "1.0.0"
}
},
"id": 1
}
OAuth 흐름
OAuth를 지원하는 클라이언트(예: Claude Desktop)의 경우, 서버는 PKCE가 포함된 OAuth 2.0을 구현합니다.
엔드포인트
| 엔드포인트 | 메서드 | 설명 |
|---|---|---|
/.well-known/oauth-protected-resource | GET | 보호된 리소스 메타데이터 |
/.well-known/oauth-authorization-server | GET | 인증 서버 메타데이터 |
/register | POST | 동적 클라이언트 등록 |
/authorize | GET | 인증 페이지 |
/authorize/submit | POST | 인증 처리 |
/token | POST | 코드를 토큰으로 교환 |
흐름 개요
1. Client discovers OAuth endpoints via .well-known
2. Client optionally registers via /register
3. Client redirects user to /authorize with PKCE challenge
4. User enters API key and submits
5. Server redirects back with authorization code
6. Client exchanges code + verifier for access token
7. Client uses access token as Bearer token for API calls
보안 기능
- PKCE 필수 - 인증 코드 가로채기 방지
- 자체 암호화 코드 - AES-256-GCM 암호화, 무상태
- 단기 코드 - 120초 후 만료
- Redirect URI 검증 - 코드가 원래 URI에 바인딩됨
오류 처리
JSON-RPC 오류 코드
| 코드 | 메시지 | 설명 |
|---|---|---|
| -32700 | Parse error | 잘못된 JSON |
| -32600 | Invalid Request | jsonrpc 또는 method 누락 |
| -32601 | Method not found | 알 수 없는 메서드 |
| -32602 | Invalid params | 잘못된 도구 매개변수 |
| -32001 | Unauthorized | API 키 누락 또는 무효 |
| -32603 | Internal error | 서버 측 오류 |
API 오류 응답
실패한 도구 호출은 오류 구조를 반환합니다:
{
"jsonrpc": "2.0",
"result": {
"isError": true,
"content": [{
"type": "text",
"text": "Error: Invalid API key"
}]
},
"id": 1
}
일반적인 HTTP 수준 오류:
| 상태 | 설명 |
|---|---|
| 401 | 잘못된 API 키 |
| 403 | 구독이 이 작업을 허용하지 않음 |
| 429 | 속도 제한 초과 |
| 400 | 검증 오류 |
속도 제한
속도 제한은 finlight 구독 플랜에 따라 다릅니다. 제한을 초과하면 API는 429 상태 코드를 반환합니다.
app.finlight.me에서 현재 사용량과 제한을 확인하세요.
지원
- 문서: docs.finlight.me
- 대시보드: app.finlight.me
- 지원: 문의하기