MCP 서버 참조

이 페이지

EmDash는 /_emdash/api/mcp에 내장 Model Context Protocol(MCP) 서버를 제공합니다. MCP 클라이언트는 이 서버로 콘텐츠, 바이라인, 스키마, 미디어, 분류 체계, 메뉴, 리비전, 설정을 읽고 관리하며, 사이트 전체를 내보내거나 가져옵니다.

인증

MCP 엔드포인트에는 Bearer 토큰이 필요합니다. EmDash는 다음과 같은 토큰 흐름을 지원합니다.

방법용도
OAuth 2.1 Authorization Code with Proof Key for Code Exchange (PKCE)대화형 MCP 클라이언트. 사용자가 브라우저에서 요청된 스코프를 승인합니다.
Personal access token클라이언트나 자동화를 위한 장기 접근. 토큰은 ec_pat_ 접두사를 사용하며 관리자 화면에서 만듭니다.
OAuth 2.0 Device Authorization Grant브라우저에서 코드를 승인하도록 사용자에게 요청하는 명령줄 클라이언트. emdash login이 이 흐름을 사용합니다.

세션 쿠키로는 MCP 엔드포인트를 인증할 수 없습니다.

스코프

OAuth 토큰과 개인 액세스 토큰은 클라이언트가 호출할 수 있는 도구를 제한합니다. 사용자의 역할은 별도로 확인하므로, 스코프가 사용자에게 없는 권한을 부여하는 일은 없습니다.

스코프접근
content:read콘텐츠, 바이라인, 분류 체계, 용어, 메뉴, 리비전을 읽고 검색합니다. 초안과 유사한 콘텐츠에는 사용자의 content:read_drafts 권한도 필요합니다.
content:write콘텐츠, 바이라인, 리비전을 만들고 변경합니다. 기존 토큰과의 호환성을 위해 taxonomies:manage와 menus:manage도 부여합니다.
media:read미디어 레코드를 읽습니다.
media:write미디어를 업로드, 등록, 업데이트, 삭제합니다.
schema:read컬렉션과 필드를 읽습니다.
schema:write컬렉션과 필드를 만들고, 업데이트하고, 삭제합니다.
taxonomies:manage분류 체계 정의와 용어를 만들고, 업데이트하고, 삭제합니다.
menus:manage메뉴와 메뉴 항목을 만들고, 업데이트하고, 삭제합니다.
settings:read사이트 설정을 읽습니다.
settings:manage사이트 설정을 업데이트합니다.
mcp:tools활성화된 모든 플러그인이 제공하는 MCP 도구를 호출합니다.
mcp:tools:<pluginId>활성화된 특정 플러그인 하나가 제공하는 MCP 도구를 호출합니다.
transfer:export사이트 전체를 사이트 패키지로 내보내고 다운로드합니다.
transfer:analyze사이트 패키지를 업로드하고 가져오기를 위해 분석합니다.
transfer:execute사이트 가져오기를 시작, 진행, 취소, 포기합니다.
admin사이트 이전 도구를 포함한 모든 코어 도구를 호출합니다. 플러그인 도구에는 여전히 mcp:tools 또는 플러그인 전용 스코프가 필요합니다.

admin 스코프에는 transfer:export, transfer:analyze, transfer:execute가 포함됩니다. 각 이전 스코프는 자신의 동작만 허용하며 관리자 역할을 요구합니다. 에이전트 같은 클라이언트가 내보내기나 가져오기 없이 사이트 패키지만 분석하게 하려면, admin 대신 transfer:analyze를 부여하세요.

인증 코드 동의 페이지에서는 사용자가 요청된 스코프를 제거할 수 있습니다. EmDash는 요청을 클라이언트에 등록된 스코프 및 사용자의 역할과 교차시켜 범위를 좁히며, 빈 권한 부여는 거부합니다.

역할 요구 사항

다음 표는 넓은 범위의 기능별 최소 역할을 보여 줍니다. 사용자가 다른 사용자의 콘텐츠를 다루는 경우에는 소유권 검사 때문에 더 높은 역할이 필요할 수 있습니다.

기능최소 역할
게시된 콘텐츠, 미디어, 분류 체계, 용어, 메뉴 읽기Subscriber
초안, 예약된 콘텐츠, 휴지통, 비교, 리비전 읽기Contributor
콘텐츠 만들기 또는 미디어 업로드Contributor
자신의 콘텐츠 편집 또는 게시, 미디어 등록Author
바이라인, 분류 체계, 메뉴 또는 모든 사용자의 콘텐츠 관리Editor
스키마 또는 설정 읽기Editor
스키마 또는 설정 변경, 콘텐츠 영구 삭제, 미디어 사용 현황 복구Admin
사이트 전체 내보내기 또는 가져오기Admin

역할의 전체 정의는 사용자 역할을 참조하세요.

트랜스포트

서버는 상태를 유지하지 않는 Streamable HTTP를 사용합니다. 각 요청은 독립적이며, 서버는 MCP 세션이나 Server-Sent Events 연결을 유지하지 않습니다.

메서드엔드포인트동작
POST/_emdash/api/mcpJSON-RPC 초기화, 도구 목록 조회, 도구 호출을 받습니다.
GET/_emdash/api/mcp405 Method Not Allowed를 반환합니다.
DELETE/_emdash/api/mcp405 Method Not Allowed를 반환합니다.

응답은 JSON-RPC 2.0을 사용합니다. 도구 요청을 작성하기 전에 tools/list를 호출하여 현재의 입력 스키마와 MCP 어노테이션을 가져오세요.

도구 목록

다음 목록은 tools/list가 반환하는 정적 도구와 일치합니다. 클라이언트가 도구 이름 대신 제목을 표시할 수 있으므로 등록된 제목도 함께 실었습니다.

콘텐츠 도구

도구등록된 제목필요한 스코프
content_listList Contentcontent:read
content_getGet Contentcontent:read
content_createCreate Contentcontent:write
content_updateUpdate Contentcontent:write
content_deleteDelete Content (Trash)content:write
content_restoreRestore Contentcontent:write
content_permanent_deletePermanently Delete Contentcontent:write
content_publishPublish Contentcontent:write
content_unpublishUnpublish Contentcontent:write
content_scheduleSchedule Contentcontent:write
content_unscheduleCancel Scheduled Publicationcontent:write
content_compareCompare Live vs Draftcontent:read
content_discard_draftDiscard Draftcontent:write
content_list_trashedList Trashed Contentcontent:read
content_duplicateDuplicate Contentcontent:write
content_translationsGet Content Translationscontent:read

바이라인 도구

도구등록된 제목필요한 스코프
byline_listList Bylinescontent:read
byline_getGet Bylinecontent:read
byline_createCreate Bylinecontent:write
byline_updateUpdate Bylinecontent:write
byline_deleteDelete Bylinecontent:write
byline_translationsList Byline Translationscontent:read

스키마 도구

도구등록된 제목필요한 스코프
schema_list_collectionsList Collectionsschema:read
schema_get_collectionGet Collection Schemaschema:read
schema_list_block_typesList Block Typesschema:read
schema_get_block_typeGet Block Typeschema:read
schema_create_block_typeCreate Block Typeschema:write
schema_update_block_typeUpdate Block Typeschema:write
schema_activate_block_type_versionActivate Block Type Versionschema:write
schema_create_collectionCreate Collectionschema:write
schema_delete_collectionDelete Collectionschema:write
schema_update_collectionUpdate Collectionschema:write
schema_create_fieldAdd Field to Collectionschema:write
schema_delete_fieldRemove Field from Collectionschema:write
schema_update_fieldUpdate Fieldschema:write

미디어 도구

도구등록된 제목필요한 스코프
media_listList Mediamedia:read
media_createConfirm Signed Media Uploadmedia:write
media_uploadUpload Mediamedia:write
media_getGet Media Itemmedia:read
media_updateUpdate Media Metadatamedia:write
media_deleteDelete Mediamedia:write
media_usage_repairRepair Media Usage Indexadmin

검색 도구

도구등록된 제목필요한 스코프
searchSearch Contentcontent:read

분류 체계 도구

도구등록된 제목필요한 스코프
taxonomy_listList Taxonomiescontent:read
taxonomy_getGet Taxonomy Definitioncontent:read
taxonomy_createCreate Taxonomy Definitiontaxonomies:manage
taxonomy_updateUpdate Taxonomy Definitiontaxonomies:manage
taxonomy_deleteDelete Taxonomy Definitiontaxonomies:manage
taxonomy_list_termsList Taxonomy Termscontent:read
taxonomy_create_termCreate Taxonomy Termtaxonomies:manage
taxonomy_update_termUpdate Taxonomy Termtaxonomies:manage
taxonomy_delete_termDelete Taxonomy Termtaxonomies:manage
taxonomy_term_translationsList Term Translationscontent:read

메뉴 도구

도구등록된 제목필요한 스코프
menu_listList Menuscontent:read
menu_getGet Menu with Itemscontent:read
menu_translationsList Menu Translationscontent:read
menu_createCreate Menumenus:manage
menu_updateUpdate Menumenus:manage
menu_deleteDelete Menumenus:manage
menu_set_itemsSet Menu Itemsmenus:manage

리비전 도구

도구등록된 제목필요한 스코프
revision_listList Revisionscontent:read
revision_restoreRestore Revisioncontent:write

설정 도구

도구등록된 제목필요한 스코프
settings_getGet Site Settingssettings:read
settings_updateUpdate Site Settingssettings:manage

사이트 이전 도구

transfer:*는 transfer:export, transfer:analyze, transfer:execute 중 어느 하나를 뜻합니다. admin 스코프는 이 표의 모든 요구 사항을 충족합니다.

도구등록된 제목필요한 스코프
site_transfer_capabilitiesGet Site Transfer Capabilitiestransfer:*
site_export_startStart Site Exporttransfer:export
site_export_statusGet Site Export Statustransfer:export
site_import_analyzeAnalyze Site Importtransfer:analyze
site_import_startStart Site Importtransfer:execute
site_import_statusGet Site Import Statustransfer:*
site_import_resumeResume Site Importtransfer:execute
site_import_receiptGet Site Import Receipttransfer:*

site_export_start와 site_import_start는 관리자가 요청을 승인하면 해당 스코프가 없는 토큰도 받아들입니다. 승인된 요청이 시작한 작업에 대해서는 site_export_status, site_import_status, site_import_resume, site_import_receipt도 해당 스코프가 없는 같은 토큰을 받아들입니다.

도구 스키마 사용

tools/list는 각 도구의 설명, JSON 입력 스키마, 어노테이션을 반환합니다. 호출을 작성하기 전에 이 메타데이터를 읽어, 클라이언트가 설치된 EmDash 버전이 지원하는 필드, 허용되는 값, 제한을 사용하도록 하세요.

예를 들어 글을 업데이트하는 클라이언트는 먼저 content_get을 호출하여 반환된 _rev를 보관합니다. 그런 다음 다음과 같은 JSON-RPC 요청을 보낼 수 있습니다.

{
	"jsonrpc": "2.0",
	"id": 2,
	"method": "tools/call",
	"params": {
		"name": "content_update",
		"arguments": {
			"collection": "articles",
			"id": "01JARTICLE0000000000000000",
			"data": { "title": "Updated title" },
			"_rev": "opaque-revision-token"
		}
	}
}

결과는 첫 번째 콘텐츠 블록에 JSON 텍스트로 반환됩니다. 출력 스키마가 있는 도구는 같은 값을 structuredContent에도 반환할 수 있습니다.

콘텐츠 수명 주기와 바이라인

콘텐츠 수명 주기 참조는 MCP, REST, CLI, 관리자 패널이 공유하는 상태, 리비전, 권한, 충돌, 훅 동작을 정의합니다.

content_get은 불투명한 _rev 값을 반환합니다. 이 값을 content_update, content_publish, content_unpublish, content_schedule, content_discard_draft에 전달하세요. 오래된 값은 충돌을 반환하므로, 다시 시도하기 전에 항목을 다시 읽으세요.

content_update는 부분 업데이트입니다. 생략한 필드는 현재 값을 유지합니다. 게시된 항목을 업데이트하면 게시된 버전은 그대로 둔 채 초안이 준비됩니다. content_compare로 게시된 값과 초안 값을 검토한 뒤, content_publish를 호출하여 초안을 게시하거나 content_discard_draft를 호출하여 초안을 제거합니다. content_delete는 항목을 휴지통으로 옮기며, 휴지통에 있는 항목을 영구적으로 제거하는 것은 content_permanent_delete뿐입니다.

바이라인은 재사용할 수 있는 저자 또는 기여자 크레딧입니다. byline_create는 게스트 크레딧을 만들거나 바이라인을 CMS 사용자에 연결할 수 있습니다. 사용자 한 명은 로케일당 하나의 바이라인만 가질 수 있습니다. translationOf로 만든 번역은 userId를 전달하지 않는 한 원본 바이라인의 사용자를 유지하며, null을 전달하면 번역이 사용자에 연결되지 않은 채로 남습니다. 반환된 바이라인 ID를 content_create와 content_update가 받는 bylines 입력에 전달하세요. 바이라인을 삭제하면 콘텐츠에서 해당 크레딧이 제거되고 기본 바이라인 지정도 해제됩니다.

다른 사용자가 관리자 화면에서 항목을 열어 두어 그 편집 잠금을 가지고 있는 동안에는, content_update, content_delete, content_publish, content_unpublish, content_schedule, content_unschedule, content_discard_draft, revision_restore가 ENTRY_LOCKED로 실패하며 오류에 잠금 보유자가 표시됩니다. 항목을 다시 읽어도 이 거부는 해제되지 않습니다. 그래도 쓰려면 overrideLock: true를 전달하세요.

번역

콘텐츠, 바이라인, 분류 체계 용어, 메뉴의 번역 도구는 해당 번역 그룹의 모든 로케일 변형을 반환합니다. 생성 도구의 스키마가 translationOf 입력을 제공하면 그것을 사용하세요. 필수 필드는 tools/list가 기준입니다.

content_translations는 컬렉션과 콘텐츠 ID 또는 슬러그를 받습니다. 바이라인, 분류 체계 용어, 메뉴의 번역 도구는 레코드 하나의 ID 또는 공유 번역 그룹 ID 중 어느 쪽이든 받습니다. 초안에 접근할 수 없는 사용자에게는 게시된 콘텐츠 번역만 보입니다.

스키마, 미디어, 분류 체계, 메뉴

스키마 도구는 데이터베이스 구조를 변경합니다. 콘텐츠를 만들거나 필드를 변경하기 전에 schema_get_collection을 사용하세요. 이 도구는 사용 가능한 필드 이름, 유형, 제약 조건, 유효성 검사 규칙을 반환합니다. 컬렉션과 필드를 삭제하면 저장된 콘텐츠나 필드 값이 제거되며 되돌릴 수 없습니다.

base64로 인코딩된 바이트를 보내려면 media_upload를 사용하세요. 업로드는 설정된 크기 및 MIME 유형 제한을 받으며, 동일한 바이트는 deduplicated: true와 함께 기존 미디어 항목을 반환할 수 있습니다.

media_create는 POST /_emdash/api/media/upload-url로 생성된 대기 중인 업로드를 확정합니다. 반환된 서명된 URL로 파일을 업로드한 다음, 같은 사용자 계정으로 반환된 storageKey와 함께 media_create를 호출하세요. 이 도구는 저장된 파일이 존재하고 업로드 URL을 요청할 때 제공된 크기와 일치하는지 확인한 뒤에 미디어 라이브러리에서 사용할 수 있게 합니다.

분류 체계 정의는 분류 방식과 그것이 적용되는 컬렉션을 설명하며, 용어는 콘텐츠에 할당되는 개별 값입니다. 계층형 용어는 parentId를 사용할 수 있지만, 부모는 같은 분류 체계에 속해야 하며 순환을 만들 수 없습니다. 계층형이 아닌 분류 체계에서 parentId로 용어를 만들거나 업데이트하면 VALIDATION_ERROR가 반환됩니다. 자식이 있는 용어는 자식을 제거하거나 옮긴 뒤에야 삭제할 수 있습니다.

menu_set_items는 하나의 원자적 작업으로 메뉴의 전체 항목 목록을 교체합니다. 배열 순서가 메뉴 순서가 됩니다. 중첩된 항목의 parentIndex는 같은 배열에서 앞에 있는 항목을 가리키므로, 모든 부모를 자식보다 앞에 두세요.

media_usage_repair는 컬렉션 하나 또는 모든 컬렉션을 처리할 수 있으며, 큰 사이트에서는 오래 실행될 수 있습니다. complete, partial, failed, stale 상태는 모두 성공한 도구 응답입니다. isError에 의존하지 말고 반환된 상태와 개수를 확인하세요. 인증, 유효성 검사, 예기치 않은 실행 실패에는 isError: true가 설정됩니다.

사이트 이전

site_* 도구는 사이트 전체를 사이트 패키지로 내보내고, 패키지를 빈 사이트로 가져옵니다. 이 도구들은 작업을 시작하고 진행시키며 크기가 제한된 요약을 반환합니다. 패키지 바이트, 미디어, 레코드 내용, 주체의 이메일 주소, 다운로드 URL은 절대 전달하지 않습니다. 내보내기 다운로드와 가져오기용 패키지 업로드는 CLI 또는 REST API로 수행한 다음, ID로 해당 작업을 참조하세요.

모든 이전 도구에는 Admin 역할이 필요합니다. 역할은 스코프보다 먼저 확인하므로, 관리자가 아닌 호출자는 INSUFFICIENT_PERMISSIONS를 받으며 승인 요청은 만들어지지 않습니다.

내보내기

site_export_start는 comments(기본값 true)를 받아 새 작업을 반환합니다. site_export_status는 호출할 때마다 크기가 제한된 내보내기 단계를 하나 실행하고 작업과 nextRequestInMs를 보고합니다. nextRequestInMs가 null이 될 때까지, 그 지연 시간 뒤에 다시 호출하세요. 단계를 실행하지 않고 상태만 읽으려면 advance: false를 전달하세요. 내보내기가 완료되면 결과에 totals도 포함됩니다. 종류별 레코드 수, 미디어 개수와 바이트 수, 패키지 파일 개수와 바이트 수입니다.

가져오기

먼저 패키지를 업로드하세요. CLI의 emdash site import <file> --analyze는 패키지를 업로드하고 분석한 뒤 작업 ID를 출력합니다.

site_import_analyze는 호출할 때마다 크기가 제한된 분석 단계를 하나 실행합니다. nextRequestInMs가 null이 될 때까지 반복하세요. 그러면 결과에 packageDigest, planDigest, executable, 개수, 크기, 주체, 결정 사항, 변환, 경고, 차단 요소가 담긴 계획 요약이 포함됩니다. 각 변환은 code, 있는 경우 레코드 kind, count로 나열되며 적용 대상 ID나 값은 포함하지 않습니다. 주체, 경고, 차단 요소는 각각 최대 50개까지 나열되고 전체 개수는 total에 담깁니다. 주체는 이메일 주소 없이 나열되며, 제안된 대상 사용자 ID와 현재 매핑된 대상 사용자 ID가 함께 표시됩니다. decisions를 전달하면 주체를 대상 사용자 ID(또는 null)에 매핑하고 패키지 또는 대상의 제목과 태그라인을 선택할 수 있습니다. 변경할 때마다 새로운 planDigest가 만들어집니다.

site_import_start는 작업 ID와 최신 계획의 packageDigest, planDigest를 받습니다. 계획에 차단 요소가 없어야 합니다. 이 도구에는 destructiveHint: true가 설정되어 있습니다. 시작하면 가져오기가 사이트에 쓰기를 수행하며, 완료되거나 관리자가 포기할 때까지 다른 쓰기를 차단합니다. 호출하기 전에 사용자에게 계획을 보여 주고 확인을 받으세요.

site_import_resume은 크기가 제한된 가져오기 단계를 하나 실행하고 작업과 nextRequestInMs를 보고합니다. nextRequestInMs가 null이 될 때까지 호출하세요. 연결이 끊긴 뒤에 반복해도 안전합니다. site_import_status는 가져오기를 진행시키지 않고 작업과 업로드된 파일 개수를 보고합니다. site_import_receipt는 가져오기가 완료된 뒤에 receiptDigest를 포함한 전체 영수증을 반환합니다.

가져오기가 실행되는 동안, 그리고 실패하거나 취소된 뒤 포기될 때까지는, 쓰기가 가능한 다른 모든 도구가 TRANSFER_IMPORT_IN_PROGRESS로 실패합니다. 여기에는 플러그인 도구도 포함됩니다. readOnlyHint: true로 표시된 도구와 8개의 site_* 도구는 계속 동작하며, initialize와 tools/list는 절대 차단되지 않습니다. 미디어 사용 현황 활성화 중에는 쓰기 도구가 같은 방식으로 MEDIA_USAGE_ACTIVATION_IN_PROGRESS로 실패합니다.

작업 요약에는 id, kind, state, stage, progress, packageDigest, planDigest, error({ code } 또는 null), 타임스탬프가 포함됩니다. progress는 { done, total } 단계 수이며, 알려진 경우에는 내보내기가 지금까지 쓴 레코드 수인 records와 bytesDone, bytesTotal도 포함됩니다. MCP 도구로는 가져오기를 취소하거나 포기할 수 없으니 REST API를 사용하세요.

승인

admin 또는 필요한 이전 스코프가 있는 토큰은 승인을 요구받지 않습니다. 둘 다 없는 토큰(예: transfer:analyze만 부여받은 에이전트)의 경우, site_export_start와 site_import_start는 관리자가 요청을 승인하면 실행됩니다.

  1. 스코프 없이 처음 호출하면 대기 중인 승인 요청이 만들어지고 TRANSFER_APPROVAL_REQUIRED로 실패합니다. 메시지 텍스트와 _meta.details에 approvalId와 expiresAt이 들어 있습니다. 같은 인수로 approvalId 없이 다시 호출하면 같은 미결 요청이 반환됩니다.
  2. 관리자는 Settings → Transfer의 Approval requests에서 요청을 승인하거나, REST API의 세션 전용 승인 엔드포인트로 승인합니다. API 토큰으로는 요청을 승인할 수 없습니다.
  3. 클라이언트는 같은 인수와 approvalId로 호출을 반복합니다. 그 호출이 작업을 시작하면 승인은 소진됩니다. 작업 시작에 실패하면, 클라이언트는 만료될 때까지 같은 approvalId로 다시 시도할 수 있습니다.

요청은 사용자, 토큰, 동작, 정확한 인수(내보내기 옵션, 또는 가져오기 작업 ID와 두 다이제스트)에 묶입니다. 대기 중인 요청은 생성 후 15분, 승인된 요청은 승인 후 15분이 지나면 만료됩니다. 인수가 다르거나 다른 토큰을 사용한 호출, 또는 거부되었거나 만료되었거나 이미 사용된 승인을 사용한 호출은 TRANSFER_APPROVAL_INVALID로 실패합니다.

site_import_start는 요청을 만들기 전에 다이제스트, 작업 상태, 계획의 차단 요소를 확인하므로, 관리자는 실행할 수 있는 가져오기에 대해서만 승인을 요청받습니다. 승인에는 토큰 ID가 필요하므로, 토큰 ID가 없는 호출자는 INSUFFICIENT_SCOPE를 받습니다.

승인된 호출이 작업을 시작한 뒤에는, 같은 사용자와 토큰이 해당 작업에 대해 스코프 없이 site_export_status 또는 site_import_status, site_import_resume, site_import_receipt를 호출할 수 있습니다.

플러그인 도구

관리자는 각 플러그인의 MCP 인터페이스를 활성화해야 합니다. 활성화된 도구는 tools/list에 <pluginId>__<localName> 형태로 나타나며, 토큰으로 인증된 호출에는 mcp:tools 또는 mcp:tools:<pluginId>가 필요합니다. EmDash는 플러그인 라우트가 선언한 권한도 확인하고, 플러그인, 도구, 라우트, 실행 주체를 감사 로그에 기록합니다.

플러그인 도구는 설치마다 다르므로 위의 정적 목록에는 포함되지 않습니다.

OAuth 디스커버리

MCP 클라이언트는 보호된 리소스 메타데이터에서 인증 서버를 찾습니다.

GET /.well-known/oauth-protected-resource

응답은 /_emdash/api/mcp를 보호된 리소스로 식별하고 인증 서버로의 링크를 제공합니다. 그런 다음 클라이언트는 다음 위치에서 해당 메타데이터를 읽습니다.

GET /.well-known/oauth-authorization-server/_emdash

이 문서는 현재의 인증, 토큰, 등록, 디바이스 인증 엔드포인트와 지원되는 스코프, 그랜트 유형, S256 PKCE 메서드를 제공합니다. OAuth 프로토콜 라우트를 하드코딩하지 말고 디스커버리로 찾은 값을 사용하세요.

인증되지 않은 MCP 요청은 디스커버리 URL이 포함된 401 응답을 반환합니다.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://example.com/.well-known/oauth-protected-resource"

오류

도구 실패에는 isError: true가 설정됩니다. 첫 번째 텍스트 블록은 안정적인 코드로 시작하며, 구조화된 메타데이터를 읽는 클라이언트를 위해 _meta.code가 같은 코드를 반복합니다.

{
	"content": [{ "type": "text", "text": "[NOT_FOUND] Collection 'articles' not found" }],
	"isError": true,
	"_meta": { "code": "NOT_FOUND" }
}

항목의 편집 잠금으로 인한 거부에는 _meta.details에 잠금 보유자가 담겨 있습니다.

{
	"content": [{ "type": "text", "text": "[ENTRY_LOCKED] Ada is holding this entry" }],
	"isError": true,
	"_meta": {
		"code": "ENTRY_LOCKED",
		"details": {
			"userId": "01JB...",
			"userName": "Ada",
			"acquiredAt": "2026-05-01T09:12:04.117Z",
			"expiresAt": "2026-05-01T09:19:04.117Z"
		}
	}
}

인증 실패에는 INSUFFICIENT_SCOPE, INSUFFICIENT_PERMISSIONS 같은 코드가 사용됩니다. 트랜스포트 실패에는 JSON-RPC 내부 오류 코드 -32603이 사용되며, 근본적인 예외는 노출되지 않습니다.