MCP 서버

Claude Code, Cursor, VS Code, Codex, OpenAI Agents SDK 등 MCP를 지원하는 모든 에이전트를 Synthorai에 연결하는 데 필요한 것은 URL 하나와 API 키뿐입니다. 모든 모델과 모달리티, API 키 관리, 청구 데이터가 에이전트가 호출할 수 있는 도구가 됩니다. 각 호출은 대응하는 REST 요청과 똑같이 인증되고, 제한되며, 과금됩니다.

엔드포인트https://synthorai.io/v1/mcp
전송 방식Streamable HTTP, 무상태(세션 없음), JSON 응답
인증Authorization: Bearer <API key>
ℹ

연결에 쓰는 키에 따라 사용할 수 있는 도구가 정해집니다. 추론 키(sk-syn-…)는 모델을 호출합니다. 관리 키(sk-syn-admin-…)로는 스코프가 허용하는 도구를 쓸 수 있습니다. keys.read 또는 keys.write가 있으면 키 관리 도구를, billing.read가 있으면 잔액과 사용량 도구를 씁니다. 관리 키 하나에 스코프가 여러 개 있으면 연결 하나로 모두 쓸 수 있습니다. 이전에 발급된 프로비저닝 키와 결제 키(sk-syn-prov-…, sk-syn-bill-…)는 계속 동작합니다.

관리 키에 다른 스코프가 있으면 요청 로그, 프롬프트 라이브러리, 워크스페이스 설정 도구도 쓸 수 있습니다. 각 도구에 필요한 스코프는 아래 표에 나와 있습니다.

빠른 시작

  1. 콘솔의 API 키 페이지에서 API 키를 만드세요. 에이전트용 키에는 지출 한도와 허용 모델 목록을 설정하세요.
  2. 아래 스니펫 중 하나로 클라이언트에 서버를 추가하세요. 키는 파일에 붙여 넣지 말고 환경 변수에서 읽도록 하세요.
  3. 에이전트에게 이렇게 요청해 보세요: “도구를 지원하는 가장 저렴한 모델 세 개를 나열하고, 그중 가장 빠른 모델에게 이 파일을 요약하게 한 다음, 비용이 얼마였는지 알려줘.”

클라이언트 연결

모든 클라이언트는 같은 엔드포인트와 헤더를 사용합니다. 먼저 환경 변수 SYNTHORAI_API_KEY를 설정하세요.

로그인으로 연결하는 클라이언트(claude.ai, Claude Desktop, ChatGPT)에는 키가 필요 없습니다. 위 엔드포인트를 커넥터로 추가하고 Synthorai에 로그인한 뒤, 워크스페이스와 이 연결에 허용할 작업을 선택하세요. 연결마다 만료일이 있는 전용 키가 발급되며, 'API 키'에 표시되고 언제든 삭제할 수 있습니다.

Claude Code

Claude Code에서 /mcp를 실행해 연결을 확인하세요. --scope user를 추가하면 모든 프로젝트에서 서버를 사용할 수 있고, .mcp.json 형식으로 커밋하면 팀과 공유할 수 있습니다(키는 각 개발자의 환경에만 남습니다).

claude mcp add --transport http synthorai https://synthorai.io/v1/mcp \
  --header "Authorization: Bearer $SYNTHORAI_API_KEY"
{
  "mcpServers": {
    "synthorai": {
      "type": "http",
      "url": "https://synthorai.io/v1/mcp",
      "headers": { "Authorization": "Bearer ${SYNTHORAI_API_KEY}" }
    }
  }
}

Cursor

~/.cursor/mcp.json(모든 프로젝트) 또는 .cursor/mcp.json(단일 프로젝트)에 추가하세요.

{
  "mcpServers": {
    "synthorai": {
      "url": "https://synthorai.io/v1/mcp",
      "headers": { "Authorization": "Bearer ${env:SYNTHORAI_API_KEY}" }
    }
  }
}

VS Code (GitHub Copilot)

.vscode/mcp.json에 추가하세요. VS Code가 키를 한 번 입력받아 안전하게 저장합니다.

{
  "inputs": [
    { "type": "promptString", "id": "synthorai-key", "description": "Synthorai API key", "password": true }
  ],
  "servers": {
    "synthorai": {
      "type": "http",
      "url": "https://synthorai.io/v1/mcp",
      "headers": { "Authorization": "Bearer ${input:synthorai-key}" }
    }
  }
}

Codex CLI

~/.codex/config.toml에 추가하거나 codex mcp add synthorai --url https://synthorai.io/v1/mcp --bearer-token-env-var SYNTHORAI_API_KEY를 실행하세요.

[mcp_servers.synthorai]
url = "https://synthorai.io/v1/mcp"
bearer_token_env_var = "SYNTHORAI_API_KEY"

OpenAI Responses API

OpenAI 서버가 사용자를 대신해 엔드포인트를 호출하므로 키의 IP 허용 목록은 비워 두세요(또는 OpenAI의 송신 IP 대역을 허용하세요). allowed_tools로 모델에 필요한 도구만 노출하세요.

import os
from openai import OpenAI

client = OpenAI()
resp = client.responses.create(
    model="gpt-4.1",
    tools=[{
        "type": "mcp",
        "server_label": "synthorai",
        "server_url": "https://synthorai.io/v1/mcp",
        "headers": {"Authorization": f"Bearer {os.environ['SYNTHORAI_API_KEY']}"},
        "allowed_tools": ["list_models", "chat_completion"],
        "require_approval": "never",
    }],
    input="Find the cheapest Synthorai chat model with tool support and ask it for a haiku about gateways.",
)
print(resp.output_text)

OpenAI Agents SDK

MCP 클라이언트 SDK 기반의 모든 프레임워크(LangChain, LlamaIndex, Pydantic AI, Vercel AI SDK, Mastra …)에서도 똑같이 동작합니다. Streamable HTTP 전송이 이 엔드포인트를 가리키도록 하고 헤더를 추가하세요.

import asyncio, os
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp

async def main():
    async with MCPServerStreamableHttp(
        name="synthorai",
        params={
            "url": "https://synthorai.io/v1/mcp",
            "headers": {"Authorization": f"Bearer {os.environ['SYNTHORAI_API_KEY']}"},
            "timeout": 120,
        },
        cache_tools_list=True,
    ) as synthorai:
        agent = Agent(name="assistant", instructions="Use the Synthorai tools.", mcp_servers=[synthorai])
        result = await Runner.run(agent, "List three chat models under $1 per million input tokens.")
        print(result.final_output)

asyncio.run(main())

MCP Python SDK

import asyncio, os, httpx2
from mcp import Client
from mcp.client.streamable_http import streamable_http_client

async def main():
    http = httpx2.AsyncClient(
        headers={"Authorization": f"Bearer {os.environ['SYNTHORAI_API_KEY']}"}, timeout=120)
    async with Client(streamable_http_client("https://synthorai.io/v1/mcp", http_client=http)) as mcp:
        tools = await mcp.list_tools()
        print([t.name for t in tools.tools])
        result = await mcp.call_tool("chat_completion",
                                     {"model": "deepseek-v4-flash", "prompt": "Say hi in five words"})
        print(result.content[0].text)

asyncio.run(main())

Claude Desktop

Claude Desktop은 로그인으로 연결합니다. 엔드포인트를 사용자 지정 커넥터로 추가하면 키가 필요 없습니다. 직접 만든 키를 쓰려면 헤더를 대신 추가해 주는 mcp-remote 브리지로 연결하세요:

{
  "mcpServers": {
    "synthorai": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://synthorai.io/v1/mcp", "--header", "Authorization:${AUTH_HEADER}"],
      "env": { "AUTH_HEADER": "Bearer sk-syn-..." }
    }
  }
}

curl

서버는 HTTP 위의 순수 JSON-RPC이므로 SDK가 필요 없습니다. 핸드셰이크도 필요 없으며, 모든 요청이 독립적으로 처리됩니다.

curl https://synthorai.io/v1/mcp \
  -H "Authorization: Bearer $SYNTHORAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"chat_completion",
                 "arguments":{"model":"deepseek-v4-flash","prompt":"Say hi in five words"}}}'

응답 예시

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      { "type": "text", "text": "Hi there, great to meet!" },
      { "type": "text", "text": "[deepseek-v4-flash · finish_reason stop · 12 in / 7 out tokens · cost $0.0000031 · request_id 0199a7c2-…]" }
    ],
    "structuredContent": {
      "model": "deepseek-v4-flash",
      "content": "Hi there, great to meet!",
      "finish_reason": "stop",
      "usage": { "prompt_tokens": 12, "completion_tokens": 7, "total_tokens": 19 },
      "cost_usd": 0.0000031,
      "request_id": "0199a7c2-…"
    }
  }
}

도구

tools/list는 키로 사용할 수 있는 도구만 반환하며, 키 종류와 워크스페이스에서 활성화된 기능에 따라 필터링됩니다(이미지 및 동영상 생성은 제한된 프리뷰로 제공됩니다). 모델을 실행하는 도구의 비용은 REST 호출 비용과 정확히 같고, 그 밖의 도구는 모두 무료입니다.

추론 키

도구기능REST 엔드포인트비고
list_models 키로 호출할 수 있는 모델을 저렴한 순으로 보여 주며, 컨텍스트 길이, 모달리티, 기능, 정가를 함께 제공합니다. 필터: 카테고리, 기능, 입력 모달리티, 검색. GET /v1/models + /api/models 읽기 전용
get_model 모델 하나의 전체 세부 정보로, 할인 적용 후 실제 가격과 키로 호출할 수 있는지 여부를 포함합니다. GET /v1/models/{id} 읽기 전용
get_pricing 가격표(할인 적용 후 USD): 토큰당, 호출당, 분당, 초당 및 구간별 가격. GET /api/pricing 읽기 전용
chat_completion 모든 모델에서 채팅 완성을 한 번 실행합니다. 프롬프트 또는 전체 messages 배열(이미지, 도구 결과)을 받으며, 구조화된 출력, 함수 도구, 추론 강도, 대체 모델을 선택적으로 지정할 수 있습니다. 텍스트, 도구 호출, 사용량, 비용, request_id를 반환합니다. POST /v1/chat/completions 과금
generate_image 이미지를 생성하거나 편집합니다. 이미지 콘텐츠로 반환되며, response_format=url을 지정하면 링크로 반환됩니다. POST /v1/images/generations 과금
list_image_models 가격과 지원 입력을 포함한 이미지 모델 목록. GET /v1/images/models 읽기 전용
create_video 프롬프트나 첫 프레임으로 동영상 작업을 시작합니다. 완료될 때까지 최대 60초 대기할 수 있으며, 작업이 완료되면 과금됩니다. POST /v1/videos 과금
get_video 작업 상태. 완료되면 동영상 링크를 제공합니다(약 24시간 유효). GET /v1/videos/{id} 읽기 전용
cancel_video 아직 대기 중인 작업을 취소합니다(이미 시작된 작업은 중지할 수 없습니다). 취소되거나 실패한 작업은 과금되지 않습니다. DELETE /v1/videos/{id} 파괴적
list_video_models 해상도, 길이, 가격을 포함한 동영상 모델 목록. GET /v1/videos/models 읽기 전용
text_to_speech 텍스트를 음성으로 변환해 오디오 콘텐츠로 반환합니다. POST /v1/audio/speech 과금
transcribe_audio URL 또는 base64 데이터로 전달한 오디오(최대 25 MB)를 텍스트로 변환합니다. POST /v1/audio/transcriptions 과금
create_embeddings 텍스트 하나 또는 최대 2048개 배치에 대한 임베딩 벡터. POST /v1/embeddings 과금
get_key_info 키의 지출 한도, 사용액과 잔여액, 재설정 주기, 오늘 / 이번 주 / 이번 달 지출액(USD). GET /v1/key 읽기 전용
get_generation request_id로 조회한 요청 한 건의 청구 기록: 비용, 토큰 내역, 지연 시간, 상태. GET /v1/generation 읽기 전용

프로비저닝 키

도구기능REST 엔드포인트비고
create_api_key 지출 한도, 재설정 주기, 허용 모델 목록과 IP 허용 목록, 만료일, metadata를 지정해 추론 키를 생성합니다. 키 원문은 결과에만 표시됩니다. POST /api/v1/keys 데이터 변경
list_api_keys 워크스페이스의 추론 키 목록(한도, 지출액, 상태 포함). metadata로 필터링할 수 있습니다. GET /api/v1/keys 읽기 전용
get_api_key 키 하나의 설정, 지출액, 상태. GET /api/v1/keys/{id} 읽기 전용
update_api_key 키의 설정을 변경하거나 비활성화 / 재활성화합니다. 지정한 필드만 변경됩니다. PATCH /api/v1/keys/{id} 파괴적
delete_api_key 키를 영구 삭제합니다. DELETE /api/v1/keys/{id} 파괴적

빌링 키

도구기능REST 엔드포인트비고
get_balance 현재 사용 가능 잔액(USD)과 바우처 및 분할 지급 크레딧. GET /api/v1/billing/balance 읽기 전용
get_usage 시간 또는 일 단위 지출액과 요청 수(키 및/또는 모델별). GET /api/v1/billing/usage 읽기 전용
list_usage_records 토큰, 비용, 상태를 포함한 요청 단위 레코드. 커서로 페이지를 나눕니다. GET /api/v1/billing/records 읽기 전용
get_billing_summary 기간 합계와 상위 키 및 모델. GET /api/v1/billing/summary 읽기 전용
get_data_freshness 청구 데이터가 얼마나 최신인지 보여 줍니다. GET /api/v1/billing/freshness 읽기 전용

관리 키: 요청 로그와 사용량

도구기능REST 엔드포인트비고
search_requests 지정한 기간의 요청: 모델, 상태, 토큰, 비용, 소요 시간, 키, 레이블. 프롬프트와 응답은 포함하지 않습니다. logs.read가 필요합니다. GET /api/v1/requests 읽기 전용
get_request ID로 요청 하나를 조회합니다. logs.read가 필요합니다. GET /api/v1/requests/{id} 읽기 전용
list_traces 트레이스 ID별로 묶은 요청. 건수, 비용, 소요 시간을 포함합니다. logs.read가 필요합니다. GET /api/v1/traces 읽기 전용
list_sessions 세션 ID별로 묶은 요청. logs.read가 필요합니다. GET /api/v1/sessions 읽기 전용
get_label_usage 레이블별로 합산한 요청 수, 토큰, 비용. usage.read가 필요합니다. GET /api/v1/usage/labels 읽기 전용

관리 키: 프롬프트 라이브러리

도구기능REST 엔드포인트비고
list_prompts 전체 프롬프트 목록. 프롬프트별 레이블과 최신 버전을 포함합니다. prompts.read가 필요합니다. GET /api/v1/prompts 읽기 전용
get_prompt 프롬프트 하나의 레이블, 점진적 배포, 버전. prompts.read가 필요합니다. GET /api/v1/prompts/{id} 읽기 전용
get_prompt_version 버전의 본문, 모델 설정, 변수. prompts.read가 필요합니다. GET /api/v1/prompts/{id}/versions/{version} 읽기 전용
save_prompt_version 다음 버전으로 저장합니다. 레이블을 옮기기 전까지 호출 측에는 아무 변화가 없습니다. prompts.write가 필요합니다. POST /api/v1/prompts/{id}/versions 데이터 변경
move_prompt_label 레이블이 특정 버전을 가리키게 합니다. production을 옮기면 호출 측이 받는 내용이 바뀝니다. prompts.write가 필요합니다. PUT /api/v1/prompts/{id}/labels/{label} 파괴적
list_prompt_test_sets 프롬프트의 테스트 세트(행 제외). evals.read가 필요합니다. GET /api/v1/prompts/{id}/test-sets 읽기 전용
get_prompt_test_set 테스트 세트의 행과 검사 항목. evals.read가 필요합니다. GET /api/v1/prompts/{id}/test-sets/{set} 읽기 전용
list_prompt_eval_runs 프롬프트의 최근 실행 기록: 비교한 버전, 테스트 세트, 통과한 행 수. evals.read가 필요합니다. GET /api/v1/prompts/{id}/eval-runs 읽기 전용
get_prompt_eval_run 한 번의 실행 결과: 두 버전의 응답과 각 검사의 판정. evals.read가 필요합니다. GET /api/v1/prompts/{id}/eval-runs/{run} 읽기 전용

관리 키: 워크스페이스

도구기능REST 엔드포인트비고
list_audit_logs 워크스페이스에서 누가 무엇을 변경했는지. audit.read가 필요합니다. GET /api/v1/audit-logs 읽기 전용
list_members 멤버와 각자의 역할. members.read가 필요합니다. GET /api/v1/members 읽기 전용
get_byok_settings 내 키를 쓰는 공급자와 공급자별 설정. 키 값은 포함하지 않습니다. byok.read가 필요합니다. GET /api/v1/byok 읽기 전용
list_export_destinations 요청 데이터를 어디로 내보내는지. 액세스 키와 헤더는 포함하지 않습니다. exports.read가 필요합니다. GET /api/v1/export-destinations 읽기 전용

list_models, get_model, get_pricing은 모든 키 종류에서 제공됩니다. 추론 키의 경우 list_models는 해당 키로 호출할 수 있는 모델만 보여 줍니다.

연결 권한 제어하기

  • 워크스페이스 단위. 관리자는 설정 > MCP에서 MCP를 켜거나 끄고, 연결이 사용할 수 있는 도구 그룹을 고르고, 변경을 일으키는 도구의 사용 여부를 정합니다. 전용 인스턴스에서는 관리자가 켜기 전까지 MCP가 꺼져 있습니다.
  • 연결 단위. X-MCP-Readonly: true를 보내면 변경을 일으키거나 비용이 드는 도구가 모두 빠지고, X-MCP-Toolsets: logs,prompts를 보내면 해당 그룹만 남습니다(usage, logs, prompts, keys, workspace, inference). 헤더를 설정할 수 없는 클라이언트는 URL에 ?readonly=true&toolsets=logs,prompts를 붙입니다.
  • 이 설정은 모두 도구를 줄이기만 합니다. 키의 스코프, 워크스페이스 설정, 연결에 건 제한이 모두 허용하는 도구만 목록에 나타납니다.
  • 모든 변경은 기록됩니다. MCP로 변경한 내용은 사용한 키, 클라이언트 이름과 함께 감사 로그에 남습니다.

결과 형식

모든 결과에는 읽기 쉬운 텍스트 블록과 함께 같은 데이터를 JSON으로 담은 structuredContent가 포함되므로, 채팅 클라이언트와 프로그램 모두 사용할 수 있습니다. 이미지와 오디오는 이미지 및 오디오 콘텐츠로, 동영상은 링크로 반환됩니다. 모델을 실행하는 도구는 끝에 영수증 줄(모델, 토큰, 비용, request_id)을 붙이며, 나중에 get_generation으로 조회할 수 있습니다.

권한과 보안

  • REST API와 동일한 규칙. 각 도구 호출은 해당 도구에 명시된 REST 엔드포인트가 사용자의 키로 수행합니다. 인증, 키 종류, IP 허용 목록, 허용 모델 목록, 지출 한도, 속도 제한, 과금이 모두 그대로 적용됩니다. MCP는 권한을 추가하지도, 검사를 건너뛰지도 않습니다.
  • 키별 최소 권한. 추론 키는 키를 관리하거나 워크스페이스 결제 정보를 읽을 수 없습니다. 관리 키는 모델을 호출할 수 없고, 스코프에 명시된 일만 할 수 있습니다.
  • 승인 힌트. 모든 도구에는 MCP 어노테이션이 붙어 있습니다. 읽기 전용 도구는 readOnlyHint로 표시되고, 비용이 발생하는 도구는 읽기 전용이 아니며, update_api_key, delete_api_key, cancel_video는 destructiveHint로 표시됩니다. 클라이언트는 이를 바탕으로 실행 전에 무엇을 확인받을지 결정합니다.
  • 권장 에이전트 키: 매일 재설정되는 지출 한도와 allowed_models 목록을 설정하고, 에이전트가 알려진 호스트에서 실행된다면 IP 허용 목록까지 지정한 전용 추론 키. 프로덕션 키에 영향을 주지 않고 이 키만 따로 폐기할 수 있습니다.
  • 비밀 값과 신뢰할 수 없는 콘텐츠. create_api_key는 새 키를 한 번만 반환하므로 에이전트에게 어디에 저장할지 알려 주세요. 모델 출력과 도구 결과는 신뢰할 수 없는 입력(프롬프트 인젝션)으로 취급한 뒤에 에이전트가 이를 바탕으로 행동하게 하세요.

프로토콜 세부 사항

항목세부 내용
프로토콜 버전2026-07-28(무상태, 요청별 _meta와 Mcp-Method / Mcp-Name 헤더, server/discover) 및 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05(initialize 핸드셰이크). 모두 같은 URL에서 제공되며, 각 요청은 해당 요청이 사용하는 버전 방식으로 처리됩니다.
세션없음. Mcp-Session-Id를 발급하지 않으므로 모든 요청이 어느 서버 레플리카에서든 처리될 수 있고, 재연결 후 다시 초기화할 필요가 없습니다.
메서드initialize, ping, tools/list, tools/call. 2026-07-28에서는 핸드셰이크 대신 server/discover를 사용합니다. GET과 DELETE는 405를 반환하며, JSON-RPC 배치는 허용되지 않습니다.
오류알 수 없는 도구는 JSON-RPC 오류(-32602)로 반환됩니다. 그 밖의 모든 경우(잘못된 인수, API 거부, 생성 실패)는 isError: true와 모델이 대응할 수 있는 메시지를 담은 도구 결과로 반환됩니다. 2026-07-28에서는 엔벨로프 문제가 있으면 HTTP 400과 함께 -32020(헤더 불일치) 또는 -32022(지원하지 않는 버전, 지원 버전 목록 포함)를 반환합니다.
캐싱tools/list는 고정된 순서(프롬프트 캐시 친화적)로 반환되며, 목록이 키에 따라 달라지므로 ttlMs 10분과 cacheScope: "private"가 지정됩니다.
속도 제한키당 분당 MCP 메시지 600개(초과 시 Retry-After와 함께 HTTP 429). 각 도구 호출은 호출하는 REST 엔드포인트의 한도에도 함께 집계됩니다.
장시간 호출호출 하나는 최대 30분까지 실행될 수 있습니다(긴 추론). 동영상 생성은 비동기 방식으로, create_video가 작업을 반환하면 get_video로 상태를 폴링합니다.

문제 해결

증상원인과 해결 방법
401 오류 또는 클라이언트가 인증이 필요하다고 표시함키가 없거나, 유효하지 않거나, 만료되었거나, 비활성화되었습니다. Authorization: Bearer <key> 형식으로 보내고, 클라이언트가 실행되는 환경에 환경 변수가 설정되어 있는지 확인하세요.
예상한 도구가 목록에 없음도구는 키 종류(위 표 참고)와 프리뷰 기능에 따라 달라집니다. 이미지 및 동영상 도구는 해당 프리뷰에 참여한 워크스페이스에만 표시됩니다.
도구 결과에 HTTP 402가 표시됨워크스페이스 잔액이 소진되었습니다. 콘솔에서 충전하세요. 키 자체의 한도는 get_key_info로 확인할 수 있습니다.
특정 모델에 대해 도구 결과에 HTTP 403이 표시됨키의 allowed_models 또는 워크스페이스의 모델 접근 권한에서 해당 모델이 제외되어 있습니다. 키로 호출할 수 있는 모델은 list_models에서 정확히 확인할 수 있습니다.
chat_completion이 finish_reason length와 함께 텍스트 없이 반환됨추론 모델이 max_tokens 예산을 모두 사고 과정에 사용했습니다. max_tokens를 늘리거나 reasoning_effort를 낮추세요.
HTTP 429한 키에서 분당 메시지가 600개를 넘었거나 REST 엔드포인트 자체의 한도에 도달했습니다. Retry-After만큼 기다린 뒤 다시 시도하세요.

향후 계획

  • MCP 게이트웨이: 같은 엔드포인트에서 서드파티 MCP 서버(GitHub, Slack, 직접 운영하는 서버)까지 사용자의 키로 통합하며, 도구별 권한, 서버 측 자격 증명 보관, 단일 감사 로그를 제공합니다.
  • 장시간 호출 진행 상황: 도구가 실행되는 동안 진행 상황을 스트리밍합니다.

관련 문서: API 키 · 프로비저닝 키 · 빌링 API · Chat Completions