좋아. 아래는 **“Cyphers(OpenAPI) → MCP Server 구현 → Smithery 배포/등록 → Cline+Cursor(Claude Agent)에서 Auto-coding/사용”**까지 바로 이어질 수 있게 만든 **아주 자세한 기술문서 초안(실제 문서 형태)**야.
(너는 이 문서를 그대로 바탕으로 **Cline + Cursor에서 Claude Agent로 자동 코딩** 돌리면 된다.)
---
# Cyphers MCP Server 기술문서
## 1. 목표와 범위
### 1.1 목표
* **Neople Cyphers Open API**를 호출하는 기능을 **MCP Server의 Tools**로 노출한다. ([Neople Developers][1])
* Smithery에 올려서 유저(또는 너 자신)가 **Cursor/Cline 같은 MCP 클라이언트에서 쉽게 설치·사용**할 수 있게 한다. ([Smithery][2])
### 1.2 범위(포함/비포함)
포함:
* Cyphers API 전체 엔드포인트(문서에 있는 11개) 기반 Tool 설계/구현 ([Neople Developers][1])
* 인증(apikey), URL 인코딩, 에러코드 매핑, 레이트 리밋, 캐싱, 관측성(logging)
* Smithery 배포(원격/로컬 형태 포함) ([Smithery][2])
* Cursor/Cline 설정 예시(설치/연결 가이드 포함)
비포함(권장 분리):
* LLM 자체 호출(OpenRouter 등)은 “옵션 모듈”로 분리(= MCP server는 도구 제공에 집중)
---
## 2. MCP / Smithery 개요(필수 이해)
### 2.1 MCP란?
* MCP(Model Context Protocol)는 LLM 클라이언트가 외부 도구/컨텍스트에 연결하는 **표준 프로토콜**이다. ([Model Context Protocol][3])
* 서버는 “tools/resources/prompts”를 노출하고, 클라이언트는 tool discovery 후 tool invocation을 수행한다. ([GitHub][4])
### 2.2 Smithery란?
* Smithery는 MCP 서버를 **빌드/배포/레지스트리 등록**해 사용자들이 쉽게 설치/연결하도록 돕는다. ([Smithery][2])
* TS 기반 서버는 Smithery 문서에서 “원격 배포(자동 컨테이너화)” 등 배포 옵션이 안내된다. ([Smithery][5])
* Smithery CLI로 설치 후 Cursor 같은 클라이언트에 자동 설정하는 패턴이 널리 쓰인다. ([GitHub][6])
---
## 3. Cyphers Open API 개요(요구사항의 기준)
### 3.1 API 게이트웨이 / 기본 URL
* Neople Open API는 보통 `https://api.neople.co.kr` 게이트웨이를 통해 호출된다. ([Neople Developers][7])
* Cyphers는 서비스 구분 경로에 `/cy/`를 사용한다. ([Neople Developers][1])
### 3.2 인증(API Key 전달 규칙)
* API Key는 **Query Parameter `apikey`** 또는 **Request Header `apikey`**로 전달 가능하다. ([Neople Developers][8])
* Header와 Query에 **서로 다른 키**가 있을 경우, **Query의 apikey가 우선** 적용된다는 FAQ가 있다. ([Neople Developers][8])
→ 구현에서는 **한 가지 방식만 고정**하는 걸 추천(혼용 금지).
### 3.3 문자 인코딩(닉네임/한글)
* 오픈 API charset은 UTF-8이며 한글/특수문자는 URL 인코딩해서 요청하라고 안내한다. ([Neople Developers][8])
→ MCP tool 입력에서 `nickname`은 “원문 문자열”로 받고, 서버에서 `encodeURIComponent` 처리.
### 3.4 레이트 리밋
* API 게이트웨이는 호출량 제한을 확인한다. (문서의 호출 허용량/제한 정책 기반) ([Neople Developers][7])
→ MCP 서버는 “서버 전역 + 사용자 전역” 제한을 걸어 **429 폭주**를 방지해야 한다.
---
## 4. 전체 아키텍처
### 4.1 구성요소
* **MCP Server (cyphers-mcp)**
* tool 목록 제공(Discovery)
* tool 호출 처리(Invocation)
* Neople API Proxy 레이어(HTTP client)
* 레이트 리밋 / 캐싱 / 에러 매핑
* **MCP Client**
* Cursor / Cline 등
* **Smithery**
* 서버 등록/배포/검색/설치 흐름 제공 ([Smithery][2])
### 4.2 Transport 선택(중요)
* MCP SDK는 stdio, SSE, Streamable HTTP 같은 표준 transport를 지원한다. ([GitHub][4])
* 운영 배포 관점에서는 HTTP 계열 transport를 권장하는 가이드가 많다. ([ai-sdk.dev][9])
**권장 전략**
* 로컬 개발/테스트: `stdio`
* Smithery 원격 배포: Smithery 문서에서 권장하는 배포 방식 + HTTP transport 사용 ([Smithery][5])
---
## 5. 시크릿/환경변수(너의 Key 2개 기준)
### 5.1 필수
* `CYPHERS_API_KEY` : Neople Cyphers API Key
### 5.2 선택(옵션 모듈로 분리 권장)
* `OPENROUTER_API_KEY` : OpenRouter 호출이 필요한 경우에만 사용
(예: “match detail 요약을 LLM으로 생성” 같은 부가 기능을 서버가 직접 제공할 때)
**원칙**
* MCP 서버의 core는 “Cyphers API tool 제공”에 집중하고,
* LLM 요약/해석은 가능한 클라이언트(Claude Agent) 쪽에서 수행하게 설계하면 운영/보안이 단순해진다.
---
## 6. Tool 설계 원칙(Claude Agent가 안정적으로 쓰게 만드는 핵심)
### 6.1 1:1 매핑 원칙
* Cyphers API 엔드포인트 **1개 = MCP tool 1개**를 기본으로 한다.
* 그 위에 “자주 쓰는 워크플로우”는 **composite tool**로 추가 가능
예: `nickname -> playerId -> recent matches -> N개 match detail` 요약
### 6.2 입력 스키마 규칙
* 모든 tool 입력은 JSON Schema로 명확히:
* 타입(string/int/bool)
* 필수/선택
* 범위(min/max), 제한(limit 최대값 등)
* 날짜 형식(ISO8601 or yyyy-mm-dd 등)
* 닉네임은 서버 내부에서 URL 인코딩 처리(사용자 입력 그대로 받기) ([Neople Developers][8])
### 6.3 출력 스키마 규칙
* 원본 API 응답을 최대한 보존하되,
* MCP에서 유용하도록 다음을 추가:
* `meta.request_id` (서버에서 생성)
* `meta.cached` (캐시 hit 여부)
* `meta.rate_limit` (내부 제한 관련 정보)
---
## 7. Cyphers API → MCP Tools 명세(“11개 엔드포인트” 기준)
> Cyphers는 “11개 API 엔드포인트”로 정리되는 타입정의 레포들도 존재한다(참고로 타입/스키마 작성에 도움). ([GitHub][10])
아래는 **tool 이름/설명/입력/출력**을 문서에 그대로 박아 넣는 형식이다.
### 7.1 Player
#### Tool: `cy.players.search`
* 목적: 닉네임으로 playerId 찾기 (검색)
* 입력:
* `nickname: string` (required)
* `wordType?: "match" | "full"` (optional, 기본값 문서 기준)
* `limit?: integer` (optional, 기본값/최대값 문서 기준)
* 처리:
* nickname URL 인코딩 적용 ([Neople Developers][8])
* 출력:
* `rows: Array<{ playerId: string, nickname: string, ... }>`
* `meta: { request_id, cached }`
#### Tool: `cy.players.get`
* 목적: playerId로 플레이어 상세 조회
* 입력:
* `playerId: string` (required)
* 출력: API 원본 + meta
#### Tool: `cy.players.matches`
* 목적: 플레이어 매칭 기록 조회
* 입력:
* `playerId: string` (required)
* `gameTypeId?: string`
* `startDate?: string`
* `endDate?: string`
* `next?: string` (페이지네이션)
* `limit?: integer`
* 출력: match list + next + meta
---
### 7.2 Match
#### Tool: `cy.matches.get`
* 목적: matchId로 매치 상세 조회
* 입력:
* `matchId: string` (required)
* 출력: match detail + meta
---
### 7.3 Ranking
#### Tool: `cy.ranking.ratingpoint`
* 목적: 통합 랭킹 조회(레이트 포인트)
* 입력:
* (문서의 필수/선택 파라미터 반영)
* 출력: ranking rows + meta
#### Tool: `cy.ranking.characters`
* 목적: 캐릭터 랭킹 조회
* 입력:
* `characterId: string`
* `rankingType: string`
* 기타 문서 파라미터
* 출력 + meta
#### Tool: `cy.ranking.tsj`
* 목적: 투신전 랭킹
* 입력:
* `tsjType: string`
* 출력 + meta
---
### 7.4 Items
#### Tool: `cy.battleitems.search`
* 목적: 아이템 검색
* 입력:
* `itemName: string` (optional, 문서 기준)
* `characterId?: string`
* `slotCode?: string`
* `rarityCode?: string`
* `seasonCode?: string`
* `limit?: integer`
* 출력 + meta
#### Tool: `cy.battleitems.get`
* 목적: itemId로 아이템 상세 조회
* 입력: `itemId: string`
* 출력 + meta
#### Tool: `cy.battleitems.multi_get`
* 목적: 여러 itemId 한번에 조회(최대 N개)
* 입력:
* `itemIds: string[]` (maxItems=문서값)
* 출력 + meta
---
### 7.5 Characters
#### Tool: `cy.characters.list`
* 목적: 캐릭터 목록/정보
* 입력:
* (문서 파라미터)
* 출력 + meta
---
### 7.6 이미지 URL 유틸(선택 tool)
Cyphers 문서에는 이미지 API 규칙이 함께 제공된다. ([Neople Developers][1])
→ 클라이언트가 편하게 쓰도록 다음 tool을 두면 유용하다.
#### Tool: `cy.images.character_url`
* 입력: `characterId: string`, `zoom?: integer`
* 출력: `url: string`
#### Tool: `cy.images.item_url`
* 입력: `itemId: string`
* 출력: `url: string`
---
## 8. HTTP Client / 재시도 / 타임아웃 정책
### 8.1 타임아웃
* connect timeout / read timeout 분리
* 기본값 예시:
* connect 3s, read 10s (운영 환경 맞게 조정)
* 타임아웃 발생 시:
* MCP error: `UPSTREAM_TIMEOUT` 로 표준화
### 8.2 재시도(권장: 제한적으로)
* GET만 존재하므로 재시도는 비교적 안전하지만,
* 5xx/503, 네트워크 오류에 한해 짧게 재시도(예: 2회, exponential backoff)
* 4xx(특히 400/401)는 재시도 금지
---
## 9. 에러 처리(Neople 에러 → MCP 에러로 매핑)
### 9.1 원칙
* MCP tool 호출 실패는 **항상 구조화된 에러**로 반환
* 포함 정보:
* `http_status`
* `neople_error_code` (있다면)
* `message`
* `request_id`
### 9.2 대표 케이스
* `401` 또는 Neople “유효하지 않은 키” 류 → `AUTH_INVALID`
* `429`(호출량 제한) → `RATE_LIMITED`
* `404`(존재하지 않는 ID) → `NOT_FOUND`
* `500/503` → `UPSTREAM_ERROR`
(Neople 게이트웨이가 호출 검증/인증/허용량 체크 후 에러코드와 메시지를 리턴하는 구조라는 점은 공통 가이드에 기반한다.) ([Neople Developers][7])
---
## 10. 레이트 리밋 / 캐싱(운영 품질의 핵심)
### 10.1 레이트 리밋(서버 측)
* 목적: Neople 허용량 초과 방지 + 클라이언트 폭주 방지 ([Neople Developers][7])
* 권장 2단 구성:
1. **서버 전역 토큰버킷**
2. **클라이언트별(세션/유저) 토큰버킷**
### 10.2 캐싱
캐시 후보:
* `characters.list` (변경 잦지 않음)
* `ranking.*` (짧은 TTL)
* `battleitems.get`, `multi_get` (중간 TTL)
캐시 키:
* endpoint + 정렬된 query string
TTL 예시:
* characters: 24h
* ranking: 1~5m
* item detail: 6~24h
캐시 응답에 `meta.cached=true/false` 포함
---
## 11. Smithery 배포 전략(실전)
### 11.1 배포 옵션
Smithery는 MCP 서버 빌드/배포 옵션을 제공한다. ([Smithery][2])
권장:
* TypeScript MCP SDK 기반으로 구현하고 Smithery의 TS 배포 가이드를 따른다. ([Smithery][5])
(물론 Python SDK로도 가능. 다만 Smithery 문서에서 TS 배포 문서가 명확히 존재) ([Smithery][5])
### 11.2 Smithery 레지스트리 등록/검색
* Smithery는 레지스트리에서 서버 검색/조회 API를 제공한다. ([Smithery][11])
### 11.3 “설치 → Cursor에 연결” 패턴
* Smithery CLI로 설치 후 Cursor에 MCP 서버를 붙이는 예시가 존재한다. ([GitHub][6])
→ 너도 동일 UX를 제공하도록:
* `@yourname/cyphers-mcp` 형태로 배포
* 설치 명령(예시 형식):
* `npx -y @smithery/cli@latest install <server> --client cursor --key <SMITHERY_KEY>`
* (실제 명령/옵션은 Smithery 문서 기준으로 문서에 그대로 명시)
---
## 12. Cursor / Cline에서 사용(Claude Agent Auto-coding 전제)
### 12.1 Cursor에서 MCP 서버 추가
* Cursor는 “MCP server 추가” 설정 플로우가 존재하며, MCP 서버 예시 문서들이 이를 안내한다. ([GitHub][6])
문서에 포함할 것:
* (A) Smithery로 설치하는 방법(가장 쉬움)
* (B) 로컬 stdio로 붙이는 방법(개발용)
### 12.2 Cline에서 MCP 서버 사용
* Cline에서 MCP 서버를 붙이는 가이드/사례가 존재한다. ([DEV Community][12])
문서에 포함할 것:
* 확장/설치 메뉴에서 MCP 서버를 선택해 설치하는 방식(또는 로컬 설정)
* 환경변수 주입 방식(CYPHERS_API_KEY)
---
## 13. Claude Agent 기반 Auto-coding 워크플로우(너의 방식에 맞춤)
### 13.1 “문서 → 자동코딩”을 위한 레포 구조(권장)
* `/src` : MCP 서버 코드
* `/docs` : 본 문서 + API 스키마 + 예제
* `/schemas` : tool input/output JSON schema
* `/examples` : Cursor/Cline 설정 예시, 프롬프트 예시
* `/tests` : API mocking 기반 테스트(키 없이도 동작)
### 13.2 Agent에게 주는 시스템 프롬프트(문서에 포함 추천)
* “tools 스펙은 docs/schemas를 single source of truth로 삼아라”
* “Neople API는 apikey는 query로만 보낸다(또는 header로만)”
* “nickname은 서버에서 인코딩”
* “에러는 표준 코드로 래핑해라”
* “캐싱/레이트리밋 구현 필수”
---
## 14. 예제 시나리오(사용자가 실제로 쓰는 흐름)
### 14.1 닉네임으로 최근 경기 분석
1. `cy.players.search(nickname="...")`
2. `cy.players.matches(playerId="...", limit=20)`
3. 상위 3개 matchId에 대해 `cy.matches.get`
4. (클라이언트/Claude Agent가) match detail을 요약/통계
### 14.2 캐릭터 랭킹 + 캐릭터 메타 리포트
1. `cy.ranking.characters(characterId="...", rankingType="...")`
2. `cy.characters.list()`로 캐릭터 메타 매핑
3. Agent가 “상위권 빌드/아이템 경향” 해석(옵션)
---
## 15. 문서 부록(필수로 넣으면 Auto-coding 성공률 급상승)
* A) Tool 목록 전체 JSON(정적) — name/description/input schema/output schema
* B) 공통 에러 코드 테이블(Neople→MCP 매핑)
* C) 레이트리밋 정책(서버 전역/유저 전역)
* D) 캐시 정책(TTL, key 규칙)
* E) Smithery 배포 체크리스트(시크릿, 엔트리포인트, 헬스체크, 버전)
---
원하면, 다음 메시지에서 내가 **위 7장(툴 명세)을 “진짜로 바로 구현 가능한 수준의 JSON Schema + 예시 요청/응답 + 에러 케이스”**로 완성해줄게.
그 형태면 Cline/Cursor의 Claude Agent에게 **“이 스키마대로 MCP server 코딩해”**라고 넣는 순간 거의 그대로 자동 생성된다.
[1]: https://developers.neople.co.kr/contents/apiDocs/cyphers?utm_source=chatgpt.com "사이퍼즈"
[2]: https://smithery.ai/docs/build?utm_source=chatgpt.com "Overview - Smithery Documentation"
[3]: https://modelcontextprotocol.io/?utm_source=chatgpt.com "What is the Model Context Protocol (MCP)? - Model Context ..."
[4]: https://github.com/modelcontextprotocol/python-sdk?utm_source=chatgpt.com "The official Python SDK for Model Context Protocol servers ..."
[5]: https://smithery.ai/docs/build/deployments/typescript?utm_source=chatgpt.com "TypeScript Servers - Smithery Documentation"
[6]: https://github.com/upstash/context7?utm_source=chatgpt.com "Context7 MCP Server -- Up-to-date code documentation for ..."
[7]: https://developers.neople.co.kr/contents/guide/pages/all?utm_source=chatgpt.com "이용안내 > 공통 가이드 > 아이템 레어리티"
[8]: https://developers.neople.co.kr/contents/faq?category=2&utm_source=chatgpt.com "FAQ - Neople 오픈 API - 네오플"
[9]: https://ai-sdk.dev/docs/ai-sdk-core/mcp-tools?utm_source=chatgpt.com "Model Context Protocol (MCP)"
[10]: https://github.com/crowrish/neople-openapi-types?utm_source=chatgpt.com "crowrish/neople-openapi-types: 네오플 Open API ..."
[11]: https://smithery.ai/docs/concepts/registry_search_servers?utm_source=chatgpt.com "Registry: Search Servers - Smithery Documentation"
[12]: https://dev.to/webdeveloperhyper/how-to-use-mcp-in-cline-and-cursor-54hg?utm_source=chatgpt.com "🧠🥷How to use MCP in Cline and Cursor"