> ## 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으로 로그인(OAuth)

> Didit MCP는 PKCE를 사용하는 OAuth 2.1, 동적 클라이언트 등록, 리소스 메타데이터, 스코프, 역할로 인증합니다. 각 클라이언트에서 연결하는 방법도 설명합니다.

Didit MCP는 **Didit으로 로그인**(OAuth 2.1)으로 인증합니다. 이때 콘솔 역할의 권한을 가진 Didit **사용자**로 동작합니다. **API 키 모드는 없습니다.**

***

## Didit으로 로그인

호스팅 서버(`https://mcp.didit.me/mcp`)는 OAuth 2.1 **리소스 서버**입니다. **Didit Business Console**(`business.didit.me`)은 동의 화면을 제공하고 토큰을 발급하는 **인가 서버**입니다. MCP 클라이언트가 표준 흐름을 자동으로 진행합니다.

**1. 탐색**

클라이언트는 토큰 없이 `/mcp`에 POST 요청을 보내고, `resource_metadata`가 보호된 리소스 메타데이터(RFC 9728)를 가리키는 `WWW-Authenticate: Bearer` 헤더와 함께 `401`을 받습니다.

```text theme={null}
https://mcp.didit.me/.well-known/oauth-protected-resource/mcp
```

이 문서에는 리소스(`https://mcp.didit.me/mcp`), 인가 서버(`https://business.didit.me`), 지원되는 스코프가 명시되어 있습니다. 같은 문서는 먼저 이 경로를 확인하는 클라이언트를 위해 오리진 루트인 `https://mcp.didit.me/.well-known/oauth-protected-resource`에서도 제공됩니다.

**2. 등록(동적 클라이언트 등록)**

클라이언트는 `https://business.didit.me/.well-known/oauth-authorization-server`에서 인가 서버 메타데이터를 읽고, 클라이언트 ID가 없으면 `registration_endpoint`에 자신을 등록합니다(RFC 7591). 사용자 측에서 미리 설정할 것은 없습니다. 루프백 또는 네이티브 콜백을 사용하는 로컬 클라이언트(Claude Code, Cursor, MCP Inspector)와 검토된 콜백을 사용하는 클라우드 호스팅 클라이언트(Claude) 모두 이 방식으로 등록합니다. Didit이 검토하지 않은 원격 콜백 URL은 `invalid_redirect_uri`와 함께 거부되며, 이런 클라이언트는 먼저 운영자가 등록해야 합니다.

**3. 인가(PKCE)**

클라이언트는 S256 PKCE 챌린지와 함께 `https://business.didit.me/authorize`를 엽니다. 사용자는 로그인하거나 등록하고, 요청된 권한을 정확히 확인할 수 있습니다. 클라이언트는 공개 클라이언트이므로 토큰 엔드포인트는 클라이언트 시크릿을 받지 않습니다(`token_endpoint_auth_methods_supported`는 `none`). 따라서 인가 코드를 클라이언트에 묶는 역할은 PKCE가 합니다.

**4. 동의**

사용자가 승인합니다. 콘솔은 해당 앱을 위한 세션을 만들고, 사용자가 승인한 스코프에 묶어 둔 뒤 인가 코드를 반환합니다. 클라이언트는 이 코드를 `token_endpoint`에서 액세스 토큰과 리프레시 토큰으로 교환합니다.

**5. 도구 호출**

클라이언트는 모든 요청에 액세스 토큰을 보냅니다. MCP는 Didit 인증 서비스에 대해 RFC 7662 토큰 인트로스펙션으로 토큰을 검증합니다(토큰은 JWT가 아닌 불투명 토큰입니다). 인트로스펙션 응답에서 사용자 조직의 권한을 읽고, 해당 요청 동안 **사용자 본인**으로서 동작합니다.

### 스코프

리소스 메타데이터에는 세 가지 스코프가 공개되어 있습니다. 동의 화면에는 클라이언트가 요청한 스코프가 쉬운 말로 표시됩니다.

| 스코프 | 부여되는 권한 |
| - | - |
| `didit:management` | 워크스페이스를 관리합니다. `organization`, `members`, `subscription`, `users`, `applications`, `workflows`, `customization`, `questionnaires`, `lists`, `webhooks`, `integrations`, `api-keys`, `audit-logs`, `roles`, `saml`, `analytics`를 포함합니다. |
| `didit:verification` | 인증을 실행하고 검토합니다. `sessions`, `businesses`, `cases`, `networks`, `transactions`, `blocklist`, `analytics`를 포함합니다. |
| `didit:staff` | Didit 직원 계정을 위해 예약되어 있습니다. 일반 계정에는 아무것도 열지 않으며, 오픈 소스 빌드에는 직원 전용 도구가 정의되어 있지 않습니다. |

두 스코프 모두 `analytics`를 포함합니다. `lists`를 관리하려면 `didit:management`가 필요하고, `blocklist`에 접근하려면 `didit:verification`이 필요합니다.

[도구 참조](https://docs.didit.me/ko/integration/mcp/tools.md)에는 각 도구가 속한 스코프가 나열되어 있습니다. 승인한 스코프는 토큰에 담겨 서버에서 강제됩니다. 따라서 `didit:verification`만 승인된 앱은 사용자의 역할이 허용하더라도 관리 영역에서 거부됩니다. 인가 서버는 OpenID 스코프(`openid profile email`)도 인식합니다. 이 스코프만 요청하는 연결은 사용자가 누구인지만 확인할 수 있고, 그 밖의 권한은 없습니다.

앱의 실효 권한은 승인된 스코프와 콘솔 역할의 **교집합**입니다. 둘 중 더 넓은 쪽이 적용되지 않습니다.

`didit_session_create`로 인증 세션을 만들려면 `didit:verification` 스코프**와** `create:sessions` 또는 `write:sessions` 권한을 가진 역할이 모두 필요합니다. **개발자** 역할에는 `create:sessions`가 포함됩니다. 역할에 필요한 권한이 있더라도 `didit:management`만 승인하면 세션을 만들 수 없습니다.

### 역할과 권한

호스팅 토큰은 **사용자 본인**을 나타내므로, 에이전트는 하나의 연결로 **사용자가 속한 모든 조직**에서 작업할 수 있습니다. 교차 앱 도구(`didit_session_search`, `didit_analytics`, `didit_context_get`, 그리고 나머지 `*_search` 도구)는 이 모든 조직의 데이터를 자동으로 집계합니다.

**사용자의 역할**은 항상 Didit 백엔드가 조직별로 강제합니다. 각 도구는 하나의 백엔드 권한 문자열에 대응합니다(예: `didit_session_update_status`는 `write:sessions`, `didit_session_delete`는 `delete:sessions`). 대응 권한은 [도구 참조](https://docs.didit.me/ko/integration/mcp/tools.md)에서 도구별로 확인할 수 있습니다. 서버는 요청을 보내기 전에 해당 권한을 확인하며, 이때 인트로스펙션 응답이 담고 있는 조직별 권한을 사용합니다.

* `enforce` 모드에서는 역할이 실행할 수 없는 도구가 `tools/list`에서 제외됩니다. 그래도 호출하면 권한 이름을 명시한 `missing_scope` 오류가 반환됩니다(`"Your role in this organization does not include the permission 'delete:sessions' that didit_session_delete requires."`).
* `shadow` 모드(서버 기본값)에서는 모든 도구가 목록에 표시되고, 호출은 백엔드로 전달됩니다. 역할에 권한이 없으면 백엔드가 `403`으로 응답합니다. 이 판정은 서버의 감사 로그에만 기록됩니다.

어느 모드에서든 MCP는 사용자의 콘솔 역할이 이미 허용하는 범위를 넘어 권한을 부여하지 않습니다. `READER`는 목록을 보고 읽을 수 있고, `OWNER` 또는 `ADMIN`은 쓰기와 삭제를 할 수 있습니다.

### 토큰 수명

앱을 승인할 때 사용한 브라우저 세션과 별개의 세션이 주어집니다. 액세스 토큰의 수명은 짧습니다. 클라이언트는 리프레시 토큰(`grant_types_supported`에 `refresh_token`이 포함됨)으로 토큰을 조용히 갱신합니다. 갱신 시 앱의 스코프는 유지되며, 토큰은 계속 해당 앱에 묶여 있습니다. 갱신이 실패하면(예: 사용자가 앱 연결을 해제한 후), 클라이언트는 다음 호출 때 **Didit으로 로그인**을 다시 실행합니다.

로그아웃해도 연결된 앱은 로그아웃되지 않으며, 앱 연결을 해제해도 어디에서도 로그아웃되지 않습니다.

### 앱 연결 해제하기

**1. 콘솔에서**

**Settings → Authentication → Connected apps**에서 승인한 모든 앱을 등록된 이름과 부여된 권한과 함께 볼 수 있습니다. **연결 해제**를 누르면 해당 앱의 액세스 토큰과 갱신 토큰이 즉시 사용할 수 없게 되며, 다른 항목에는 영향을 주지 않습니다.

**2. 앱에서 (RFC 7009)**

클라이언트는 `https://business.didit.me/.well-known/oauth-authorization-server`의 메타데이터에 게시된 인가 서버의 `revocation_endpoint`로 토큰을 POST 요청으로 전송하여 자신의 액세스 권한을 철회할 수 있습니다. RFC 7009에 따라 호출이 성공하면 토큰이 여전히 유효했는지와 관계없이 `200`이 응답되므로, 응답만으로는 토큰이 유효했는지 알 수 없습니다. `503`은 권한 철회가 적용되지 않았다는 뜻입니다. 이 경우 토큰은 여전히 유효한 것으로 간주하고 다시 시도하십시오.

```bash theme={null}
curl -X POST https://business.didit.me/api/auth/oauth-revoke \
  -H "Content-Type: application/json" \
  -d '{"token": "<refresh-or-access-token>", "token_type_hint": "refresh_token", "client_id": "<your-client-id>"}'
```

> [!NOTE]
>
> **API 키가 필요하지 않은 이유는 무엇인가요?** 모든 MCP 도구는 사용자 범위의 콘솔 엔드포인트(`/organization/{org}/application/{app}/…`)를 호출합니다. 이 엔드포인트는 역할별 권한이 있는 Bearer 토큰으로 인가하며 **`x-api-key`를 거부합니다**. 애플리케이션 API 키는 자체 백엔드에서 [REST API](https://docs.didit.me/openapi-25.json)를 직접 호출할 때(예: 세션 생성) 사용하며, 이 MCP에는 사용하지 않습니다. `didit_org_list_api_keys`는 값을 가린 키 메타데이터를 보여 줍니다. 원시 키를 노출하는 도구는 호스팅된 커넥터에서 숨겨져 있습니다.

***

## 각 클라이언트에서 연결하기

모든 클라이언트는 같은 절차를 따르며, URL을 전달하는 방법만 다릅니다.

> [tab] Claude
>
> Business Console의 연동 페이지에 표시되는 딥 링크를 사용하십시오. 이 링크를 열면 **Add custom connector** 대화 상자가 미리 채워진 claude.ai가 열립니다.
>
> ```text theme={null}
> https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=Didit&connectorUrl=https://mcp.didit.me/mcp
> ```
>
> 확인한 다음 **Didit으로 로그인**을 완료하십시오. Claude Desktop에서는 **Settings → Connectors → Add custom connector**에서 같은 URL을 사용합니다. 자세한 내용은 [Claude 연결](https://docs.didit.me/ko/integration/mcp/claude.md)을 참조하십시오.

> [tab] Claude Code
>
> ```bash theme={null}
> claude mcp add --transport http didit https://mcp.didit.me/mcp
> ```
>
> 그런 다음 Claude Code 안에서 `/mcp`를 실행하여 브라우저 로그인을 시작하십시오.

> [tab] Cursor
>
> `~/.cursor/mcp.json`:
>
> ```json theme={null}
> { "mcpServers": { "didit": { "url": "https://mcp.didit.me/mcp" } } }
> ```
>
> Cursor는 자체적으로 등록하고 처음 사용할 때 브라우저를 엽니다.

> [tab] 일반 클라이언트
>
> OAuth 2.1을 지원하는 모든 Streamable HTTP 클라이언트에서 `https://mcp.didit.me/mcp`를 지정하십시오. 클라이언트는 다음을 수행해야 합니다.
>
> 1. `POST /mcp`를 보내고 `401`을 받은 뒤 `WWW-Authenticate`에서 `resource_metadata`를 읽습니다.
> 2. `https://mcp.didit.me/.well-known/oauth-protected-resource/mcp`를 가져온 다음 `https://business.didit.me/.well-known/oauth-authorization-server`에서 인가 서버 메타데이터를 가져옵니다.
> 3. 클라이언트 ID가 없으면 `registration_endpoint`에 등록합니다.
> 4. `authorization_endpoint`에서 PKCE(S256)를 사용한 인가 코드 흐름을 실행하고, `token_endpoint`에서 코드를 교환합니다.
> 5. 모든 `POST /mcp` 요청에 `Authorization: Bearer <access_token>`을 보냅니다.
>
> OAuth를 지원하지 않는 클라이언트는 `npx -y mcp-remote@latest https://mcp.didit.me/mcp`를 통해 연결할 수 있으며, 이 명령이 위의 1–5단계를 대신 수행합니다.

***

## 인증 실패

```text theme={null}
HTTP 401
WWW-Authenticate: Bearer error="invalid_token", error_description="Missing Authorization header", resource_metadata="https://mcp.didit.me/.well-known/oauth-protected-resource/mcp"
```

`/mcp`에서 `401`이 반환되면 토큰이 없거나 만료되었거나 철회된 것입니다. 클라이언트는 토큰을 갱신하거나 **Didit으로 로그인**을 다시 실행해야 합니다.

특정 도구에서 `403` 또는 `missing_scope` 오류가 발생하면, 보통 **역할**에 해당 권한이 없거나(예: `READER`가 쓰기 작업을 시도한 경우), 연결이 그 도구에 필요한 범위 없이 승인된 경우입니다. 전체 연결이 깨진 것은 아닙니다. 다시 연결하면서 두 범위를 모두 승인하면 두 번째 경우는 해결되며, 첫 번째 경우에는 역할을 변경해야 합니다.

모든 도구가 실패하면 콘솔의 **Settings → Authentication → Connected apps**를 확인하십시오. 거기에서 연결 해제된 앱은 다시 승인해야 합니다.

***

> [card] [도구 참조](https://docs.didit.me/ko/integration/mcp/tools.md)
>
> 각 도구가 하는 일, 필요한 범위, 역할별 권한을 설명합니다.

> [card] [고급](https://docs.didit.me/ko/integration/mcp/advanced.md)
>
> 역할, 앱 간 동작, 자체 호스팅을 설명합니다.


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