This skill should be used when the user asks to "generate API schema from Apidog", "extract request response schema", "Apidog에서 스키마 뽑아줘", "API 스키마 ��성", "엔드포인트 스��마 추출", "스키마 파일로 저장", "flat schema", "Apidog에 푸시", "Apidog 동기화", "API 문서 업데이트", or mentions extracting JSON schema from Apidog OAS endpoints or pushing specs to Apidog. Reads Apidog OAS endpoint definitions, cross-references with Go codebase structs to catch missing fields, generates flat inline JSON schemas, and optionally pushes OpenAPI specs to Apidog via Import API.
43:T4bec,
Apidog OAS 엔드포인트 정의에서 request/response JSON 스키마를 추출하고, 모든 중첩 객체를 flat 인라인으로 펼쳐서 생성한다.
유저와의 모든 대화(유저 질문, 안내, 설명, 확인)는 한국어로 진행한다.
APIDOG_ACCESS_TOKEN: Apidog Personal Access TokenAPIDOG_PROJECT_ID: 대상 프로젝트 ID--init (초기 세팅)$ARGUMENTS가 --init이면 아래 절차를 실행하고 종료한다:
.mcp.json 또는 프로젝트 설정에 apidog MCP가 등록되어 있는지 /로 확인한다.
GlobRead"Apidog MCP 서버가 설정되어 있지 않습니다.
.mcp.json에 아래 설정을 추가하세요:"{ "mcpServers": { "apidog": { "command": "npx", "args": ["-y", "apidog-mcp-server@latest", "--project-id=<YOUR_PROJECT_ID>"] } } }
.mcp.json에 자동 추가한다.echo "TOKEN=${APIDOG_ACCESS_TOKEN:+set}" "PROJECT=${APIDOG_PROJECT_ID:+set}"
--doctor (상태 진단)$ARGUMENTS가 --doctor이면 아래 항목을 점검하고 결과를 보고한 뒤 종료한다:
## Apidog Schema Gen — Doctor
| 항목 | 상태 | 비고 |
|------|------|------|
| Apidog MCP 등록 | OK / MISSING | .mcp.json 확인 |
| Apidog MCP 응답 | OK / FAIL | OAS 읽기 시도 |
| APIDOG_ACCESS_TOKEN | SET / UNSET | Push 기능용 |
| APIDOG_PROJECT_ID | SET / UNSET | Push 기능용 |
mcp__apidog__read_project_oas_w9of5k를 한 번 호출하여 정상 응답이 오는지 확인한다.--init을 실행하라고 안내한다.GET /v1/carts)" 라고 요청한다.전체 API 목록을 나열하지 않는다. 유저가 경로를 모르는 경우에만 OAS를 읽어 관련 키워드로 검색하여 후보를 좁혀 안내한다.
OAS에서 해당 경로를 찾을 수 없는 경우 (신규 API이거나 아직 Apidog에 등록되지 않은 경우):
"Apidog에
[METHOD] [PATH]경로가 존재하지 않습니다. 코드베이스 기반으로 스키마를 생성하여 파일로 저장할까요?"
"스키마 파일을 어디에 저장할까요?
docs/schemas/[endpoint-slug].json(기본)- 직접 경로 지정"
유저가 거부하면 스킬을 종료한다.
$ref 값을 확인한다.mcp__apidog__read_project_oas_ref_resources_w9of5k로 상세 스키마를 가져온다.requestBody.content.application/json.schema와 responses.{statusCode}.content.application/json.schema를 추출한다.OAS 스키마를 가져온 후, Go 코드베이스의 실제 struct 정의와 교차 검증하여 OAS에 누락된 필드를 보완한다.
Grep으로 경로 패턴 또는 handler 함수명��� 검색한다.json:"fieldName" 태그가 있는 structjson 태그 필드 목록과 OAS 스키마의 properties 키를 비교한다.string → "string", int/int64 → "integer", float64 → "number", bool → "boolean", []T �� "array", struct → "object"*string 등)은 optional 필드로 간주한다.enum 값이 있는 경우 (코드 내 validation 함수 등에서 확인) enum 배열을 추가한다.[코드 기준 추가] 같은 태그를 붙이지 않는다. 대신 별도 비교 테이블(Phase 4.1.1)에서 출처를 정리한다.우선순위: 코드베이스가 OAS보다 우선한다. OAS에 없는 필드라도 코드에 존재하�� 스키마에 포함한다. 타입 불일치 시에도 코드 기준으로 출력한다.
OAS에서 읽어온 raw schema를 코드베이스 교차 검증 결과와 병합하여 분석한다.
모든 중첩 객체는 예외 없이 flat 인라인으로 출력한다. $ref 분리를 하지 않는다. 동일 구조가 여러 곳에서 반복되더라도 매번 전체 필드를 펼쳐서 출력한다.
핵심: 유저가 스키마를 한 번에 copy → Apidog에 붙여넣기 할 수 있어야 한다. 외부 참조 없이 각 섹션이 완전한(self-contained) JSON schema여야 한다.
유저에게 최종 결과를 아래 형식으��� 출력한다. 각 섹션은 독립적으로 copy 가능해야 한다.
Response Schema 1개 + (해당 시) Request Schema 1개를 출력한다. 코드 기준으로 완전한 스키마를 구성한다. OAS에만 있든 코���에만 있든 관계없이 코드에 존재하는 모��� 필드를 포함한다. 스키마 내부에 [코드 기�� 추가] 같은 태그는 붙이지 않는다.
Main Schema 하단에 OAS와 코드 간 차이를 별도 테이블로 정리한다. 유저가 Apidog OAS를 업���이트할 때 참고할 수 있도록 한다.
출력 형식:
### OAS vs 코드 비교
| 위치 | 필드명 | OAS | 코드 | 비고 |
|------|--------|-----|------|------|
| data[] | publishedStatus | 없음 | string | 코드에만 존재 |
| data[] | discountRate | integer | number (float64) | 타입 ���일치 |
| data[] | type -> productType | type (string) | productType (string) | 키 이름 불일치 |
| query | publishedStatus | 없음 | string | 코드��만 존재 |
GET 엔드포인트의 query parameters는 CSV 형태로 출력한���. 헤더 행 없이 데이터만 출력한다.
CSV 컬럼 순서 (고정, 헤더 미출력):
이름,유형,필수,예시,고정 파라미터,설명
string, integer, number, boolean)true / false출력 후 유저에게 옵션을 제시한다:
상세 형식은
references/extraction-patterns.md의 "Query Parameters (GET)" 섹션 참���.
응답에 interface{} 또는 type discriminator 기반 다형성 필드가 있는 경우, Apidog의 schema composition을 활용���다.
Apidog composition 타입 선택 기준:
| Apidog 옵션 | OpenAPI | 의미 | 사용 시점 |
|---|---|---|---|
| XOR | oneOf | 정확히 하나만 만족 | type discriminator 기반 다형성 (기본 선택) |
| OR | anyOf | 하나 이상 만족 | 여러 형태가 동시 가능한 경우 (드묾) |
| AND | allOf | 모두 만족 | 상속/확장 패턴 |
출력 방식:
"extraInfo": {
"oneOf": [
{ "title": "variant_name", "type": "object", "properties": { ... } },
{ "title": "variant_name", "type": "object", "properties": { ... } }
]
}
extraInfo[0] — variant_name 형태로 각 variant의 full schema를 별도 섹션에 flat 인라인으로 출력한다. 이 섹션은 Apidog에서 해당 oneOf 인덱스에 직접 붙여넣을 수 있는 형태이다.핵심: 공통 필드는 Main Schema에 1번만, variant별 차이는 인덱스 섹션에 분리하여 필요한 것만 copy → Apidog composition 인덱스에 바��� 붙여넣기 가능하게 한다.
결���를 유저에게 보여주고 확인 받는다:
유저 피드백 반영 후 최종 스키마를 확정한다.
스키마 확정 후, 유저에게 "Apidog에 자동 푸시할까��?" 를 물어본다. 유저가 동의하면 아래 절차를 수행한다.
유저가 처음부터 "Apidog에 푸시해줘", "Apidog 동기화" 등을 요청한 경우, Phase 1~5를 모두 수행한 후 자동으로 Phase 6을 진행한다.
필요한 환경 변수 2개:
APIDOG_ACCESS_TOKEN: Apidog Personal Access TokenAPIDOG_PROJECT_ID: 대상 프로젝��� ID확인 방법:
echo "TOKEN=${APIDOG_ACCESS_TOKEN:+set}" "PROJECT=${APIDOG_PROJECT_ID:+set}"
미설정 시 유저에게 안내:
"Apidog Push에 필��한 환경 변수가 설정되어 있지 않��니다.
- Apidog → Settings → API Access Token에서 토큰 생성
- 아래 명령으로 설정:
export APIDOG_ACCESS_TOKEN='your-token' export APIDOG_PROJECT_ID='your-project-id' ```"
Push 전에 Apidog 프로젝트에서 해당 API 경로의 기존 존재 여부를 확인하고 폴더를 결정한다.
판정 로직:
mcp__apidog__read_project_oas_*로 OAS 전체를 읽어 기존 경로 목록을 확인한다.updateFolderOfChangedEndpoint: false로 기존 위치에서 수정 (폴더 이동 안 함)./v1/products/{id} 추가 시 → 기존 /v1/products 목록 API가 있는 폴더를 찾아 targetFolderId로 지정유사 경로 탐색 예시:
| 신규 경로 | 기존 경로 | prefix 일치 | 폴더 |
|---|---|---|---|
POST /v1/reviews | GET /v1/reviews | /v1/reviews (완전 일치) | 같은 폴더 |
GET /v1/products/{id}/options | GET /v1/products/{id} | /v1/products/{id} | 같은 폴더 |
POST /v1/cart/items | GET /v1/cart | /v1/cart | 같은 폴더 |
POST /v1/notifications | (없음) | 없음 | Root |
코드 기준 최종 스키마를 단일 엔드포인트 OpenAPI 3.0 YAML로 변환한다.
생성 규칙:
openapi: "3.0.0" 고��info.title: 프로젝트명 또는 서비스명paths: 해당 ���드포인트 1개만 포함parameters: GET이면 query params 포함requestBody: POST/PUT/PATCH이면 request schema 포함responses.200: response schema 포함파일 저장: /tmp/apidog-push-{endpoint-slug}.yaml
curl -s -X POST \
"https://api.apidog.com/v1/projects/${APIDOG_PROJECT_ID}/import-openapi" \
-H "Authorization: Bearer ${APIDOG_ACCESS_TOKEN}" \
-H "X-Apidog-Api-Version: 2024-03-28" \
-H "Content-Type: application/json" \
-d "{
\"input\": $(cat /tmp/apidog-push-{endpoint-slug}.yaml | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))'),
\"options\": {
\"endpointOverwriteBehavior\": \"OVERWRITE_EXISTING\",
\"schemaOverwriteBehavior\": \"OVERWRITE_EXISTING\",
\"updateFolderOfChangedEndpoint\": false,
\"prependBasePath\": false,
\"targetFolderId\": {folderId 또는 생략}
}
}"
targetFolderId: 6.2에서 결정한 폴더 ID. 기존 경로 수정 시에는 생략한다.API 응답의 data.counters를 파싱하여 유저에게 보고:
### Apidog Push 결과
| 항목 | 생성 | 수정 | 실패 | 무시 |
|------|------|------|------|------|
| Endpoint | {created} | {updated} | {failed} | {ignored} |
| Schema | {created} | {updated} | {failed} | {ignored} |
errors 배열이 비어있지 않으면 에러 내용도 함께 출���한다.
유저가 커스텀 옵션을 지정할 수 있다:
| ���션 | 설명 | 기본값 |
|---|---|---|
--folder {id} | 대상 폴더 ID 지정 | Root |
--merge | 기존 API와 병합 (AUTO_MERGE) | OVERWRITE_EXISTING |
--keep | 기존 API 유지, 새 것만 추가 (KEEP_EXISTING) | OVERWRITE_EXISTING |
--new | 항상 새로 생성 (CREATE_NEW) | OVERWRITE_EXISTING |
--branch {id} | 대상 브랜치 ID | main |
--dry-run | YAML만 생성하고 실제 푸시하지 않음 | false |
MCP에 write 기능이 없을 때 사용하는 Apidog REST API 스펙. 매번 검색하지 않도록 여기에 기록한다.
POST https://api.apidog.com/v1/projects/{projectId}/import-openapi
| Header | 값 |
|---|---|
Authorization | Bearer ${APIDOG_ACCESS_TOKEN} |
X-Apidog-Api-Version | 2024-03-28 |
Content-Type | application/json |
{
"input": "<OpenAPI YAML 문자열 (JSON escaped)>",
"options": {
"endpointOverwriteBehavior": "OVERWRITE_EXISTING",
"schemaOverwriteBehavior": "OVERWRITE_EXISTING",
"updateFolderOfChangedEndpoint": false,
"prependBasePath": false
}
}
| 필드 | 값 | 설명 |
|---|---|---|
endpointOverwriteBehavior | OVERWRITE_EXISTING / KEEP_EXISTING / AUTO_MERGE / CREATE_NEW | 기존 엔드포인트 처리 방식 |
schemaOverwriteBehavior | OVERWRITE_EXISTING / KEEP_EXISTING / AUTO_MERGE / CREATE_NEW | 기존 스키마 처리 방식 |
updateFolderOfChangedEndpoint | false | 변경된 엔드포인트의 폴더 이동 여부 |
prependBasePath | false | basePath를 경로 앞에 추가할지 |
targetBranchId | number (선택) | 대상 브랜치 ID |
targetFolderId | number (선택) | 대상 폴더 ID |
{
"success": true,
"data": {
"counters": {
"endpoint": { "created": 0, "updated": 1, "failed": 0, "ignored": 0 },
"schema": { "created": 0, "updated": 1, "failed": 0, "ignored": 0 }
},
"errors": []
}
}
curl -s -X POST \
"https://api.apidog.com/v1/projects/${APIDOG_PROJECT_ID}/import-openapi" \
-H "Authorization: Bearer ${APIDOG_ACCESS_TOKEN}" \
-H "X-Apidog-Api-Version: 2024-03-28" \
-H "Content-Type: application/json" \
-d "{
\"input\": $(cat /tmp/apidog-push-{slug}.yaml | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))'),
\"options\": {
\"endpointOverwriteBehavior\": \"OVERWRITE_EXISTING\",
\"schemaOverwriteBehavior\": \"OVERWRITE_EXISTING\",
\"updateFolderOfChangedEndpoint\": false,
\"prependBasePath\": false
}
}"
| 증상 | 원인 | 해결 |
|---|---|---|
| 302 Redirect | URL 오타 또는 프로젝트 ID 오류 | URL/ID 재확인. 반복 디버깅 금지, 즉시 수동 안내로 전환 |
| 401 Unauthorized | 토큰 만료/잘못됨 | APIDOG_ACCESS_TOKEN 재생성 안내 |
| 400 Bad Request | YAML 포맷 오류 | python3 -c 'import yaml; yaml.safe_load(open(f))'로 검증 |
errors 배열 비어있지 않음 | 스키마 충돌 | 에러 메시지 확인 후 options 조정 |
| 항목 | 규칙 |
|---|---|
pagination 객체 | 인라인 유지 (ref 분리 안 함) |
data wrapper | 인라인 ���지 |
null 타입 필드 | nullable로 표기: "type": ["{inferredType}", "null"] (실제 타입은 context에서 유추, 상세는 references/extraction-patterns.md Pattern 4 참조) |
required 배열 | OAS 원본의 required 필드를 그대로 ���지 |
빈 items: {} | "items": {} 그대로 유지 (any type array) |
example 필드 | 스키마 출력에서 제외 |
deprecated 엔��포인트 | 유저에게 deprecated 경고 표시 |
| 코드 vs OAS 불일치 | 코드 기준 우선. 불일치 사항은 출력 하단에 별도 안내 |
| 코드 추가 필드 | 스키마에 포함하되 태그 없이 출력. 별도 비교 테이��(4.1.1)에서 출처 정리 |
| Go 포인터 타입 | optional 필드로 간주 (required에 포함하지 않음) |
유저가 원할 경우 다음 옵션을 제공한다:
상세 패턴과 엣지 케이스 처리:
references/extraction-patterns.md - Ref 추출 상세 패턴, 엣지 ��이스, 실제 예시