SpyBara
Go Premium

plugins/components.md 2026-09-24 22:57 UTC to 2026-09-25 23:58 UTC

This page contains 1130 additions and 0 deletions.

2026
Fri 25 23:58

Tambahkan komponen ke plugin

Tambahkan skills, hooks, server MCP, dan setiap jenis komponen lainnya ke plugin Claude Code, dengan contoh yang memvalidasi untuk masing-masing.

export const Piece = ({id, children}) =>

{children}
;

export const PluginExplorer = ({children}) => { const PIECES = [{ id: 'manifest', name: 'Manifest', path: '.claude-plugin/plugin.json', required: "Required by Anthropic's directory", lines: [{ depth: 0, kind: 'folder', text: '.claude-plugin/' }, { depth: 1, kind: 'file', text: 'plugin.json' }], href: '/en/plugins/manifest-reference#manifest-file', linkText: 'Go to the manifest reference' }, { id: 'skills', name: 'Skills', path: 'skills/review/SKILL.md', lines: [{ depth: 0, kind: 'folder', text: 'skills/' }, { depth: 1, kind: 'folder', text: 'review/' }, { depth: 2, kind: 'file', text: 'SKILL.md' }], href: '/en/plugins/components#skills', linkText: 'Go to the Skills section' }, { id: 'commands', name: 'Commands', path: 'commands/about.md', lines: [{ depth: 0, kind: 'folder', text: 'commands/' }, { depth: 1, kind: 'file', text: 'about.md' }], href: '/en/plugins/components#commands', linkText: 'Go to the Commands section' }, { id: 'agents', name: 'Agents', path: 'agents/security-reviewer.md', lines: [{ depth: 0, kind: 'folder', text: 'agents/' }, { depth: 1, kind: 'file', text: 'security-reviewer.md' }], href: '/en/plugins/components#agents', linkText: 'Go to the Agents section' }, { id: 'hooks', name: 'Hooks', path: 'hooks/hooks.json', lines: [{ depth: 0, kind: 'folder', text: 'hooks/' }, { depth: 1, kind: 'file', text: 'hooks.json' }], href: '/en/plugins/components#hooks', linkText: 'Go to the Hooks section' }, { id: 'monitors', name: 'Monitors', path: 'monitors/monitors.json', lines: [{ depth: 0, kind: 'folder', text: 'monitors/' }, { depth: 1, kind: 'file', text: 'monitors.json' }], href: '/en/plugins/components#monitors', linkText: 'Go to the Monitors section' }, { id: 'output-styles', name: 'Output styles', path: 'output-styles/terse.md', lines: [{ depth: 0, kind: 'folder', text: 'output-styles/' }, { depth: 1, kind: 'file', text: 'terse.md' }], href: '/en/plugins/components#themes-and-output-styles', linkText: 'Go to the Themes and output styles section' }, { id: 'themes', name: 'Themes', path: 'themes/dracula.json', lines: [{ depth: 0, kind: 'folder', text: 'themes/' }, { depth: 1, kind: 'file', text: 'dracula.json' }], href: '/en/plugins/components#themes-and-output-styles', linkText: 'Go to the Themes and output styles section' }, { id: 'workflows', name: 'Workflows', path: 'workflows/audit-routes.js', lines: [{ depth: 0, kind: 'folder', text: 'workflows/' }, { depth: 1, kind: 'file', text: 'audit-routes.js' }], href: '/en/workflows#distribute-a-workflow-in-a-plugin', linkText: 'Go to Distribute a workflow in a plugin' }, { id: 'bin', name: 'Executables', path: 'bin/hello-plugin', lines: [{ depth: 0, kind: 'folder', text: 'bin/' }, { depth: 1, kind: 'file', text: 'hello-plugin' }], href: '/en/plugins/components#executables', linkText: 'Go to the Executables section' }, { id: 'scripts', name: 'Scripts', path: 'scripts/format.sh', lines: [{ depth: 0, kind: 'folder', text: 'scripts/' }, { depth: 1, kind: 'file', text: 'format.sh' }], href: '/en/plugins/components#hooks', linkText: 'Go to the Hooks section' }, { id: 'settings', name: 'Default settings', path: 'settings.json', lines: [{ depth: 0, kind: 'file', text: 'settings.json' }], href: '/en/plugins/components#default-settings', linkText: 'Go to the Default settings section' }, { id: 'mcp', name: 'MCP servers', path: '.mcp.json', lines: [{ depth: 0, kind: 'file', text: '.mcp.json' }], href: '/en/plugins/components#mcp-servers', linkText: 'Go to the MCP servers section' }, { id: 'lsp', name: 'LSP servers', path: '.lsp.json', lines: [{ depth: 0, kind: 'file', text: '.lsp.json' }], href: '/en/plugins/components#lsp-servers', linkText: 'Go to the LSP servers section' }]; const [selectedId, setSelectedId] = useState('manifest'); const [isFullscreen, setIsFullscreen] = useState(false); const rootRef = useRef(null); useEffect(() => { const onFsChange = () => setIsFullscreen(!!document.fullscreenElement); document.addEventListener('fullscreenchange', onFsChange); return () => document.removeEventListener('fullscreenchange', onFsChange); }, []); const toggleFullscreen = () => { if (!rootRef.current) return; if (document.fullscreenElement) document.exitFullscreen(); else rootRef.current.requestFullscreen().catch(() => {}); }; const selected = PIECES.find(p => p.id === selectedId) || PIECES[0]; const onTreeKeyDown = e => { const keys = ['ArrowDown', 'ArrowUp', 'Home', 'End']; if (keys.indexOf(e.key) === -1) return; const i = PIECES.findIndex(p => p.id === selectedId); let next = i; if (e.key === 'ArrowDown') next = Math.min(PIECES.length - 1, i + 1); if (e.key === 'ArrowUp') next = Math.max(0, i - 1); if (e.key === 'Home') next = 0; if (e.key === 'End') next = PIECES.length - 1; e.preventDefault(); if (next === i) return; const id = PIECES[next].id; setSelectedId(id); const el = document.getElementById('pe-node-' + id); if (el) el.focus(); }; const FolderIcon = () => ; const FileIcon = () => ; return <div ref={rootRef} className={isFullscreen ? 'pe-root pe-fullscreen not-prose' : 'pe-root not-prose'} data-selected={selected.id}>

  <div className="pe-head">
    <div className="pe-head-text">
      <div className="pe-title">What goes in a plugin</div>
      <div className="pe-sub">This example plugin, <code>my-plugin</code>, has one of every kind of component, each in its default location. Select a file or folder to read what it’s for and see what goes in it.</div>
    </div>
    <button type="button" className="pe-fs-btn" onClick={toggleFullscreen} aria-label={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'} title={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}>
      {isFullscreen ? '⤡' : '⛶'}
    </button>
  </div>

  <div className="pe-body">
    <div className="pe-tree-pane">
      <div className="pe-caption" id="pe-tree-caption">Plugin directory</div>
      <div role="group" aria-labelledby="pe-tree-caption" onKeyDown={onTreeKeyDown}>
        <div className="pe-rootline"><FolderIcon /><span>my-plugin/</span></div>
        {PIECES.map(p => <button key={p.id} id={'pe-node-' + p.id} type="button" className="pe-node" aria-pressed={p.id === selected.id} aria-label={p.name + ', ' + p.path} onClick={() => setSelectedId(p.id)}>
            {p.lines.map((line, i) => <span key={i} className="pe-line pe-line-tree" style={{
paddingLeft: line.depth * 18 + 'px'

}}> {line.kind === 'folder' ? : } {line.text} {p.required && i === p.lines.length - 1 ? {p.required} : null} )} {p.path} {p.required ? {p.required} : null} )}

    <div className="pe-panel" role="region" aria-labelledby="pe-panel-caption" aria-live="polite" aria-atomic="true">
      <div className="pe-caption" id="pe-panel-caption">Selected piece</div>
      <div className="pe-name">{selected.name}{selected.required ? <span className="pe-req">{selected.required}</span> : null}</div>
      <div className="pe-path">{selected.path}</div>

      <div className="pe-block">{children}</div>

      <a className="pe-link" href={selected.href}>{selected.linkText}</a>
    </div>
  </div>
</div>;

};

Plugin Claude Code dibangun dari komponen, seperti skills, agents, hooks, dan server MCP. Setiap komponen memiliki folder default di plugin, kunci manifest opsional di .claude-plugin/plugin.json yang menggantikan atau menambah folder tersebut, dan nama yang dilihat pengguna. Untuk tabel bidang lengkap setiap kunci, lihat referensi manifest.

Gunakan halaman ini untuk menambahkan komponen ke plugin yang sudah dimuat.

Setelah Anda menambahkan komponen, jalankan /reload-plugins dalam sesi yang sedang berjalan atau mulai sesi baru sehingga Claude Code memuatnya. Untuk memeriksa file komponen sebelum memuatnya, jalankan claude plugin validate . di shell Anda dari direktori plugin.

Jelajahi direktori plugin

Explorer menunjukkan plugin contoh, my-plugin, yang memiliki satu dari setiap jenis komponen di lokasi defaultnya:

Setiap file adalah contoh valid terkecil dari formatnya, ada untuk menunjukkan bentuknya daripada untuk berguna: skill atau agent nyata membawa instruksi lengkap dan sering kali file pendukung, dan hook atau monitor nyata melakukan pekerjaan nyata. Bagian setelah explorer menggunakan file yang sama sebagai contoh mereka dan menautkan ke yang lebih lengkap. Pilih file atau folder untuk membaca tujuannya, lihat apa yang ada di dalamnya, dan temukan bagian yang mencakupnya.

[Manifest](/docs/id/plugins/manifest-reference) adalah file `plugin.json` di direktori `.claude-plugin/` plugin. Ini berisi metadata plugin dan nilai `userConfig` yang diminta Claude Code kepada pengguna. Hanya `name` yang diperlukan. Di sini, `description` adalah teks yang dilihat pengguna untuk plugin di `/plugin`, dan `version` membuat pengguna tetap pada versi itu sampai Anda mengubahnya:
```json theme={null}
{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "Review, formatting, and database tools for this team"
}
```
[Skill](/docs/id/skills) adalah file `SKILL.md`. Simpan setiap skill di direktorinya sendiri di bawah `skills/`. Claude membaca `description` setiap skill, dan ketika apa yang diminta pengguna cocok dengannya, seperti meminta Claude untuk meninjau pull request di sini, Claude memuat instruksi skill dan mengikutinya. Pengguna juga dapat menjalankannya secara langsung sebagai `/my-plugin:review`:
```markdown theme={null}
---
description: Reviews a pull request for style and test coverage. Use when asked to review code.
---

Review the changed files. Report style problems first, then missing tests.
```
Perintah adalah file Markdown tunggal yang dijalankan pengguna berdasarkan nama. Perintah adalah format yang lebih lama: skill berjalan berdasarkan nama dengan cara yang sama dan juga dapat membawa file pendukung di direktorinya sendiri, jadi tulis yang baru sebagai skills dan simpan `commands/` untuk file yang sudah Anda miliki. File ini menjadi `/my-plugin:about` dan mengambil frontmatter yang sama dengan skill:
```markdown theme={null}
---
description: Summarize the repository
---

Summarize what this repository does in three sentences.
```
[Subagent](/docs/id/sub-agents) adalah asisten terpisah, dengan instruksinya sendiri dan jendela konteksnya sendiri, yang dapat didelegasikan Claude untuk menyelesaikan tugas dan mendapatkan hasil kembali. Setiap file Markdown di bawah `agents/` mendefinisikan satu: frontmatter menamainya dan mengatakan kapan menggunakannya, dan body adalah system prompt-nya. Yang ini dinamai `my-plugin:security-reviewer`, dan pengguna dapat memanggilnya dengan `@agent-my-plugin:security-reviewer`:
```markdown theme={null}
---
name: security-reviewer
description: Reviews code changes for security issues. Use after edits to authentication or input handling.
model: sonnet
---

You are a security reviewer. Read the changed files and report injection, authentication, and secrets-handling risks.
```
[Hook](/docs/id/hooks-guide) menjalankan sesuatu secara otomatis pada titik dalam siklus hidup Claude Code, seperti setelah setiap pengeditan file: perintah shell, permintaan HTTP, panggilan tool MCP, prompt ke model, atau subagent. Simpan hooks plugin di `hooks/hooks.json` di root plugin. Yang ini menjalankan `scripts/format.sh` plugin setelah Claude menulis atau mengedit file:
```json theme={null}
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/format.sh\""
          }
        ]
      }
    ]
  }
}
```
Monitor adalah perintah shell yang dimulai Claude Code di latar belakang ketika sesi dimulai dan terus berjalan sampai berakhir, menggunakan [Monitor tool](/docs/id/tools-reference#monitor-tool). Apa yang dicetak mencapai Claude sebagai notifikasi. Field `when` dapat malah memulainya pertama kali skill bernama berjalan. Yang ini mengekor log kesalahan:
```json theme={null}
[
  {
    "name": "error-log",
    "command": "tail -F ./logs/error.log",
    "description": "Application error log"
  }
]
```
Plugin dapat menyertakan [output styles](/docs/id/output-styles), yang mengubah cara Claude memformat dan merumuskan balasannya. Simpan setiap output style sebagai `output-styles/.md`. Yang ini muncul di `/output-style` sebagai `my-plugin:terse`:
```markdown theme={null}
---
name: terse
description: Answer in as few words as possible
keep-coding-instructions: true
---

Keep every reply short. Skip preambles and summaries.
```
Plugin dapat menyertakan [color themes](/docs/id/terminal-config#create-a-custom-theme) untuk antarmuka Claude Code. Simpan setiap tema sebagai `themes/.json`. Yang ini muncul di `/theme` sebagai `Dracula`, ditandai sebagai dari `my-plugin`:
```json theme={null}
{
  "name": "Dracula",
  "base": "dark",
  "overrides": {
    "claude": "#bd93f9",
    "error": "#ff5555"
  }
}
```
Folder `workflows/` menyimpan file `.js` [workflow](/docs/id/workflows): blok `meta`, kemudian body script yang mengorkestra beberapa subagent. Yang ini berjalan sebagai `/my-plugin:audit-routes`:
```javascript theme={null}
export const meta = {
  name: 'audit-routes',
  description: 'Audit every route handler for missing auth checks',
}

const found = await agent('List every .ts file under src/routes/.', {
  schema: { type: 'object', required: ['files'], properties: { files: { type: 'array', items: { type: 'string' } } } },
})

const audits = await pipeline(found.files, file =>
  agent(`Audit ${file} for missing authentication checks.`, { label: file }),
)

return audits.filter(Boolean)
```
`bin/` adalah cara plugin mengirimkan alat command-line. Sementara plugin diaktifkan, Claude Code menempatkan folder ini di `PATH` shell tempat ia menjalankan perintah, sehingga Claude, atau instruksi skill, dapat menjalankan alat berdasarkan nama tanpa pengguna memasangnya. Dengan [executable](#executables) ini di tempat, `hello-plugin` adalah perintah yang dapat dijalankan Claude:
```bash theme={null}
#!/bin/bash
echo "hello from my-plugin"
```
Hook di `hooks/hooks.json` menjalankan script, dan folder ini adalah tempat contoh menyimpannya. Nama `scripts/` adalah konvensi, bukan sesuatu yang dicari Claude Code: hook menunjuk ke file berdasarkan jalurnya, `${CLAUDE_PLUGIN_ROOT}/scripts/format.sh`. Script formatter mungkin terlihat seperti ini:
```bash theme={null}
#!/bin/bash
npx prettier --write .
```
`settings.json` di root plugin menyimpan [settings](/docs/id/settings-reference) yang berlaku sementara plugin diaktifkan, sehingga plugin dapat mengubah cara sesi berperilaku dan tidak hanya menambahkan komponen. Hanya dua kunci yang berlaku dari plugin, [`agent`](/docs/id/settings-reference#agent) dan [`subagentStatusLine`](/docs/id/settings-reference#subagentstatusline); setiap kunci lain dijatuhkan. Lihat [Default settings](#default-settings).
Yang ini menetapkan `agent`, yang menjalankan thread utama sesi sebagai agent `security-reviewer` plugin sendiri, sehingga system prompt, pembatasan tool, dan model agent itu berlaku untuk seluruh sesi:

```json theme={null}
{
  "agent": "security-reviewer"
}
```
[Server MCP](/docs/id/mcp) memberikan Claude tools dari sistem eksternal. Deklarasikan di `.mcp.json` di root plugin. Yang ini memulai server lokal dari script di dalam plugin, dan muncul di `/mcp` sebagai `plugin:my-plugin:db`:
```json theme={null}
{
  "mcpServers": {
    "db": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"]
    }
  }
}
```
Server LSP memberikan Claude [diagnostics dan code navigation](/docs/id/plugins/code-intelligence) untuk bahasa. Deklarasikan server di `.lsp.json` di root plugin. Yang ini menghubungkan language server Go untuk file `.go`:
```json theme={null}
{
  "gopls": {
    "command": "gopls",
    "args": ["serve"],
    "extensionToLanguage": {
      ".go": "go"
    }
  }
}
```

Tambahkan setiap jenis komponen

Setiap bagian di bawah mencakup satu jenis komponen: di mana file-filenya berada di plugin, contoh yang memvalidasi, apa yang dilihat pengguna setelah plugin dimuat, dan kunci manifest yang mengubah lokasi default. Tambahkan yang dibutuhkan plugin Anda; tidak ada yang diperlukan.

Skills

Skill adalah file SKILL.md yang dapat dimuat Claude ketika deskripsinya cocok dengan tugas. Pengguna juga dapat menjalankannya sebagai perintah. Simpan setiap skill di direktorinya sendiri di bawah skills/:

my-plugin/
├── .claude-plugin/
│   └── plugin.json
└── skills/
    └── review/
        └── SKILL.md

Berikan SKILL.md description sehingga Claude tahu kapan menggunakannya:

---
description: Reviews a pull request for style and test coverage. Use when asked to review code.
---

Review the changed files. Report style problems first, then missing tests.

Setelah Anda memuat plugin, /my-plugin:review menjalankan skill. Nama perintah dan siapa yang dapat memanggilnya mengikuti aturan ini:

Anda juga dapat menempatkan skills di luar direktori default skills/:

Untuk menyertakan instruksi dalam plugin, tulislah sebagai skill. Claude Code tidak memuat CLAUDE.md di root plugin, dan claude plugin validate memperingatkan CLAUDE.md at the plugin root is not loaded as project context.

Untuk field frontmatter dan file pendukung, lihat Skills.

Commands

Perintah adalah file Markdown tunggal yang dijalankan pengguna berdasarkan nama, seperti /my-plugin:about.

Simpan perintah di commands/<file>.md dan itu menjadi /<plugin>:<file>. Subdirektori menambah segmen, jadi commands/db/migrate.md adalah /my-plugin:db:migrate.

File perintah mengambil frontmatter yang sama dengan skills.

Tentukan perintah di manifest

Anda hanya membutuhkan ini jika Anda ingin menyimpan file perintah di tempat lain selain commands/, atau untuk mendefinisikan perintah pendek di dalam plugin.json tanpa file Markdown terpisah. Tetapkan kunci manifest commands, dan Claude Code membacanya daripada memindai commands/. Kunci mengambil jalur, array jalur, atau objek yang memetakan setiap nama perintah ke file source atau content inline.

Manifest ini mendefinisikan /my-plugin:about inline, tanpa file Markdown:

{
  "name": "my-plugin",
  "commands": {
    "about": {
      "content": "Summarize what this repository does in three sentences.",
      "description": "Summarize the repository"
    }
  }
}

Muat plugin dan jalankan /my-plugin:about dalam sesi untuk mengonfirmasi itu dimuat.

Untuk sintaks kunci lengkap, lihat commands.

Agents

Subagent adalah asisten terpisah, dengan instruksinya sendiri dan jendela konteks, yang dapat didelegasikan Claude untuk menyelesaikan tugas. Setiap file Markdown di bawah agents/ mendefinisikan satu:

---
name: security-reviewer
description: Reviews code changes for security issues. Use after edits to authentication or input handling.
model: sonnet
---

You are a security reviewer. Read the changed files and report injection, authentication, and secrets-handling risks.

Agent ini dinamai my-plugin:security-reviewer, dan pengguna dapat memanggilnya secara eksplisit dengan @agent-my-plugin:security-reviewer. Bentuk nama adalah <plugin>:<name>, di mana <name> berasal dari frontmatter, atau dari nama file ketika tidak ada.

Kunci manifest agents menggantikan pemindaian agents/.

Atur agents dalam subfolder

Anda dapat menempatkan file agent plugin dalam subfolder agents/. Claude Code memuatnya secara rekursif dan menggabungkan nama plugin, setiap nama subfolder, dan nama file dengan titik dua untuk membentuk nama scoped agent. Misalnya, agents/review/security.md dalam plugin bernama my-plugin dimuat sebagai my-plugin:review:security. Dua pengaturan mengubah nama itu:

Field frontmatter dalam agent plugin

Frontmatter agent plugin mengikuti aturan ini:

Untuk apa yang dilakukan setiap field dan aturan prioritas, lihat Subagents.

Hooks

Hook menjalankan sesuatu secara otomatis pada titik dalam siklus hidup Claude Code, seperti setelah setiap pengeditan file: perintah shell, permintaan HTTP, panggilan tool MCP, prompt ke model, atau subagent. Simpan hooks plugin di hooks/hooks.json di root plugin, di bawah kunci top-level "hooks", dalam bentuk yang sama dengan objek hooks di settings.json. Itu memungkinkan Anda menyalin hook pengaturan yang ada tanpa perubahan.

Hook ini menjalankan script bundled setelah setiap Write atau Edit:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/format.sh\""
          }
        ]
      }
    ]
  }
}

Simpan script di scripts/format.sh dan buat dapat dieksekusi.

Muat plugin dan minta Claude untuk mengedit file. Hook PostToolUse yang keluar 0 tidak menunjukkan apa pun dalam transkrip, jadi konfirmasi itu berjalan dengan debug logging atau dengan apa yang diubah script itu sendiri.

Hooks di hooks/hooks.json dan di kunci manifest hooks keduanya dimuat. Untuk setiap event dan payload-nya, lihat Hook events.

Kapan hook plugin dipecat

Hook plugin tidak menunggu salah satu skill atau perintah plugin digunakan. Claude Code mendaftarkannya ketika sesi memuat plugin, dan mereka dipecat pada event mereka sejak saat itu. Untuk membatasi kapan hook berjalan, persempit matcher-nya.

Jika hook tidak pernah dipecat, lihat hooks yang tidak dipecat.

Lingkungan, quoting, dan pencocokan tool MCP

Lingkungan hook, quoting ${CLAUDE_PLUGIN_ROOT}, dan matcher untuk tool MCP plugin sendiri bekerja sebagai berikut:

Server MCP

Server MCP memberikan Claude tools dari sistem eksternal. Deklarasikan di .mcp.json di root plugin, dalam bentuk yang sama dengan project .mcp.json. .mcp.json ini mendeklarasikan satu server bernama db:

{
  "mcpServers": {
    "db": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"]
    }
  }
}

Anda juga dapat menghilangkan wrapper mcpServers dan menempatkan db di level atas file.

Muat plugin dan jalankan /mcp untuk mengonfirmasi server muncul sebagai plugin:my-plugin:db.

claude plugin validate memeriksa .mcp.json dan melaporkan entri server yang akan dijatuhkan Claude Code pada waktu muat sebagai kesalahan. Memerlukan Claude Code v2.1.281 atau lebih baru.

Untuk di mana entri buruk muncul pada waktu muat, lihat Server MCP yang tidak dimulai.

Kunci manifest mcpServers mengambil peta server inline, jalur ke file JSON, atau array dari itu. Ketika server manifest memiliki nama yang sama dengan yang di .mcp.json, server manifest menggantinya.

Jangkau pengguna di claude.ai dan Cowork

Server stdio lokal, seperti server db di bawah Server MCP, berjalan di Claude Code dan dalam sesi Cowork yang berjalan di mesin Anda di aplikasi Claude Desktop, tetapi bukan di claude.ai. Untuk menjangkau pengguna di sana juga, referensikan server jarak jauh dengan URL https://-nya, yang claude.ai dan Cowork tawarkan kepada pengguna sebagai konektor.

Nama server, nama tool, dan reload

Nama server, substitusi variabel, dan perilaku reload mengikuti aturan ini:

Sertakan server MCPB yang dikemas

Kunci mcpServers juga menerima server yang dikemas sebagai file MCPB, yang ekstensinya adalah .mcpb atau .dxt yang lebih lama. Arahkan kunci ke file, sebagai jalur di dalam plugin atau URL https://:

{
  "name": "my-plugin",
  "mcpServers": "./servers/db.mcpb"
}

Server mengambil namanya dari name dalam manifest bundle.

Untuk transport dan autentikasi, lihat MCP.

Server LSP

Server LSP memberikan Claude diagnostics dan code navigation untuk bahasa. Jika plugin code intelligence resmi sudah mencakup bahasa Anda, pasang itu daripada menulis satu. Jika tidak, deklarasikan server di .lsp.json di root plugin:

{
  "gopls": {
    "command": "gopls",
    "args": ["serve"],
    "extensionToLanguage": {
      ".go": "go"
    }
  }
}

File memetakan setiap nama server langsung ke konfigurasinya, tanpa objek wrapper di sekitar peta. command adalah nama binary, dengan argumennya di args. extensionToLanguage memerlukan setidaknya satu ekstensi, masing-masing dimulai dengan ..

claude plugin validate tidak membaca file ini. Ketika entri apa pun tidak valid, seluruh file dilewati pada waktu muat dan Invalid LSP server config for ".lsp.json" muncul di tab Errors /plugin.

Plugin Anda mengonfigurasi koneksi tetapi tidak memasang binary server, dan setiap ekstensi file mendapat satu server:

Kunci manifest lspServers mengambil peta yang sama inline, jalur ke file JSON, atau array dari itu, dan server-nya menambah yang di .lsp.json. Ketika server manifest memiliki nama yang sama dengan yang di .lsp.json, server manifest menggantinya.

Untuk transport, timeout, restart, dan field lainnya, lihat lspServers.

Kirim output log ke stderr, bukan stdout. Claude Code membaca stdout server sebagai pesan protokol saja, dan menerima header pesan hingga 64 KiB dan body pesan hingga 32 MiB.

Claude Code memutuskan server yang melebihi batas apa pun atau menulis output non-protokol ke stdout, dan menghitung putus sebagai crash untuk restartOnCrash dan maxRestarts. Ketika Anda menjalankan dengan --debug, Claude Code menulis kesalahan yang menamai penyebabnya ke log debug.

Executables

File di bin/ di root plugin berada di PATH shell tool Bash sementara plugin diaktifkan, sehingga Claude dapat menjalankannya sebagai perintah bare. Tambahkan script yang dapat dieksekusi:

#!/bin/bash
echo "hello from my-plugin"

Buat dapat dieksekusi dengan chmod +x bin/hello-plugin dan muat plugin. Ketika Anda meminta Claude untuk menjalankan hello-plugin, hasil tool Bash menunjukkan output script.

Direktori bin/ plugin datang setelah entri PATH pengguna sendiri, jadi plugin tidak dapat menaungi git, ls, atau perintah sistem lainnya.

claude.ai dan Cowork tidak memasang plugin yang memiliki direktori bin/ level atas, termasuk yang Anda distribusikan melalui pengaturan organisasi claude.ai.

Pengaturan default

Untuk menetapkan default yang berlaku sementara plugin diaktifkan, tambahkan settings.json di root plugin, atau letakkan objek yang sama inline di kunci manifest settings. Dua kunci berlaku, agent dan subagentStatusLine, dan setiap kunci lain dijatuhkan.

Tetapkan agent untuk menjalankan salah satu agent plugin sendiri sebagai thread utama:

{
  "agent": "security-reviewer"
}

Muat plugin dan mulai sesi. Claude kemudian menjawab dalam percakapan utama dengan system prompt dan model agent security-reviewer.

Untuk semua yang dikontrol kunci, lihat pengaturan agent.

Ketika kunci yang sama ditetapkan di lebih dari satu tempat, aturan ini memutuskan nilai mana yang berlaku:

Untuk bentuk subagentStatusLine, lihat subagent status lines.

Tema dan output styles

Plugin dapat menyertakan color themes dan output styles. Keduanya muncul di picker yang sama dengan pengguna sendiri. Untuk salah satu, menetapkan kunci manifest menggantikan pemindaian folder.

Komponen Simpan sebagai Format Muncul di Kunci manifest
Tema themes/<slug>.json Format file tema kustom yang ditulis pengguna di ~/.claude/themes/ /theme, di bawah name file experimental.themes
Output style output-styles/<name>.md Format output style kustom, dengan frontmatter name dan description /output-style, sebagai <plugin>:<name> outputStyles

Tema plugin adalah read-only, jadi ketika pengguna mengedit satu di /theme, edit disimpan sebagai salinan di direktori tema mereka sendiri.

Tema ini mengubah warna prompt accent dan error text pada preset dark:

{
  "name": "Dracula",
  "base": "dark",
  "overrides": {
    "claude": "#bd93f9",
    "error": "#ff5555"
  }
}

Channels

Channel memungkinkan sistem luar seperti aplikasi chat mengirim pesan ke sesi. Dalam plugin, channel adalah salah satu server MCP ditambah entri channels yang mengikat ke itu dan dapat meminta konfigurasinya sendiri. Manifest ini mengikat channel ke server telegram dan meminta token bot:

{
  "name": "my-plugin",
  "mcpServers": {
    "telegram": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"],
      "env": { "BOT_TOKEN": "${user_config.bot_token}" }
    }
  },
  "channels": [
    {
      "server": "telegram",
      "userConfig": {
        "bot_token": {
          "type": "string",
          "title": "Bot token",
          "description": "Telegram bot token",
          "sensitive": true
        }
      }
    }
  ]
}

server harus cocok dengan kunci di mcpServers. Per-channel userConfig mengambil bentuk yang sama dengan kunci userConfig level atas.

Untuk apa yang harus diimplementasikan server dan bagaimana pengguna mengaktifkan plugin channel, lihat Package as a plugin dalam referensi channels. Untuk tabel field, lihat channels.

Monitors

Monitor adalah perintah shell yang berjalan di latar belakang untuk seluruh sesi. Apa yang dicetak mencapai Claude sebagai notifikasi, sehingga Claude dapat bereaksi terhadap log atau perubahan status tanpa diminta untuk menontonnya. Simpan entri di monitors/monitors.json:

[
  {
    "name": "error-log",
    "command": "tail -F ./logs/error.log",
    "description": "Application error log"
  }
]

Perintah berjalan dalam shell, di direktori kerja tempat sesi dimulai.

Perintah monitor dibatasi di mana itu dimulai dan apa yang dapat direferensikan:

Kunci manifest experimental.monitors mengambil array yang sama inline atau jalur ke file JSON, dan dibaca daripada monitors/monitors.json.

Untuk trigger when dan field lainnya, lihat monitors.

Minta pengguna untuk nilai konfigurasi

Deklarasikan nilai yang dibutuhkan plugin Anda dari pengguna di kunci manifest userConfig, sehingga pengguna tidak mengedit settings.json sendiri. Setiap opsi muncul dalam dialog dengan title-nya sebagai label dan description-nya di bawahnya.

Tetapkan "sensitive": true untuk token atau password. Dialog kemudian menutupi input, dan nilai disimpan dalam penyimpanan aman daripada settings.json.

Manifest ini meminta endpoint dan token:

{
  "name": "my-plugin",
  "userConfig": {
    "api_url": {
      "type": "string",
      "title": "API URL",
      "description": "Base URL of your team's API"
    },
    "api_token": {
      "type": "string",
      "title": "API token",
      "description": "Token for your team's API",
      "sensitive": true
    }
  }
}

Kapan dialog konfigurasi muncul

Dialog muncul hanya dalam antarmuka /plugin interaktif. Itu terbuka untuk opsi apa pun yang belum ditetapkan ketika pengguna melakukan salah satu dari berikut:

Untuk membuka dialog yang sama kapan saja, pengguna menjalankan /plugin configure <plugin>@<marketplace>.

Perintah shell claude plugin install tidak pernah meminta nilai userConfig. Untuk menetapkan nilai dari shell, lewatkan masing-masing sebagai --config KEY=VALUE. Ketika opsi tetap tidak ditetapkan, perintah mencetak baris userConfig options not yet set yang menamai kedua cara untuk menetapkannya. Dialog userConfig tidak pernah muncul mengutip baris.

Untuk field opsi, di mana setiap nilai disimpan, bagaimana komponen mereferensikan nilai yang disimpan, dan field mana yang menolak ${user_config.*}, lihat User configuration.

Referensikan jalur plugin dan simpan data

Anda tidak tahu di mana plugin Anda akan dipasang, jadi referensikan file dan data-nya melalui variabel ini daripada jalur tetap. Mereka disubstitusikan dalam skill, command, dan agent content, dalam hook dan monitor commands, dan dalam konfigurasi server MCP dan LSP. Mereka juga diekspor ke hook, MCP, dan proses LSP:

Dalam jalur direktori data, <id> adalah identifier plugin dengan setiap karakter selain huruf, digit, _, dan - diganti dengan -, jadi my-plugin@my-marketplace menjadi my-plugin-my-marketplace.

Di Windows, jalur yang disubstitusikan menggunakan forward slashes sehingga shell tidak membaca backslashes sebagai escapes.

Pasang dependensi ke direktori data

Untuk plugin yang dipasang marketplace, Claude Code memasang dependensi paket Node.js yang memenuhi syarat secara otomatis ketika itu cache plugin, jadi Anda mungkin tidak perlu memasangnya sendiri. Ketika Anda melakukannya, hook SessionStart ini memasang node_modules ke ${CLAUDE_PLUGIN_DATA} pada run pertama dan lagi setelah update mengubah package.json:

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "diff -q \"${CLAUDE_PLUGIN_ROOT}/package.json\" \"${CLAUDE_PLUGIN_DATA}/package.json\" >/dev/null 2>&1 || (cd \"${CLAUDE_PLUGIN_DATA}\" && cp \"${CLAUDE_PLUGIN_ROOT}/package.json\" . && npm install) || rm -f \"${CLAUDE_PLUGIN_DATA}/package.json\""
          }
        ]
      }
    ]
  }
}

Setelah sesi pertama, ~/.claude/plugins/data/<id>/node_modules ada. Server MCP kemudian dapat menetapkan NODE_PATH ke ${CLAUDE_PLUGIN_DATA}/node_modules di env-nya. Untuk field mana yang mensubstitusikan variabel mana, lihat Environment variables.

Langkah berikutnya