MCP 서버 참조

이 페이지

EmDash에는 /_emdash/api/mcp에 내장된 Model Context Protocol(MCP) 서버가 있으며, 콘텐츠 관리 작업을 AI 어시스턴트용 도구로 노출합니다.

이 페이지는 인증, 전송, 도구 사양, OAuth 디스커버리, 오류 처리 등 프로토콜 세부 정보를 다룹니다.

인증

MCP 서버는 세 가지 인증 방식을 지원합니다.

방식동작
OAuth 2.1 인가 코드 + PKCEMCP 클라이언트용 표준 흐름. 사용자가 브라우저에서 범위(scope)를 승인합니다.
개인용 액세스 토큰(PAT)관리자 패널에서 생성하는 장기 ec_pat_* 토큰.
디바이스 흐름브라우저에서 코드를 승인하는 CLI 스타일 흐름. emdash login에서 사용.

관리 UI의 세션 쿠키도 동작하지만 외부 MCP 클라이언트에는 실용적이지 않습니다.

범위(스코프)

토큰은 클라이언트가 수행할 수 있는 작업을 제한하는 범위로 한정됩니다. 범위는 OAuth 인가 중에 요청되며 모든 도구 호출에서 강제됩니다.

범위허용 작업
content:read콘텐츠 목록, 조회, 비교, 검색. 분류체계, 용어, 메뉴 목록.
content:write콘텐츠 생성, 수정, 삭제, 게시, 게시 취소, 예약, 예약 취소, 복제, 복원. 해당 범위가 나뉘기 전에 발급된 토큰과의 호환을 위해 암시적으로 taxonomies:managemenus:manage를 부여합니다.
media:read미디어 항목 목록 및 조회.
media:write미디어 메타데이터 등록(생성), 수정, 삭제.
schema:read컬렉션 목록 및 컬렉션 스키마 조회.
schema:write컬렉션 및 필드 생성·삭제.
taxonomies:manage분류체계 용어 생성·수정·삭제.
menus:manage탐색 메뉴 및 항목 생성·수정·삭제.
settings:read사이트 전역 설정 읽기.
settings:manage사이트 전역 설정 업데이트.
admin모든 작업에 대한 전체 액세스.

admin 범위는 모든 것에 액세스할 수 있습니다. 토큰이 없는 세션 인증도 사용자 역할에 따라 전체 액세스를 가질 수 있습니다.

content:write는 범위가 분리되기 전에 발급된 개인용 액세스 토큰이 재발급 없이 계속 동작하도록 taxonomies:managemenus: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

선택적 필터와 페이지 매김으로 컬렉션의 콘텐츠 항목을 나열합니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그(예: posts, pages)
statusstring아니요필터: draft, published, scheduled
limitinteger아니요최대 개수(1–100, 기본값 50)
cursorstring아니요이전 응답의 페이지 매김 커서
orderBystring아니요정렬 필드(예: created_at, updated_at)
orderstring아니요asc 또는 desc(기본값 desc)
localestring아니요로캘로 필터(예: en, fr). i18n 사용 시에만 해당.

범위: content:read | 읽기 전용:

content_get

ID 또는 슬러그로 단일 콘텐츠 항목을 가져옵니다. 모든 필드 값, 메타데이터, 낙관적 동시성용 _rev 토큰을 반환합니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 항목 ID(ULID) 또는 슬러그
localestring아니요슬러그 조회용 로캘. ID는 전역 고유.

범위: content:read | 읽기 전용:

content_create

새 콘텐츠 항목을 만듭니다. data 객체는 컬렉션 스키마에 맞는 필드 값이어야 합니다. 사용 가능한 필드는 schema_get_collection으로 확인하세요. 기본적으로 draft로 생성됩니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
dataobject키-값 필드
slugstring아니요URL 슬러그(생략 시 제목에서 자동 생성)
statusstring아니요초기 상태: draft 또는 published(기본값 draft)
localestring아니요이 콘텐츠의 로캘(기본값: 사이트 기본)
translationOfstring아니요번역 원본 항목 ID

범위: content:write

content_update

기존 콘텐츠를 업데이트합니다. 변경할 필드만 포함합니다. 지정하지 않은 필드는 그대로입니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그
dataobject아니요업데이트할 필드 값
slugstring아니요새 URL 슬러그
statusstring아니요새 상태: draft 또는 published
_revstring아니요content_get의 수정 토큰(충돌 감지)

범위: content:write

content_delete

콘텐츠를 휴지통으로 옮겨 소프트 삭제합니다. 되돌리려면 content_restore, 영구 삭제는 content_permanent_delete를 사용하세요.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그

범위: content:write | 파괴적:

content_restore

휴지통에서 소프트 삭제된 항목을 복원합니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그

범위: content:write

content_permanent_delete

휴지통에 있는 항목을 되돌릴 수 없이 영구 삭제합니다. 항목이 먼저 휴지통에 있어야 합니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그

범위: content:write | 파괴적:

content_publish

콘텐츠를 게시해 라이브 사이트에 반영합니다. 현재 초안에서 게시된 수정본을 만듭니다. 이후 편집은 새 초안을 만들며 다시 게시하기 전까지 라이브 버전에 영향을 주지 않습니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그

범위: content:write

content_unpublish

게시된 항목을 초안으로 되돌립니다. 라이브 사이트에서는 더 이상 보이지 않지만 내용은 보존됩니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그

범위: content:write

content_schedule

콘텐츠를 예약 게시합니다. 지정한 날짜·시간에 자동 게시됩니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그
scheduledAtstringISO 8601 날짜/시간(예: 2026-06-01T09:00:00Z)

범위: content:write

content_unschedule

예약 게시를 취소합니다. 항목은 현재 상태를 유지하고 scheduledAt 타임스탬프만 지워집니다. 멱등(idempotent) — 예약되지 않은 항목에서 호출해도 아무 작업도 하지 않습니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그

범위: content:write

content_compare

게시(라이브) 버전과 현재 초안을 비교합니다. 두 버전과 변경 여부 플래그를 반환합니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그

범위: content:read | 읽기 전용:

content_discard_draft

현재 초안을 버리고 마지막 게시 버전으로 되돌립니다. 항목이 최소 한 번 게시된 경우에만 동작합니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그

범위: content:write | 파괴적:

content_list_trashed

컬렉션 휴지통에 있는 소프트 삭제 항목을 나열합니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
limitinteger아니요최대(1–100, 기본값 50)
cursorstring아니요페이지 매김 커서

범위: content:read | 읽기 전용:

content_duplicate

기존 항목의 사본을 만듭니다. 복제본은 초안이며 제목에 «(Copy)»가 붙고 슬러그는 자동 생성됩니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring복제할 항목 ID 또는 슬러그

범위: content:write

content_translations

한 항목의 모든 로캘 변형을 가져옵니다. 번역 그룹과 각 로캘 버전 요약을 반환합니다. i18n이 켜져 있을 때만 해당합니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그

범위: content:read | 읽기 전용:

스키마 도구

schema_list_collections

CMS에 정의된 모든 콘텐츠 컬렉션을 나열합니다. 슬러그, 레이블, 지원 기능, 타임스탬프를 반환합니다.

매개변수 없음.

범위: schema:read | 최소 역할: 편집자 | 읽기 전용:

schema_get_collection

모든 필드 정의를 포함한 컬렉션 상세 정보를 가져옵니다. 필드는 데이터 모델(이름, 유형, 제약, 검증 규칙)을 설명합니다. content_createcontent_update에 필요한 입력을 이해하는 데 사용합니다.

매개변수유형필수설명
slugstring컬렉션 슬러그(예: posts)

범위: schema:read | 최소 역할: 편집자 | 읽기 전용:

schema_create_collection

새 콘텐츠 컬렉션을 만듭니다. 데이터베이스 테이블과 스키마 정의가 생성됩니다. 슬러그는 소문자 영숫자와 밑줄이며 문자로 시작해야 합니다.

매개변수유형필수설명
slugstring고유 식별자(/^[a-z][a-z0-9_]*$/)
labelstring표시 이름(복수, 예: «Blog Posts»)
labelSingularstring아니요단수 표시 이름
descriptionstring아니요컬렉션 설명
iconstring아니요관리 UI 아이콘 이름
supportsstring[]아니요기능: drafts, revisions, preview, scheduling, search(기본값: ['drafts', 'revisions'])

범위: schema:write | 최소 역할: 관리자

schema_delete_collection

컬렉션과 DB 테이블을 삭제합니다. 되돌릴 수 없으며 컬렉션의 모든 콘텐츠가 삭제됩니다.

매개변수유형필수설명
slugstring삭제할 컬렉션 슬러그
forceboolean아니요콘텐츠가 있어도 강제 삭제

범위: schema:write | 최소 역할: 관리자 | 파괴적:

schema_create_field

컬렉션 스키마에 필드를 추가합니다. 테이블에 열이 추가됩니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
slugstring필드 식별자(/^[a-z][a-z0-9_]*$/)
labelstring표시 이름
typestring데이터 유형(아래 참고)
requiredboolean아니요필수 여부
uniqueboolean아니요값 고유 여부
defaultValueany아니요새 항목의 기본값
validationobject아니요제약: min, max, minLength, maxLength, pattern, options
optionsobject아니요위젯 구성: collection(참조), rows(textarea)
searchableboolean아니요전체 텍스트 검색 색인에 포함
translatableboolean아니요번역 가능 필드 여부(기본값 true)

필드 유형: string, text, number, integer, boolean, datetime, select, multiSelect, portableText, image, file, reference, json, slug.

selectmultiSelectvalidation.options에 허용 값을 제공합니다.

범위: schema:write | 최소 역할: 관리자

schema_delete_field

컬렉션에서 필드를 제거합니다. 열과 해당 필드의 모든 데이터가 삭제됩니다. 되돌릴 수 없습니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
fieldSlugstring제거할 필드 슬러그

범위: schema:write | 최소 역할: 관리자 | 파괴적:

미디어 도구

media_list

선택적 MIME 유형 필터와 페이지 매김으로 업로드된 미디어 파일을 나열합니다.

매개변수유형필수설명
mimeTypestring아니요MIME 접두사로 필터(예: image/, application/pdf)
limitinteger아니요최대(1–100, 기본값 50)
cursorstring아니요페이지 매김 커서

범위: media:read | 읽기 전용:

media_create

스토리지에 이미 업로드된 미디어 파일을 등록합니다. 호출자가 storageKey에 파일을 둘 책임이 있습니다(보통 관리 UI 또는 별도 API의 서명된 업로드 URL). 이 도구가 메타데이터 레코드를 저장하여 media_list / media_get으로 찾고 콘텐츠에서 참조할 수 있습니다.

매개변수유형필수설명
filenamestring원본 파일 이름(예: logo.png)
mimeTypestringMIME 유형(예: image/png)
storageKeystring파일이 업로드된 스토리지 경로/키
sizeinteger아니요바이트 크기
widthinteger아니요이미지 너비(픽셀)
heightinteger아니요이미지 높이(픽셀)
contentHashstring아니요파일 내용 해시(중복 제거)
blurhashstring아니요이미지 플레이스홀더용 Blurhash
dominantColorstring아니요지배색 16진 문자열

범위: media:write | 최소 역할: 저자

media_get

ID로 단일 미디어 파일 상세를 가져옵니다. 파일 이름, MIME, 크기, 치수, 대체 텍스트, URL 등 메타데이터를 반환합니다.

매개변수유형필수설명
idstring미디어 항목 ID

범위: media:read | 읽기 전용:

media_update

업로드된 미디어 파일의 메타데이터만 업데이트합니다. 파일 자체는 변경할 수 없습니다.

매개변수유형필수설명
idstring미디어 항목 ID
altstring아니요접근성용 대체 텍스트
captionstring아니요캡션
widthinteger아니요이미지 너비(픽셀)
heightinteger아니요이미지 높이(픽셀)

범위: media:write

media_delete

미디어 파일을 영구 삭제합니다. DB 레코드와 스토리지의 파일을 제거합니다. 이 미디어를 참조하는 콘텐츠는 깨진 참조가 됩니다.

매개변수유형필수설명
idstring미디어 항목 ID

범위: media:write | 파괴적:

검색 도구

콘텐츠 컬렉션 전체 텍스트 검색. 컬렉션의 supportssearch가 있어야 하고 필드는 searchable이어야 합니다.

매개변수유형필수설명
querystring검색어
collectionsstring[]아니요특정 컬렉션 슬러그로 제한
localestring아니요로캘로 결과 필터
limitinteger아니요최대 결과(1–50, 기본값 20)

범위: content:read | 읽기 전용:

분류체계 도구

taxonomy_list

모든 분류체계 정의(예: 카테고리, 태그)를 나열합니다. 이름, 레이블, 계층 여부, 연결된 컬렉션을 반환합니다.

매개변수 없음.

범위: content:read | 읽기 전용:

taxonomy_list_terms

페이지 매김으로 분류체계의 용어를 나열합니다.

매개변수유형필수설명
taxonomystring분류체계 이름(예: categories, tags)
limitinteger아니요최대(1–100, 기본값 50)
cursorstring아니요페이지 매김 커서

범위: content:read | 읽기 전용:

taxonomy_create_term

분류체계에 새 용어를 만듭니다. 계층형이면 자식 용어를 위해 parentId를 지정합니다. 부모의 조상 체인은 100단계를 넘을 수 없습니다.

매개변수유형필수설명
taxonomystring분류체계 이름
slugstringURL에 안전한 식별자
labelstring표시 이름
parentIdstring아니요부모 용어 ID(계층형)
descriptionstring아니요용어 설명

범위: taxonomies:manage | 최소 역할: 편집자

taxonomy_update_term

기존 용어를 업데이트합니다. 필드를 생략하면 변경하지 않습니다. 슬러그 이름 변경은 동일 분류체계 내 다른 용어와 충돌하면 안 됩니다. parentIdnull로 설정하면 부모에서 분리합니다. 새 부모는 존재하고 같은 분류체계에 속하며 순환을 만들지 않아야 합니다.

매개변수유형필수설명
taxonomystring분류체계 이름
termSlugstring업데이트할 용어의 현재 슬러그
slugstring아니요새 슬러그(분류체계 내 고유)
labelstring아니요새 표시 이름
parentIdstring | null아니요새 부모 ID; 분리하려면 null
descriptionstring아니요새 설명

범위: taxonomies:manage | 최소 역할: 편집자

taxonomy_delete_term

분류체계에서 용어를 영구 삭제합니다. 태그가 붙은 콘텐츠는 연결이 끊깁니다. 자식이 있는 용어는 삭제할 수 없습니다. 먼저 자식을 삭제하세요.

매개변수유형필수설명
taxonomystring분류체계 이름
termSlugstring삭제할 용어 슬러그

범위: taxonomies:manage | 최소 역할: 편집자 | 파괴적:

메뉴 도구

모든 탐색 메뉴를 나열합니다. 이름, 레이블, 타임스탬프를 반환합니다.

매개변수 없음.

범위: content:read | 읽기 전용:

이름으로 메뉴를 가져와 순서대로 모든 항목을 반환합니다. 항목에는 레이블, URL, 유형, 중첩용 선택적 부모가 있습니다.

매개변수유형필수설명
namestring메뉴 이름(예: main, footer)

범위: content:read | 읽기 전용:

새 탐색 메뉴를 만듭니다. name은 사이트 템플릿이 사용하는 안정 식별자이고, label은 관리자에 표시되는 이름입니다. 이후 menu_set_items로 항목을 추가하세요.

매개변수유형필수설명
namestring안정 식별자(/^[a-z][a-z0-9_]*$/)
labelstring관리용 표시 이름

범위: menus:manage | 최소 역할: 편집자

메뉴 레이블을 업데이트합니다. name(안정 식별자)은 바꿀 수 없습니다.

매개변수유형필수설명
namestring업데이트할 메뉴 이름
labelstring새 표시 레이블

범위: menus:manage | 최소 역할: 편집자

메뉴와 모든 항목을 삭제합니다. 되돌릴 수 없습니다.

매개변수유형필수설명
namestring삭제할 메뉴 이름

범위: menus:manage | 최소 역할: 편집자 | 파괴적:

한 번의 호출로 메뉴의 항목 목록 전체를 바꿉니다. 원자적(atomic)으로 기존 항목을 삭제하고 제공한 순서대로 새 목록을 삽입합니다. 항목별 추가·삭제보다 순서와 부모 연결이 분명합니다.

항목 위치는 배열 인덱스로 결정합니다. 중첩은 parentIndex로 표현합니다. parentIndex: 0이면 인덱스 0 항목의 자식입니다. 부모는 목록에서 더 앞에 있어야 합니다. parentIndex가 없으면 최상위입니다.

매개변수유형필수설명
namestring업데이트할 메뉴 이름
itemsMenuItem[]정렬된 항목 목록(아래 참고)

MenuItem 필드:

필드유형필수설명
labelstring표시 텍스트
typestringcustom, page, post, taxonomy, collection 중 하나
customUrlstring아니요type: "custom"일 때 URL(그 외에는 무시)
referenceCollectionstring아니요콘텐츠 참조 대상 컬렉션 슬러그
referenceIdstring아니요대상 콘텐츠 또는 용어 ID
titleAttrstring아니요HTML title 속성
targetstring아니요HTML target(예: _blank)
cssClassesstring아니요공백으로 구분한 CSS 클래스
parentIndexinteger아니요부모 항목의 배열 인덱스. 최상위는 생략.

범위: menus:manage | 최소 역할: 편집자

수정본 도구

revision_list

콘텐츠 항목의 수정본 기록을 최신순으로 나열합니다. 컬렉션은 revisions를 지원해야 합니다.

매개변수유형필수설명
collectionstring컬렉션 슬러그
idstring콘텐츠 ID 또는 슬러그
limitinteger아니요최대 수정본 수(1–50, 기본값 20)

범위: content:read | 읽기 전용:

revision_restore

콘텐츠를 이전 수정본으로 되돌립니다. 현재 초안을 지정한 수정본의 데이터로 바꿉니다. 자동 게시되지 않습니다. 필요하면 이후 content_publish를 사용하세요.

매개변수유형필수설명
revisionIdstring복원할 수정본 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를 사용하세요.

매개변수유형필수설명
titlestring아니요사이트 제목
taglinestring아니요제목 옆 짧은 설명
logoMediaRef아니요로고 참조({ mediaId, alt? })
faviconMediaRef아니요파비콘 참조
urlstring아니요정규 사이트 URL(http 또는 https). 빈 문자열로 지웁니다.
postsPerPageinteger아니요목록 기본 페이지 크기(1–100)
dateFormatstring아니요날짜 형식 토큰 문자열
timezonestring아니요IANA 시간대 식별자
socialobject아니요소셜 — twitter, github, facebook, instagram, linkedin, youtube
seoobject아니요SEO 기본값(아래 참고)

seo 객체 필드:

필드유형설명
titleSeparatorstring페이지 제목과 사이트 제목 사이 구분자(예: 수직 막대 " | ")
defaultOgImageMediaRef콘텐츠에 OG 이미지가 없을 때 기본 Open Graph 이미지
robotsTxtstring사용자 정의 robots.txt 본문. 생략 시 EmDash 기본값.
googleVerificationstringGoogle Search Console 확인 토큰
bingVerificationstringBing 웹마스터 도구 확인 토큰

범위: 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(내부 오류)을 반환합니다.