EmDash에는 /_emdash/api/mcp에 내장된 Model Context Protocol(MCP) 서버가 있으며, 콘텐츠 관리 작업을 AI 어시스턴트용 도구로 노출합니다.
이 페이지는 인증, 전송, 도구 사양, OAuth 디스커버리, 오류 처리 등 프로토콜 세부 정보를 다룹니다.
인증
MCP 서버는 세 가지 인증 방식을 지원합니다.
| 방식 | 동작 |
|---|---|
| OAuth 2.1 인가 코드 + PKCE | MCP 클라이언트용 표준 흐름. 사용자가 브라우저에서 범위(scope)를 승인합니다. |
| 개인용 액세스 토큰(PAT) | 관리자 패널에서 생성하는 장기 ec_pat_* 토큰. |
| 디바이스 흐름 | 브라우저에서 코드를 승인하는 CLI 스타일 흐름. emdash login에서 사용. |
관리 UI의 세션 쿠키도 동작하지만 외부 MCP 클라이언트에는 실용적이지 않습니다.
범위(스코프)
토큰은 클라이언트가 수행할 수 있는 작업을 제한하는 범위로 한정됩니다. 범위는 OAuth 인가 중에 요청되며 모든 도구 호출에서 강제됩니다.
| 범위 | 허용 작업 |
|---|---|
content:read | 콘텐츠 목록, 조회, 비교, 검색. 분류체계, 용어, 메뉴 목록. |
content:write | 콘텐츠 생성, 수정, 삭제, 게시, 게시 취소, 예약, 예약 취소, 복제, 복원. 해당 범위가 나뉘기 전에 발급된 토큰과의 호환을 위해 암시적으로 taxonomies:manage 및 menus:manage를 부여합니다. |
media:read | 미디어 항목 목록 및 조회. |
media:write | 미디어 메타데이터 등록(생성), 수정, 삭제. |
schema:read | 컬렉션 목록 및 컬렉션 스키마 조회. |
schema:write | 컬렉션 및 필드 생성·삭제. |
taxonomies:manage | 분류체계 용어 생성·수정·삭제. |
menus:manage | 탐색 메뉴 및 항목 생성·수정·삭제. |
settings:read | 사이트 전역 설정 읽기. |
settings:manage | 사이트 전역 설정 업데이트. |
admin | 모든 작업에 대한 전체 액세스. |
admin 범위는 모든 것에 액세스할 수 있습니다. 토큰이 없는 세션 인증도 사용자 역할에 따라 전체 액세스를 가질 수 있습니다.
content:write는 범위가 분리되기 전에 발급된 개인용 액세스 토큰이 재발급 없이 계속 동작하도록 taxonomies:manage와 menus:manage를 암시적으로 부여합니다. 새 토큰은 세분화된 범위를 요청해야 합니다.
역할 요구 사항
범위 외에 일부 도구는 최소 RBAC 역할을 요구합니다. 둘 다 충족해야 합니다. 올바른 범위의 토큰도 호출 사용자의 역할이 낮으면 실패합니다.
| 작업 | 최소 역할 |
|---|---|
| 콘텐츠 읽기 | 게시된 항목은 구독자(10). 초안, 예약, 휴지통, 수정본은 기여자(20) |
| 콘텐츠 생성 / 본인 소유 편집·삭제 | 저자(30) |
| 콘텐츠 게시 | 본인 항목은 저자(30). 타인 항목은 편집자(40) |
| 스키마 읽기 | 편집자(40) |
| 스키마 쓰기 | 관리자(50) |
| 분류체계 관리 | 편집자(40) |
| 메뉴 관리 | 편집자(40) |
| 설정 읽기 | 편집자(40) |
| 설정 관리 | 관리자(50) |
미디어 업로드(media_create) | 저자(30) |
역할 정의는 인증 가이드를 참조하세요.
전송
서버는 무상태(stateless) 모드에서 Streamable HTTP 전송을 사용합니다. 요청마다 독립적이며 세션이나 장수명 연결이 없습니다.
POST /_emdash/api/mcp— JSON-RPC 도구 호출 전송GET /_emdash/api/mcp— 405 반환(무상태 모드에서는 SSE 없음)DELETE /_emdash/api/mcp— 405 반환(종료할 세션 없음)
응답은 JSON-RPC 2.0 형식을 따릅니다. 오류는 표준 JSON-RPC 코드를 사용하고, 범위·권한 실패에는 MCP 전용 코드가 적용됩니다.
도구
서버는 콘텐츠, 스키마, 미디어, 검색, 분류체계, 메뉴, 수정본, 설정 여덟 영역에 총 43개의 도구를 노출합니다. 각 도구는 JSON 텍스트로 결과를 반환하거나, 실패 시 isError: true가 있는 메시지를 반환합니다.
콘텐츠 도구
content_list
선택적 필터와 페이지 매김으로 컬렉션의 콘텐츠 항목을 나열합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그(예: posts, pages) |
status | string | 아니요 | 필터: draft, published, scheduled |
limit | integer | 아니요 | 최대 개수(1–100, 기본값 50) |
cursor | string | 아니요 | 이전 응답의 페이지 매김 커서 |
orderBy | string | 아니요 | 정렬 필드(예: created_at, updated_at) |
order | string | 아니요 | asc 또는 desc(기본값 desc) |
locale | string | 아니요 | 로캘로 필터(예: en, fr). i18n 사용 시에만 해당. |
범위: content:read | 읽기 전용: 예
content_get
ID 또는 슬러그로 단일 콘텐츠 항목을 가져옵니다. 모든 필드 값, 메타데이터, 낙관적 동시성용 _rev 토큰을 반환합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 항목 ID(ULID) 또는 슬러그 |
locale | string | 아니요 | 슬러그 조회용 로캘. ID는 전역 고유. |
범위: content:read | 읽기 전용: 예
content_create
새 콘텐츠 항목을 만듭니다. data 객체는 컬렉션 스키마에 맞는 필드 값이어야 합니다. 사용 가능한 필드는 schema_get_collection으로 확인하세요. 기본적으로 draft로 생성됩니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
data | object | 예 | 키-값 필드 |
slug | string | 아니요 | URL 슬러그(생략 시 제목에서 자동 생성) |
status | string | 아니요 | 초기 상태: draft 또는 published(기본값 draft) |
locale | string | 아니요 | 이 콘텐츠의 로캘(기본값: 사이트 기본) |
translationOf | string | 아니요 | 번역 원본 항목 ID |
범위: content:write
content_update
기존 콘텐츠를 업데이트합니다. 변경할 필드만 포함합니다. 지정하지 않은 필드는 그대로입니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
data | object | 아니요 | 업데이트할 필드 값 |
slug | string | 아니요 | 새 URL 슬러그 |
status | string | 아니요 | 새 상태: draft 또는 published |
_rev | string | 아니요 | content_get의 수정 토큰(충돌 감지) |
범위: content:write
content_delete
콘텐츠를 휴지통으로 옮겨 소프트 삭제합니다. 되돌리려면 content_restore, 영구 삭제는 content_permanent_delete를 사용하세요.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
범위: content:write | 파괴적: 예
content_restore
휴지통에서 소프트 삭제된 항목을 복원합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
범위: content:write
content_permanent_delete
휴지통에 있는 항목을 되돌릴 수 없이 영구 삭제합니다. 항목이 먼저 휴지통에 있어야 합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
범위: content:write | 파괴적: 예
content_publish
콘텐츠를 게시해 라이브 사이트에 반영합니다. 현재 초안에서 게시된 수정본을 만듭니다. 이후 편집은 새 초안을 만들며 다시 게시하기 전까지 라이브 버전에 영향을 주지 않습니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
범위: content:write
content_unpublish
게시된 항목을 초안으로 되돌립니다. 라이브 사이트에서는 더 이상 보이지 않지만 내용은 보존됩니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
범위: content:write
content_schedule
콘텐츠를 예약 게시합니다. 지정한 날짜·시간에 자동 게시됩니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
scheduledAt | string | 예 | ISO 8601 날짜/시간(예: 2026-06-01T09:00:00Z) |
범위: content:write
content_unschedule
예약 게시를 취소합니다. 항목은 현재 상태를 유지하고 scheduledAt 타임스탬프만 지워집니다. 멱등(idempotent) — 예약되지 않은 항목에서 호출해도 아무 작업도 하지 않습니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
범위: content:write
content_compare
게시(라이브) 버전과 현재 초안을 비교합니다. 두 버전과 변경 여부 플래그를 반환합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
범위: content:read | 읽기 전용: 예
content_discard_draft
현재 초안을 버리고 마지막 게시 버전으로 되돌립니다. 항목이 최소 한 번 게시된 경우에만 동작합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
범위: content:write | 파괴적: 예
content_list_trashed
컬렉션 휴지통에 있는 소프트 삭제 항목을 나열합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
limit | integer | 아니요 | 최대(1–100, 기본값 50) |
cursor | string | 아니요 | 페이지 매김 커서 |
범위: content:read | 읽기 전용: 예
content_duplicate
기존 항목의 사본을 만듭니다. 복제본은 초안이며 제목에 «(Copy)»가 붙고 슬러그는 자동 생성됩니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 복제할 항목 ID 또는 슬러그 |
범위: content:write
content_translations
한 항목의 모든 로캘 변형을 가져옵니다. 번역 그룹과 각 로캘 버전 요약을 반환합니다. i18n이 켜져 있을 때만 해당합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
범위: content:read | 읽기 전용: 예
스키마 도구
schema_list_collections
CMS에 정의된 모든 콘텐츠 컬렉션을 나열합니다. 슬러그, 레이블, 지원 기능, 타임스탬프를 반환합니다.
매개변수 없음.
범위: schema:read | 최소 역할: 편집자 | 읽기 전용: 예
schema_get_collection
모든 필드 정의를 포함한 컬렉션 상세 정보를 가져옵니다. 필드는 데이터 모델(이름, 유형, 제약, 검증 규칙)을 설명합니다. content_create와 content_update에 필요한 입력을 이해하는 데 사용합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
slug | string | 예 | 컬렉션 슬러그(예: posts) |
범위: schema:read | 최소 역할: 편집자 | 읽기 전용: 예
schema_create_collection
새 콘텐츠 컬렉션을 만듭니다. 데이터베이스 테이블과 스키마 정의가 생성됩니다. 슬러그는 소문자 영숫자와 밑줄이며 문자로 시작해야 합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
slug | string | 예 | 고유 식별자(/^[a-z][a-z0-9_]*$/) |
label | string | 예 | 표시 이름(복수, 예: «Blog Posts») |
labelSingular | string | 아니요 | 단수 표시 이름 |
description | string | 아니요 | 컬렉션 설명 |
icon | string | 아니요 | 관리 UI 아이콘 이름 |
supports | string[] | 아니요 | 기능: drafts, revisions, preview, scheduling, search(기본값: ['drafts', 'revisions']) |
범위: schema:write | 최소 역할: 관리자
schema_delete_collection
컬렉션과 DB 테이블을 삭제합니다. 되돌릴 수 없으며 컬렉션의 모든 콘텐츠가 삭제됩니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
slug | string | 예 | 삭제할 컬렉션 슬러그 |
force | boolean | 아니요 | 콘텐츠가 있어도 강제 삭제 |
범위: schema:write | 최소 역할: 관리자 | 파괴적: 예
schema_create_field
컬렉션 스키마에 필드를 추가합니다. 테이블에 열이 추가됩니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
slug | string | 예 | 필드 식별자(/^[a-z][a-z0-9_]*$/) |
label | string | 예 | 표시 이름 |
type | string | 예 | 데이터 유형(아래 참고) |
required | boolean | 아니요 | 필수 여부 |
unique | boolean | 아니요 | 값 고유 여부 |
defaultValue | any | 아니요 | 새 항목의 기본값 |
validation | object | 아니요 | 제약: min, max, minLength, maxLength, pattern, options |
options | object | 아니요 | 위젯 구성: collection(참조), rows(textarea) |
searchable | boolean | 아니요 | 전체 텍스트 검색 색인에 포함 |
translatable | boolean | 아니요 | 번역 가능 필드 여부(기본값 true) |
필드 유형: string, text, number, integer, boolean, datetime, select, multiSelect, portableText, image, file, reference, json, slug.
select 및 multiSelect는 validation.options에 허용 값을 제공합니다.
범위: schema:write | 최소 역할: 관리자
schema_delete_field
컬렉션에서 필드를 제거합니다. 열과 해당 필드의 모든 데이터가 삭제됩니다. 되돌릴 수 없습니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
fieldSlug | string | 예 | 제거할 필드 슬러그 |
범위: schema:write | 최소 역할: 관리자 | 파괴적: 예
미디어 도구
media_list
선택적 MIME 유형 필터와 페이지 매김으로 업로드된 미디어 파일을 나열합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
mimeType | string | 아니요 | MIME 접두사로 필터(예: image/, application/pdf) |
limit | integer | 아니요 | 최대(1–100, 기본값 50) |
cursor | string | 아니요 | 페이지 매김 커서 |
범위: media:read | 읽기 전용: 예
media_create
스토리지에 이미 업로드된 미디어 파일을 등록합니다. 호출자가 storageKey에 파일을 둘 책임이 있습니다(보통 관리 UI 또는 별도 API의 서명된 업로드 URL). 이 도구가 메타데이터 레코드를 저장하여 media_list / media_get으로 찾고 콘텐츠에서 참조할 수 있습니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
filename | string | 예 | 원본 파일 이름(예: logo.png) |
mimeType | string | 예 | MIME 유형(예: image/png) |
storageKey | string | 예 | 파일이 업로드된 스토리지 경로/키 |
size | integer | 아니요 | 바이트 크기 |
width | integer | 아니요 | 이미지 너비(픽셀) |
height | integer | 아니요 | 이미지 높이(픽셀) |
contentHash | string | 아니요 | 파일 내용 해시(중복 제거) |
blurhash | string | 아니요 | 이미지 플레이스홀더용 Blurhash |
dominantColor | string | 아니요 | 지배색 16진 문자열 |
범위: media:write | 최소 역할: 저자
media_get
ID로 단일 미디어 파일 상세를 가져옵니다. 파일 이름, MIME, 크기, 치수, 대체 텍스트, URL 등 메타데이터를 반환합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
id | string | 예 | 미디어 항목 ID |
범위: media:read | 읽기 전용: 예
media_update
업로드된 미디어 파일의 메타데이터만 업데이트합니다. 파일 자체는 변경할 수 없습니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
id | string | 예 | 미디어 항목 ID |
alt | string | 아니요 | 접근성용 대체 텍스트 |
caption | string | 아니요 | 캡션 |
width | integer | 아니요 | 이미지 너비(픽셀) |
height | integer | 아니요 | 이미지 높이(픽셀) |
범위: media:write
media_delete
미디어 파일을 영구 삭제합니다. DB 레코드와 스토리지의 파일을 제거합니다. 이 미디어를 참조하는 콘텐츠는 깨진 참조가 됩니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
id | string | 예 | 미디어 항목 ID |
범위: media:write | 파괴적: 예
검색 도구
search
콘텐츠 컬렉션 전체 텍스트 검색. 컬렉션의 supports에 search가 있어야 하고 필드는 searchable이어야 합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
query | string | 예 | 검색어 |
collections | string[] | 아니요 | 특정 컬렉션 슬러그로 제한 |
locale | string | 아니요 | 로캘로 결과 필터 |
limit | integer | 아니요 | 최대 결과(1–50, 기본값 20) |
범위: content:read | 읽기 전용: 예
분류체계 도구
taxonomy_list
모든 분류체계 정의(예: 카테고리, 태그)를 나열합니다. 이름, 레이블, 계층 여부, 연결된 컬렉션을 반환합니다.
매개변수 없음.
범위: content:read | 읽기 전용: 예
taxonomy_list_terms
페이지 매김으로 분류체계의 용어를 나열합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
taxonomy | string | 예 | 분류체계 이름(예: categories, tags) |
limit | integer | 아니요 | 최대(1–100, 기본값 50) |
cursor | string | 아니요 | 페이지 매김 커서 |
범위: content:read | 읽기 전용: 예
taxonomy_create_term
분류체계에 새 용어를 만듭니다. 계층형이면 자식 용어를 위해 parentId를 지정합니다. 부모의 조상 체인은 100단계를 넘을 수 없습니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
taxonomy | string | 예 | 분류체계 이름 |
slug | string | 예 | URL에 안전한 식별자 |
label | string | 예 | 표시 이름 |
parentId | string | 아니요 | 부모 용어 ID(계층형) |
description | string | 아니요 | 용어 설명 |
범위: taxonomies:manage | 최소 역할: 편집자
taxonomy_update_term
기존 용어를 업데이트합니다. 필드를 생략하면 변경하지 않습니다. 슬러그 이름 변경은 동일 분류체계 내 다른 용어와 충돌하면 안 됩니다. parentId를 null로 설정하면 부모에서 분리합니다. 새 부모는 존재하고 같은 분류체계에 속하며 순환을 만들지 않아야 합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
taxonomy | string | 예 | 분류체계 이름 |
termSlug | string | 예 | 업데이트할 용어의 현재 슬러그 |
slug | string | 아니요 | 새 슬러그(분류체계 내 고유) |
label | string | 아니요 | 새 표시 이름 |
parentId | string | null | 아니요 | 새 부모 ID; 분리하려면 null |
description | string | 아니요 | 새 설명 |
범위: taxonomies:manage | 최소 역할: 편집자
taxonomy_delete_term
분류체계에서 용어를 영구 삭제합니다. 태그가 붙은 콘텐츠는 연결이 끊깁니다. 자식이 있는 용어는 삭제할 수 없습니다. 먼저 자식을 삭제하세요.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
taxonomy | string | 예 | 분류체계 이름 |
termSlug | string | 예 | 삭제할 용어 슬러그 |
범위: taxonomies:manage | 최소 역할: 편집자 | 파괴적: 예
메뉴 도구
menu_list
모든 탐색 메뉴를 나열합니다. 이름, 레이블, 타임스탬프를 반환합니다.
매개변수 없음.
범위: content:read | 읽기 전용: 예
menu_get
이름으로 메뉴를 가져와 순서대로 모든 항목을 반환합니다. 항목에는 레이블, URL, 유형, 중첩용 선택적 부모가 있습니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
name | string | 예 | 메뉴 이름(예: main, footer) |
범위: content:read | 읽기 전용: 예
menu_create
새 탐색 메뉴를 만듭니다. name은 사이트 템플릿이 사용하는 안정 식별자이고, label은 관리자에 표시되는 이름입니다. 이후 menu_set_items로 항목을 추가하세요.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
name | string | 예 | 안정 식별자(/^[a-z][a-z0-9_]*$/) |
label | string | 예 | 관리용 표시 이름 |
범위: menus:manage | 최소 역할: 편집자
menu_update
메뉴 레이블을 업데이트합니다. name(안정 식별자)은 바꿀 수 없습니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
name | string | 예 | 업데이트할 메뉴 이름 |
label | string | 예 | 새 표시 레이블 |
범위: menus:manage | 최소 역할: 편집자
menu_delete
메뉴와 모든 항목을 삭제합니다. 되돌릴 수 없습니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
name | string | 예 | 삭제할 메뉴 이름 |
범위: menus:manage | 최소 역할: 편집자 | 파괴적: 예
menu_set_items
한 번의 호출로 메뉴의 항목 목록 전체를 바꿉니다. 원자적(atomic)으로 기존 항목을 삭제하고 제공한 순서대로 새 목록을 삽입합니다. 항목별 추가·삭제보다 순서와 부모 연결이 분명합니다.
항목 위치는 배열 인덱스로 결정합니다. 중첩은 parentIndex로 표현합니다. parentIndex: 0이면 인덱스 0 항목의 자식입니다. 부모는 목록에서 더 앞에 있어야 합니다. parentIndex가 없으면 최상위입니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
name | string | 예 | 업데이트할 메뉴 이름 |
items | MenuItem[] | 예 | 정렬된 항목 목록(아래 참고) |
각 MenuItem 필드:
| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
label | string | 예 | 표시 텍스트 |
type | string | 예 | custom, page, post, taxonomy, collection 중 하나 |
customUrl | string | 아니요 | type: "custom"일 때 URL(그 외에는 무시) |
referenceCollection | string | 아니요 | 콘텐츠 참조 대상 컬렉션 슬러그 |
referenceId | string | 아니요 | 대상 콘텐츠 또는 용어 ID |
titleAttr | string | 아니요 | HTML title 속성 |
target | string | 아니요 | HTML target(예: _blank) |
cssClasses | string | 아니요 | 공백으로 구분한 CSS 클래스 |
parentIndex | integer | 아니요 | 부모 항목의 배열 인덱스. 최상위는 생략. |
범위: menus:manage | 최소 역할: 편집자
수정본 도구
revision_list
콘텐츠 항목의 수정본 기록을 최신순으로 나열합니다. 컬렉션은 revisions를 지원해야 합니다.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
collection | string | 예 | 컬렉션 슬러그 |
id | string | 예 | 콘텐츠 ID 또는 슬러그 |
limit | integer | 아니요 | 최대 수정본 수(1–50, 기본값 20) |
범위: content:read | 읽기 전용: 예
revision_restore
콘텐츠를 이전 수정본으로 되돌립니다. 현재 초안을 지정한 수정본의 데이터로 바꿉니다. 자동 게시되지 않습니다. 필요하면 이후 content_publish를 사용하세요.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
revisionId | string | 예 | 복원할 수정본 ID |
범위: content:write
설정 도구
사이트 전역 설정 — 제목, 태그라인, 로고, 파비콘, 정규 URL, 기본 페이지 크기, 날짜·시간 형식, 소셜 계정, SEO 기본값.
settings_get
모든 사이트 전역 설정을 가져옵니다. 미디어 참조(logo, favicon, seo.defaultOgImage)에는 기본 mediaId와 함께 해석된 URL이 포함됩니다. 설정되지 않은 값은 응답에서 생략됩니다.
매개변수 없음.
범위: settings:read | 최소 역할: 편집자 | 읽기 전용: 예
settings_update
하나 이상의 사이트 전역 설정을 업데이트합니다. 부분 업데이트: 제공한 필드만 변경하고, 생략한 필드는 유지합니다. 업데이트 후 전체 설정 객체를 반환합니다.
미디어 참조(logo, favicon, seo.defaultOgImage)에는 mediaId(선택 alt)가 있는 객체를 전달합니다. 미디어 항목은 이미 존재해야 합니다. 먼저 media_create를 사용하세요.
| 매개변수 | 유형 | 필수 | 설명 |
|---|---|---|---|
title | string | 아니요 | 사이트 제목 |
tagline | string | 아니요 | 제목 옆 짧은 설명 |
logo | MediaRef | 아니요 | 로고 참조({ mediaId, alt? }) |
favicon | MediaRef | 아니요 | 파비콘 참조 |
url | string | 아니요 | 정규 사이트 URL(http 또는 https). 빈 문자열로 지웁니다. |
postsPerPage | integer | 아니요 | 목록 기본 페이지 크기(1–100) |
dateFormat | string | 아니요 | 날짜 형식 토큰 문자열 |
timezone | string | 아니요 | IANA 시간대 식별자 |
social | object | 아니요 | 소셜 — twitter, github, facebook, instagram, linkedin, youtube |
seo | object | 아니요 | SEO 기본값(아래 참고) |
seo 객체 필드:
| 필드 | 유형 | 설명 |
|---|---|---|
titleSeparator | string | 페이지 제목과 사이트 제목 사이 구분자(예: 수직 막대 " | ") |
defaultOgImage | MediaRef | 콘텐츠에 OG 이미지가 없을 때 기본 Open Graph 이미지 |
robotsTxt | string | 사용자 정의 robots.txt 본문. 생략 시 EmDash 기본값. |
googleVerification | string | Google Search Console 확인 토큰 |
bingVerification | string | Bing 웹마스터 도구 확인 토큰 |
범위: settings:manage | 최소 역할: 관리자
OAuth 디스커버리
OAuth 2.1을 지원하는 MCP 클라이언트는 인증 방법을 자동으로 찾을 수 있습니다. 서버는 메타데이터 문서 두 가지를 게시합니다.
보호 리소스 메타데이터
GET /.well-known/oauth-protected-resource
{
"resource": "https://example.com/_emdash/api/mcp",
"authorization_servers": ["https://example.com/_emdash"],
"scopes_supported": [
"content:read", "content:write",
"media:read", "media:write",
"schema:read", "schema:write",
"taxonomies:manage", "menus:manage",
"settings:read", "settings:manage",
"admin"
],
"bearer_methods_supported": ["header"]
}
인가 서버 메타데이터
GET /.well-known/oauth-authorization-server/_emdash
{
"issuer": "https://example.com/_emdash",
"authorization_endpoint": "https://example.com/_emdash/oauth/authorize",
"token_endpoint": "https://example.com/_emdash/api/oauth/token",
"scopes_supported": ["content:read", "content:write", "..."],
"response_types_supported": ["code"],
"grant_types_supported": [
"authorization_code",
"refresh_token",
"urn:ietf:params:oauth:grant-type:device_code"
],
"code_challenge_methods_supported": ["S256"],
"token_endpoint_auth_methods_supported": ["none"],
"device_authorization_endpoint": "https://example.com/_emdash/api/oauth/device/code"
}
인증되지 않은 요청이 MCP 엔드포인트에 오면 서버는 다음처럼 응답합니다.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://example.com/.well-known/oauth-protected-resource"
이것이 표준 MCP 클라이언트 디스커버리 흐름을 시작합니다.
오류 처리
도구 오류는 isError: true와 함께 텍스트 콘텐츠로 반환됩니다.
{
"content": [{ "type": "text", "text": "Collection 'nonexistent' not found" }],
"isError": true
}
범위 및 권한 오류는 MCP 프로토콜 오류를 발생시킵니다.
{
"jsonrpc": "2.0",
"error": {
"code": -32600,
"message": "Insufficient scope: requires content:write"
},
"id": 1
}
전송 수준 오류(서버 설정 오류, 처리되지 않은 예외 등)는 구현 세부 정보를 노출하지 않고 JSON-RPC 오류 코드 -32603(내부 오류)을 반환합니다.