Plugins API
Claude Enterprise 조직의 플러그인 인벤토리를 파악하고 관리합니다. 플러그인과 버전을 업로드하고, 멤버에게 제공할 버전을 선택하고, 각 플러그인을 사용할 수 있는 사람을 제어하고, 검토를 위해 플러그인 파일을 다운로드하고, 마켓플레이스를 연결하기 전에 검증할 수 있습니다.
Plugins API를 사용하면 Claude Enterprise 조직의 모든 "plugin"(플러그인) 인벤토리를 파악하고, 자체 파이프라인에서 플러그인과 새 버전을 게시하고, 멤버에게 제공할 버전을 선택하고, 각 플러그인을 사용할 수 있는 사람을 제어하고, 검토를 위해 플러그인 파일을 다운로드하고, Git "marketplace"(마켓플레이스)를 연결하기 전에 확인할 수 있습니다.
플러그인 사용량 보고(멤버가 어떤 플러그인과 스킬을 얼마나 자주 사용하는지)에 대해서는 Analytics API를 참조하세요.
엔드포인트
이 API는 5개 리소스에 걸쳐 18개의 엔드포인트를 제공합니다:
| 리소스 | 엔드포인트 |
|---|---|
| 플러그인: 조직의 모든 플러그인 나열, 새 플러그인 업로드, 플러그인 조회, 멤버에게 제공할 버전 선택(롤백 또는 승격), 플러그인 삭제 | GET /v1/organizations/pluginsPOST /v1/organizations/pluginsGET /v1/organizations/plugins/{plugin_id}POST /v1/organizations/plugins/{plugin_id}DELETE /v1/organizations/plugins/{plugin_id} |
| 플러그인 버전: 플러그인의 버전 기록 나열, 새 버전 업로드, 버전 조회, 버전 파일 다운로드 | GET /v1/organizations/plugins/{plugin_id}/versionsPOST /v1/organizations/plugins/{plugin_id}/versionsGET /v1/organizations/plugins/{plugin_id}/versions/{version}GET /v1/organizations/plugins/{plugin_id}/versions/{version}/content |
| 설치 설정: 조직 소유 플러그인을 사용할 수 있는 사람 읽기, 조직 전체 또는 한 그룹에 대해 설정, 한 그룹의 설정 제거 | GET /v1/organizations/plugins/{plugin_id}/installation_settingsPOST /v1/organizations/plugins/{plugin_id}/installation_settings/{target}DELETE /v1/organizations/plugins/{plugin_id}/installation_settings/{target} |
| 공유: 멤버가 자신의 플러그인을 누구와 공유했는지 읽기(읽기 전용) | GET /v1/organizations/plugins/{plugin_id}/shares |
| 플러그인 마켓플레이스: 마켓플레이스 ID 찾기, 마켓플레이스 조회, 해당 마켓플레이스 플러그인의 기본 설치 설정 지정, 연결 전 마켓플레이스 콘텐츠 확인 | GET /v1/organizations/plugin_marketplacesGET /v1/organizations/plugin_marketplaces/{marketplace_id}POST /v1/organizations/plugin_marketplaces/{marketplace_id}POST /v1/organizations/plugin_marketplaces/validate_repositoryPOST /v1/organizations/plugin_marketplaces/validate_archive |
이번 릴리스에는 독립형 스킬(멤버가 claude.ai의 스킬 편집기에서 작성하거나 단일 스킬로 업로드한 스킬)이 포함되지 않습니다. 독립형 스킬은 인벤토리에 나타나지 않으며 여기서 생성할 수 없습니다. Anthropic이 게시하는 플러그인도 인벤토리에 포함되지 않으며, 그 사용량은 Analytics API에서 보고됩니다. 마켓플레이스의 생성, 저장소 연결, 삭제는 이 API가 아니라 claude.ai에서 이루어집니다.
사전 요구 사항
- 조직이 Claude Enterprise 플랜을 사용해야 합니다.
- 기본 소유자가 claude.ai > 조직 설정 > API에서
read:plugins범위,write:plugins범위 또는 둘 다를 가진 Admin API 키를 생성합니다. Admin API 키 생성을 참조하세요. - 모든 요청에는
x-api-key,anthropic-version: 2023-06-01,anthropic-beta: ce-plugins-2026-09-01의 세 가지 헤더가 포함됩니다.
Python, TypeScript, C#, Go, Java, PHP, Ruby SDK는 이러한 엔드포인트를 client.beta.organization 아래에, ant CLI는 ant beta:organization 아래에 제공하며, anthropic-version 및 anthropic-beta 헤더를 자동으로 전송합니다. 이 페이지의 예제는 각 SDK의 기본 클라이언트를 사용하며, 이 클라이언트는 CLI와 마찬가지로 ANTHROPIC_API_KEY 환경 변수에서 Admin API 키를 읽습니다. curl 예제는 같은 변수에서 키를 읽어 x-api-key 헤더로 전달합니다. Python, TypeScript, C#, Go, Java, Ruby 목록 예제와 CLI에서는 반복하는 동안 SDK가 추가 페이지를 가져오므로 limit은 전체 개수가 아니라 페이지 크기를 설정합니다. PHP 및 curl 예제는 한 페이지를 반환합니다(페이지네이션 참조).
API 키는 조직에 속하며, 키를 생성한 사람이 조직을 떠난 후에도 계속 작동합니다. 키를 공유하거나 소스 제어에 체크인하지 마세요.
빠른 시작
조직 자체 마켓플레이스에 있는 플러그인을 최신순으로 나열합니다:
client = anthropic.Anthropic()
plugins = client.beta.organization.plugins.list(owner_type="organization", limit=20)
# 필요에 따라 추가 페이지를 자동으로 가져옵니다.
for plugin in plugins:
print(f"{plugin.id}: {plugin.name}"){
"data": [
{
"type": "plugin",
"id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
"name": "sales-toolkit",
"display_name": "Sales Toolkit",
"description": "Account research and call prep for the sales team.",
"served_version_id": "pluginver_01Km7tL4pR9xF5sU2zV3jP6q",
"served_version_pinned": true,
"latest_version_id": "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p",
"manifest_version": "1.4.0",
"owner": { "type": "organization" },
"marketplace_id": "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
"created_by": { "type": "api_actor", "api_key_id": "apikey_01Nq9vN6rT2zH7uW4bX5mR8s" },
"organization_installation_preference": "available",
"organization_installation_preference_inherited": true,
"content_scan": { "status": "completed", "assessment": "pass", "reason": null },
"components": [
{
"type": "skill",
"name": "account-research",
"description": "Researches a customer account before a call."
},
{ "type": "mcp_server", "name": "crm", "description": null }
],
"reach": "remote",
"created_at": "2026-09-01T17:04:11Z",
"updated_at": "2026-09-15T14:12:30Z"
}
],
"next_page": "page_xK9f2LqT7vNw3pRzBd8sHy"
}이 예제에서 플러그인은 이전 버전에 고정되어 있습니다. 더 새로운 버전(latest_version_id)이 저장되어 있지만 아직 제공되지 않습니다.
범위
| 범위 | 부여 권한 |
|---|---|
read:plugins | 이 페이지의 모든 GET 엔드포인트(아카이브 다운로드 포함) 및 마켓플레이스 검증. |
write:plugins | 이 페이지의 모든 POST 및 DELETE 엔드포인트: 플러그인 생성, 버전 생성, 제공 버전 변경, 플러그인 삭제, 설치 설정 지정 및 제거, 마켓플레이스 기본값 설정, 그리고 마켓플레이스 검증. 읽기 권한은 부여하지 않습니다. |
read:org_audit | 보안 감사 통합을 위한 읽기 전용 범위: 이 페이지의 모든 GET 엔드포인트(아카이브 다운로드 포함)와 사용자 관리 및 Compliance API 읽기 엔드포인트. 마켓플레이스 검증이나 쓰기 권한은 부여하지 않습니다. |
read:compliance_org_data | 조직 메타데이터(이름, 유형, 역할, 그룹) 및 유효 설정을 위한 Compliance API의 범위. read:org_audit과 똑같이 이 페이지의 모든 GET 엔드포인트에 대한 권한을 부여하므로, Compliance Access Key로 두 번째 키 없이 플러그인을 읽을 수 있습니다. 마켓플레이스 검증이나 쓰기 권한은 부여하지 않습니다. |
하나의 키에 여러 범위를 지정할 수 있습니다. 플러그인을 업로드한 후 다시 읽는 통합에는 read:plugins와 write:plugins가 모두 필요합니다. 이 페이지에서 엔드포인트에 read:plugins 범위가 필요하다고 명시된 곳에서는 read:org_audit 또는 read:compliance_org_data를 가진 키도 사용할 수 있습니다.
멤버의 플러그인 파일에 대한 액세스
이러한 각 읽기 범위(read:plugins, read:org_audit, read:compliance_org_data)로는 claude.ai의 관리자 설정에 표시되지 않는 파일을 포함하여 멤버의 개인 마켓플레이스에 있는 플러그인의 파일을 다운로드할 수 있습니다. 또한 상위 조직에 바인딩된 read:org_audit 또는 read:compliance_org_data 키는 organization_id를 전달하여, 그 아래에 있으며 이 API에 액세스할 수 있는 모든 조직에서 이 작업을 수행할 수 있습니다(같은 상위 조직 아래의 다른 조직 읽기 참조). 이러한 각 다운로드는 Compliance API Activity Feed에 키, 플러그인, 버전, 멤버를 식별하는 claude_plugin_archive_accessed 이벤트를 기록합니다(Activity Feed 이벤트 참조). 조직 소유 플러그인의 다운로드는 기록되지 않습니다.
같은 상위 조직 아래의 다른 조직 읽기
read:plugins 및 write:plugins 키는 해당 키가 생성된 조직만 읽고 씁니다. 회사에 하나의 상위 조직 아래에 연결된 여러 Claude 조직이 있는 경우, 상위 조직의 기본 소유자가 연결된 모든 조직에 대해 생성한 read:org_audit 또는 read:compliance_org_data 키(Admin API 키 생성 참조)는 이 API에 액세스할 수 있는 해당 조직 중 어느 것이든 읽을 수 있습니다. 이 페이지의 모든 GET 엔드포인트에서 organization_id 쿼리 매개변수에 해당 조직의 ID를 전달하세요. ID는 claude.ai 설정에 표시되는 조직 UUID입니다(org_ 접두사가 붙은 형식도 허용됩니다). 매개변수가 없으면 키는 자신이 생성된 조직을 읽습니다. 404는 지정된 조직이 키의 상위 조직 아래에 없거나 해당 조직에서 이 API를 사용할 수 없음을 의미합니다. UUID나 org_ ID가 아닌 값은 400을 반환합니다. 그 외의 키가 자신의 조직이 아닌 다른 조직을 지정하면 404를 받습니다. 쓰기 작업은 organization_id를 허용하지 않습니다.
주요 개념
플러그인과 구성 요소
플러그인은 조직 멤버를 위해 Claude를 확장하는 패키지입니다. 플러그인은 다음 구성 요소를 임의로 조합하여 포함합니다:
| 구성 요소 | 설명 |
|---|---|
| 스킬(Skill) | 작업에 필요할 때 Claude가 로드하는 지침과 파일. |
| 명령(Command) | 멤버가 / 다음에 명령 이름을 입력하여 실행하는 저장된 프롬프트. |
| 에이전트(Agent) | Claude가 작업의 일부를 넘길 수 있는, 자체 지침을 가진 도우미 어시스턴트. |
| 훅(Hook) | Claude가 도구를 사용하기 전과 같이 세션에서 이벤트가 발생할 때 자동으로 실행되는 명령. |
| MCP 서버(MCP server) | Claude에서 다른 시스템의 도구와 데이터로의 연결(Model Context Protocol). |
| CLI | 플러그인을 통해 Claude가 실행할 수 있는 명령줄 프로그램. |
모든 플러그인에는 .claude-plugin/plugin.json에 매니페스트가 있습니다. 매니페스트의 name은 플러그인의 name이 되며, 이는 마켓플레이스 내에서 고유한 소문자 식별자입니다.
마켓플레이스
마켓플레이스는 플러그인의 컨테이너입니다. 각 마켓플레이스에는 소유자와 소스가 있습니다.
- 소유자. 조직은 자체 마켓플레이스를 소유합니다. 각 멤버도 개인 마켓플레이스를 가질 수 있습니다.
- 소스.
manual은 플러그인이 claude.ai에서, 또는 조직 마켓플레이스의 경우 이 API를 통해 업로드됨을 의미합니다.github,gitlab,public_git은 소유자가 연결한 Git 저장소에서 플러그인이 동기화됨을 의미합니다. 동기화된 마켓플레이스에는 아무것도 업로드할 수 없으며, 다음 동기화가 어느 변경이든 되돌리기 때문에 이 API로 해당 플러그인을 삭제할 수도 없습니다. 대신 저장소를 변경하세요.
조직의 "library marketplace"(라이브러리 마켓플레이스)는 마켓플레이스를 지정하지 않을 때 업로드가 들어가는 조직 소유 manual 마켓플레이스입니다. 이 마켓플레이스는 처음으로 무언가가 업로드될 때 생성됩니다.
조직 소유 플러그인과 멤버 소유 플러그인
플러그인의 owner.type은 플러그인이 누구의 마켓플레이스에 있는지를 나타냅니다:
organization: 이 API를 통해 관리할 수 있습니다. 단, Git에서 동기화되는 마켓플레이스의 플러그인은 여기서 업로드를 받거나 삭제할 수 없습니다.user: 한 멤버의 개인 마켓플레이스에 있습니다. 세부 정보를 읽고 파일을 다운로드할 수 있으며, 마켓플레이스가manual이면 삭제할 수 있습니다. 버전 업로드와 제공 버전 선택은403을 반환합니다. 공유는 claude.ai에서 멤버만 관리할 수 있습니다.
조직에서 멤버를 제거해도 해당 멤버의 플러그인은 제거되지 않습니다. 플러그인은 멤버의 user_id 아래 인벤토리에 남아 있으며 owner_user_id 필터로 여전히 찾을 수 있으므로, 떠난 멤버의 콘텐츠를 검토하고 제거할 수 있습니다. 플러그인은 멤버의 계정이 삭제될 때 삭제됩니다.
버전과 제공 버전
이 API, claude.ai, Git 동기화 중 어디에서 오든 모든 업로드는 변경할 수 없는 새 "version"(버전)을 생성합니다. 플러그인에는 버전을 가리키는 두 개의 포인터가 있습니다:
latest_version_id: 최신 버전.served_version_id: 멤버에게 제공되는 버전.
기본적으로 served_version_pinned는 false입니다. 즉, "served version"(제공 버전)은 최신 버전을 따르며, 각 새 버전은 저장되는 즉시 제공됩니다.
POST /v1/organizations/plugins/{plugin_id}로 버전을 선택하면 플러그인이 "pin"(고정)됩니다(served_version_pinned: true). 관리자가 claude.ai에서 버전을 선택하거나, 플러그인에 게시하려는 멤버의 요청을 수락하는 경우에도 마찬가지입니다. 그 이후로 새 업로드는 저장되고 latest_version_id를 갱신하지만, served_version_id를 다른 버전으로 지정할 때까지 멤버는 고정된 버전을 계속 사용합니다. 두 포인터가 서로 다른 플러그인에는 제공되지 않는 저장된 버전이 있습니다.
이를 통해 릴리스 파이프라인은 각 빌드를 업로드하고, 테스트한 다음, 승격할 수 있습니다. 각 빌드가 제공되는 시점을 파이프라인이 결정하도록 하려면 served_version_id를 현재 버전으로 설정하여 플러그인을 한 번 고정하세요. 그 이후로는 제공하려는 각 빌드를 승격하세요. "content scanning"(콘텐츠 스캔)이 켜져 있으면, 첫 번째 고정은 현재 버전의 스캔이 완료될 때까지 409 scan_pending을 반환하고, 스캔이 fail 또는 unknown으로 완료되었거나 오류가 발생한 경우 400 scan_failed를 반환합니다(warn은 허용됩니다). 고정된 플러그인은 현재 여기서든 claude.ai에서든 고정을 해제할 수 없습니다.
롤백하려면 served_version_id를 이전 버전으로 설정하세요. 롤포워드도 같은 방식으로 합니다.
이 규칙은 조직 소유 플러그인에 대한 설명입니다. 멤버 소유 플러그인의 제공 버전은 claude.ai에서 소유자가 제어합니다.
설치 설정
"Installation settings"(설치 설정)는 조직 소유 플러그인을 사용할 수 있는 사람을 결정합니다. 각 설정은 installation_preference라는 필드(그리고 플러그인 및 마켓플레이스 객체에서는 organization_installation_preference 및 default_installation_preference)에 담긴 네 가지 값 중 하나를 가집니다:
| 값 | 멤버에게 표시되는 내용 |
|---|---|
required | 플러그인이 설치되며 제거할 수 없습니다. |
auto_install | 플러그인이 설치되며 제거할 수 있습니다. |
available | 요청 시 플러그인을 설치할 수 있습니다. |
not_available | 플러그인이 숨겨집니다. |
플러그인은 조직 전체 설정 하나와 그룹별 설정 하나씩(사용자 관리에서 관리되는 역할 기반 액세스 제어 그룹)을 가질 수 있습니다. 멤버는 다음 규칙에 따라 값을 받습니다:
- 조직 전체 값은 플러그인 자체의 조직 전체 설정이 있으면 그 값이고, 없으면 마켓플레이스의 기본값이며, 그것도 없으면
not_available입니다. 플러그인은 이 값을organization_installation_preference에 보고하며, 값이 마켓플레이스 기본값에서 오는 동안에는organization_installation_preference_inherited: true를 함께 보고합니다. - 플러그인에 대한 설정을 가진 그룹에 속하지 않은 멤버는 조직 전체 값을 받습니다.
- 설정을 가진 그룹에 하나 이상 속한 멤버는 대신 해당 그룹 설정 중 가장 허용적인 값을 받으며, 순위는
required,auto_install,available,not_available순입니다.
그룹의 설정은 해당 그룹 멤버에 대해 조직 전체 값을 대체하며, 조직 전체 값에 추가되는 것이 아닙니다. 예를 들어 조직 전체 값이 required이고 Pilot 그룹이 available을 가지고 있으면 Pilot 멤버는 available을 받습니다. 플러그인을 파일럿 그룹에서 조직 전체로 옮길 때는 조직 전체 값을 설정한 다음 그룹의 설정을 제거하세요(조직 전체 값을 설정하면 설치 설정 지정에서 설명하듯이 플러그인이 마켓플레이스 기본값을 상속하는 것이 영구적으로 중단됩니다).
이 API를 통해 생성된 플러그인은 자체 설정 없이 시작하므로 마켓플레이스의 기본값을 상속합니다. 누군가 기본값을 설정하지 않았다면 이 값은 not_available입니다. 그룹을 삭제하면 모든 플러그인에서 해당 그룹의 설정이 제거됩니다.
공유
"Shares"(공유)는 멤버 소유 플러그인을 사용할 수 있는 사람을 결정합니다. 소유자는 claude.ai에서 모든 멤버, 그룹 또는 지정된 멤버와 플러그인을 공유합니다. 이 API는 공유를 나열할 수 있지만 변경할 수는 없습니다.
조직이 claude.ai 설정에서 특정 종류의 공유를 꺼 둔 경우, 해당 종류의 공유는 목록에 계속 나타나지만 그 설정이 꺼져 있는 동안에는 누구에게도 액세스 권한을 부여하지 않습니다. 목록 자체에는 해당 설정이 꺼져 있는지 여부가 표시되지 않습니다.
콘텐츠 스캔
콘텐츠 스캔은 claude.ai의 조직 설정입니다. 이 설정이 켜져 있으면 새로 저장된 버전이 스캔되고(claude.ai는 일부를 예외로 둡니다) 결과가 content_scan에 보고됩니다. 스캔되지 않은 버전(예: 스캔이 켜지기 전에 저장된 버전)은 content_scan: null을 가집니다. 고객 관리형 암호화 키 또는 "zero data retention"(데이터 무보존)을 사용하는 조직에는 스캔이 제공되지 않습니다.
스캔이 켜져 있는 동안 멤버는 제공 버전의 스캔이 pass 또는 warn으로 completed된 경우에만 플러그인을 제공받습니다. 스캔이 실행되는 동안, 또는 스캔이 실패하거나 오류가 발생하거나 판정에 도달하지 못한 후에는 플러그인이 멤버에게 제공되지 않으며, 그 대신 이전 버전이 제공되지도 않습니다. 스캔된 적이 없는 버전(content_scan: null)은 정상적으로 제공됩니다.
고정되지 않은 플러그인에서는 각 업로드가 즉시 제공 버전이 됩니다. 멤버는 새 버전의 스캔이 통과할 때까지 플러그인을 사용할 수 없으며, 스캔이 실패하면 계속 사용할 수 없습니다. 새 버전이 스캔되는 동안 멤버가 현재 버전을 계속 사용해야 한다면 먼저 플러그인을 고정하세요(버전과 제공 버전 참조).
업로드 후 content_scan.status는 processing이며 판정은 비동기적으로 도착합니다. 판정을 확인하려면 버전을 읽으세요. 플러그인 객체는 제공 버전의 스캔만 표시합니다. 스캔이 아직 실행 중인 버전으로 제공 버전을 변경하면 409 scan_pending을 반환하고, 스캔이 실패한 버전으로 변경하면 400 scan_failed를 반환합니다.
도달 범위
reach는 버전이 멤버의 컴퓨터와 그 너머에 얼마나 멀리 도달하는지를 하나의 값으로 요약합니다:
| 값 | 의미 |
|---|---|
remote | 다른 무엇을 선언하든 관계없이 MCP 서버 또는 CLI를 선언합니다. |
privileged | MCP 서버나 CLI는 선언하지 않지만, 훅, 모니터(세션 동안 계속 실행되는 백그라운드 명령), LSP(Language Server Protocol) 서버, 또는 플러그인이 멤버의 앱에 적용하는 설정을 선언하거나, 자체적으로 도구를 사전 승인하는 스킬 또는 명령(프런트매터의 allowed-tools)을 포함합니다. 이러한 항목은 멤버 자신의 컴퓨터에서 실행되거나 적용됩니다. |
contained | MCP 서버, CLI, 훅, 모니터, LSP 서버, 앱 설정을 선언하지 않으며, 스킬이나 명령 중 어느 것도 도구를 사전 승인하지 않습니다(예: allowed-tools가 없는 스킬, 명령, 에이전트만 포함하는 플러그인). |
reach는 components에 나열되지 않는 모니터, LSP 서버, 앱 설정을 포함하여 버전이 선언하는 모든 것을 고려하므로, components 목록이 비어 있는 버전도 privileged일 수 있습니다. 구성 요소가 기록되기 전에 저장된 버전, 그리고 스킬 또는 명령 파일 중 하나를 읽을 수 없어 도달 범위를 판단할 수 없는 버전의 경우 null입니다. null은 분류되지 않은 것으로 취급하세요.
업로드 요구 사항
업로드는 claude.ai의 플러그인 업로드와 동일한 규칙을 따르므로, 두 곳에서 동일한 아카이브가 허용됩니다.
- 업로드는 하나의
.zip또는.plugin아카이브이거나 개별 파일 집합입니다. 아카이브는 모든 내용을 하나의 최상위 폴더로 감쌀 수 있습니다. - 정확히 하나의 매니페스트가
.claude-plugin/plugin.json에 있어야 하며, 매니페스트는name을 선언해야 합니다. 매니페스트 없이SKILL.md만 있으면 거부됩니다. - 프런트매터에서 플러그인 구성 요소를 선언하는 최상위
SKILL.md는 매니페스트에 병합됩니다. 둘 다 값을 설정하는 경우plugin.json이 우선합니다. name에는 소문자(모든 문자 체계), 숫자, 하이픈을 최대 64자까지 사용할 수 있습니다. 대문자, 공백, 밑줄 및 기타 구두점은 거부됩니다.displayName은 최대 64자,description은 최대 500자입니다.- 모든
SKILL.md에는name과description이 있는 유효한 YAML 프런트매터가 필요하며, 둘 다<example>과 같은 XML 태그를 포함할 수 없습니다. 두 스킬 또는 두 명령은 같은 이름을 가질 수 없습니다. - 최상위
bin/디렉터리 아래에는 파일이 있을 수 없습니다. - 중첩된
.zip파일은 허용되지 않습니다. 패키징된 MCP 서버(.mcpb,.dxt)는 허용됩니다. - 파일 경로는 상대 경로여야 하고,
..를 포함하지 않아야 하며, 문자, 숫자, 공백 및_ . - / ( ) ,만 사용해야 합니다. - 요청 본문과 압축 해제된 아카이브는 각각 최대 200MB입니다. 한도를 초과하는 요청 본문은
400이 아닌413(request_too_large)을 반환합니다. 업로드는 최대 5,000개 파일, 경로 깊이 12, 경로 길이 472자, 파일 또는 폴더 이름 255자로 제한됩니다. - ZIP 아카이브는 DEFLATE 또는 STORE 압축을 사용해야 하며, 암호화되거나 심볼릭 링크를 포함할 수 없습니다.
- 마켓플레이스는 플러그인과 멤버가 보관하는 독립형 스킬을 합쳐 최대 500개 항목을 보유할 수 있습니다. 이 한도와 5,000개 파일 한도는 현재 값이며 상향될 수 있습니다.
예제 워크플로
릴리스 파이프라인에서 각 빌드 게시
CI에서 태그가 지정된 모든 빌드를 업로드하고, 빌드가 제공되는 시점을 파이프라인이 결정하도록 합니다.
GET /v1/organizations/plugin_marketplaces?owner_type=organization으로 업로드할 마켓플레이스를 찾거나,marketplace_id를 생략하여 라이브러리 마켓플레이스를 사용하세요.- 첫 번째 릴리스에서는
POST /v1/organizations/plugins로 플러그인을 생성하세요. 이후 모든 릴리스에서는 플러그인의latest_version_id를 기록한 다음POST /v1/organizations/plugins/{plugin_id}/versions로 버전을 업로드하세요. 업로드 응답이 유실되면 플러그인을 읽고latest_version_id가 변경되지 않은 경우에만 재시도하세요(업로드 재시도 참조). - 각 새 빌드를 확인하는 동안 멤버가 현재 버전을 계속 사용하도록 하려면
served_version_id를 현재 버전으로 설정하여 플러그인을 한 번 고정하세요. 그 이후로 각 업로드는 제공되지 않은 채 저장되며, 고정은 취소할 수 없습니다. 제공하려는 모든 빌드에는 5단계가 필요합니다. - 콘텐츠 스캔이 켜져 있으면
content_scan.status가 더 이상processing이 아닐 때까지GET /v1/organizations/plugins/{plugin_id}/versions/{version}을 폴링하고,pass또는warn으로completed된 경우에만 승격하세요. POST /v1/organizations/plugins/{plugin_id}와{"served_version_id": "<the new version's ID>"}로 빌드를 승격하세요. 롤백하려면 같은 방식으로 이전 버전의 ID를 보내세요.
파일럿 그룹에 플러그인을 배포한 다음 모든 사람에게 배포
-
GET /v1/organizations/rbac_groups로 파일럿 그룹의 ID를 조회하세요. 이 호출에는read:rbac_groups범위가 필요하며, 이 범위를 사용하려면 연결된 모든 조직에 대해 생성된 키가 필요합니다(사용자 관리 참조). 다음 단계에는 키가 생성된 조직에서만 작동하는write:plugins가 필요하므로, 연결된 조직이 여러 개인 엔터프라이즈에서는 플러그인을 보유한 조직에서 이 키를 생성하고 두 범위를 모두 부여하거나, 해당 단계에는 그 조직에서 생성한 두 번째 키를 사용하세요. -
POST /v1/organizations/plugins/{plugin_id}/installation_settings/{target}으로 그룹에 자체 설정을 부여하세요(예:auto_install). 여기서{target}은 그룹의rbac_group_ID이며, 조직 전체 값은not_available로 유지됩니다. 그룹 멤버만 플러그인을 받습니다. -
파일럿이 끝나면 조직 전체 값을 설정한 다음(이렇게 하면 설치 설정 지정에서 설명하듯이 플러그인이 마켓플레이스 기본값을 상속하는 것이 영구적으로 중단됩니다), 그룹이 다시 조직 설정을 따르도록 그룹의 설정을 제거하세요:
client = anthropic.Anthropic() setting = client.beta.organization.plugins.installation_settings.set( "organization", plugin_id="plugin_01Hq3vX8kZcN2mB7pR4tY9wL", installation_preference="required", ) print(f"plugin_id: {setting.plugin_id}") print(f"installation_preference: {setting.installation_preference}")그런 다음
DELETE /v1/organizations/plugins/{plugin_id}/installation_settings/{target}으로 그룹의 설정을 제거하세요. 여기서{target}은 그룹의 ID입니다. 그룹의 설정은 해당 멤버에 대해 조직 전체 값에 추가되는 것이 아니라 조직 전체 값을 대체하므로,available인 그룹 설정이 남아 있으면 해당 멤버는 계속available을 받게 됩니다.
보안 인벤토리 동기화 유지
멤버의 세션 외부로 도달하거나 콘텐츠 스캔에 실패한 플러그인을 표시하는 야간 작업을 실행하세요.
next_page가null이 될 때까지GET /v1/organizations/plugins?limit=100을 페이지 단위로 조회하세요. 이 목록에서는 일찍 중단될 수 있는 SDK 목록 반복자를 사용하는 대신, 각 페이지의next_page를 직접page로 전달하세요(페이지네이션 참조). 매 실행마다 해당 목록에서 각 플러그인의reach와content_scan을 읽으세요. 나중에 도착하는 스캔 판정은updated_at을 변경하지 않습니다.updated_at은 마지막 실행 이후 새 콘텐츠나 새 제공 버전이 있는 플러그인을 알려 줍니다(아카이브를 새로 다운로드할 가치가 있습니다). 전체 목록을 다시 조회하는 것은 제거된 플러그인을 포착하는 수단이기도 합니다. Git 동기화나 계정 삭제로 제거된 플러그인은 이벤트 없이 사라지기 때문입니다.reach가remote인(MCP 서버 또는 CLI를 선언하는) 플러그인, 또는content_scan.assessment가fail또는unknown인 플러그인을 표시하세요.- 표시된 각 플러그인에 대해
GET /v1/organizations/plugins/{plugin_id}/versions/{served_version_id}/content로 검토용 제공 버전 아카이브를 다운로드하세요(버전 파일 다운로드 참조). - 검토하는 동안 멤버가 플러그인을 사용하지 못하게 하려면, 되돌릴 수 있는 옵션(조직 소유)과 영구적인 옵션에 대해 플러그인 삭제를 참조하세요.
플러그인
플러그인 객체는 조직의 마켓플레이스 중 하나 또는 멤버의 개인 마켓플레이스에 있는 플러그인을 설명합니다(빠른 시작 응답에 전체 객체가 나와 있습니다). 객체의 display_name, description, manifest_version, content_scan, components, reach는 제공 버전을 설명하므로, 한 번의 목록 호출로 멤버에게 무엇이 제공되고 있는지 확인할 수 있습니다.
| 필드 | 설명 |
|---|---|
id | plugin_ 접두사가 붙습니다. |
name | 매니페스트에서 가져옵니다. 조직 전체가 아니라 마켓플레이스 내에서 고유합니다. 조직 소유 플러그인의 경우 고정되며, 멤버가 claude.ai에서 자신의 플러그인 이름을 변경하면 바뀝니다. |
display_name, description, manifest_version | 제공 버전의 매니페스트 displayName, description, version입니다. 매니페스트에 선언되지 않은 경우 각각 null입니다. manifest_version은 표시용으로 정규화됩니다. 앞에 붙은 v 또는 V 하나가 제거되므로, 매니페스트 version이 "v1.4.0"이면 "1.4.0"으로 반환됩니다. 또한 "latest"처럼 버전 번호로 보이지 않는 값, 그리고 claude.ai가 2026년 8월에 이 필드를 기록하기 시작하기 전에 생성된 플러그인 버전의 경우에도 null입니다. 업로드는 version 때문에 거부되지 않으며, manifest_version은 고유하지 않습니다. |
served_version_id, latest_version_id | pluginver_ 접두사가 붙습니다. 각각 멤버에게 제공되는 버전과 최신 버전입니다. 버전과 제공 버전을 참조하세요. |
served_version_pinned | 제공 버전이 각 새 버전을 따르는 동안에는 false이고, 버전이 명시적으로 선택되면 true입니다. |
owner | {"type": "organization"}, 또는 멤버의 개인 마켓플레이스의 경우 {"type": "user", "user_id": "user_..."}입니다. |
marketplace_id | marketplace_ 접두사가 붙습니다. |
created_by | 플러그인을 생성한 주체입니다. claude.ai의 사람인 경우 {"type": "user_actor", "user_id": "user_...", "email_address": "..."}(email_address는 null일 수 있음), API 키인 경우 {"type": "api_actor", "api_key_id": "apikey_..."}입니다. 다른 행위자 유형이 나타날 수도 있습니다. Git에서 동기화된 플러그인처럼 생성자가 기록되지 않은 경우 null입니다. |
organization_installation_preference, organization_installation_preference_inherited | 조직 소유: 조직 전체 값과, 그 값이 마켓플레이스의 기본값에서 오는지 여부입니다(설치 설정 참조). 멤버 소유: 둘 다 null입니다. |
content_scan | 제공 버전의 스캔 결과로, status, assessment, reason을 가진 객체입니다(이 표 다음에 설명). 스캔된 적이 없으면 null입니다. |
components | 제공 버전의 구성 요소로, 각각 {"type", "name", "description"} 형식이며 type은 skill, mcp_server, command, agent, hook, cli 중 하나입니다. 이 유형 순서대로 나열된 다음 이름순으로 나열됩니다. MCP 서버의 경우 name은 매니페스트의 키이고, 훅의 경우 훅이 실행되는 이벤트이며, CLI의 경우 실행 파일의 이름입니다. MCP 서버, 훅, CLI의 description은 항상 null입니다. 기록되지 않은 경우 null입니다. |
reach | contained, privileged, remote 중 하나입니다. 도달 범위를 참조하세요. |
updated_at | 새 버전이 저장되거나 제공 버전이 변경될 때만 바뀝니다. 설치 설정, 공유, 새 스캔 결과에 대해서는 바뀌지 않습니다. |
content_scan 객체:
| 필드 | 설명 |
|---|---|
status | 스캔이 실행되는 동안에는 processing, 완료되면 completed, 완료할 수 없으면 errored입니다(또는 드물게 이 응답에서 결과를 읽을 수 없는 경우에도 errored이며, 이 경우 나중에 읽으면 결과가 보고될 수 있습니다). 스캔이 processing 또는 errored인 버전은 멤버에게 제공되지 않습니다. 콘텐츠를 새 버전으로 다시 업로드하면 새로 스캔됩니다. |
assessment | status가 completed일 때 설정됩니다: pass(발견된 항목 없음), warn(사용을 차단하지 않는 항목 발견), fail(사용을 차단하는 항목 발견), unknown(판정 없음). 그 외에는 null입니다. |
reason | warn 및 fail의 경우 다음 목록에 있는 주요 우려 사항입니다. 그 외에는 null이며, 사유 기록 기능 이전의 오래된 스캔에서도 null입니다. |
reason | 의미 |
|---|---|
covert-usage-telemetry | 멤버에게 알리지 않고 멤버 또는 멤버의 사용에 관한 정보를 외부 주소로 보내도록 Claude에 지시합니다. |
undisclosed-data-destination | 파일, 이메일, 문서 또는 기타 콘텐츠를 멤버에게 표시되지 않고 멤버가 제어하지 않는 고정된 외부 대상으로 보냅니다. |
remote-code-instruction-loader | 플러그인 설치 후 변경될 수 있는 외부 콘텐츠를 다운로드하여 실행하거나 그 지침을 따르도록 Claude에 지시합니다. |
credential-exposure | 실제 자격 증명을 포함하거나, 멤버의 환경에서 자격 증명 또는 토큰을 수집합니다. |
guardrail-tampering | 예를 들어 모든 권한 프롬프트를 사전 승인하는 방식으로 멤버의 보호 장치를 약화시킵니다. |
system-prompt-spoofing | Claude의 시스템 지침을 모방하거나 대체하려고 시도합니다. |
covert-record-tampering | 멤버가 원래 보게 될 정보를 몰래 변경하거나, 숨기거나, 삭제합니다. |
covert-behavior-override | 플러그인의 목적을 넘어 Claude의 동작을 변경하고 그 변경을 멤버에게 숨깁니다. |
hidden-code-execution | 번들된 코드를 실행하면서 그 코드가 하는 일을 밝히지 말라고 Claude에 지시합니다. |
undisclosed-promotion-injection | 공개되지 않은 홍보 콘텐츠를 Claude의 출력에 삽입합니다. |
hidden-identity-gate | 이유를 밝히지 않고 어떤 계정이 실행하는지에 따라 동작을 변경하거나 중단합니다. |
destructive-persistence | 멤버의 파일을 삭제하거나 손상시킬 수 있으며, 플러그인이 제거된 후에도 남는 프로그램을 설치할 수 있습니다. |
unanalyzable-binary | 컴파일되었거나 읽을 수 없는 프로그램을 포함하고 있어 스캔이 그 동작을 확인할 수 없습니다. |
other | 이 목록보다 새로운 우려 사항을 포함한 기타 모든 우려 사항입니다. |
plugin_ 접두사가 없는 plugin_id는 400을 반환합니다. 접두사가 있지만 확인되지 않거나, 다른 조직에 속하거나, 독립형 스킬을 가리키는 plugin_id는 404를 반환합니다.
플러그인 나열
GET /v1/organizations/plugins는 조직의 마켓플레이스와 멤버의 개인 마켓플레이스에 있는 조직의 모든 플러그인을 created_at 내림차순으로 나열합니다. owner_type(organization 또는 user), owner_user_id(user_ 접두사가 붙으며, 멤버가 조직을 떠난 후를 포함한 해당 멤버의 플러그인), marketplace_id, 그리고 created_at[gte], created_at[gt], created_at[lte], created_at[lt](RFC 3339 타임스탬프)로 필터링할 수 있습니다. 필터는 AND로 결합됩니다. 조직에서 일치하는 항목이 없는 marketplace_id 또는 owner_user_id는 오류가 아닌 빈 페이지를 반환합니다. 응답은 빠른 시작에 표시된 형식입니다. read:plugins 범위가 필요합니다.
client = anthropic.Anthropic()
plugins = client.beta.organization.plugins.list(owner_type="organization", limit=20)
# 필요에 따라 추가 페이지를 자동으로 가져옵니다.
for plugin in plugins:
print(f"{plugin.id}: {plugin.name}")플러그인 생성
POST /v1/organizations/plugins는 조직 소유 플러그인과 그 첫 번째 버전을 한 번의 호출로 생성하며, 이 버전이 "served version"(제공 버전)이 됩니다. 본문은 multipart/form-data입니다. files[]는 하나의 .zip 또는 .plugin 아카이브이거나, 파일당 하나의 파트로 구성됩니다. 후자의 경우 각 파트의 파일 이름은 플러그인 내 해당 파일의 경로입니다(예: .claude-plugin/plugin.json). 선택적 필드는 marketplace_id(조직 소유의 manual 마켓플레이스이며, 기본값은 처음 사용할 때 생성되는 라이브러리 마켓플레이스입니다)와 release_notes(최대 5,000자이며, claude.ai의 버전 기록에 표시되고 버전에 반환됩니다)입니다. 플러그인의 name, display_name, description, manifest_version은 업로드된 매니페스트에서 가져오며, 업로드는 업로드 요구 사항을 충족해야 합니다. 콘텐츠 스캔이 켜져 있으면 응답의 content_scan.status는 processing이며, 판정 결과는 비동기적으로 도착합니다. 플러그인을 반환합니다. write:plugins 스코프가 필요합니다.
아카이브 업로드:
client = anthropic.Anthropic()
with open("dist/sales-toolkit.zip", "rb") as archive:
plugin = client.beta.organization.plugins.create(
files=[archive],
release_notes="First release",
)
print(f"id: {plugin.id}")
print(f"served_version_id: {plugin.served_version_id}"){
"type": "plugin",
"id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
"name": "sales-toolkit",
"display_name": "Sales Toolkit",
"description": "Account research and call prep for the sales team.",
"served_version_id": "pluginver_01Km7tL4pR9xF5sU2zV3jP6q",
"served_version_pinned": false,
"latest_version_id": "pluginver_01Km7tL4pR9xF5sU2zV3jP6q",
"manifest_version": "1.4.0",
"owner": { "type": "organization" },
"marketplace_id": "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
"created_by": { "type": "api_actor", "api_key_id": "apikey_01Nq9vN6rT2zH7uW4bX5mR8s" },
"organization_installation_preference": "available",
"organization_installation_preference_inherited": true,
"content_scan": { "status": "processing", "assessment": null, "reason": null },
"components": [
{
"type": "skill",
"name": "account-research",
"description": "Researches a customer account before a call."
},
{ "type": "mcp_server", "name": "crm", "description": null }
],
"reach": "remote",
"created_at": "2026-09-01T17:04:11Z",
"updated_at": "2026-09-01T17:04:11Z"
}개별 파일을 지정한 마켓플레이스에 업로드합니다. 각 파일은 플러그인 내 경로로 첨부하세요(cURL 예제의 ;filename= 접미사, SDK 예제의 파일 이름 인수). 기본 이름만으로 전송된 파일이 있으면 매니페스트를 찾을 수 없게 됩니다. TypeScript 및 Java SDK와 ant CLI는 아직 경로를 지정하여 파일을 첨부할 수 없으므로, 해당 예제에서는 대신 플러그인을 하나의 아카이브로 마켓플레이스에 업로드합니다:
client = anthropic.Anthropic()
# (filename, file) 튜플을 사용하면 플러그인 내 각 파일의 경로가 유지됩니다.
# 파일 객체만 전달하면 기본 이름(base name)으로만 전송됩니다.
with (
open(".claude-plugin/plugin.json", "rb") as manifest,
open("skills/account-research/SKILL.md", "rb") as skill_md,
):
plugin = client.beta.organization.plugins.create(
files=[
(".claude-plugin/plugin.json", manifest),
("skills/account-research/SKILL.md", skill_md),
],
marketplace_id="marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
)
print(f"id: {plugin.id}")
print(f"served_version_id: {plugin.served_version_id}")업로드 요구 사항을 위반하는 업로드에 대한 400(요청 본문이 200 MB를 초과하는 경우 413)과 공통 응답(marketplace_id가 멤버의 개인 마켓플레이스인 경우 403. 오류 응답 참조) 외에도, 생성 요청은 다음과 같은 이유로 실패할 수 있습니다:
| 상태 | 원인 | 조치 방법 |
|---|---|---|
| 404 | marketplace_id가 조직의 마켓플레이스가 아닙니다. | 마켓플레이스 목록 조회에서 ID를 가져오세요. |
| 400 | 마켓플레이스가 Git에서 동기화되거나, 이미 500개의 플러그인과 스킬을 보유하고 있습니다. | manual 마켓플레이스에 업로드하거나, 대신 리포지토리를 변경하세요. |
409 plugin_name_taken | 해당 마켓플레이스에서 이미 사용 중인 이름입니다. | details.plugin_id로 계속 진행하거나(해당 플러그인에 버전 업로드), 매니페스트의 name을 변경하세요. |
409 skill_name_taken | 플러그인이 라이브러리 마켓플레이스에 추가되는데, 그 스킬 중 하나가 조직 스킬과 같은 이름을 가지고 있습니다. | 스킬 이름을 변경하거나, claude.ai에서 조직 스킬을 제거하세요. |
409 (error_code 없음) | 같은 마켓플레이스에 같은 이름으로 진행 중인 다른 업로드가 있습니다. | 잠시 후 다시 시도하세요. |
503 registration_pending | 플러그인은 생성되었지만 등록이 완료되지 않았습니다. | 다시 전송하지 말고, 같은 파일을 details.plugin_id의 버전으로 업로드하세요(업로드 재시도 참조). |
플러그인 조회
GET /v1/organizations/plugins/{plugin_id}는 하나의 플러그인을 반환합니다. read:plugins 스코프가 필요합니다.
client = anthropic.Anthropic()
plugin = client.beta.organization.plugins.retrieve("plugin_01Hq3vX8kZcN2mB7pR4tY9wL")
print(f"id: {plugin.id}")
print(f"name: {plugin.name}")제공 버전 변경
POST /v1/organizations/plugins/{plugin_id}는 조직 소유 플러그인에서 멤버에게 제공되는 버전을 변경합니다. 롤백하려면 이전 버전을 전달하고, 제공되지 않은 채 저장된 빌드를 승격하려면 더 새로운 버전을 전달하세요. 이 작업은 플러그인을 "pin"(고정)하며, 고정된 플러그인은 현재 여기서든 claude.ai에서든 고정을 해제할 수 없습니다(버전과 제공 버전 참조). 업데이트할 수 있는 유일한 필드는 served_version_id이며, 필수입니다. 변경 사항은 응답이 반환되기 전에 멤버에게 반영되며, 새 버전을 생성하지 않습니다. 콘텐츠 스캔이 켜져 있으면 해당 버전은 멤버에게 제공될 수 있는 버전이어야 합니다(콘텐츠 스캔 참조). 고정된 플러그인에 이미 제공 중인 버전을 전달하면 아무것도 변경되지 않습니다. 고정되지 않은 플러그인에 이를 전달하면 해당 버전으로 고정되므로, 이후 업로드는 더 이상 자동으로 제공되지 않습니다. 플러그인을 반환합니다. write:plugins 스코프가 필요합니다.
client = anthropic.Anthropic()
plugin = client.beta.organization.plugins.update(
"plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
served_version_id="pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p",
)
print(f"id: {plugin.id}")
print(f"served_version_id: {plugin.served_version_id}"){
"type": "plugin",
"id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
"name": "sales-toolkit",
"display_name": "Sales Toolkit",
"description": "Account research and call prep for the sales team.",
"served_version_id": "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p",
"served_version_pinned": true,
"latest_version_id": "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p",
"manifest_version": "1.5.0",
"owner": { "type": "organization" },
"marketplace_id": "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
"created_by": { "type": "api_actor", "api_key_id": "apikey_01Nq9vN6rT2zH7uW4bX5mR8s" },
"organization_installation_preference": "available",
"organization_installation_preference_inherited": true,
"content_scan": { "status": "completed", "assessment": "pass", "reason": null },
"components": [
{
"type": "skill",
"name": "account-research",
"description": "Researches a customer account before a call."
},
{ "type": "mcp_server", "name": "crm", "description": null },
{
"type": "command",
"name": "call-prep",
"description": "Builds a one-page brief for an upcoming call."
}
],
"reach": "remote",
"created_at": "2026-09-01T17:04:11Z",
"updated_at": "2026-09-16T10:02:45Z"
}공통 응답(멤버 소유 플러그인에 대한 403, 멤버에게 제공될 수 없는 버전에 대한 409 scan_pending 또는 400 scan_failed. 오류 응답 참조) 외에도, 요청은 다음과 같은 이유로 실패할 수 있습니다:
| 상태 | 원인 | 조치 방법 |
|---|---|---|
| 400 | 본문에 served_version_id가 없거나, null로 설정되었거나, 다른 필드가 포함되어 있습니다. 또는 값에 pluginver_ 접두사가 없거나 값이 latest입니다. | 정확히 {"served_version_id": "pluginver_…"}를 전송하세요. |
| 404 | served_version_id가 이 플러그인의 버전이 아닙니다. | 플러그인 버전 목록 조회에서 ID를 가져오세요. |
409 (error_code 없음) | 이 플러그인에 대한 업로드 또는 다른 제공 버전 변경이 아직 진행 중입니다. | 잠시 후 다시 시도하세요. |
409 skill_name_taken | 플러그인이 라이브러리 마켓플레이스에 있고, 해당 버전에 현재 조직 스킬이 사용 중인 이름의 스킬이 있습니다. | 다른 버전을 선택하거나, 스킬 중 하나의 이름을 변경하세요. |
플러그인 삭제
DELETE /v1/organizations/plugins/{plugin_id}는 claude.ai에서 관리자가 삭제하는 것과 마찬가지로 플러그인과 그 플러그인이 보유한 모든 버전을 영구적으로 삭제합니다. 이 작업은 manual 마켓플레이스에 있는 모든 플러그인에 적용되며, 멤버의 플러그인도 포함됩니다. 해당 멤버가 이후 조직을 떠났더라도 마찬가지입니다. 삭제가 반환되면 플러그인, 그 버전 및 파일은 모든 읽기 작업에서 사라지며, 더 이상 멤버에게 제공되지 않습니다. 조직 소유 플러그인의 설치 설정은 플러그인과 함께 제거됩니다. 멤버 소유 플러그인의 공유는 철회되며, 소유자에게서도 사라집니다. Git에서 동기화되는 마켓플레이스에 있는 플러그인은 400을 반환합니다. 리포지토리에서 제거하거나, claude.ai에서 마켓플레이스를 제거하세요. write:plugins 스코프가 필요합니다.
삭제는 되돌릴 수 없으며, 버전별 삭제는 없습니다. 대신 조직 소유 플러그인을 되돌릴 수 있는 방식으로 보류하려면, 조직 전체 설치 설정을 not_available로 설정하고(마켓플레이스의 기본값을 상속하던 플러그인은 그때부터 자체 설정을 유지합니다), GET /v1/organizations/plugins/{plugin_id}/installation_settings가 나열하는 모든 그룹 설정을 제거(또는 not_available로 설정)하세요. 그룹의 설정은 해당 그룹 멤버에 대해 조직 전체 값보다 우선하기 때문입니다. 이러한 쓰기 요청은 병렬이 아니라 하나씩 순서대로 전송하세요(설치 설정 지정 참조). 멤버 소유 플러그인은 삭제하는 방법 외에는 이 API를 통해 보류할 수 없으며, 삭제도 해당 마켓플레이스가 manual인 경우에만 가능합니다.
client = anthropic.Anthropic()
deleted_plugin = client.beta.organization.plugins.delete(
"plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
)
print(f"id: {deleted_plugin.id}"){ "type": "plugin_deleted", "id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL" }플러그인 버전
플러그인 버전은 한 번의 업로드로 생성된 플러그인 파일의 변경 불가능한 스냅샷입니다(버전 생성 응답에서 전체 객체를 확인할 수 있습니다). 버전의 필드는 이 버전에 대한 플러그인의 제공 버전 필드(display_name, description, manifest_version, content_scan, components, reach)를 그대로 반영하며, 여기에 release_notes(업로드 시 제공된 내용이며, claude.ai의 버전 기록에 표시됨)와 created_by(업로드한 사람)가 추가됩니다.
pluginver_ 접두사가 없는 {version}은 400을 반환합니다(명시된 경우의 리터럴 latest는 예외). 접두사가 있지만 해당 플러그인의 버전을 식별하지 못하는 값은 404를 반환합니다.
플러그인 버전 목록 조회
GET /v1/organizations/plugins/{plugin_id}/versions는 플러그인의 버전을 created_at 내림차순으로 나열합니다. 첫 번째 항목은 latest_version_id가 식별하는 버전입니다. limit은 1에서 1,000 사이입니다. read:plugins 스코프가 필요합니다.
client = anthropic.Anthropic()
versions = client.beta.organization.plugins.versions.list(
"plugin_01Hq3vX8kZcN2mB7pR4tY9wL", limit=50
)
# 필요에 따라 추가 페이지를 자동으로 가져옵니다.
for version in versions:
print(f"{version.id}: {version.manifest_version}")버전 생성
POST /v1/organizations/plugins/{plugin_id}/versions는 manual 마켓플레이스에 있는 조직 소유 플러그인에 버전을 추가합니다. 본문은 multipart/form-data이며, 플러그인 생성과 동일한 files[] 및 release_notes 필드, 업로드 요구 사항, 그리고 파일, 매니페스트, 아카이브, 크기 관련 오류가 적용됩니다. 업로드된 이름(매니페스트의 name)은 플러그인의 name과 같아야 합니다. 플러그인이 고정되어 있지 않으면 새 버전은 저장되는 즉시 제공됩니다. 고정되어 있으면 버전은 저장되지만, 제공 버전을 해당 버전으로 변경할 때까지 제공되지 않습니다. 확인하려면 응답의 id를 플러그인의 served_version_id와 비교하세요. 버전을 반환합니다. write:plugins 스코프가 필요합니다.
client = anthropic.Anthropic()
with open("dist/sales-toolkit.zip", "rb") as archive:
version = client.beta.organization.plugins.versions.create(
"plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
files=[archive],
release_notes="Adds the call-prep command.",
)
print(f"id: {version.id}")
print(f"manifest_version: {version.manifest_version}"){
"type": "plugin_version",
"id": "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p",
"plugin_id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
"display_name": "Sales Toolkit",
"description": "Account research and call prep for the sales team.",
"manifest_version": "1.5.0",
"release_notes": "Adds the call-prep command.",
"created_by": { "type": "api_actor", "api_key_id": "apikey_01Nq9vN6rT2zH7uW4bX5mR8s" },
"content_scan": { "status": "processing", "assessment": null, "reason": null },
"components": [
{
"type": "skill",
"name": "account-research",
"description": "Researches a customer account before a call."
},
{ "type": "mcp_server", "name": "crm", "description": null },
{
"type": "command",
"name": "call-prep",
"description": "Builds a one-page brief for an upcoming call."
}
],
"reach": "remote",
"created_at": "2026-09-15T14:12:30Z"
}업로드 요구 사항을 위반하는 업로드에 대한 400(요청 본문이 200 MB를 초과하는 경우 413)과 공통 응답(멤버 소유 플러그인에 대한 403. 오류 응답 참조) 외에도, 요청은 다음과 같은 이유로 실패할 수 있습니다:
| 상태 | 원인 | 조치 방법 |
|---|---|---|
| 400 | 플러그인이 Git에서 동기화되는 마켓플레이스에 있거나, 업로드된 이름이 플러그인의 이름과 다릅니다. | 대신 리포지토리를 변경하거나, 매니페스트의 name을 수정하세요. |
409 (error_code 없음) | 이 플러그인에 대한 다른 업로드 또는 제공 버전 변경이 아직 진행 중입니다. | 잠시 후 다시 시도하세요. |
409 skill_name_taken | 플러그인이 라이브러리 마켓플레이스에 있고, 해당 버전이 조직 스킬과 같은 이름의 스킬을 추가합니다. | 스킬 이름을 변경하거나, claude.ai에서 조직 스킬을 제거하세요. |
503 registration_pending | 버전은 저장되었지만 등록이 완료되지 않았습니다. | 응답에 x-should-retry: true가 포함되어 있으면 같은 요청을 다시 전송하세요(업로드 재시도 참조). |
버전 조회
GET /v1/organizations/plugins/{plugin_id}/versions/{version}은 하나의 버전을 반환합니다. {version}은 버전 ID이거나, 요청 시점에 latest_version_id가 식별하는 버전을 나타내는 latest입니다. read:plugins 스코프가 필요합니다.
client = anthropic.Anthropic()
version = client.beta.organization.plugins.versions.retrieve(
"latest",
plugin_id="plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
)
print(f"id: {version.id}")
print(f"manifest_version: {version.manifest_version}")버전 파일 다운로드
GET /v1/organizations/plugins/{plugin_id}/versions/{version}/content는 버전의 파일을 저장된 .zip 아카이브(Content-Type: application/zip)로 다운로드합니다. 아카이브는 콘텐츠 스캔 결과와 관계없이 반환되므로, 멤버에게 보류된 버전도 검사할 수 있습니다. 아카이브는 저장된 그대로 제공되므로, manual 마켓플레이스에 있는 조직 소유 플러그인의 경우 현재 업로드 요구 사항을 충족한다면 변경 없이 새 버전으로 다시 업로드할 수 있습니다. {version}은 latest가 아닌 버전 ID여야 합니다. 먼저 플러그인의 served_version_id 또는 latest_version_id를 읽거나, GET /v1/organizations/plugins/{plugin_id}/versions/latest로 latest를 확인하세요. Content-Disposition 파일 이름은 플러그인 이름에서 파생되며 고유하지 않으므로, 저장하는 파일의 이름은 플러그인 ID와 버전 ID를 기준으로 지정하세요. read:plugins 스코프가 필요합니다.
멤버 소유 플러그인의 아카이브를 다운로드하면 Compliance API Activity Feed에 claude_plugin_archive_accessed 이벤트가 기록되며, 이 이벤트는 키(api_actor로), 플러그인과 그 마켓플레이스, 버전, 소유 멤버를 ID로 식별합니다. 이름은 포함되지 않습니다. 조직 소유 플러그인의 아카이브를 다운로드하면 아무것도 기록되지 않습니다.
client = anthropic.Anthropic()
plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
version_id = "pluginver_01Km7tL4pR9xF5sU2zV3jP6q"
with client.beta.organization.plugins.versions.with_streaming_response.download(
version_id,
plugin_id=plugin_id,
) as response:
response.stream_to_file(f"{plugin_id}_{version_id}.zip")플러그인 설치 설정
이 엔드포인트는 조직 소유 플러그인에 적용됩니다. 멤버 소유 플러그인에 대해서는 404를 반환하며, 멤버 소유 플러그인에는 대신 공유가 있습니다. {target}은 플러그인의 조직 전체 설정을 나타내는 리터럴 organization이거나, 해당 그룹의 설정을 나타내는 그룹의 rbac_group_ ID입니다. 그 외의 값은 400을 반환합니다. 그룹 ID는 GET /v1/organizations/rbac_groups(스코프 read:rbac_groups. 사용자 관리 참조)에서 가져옵니다. 설정에는 자체 id가 없습니다. 설정은 (plugin_id, target)으로 지정되며, 설정에는 행위자가 기록되지 않습니다(행위자는 plugin_installation_preference_updated 활동 이벤트에 기록됩니다).
플러그인 설치 설정 목록 조회
GET /v1/organizations/plugins/{plugin_id}/installation_settings는 조직 소유 플러그인이 보유한 설정을 created_at 내림차순으로 나열합니다. 여기에는 플러그인 자체의 조직 전체 설정(마켓플레이스의 기본값을 상속하는 동안에는 없음)과 각 그룹의 설정이 포함됩니다. target_type(organization 또는 rbac_group)으로 필터링할 수 있습니다. read:plugins 스코프가 필요합니다.
client = anthropic.Anthropic()
settings = client.beta.organization.plugins.installation_settings.list(
"plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
)
# 필요에 따라 추가 페이지를 자동으로 가져옵니다.
for setting in settings:
print(f"{setting.plugin_id}: {setting.installation_preference}")설치 설정 지정
POST /v1/organizations/plugins/{plugin_id}/installation_settings/{target}은 조직 소유 플러그인에 대해 하나의 대상의 설치 설정을 지정하며, 설정을 새로 생성하거나 이미 보유한 값을 변경합니다. 본문의 유일한 필드는 installation_preference(required, auto_install, available 또는 not_available)이며, 필수입니다. 대상이 이미 보유한 값으로 설정하면 아무것도 변경되지 않습니다. organization 대상을 설정하면 값이 기본값과 같더라도 플러그인이 마켓플레이스의 기본값을 더 이상 상속하지 않습니다(organization_installation_preference_inherited가 false가 됨). 조직 전체 설정은 제거할 수 없으므로 이 작업은 되돌릴 수 없으며, 따라서 플러그인은 이후 마켓플레이스 기본값의 변경을 더 이상 따르지 않습니다. 그룹 대상은 조직이 GET /v1/organizations/rbac_groups에서 볼 수 있는 그룹이어야 하며, 그렇지 않으면 요청은 404를 반환합니다. 이 변경은 플러그인의 updated_at을 변경하지 않으며, Activity Feed에 기록됩니다. 설정을 반환합니다. write:plugins 스코프가 필요합니다.
플러그인의 설치 설정 쓰기 요청은 한 번에 하나씩 전송하세요. 같은 플러그인에 대한 여러 쓰기 요청이 동시에 도착하면, 서버는 이를 하나씩 순서대로 처리하며 일부 요청에는 적용하는 대신 503으로 응답할 수 있습니다. 이 503에는 x-should-retry: true가 포함되며, 해당 쓰기 요청은 반복해도 안전합니다. 1~2초 기다린 후 다시 전송하세요.
client = anthropic.Anthropic()
setting = client.beta.organization.plugins.installation_settings.set(
"rbac_group_01F3xQqQzXyWvUtSrQpOnMlK",
plugin_id="plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
installation_preference="available",
)
print(f"plugin_id: {setting.plugin_id}")
print(f"installation_preference: {setting.installation_preference}"){
"type": "plugin_installation_setting",
"plugin_id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
"target": { "type": "rbac_group", "rbac_group_id": "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK" },
"installation_preference": "available",
"created_at": "2026-09-02T10:00:00Z",
"updated_at": "2026-09-02T10:00:00Z"
}그룹 설치 설정 제거
DELETE /v1/organizations/plugins/{plugin_id}/installation_settings/{target}은 조직 소유 플러그인에 대한 하나의 그룹 설정을 제거합니다. 해당 그룹의 멤버에게는 조직 전체 값 또는 멤버가 속한 다른 그룹의 설정이 적용됩니다. claude.ai에서와 마찬가지로 조직 전체 설정은 한 번 지정되면 제거할 수 없으므로({target}이 organization이면 400 반환), 대신 값을 변경하세요. 이 플러그인에 대한 설정을 보유하지 않은 그룹은 404를 반환합니다. 응답에는 id 대신 복합 키가 포함됩니다. write:plugins 스코프가 필요합니다.
client = anthropic.Anthropic()
removed_setting = client.beta.organization.plugins.installation_settings.remove(
"rbac_group_01F3xQqQzXyWvUtSrQpOnMlK",
plugin_id="plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
)
print(f"plugin_id: {removed_setting.plugin_id}"){
"type": "plugin_installation_setting_deleted",
"plugin_id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
"target": { "type": "rbac_group", "rbac_group_id": "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK" }
}플러그인 공유
공유는 멤버 소유 플러그인에만 존재하며, 이 API에서는 읽기 전용입니다(공유 참조).
플러그인 공유 목록 조회
GET /v1/organizations/plugins/{plugin_id}/shares는 멤버 소유 플러그인의 소유자가 플러그인을 공유한 대상을 granted_at 내림차순으로 나열합니다. 대상은 모든 멤버(organization), 그룹(rbac_group) 또는 지정된 멤버(organization_member)입니다. target_type으로 필터링할 수 있습니다. 소유자가 공유하지 않은 플러그인은 빈 목록을 반환하며, 조직 소유 플러그인은 404를 반환합니다. 공유는 이 API에서 읽기 전용이며, 나열된 공유는 claude.ai에서 조직에 해당 유형의 공유가 켜져 있는 동안에만 액세스 권한을 부여합니다(공유 참조). granted_at은 공유가 부여된 시점이며, 소유자가 이후 claude.ai에서 공유를 변경한 경우에는 그 변경 시점입니다. read:plugins 스코프가 필요합니다.
client = anthropic.Anthropic()
shares = client.beta.organization.plugins.shares.list("plugin_01Mr2wP7sU3aJ8vX5cY6nS9t")
# 필요에 따라 추가 페이지를 자동으로 가져옵니다.
for share in shares:
print(f"plugin_id: {share.plugin_id}"){
"data": [
{
"type": "plugin_share",
"plugin_id": "plugin_01Mr2wP7sU3aJ8vX5cY6nS9t",
"target": { "type": "organization_member", "user_id": "user_01WCz9BvGLdMYRUMmcAxMWvW" },
"granted_at": "2026-08-20T15:12:00Z"
}
],
"next_page": null
}플러그인 마켓플레이스
이 API는 마켓플레이스를 읽고 조직 마켓플레이스의 기본 설치 설정을 지정합니다. 마켓플레이스 자체의 생성, 리포지토리 연결, 삭제는 claude.ai에서 이루어집니다.
{
"type": "plugin_marketplace",
"id": "marketplace_01VbNcMxZaSdFgHjKlQwErTy",
"name": "engineering-tools",
"owner": { "type": "organization" },
"source": "github",
"sync_status": "success",
"last_sync_ended_at": "2026-09-10T22:15:03Z",
"last_sync_read_sha": "9fceb02d0ae598e95dc970b74767f19372d61af8",
"default_installation_preference": "available",
"created_at": "2026-06-12T08:45:00Z"
}| 필드 | 설명 |
|---|---|
name | 마켓플레이스의 이름입니다. 마켓플레이스가 존재하는 동안 고정됩니다. |
owner | 플러그인의 경우와 같은 형태입니다. |
source | manual, github, gitlab 또는 public_git입니다. 마켓플레이스를 참조하세요. |
sync_status | 가장 최근 동기화의 결과입니다: success, in_progress, failed_content, failed_transient, failed_auth 또는 failed_limits. 동기화가 처음 시도되기 전까지는 null이며, 소스가 manual인 마켓플레이스에서는 동기화가 시도되지 않습니다. |
last_sync_ended_at | 결과와 관계없이 가장 최근 동기화 시도가 완료된 시점입니다. 아직 동기화되지 않은 연결된 리포지토리의 경우 마켓플레이스가 생성된 시점입니다. 동기화되지 않는 마켓플레이스의 경우 null입니다. |
last_sync_read_sha | 마지막 동기화가 리포지토리에서 읽은 커밋입니다. 제공 버전이 생성된 커밋과 반드시 같지는 않습니다. 동기화되지 않는 마켓플레이스의 경우 null입니다. |
default_installation_preference | 조직 마켓플레이스: 자체 설정이 없는 마켓플레이스 내 모든 플러그인에 대한 조직 전체 값입니다(설정된 적이 없으면 not_available). 개인 마켓플레이스: null. |
marketplace_ 접두사가 없는 marketplace_id는 400을 반환합니다. 접두사가 있지만 확인되지 않거나 다른 조직에 속한 값은 404를 반환합니다.
마켓플레이스 목록 조회
GET /v1/organizations/plugin_marketplaces는 조직의 마켓플레이스와 멤버의 개인 마켓플레이스를 created_at 내림차순으로 나열합니다. 마켓플레이스가 플러그인을 보유하기 전에 그 ID를 찾아 플러그인 목록을 필터링하거나 해당 마켓플레이스에 업로드할 때 사용하세요. 라이브러리 마켓플레이스는 claude.ai에서든 이 API를 통해서든 그 안에 무언가가 처음 생성된 후에 나타납니다. owner_type(organization 또는 user)과 source로 필터링할 수 있습니다. limit은 1에서 1,000 사이입니다. read:plugins 스코프가 필요합니다.
client = anthropic.Anthropic()
marketplaces = client.beta.organization.plugin_marketplaces.list(
owner_type="organization"
)
# 필요에 따라 추가 페이지를 자동으로 가져옵니다.
for marketplace in marketplaces:
print(f"{marketplace.id}: {marketplace.name}")마켓플레이스 조회
GET /v1/organizations/plugin_marketplaces/{marketplace_id}는 하나의 마켓플레이스를 반환합니다. read:plugins 스코프가 필요합니다.
client = anthropic.Anthropic()
marketplace = client.beta.organization.plugin_marketplaces.retrieve(
"marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r"
)
print(f"id: {marketplace.id}")
print(f"name: {marketplace.name}")마켓플레이스 기본 설치 설정 지정
POST /v1/organizations/plugin_marketplaces/{marketplace_id}는 조직 소유 마켓플레이스의 기본 설치 설정을 지정합니다. 자체 조직 전체 설정이 없는 마켓플레이스 내 모든 플러그인은 나중에 추가되는 플러그인을 포함하여 이 기본값을 organization_installation_preference로 보고합니다. 이 작업은 manual 마켓플레이스와 동기화되는 마켓플레이스 모두에 적용되며, 멤버의 개인 마켓플레이스는 403을 반환합니다. 업데이트할 수 있는 유일한 필드는 default_installation_preference이며, 필수입니다. 이 값은 다시 null로 설정할 수 없습니다. claude.ai에서와 마찬가지로 마켓플레이스에 기본값이 한 번 지정되면 계속 유지됩니다. 변경 사항은 플러그인별 이벤트 없이 하나의 marketplace_updated 이벤트로 기록되며, 어떤 플러그인의 updated_at도 변경하지 않습니다. 이미 설정된 값으로 설정하면 아무것도 변경되지 않지만, 한 가지 예외가 있습니다. 기본값이 설정된 적이 없는 마켓플레이스는 not_available을 보고하지만 실제로는 설정을 보유하지 않으므로, 첫 번째 쓰기(not_available이라도)는 변경으로 간주됩니다. 마켓플레이스를 반환합니다. write:plugins 스코프가 필요합니다.
client = anthropic.Anthropic()
marketplace = client.beta.organization.plugin_marketplaces.update(
"marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
default_installation_preference="available",
)
print(f"id: {marketplace.id}")
print(f"default_installation_preference: {marketplace.default_installation_preference}")마켓플레이스 콘텐츠 검증
두 엔드포인트는 아무것도 연결하거나 저장하지 않고, 주어진 마켓플레이스 콘텐츠를 동기화하면 어떤 결과가 나올지 보고합니다. POST /v1/organizations/plugin_marketplaces/validate_repository는 공개 GitHub 리포지토리를 읽고, POST /v1/organizations/plugin_marketplaces/validate_archive는 업로드한 마켓플레이스 디렉터리의 .zip을 읽습니다. 두 엔드포인트 모두 같은 보고서를 반환합니다. 보고서에는 marketplace.json의 형식이 올바른지, 어떤 플러그인이 어떤 이유로 건너뛰어지는지, 어떤 플러그인이 일부 콘텐츠가 제외된 채 동기화되는지가 포함됩니다. 검사 항목은 실제 동기화에서 실행되는 것과 같습니다. 콘텐츠 관련 문제는 HTTP 오류가 아니라 보고서로 반환됩니다. 리포지토리나 아카이브를 전혀 읽을 수 없는 경우에도 요청은 valid: false와 함께 성공합니다. 검증은 읽기 요청으로 계산되며, 두 엔드포인트를 합쳐 조직당 분당 10회의 검증으로 추가 제한됩니다(속도 제한 참조). 검증은 Activity Feed에 아무것도 기록하지 않습니다. 검증은 반환되기까지 최대 120초가 걸릴 수 있으므로, 클라이언트의 타임아웃을 그보다 길게 설정하세요. 두 엔드포인트 모두 read:plugins 또는 write:plugins 스코프가 필요합니다(read:org_audit 및 read:compliance_org_data로는 권한이 부여되지 않습니다).
리포지토리와 그 외부에 있는 GitHub의 플러그인 소스는 익명으로 읽히므로, 비공개 리포지토리나 비공개 플러그인 소스는 찾을 수 없는 것으로 보고됩니다. GitHub 이외의 호스트에 있는 플러그인 소스는 가져오지 않습니다. 이러한 플러그인은 일반적으로 marketplace_validate_source_not_checked 경고를 받으며, 마켓플레이스가 실제로 동기화될 때 검사됩니다. 리포지토리가 Anthropic이 모든 조직에 동기화하는 마켓플레이스이거나 아카이브가 그러한 마켓플레이스를 지정하는 경우, 더 엄격한 규칙이 적용됩니다. 마켓플레이스 외부의 모든 플러그인 소스는 전체 커밋 SHA로 고정되어야 하고, 고정되지 않았거나 지원되지 않는 호스트의 소스는 플러그인 오류로 보고되며, 읽는 브랜치의 기본값은 해당 마켓플레이스가 동기화하는 브랜치입니다.
validate_repository는 두 개의 필드가 있는 JSON 본문을 받습니다. repository_url은 github.com에 있는 공개 리포지토리의 https:// URL이며(필수), ref는 브랜치 이름 또는 40자 전체 커밋 SHA입니다(선택 사항. 생략하거나 null이면 동기화가 읽을 브랜치이며, 일반적으로 리포지토리의 기본 브랜치입니다). validate_archive는 정확히 하나의 파트 archive가 있는 multipart/form-data를 받으며, 이 파트는 파일 이름이 있는 파일 파트로 전송되어야 합니다. 이 파트는 마켓플레이스 디렉터리의 .zip으로, 최대 32 MB이고, 콘텐츠가 루트에 있거나 하나의 폴더로 감싸져 있어야 하며(Git 호스트의 다운로드가 생성하는 형태), DEFLATE 또는 STORE 압축만 허용됩니다. 다른 폼 필드는 허용되지 않습니다.
특정 브랜치의 공개 리포지토리 검증:
client = anthropic.Anthropic()
report = client.beta.organization.plugin_marketplaces.validate_repository(
repository_url="https://github.com/example-org/claude-plugins",
ref="release-candidate",
)
print(f"valid: {str(report.valid).lower()}")
print(f"total_plugin_count: {report.total_plugin_count}"){
"type": "plugin_marketplace_validation_report",
"valid": false,
"ref": "release-candidate",
"commit_sha": "9fceb02d0ae598e95dc970b74767f19372d61af8",
"total_plugin_count": 3,
"manifest_error": null,
"manifest_error_code": null,
"plugin_errors": [
{
"name": "deploy-helper",
"error": "The plugin has a top-level bin/ directory.",
"error_code": "marketplace_sync_bin_directory_not_allowed"
}
],
"plugin_warnings": [
{
"name": "release-notes",
"warnings": [
{
"message": "plugin.json has unrecognized top-level keys: owners",
"error_code": "marketplace_sync_plugin_unrecognized_keys"
}
]
}
]
}| 필드 | 설명 |
|---|---|
valid | marketplace.json의 형식이 올바르고 건너뛰어지는 플러그인이 없으면 true입니다. 경고가 있어도 false가 되지 않습니다. |
ref | 읽은 브랜치의 이름입니다. 브랜치를 지정하지 않아 기본 브랜치를 읽은 경우, 커밋 SHA인 경우, 아카이브인 경우에는 null입니다. |
commit_sha | 검증된 커밋입니다. Git 호스트에서 다운로드한 아카이브의 경우, 호스트가 ZIP 파일의 주석 필드에 기록한 커밋이 있으면 그 커밋입니다(검증되지 않음). |
total_plugin_count | marketplace.json이 선언한 플러그인 수입니다. 읽을 수 없는 경우 0입니다. |
manifest_error, manifest_error_code | 아무것도 검증할 수 없을 때 설정됩니다. 소스를 읽을 수 없거나, marketplace.json이 없거나, 형식이 잘못되었거나, 제한을 초과한 경우입니다. 120초 이내에 완료되지 않은 검증은 manifest_error_code: "marketplace_validate_deadline_exceeded"를 보고합니다. |
plugin_errors | 동기화 시 건너뛰어지는 플러그인마다 하나의 {name, error, error_code}입니다. |
plugin_warnings | 일부 콘텐츠가 제외된 채 동기화되는 플러그인마다 하나의 {name, warnings: [{message, error_code}]}입니다. |
대신 마켓플레이스 디렉터리의 로컬 사본을 .zip으로 검증할 수도 있으며, 응답은 같은 보고서입니다:
client = anthropic.Anthropic()
with open("marketplace.zip", "rb") as archive:
report = client.beta.organization.plugin_marketplaces.validate_archive(
archive=archive
)
print(f"valid: {str(report.valid).lower()}")
print(f"total_plugin_count: {report.total_plugin_count}")콘텐츠 관련 문제로 요청이 실패하는 경우는 없습니다. 모든 엔드포인트에 공통인 응답(read:org_audit 또는 read:compliance_org_data만 있는 키에 대한 403. 오류 응답 및 속도 제한 참조) 외에, 요청 자체는 다음과 같은 이유로 실패할 수 있습니다:
| 상태 | 원인 | 조치 방법 |
|---|---|---|
| 400 | validate_repository의 경우: 본문이 JSON 객체가 아니거나, repository_url이 없거나, 2,048자를 초과하거나, 자격 증명을 포함하거나, https://github.com/{owner}/{repo} 형식이 아닙니다(.git 접미사는 허용되지만, 다른 호스트, 브랜치 페이지의 /tree/main과 같은 더 긴 경로, 443 또는 80 이외의 포트는 허용되지 않습니다). 또는 ref가 비어 있거나, 255자를 초과하거나, ..를 포함하거나, ASCII 문자, 숫자, ., _, -, +, / 이외의 문자를 포함합니다. 또는 다른 필드가 있습니다. 이러한 검사를 통과했지만 리포지토리에 없는 브랜치를 지정한 ref는 거부되지 않습니다. 요청은 valid: false와 함께 성공하며, manifest_error에 브랜치를 찾을 수 없다고 표시됩니다. validate_archive의 경우: 본문이 multipart/form-data가 아니거나, archive 파트가 없거나, 반복되거나, 파일 이름이 있는 파일 파트로 전송되지 않았거나, 다른 폼 필드가 있습니다. | 요청을 수정하여 다시 전송하세요. |
| 413 | validate_archive의 경우: archive 파트 또는 요청에 선언된 본문 길이가 32 MB를 초과합니다. | 대신 URL로 리포지토리를 검증하거나, 아카이브 크기를 줄이세요. |
보고서 코드
보고서의 각 결과에는 안정적인 코드가 있습니다. 아무것도 검증할 수 없을 때는 manifest_error_code, 각 plugin_errors 항목에는 error_code, 각 경고에는 error_code가 있습니다. 플러그인에 여러 문제가 있는 경우 error_code는 첫 번째 문제의 코드이며, error는 모든 메시지를 결합한 것입니다. 새 코드가 추가될 수 있습니다. 인식할 수 없는 manifest_error_code도 여전히 콘텐츠를 검증할 수 없었음을 의미하고, plugin_errors 항목의 인식할 수 없는 코드도 여전히 플러그인이 건너뛰어짐을 의미하며, 경고의 인식할 수 없는 코드도 여전히 플러그인이 동기화됨을 의미합니다. 다음 코드는 일시적인 상태를 나타내므로, 같은 요청이 나중에 성공할 수 있습니다: marketplace_host_rate_limited, marketplace_host_server_error, marketplace_host_timeout, marketplace_host_unreachable, marketplace_repo_access_denied, marketplace_sync_transient_fetch_budget_exhausted, marketplace_validate_network_error, 그리고 대개 marketplace_validate_deadline_exceeded.
인식할 수 없는 값
이 페이지의 모든 문자열 값(컴포넌트 유형, reach, 스캔 필드, 마켓플레이스 source, 오류 코드)에는 언제든지 새로운 값이 추가될 수 있습니다. 인식할 수 없는 값은 실패로 처리하지 말고, 다른 알 수 없는 문자열과 마찬가지로 처리하세요.
속도 제한
읽기 요청(이 페이지의 모든 GET 엔드포인트)은 조직당 분당 300회 요청의 "rate limit"(속도 제한)을 공유하며, 쓰기 요청(플러그인 또는 버전 생성, 제공 버전 변경, 삭제, 설치 설정 지정 또는 제거, 마켓플레이스 업데이트)은 조직당 분당 60회 요청의 제한을 공유합니다. 마켓플레이스 검증(두 엔드포인트 모두)은 읽기 요청으로 계산되며, 검증은 두 엔드포인트를 합쳐 조직당 분당 10회로 추가 제한됩니다. 두 제한 모두 요청 본문을 읽기 전에 확인됩니다. 이러한 제한은 조직의 모든 키에 걸쳐 계산되며, 조직의 다른 Admin API 제한과는 별개입니다. 제한을 초과한 요청은 retry-after 헤더와 함께 429 Too Many Requests를 반환합니다. 응답에는 적용되는 제한에 대한 anthropic-ratelimit-requests-* 헤더가 포함됩니다(마켓플레이스 검증의 경우 분당 10회 제한, 429의 경우 요청을 거부한 제한).
업로드, 제공 버전 변경 또는 검증은 서비스에 일시적으로 추가 작업을 처리할 용량이 없을 때도 retry-after와 함께 429를 반환할 수 있으며, 업로드는 조직이 콘텐츠 스캔 속도를 초과한 경우에도 429를 반환합니다. 이 모든 경우를 같은 방식으로 처리하세요. retry-after만큼 기다린 후 다시 시도하면 됩니다. 이러한 제한과는 별도로, 같은 플러그인에 대한 설치 설정 쓰기 요청은 한 번에 하나씩 전송하세요. 여러 요청이 동시에 도착하면 일부는 503 및 x-should-retry: true로 응답될 수 있으며, 이러한 요청은 1~2초 후에 다시 전송해도 안전합니다(설치 설정 지정 참조).
페이지네이션
목록 엔드포인트는 불투명 커서를 사용합니다. 첫 번째 요청은 최대 limit개의 행과 next_page 커서를 반환합니다. 다음 요청에서 이 커서를 변경하지 않고 page 매개변수로 전달하고, next_page가 null이 될 때까지 반복하세요. 커서 문자열은 불투명한 값으로 취급하세요. 직접 파싱하거나, 수정하거나, 생성하지 마세요. 플러그인 목록 조회는 next_page가 여전히 설정된 상태에서 limit보다 적은 수의 플러그인이 있거나 플러그인이 없는 페이지를 반환할 수 있으므로, next_page가 null이 될 때까지 계속 페이지를 요청하세요. SDK의 목록 이터레이터는 반복하면서 추가 페이지를 가져오지만 첫 번째 빈 페이지에서 중지하므로, 플러그인 목록에서는 일찍 종료될 수 있습니다. 보안 인벤토리 워크플로에서처럼 모든 플러그인이 필요한 경우에는 각 페이지를 직접 요청하고 해당 페이지의 next_page를 page로 전달하세요.
limit의 기본값은 20이며 최솟값은 1입니다. 최댓값은 플러그인, 설치 설정, 공유의 경우 100이고, 버전과 마켓플레이스의 경우 1,000입니다. 모든 목록은 최신 항목부터 정렬됩니다.
오류 응답
오류 응답은 오류에 설명된 표준 형식을 따릅니다. 지원팀에 문의할 때는 응답 본문의 request_id를 함께 알려 주세요.
| 상태 | 의미 |
|---|---|
| 400 | 입력이 잘못되었거나, 해당 작업을 이 플러그인 또는 마켓플레이스에 적용할 수 없습니다(각 엔드포인트 섹션 참조). 엔드포인트가 인식하지 못하는 쿼리 매개변수가 포함된 경우와 Claude Enterprise 조직이 아닌 조직인 경우(this endpoint is not supported for this organization type)에도 반환됩니다. |
| 401 | x-api-key 헤더가 없거나 키를 인식할 수 없습니다. |
| 403 | 키에 필요한 scope(범위)가 없거나, 요청이 구성원의 플러그인 또는 개인 마켓플레이스에 업로드하거나, 그 제공 버전을 변경하거나, 그 기본값을 설정하려고 합니다. (구성원의 플러그인 삭제는 허용됩니다.) |
| 404 | 리소스를 찾을 수 없습니다. 요청에 anthropic-beta 값이 누락되었거나 조직에서 API가 활성화되지 않은 경우에도 반환되며, 이때 엔드포인트는 존재하지 않는 것처럼 보입니다. |
| 409 | 이름이 이미 사용 중이거나, 콘텐츠 스캔이 아직 실행 중이거나, 충돌하는 업로드가 진행 중입니다. |
| 413 | 요청 본문이 크기 제한을 초과했습니다. 업로드의 경우 200 MB, 마켓플레이스 검증의 경우 32 MB입니다. |
| 429 | 속도 제한을 초과했습니다. 속도 제한을 참조하세요. |
| 500 | 내부 오류입니다. |
| 503 | 일시적인 오류입니다. 하나의 플러그인에 대한 여러 설치 설정 쓰기 요청이 동시에 도착한 경우에도 반환되므로, 이러한 요청은 하나씩 보내세요. registration_pending(다음 표 참조)을 제외하고는 "backoff"(백오프)를 적용하여 재시도하세요. |
하나의 상태 코드에 서로 다르게 처리해야 하는 여러 원인이 있는 경우, 오류에는 error.details.error_code도 포함되며, 원인이 특정 플러그인이나 버전과 관련된 경우 error.details.plugin_id 또는 error.details.plugin_version_id도 포함됩니다:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "...",
"details": {
"error_code": "plugin_name_taken",
"plugin_id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
}
},
"request_id": "req_018EeWyXxfu5pfWkrYcMdjWG"
}error_code | 상태 | 의미 및 조치 방법 |
|---|---|---|
plugin_name_taken | 409 | 이 이름을 가진 플러그인이 마켓플레이스에 이미 존재합니다. details.plugin_id가 해당 플러그인입니다. 응답을 받지 못한 생성 요청을 재시도하는 중이라면 해당 플러그인으로 계속 진행하세요. plugin_id가 없으면 해당 이름은 독립형 스킬이 사용 중인 것입니다. 다른 이름으로 업로드하거나 claude.ai에서 해당 스킬을 삭제하세요. |
skill_name_taken | 409 | 플러그인이 라이브러리 마켓플레이스에 있으며, 그 스킬 중 하나가 조직 스킬(관리자가 claude.ai에서 조직 전체를 위해 업로드한 스킬)과 이름이 같습니다. details.skill_name에 해당 이름이 표시됩니다. 둘 중 하나의 이름을 바꾸거나 제거하세요. |
registration_pending | 503 | 파일은 저장되었지만 플러그인의 스킬을 아직 구성원이 사용할 수 있도록 만들지 못했습니다. 업로드 재시도를 참조하세요. |
scan_pending | 409 | 버전의 콘텐츠 스캔이 아직 실행 중입니다. 스캔이 완료되면 재시도하세요. |
scan_failed | 400 | 버전의 콘텐츠 스캔이 실패했거나, 오류가 발생했거나, 판정에 도달하지 못해 해당 버전을 제공할 수 없습니다. 다른 버전을 선택하세요. |
cmek_key_disabled, cmek_key_network_blocked | 400 | 조직의 고객 관리형 암호화 키를 사용할 수 없습니다. 고객 관리형 암호화 키를 참조하세요. |
새로운 코드가 추가될 수 있습니다. 인식하지 못하는 코드는 해당 상태 코드와 동일하게 처리하세요.
업로드 재시도
어떤 엔드포인트도 Idempotency-Key를 허용하지 않습니다. 제공 버전 변경, 설치 설정 지정, 마켓플레이스 기본값 설정은 반복해도 안전합니다. 삭제를 반복하거나 그룹의 설치 설정 제거를 반복하면 404가 반환됩니다.
오류를 반환한 업로드는 아무것도 저장하지 않았으며, 단 하나의 예외가 있습니다: error_code: "registration_pending"이 포함된 503입니다. 서버는 업로드된 파일을 저장한 후 새 버전의 스킬을 claude.ai에 등록하며, 이 과정을 거쳐야 구성원이 스킬을 사용할 수 있습니다. registration_pending은 파일은 저장되었지만 이 마지막 단계가 완료되지 않았음을 의미합니다. 동일한 파일을 한 번 더 업로드하면 이 단계가 완료됩니다(그리고 동일한 버전이 하나 더 저장됩니다):
POST /v1/organizations/plugins에서는 플러그인이 생성된 상태이며, 응답에x-should-retry: false가 포함됩니다. 생성 요청을 다시 보내지 마세요(다시 보내면409 plugin_name_taken이 반환됩니다). 대신 동일한 파일을details.plugin_id의 버전으로 업로드하세요.POST /v1/organizations/plugins/{plugin_id}/versions에서는 버전이 저장된 상태입니다(details.plugin_version_id). 응답에x-should-retry: true가 포함되어 있으면 동일한 요청을 다시 보내고,false가 포함되어 있으면 다시 보내지 마세요.
생성 요청의 응답을 받지 못한 경우 재시도하세요. 재시도하면 details.plugin_id에 플러그인 ID가 포함된 409 plugin_name_taken이 반환되며, 해당 플러그인으로 계속 진행하면 됩니다. 응답을 받지 못한 버전 생성 요청을 재시도하면 동일한 두 번째 버전이 저장됩니다. 이를 방지하려면 각 업로드 전에 플러그인의 latest_version_id를 기록해 두세요. 응답을 받지 못한 경우 플러그인을 조회하여 latest_version_id가 변경되지 않았을 때만 재시도하세요.
Activity Feed 이벤트
이 API를 통한 모든 쓰기 작업은 조직의 Compliance API Activity Feed에 기록되며, apikey_ ID를 포함하는 api_actor로서 API 키에 귀속됩니다. 키가 생성한 플러그인과 버전의 created_by에도 동일한 행위자가 표시됩니다.
| 이벤트 | 발생 시점 |
|---|---|
claude_plugin_created | 업로드(여기 또는 claude.ai에서) 또는 승인된 게시 요청으로 플러그인이 생성될 때. Git 동기화로 생성된 플러그인은 claude_plugin_version_created만 발생시킵니다. |
claude_plugin_version_created | 버전이 저장될 때. Git 동기화로 저장된 버전은 system_actor에 귀속됩니다. |
claude_plugin_updated | 기존 플러그인에 새 버전이 업로드될 때. |
claude_plugin_served_version_updated | 제공 버전이 변경될 때. |
claude_plugin_deleted | 플러그인이 여기 또는 claude.ai에서 개별적으로 삭제될 때. |
plugin_installation_preference_updated | 설치 설정이 지정되거나 제거될 때. |
marketplace_created | 첫 번째 업로드로 라이브러리 마켓플레이스가 생성될 때. |
marketplace_updated | 마켓플레이스의 기본 설치 설정이 변경되거나, 관리자 또는 소유자가 claude.ai에서 동기화를 시작할 때. |
marketplace_deleted | claude.ai에서 마켓플레이스가 해당 플러그인과 함께 삭제될 때(플러그인별 이벤트는 발생하지 않음). |
claude_plugin_archive_accessed | 구성원 소유 플러그인의 아카이브가 다운로드될 때. |
claude_plugin_security_scan_completed | 콘텐츠 스캔이 완료될 때. |
이러한 이벤트의 플러그인, 버전, 마켓플레이스 ID는 이 API가 반환하는 ID와 동일합니다. plugin_installation_preference_updated는 플러그인을 id가 아닌 name과 marketplace_id로 식별합니다.
마켓플레이스의 기본값을 변경하면 기본값을 상속하는 모든 플러그인의 값이 변경되더라도 marketplace_updated 이벤트 하나만 기록되고 플러그인별 이벤트는 기록되지 않습니다. 구성원 소유 플러그인의 아카이브 다운로드를 제외하고 읽기 작업은 기록되지 않습니다. 아무것도 변경하지 않는 쓰기 작업은 아무것도 기록하지 않습니다.
claude.ai에서 부여되거나 철회된 공유는 피드에 role_assignment_granted 및 role_assignment_revoked 이벤트로 표시됩니다. 이 API는 삭제를 보고하지 않습니다. 삭제된 플러그인은 다음 목록에서 단순히 나타나지 않을 뿐입니다. Git 동기화, 마켓플레이스 삭제(marketplace_deleted 이벤트 하나), 구성원 계정 또는 조직 삭제로 제거된 플러그인은 플러그인별 이벤트를 발생시키지 않으므로, 제거된 항목을 파악하려면 전체 인벤토리를 주기적으로 다시 조회하세요.
고객 관리형 암호화 키
조직에서 "customer-managed encryption key"(고객 관리형 암호화 키)를 사용하는 경우, 버전의 description, release_notes, components 및 파일은 해당 키로 암호화됩니다. 키를 사용할 수 없는 동안에는 다음과 같습니다:
- 읽기 및 목록 조회는 계속 성공하지만,
description,release_notes,components는null로 반환됩니다. - 아카이브 다운로드, 생성, 버전 생성, 제공 버전 변경은
cmek_key_disabled또는cmek_key_network_blocked와 함께400을 반환합니다. - 라이브러리 마켓플레이스의 플러그인을 삭제하면
400 cmek_key_disabled가 반환되고 아무것도 삭제되지 않습니다. 플러그인의 스킬을 먼저 claude.ai에서 철회해야 하는데, 이 작업에 키가 필요하기 때문입니다. 그 외의 삭제, 설치 설정, 마켓플레이스 기본값은 정상적으로 작동합니다.
키를 복원하면 이러한 제한이 모두 해제됩니다.
참고 항목
기본 소유자가 범위가 지정된 키를 생성하는 곳입니다.
설치 설정에 사용되는 rbac_group_ ID를 제공하는 그룹 엔드포인트입니다.
플러그인 쓰기 작업과 구성원 아카이브 다운로드가 기록되는 곳입니다.
Claude Enterprise의 플러그인 및 스킬 사용량 보고입니다.
Was this page helpful?