> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Didit MCP 고급 설정, 문제 해결 및 자체 호스팅

> Didit MCP의 역할 및 권한, 앱 간 동작, 호스팅 카탈로그, 분기 워크플로, webhook, 전송 방식, 문제 해결, 자체 호스팅을 다룹니다.

## 범위 및 역할 권한

이 커넥터는 `didit:management` 및 `didit:verification` 범위에서 동작합니다(세 번째 범위인 `didit:staff`도 안내되지만 Didit 직원 계정에만 의미가 있습니다). 두 경계는 모든 호출에서 적용됩니다. 토큰에는 승인한 범위가 담기고, **그 범위 안에서는 콘솔 역할이 수행할 수 있는 작업을 결정합니다**. 실제 접근 권한은 두 조건의 교집합입니다. 따라서 `didit:verification`만 승인하면 `OWNER`라도 관리 영역은 계속 닫혀 있습니다.

각 도구는 하나의 백엔드 권한에 대응합니다(`read:sessions`, `write:workflows`, `delete:lists` 등. [도구 참조](https://docs.didit.me/ko/integration/mcp/tools.md)에서 도구별로 확인할 수 있습니다). 서버는 토큰 인트로스펙션이 반환하는 조직 권한을 기준으로 해당 권한을 사전 검사하며, 이 동작은 `MCP_PERMISSION_MODE`로 제어합니다.

| 모드 | 동작 |
| - | - |
| `shadow` (기본값) | 모든 도구가 목록에 표시됩니다. 역할로 실행할 수 없는 호출도 백엔드로 전달되며, 백엔드가 `403`으로 응답합니다. 판정 결과는 서버의 감사 로그에 기록됩니다. |
| `enforce` | 역할로 실행할 수 없는 도구는 `tools/list`에서 제외됩니다. 해당 도구를 호출하면 권한 이름을 명시한 `missing_scope` 오류가 반환됩니다. |
| `off` | 사전 검사를 하지 않습니다. |

MCP는 역할을 넘어서는 권한을 부여하지 않습니다. 한 도구에서 `403`이 나오면 역할에 해당 권한이 없다는 뜻이며, 연결 전체가 실패한 것은 아닙니다.

***

## 교차 애플리케이션 및 조직 확인

Didit 관리 API는 애플리케이션 단위로 범위가 지정됩니다(`/organization/{org}/application/{app}/…`). MCP가 범위를 대신 확인합니다.

* **단일 조직 + 애플리케이션** → 자동으로 확인되며, ID를 직접 전달할 필요가 없습니다.
* **여러 애플리케이션** → 교차 애플리케이션 도구(`didit_session_search`, `didit_transaction_search`, `didit_case_search`, `didit_vendor_user_search`, `didit_vendor_business_search`, `didit_workflow_search`, `didit_analytics`)는 한 번의 호출로 **전체**를 대상으로 집계하며, 각 행에 `organization_id` / `application_id`가 태그로 붙습니다.
* 애플리케이션별 목록 도구(`didit_session_list`, `didit_transaction_list`, `didit_case_list`, `didit_vendor_user_list`, `didit_vendor_business_list`, `didit_workflow_list`)는 애플리케이션을 지정하지 않으면 **전체** 애플리케이션에 걸쳐 자동으로 조회합니다. 따라서 애플리케이션이 많아도 "내 세션 목록 보기" 같은 단순 요청이 동작합니다. 단일 애플리케이션으로 좁히려면 `organization_id`와 `application_id`를 전달하세요.

`didit_context_get`을 사용하면 한 번의 호출로 모든 조직과 애플리케이션 및 ID를 확인할 수 있습니다. 이 도구는 각 애플리케이션의 `mode`(`live` 또는 `sandbox`)도 함께 반환하므로, 애플리케이션 이름으로 환경을 추측하지 마세요. `didit_session_create`는 샌드박스 애플리케이션에서 `sandbox_scenario`를 받아 요금이 청구되지 않는 테스트 실행을 지원합니다.

***

## 호스팅 카탈로그의 내용

호스팅 커넥터에서는 **169개 도구**를 사용할 수 있습니다. 목록에는 Investigator를 조직에 활성화한 경우에만 동작하는 Investigator 도구 17개도 포함됩니다. 추가로 두 도구, `didit_org_top_up`(Stripe 체크아웃)과 `didit_org_reveal_application_api_key`(원본 비밀 값)는 OAuth로 인증한 모든 호출자의 `tools/list`에서 숨겨집니다. 계정 설정 도구 5개(`didit_account_*`)는 원격 서버에서 완전히 제외되며, 실행을 시도하면 거부됩니다. 원격 커넥터는 자격 증명을 도구 인자로 받아서는 안 되기 때문입니다. 로컬 stdio 서버에서는 이 도구들을 모두 유지하며, 총 193개입니다.

각 도구에는 MCP 주석(`readOnlyHint`, `destructiveHint`, `openWorldHint`, `title`)과 `outputSchema`가 있습니다. 또한 해당 영역(세션, 워크플로 및 설문지, 거래(AML) 등)을 나타내는 `_meta["anthropic/toolGroup"]` 레이블이 붙습니다. Claude 같은 클라이언트는 이 주석을 사용해 커넥터의 도구를 읽기 전용, 쓰기, 파괴적 작업 그룹으로 나눕니다.

## 분기 워크플로

단순한 워크플로는 기능의 평면 목록입니다. **조건부 로직**(상태에 따른 거부, 추출된 필드에 따른 경로 분기, 일치 여부에 따라 단계 진행 여부를 결정, Document AI 요청 추가 등)을 구현하려면 MCP가 Didit의 **노드 그래프**(콘솔 비주얼 빌더와 같은 구조)를 사용합니다. 그래프는 `{ start_node, nodes }` 형태이며, 각 노드는 `feature`, `branch`, `status`(종료), `action`, `webhook` 중 하나입니다. 분기 규칙은 `kyc.extra_fields.profession`과 같은 추출 필드에 대해 `fuzzy_match`를 포함한 연산자를 지원합니다(문자열 필드, 유사도 임계값 `score`는 0\~100). `DOCUMENT_AI` 기능 노드는 문서(예: 자금 증명)를 요청합니다.

### 기존 워크플로 편집(권장)

실제 워크플로에는 **대용량** 기능 구성이 포함됩니다. OCR `documents_allowed` 허용 목록은 150 KB 이상일 수 있고, 주소 증명 목록과 전화번호 국가 목록도 있습니다. 따라서 그래프 전체를 읽어서 다시 보내지 **마십시오**. 대신 작은 **작업(operation)**으로 편집합니다.

**1. 위치 찾기 및 확인**

`didit_workflow_search { workflow_id }`는 모든 앱에서 워크플로를 찾습니다. `didit_workflow_get_graph`는 구조를 반환하며, 대용량 구성은 **요약**되어 반환되며, 응답이 크기 제한을 초과하지 않습니다. 원본 값을 보려면 `include_config: true`를 전달하십시오. `didit_workflow_get_field_definitions`는 분기에 사용할 수 있는 필드와 유효한 연산자를 나열합니다.

**2. 작업으로 편집**

`didit_workflow_edit_graph`는 `set_next`, `set_node`, `set_branches`, `merge_node_config`와 같은 작은 작업 몇 개를 받습니다. MCP는 서버에서 **전체 그래프**를 가져와 작업을 적용하고 검증한 뒤, **초안**을 자동으로 만들어 저장합니다. 허용 목록은 바이트 단위로 그대로 보존되며 요청을 통해 전달되지 않습니다. 검증이 실패하면 `applied: false`가 반환되며, 아무것도 저장되지 않습니다.

**3. 검토 및 게시**

`publish`(콘솔에서 또는 `didit_workflow_publish`로)를 실행하기 전까지는 검토 가능한 초안으로 남습니다. 프로덕션 버전은 변경되지 않습니다.

예를 들어 신분증 인증 뒤에 기존 파이프라인으로 **다시 연결되는** 분기를 삽입하려면, OCR 노드의 `next`를 새 분기로 다시 연결하고, 분기, 종료 노드인 `Declined`, 그리고 `DOCUMENT_AI` 단계(그 `next`가 원래의 다음 단계를 가리킴)를 추가하는 작업만 보내면 됩니다. 나머지 10개 노드와 그 허용 목록은 변경되지 않습니다.

> *"신분증 인증 후 거부되었다면 거부합니다. 직업이 'Software Engineer'와 80% 이상 유사하면 자금 증명을 요청한 다음 계속 진행합니다."* → `branch` 노드 하나: `kyc.status == Declined` → `Declined` 상태 노드, `kyc.extra_fields.profession`의 `fuzzy_match` "Software Engineer" score 80 → `DOCUMENT_AI` 자금 증명 노드, 그리고 파이프라인으로 돌아가는 **기타** 경로.

> [!NOTE]
>
> **분기에는 항상 명시적인 기타 경로가 있어야 합니다.** 포괄 경로(어떤 조건과도 일치하지 않을 때 선택되는 경로)는 빈 `rules`를 가진 분기여야 하며, 예를 들어 `{ "id": "else", "rules": [], "goto": "<liveness>" }`와 같아야 합니다. 분기 노드의 단순 `next`를 사용하면 안 됩니다. MCP(및 백엔드)는 분기 노드의 `next`를 기타 분기로 자동 변환하므로, 분기가 보이는 기타 경로 없이 모호한 간선으로 표시되는 일은 없습니다.

**새** 워크플로를 처음부터 만들려면 `didit_workflow_validate_graph`를 실행한 뒤 `didit_workflow_set_graph`(전체 그래프)를 사용하거나, `didit_workflow_build_graph`가 저장하지 않고 일반 기능 사양으로부터 완전한 그래프를 조립하도록 하십시오. 일반 `didit_workflow_create`도 같은 노드 그래프로 저장됩니다. MCP는 `features` 목록을 연결된 기능 노드로 조립하고, 자동 결정 상태 노드로 끝나도록 만들어 기능이 실제로 실행되게 합니다. 기본적으로 게시되며, 게시하지 않으려면 `status: "draft"`를 전달하십시오. 전체 JSON 구조는 [Create Workflow → branching & node-based workflows](https://docs.didit.me/ko/management-api/workflows/create.md)를 참조하십시오.

### MCP로 NFC 건너뛰기 사유 분기 만들기

새 그래프의 경우 다음과 같이 요청합니다.

> *"신분증 인증 다음에 NFC를 수행하는 초안 워크플로를 만드십시오. `nfc.skip_reason`이 `DEVICE_WITHOUT_NFC` 또는 `DOCUMENT_WITHOUT_CHIP`이면 세션을 검토 중으로 보내고, 그렇지 않으면 승인하십시오. 명시적인 기타 분기를 유지하고 저장 전에 그래프를 검증하십시오."*

에이전트는 `didit_workflow_get_field_definitions`, `didit_workflow_validate_graph`, `didit_workflow_set_graph` 순으로 호출해야 합니다. 기존 워크플로의 경우 다음과 같이 요청합니다.

> *"워크플로 `26d33c04…`를 편집하십시오. NFC 노드 뒤에서, 알려진 `nfc.skip_reason` 값 7개 중 어느 하나라도 해당하면 검토 중으로 보내고, 기존의 NFC 성공 경로는 명시적인 기타 경로로 유지하십시오. 초안으로 저장하고 게시하지 마십시오."*

에이전트는 `didit_workflow_search`, `didit_workflow_get_graph`, `didit_workflow_get_field_definitions`, `didit_workflow_edit_graph` 순으로 호출해야 합니다. 편집 도구는 서버에서 작은 작업을 적용하므로 관련 없는 노드와 대용량 허용 목록이 보존됩니다. 7개 값, `equals`/`in` 규칙, null 동작, 그리고 완전한 순서 그래프는 [Create Workflow → Branch on why NFC did not run](https://docs.didit.me/ko/management-api/workflows/create.md#nfc가-실행되지-않은-이유에-따른-분기)을 참조하십시오.

### 기능 구성과 허용 목록

기능 노드의 `config`는 허용되는 입력을 제한합니다. `didit_workflow_get_feature_config_schema`는 각 기능이 받는 모든 키를 타입과 기본값과 함께 반환하며, 두 카탈로그 도구(`didit_workflow_get_id_verification_methods_catalog`, `didit_workflow_get_kyb_registry_catalog`)는 구성이 의존하는 서버 기반 질문에 답합니다. 표준 OCR 허용 목록은 국가별 → 문서별 → 객체 구조입니다: `{ "<ISO3>": { "<CODE>": { "enabled": 1 } } }`(예: `{ "ESP": { "P": { "enabled": 1 } } }`). MCP는 검증 전에 더 간단한 형태를 **정규화**하므로 이 구조를 직접 작성할 필요가 없습니다.

| 전달 가능한 형태 | 정규화 결과 |
| - | - |
| 문서 유형 배열 — `["PASSPORT"]` | **모든** 국가에서 해당 문서(전 세계 여권만) |
| 문서 **이름** 또는 **코드** — `PASSPORT`/`P`, `NATIONAL_ID`/`ID`, `DRIVER_LICENSE`/`DL`, `RESIDENCE_PERMIT`/`RP`(`SSC`, `HIC`, `TC`도 가능) | 표준 코드 |
| `"ALL"` 국가 키 — `{ "ALL": { "P": 1 } }` | 모든 국가에 적용 |
| 스칼라 플래그 — `{ "ESP": { "P": 1 } }` | `{ "ESP": { "P": { "enabled": 1 } } }` |
| 완전히 생략 | 모든 문서, 모든 국가 |

`PROOF_OF_ADDRESS`의 `poa_languages_allowed`도 같은 개념입니다. 언어 배열(`["es"]`) 또는 맵(`{ "es": 1 }`)을 전달할 수 있습니다. 이러한 편의 기능은 MCP에 기능 구성을 전달하는 모든 곳에서 적용됩니다. 즉, `didit_workflow_create`의 features, 그리고 `set_graph`, `edit_graph`, `validate_graph`의 노드 `config`에 해당합니다.

## 응답 형식 (V3 계약)

모든 도구는 기반이 되는 REST endpoint의 JSON 응답을 가공하지 않고 그대로 반환합니다. 알아두실 사항은 두 가지입니다.

* **동기 도구**(워크플로, 결제, 단독 `verify_*`, 목록 관리)는 최종 결과를 응답에 바로 포함합니다. 같은 턴에서 바로 처리하면 됩니다.
* **세션 생성은 비동기입니다.** `didit_session_create`는 사용자가 완료해야 하는 `url`을 반환하며, 결정 결과는 webhook 또는 `didit_session_get_decision`으로 전달됩니다.

결정 키는 **항상 복수형 배열**이며, 각 항목에 `node_id`가 있습니다(`id_verifications[]`, `liveness_checks[]`, `face_matches[]`, `aml_screenings[]`, `poa_verifications[]`, `phone_verifications[]`, `email_verifications[]`, `database_validations[]`, `reviews[]`, 그리고 KYB의 `registry_checks[]`, `document_verifications[]`, `key_people_checks[]`). 자세한 내용은 [데이터 모델](https://docs.didit.me/ko/reference/data-models.md)과 [인증 상태](https://docs.didit.me/ko/integration/verification-statuses.md)를 참고하세요.

***

## webhook 처리

에이전트가 폴링하지 않고, webhook으로 최종 결정을 백엔드에 전달받으세요.

1. 에이전트는 `didit_webhook_create`를 한 번 호출하며, 이때 `label`, 공개 HTTPS `url`, `webhook_version: "v3"`, `subscribed_events`(보통 `["status.updated", "data.updated"]`)를 전달합니다. 응답에서는 서명 비밀이 가려지며, `didit_webhook_get`과 `didit_webhook_list`도 마찬가지입니다. 콘솔의 **Webhooks**에서 비밀을 복사해 `DIDIT_WEBHOOK_SECRET`으로 저장하세요.
2. 백엔드는 모든 전송에서 정규화된 **X-Signature-V2** 헤더를 검증해야 합니다. 순서는 `shortenFloats` → `sortKeys` → `JSON.stringify`(유니코드 이스케이프 없이) → HMAC-SHA256 → `timingSafeEqual`입니다. `abs(now − X-Timestamp) > 300`(초)이면 요청을 거부하세요.
3. `event_id`로 중복을 제거하세요. **5초** 안에 `2xx`를 반환하고, 무거운 작업은 큐로 넘기세요.
4. Didit은 `5xx` 또는 `404` 응답에 대해 최대 **2회** 재시도합니다(약 1분 후, 이후 약 4분 후). 그 후에는 해당 전송을 폐기합니다. 실패한 전송은 콘솔의 **전송** 탭에서 다시 보낼 수 있습니다.

에이전트는 수신 측을 *연결*하기만 하면 되며, 직접 수신하지는 않습니다. 전체 계약은 [webhook](https://docs.didit.me/ko/integration/webhooks.md)을 참고하세요.

***

## 전송 방식과 endpoint

| Endpoint | 용도 |
| - | - |
| `POST https://mcp.didit.me/mcp` | MCP endpoint(Streamable HTTP)입니다. `GET`과 `DELETE`는 `405`를 반환합니다. 서버는 상태를 저장하지 않으며, 요청마다 새 서버 인스턴스를 만듭니다. 서버가 시작하는 스트림이나 세션이 없으므로 종료할 대상도 없습니다. |
| `GET https://mcp.didit.me/healthz` | 상태 확인: `{ "status": "ok", "service": "didit-mcp-server", "version": "5.1.1" }`. |
| `GET https://mcp.didit.me/.well-known/oauth-protected-resource/mcp` | RFC 9728 보호된 리소스 메타데이터입니다(오리진 루트에서도 제공됩니다). |

이 endpoint는 두 가지 방식을 모두 지원합니다. 모든 메시지에 2026-07-28 이상의 프로토콜 버전을 고정하는 클라이언트는 `initialize` 핸드셰이크를 건너뛰고 `server/discover`를 호출할 수 있습니다. 그 이전 버전을 사용하는 클라이언트(Claude Code, Cursor, SDK 기반 클라이언트)는 표준 Streamable HTTP 핸드셰이크를 그대로 사용합니다. CORS는 열려 있으므로, 브라우저 기반 클라이언트(Claude 웹 커넥터, MCP Inspector)도 `/mcp`와 디스커버리 문서에 교차 출처로 접근할 수 있습니다. JSON 본문 제한은 25 MB이며, 이는 15 MB base64 파일 입력을 처리하기에 충분합니다.

***

## 문제 해결

> [accordion] 에이전트가 도구를 호출했지만 403 또는 missing\_scope를 받습니다
>
> 해당 조직에서 사용자의 **역할**에 도구가 필요로 하는 권한이 없습니다(예: `READER`가 쓰기를 시도한 경우). `missing_scope` 오류에 필요한 권한이 표시됩니다. 모든 도구가 실패하면 다시 연결하거나 *Log in with Didit*을 다시 실행하세요. (MCP는 Bearer/OAuth만 지원합니다. 모든 도구가 `x-api-key`를 거부하므로, API 키로는 403을 해결할 수 없습니다.)

> [accordion] 쓰기 또는 삭제가 실행되지 않았습니다
>
> 파괴적인 도구는 클라이언트에서 확인을 요구합니다. 호출을 승인하거나, 도구의 확인 메시지가 자동으로 거부되고 있지 않은지 확인하세요. `didit_session_delete`, `didit_session_batch_delete`, `didit_org_reveal_application_api_key`는 도구 인수에 `confirm: true`도 필요합니다. 이 값이 없으면 아무것도 실행되기 전에 호출이 거부됩니다.

> [accordion] 'organization\_id is required' 또는 결과가 없습니다
>
> 앱이 여러 개일 가능성이 높습니다. 전체를 검색하는 `*_search` 도구를 사용하거나, `didit_context_get`을 실행한 후 원하는 `organization_id` / `application_id`를 전달하세요.

> [accordion] 브라우저에서 로그인 창이 열리지 않습니다(호스팅)
>
> 일부 클라이언트(Windsurf, Zed)는 `mcp-remote` 브리지를 통해 연결합니다. 설정에 `npx -y mcp-remote@latest https://mcp.didit.me/mcp`가 있는지 확인하세요. 클라이언트를 다시 열면 OAuth 핸드셰이크가 다시 시작됩니다.

> [accordion] 클라이언트에 도구가 표시되지 않습니다
>
> 서버가 연결되었는지 확인하세요(대부분의 클라이언트는 상태 표시등을 보여줍니다). *Log in with Didit*을 완료했는지도 확인하세요. 설정을 변경한 후에는 MCP 호스트를 다시 시작하세요. `didit_org_top_up`과 `didit_org_reveal_application_api_key`는 호스팅 커넥터에 절대 나열되지 않습니다.

> [accordion] VS Code(또는 다른 클라이언트)가 OAuth를 찾지 못하거나 브라우저를 열지 않습니다
>
> 기본 오리진 `https://mcp.didit.me`가 아니라 `https://mcp.didit.me/mcp`를 가리키는지 확인하세요. 리소스 메타데이터는 `/.well-known/oauth-protected-resource/mcp`에서 해당 경로 범위로 제공됩니다(오리진 루트에도 사본이 있어 해당 위치를 확인하는 클라이언트를 지원합니다). 자체 호스팅 중이라면 보통 `MCP_RESOURCE_URI`가 전체 전송 URL 대신 오리진으로 설정되어 있는 경우입니다. [자체 호스팅](#셀프-호스팅)을 참고하세요.

> [accordion] 파일 업로드가 거부됩니다
>
> 호스팅 endpoint에서는 파일을 `*_base64`(순수 base64 또는 `data:` URL)로 보내야 합니다. `*_path`는 로컬 stdio 서버에서만 작동합니다. 파일은 최대 15 MB이며, 확장자가 아닌 내용 기준으로 PNG, JPG, WebP, GIF, BMP, ICO 또는 PDF 형식이어야 합니다.

***

## 보안

MCP는 사용자의 실제 권한으로 동작하며 운영 리소스를 변경할 수 있습니다. 클라이언트에서 **"review tool calls before running"** 설정을 계속 켜 두십시오. 특히 **Write** 및 **Destructive** 도구에 대해 활성화해 두십시오. MCP 자체는 설정에 **비밀 값을 저장하지 않습니다**(**Didit으로 로그인**을 사용합니다). 도구 출력에서는 API 키와 webhook 서명 비밀을 가립니다. 호스팅된 카탈로그에서는 충전 도구와 원본 키 도구를 숨기며, 원격 서버에서는 계정 자격 증명을 도구 인자로 절대 받지 않습니다. 모든 도구 호출은 호출자, 도구, 권한 판정과 함께 서버의 감사 로그에 기록됩니다.

### 프롬프트 인젝션

Didit 도구는 이름, 문서 텍스트, 설문지 답변처럼 사용자가 입력하거나 업로드한 내용을 반환합니다.
인증을 받는 사람이 이 텍스트를 통제할 수 있으므로, 이름이나 문서에 에이전트를 겨냥한 지시를 적어 넣을 수 있습니다. 서버는 이 필드를 수집된 그대로 반환합니다.
에이전트는 이 텍스트를 여러분의 지시와 안정적으로 구분하지 못합니다. 따라서 모든 도구 결과를 데이터로 취급하십시오.

* **Write** 및 **Destructive** 도구에 대한 도구 승인을 계속 켜 두고, 승인하기 전에 에이전트가 무엇을 하려는지 확인하십시오.
* 작업에 맞는 역할의 멤버로 로그인하십시오. 세션만 읽는 에이전트라면 `READER` 멤버를 사용할 수 있으며, 에이전트가 무엇을 시도하든 백엔드는 그 쓰기 요청을 거부합니다.
* 새 에이전트나 프롬프트는 먼저 [샌드박스 애플리케이션](https://docs.didit.me/ko/integration/sandbox-testing.md)에서 시험하십시오.
* 인증 내부의 텍스트가 그렇게 하라고 한다는 이유로 인증을 승인하거나 거부하지 마십시오. 결정, 경고, 그리고 여러분의 직접 검토에 근거하십시오.

### 개인정보

도구 결과에는 이름, 생년월일, 문서 번호, 이미지 링크 같은 개인정보가 포함될 수 있으며, MCP 클라이언트는 이를 사용하는 모델로 전송합니다.
실제 애플리케이션을 연결하기 전에, AI 제공업체와의 계약이 이 데이터를 포괄하는지 확인하거나 샌드박스 애플리케이션에서 작업하십시오.

***

## 셀프 호스팅

호스팅된 서버는 [github.com/didit-protocol/mcp](https://github.com/didit-protocol/mcp)(MIT)에서 빌드됩니다. 저장소를 복제한 뒤 **Docker** 또는 Node로 실행하십시오. 전송 방식과 관계없이 항상 Didit **사용자**로 인증하며 API 키 모드는 없습니다. 설정 단계는 [설치 → 셀프 호스팅](https://docs.didit.me/ko/integration/mcp/installation.md#셀프-호스팅)에 있습니다.

```bash theme={null}
git clone https://github.com/didit-protocol/mcp.git && cd mcp

# Docker (recommended) — serves /mcp + /healthz on port 3000
docker build -t didit-mcp . && docker run -p 3000:3000 --env-file .env didit-mcp

# …or with Node
npm install && npm run build
node dist/http.js                                          # hosted HTTP/OAuth
DIDIT_ACCESS_TOKEN=<user-access-token> node dist/index.js  # stdio (headless)
```

### 환경 변수

| 변수 | 모드 | 용도 |
| - | - | - |
| `DIDIT_ACCESS_TOKEN` | stdio | 헤드리스 실행에 사용하는 사용자의 Bearer 액세스 토큰입니다. |
| `DIDIT_API_BASE_URL` | 둘 다 | 인증 API 기본 URL입니다(기본값 `https://verification.didit.me/v3`). |
| `DIDIT_AUTH_BASE_URL` | 둘 다 | 인증 API 기본 URL입니다(기본값 `https://apx.didit.me/auth/v2`). |
| `MCP_PORT` | 호스팅 | HTTP 수신 포트입니다(기본값 `3000`). |
| `MCP_RESOURCE_URI` | 호스팅 | 전송 계층의 공개 URL이며 경로를 포함합니다(예: `https://mcp.example.com/mcp`). RFC 9728 메타데이터 URL은 이 값에서 파생됩니다. |
| `MCP_AUTHORIZATION_SERVER_ORIGIN` | 호스팅 | 인가 서버의 출처(origin)입니다(기본값 `https://business.didit.me`). |
| `MCP_TOKEN_VERIFY_MODE` | 호스팅 | `introspection`(기본값, 불투명 토큰) 또는 `jwks`(JWT 액세스 토큰)입니다. |
| `MCP_OAUTH_INTROSPECT_URL` | 호스팅 | RFC 7662 인트로스펙션 endpoint입니다. |
| `MCP_OAUTH_CLIENT_ID` / `MCP_OAUTH_CLIENT_SECRET` | 호스팅 | 리소스 서버가 인트로스펙션을 호출할 때 사용하는 Basic 인증 자격 증명입니다. 시크릿 관리자에서 제공하십시오. |
| `MCP_SCOPES_SUPPORTED` | 호스팅 | 메타데이터에 공개되는 스코프입니다(기본값 `didit:management didit:verification`). |
| `MCP_DEFAULT_ORG` / `MCP_DEFAULT_APP` | 둘 다 | 단일 테넌트 배포에서 스코프를 자동으로 채웁니다. |
| `DIDIT_AUTH_ISSUER`, `DIDIT_OIDC_DISCOVERY_URL`, `DIDIT_OIDC_AUTHORIZE_URL`, `DIDIT_OIDC_TOKEN_URL`, `DIDIT_OIDC_REGISTRATION_URL` | 호스팅 | 인가 서버 메타데이터를 재정의합니다. 인가 서버가 엔드포인트를 origin의 기본 위치가 아닌 다른 곳에 게시하는 경우에만 필요합니다. |
| `DIDIT_JWKS_URL` | 호스팅 | `MCP_TOKEN_VERIFY_MODE=jwks`일 때 사용하는 JWKS입니다. |
| `MCP_PERMISSION_MODE` | 둘 다 | 도구별 권한 사전 검사입니다: `shadow`(기본값), `enforce` 또는 `off`. |
| `MCP_JSON_BODY_LIMIT` | 호스팅 | JSON-RPC 본문 크기 제한입니다(기본값 `25mb`). |

저장소의 `.env.example`은 복사해 사용할 수 있는 템플릿이며, `ARCHITECTURE.md`는 리소스 서버와 인가 서버의 분리 구조를 설명합니다. 부팅 시 HTTP 서버는 인가 서버의 디스커버리 문서를 가져오며, 도달할 수 없으면 설정된 URL로 대체합니다.

***

> [card] [도구 참조](https://docs.didit.me/ko/integration/mcp/tools.md)
>
> 모든 도구를 영역별로 묶어 정리했습니다.

> [card] [예시](https://docs.didit.me/ko/integration/mcp/examples.md)
>
> 프롬프트와 처음부터 끝까지의 대화 예시입니다.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.