지식위키

Claude Code · 플러그인/마켓플레이스와 OMC 팀·브리지

Claude Code · 플러그인/마켓플레이스와 OMC 팀·브리지

한 줄 요약

플러그인은 skill·agent·hook·MCP 같은 낱개 확장을 한 폴더로 묶어 “설치 가능한 한 덩어리”로 만든 포장 형식이고, OMC는 그 위에 여러 AI를 동시에 부리는 공장을 얹은 플러그인이다. 왜 배우나: 내 기능을 남에게 배포·버전관리하는 법과, 한 대가 아니라 여러 AI를 팀으로 굴리는 구조가 어떻게 가능한지 이해하기 위해서다.


그림

플러그인이 설치되어 디스크에 영속화되고, 그 위에 OMC 팀 런타임이 도는 전체 구조다.

flowchart TD
  subgraph CORE["코어: 포장과 보관"]
    MKT["마켓플레이스 카탈로그<br/>(marketplace.json = 상품 목록)"]
    PLG["플러그인 한 덩어리<br/>(plugin.json + skills/agents/hooks/MCP)"]
    CACHE["설치 캐시<br/>~/.claude/plugins/cache/버전별"]
    REC["영속 장부 두 장<br/>installed_plugins.json<br/>known_marketplaces.json"]
    MKT -->|install| PLG
    PLG -->|소스 복사| CACHE
    CACHE -->|기록| REC
  end
  subgraph OMC["OMC: 멀티에이전트 공장"]
    MCP["MCP 서버 t<br/>(팀 시작 도구)"]
    WORKER["워커들<br/>(tmux 패널마다 claude/codex/gemini)"]
    DISK["파일시스템 칠판<br/>.omc/state/team/<팀>"]
    MCP -->|팀 시작| WORKER
    WORKER -->|결과 기록| DISK
    DISK -->|상태 읽기| WORKER
  end
  PLG -.->|OMC도 평범한 플러그인 하나| MCP

쉽게 풀기

1단계 — 낱개를 한 봉투에 (플러그인). skill·agent·hook·MCP·LSP 등은 원래 흩어진 낱개 파일이라 남에게 주려면 일일이 위치를 설명해야 한다. 플러그인은 이걸 한 폴더로 묶고 plugin.json이라는 이름표를 붙인 것이다. 이사 박스에 “주방용품”이라 써 붙이듯, 이름표 하나로 통째로 옮기고 열고 버린다.

2단계 — 박스들의 목록표 (마켓플레이스). marketplace.json은 플러그인 박스들의 카탈로그다. 백화점 안내판처럼 “어디에 무슨 물건이 있는지”만 보여준다. claude plugin install foo@bar 하면 카탈로그를 보고 → 실제 소스(깃허브/로컬/npm)를 받아서 → 보관함(~/.claude/plugins/cache)에 버전별로 복사한다.

flowchart LR
  U["사용자<br/>install foo@bar"] --> C["카탈로그 조회<br/>marketplace.json"]
  C --> S["소스 fetch<br/>github/로컬/npm"]
  S --> K["버전별 캐시 복사<br/>cache/<마켓>/<플러그인>/<버전>"]
  K --> L["장부 기록<br/>installed+known"]

3단계 — 무엇을 깔았는지 적어 둔다 (영속성). 설치가 끝나면 두 장부에 남긴다. installed_plugins.json(무엇을 어디에) + known_marketplaces.json(어떤 카탈로그를 등록). 덕분에 세션을 껐다 켜거나 재부팅해도 깔아 둔 게 그대로 뜬다. 이게 영속성이다.

3.5단계 — 박스 안의 물건만 실제로 쓰인다. 플러그인 자체는 AI에게 말을 걸지 않는다. 봉투일 뿐이고, 모델이 실제로 소비하는 건 안의 컴포넌트(skill·agent·hook·MCP 도구)다. 봉투는 이것들을 한꺼번에 켜고/끄고/버전 올리기 좋게 묶을 뿐이다. (그래서 플러그인 루트의 CLAUDE.md는 컨텍스트로 안 실린다. 지시를 넣으려면 skill로 만들어야 한다.)

4단계 — 그 위에 공장을 얹는다 (OMC). oh-my-claudecode(OMC)는 겉보기엔 평범한 플러그인이지만 안에 여러 AI를 동시에 부리는 런타임을 넣어 뒀다. t라는 MCP 서버를 띄우고, “팀 시작” 도구를 호출하면 tmux 패널마다 claude/codex/gemini CLI를 워커로 띄운다. 워커들은 서로 대화하지 않는다. 대신 파일시스템이라는 공용 칠판(.omc/state/team/...)에 “할 일 목록”과 “공유 메모리”를 적어 두고, 각자 칠판을 보며 일을 나눠 갖는다.

[!note] 비유로 정리

  • 플러그인 = 라벨 붙인 이사 박스 (낱개를 한 단위로 운반)
  • 마켓플레이스 = 백화점 안내판 (어디서 받을지 알려주는 목록)
  • 영속 장부 = 창고 입출고 대장 (껐다 켜도 기억)
  • OMC = 그 박스에 실려 온 작은 공장 (여러 AI가 칠판을 보며 협업) 핵심: 코어는 포장과 보관까지만, 멀티에이전트 협업은 그 위에 별도 레이어로 얹는다.

핵심 정리

plugin.json (.claude-plugin/plugin.json)

name만 필수다. 매니페스트 자체가 선택이라, 없으면 기본 폴더(skills/·agents/·hooks/·.mcp.json)를 자동 발견하고 폴더명을 플러그인명으로 쓴다.

필드필수핵심
name식별자. kebab-case, 네임스페이스에 쓰임(plugin-dev:agent-creator)
versionsemver. 캐시 키 → 올려야 업데이트 배포. 생략 시 git SHA 폴백
그 외defaultEnabled·userConfig 등 (아래 펼쳐보기)

[!note]- 펼쳐보기: 전체 필드와 변수 컴포넌트 지정 — “더함 vs 대체” 함정

  • skills → 기본 skills/더한다
  • commands/agents/outputStyles → 기본 폴더를 대체한다
  • hooks/mcpServers/lspServers → 경로 또는 인라인 객체 둘 다 가능

그 외 선택 필드: defaultEnabled(기본 true), userConfig(enable 시 사용자에게 물을 값, ${user_config.KEY}로 치환), displayName(v2.1.143+), author, homepage, repository, license, keywords, channels, dependencies.

변수 세 개 — 어디에 무엇을 저장할지

  • ${CLAUDE_PLUGIN_ROOT} = 설치 위치. 업데이트 시 바뀜 → 상태 저장 금지
  • ${CLAUDE_PLUGIN_DATA} = ~/.claude/plugins/data/{id}/. 업데이트에도 살아남는 영속 폴더
  • ${CLAUDE_PROJECT_DIR} = 프로젝트 루트

marketplace.json (.claude-plugin/marketplace.json)

필드필수핵심
name카탈로그 식별자(@name). 사용자당 같은 이름 하나(덮어씀)
owner{name 필수, email?}
plugins엔트리 목록(엔트리는 name+source 필수)

[!note]- 펼쳐보기: source 다섯 종류와 strict

  • 상대경로 "./plugins/foo"./로 시작, .. 금지
  • githubrepo, ref?, sha?
  • urlurl, ref?, sha? (GitLab 등 git URL)
  • git-subdirurl, path, ref?, sha? (모노레포 sparse clone)
  • npmpackage, version?, registry?

strict(기본 true): true면 plugin.json이 권위·마켓 엔트리는 보충, false면 마켓 엔트리가 전체 정의.

영속성은 세 곳으로 분리된다

flowchart TD
  I["설치 기록<br/>installed_plugins.json<br/>(무엇을 어디에)"]
  K["카탈로그 등록<br/>known_marketplaces.json<br/>(사용자당 1회)"]
  E["켜짐 상태(enable)<br/>settings.json<br/>(스코프별)"]
  S["실제 소스<br/>cache/<마켓>/<플러그인>/<버전>"]
  I --- K --- E --- S

체크리스트: 설치 기록·카탈로그 등록·enable 상태·실제 소스 캐시 — 네 개가 따로 산다. 특히 설치와 enable은 별개 파일이다.

OMC 팀 워커의 영속 상태 경로 (모두 .omc/state/team/<팀>/ 아래)

경로용도
tasks/<id>.json (+.lock, .failure.json)공유 태스크·클레임 락·실패 사이드카
workers/<w>/inbox·outbox·heartbeat·status워커 메일박스/하트비트
shared-memory / logs/team-bridge-<팀>.jsonl공유 메모리 / 감사 로그

실제 예시

최소 마켓플레이스 + 플러그인 (복붙용)

my-marketplace/
├── .claude-plugin/marketplace.json
└── plugins/my-tool/
    ├── .claude-plugin/plugin.json
    ├── skills/greet/SKILL.md
    └── hooks/hooks.json          # 선택
// marketplace.json
{ "name": "my-plugins", "owner": { "name": "Your Name" },
  "plugins": [ { "name": "my-tool", "source": "./plugins/my-tool", "description": "데모 도구" } ] }
// plugins/my-tool/.claude-plugin/plugin.json
{ "name": "my-tool", "version": "0.1.0", "description": "데모 도구" }
claude plugin validate ./my-marketplace   # 스키마/중복/경로 검사
/plugin marketplace add ./my-marketplace
/plugin install my-tool@my-plugins
/my-tool:greet                            # 네임스페이스: <plugin>:<skill>

[!note]- 펼쳐보기: 실제 Anthropic 번들 + 영속 장부 디스크 상태 번들 마켓플레이스/플러그인 (최소 plugin.json의 모범)

// harness-work/claude-code/.claude-plugin/marketplace.json
{
  "$schema": "https://json.schemastore.org/claude-code-marketplace.json",
  "name": "claude-code-plugins",
  "owner": { "name": "Anthropic", "email": "support@anthropic.com" },
  "plugins": [
    { "name": "hookify", "description": "Easily create custom hooks...",
      "version": "0.1.0", "source": "./plugins/hookify", "category": "productivity" }
    // agent-sdk-dev, code-review, plugin-dev, ralph-wiggum, security-guidance ...
  ]
}
// plugins/hookify/.claude-plugin/plugin.json
{ "name": "hookify", "version": "0.1.0",
  "description": "Easily create hooks to prevent unwanted behaviors...",
  "author": { "name": "Daisy Hollman", "email": "daisy@anthropic.com" } }

주목: hookify엔 hooks 필드가 없다hooks/ 폴더 자동발견에 맡김. strict:true 기본이라 마켓 엔트리의 description은 보충일 뿐.

영속 장부 두 장 (실제 디스크)

// ~/.claude/plugins/installed_plugins.json — "무엇을 어디에"
{ "version": 2, "plugins": {
  "oh-my-claudecode@omc": [ {
    "scope": "user",
    "installPath": "~/.claude/plugins/cache/omc/oh-my-claudecode/4.14.6",
    "version": "4.14.6", "installedAt": "2026-06-10T04:03:46.951Z",
    "gitCommitSha": "deee3a446dadc9bfea31cdc8b19b00b16718082e" } ],
  "dd@gptaku-plugins": [ { "scope": "user", "version": "0.2.1" } ] } }
// ~/.claude/plugins/known_marketplaces.json — "어떤 카탈로그를 등록"
{ "omc": {
  "source": { "source": "git", "url": "https://github.com/Yeachan-Heo/oh-my-claudecode.git" },
  "installLocation": "~/.claude/plugins/marketplaces/omc",
  "lastUpdated": "2026-06-10T04:03:26.437Z" } }

OMC가 MCP 서버 하나로 멀티에이전트의 문을 여는 법

코어가 보기엔 그냥 MCP 도구 하나지만, 그 도구가 호출되면 코어 바깥 tmux에서 워커들이 떠 파일시스템으로 협업한다.

sequenceDiagram
  participant CC as Claude Code(코어)
  participant T as MCP 서버 t
  participant TX as tmux 패널
  participant FS as 파일시스템 칠판
  CC->>T: team_start(agentTypes, tasks, cwd)
  T->>TX: 패널마다 워커 기동(claude/codex/gemini)
  TX->>FS: tasks 클레임(.lock O_EXCL)·결과 기록
  FS-->>TX: 남은 태스크·공유 메모리 읽기
  Note over TX,FS: 완료 또는 cleanup까지 워커 생존

[!note]- 펼쳐보기: 브리지 코드 전문(MCP 등록·스키마·CLI 기동)

// marketplaces/omc/.mcp.json
{ "mcpServers": { "t": { "command": "node",
  "args": ["${CLAUDE_PLUGIN_ROOT}/bridge/mcp-server.cjs"] } } }
// bridge/team-mcp.cjs (startSchema) — 팀 시작 도구의 입력 스키마
var startSchema = external_exports.object({
  teamName: ...string().describe('Slug name (e.g. "auth-review")'),
  agentTypes: ...array(...string()).describe('"claude" | "codex" | "gemini"'),
  tasks: ...array(...object({ subject: ...string(), description: ...string() }))
           .describe("Tasks to distribute to workers"),
  cwd: ...string().describe("Working directory (absolute path)"),
  newWindow: ...boolean().optional()  // 전용 tmux 윈도우 vs 현재 분할
});
// bridge/team-bridge.cjs (spawnCliProcess) — 외부 CLI 기동
if (provider === "codex") {
  cmd = "codex";
  args = ["exec", "-m", model || "gpt-5.3-codex", "--json",
          "--dangerously-bypass-approvals-and-sandbox", "--skip-git-repo-check"];
} else {
  cmd = "gemini"; args = ["--approval-mode", "yolo"];
  if (model) args.push("--model", model);
}
const child = spawn(cmd, args, { stdio: ["pipe","pipe","pipe"], cwd });
child.stdin?.write(prompt); child.stdin?.end();   // 프롬프트는 stdin으로

[!warning] 보안 게이트 (남의 팀 런타임을 흉내 낼 때 필수) 브리지는 --config <path>로만 기동되고, validateConfigPath가 경로를 ~/.claude/·~/.omc/ 하위로 강제한다. workingDirectory도 홈 하위 + git 워크트리 내부여야 한다. 태스크 본문은 sanitizePromptContent<system-reminder> 류 주입 태그를 무력화한 뒤 넣는다(프롬프트 인젝션 방어).

[!note]- 펼쳐보기: 멀티에이전트 런타임을 직접 얹는 5단계 (OMC 패턴 모방)

  1. plugin.jsonmcpServers로 stdio MCP 서버 등록(${CLAUDE_PLUGIN_ROOT}/server.js).
  2. 그 서버에 team_start(agentTypes, tasks, cwd) 류 도구 노출.
  3. 도구가 tmux를 new-session/split 하고, 각 패널 워커를 --config <state/config.json>로 기동.
  4. 통신·영속은 파일시스템으로: tasks/<id>.json(+.lock O_EXCL), outbox.jsonl, heartbeat.json, shared-memory/.
  5. 외부 CLI(codex/gemini)는 stdin으로 프롬프트 주입, stdout을 outputs/*.md에 기록.

요약 & 셀프체크

3줄 요약:

  1. 플러그인은 낱개 확장을 한 폴더+이름표로 묶은 포장, 마켓플레이스는 그 박스들의 카탈로그다.
  2. Claude Code는 설치한 것을 installed_plugins.json·known_marketplaces.json 두 장부에 기록해 꺼져도 기억한다(영속성). 단 모델이 소비하는 건 봉투가 아니라 안의 컴포넌트다.
  3. OMC는 평범한 플러그인이지만 MCP 서버 t로 멀티에이전트 런타임을 얹어, tmux 워커들이 파일시스템 칠판으로 태스크를 나눈다 — 통신 매체가 컨텍스트가 아니라 디스크라서 재개가 가능하다.

스스로 답해 보기:

  • Q1. 플러그인 폴더에 CLAUDE.md를 넣으면 모델 컨텍스트에 실릴까? (왜?)
  • Q2. version을 생략하면 무슨 일이 일어나고, 안정 배포 시 왜 매 릴리스마다 올려야 하나?
  • Q3. OMC 워커들은 서로 어떻게 일을 나누고 진척을 공유하나? 세션이 죽어도 이어서 할 수 있는 이유는?

연결

CC_개요 · _분석축_루브릭 · CC_40_skills · CC_60_subagents · CC_70_mcp-and-tools · CC_80_guardrails

[!tip]- Codex 교차검증 (원문 분석 시점 보존)

  • hookify엔 hooks 필드가 없고 hooks/ 자동발견에 맡김 — strict:true 기본이라 마켓 엔트리 description은 보충일 뿐 확인됨.
  • 설치(installed_plugins.json)와 enable(settings.json) 분리, cache/<마켓>/<플러그인>/<버전>/ 버전별 복사 구조 확인됨.
  • OMC 팀은 코어가 보기엔 MCP 도구일 뿐, 진짜 멀티에이전트는 코어 바깥 tmux 자식 프로세스에서 돌고 통신 매체가 파일시스템 — 워커는 완료 또는 명시적 omc_run_team_cleanup까지 살며 타임아웃은 wait 호출에만 적용됨.
  • 근거 파일: _원문아카이브/claude-code/plugins-reference.md, plugin-marketplaces.md, harness-work/claude-code/.claude-plugin/marketplace.json, plugins/hookify/.claude-plugin/plugin.json, ~/.claude/plugins/installed_plugins.json, known_marketplaces.json, marketplaces/omc/.claude-plugin/plugin.json+/.mcp.json, omc/bridge/team-bridge.cjs, team-mcp.cjs, omc/CLAUDE.md.