Making Claude Code Plugins Work with Copilot CLI

GitHub’s Copilot CLI went GA in February 2026 with a plugin system that closely mirrors Claude Code’s. If you maintain a Claude Code plugin, you can make it work with both tools with minimal effort.

This guide covers what’s compatible, what’s not, and the concrete steps to make one repo serve both ecosystems.

TL;DR

Copilot CLI reads .claude-plugin/plugin.json natively. Most Claude Code plugins work with zero changes.

Fully portable — works on both, no changes needed

  • Plugin manifest.claude-plugin/plugin.json read by both tools
  • Skillsskills/<name>/SKILL.md identical format and paths
  • MCP servers.mcp.json same schema

Portable with graceful degradation

  • Agents — extra frontmatter (model, permissionMode, etc.) ignored by Copilot CLI; declare paths explicitly in plugin.json and .md files work for both
  • HooksPreToolUse/PostToolUse command hooks work in both (watch PascalCase vs camelCase); 12 Claude Code-only events and prompt/agent handler types degrade silently

Not portable — Claude Code only

  • Commands (commands/) — use skills instead
  • Styles (styles/) — no Copilot CLI equivalent
  • Advanced hooksPermissionRequest, SubagentStart, InstructionsLoaded, etc.
  • LLM-based hook handlersprompt and agent types
  • Context hierarchy — layered CLAUDE.md (user, project, per-directory)

Why Portability Matters

The feature sets have converged significantly. Both tools now support plugins, skills, agents, hooks, and MCP servers – and both use markdown files with YAML frontmatter as the primary authoring format. Users are already running both tools depending on the task. A portable plugin doubles your audience without doubling your maintenance.

Format Comparison

Plugin Manifest

The manifest tells each tool where to find your plugin’s components.

Claude CodeCopilot CLI
Location.claude-plugin/plugin.jsonRoot plugin.json, .claude-plugin/plugin.json, or .github/plugin/plugin.json
Required fieldsname, description, version, authorname, description, version, author
Optional fieldsagents, skills, hooks, commands, stylesagents, skills, hooks, mcpServers

The schema is nearly identical. Copilot CLI accepts plugin.json in multiple locations – including .claude-plugin/plugin.json, the repo root, and .github/plugin/. This means Claude Code’s standard layout works with Copilot CLI out of the box – no symlinks or extra files needed.

Claude Code plugin.json:

{
  "name": "my-plugin",
  "description": "My plugin",
  "version": "1.0.0",
  "author": { "name": "Jane Doe" },
  "skills": "skills/",
  "agents": [
    "agents/reviewer.md"
  ],
  "hooks": "hooks/hooks.json"
}

Copilot CLI plugin.json:

{
  "name": "my-plugin",
  "description": "My plugin",
  "version": "1.0.0",
  "author": { "name": "Jane Doe" },
  "skills": "skills/",
  "agents": "agents/",
  "hooks": "hooks.json",
  "mcpServers": ".mcp.json"
}

Claimed differences vs tested reality:

  • Location: Copilot CLI reads .claude-plugin/plugin.json natively. No symlink needed. ✅ Tested
  • Agents: Claude Code uses an array of file paths; Copilot CLI accepts a directory path. Both accept .md files. ✅ Tested — Copilot installs .md agents from Claude Code layout
  • Hooks: Claude Code expects hooks/hooks.json (subdirectory). Copilot CLI follows the path declared in plugin.json, so "hooks": "hooks/hooks.json" works. ✅ Tested
  • MCP: Copilot CLI references MCP config via mcpServers in plugin.json; Claude Code uses .mcp.json at the plugin root (auto-discovered, not declared in plugin.json).
  • LSP: Claude Code supports .lsp.json for language servers; Copilot CLI uses lspServers in plugin.json.
  • Commands/Styles: Claude Code supports commands/ and styles/ directories; Copilot CLI does not have these concepts.

Skills

Skills are the most portable component. Both tools use the same format.

Claude CodeCopilot CLI
File nameSKILL.mdSKILL.md
Directoryskills/<name>/SKILL.mdskills/<name>/SKILL.md
User-level~/.claude/skills/~/.copilot/skills/ or ~/.claude/skills/
Project-level.claude/skills/.github/skills/ or .claude/skills/
Frontmattername, description (required)name, description (required), license (optional)
Invocation/skill-name/skill-name

Copilot CLI explicitly supports .claude/skills/ as a lookup path, so your existing skills work without changes.

Agents

Agent files are the biggest format difference between the two tools.

Claude CodeCopilot CLI
File extension.md.agent.md
Directoryagents/agents/
User-level~/.claude/agents/~/.copilot/agents/
Project-level.claude/agents/.github/agents/
Frontmatter fieldsname, description, tools, model, color, permissionMode, maxTurns, skills, mcpServers, hooks, memoryname, description, tools

Claude Code agents have significantly richer frontmatter (model selection, color, permission modes, hooks, memory, skills injection). Copilot CLI agents are simpler – name, description, tools, and the markdown body.

Making agents work for both: You can include Claude Code-specific frontmatter fields; Copilot CLI ignores fields it doesn’t recognize. Despite the documented preference for .agent.md, testing shows Copilot CLI installs .md agent files from the Claude Code layout without issues. Runtime discovery of .md agents needs further testing.

Hooks

Hooks have the largest gap in capability between the two tools.

Claude CodeCopilot CLI
Config filehooks/hooks.json (plugin) or .claude/settings.jsonhooks.json
Hook events18 events6 events
Handler typescommand, prompt, agentcommand only
MatchersRegex on tool name, agent type, etc.Supported

Claude Code events (18): SessionStart, UserPromptSubmit, PreToolUse, PermissionRequest, PostToolUse, PostToolUseFailure, Notification, SubagentStart, SubagentStop, Stop, TeammateIdle, TaskCompleted, InstructionsLoaded, ConfigChange, WorktreeCreate, WorktreeRemove, PreCompact, SessionEnd

Copilot CLI events (6): sessionStart, sessionEnd, userPromptSubmitted, preToolUse, postToolUse, errorOccurred

The six Copilot CLI events roughly map to a subset of Claude Code’s events. If your hooks only use PreToolUse and PostToolUse, they’re portable. LLM-based hooks (prompt and agent types) are Claude Code-only.

Both tools use a versioned JSON wrapper:

{
  "version": 1,
  "hooks": {
    "preToolUse": [...]
  }
}

Note the casing difference: Claude Code uses PascalCase (PreToolUse), Copilot CLI uses camelCase (preToolUse).

MCP Servers

MCP configuration is portable – both tools use .mcp.json at the project or plugin root with the same schema.

Claude CodeCopilot CLI
Config file.mcp.json (auto-discovered).mcp.json (referenced in plugin.json as mcpServers)
SchemaStandard MCP configStandard MCP config

LSP Servers

Claude CodeCopilot CLI
Config.lsp.json at plugin rootlspServers field in plugin.json

Both support language server integration but configure it differently.

Zero-Change Compatibility

The good news: Copilot CLI reads .claude-plugin/plugin.json natively. No symlinks, no extra files, no changes needed. Your existing Claude Code plugin layout works as-is.

my-plugin/
├── .claude-plugin/
│   ├── plugin.json        # Works for BOTH Claude Code and Copilot CLI
│   └── marketplace.json   # Claude Code marketplace listing (ignored by Copilot)
├── skills/
│   └── my-skill/
│       └── SKILL.md       # Works for both tools
├── hooks/
│   └── hooks.json         # Works for both (if declared in plugin.json)
├── .mcp.json              # Works for both tools
└── README.md

Working Example: show-me

The show-me plugin required zero changes to work with Copilot CLI:

show-me/
├── .claude-plugin/
│   └── plugin.json         # Manifest — works for both tools
├── skills/
│   └── show-me/
│       ├── SKILL.md        # Skill — works for both tools
│       └── docs/
├── bin/
│   ├── show
│   └── look
└── README.md

Install from either tool:

claude plugin install mbailey/show-me    # Claude Code
copilot plugin install mbailey/show-me   # Copilot CLI

Installation

Users install from each tool using similar commands:

Claude CodeCopilot CLI
From repoclaude plugin install mbailey/show-mecopilot plugin install mbailey/show-me
From marketplace/plugin marketplace add user/repo then /plugin install namecopilot plugin install name@marketplace
Localclaude --plugin-dir ./my-plugincopilot plugin install ./my-plugin
Installed to~/.claude/plugins/cache/~/.copilot/state/installed-plugins/

Both tools support installing directly from a GitHub owner/repo path, making distribution straightforward.

What’s NOT Portable

Hook Events and Handler Types

Claude Code has 18 hook events with three handler types (command, prompt, agent). Copilot CLI has 6 events with command handlers only. If your plugin relies on PermissionRequest, SubagentStart, InstructionsLoaded, or other Claude Code-specific events, those hooks won’t fire in Copilot CLI. LLM-evaluated hooks (prompt and agent types) are Claude Code-only.

Agent Frontmatter

Claude Code agents support model, color, permissionMode, maxTurns, skills, mcpServers, hooks, and memory in frontmatter. Copilot CLI agents support name, description, and tools. The extra fields are ignored by Copilot CLI but don’t cause errors – your agents just won’t have those capabilities.

Agent File Extension

Claude Code uses *.md; Copilot CLI conventionally uses *.agent.md. However, when agent paths are declared explicitly in plugin.json (e.g., "agents": ["agents/greeter.md"]), Copilot CLI installs and uses .md files without issues. The extension convention only matters for auto-discovery in the agents/ directory — explicit paths work regardless of extension.

Progressive Plugin Pattern

Claude Code’s .claude/ subdirectory pattern (for projects that are both standalone tools and plugins) has no Copilot CLI equivalent. Copilot CLI looks for components at the paths declared in plugin.json, so you can point to .claude/ paths, but the convention is different.

Marketplace and Discovery

Claude Code uses marketplace.json in .claude-plugin/ for marketplace distribution. Copilot CLI has its own marketplace system. You’ll need separate marketplace listings for each ecosystem.

Commands and Styles

Claude Code supports commands/ (slash commands) and styles/ (output formatting). Copilot CLI doesn’t have these concepts. Commands are being merged into skills in Claude Code anyway, so prefer skills for new work.

Hook Casing Convention

Claude Code uses PascalCase for event names (PreToolUse); Copilot CLI uses camelCase (preToolUse). If you maintain separate hooks configs, watch the casing.

Context Hierarchy

Claude Code’s layered CLAUDE.md system (user, project, per-directory) is richer than Copilot CLI’s single .github/copilot-instructions.md per repo.

Portability Checklist

Use this checklist when adapting a Claude Code plugin for Copilot CLI compatibility:

  • No manifest changes needed — Copilot CLI reads .claude-plugin/plugin.json natively
  • Skills: No changes needed — skills/<name>/SKILL.md works for both
  • MCP config: .mcp.json works for both; add "mcpServers": ".mcp.json" to plugin.json for explicit Copilot CLI discovery
  • Agents: .md files install fine; runtime discovery of .md vs .agent.md may vary
  • Hooks: If using only PreToolUse/PostToolUse with command handlers, they work in both. Watch PascalCase vs camelCase. Advanced hook types are Claude Code-only.
  • Test both: Install with claude --plugin-dir ./ and copilot plugin install ./ to verify
  • README: Document that the plugin works with both tools and any feature differences
  • Avoid Claude Code-only features in shared components: prompt/agent hooks, commands, styles, advanced agent frontmatter

Summary

ComponentPortabilityNotes
SkillsFully portableSame format, same paths
MCP serversFully portableSame .mcp.json format
Plugin manifestFully portableCopilot CLI reads .claude-plugin/plugin.json natively
Hooks (basic)AdaptablePreToolUse/PostToolUse command hooks work; watch casing
Hooks (advanced)Not portable12 Claude Code-only events; prompt/agent handlers
AgentsAdaptableExtra frontmatter ignored; file extension differs
CommandsNot portableClaude Code-only (use skills instead)
StylesNot portableClaude Code-only

The convergence between these tools is good news for plugin authors. Skills, MCP servers, and plugin manifests are fully portable today — Copilot CLI reads .claude-plugin/plugin.json natively, so Claude Code plugins work with zero changes. As the tools continue to evolve, expect the remaining gaps to narrow.


Last updated: March 2026

Resources