AI 해결 노트 · 2026-09-17 · 실측 2026-09-17

Claude Code 로컬 플러그인 만들고 불러오기 — claude plugin validate와 --plugin-dir 윈도우 실측

한 줄로

공식 문서의 빠른 시작대로 plugin.jsonSKILL.md 두 파일만 만들면 claude plugin validate✔ Validation passed를 냈습니다. --plugin-dir로 불러온 플러그인은 대화 세션을 열지 않아도 claude --plugin-dir <폴더> plugin listplugin details로 로드 여부를 볼 수 있었습니다. skills/.claude-plugin/ 안에 넣는 실수는 validate를 통과했지만, details에서 Skills (0)으로 드러났습니다.

이런 분께

마켓플레이스에 올리기 전에 내 PC에서 플러그인을 먼저 시험해 보고 싶은 분. plugin.json을 고쳤는데 플러그인이 안 뜨는 이유를 찾는 분. 사용자 설정에 설치하지 않고 이번 실행에만 플러그인을 불러오고 싶은 분.

실측 환경

항목
OSWindows 11 Home (10.0.26200)
Git Bash
Claude Code2.1.274 (Claude Code)
실험 폴더C:\Users\User\AppData\Local\Temp\longtail_B2\plugins
참고 문서code.claude.com/docs/en/plugins , code.claude.com/docs/en/plugins-reference , code.claude.com/docs/en/plugin-marketplaces (모두 2026-09-17 확인)

도움말에서 쓸 것 고르기

claude plugin --help에는 validate, details, list, init, install 등이 있습니다. 이번에 쓴 것과 쓰지 않은 것을 나눴습니다.

  validate [options] <path>            Validate a plugin or marketplace
                                       manifest, or the skills, agents, and
                                       commands in a directory
  details [options] <name>             Show a plugin's component inventory and
                                       projected token cost
  list [options]                       List installed plugins
  init|new [options] <name>            Scaffold a new plugin at
                                       ~/.claude/skills/<name>/ (auto-loads next
                                       session as <name>@skills-dir)

init은 도움말대로라면 사용자 폴더(~/.claude/skills/)에 파일을 만듭니다. 이번에는 initinstall을 쓰지 않고, 임시 폴더에 파일을 직접 작성했습니다. 불러오기에는 claude --help의 이 옵션을 썼습니다.

  --plugin-dir <path>                   Load a plugin from a directory or .zip
                                        for this session only; a folder of
                                        plugins loads each child (repeatable:
                                        --plugin-dir A --plugin-dir B.zip)

claude plugin validate --help의 옵션은 --json(Output the validation report as JSON (same exit codes))과 --strict(Treat warnings as errors (exit 1))입니다.

1단계 — 최소 플러그인 만들기

문서(plugins)의 빠른 시작 예시를 그대로 옮겼습니다. 구조는 이렇습니다.

my-first-plugin/
├── .claude-plugin/
│   └── plugin.json
└── skills/
    └── hello/
        └── SKILL.md
{
  "name": "my-first-plugin",
  "description": "A greeting plugin to learn the basics",
  "version": "1.0.0",
  "author": {
    "name": "Your Name"
  }
}
---
description: Greet the user with a friendly message
disable-model-invocation: true
---

Greet the user warmly and ask how you can help them today.

문서(plugins-reference)에는 "If you include a manifest, name is the only required field."라고 적혀 있습니다. 스킬 폴더 이름 hello가 스킬 이름이 되고, 플러그인 이름이 앞에 붙어 /my-first-plugin:hello가 된다고 설명합니다.

2단계 — claude plugin validate

$ claude plugin validate ./my-first-plugin
Validating plugin manifest: C:\Users\User\AppData\Local\Temp\longtail_B2\plugins\my-first-plugin\.claude-plugin\plugin.json

✔ Validation passed

종료 코드는 0이었고, --strict를 붙여도 같았습니다. --json으로 받으면 이렇습니다.

{
  "success": true,
  "strict": false,
  "target": "C:\\Users\\User\\AppData\\Local\\Temp\\longtail_B2\\plugins\\my-first-plugin\\.claude-plugin\\plugin.json",
  "manifest": {
    "file": "C:\\Users\\User\\AppData\\Local\\Temp\\longtail_B2\\plugins\\my-first-plugin\\.claude-plugin\\plugin.json",
    "type": "plugin",
    "errors": [],
    "warnings": [],
    "notes": []
  },
  "contents": []
}

3단계 — 일부러 고장 낸 플러그인 검증

검증용 플러그인을 몇 개 더 만들었습니다. 대부분 정상 플러그인에서 한 군데만 바꿨고, noname-plugin은 plugin.json"description": "no name field"만 넣었습니다.

폴더바꾼 것validate 결과종료 코드
typo-plugindescriptiondescripton으로 오타⚠ Found 2 warnings✔ Validation passed with warnings0
typo-plugin + --strict같음✘ Validation failed (--strict treats warnings as errors)1
badtype-plugin"keywords": "greeting" (배열 자리에 문자열)❯ keywords: Invalid input✘ Validation failed1
noname-pluginname 없이 description만 있음❯ name: Invalid input✘ Validation failed1
wrongdir-pluginskills/.claude-plugin/ 안에 둠✔ Validation passed0
badskill-plugin (1차)SKILL.mddescription: [unclosed✔ Validation passed0
badskill-plugin (2차)SKILL.md 머리말을 더 망가뜨리고 agents/broken.md 추가✘ Validation failed1
no-such-dir없는 경로❯ file: File not found: ...✘ Validation failed1

오타 경고 문구는 이랬습니다.

  ❯ descripton: Unknown field 'descripton' — did you mean 'description'? Claude Code ignores unrecognized fields at load time, so this field has no effect.
  ❯ description: No description provided. Adding a description helps users understand what your plugin does

badskill-plugin 2차의 SKILL.md 머리말은 description: "unterminated로 따옴표를 닫지 않고, 들여쓰기가 어긋난 줄과 탭 줄을 넣은 것입니다. 결과는 이랬습니다.

Validating skill: C:\...\badskill-plugin\skills\hello\SKILL.md

✘ Found 1 error:

  ❯ frontmatter: YAML frontmatter failed to parse: YAML Parse error: Unexpected EOF. At runtime this skill loads with empty metadata (all frontmatter fields silently dropped).

Validating agent: C:\...\badskill-plugin\agents\broken.md

⚠ Found 1 warning:

  ❯ description: No description in frontmatter. A description helps users and Claude understand when to use this agent.

눈여겨볼 점이 세 가지 있었습니다.

스킬 폴더만 따로 검증하는 방법도 문서(plugin-marketplaces)에 있습니다. claude plugin validate ./badskill-plugin/skillsValidating components in: ... 뒤에 같은 frontmatter 오류를 내고 종료 코드 1이었습니다.

4단계 — --plugin-dir로 불렀을 때 실제로 로드됐나

문서의 테스트 방법은 claude --plugin-dir ./my-first-plugin으로 대화 세션을 여는 것입니다. 이번에는 대화 세션을 열지 않고, --plugin-dirplugin list·plugin details와 함께 줬습니다.

claude --plugin-dir ./my-first-plugin plugin list | grep -n -A4 'my-first-plugin'
300:  ❯ my-first-plugin@inline
301-    Version: 1.0.0
302:    Path: C:\Users\User\AppData\Local\Temp\longtail_B2\plugins\my-first-plugin
303-    Status: ✔ loaded

--json으로 받으면 "id": "my-first-plugin@inline", "scope": "session", "enabled": true였습니다. --plugin-dir 없이 claude plugin list --json을 돌리면 my-first-plugin은 0건이었습니다.

$ claude --plugin-dir ./my-first-plugin plugin details my-first-plugin
my-first-plugin 1.0.0
  Description: A greeting plugin to learn the basics
  Source: my-first-plugin@inline

Component inventory
  Skills (1)  hello
  Agents (0)
  Hooks (0)
  MCP servers (0)
  LSP servers (0)

Projected token cost
  Always-on:   ~27 tok   added to every session

--plugin-dir 없이 claude plugin details my-first-plugin을 치면 `Plugin "my-first-plugin" not found. Run claude plugin list to see installed plugins, or pass --plugin-dir <path> to load one from disk.`와 함께 종료 코드 1이었습니다.

고장 낸 플러그인들도 같은 방법으로 봤습니다.

폴더plugin list(--plugin-dir)plugin details
wrongdir-plugin(개별로는 보지 않음)Skills (0), Always-on: ~0 tok
badtype-plugin✘ Failed to load plugin: Plugin badtype-plugin has an invalid manifest file at ... Validation errors: keywords: Invalid inputnot found, 종료 코드 1
badskill-plugin (2차)(폴더 전체 로드에서) ✔ loadedSkills (1) hello, Agents (1) broken

wrongdir-plugin은 validate를 통과하고 로드도 됐지만 스킬이 0개였습니다. badskill-plugin은 머리말 파싱 오류가 있어도 스킬이 목록에 올라왔습니다. validate의 오류 문구대로라면 이 스킬은 머리말 값이 빠진 채로 로드됩니다.

5단계 — 플러그인 여러 개를 폴더째로

--plugin-dir에 플러그인들을 담은 상위 폴더를 주면 하위 폴더를 각각 불러온다고 도움말에 적혀 있습니다. 문서(plugins)는 이 기능에 v2.1.265 이상이 필요하다고 합니다.

claude --plugin-dir . plugin list | grep -n 'inline'
300:  ❯ badskill-plugin@inline
305:  ❯ my-first-plugin@inline
310:  ❯ typo-plugin@inline
315:  ❯ wrongdir-plugin@inline
320:  ❯ inline[1]: ✘ Failed to load plugin: Plugin badtype-plugin has an invalid manifest file at ...\badtype-plugin\.claude-plugin\plugin.json. Validation errors: keywords: Invalid input
322:  ❯ inline[3]: ✘ Failed to load plugin: Plugin noname-plugin has an invalid manifest file at ...\noname-plugin\.claude-plugin\plugin.json. Validation errors: name: Invalid input

validate에서 오류(종료 코드 1)였던 두 개는 로드에 실패했고, 경고만 있던 typo-plugin은 로드됐습니다. 문서의 "A plugin with only unrecognized-field warnings still passes validation and loads at runtime."과 같은 결과입니다.

결과

확인명령결과
정상 플러그인 검증claude plugin validate ./my-first-plugin✔ Validation passed, 종료 코드 0
오류가 있는 manifestvalidate (keywords 타입, name 누락)✘ Validation failed, 종료 코드 1
경고만 있는 manifestvalidate / validate --strict0 / 1
구조 실수(.claude-plugin/skills)validatedetails통과 → Skills (0)
로드 확인claude --plugin-dir <폴더> plugin list@inline, Status: ✔ loaded
로드 실패 확인같음✘ Failed to load plugin: ...
사용자 설정 흔적~/.claude.json, ~/.claude/settings.json, installed_plugins.json 문자열 건수모두 0건

실패한 것

validate로 머리말 오류를 잡으려던 첫 시도(description: [unclosed)는 오류로 잡히지 않았습니다. 따옴표를 닫지 않은 두 번째 파일에서야 YAML frontmatter failed to parse가 나왔습니다.

확인하지 않은 것

함께 보기