공개 디렉터리에 제출하는 플러그인에는 워크스페이스에 설치하는 플러그인보다 엄격한 기준이 적용됩니다. 디렉터리에 제출하려면 공통 패키지 검사뿐 아니라 등록 정보 필드, 심사 자료, MCP 도구, 스킬, 에셋, 이미지에 대한 추가 검사도 통과해야 합니다. 이 문서에서는 MCP 서버 참조 검사처럼 제출 포털 밖에서도 실행될 수 있는 공통 패키지 검사도 다룹니다.
제출할 때 반환된 오류 코드로 해당 요구 사항을 찾으세요. 오류가 있으면 제출할 수 없습니다. 경고가 있어도 제출할 수 있지만 계속하기 전에 내용을 확인하세요.
비워 둘 수 없는 값에는 공백이 아닌 문자가 하나 이상 있어야 합니다. 지원되는 텍스트에는 제어 문자, 유니코드 줄 구분자나 단락 구분자, 지원되지 않는 비가시적 서식 문자가 포함되지 않습니다. HTTPS URL에는 호스트가 있어야 하며, 인증 정보나 지원되지 않는 문자가 들어가면 안 됩니다.
디렉터리 최종 제출
패키지가 업로드 검증을 통과해도 디렉터리 최종 제출 단계에서 실패할 수 있습니다. 최종 제출 단계에서는 등록 정보에 더 엄격한 제한을 적용하고 MCP 구성, 스킬 검사 결과, 테스트 케이스, 정책 준수 확인 사항을 검토합니다.
| 필드 | 최종 제출 규칙 |
|---|---|
| 패키지 이름 | 필수이며 최대 64자입니다. ASCII 영문자나 숫자로 시작해야 하며 ASCII 영문자, 숫자, _, -만 사용할 수 있습니다. |
| 버전 | 필수이며 최대 64자의 시맨틱 버전을 사용해야 합니다. |
| 표시 이름 | 필수이며 한 줄로 작성해야 합니다. 최대 30자입니다. |
| 짧은 설명 | 필수이며 한 줄로 작성해야 합니다. 최대 30자입니다. |
| 상세 설명 | 필수이며 최대 4,000자입니다. 줄바꿈을 사용할 수 있습니다. |
| 개발자 이름 | 필수이며 한 줄로 작성해야 합니다. 최대 80자입니다. |
| 카테고리 | 필수입니다. 등록 정보 및 인터페이스 오류 섹션에 나열된 지원 카테고리 중 하나를 선택하세요. |
| 기능 | 최대 20개입니다. 각 기능은 120자 이내의 한 줄로 작성해야 하며 비워 둘 수 없습니다. |
| 시작 프롬프트 | 최대 3개입니다. 각 프롬프트는 128자 이내의 한 줄로 작성해야 하며 비워 둘 수 없습니다. 유니코드와 공백을 정규화한 후에도 서로 달라야 하며 MCP 서버 @mention을 포함하면 안 됩니다. |
| URL | 원격 MCP 제출 시 필수이며, 스킬 전용 플러그인을 ZIP으로 업로드할 때는 선택 사항입니다. 웹사이트, 지원, 개인정보 보호 정책, 이용약관 URL은 각각 HTTPS를 사용하고 1,024자 이하여야 합니다. |
| 브랜드 색상 | 선택 사항이며 6자리 16진수 색상값을 사용합니다. 밝은 테마용 색상은 흰색과의 대비가 2:1 이상이어야 하며, 어두운 테마용 색상은 #212121과의 대비가 2:1 이상이어야 합니다. |
모든 플러그인 제출 시 다음 요건도 충족해야 합니다.
- 패키지에 포함된 모든 스킬이 안전 및 보안 검사를 통과해야 합니다. 검사에는 최대 2시간이 걸릴 수 있습니다.
- 개발자 또는 사업자 신원이 확인되어야 하며 필수 정책 준수 확인 절차를 모두 완료해야 합니다.
원격 MCP 플러그인을 최종 제출할 때는 다음 요건도 충족해야 합니다.
- 위 규칙에 맞는 웹사이트, 지원, 개인정보 보호 정책, 이용약관 URL을 제공하세요.
- 지원하는 플랫폼에서 주요 사용 사례와 도구를 시연하는 녹화 영상의 URL을 제공하세요.
- 정상 동작을 확인하는 테스트 케이스를 정확히 5개, 예외 상황을 확인하는 테스트 케이스를 정확히 3개 제공하고 릴리스 노트를 첨부하세요.
- 프로덕션 HTTPS MCP 서버 URL을 제공하고 도메인 검증 챌린지를 완료하세요. 최신 도구 검사도 통과해야 합니다.
- 모든 MCP 도구에
readOnlyHint,openWorldHint,destructiveHint값을 명시하고 각 값을 설정한 근거를 제시하세요. - 서버가 OAuth를 사용한다면 심사자가 바로 사용할 수 있는 데모용 인증 정보를 제공하세요.
최종 제출 메타데이터 오류
다음 오류 이름에서 subtitle은 짧은 설명을, description은 상세 설명을 뜻합니다.
| 이름 | 요구 사항 |
|---|---|
submission_display_name_required |
표시 이름은 필수이며 비워 둘 수 없습니다. 한 줄로 작성해야 합니다. |
submission_display_name_too_long |
표시 이름은 30자 이하여야 합니다. |
submission_display_name_character_unsupported |
표시 이름은 지원되는 텍스트로 한 줄에 작성해야 합니다. |
submission_subtitle_required |
짧은 설명은 필수이며 비워 둘 수 없습니다. 한 줄로 작성해야 합니다. |
submission_subtitle_too_long |
짧은 설명은 30자 이하여야 합니다. |
submission_subtitle_character_unsupported |
짧은 설명은 지원되는 텍스트로 한 줄에 작성해야 합니다. |
submission_description_required |
상세 설명은 필수이며 비워 둘 수 없습니다. 줄바꿈을 사용할 수 있습니다. |
submission_description_too_long |
상세 설명은 4,000자 이하여야 합니다. |
submission_description_character_unsupported |
상세 설명에는 지원되는 텍스트를 사용해야 합니다. 줄바꿈을 사용할 수 있습니다. |
submission_developer_name_required |
개발자 이름은 필수이며 비워 둘 수 없습니다. 한 줄로 작성해야 합니다. |
submission_developer_name_too_long |
개발자 이름은 80자 이하여야 합니다. |
submission_developer_name_character_unsupported |
개발자 이름은 지원되는 텍스트로 한 줄에 작성해야 합니다. |
plugin_capability_invalid |
각 기능은 지원되는 텍스트로 120자 이내의 한 줄에 작성해야 하며 비워 둘 수 없습니다. |
plugin_default_prompt_mention |
시작 프롬프트에는 MCP 서버 @mentions를 포함하면 안 됩니다. |
plugin_default_prompt_duplicate |
시작 프롬프트는 유니코드와 공백을 정규화한 후에도 서로 달라야 합니다. |
MCP 및 심사 오류
다음 오류는 원격 MCP 제출 시 적용됩니다.
| 이름 | 요구 사항 |
|---|---|
annotations_required |
모든 MCP 도구에서 readOnlyHint, openWorldHint, destructiveHint를 실제 동작에 맞게 설정해야 합니다. |
justification_required |
각 MCP 도구 주석에는 해당 도구의 읽기 전용 동작, 외부 시스템과의 상호작용 또는 파괴적 동작을 기준으로 값을 설정한 근거가 있어야 합니다. |
scan_required |
프로덕션 MCP 서버를 대상으로 실행한 최신 MCP 도구 검사가 성공해야 합니다. |
domain_verification_required |
MCP 호스트 또는 허용된 상위 호스트에 생성된 /.well-known/openai-apps-challenge URL에서 정확한 검증 토큰을 제공해야 하며 도메인 검증 단계도 통과해야 합니다. |
frame_domain_explanation_required |
MCP 도구 검사에서 보고된 외부 프레임 도메인마다 UI에 해당 도메인이 필요한 이유와 해당 도메인이 제공하는 콘텐츠를 설명해야 합니다. |
아카이브 오류
ZIP 업로드 오류 및 경고
포털의 스킬 전용 제출 옵션에서는 스킬 ZIP 패키지와 승인된 로컬 MCP 플러그인을 업로드할 수 있습니다. 승인된 로컬 MCP 플러그인에는 스킬이 없어도 됩니다. 오류가 있으면 업로드할 수 없으며 경고가 있으면 확인이 필요합니다.
| 이름 | 요구 사항 |
|---|---|
plugin_name_mismatch |
업데이트할 패키지 이름은 기존 플러그인 이름과 일치해야 합니다. |
plugin_version_unchanged |
새 릴리스에는 기존과 다른 매니페스트 version 값을 사용해야 합니다. 이미 게시한 버전을 다시 사용하려면 확인이 필요합니다. |
mcp_configuration_excluded |
조직이 로컬 MCP 제출 승인을 받지 않았다면 MCP 구성은 제외됩니다. 로컬 MCP 플러그인의 경우 제출 조직이 허용 목록에 있는지 OpenAI 담당자에게 확인하세요. 원격 MCP 서버는 MCP 포함 옵션으로 제출하세요. |
app_configuration_excluded |
ZIP 업로드에는 apps 또는 .app.json을 포함하면 안 됩니다. 원격 MCP 서버는 MCP 포함 옵션으로 제출하세요. 로컬 MCP 서버는 데스크톱 전용 제출 안내를 따르세요. |
claude_format_normalized |
포털은 .claude-plugin/plugin.json을 .codex-plugin/plugin.json으로 변환하고, 누락된 인터페이스 기본값과 정규화된 텍스트 필드를 추가합니다. |
manifest_normalized |
포털은 정규화된 매니페스트를 .codex-plugin/plugin.json으로 저장합니다. 변경된 필드는 확인이 필요합니다. |
developer_name_defaulted |
ZIP에 적힌 이름과 관계없이, 등록 정보의 개발자 이름은 선택한 인증 개발자 정보에 따라 자동으로 설정됩니다. |
ZIP 구조 및 제한 오류
| 이름 | 요구 사항 |
|---|---|
archive_empty |
아카이브는 비어 있으면 안 됩니다. |
archive_too_large |
압축된 ZIP 파일은 100 MB 이하여야 합니다. |
archive_format_not_zip |
아카이브는 손상되지 않은 유효한 ZIP 파일이어야 합니다. |
archive_member_path_empty |
아카이브 항목의 경로는 비어 있으면 안 됩니다. |
archive_member_path_has_outer_whitespace |
아카이브 항목의 경로 앞뒤에 공백이 있으면 안 됩니다. |
archive_member_path_has_backslash |
아카이브 항목의 경로에는 /를 사용해야 하며 역슬래시는 허용되지 않습니다. |
archive_member_path_absolute |
아카이브 항목의 경로는 아카이브 루트를 기준으로 한 상대 경로여야 합니다. |
archive_member_path_has_empty_segment |
아카이브 항목의 경로에는 빈 구간이 있으면 안 됩니다. |
archive_member_path_has_parent_segment |
아카이브 항목의 경로에는 .. 구간이 있으면 안 됩니다. |
archive_member_path_too_deep |
아카이브 항목의 경로는 파일 이름을 포함해 최대 20개 구간으로 구성할 수 있습니다. |
archive_member_path_too_long |
아카이브 항목의 경로는 지원되는 경로 길이 제한을 초과하면 안 됩니다. |
archive_member_path_normalization_collision |
아카이브 항목의 경로는 대소문자와 유니코드를 정규화한 후에도 서로 달라야 합니다. |
archive_member_type_unsupported |
아카이브 항목은 일반 파일 또는 디렉터리여야 합니다. |
archive_member_too_large |
아카이브 항목은 100 MiB 이하여야 합니다. |
archive_member_path_duplicate |
아카이브 항목의 경로는 중복되면 안 됩니다. |
archive_member_path_type_conflict |
파일 경로를 디렉터리 경로로도 사용하거나 그 아래에 다른 아카이브 항목을 둘 수 없습니다. |
archive_too_many_entries |
아카이브 항목은 5,000개 이하여야 합니다. |
archive_uncompressed_too_large |
압축을 푼 아카이브는 512 MiB 이하여야 합니다. |
archive_member_unreadable |
모든 아카이브 항목은 읽을 수 있어야 하며, 암호화되지 않은 상태로 지원되는 압축 방식을 사용해야 합니다. |
플러그인 루트 오류
| 이름 | 요구 사항 |
|---|---|
plugin_root_missing |
선택한 경로에 플러그인이 포함된 디렉터리가 있어야 합니다. |
archive_plugin_files_missing |
ZIP에는 지원되는 플러그인 매니페스트와 유효한 스킬이 하나 이상 있어야 합니다. 승인된 로컬 MCP 서버가 있으면 스킬을 대신할 수 있습니다. |
plugin_root_ambiguous |
ZIP에는 플러그인 루트가 정확히 하나 있어야 합니다. 위치는 아카이브 루트 또는 단일 최상위 디렉터리 안이어야 합니다. |
plugin_root_has_siblings |
ZIP의 최상위에 플러그인 디렉터리가 있으면 같은 수준에 파일이 있으면 안 됩니다. |
플러그인 매니페스트 오류
| 이름 | 요구 사항 |
|---|---|
plugin_manifest_missing |
ZIP의 루트 또는 그 안의 단일 최상위 디렉터리에 다음 파일 중 하나가 있어야 합니다. 지원되는 Agent Plugins 스키마를 사용하는 plugin.json, .codex-plugin/plugin.json, .agent-plugin/plugin.json, .claude-plugin/plugin.json 중 하나를 포함하세요. |
plugin_manifest_not_file |
플러그인 매니페스트는 일반 JSON 파일이어야 합니다. |
plugin_manifest_unreadable |
플러그인 매니페스트는 읽을 수 있는 UTF-8 텍스트여야 합니다. |
plugin_manifest_json_malformed |
플러그인 매니페스트에는 유효한 JSON이 있어야 합니다. 구문 오류가 있으면 해당 줄 번호가 표시됩니다. |
plugin_manifest_root_not_object |
플러그인 매니페스트의 최상위 값은 JSON 객체여야 합니다. |
codex_manifest_parent_not_directory |
.codex-plugin은 디렉터리여야 합니다. |
codex_manifest_path_not_file |
.codex-plugin/plugin.json은 일반 JSON 파일이어야 합니다. |
plugin_id_wrong_type |
id를 지정하는 경우 값은 문자열이어야 합니다. |
plugin_id_empty |
id를 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_name_missing |
name은 필수입니다. |
plugin_name_wrong_type |
name은 문자열이어야 합니다. |
plugin_name_empty |
name은 비워 둘 수 없습니다. |
plugin_name_too_long |
name은 64자 이하여야 합니다. |
plugin_name_format |
name은 ASCII 영문자나 숫자로 시작해야 하며 ASCII 영문자, 숫자, _, -만 포함할 수 있습니다. |
plugin_version_missing |
version은 필수입니다. |
plugin_version_wrong_type |
version은 문자열이어야 합니다. |
plugin_version_empty |
version은 1.0.0과 같은 비어 있지 않은 시맨틱 버전 문자열이어야 합니다. |
plugin_version_not_semver |
version은 1.0.0과 같이 시맨틱 버전 규칙을 따라야 합니다. |
plugin_version_too_long |
version은 64자 이하여야 합니다. |
plugin_description_missing |
description은 필수입니다. |
plugin_description_wrong_type |
description은 문자열이어야 합니다. |
plugin_description_empty |
description은 비워 둘 수 없습니다. |
plugin_description_too_long |
description은 1,024자 이하여야 합니다. |
plugin_description_character_unsupported |
description에는 지원되는 텍스트를 사용해야 합니다. 줄바꿈을 사용할 수 있습니다. |
plugin_developer_missing |
author.name은 필수입니다. interface.developerName도 필수이며 관련 오류는 별도로 보고됩니다. |
plugin_author_wrong_type |
author는 객체여야 합니다. |
plugin_author_name_wrong_type |
author.name은 문자열이어야 합니다. |
plugin_author_name_empty |
author.name은 비워 둘 수 없습니다. |
plugin_author_name_too_long |
author.name은 120자 이하여야 합니다. |
plugin_author_name_character_unsupported |
author.name에는 지원되는 텍스트를 사용해야 합니다. |
plugin_author_email_wrong_type |
author.email을 지정하는 경우 값은 문자열이어야 합니다. |
plugin_author_email_empty |
author.email을 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_author_email_too_long |
author.email은 320자 이하여야 합니다. |
plugin_author_email_character_unsupported |
author.email에는 지원되는 텍스트를 사용해야 합니다. |
plugin_author_url_wrong_type |
author.url을 지정하는 경우 값은 문자열이어야 합니다. |
plugin_author_url_empty |
author.url을 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_author_url_not_https |
author.url은 HTTPS URL이어야 합니다. |
plugin_author_url_has_credentials |
author.url에는 인증 정보를 포함하면 안 됩니다. |
plugin_author_url_too_long |
author.url은 2,048자 이하여야 합니다. |
plugin_author_url_character_unsupported |
author.url에는 지원되는 텍스트를 사용해야 합니다. |
등록 정보 및 인터페이스 오류
플러그인 매니페스트의 interface 객체는 사용자에게 공개되는 디렉터리 등록 정보를 정의합니다. 이 객체는 .codex-plugin/plugin.json에 있으며 displayName, shortDescription 등의 필드를 사용합니다.
{
"interface": {
"displayName": "Example Plugin",
"shortDescription": "Summarize documents",
"longDescription": "Summarize and organize documents.",
"developerName": "Example",
"category": "Productivity",
"capabilities": ["Summarize documents"]
}
}
스킬 전용 플러그인을 ZIP으로 업로드할 때는 등록 정보의 URL 4개(웹사이트, 개인정보 보호 정책, 이용약관, 지원)가 선택 사항입니다. 원격 MCP 제출 시에는 모두 필수입니다. 각 URL의 길이 제한은 패키지 검증 시 2,048자, 디렉터리 최종 제출 시 1,024자입니다.
| 이름 | 요구 사항 |
|---|---|
plugin_interface_wrong_type |
플러그인 매니페스트의 interface 필드는 JSON 객체여야 합니다. |
plugin_display_name_wrong_type |
interface.displayName은 문자열이어야 합니다. |
plugin_display_name_empty |
interface.displayName은 필수이며 비워 둘 수 없습니다. |
plugin_display_name_too_long |
interface.displayName은 패키지 검증 시 80자 이하, 디렉터리 최종 제출 시 30자 이하여야 합니다. |
plugin_display_name_character_unsupported |
interface.displayName에는 지원되는 텍스트를 사용해야 합니다. |
plugin_short_description_missing |
interface.shortDescription은 필수이며 한 줄로 작성해야 합니다. 패키지 검증 시 240자 이하, 디렉터리 최종 제출 시 30자 이하여야 합니다. |
plugin_short_description_wrong_type |
interface.shortDescription은 문자열이어야 합니다. |
plugin_short_description_empty |
interface.shortDescription은 비워 둘 수 없습니다. |
plugin_short_description_too_long |
interface.shortDescription은 패키지 검증 시 240자 이하, 디렉터리 최종 제출 시 30자 이하여야 합니다. |
plugin_short_description_character_unsupported |
interface.shortDescription에는 지원되는 텍스트를 사용해야 합니다. |
plugin_long_description_wrong_type |
interface.longDescription은 문자열이어야 합니다. |
plugin_long_description_empty |
interface.longDescription은 필수이며 비워 둘 수 없습니다. |
plugin_long_description_too_long |
interface.longDescription은 4,000자 이하여야 합니다. |
plugin_long_description_character_unsupported |
interface.longDescription에는 지원되는 텍스트를 사용해야 합니다. 줄바꿈을 사용할 수 있습니다. |
plugin_developer_name_wrong_type |
interface.developerName은 문자열이어야 합니다. |
plugin_developer_name_empty |
interface.developerName은 필수이며 비워 둘 수 없습니다. |
plugin_developer_name_too_long |
interface.developerName은 패키지 검증 시 120자 이하, 디렉터리 최종 제출 시 80자 이하여야 합니다. |
plugin_developer_name_character_unsupported |
interface.developerName에는 지원되는 텍스트를 사용해야 합니다. |
plugin_category_wrong_type |
interface.category는 문자열이어야 합니다. |
plugin_category_empty |
interface.category를 지정하는 경우 값을 비워 둘 수 없습니다. 생략하면 Other가 적용됩니다. |
plugin_category_unknown |
interface.category에는 Productivity, Creativity, Developer Tools, Business & Operations, Data & Analytics, Communication, Education & Research, Security, Finance, Healthcare, Travel, Entertainment, Other 중 하나를 사용해야 합니다. |
plugin_category_character_unsupported |
interface.category에는 지원되는 텍스트를 사용해야 합니다. |
plugin_capabilities_wrong_type |
interface.capabilities는 문자열 목록이어야 합니다. |
plugin_capabilities_too_many |
interface.capabilities의 항목은 20개 이하여야 합니다. |
plugin_capability_wrong_type |
interface.capabilities의 각 항목은 문자열이어야 합니다. |
plugin_capability_empty |
interface.capabilities에 항목을 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_capability_too_long |
interface.capabilities의 각 항목은 120자 이하여야 합니다. |
plugin_capability_character_unsupported |
interface.capabilities의 각 항목에는 지원되는 텍스트를 사용해야 합니다. |
plugin_website_url_wrong_type |
interface.websiteURL을 지정하는 경우 값은 문자열이어야 합니다. |
plugin_website_url_empty |
interface.websiteURL을 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_website_url_format |
interface.websiteURL은 HTTPS URL이어야 합니다. |
plugin_website_url_too_long |
interface.websiteURL은 등록 정보의 URL 길이 제한을 충족해야 합니다. |
plugin_privacy_policy_url_wrong_type |
interface.privacyPolicyURL을 지정하는 경우 값은 문자열이어야 합니다. |
plugin_privacy_policy_url_empty |
interface.privacyPolicyURL을 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_privacy_policy_url_format |
interface.privacyPolicyURL은 HTTPS URL이어야 합니다. |
plugin_privacy_policy_url_too_long |
interface.privacyPolicyURL은 등록 정보의 URL 길이 제한을 충족해야 합니다. |
plugin_terms_of_service_url_wrong_type |
interface.termsOfServiceURL을 지정하는 경우 값은 문자열이어야 합니다. |
plugin_terms_of_service_url_empty |
interface.termsOfServiceURL을 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_terms_of_service_url_format |
interface.termsOfServiceURL은 HTTPS URL이어야 합니다. |
plugin_terms_of_service_url_too_long |
interface.termsOfServiceURL은 등록 정보의 URL 길이 제한을 충족해야 합니다. |
plugin_support_url_wrong_type |
interface.supportURL을 지정하는 경우 값은 문자열이어야 합니다. |
plugin_support_url_empty |
interface.supportURL을 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_support_url_format |
interface.supportURL은 HTTPS URL이어야 합니다. |
plugin_support_url_too_long |
interface.supportURL은 등록 정보의 URL 길이 제한을 충족해야 합니다. |
plugin_homepage_wrong_type |
homepage를 지정하는 경우 값은 문자열이어야 합니다. |
plugin_homepage_empty |
homepage를 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_homepage_format |
homepage는 HTTPS URL이어야 합니다. |
plugin_homepage_too_long |
homepage는 2,048자 이하여야 합니다. |
plugin_brand_color_wrong_type |
interface.brandColor를 지정하는 경우 값은 문자열이어야 합니다. |
plugin_brand_color_empty |
interface.brandColor를 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_brand_color_format |
interface.brandColor는 #1ABCFE와 같은 6자리 16진수 색상값이어야 합니다. |
plugin_brand_color_dark_wrong_type |
interface.brandColorDark를 지정하는 경우 값은 문자열이어야 합니다. |
plugin_brand_color_dark_empty |
interface.brandColorDark를 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_brand_color_dark_format |
interface.brandColorDark는 #1ABCFE와 같은 6자리 16진수 색상값이어야 합니다. |
plugin_brand_color_contrast |
interface.brandColor는 흰색과의 대비가 2:1 이상이어야 합니다. |
plugin_brand_color_dark_contrast |
interface.brandColorDark는 #212121과의 대비가 2:1 이상이어야 합니다. |
plugin_default_prompt_wrong_type |
interface.defaultPrompt는 문자열 또는 문자열 목록이어야 합니다. |
plugin_default_prompt_too_many |
interface.defaultPrompt에는 프롬프트를 최대 3개까지 지정할 수 있습니다. |
plugin_default_prompt_entry_wrong_type |
interface.defaultPrompt의 각 항목은 문자열이어야 합니다. |
plugin_default_prompt_empty |
interface.defaultPrompt에 항목을 지정하는 경우 값을 비워 둘 수 없습니다. |
plugin_default_prompt_too_long |
interface.defaultPrompt의 각 항목은 패키지 검증 시 512자 이하, 디렉터리 최종 제출 시 128자 이하여야 합니다. |
plugin_default_prompt_character_unsupported |
interface.defaultPrompt의 각 항목은 지원되는 텍스트로 한 줄에 작성해야 합니다. |
플러그인 콘텐츠 오류
| 이름 | 요구 사항 |
|---|---|
plugin_skills_path_wrong_type |
skills는 루트의 skills/ 디렉터리를 가리키는 경로 문자열이어야 합니다. |
plugin_skills_path_empty |
skills를 지정하는 경우 루트의 skills/ 디렉터리를 가리키는 비어 있지 않은 경로여야 합니다. |
plugin_skills_path_unsupported |
skills 경로가 가리키는 위치는 루트의 skills/ 디렉터리여야 합니다. |
plugin_skills_directory_missing |
루트의 skills/ 디렉터리를 선언했다면 해당 디렉터리가 있어야 합니다. |
plugin_skills_path_not_directory |
루트의 skills/를 선언했다면 해당 경로는 디렉터리여야 합니다. |
plugin_apps_path_wrong_type |
apps는 루트의 .app.json을 가리키는 경로 문자열이어야 합니다. |
plugin_apps_path_empty |
apps를 지정하는 경우 루트의 .app.json을 가리키는 비어 있지 않은 경로여야 합니다. |
plugin_apps_path_unsupported |
apps 경로가 가리키는 파일은 루트의 .app.json이어야 합니다. |
plugin_apps_file_missing |
루트의 .app.json을 선언했다면 해당 파일이 있어야 합니다. |
plugin_apps_path_not_file |
루트의 .app.json을 선언했다면 해당 경로는 일반 파일이어야 합니다. |
plugin_mcp_path_wrong_type |
mcpServers는 루트의 .mcp.json을 가리키는 경로 문자열이어야 합니다. |
plugin_mcp_path_empty |
mcpServers는 비어 있지 않은 경로여야 합니다. 값을 ./.mcp.json으로 설정하거나 필드를 삭제하세요. |
plugin_mcp_path_unsupported |
mcpServers 경로가 가리키는 파일은 루트의 .mcp.json이어야 합니다. |
plugin_mcp_file_missing |
mcpServers에 루트의 .mcp.json이 선언되어 있지만 해당 파일이 없습니다. |
plugin_mcp_path_not_file |
루트의 .mcp.json은 일반 파일이어야 합니다. |
plugin_runtime_surface_missing |
공개 디렉터리에 제출하는 ZIP에는 유효한 스킬이 하나 이상 있거나 승인된 로컬 MCP 서버가 있어야 합니다. 로컬 패키지와 워크스페이스 패키지는 요건을 충족하는 MCP 서버를 참조할 수도 있습니다. |
MCP 매니페스트 오류
다음 오류는 호환성을 위한 .mcp.json 파일에 적용됩니다. 이식 가능한 패키지를 가져올 때는 이 파일과 .codex-plugin/plugin.json을 루트의 plugin.json과 mcp.json에서 생성합니다. 위의 구성 요소 경로 오류가 이렇게 생성된 파일을 가리킬 수도 있습니다. 이 경우 이식 가능한 패키지의 원본 구성을 수정하세요. 호환성 진단 메시지에 표시된 이름에 맞추려고 mcp.json의 이름을 .mcp.json으로 변경하지 마세요.
| 이름 | 요구 사항 |
|---|---|
mcp_manifest_unreadable |
.mcp.json은 읽을 수 있는 UTF-8 텍스트여야 합니다. |
mcp_manifest_json_malformed |
.mcp.json에는 유효한 JSON이 있어야 합니다. 구문 오류가 있으면 해당 줄 번호가 표시됩니다. |
mcp_manifest_wrong_type |
.mcp.json의 최상위 값은 JSON 객체여야 합니다. |
mcp_servers_missing |
.mcp.json의 최상위에 mcpServers 필드가 있어야 합니다. |
mcp_servers_wrong_type |
mcpServers는 객체여야 합니다. |
mcp_server_name_empty |
각 MCP 서버 이름에는 공백이 아닌 문자가 하나 이상 있어야 합니다. |
mcp_server_wrong_type |
각 mcpServers.<server-name> 값은 해당 서버의 선언을 담은 객체여야 합니다. |
스킬 오류
| 이름 | 요구 사항 |
|---|---|
skill_manifest_missing |
스킬에 SKILL.md 파일이 있어야 합니다. |
skill_bundle_too_large |
압축된 각 스킬 번들의 크기는 오류 메시지에 표시된 MiB 단위 제한 이하여야 합니다. |
skill_directory_hidden |
스킬 디렉터리 이름은 .으로 시작하면 안 됩니다. |
skill_manifest_nested |
각 스킬 디렉터리는 skills/ 바로 아래에 있어야 합니다. |
skill_manifest_not_regular_file |
SKILL.md는 일반 파일이어야 합니다. |
skill_manifest_unreadable |
SKILL.md는 읽을 수 있어야 합니다. |
skill_manifest_invalid_utf8 |
SKILL.md는 유효한 UTF-8로 인코딩되어야 합니다. |
skill_frontmatter_missing |
SKILL.md는 --- 줄 사이에 작성한 YAML 프런트매터로 시작해야 합니다. |
skill_frontmatter_unclosed |
SKILL.md의 YAML 프런트매터는 ---로 끝나야 합니다. |
skill_frontmatter_yaml_malformed |
SKILL.md의 프런트매터는 유효한 YAML이어야 합니다. |
skill_frontmatter_wrong_type |
SKILL.md의 프런트매터에는 YAML 매핑이 있어야 합니다. |
skill_name_missing |
name은 필수이며 비워 둘 수 없습니다. |
skill_name_wrong_type |
name은 문자열이어야 합니다. |
skill_name_empty |
name은 비워 둘 수 없습니다. |
skill_name_character_unsupported |
스킬 프런트매터의 name에는 지원되는 텍스트를 사용해야 합니다. |
skill_description_missing |
description은 필수이며 비워 둘 수 없습니다. |
skill_description_wrong_type |
description은 문자열이어야 합니다. |
skill_description_empty |
description은 비워 둘 수 없습니다. |
skill_description_too_long |
description은 1,024자 이하여야 합니다. |
skill_description_character_unsupported |
스킬 프런트매터의 description에는 지원되는 텍스트를 사용해야 합니다. |
skill_body_empty |
스킬 지침은 비워 둘 수 없습니다. |
skill_identity_too_long |
플러그인 이름과 스킬 이름을 결합한 값(plugin-name:skill-name)은 64자 이하여야 합니다. |
skill_identity_duplicate |
플러그인 안에서 각 스킬의 name은 서로 달라야 합니다. |
스킬 에이전트 메타데이터 오류
패키지에 포함된 스킬은 자체 interface를 skills/<skill>/agents/openai.yaml에 정의할 수 있습니다. 이 설정은 스킬이 사용자에게 어떻게 표시되는지 결정하며 플러그인 매니페스트의 interface와는 별개입니다. 스킬 인터페이스 필드 이름에는 snake_case를 사용합니다.
interface:
display_name: "Summarize documents"
short_description: "Summarize a document"
icon_small: "./assets/icon.png"
default_prompt: "Summarize the selected document."
| 이름 | 요구 사항 |
|---|---|
skill_agent_not_regular_file |
agents/openai.yaml은 일반 파일이어야 합니다. |
skill_agent_unreadable |
agents/openai.yaml은 읽을 수 있어야 합니다. |
skill_agent_invalid_utf8 |
agents/openai.yaml은 유효한 UTF-8로 인코딩되어야 합니다. |
skill_agent_yaml_malformed |
agents/openai.yaml에는 유효한 YAML이 있어야 합니다. |
skill_agent_top_level_wrong_type |
agents/openai.yaml의 최상위 값은 YAML 매핑이어야 합니다. |
skill_agent_interface_missing |
interface는 agents/openai.yaml 파일을 포함하는 경우 필수입니다. |
skill_agent_interface_wrong_type |
interface는 agents/openai.yaml에서 YAML 매핑으로 정의해야 합니다. |
skill_agent_display_name_missing |
interface.display_name은 필수이며 비워 둘 수 없습니다. |
skill_agent_display_name_wrong_type |
interface.display_name은 문자열이어야 합니다. |
skill_agent_display_name_empty |
interface.display_name은 비워 둘 수 없습니다. |
skill_agent_short_description_missing |
interface.short_description은 필수이며 비워 둘 수 없습니다. |
skill_agent_short_description_wrong_type |
interface.short_description은 문자열이어야 합니다. |
skill_agent_short_description_empty |
interface.short_description은 비워 둘 수 없습니다. |
skill_agent_icon_small_wrong_type |
interface.icon_small을 지정하는 경우 값은 비어 있지 않은 상대 파일 경로여야 합니다. |
skill_agent_icon_small_empty |
interface.icon_small을 지정하는 경우 assets/icon.png와 같이 비어 있지 않은 상대 파일 경로를 사용해야 합니다. |
skill_agent_icon_large_wrong_type |
interface.icon_large를 지정하는 경우 값은 비어 있지 않은 상대 파일 경로여야 합니다. |
skill_agent_icon_large_empty |
interface.icon_large를 지정하는 경우 assets/icon.png와 같이 비어 있지 않은 상대 파일 경로를 사용해야 합니다. |
skill_agent_brand_color_wrong_type |
interface.brand_color를 지정하는 경우 값은 문자열이어야 합니다. |
skill_agent_brand_color_empty |
interface.brand_color를 지정하는 경우 #1ABCFE와 같은 6자리 16진수 색상값을 사용해야 하며 비워 둘 수 없습니다. |
skill_agent_brand_color_format |
interface.brand_color는 #1ABCFE와 같은 6자리 16진수 색상값이어야 합니다. |
skill_agent_default_prompt_wrong_type |
interface.default_prompt를 지정하는 경우 값은 문자열이어야 합니다. |
skill_agent_default_prompt_empty |
interface.default_prompt를 지정하는 경우 값을 비워 둘 수 없습니다. |
skill_agent_policy_wrong_type |
policy를 지정하는 경우 값은 YAML 매핑이어야 합니다. |
skill_agent_allow_implicit_invocation_wrong_type |
policy에는 products와 allow_implicit_invocation만 포함할 수 있습니다. products에는 CHAT, CODEX 또는 둘 다 있어야 하며, allow_implicit_invocation은 true 또는 false여야 합니다. |
skill_agent_dependencies_wrong_type |
dependencies는 YAML 매핑이어야 하며 tools만 지원됩니다. |
skill_agent_dependency_unsupported |
dependencies.tools는 agents/openai.yaml에서 지원하는 유일한 종속성 필드입니다. |
에셋 경로 오류
| 이름 | 요구 사항 |
|---|---|
declared_asset_path_wrong_type |
오류에 표시된 에셋 필드의 값은 파일 경로 문자열이어야 합니다. |
declared_asset_path_empty |
오류에 표시된 에셋 필드는 비워 둘 수 없습니다. |
declared_asset_path_has_outer_whitespace |
오류에 표시된 에셋 필드 값의 앞뒤에 공백이 있으면 안 됩니다. |
declared_asset_path_has_control_character |
오류에 표시된 에셋 필드에는 U+0000~U+001F 범위의 문자나 U+007F 문자가 있으면 안 됩니다. |
branding_asset_path_missing_root_prefix |
오류에 표시된 에셋 필드의 값은 ./로 시작해야 합니다. |
declared_asset_path_unsafe |
오류에 표시된 에셋 필드의 값은 플러그인 내부의 상대 경로여야 합니다. 절대 경로, 드라이브 접두사, 상위 디렉터리로 이동하는 .. 구간을 포함하면 안 됩니다. |
declared_asset_path_outside_package |
오류에 표시된 에셋 필드는 플러그인 내부의 파일을 참조해야 합니다. |
declared_asset_file_missing |
오류에 표시된 에셋 필드가 참조하는 파일이 없습니다. |
declared_asset_not_regular_file |
오류에 표시된 에셋 필드는 일반 파일을 참조해야 합니다. 디렉터리나 특수 파일은 허용되지 않습니다. |
이미지 오류
디렉터리에 표시할 브랜드 이미지는 지원되는 파일 형식을 사용하고 아래의 파일 크기 및 이미지 치수 제한을 충족해야 합니다. 이 규칙은 패키지에 포함된 브랜드 에셋에 적용됩니다.
| 이름 | 요구 사항 |
|---|---|
plugin_logo_path_missing |
interface.logo는 필수이며 정사각형 이미지를 참조해야 합니다. |
plugin_composer_icon_path_missing |
interface.composerIcon은 필수이며 정사각형 이미지를 참조해야 합니다. |
image_file_unreadable |
이미지 파일을 읽을 수 있어야 합니다. |
image_file_too_large |
이미지 파일은 5 MiB 이하여야 합니다. |
image_file_format_unsupported |
이미지 파일 이름은 .png, .jpg, .jpeg, .webp, .svg 중 하나로 끝나야 합니다. |
raster_image_decode_failed |
래스터 이미지는 안전하게 디코딩할 수 있는 PNG, JPEG 또는 WebP 파일이어야 합니다. |
raster_image_extension_content_mismatch |
이미지 파일 확장자는 감지된 이미지 형식과 일치해야 합니다. |
raster_image_not_square |
이미지는 정사각형이어야 합니다. |
raster_image_dimensions_too_small |
이미지 크기는 48×48픽셀 이상이어야 합니다. |
raster_image_dimensions_too_large |
이미지 크기는 4,096×4,096픽셀 이하여야 합니다. |
svg_xml_malformed |
SVG에는 유효한 UTF-8 XML이 있어야 합니다. |
svg_root_element_invalid |
SVG의 루트 요소는 <svg>여야 합니다. |
svg_dimensions_missing |
SVG에는 숫자로 지정한 viewBox가 있거나 width와 height가 모두 숫자로 지정되어 있어야 합니다. |
svg_dimensions_not_numeric |
SVG 치수에는 단위나 백분율 없이 숫자만 사용해야 합니다. |
svg_dimensions_not_positive |
SVG의 너비와 높이는 유한한 양수여야 합니다. |
svg_dimensions_not_square |
SVG의 너비와 높이는 같아야 합니다. |
svg_dimensions_too_small |
SVG 크기는 48×48픽셀 이상이어야 합니다. |
MCP 서버 참조 오류
플러그인이 등록된 MCP 서버를 참조하면 공통 패키지 검사에서 .app.json을 검증합니다. 제출 포털에서는 기존 통합에 대한 참조를 게시하지 않습니다. 스킬 전용 옵션으로 업로드하면 .app.json이 제거됩니다. MCP 서버를 직접 제출하려면 MCP 포함 옵션을 사용하세요.
로컬 패키지와 워크스페이스 패키지에서는 최상위 apps 객체가 각 MCP 서버 별칭을 등록된 서버 항목에 매핑합니다. 이러한 구성 이름과 오류 코드에서는 app 표기를 그대로 사용합니다.
| 이름 | 요구 사항 |
|---|---|
app_manifest_unreadable |
.app.json은 읽을 수 있는 UTF-8 텍스트여야 합니다. |
app_manifest_json_malformed |
.app.json에서 보고된 줄 근처에 JSON 구문 오류가 있습니다. |
app_manifest_wrong_type |
.app.json의 최상위 값은 JSON 객체여야 합니다. |
app_entries_missing |
apps는 필수입니다. |
app_entries_wrong_type |
apps는 객체여야 합니다. |
app_entry_wrong_type |
각 서버 항목은 객체여야 합니다. |
app_id_missing |
각 서버 항목의 id는 필수입니다. |
app_id_wrong_type |
각 서버 항목의 id는 문자열이어야 합니다. |
app_id_format |
각 서버 항목의 id는 asdk_app_, connector_, templated_apps_ 중 하나로 시작해야 합니다. 바로 다음 문자는 영문자나 숫자여야 하며, 그 뒤에는 영문자, 숫자, _, -만 사용할 수 있습니다. |
app_entry_optional_wrong_type |
각 서버 항목에 optional을 지정하는 경우 값은 true 또는 false여야 합니다. |
app_entry_required_wrong_type |
각 서버 항목에 required를 지정하는 경우 값은 true 또는 false여야 합니다. |
app_not_eligible |
로컬 패키지와 워크스페이스 패키지는 요건을 충족하고 사용 가능한 MCP 서버를 참조해야 합니다. 디렉터리에 제출할 때는 MCP 포함 옵션으로 MCP 서버를 직접 제출해야 합니다. |
패키지 경고
다음 경고는 검증 과정에서 무시되거나 정규화되는 패키지 콘텐츠를 알려 줍니다. 경고가 있어도 제출할 수 있습니다. 경고 내용을 검토해 제출하는 플러그인에 의도한 파일과 설정이 포함되어 있는지 확인하세요.
| 이름 | 요구 사항 |
|---|---|
duplicate_app_reference |
.app.json에서는 각 서버 ID를 한 번씩만 참조해야 합니다. 중복 참조는 하나의 서버로 처리됩니다. |
undeclared_app_manifest_ignored |
루트의 .app.json은 플러그인 매니페스트의 apps 필드가 ./.app.json으로 설정된 경우에만 가져옵니다. |
undeclared_mcp_manifest_ignored |
루트의 .mcp.json은 플러그인 매니페스트의 mcpServers 필드가 ./.mcp.json으로 설정된 경우에만 가져옵니다. |
skill_file_ignored |
skills/ 바로 아래에 있는 파일은 스킬로 가져오지 않습니다. 각 스킬은 SKILL.md가 있는 디렉터리에 있어야 합니다. |
skill_symlink_ignored |
skills/ 바로 아래에 있는 심볼릭 링크는 스킬로 가져오지 않습니다. 각 스킬은 SKILL.md가 있는 실제 디렉터리여야 합니다. |
skill_frontmatter_adjusted |
스킬을 가져올 때 name과 description의 앞뒤 공백을 제거하고 내부의 연속된 공백을 하나로 줄입니다. |
skill_metadata_ignored |
스킬 인터페이스 설정에는 interface 매핑을 사용하며, 이 매핑은 agents/openai.yaml에 작성해야 합니다. metadata를 SKILL.md에 작성해도 인터페이스에는 적용되지 않습니다. |
다음 단계
검증 오류를 모두 해결한 후 플러그인 제출 페이지로 돌아가 제출을 완료하세요.