Construct is a wrapper for copilot CLI (https://github.com/github/copilot-cli/) that enables loading plugins, skills, MCPs, and custom agents from Claude Code marketplaces.
construct [options] [-- copilot-args...]- Run with enabled plugins, passing remaining args to copilotconstruct --list- List all discoverable pluginsconstruct --load <plugin>@<marketplace>- Load plugin(s) for this run (repeatable)construct(no args) - Use.construct.jsonconfig from current directory
Passthrough args: Everything after -- is passed directly to copilot. Example:
construct --load tmux@scaryrawr-plugins -- --continue --allow-all-toolsBehavior: Construct translates enabled plugins into appropriate environment variables and CLI args, then spawns copilot as a subprocess with spawnSync.
- Local config:
.construct.jsonin current directory stores last-used loadout - Format:
{ "enabledPlugins": ["plugin1@marketplace1", "plugin2@marketplace2"], "lastUsed": "2026-01-09T21:32:00.000Z" }
-
Known Marketplaces:
~/.claude/plugins/known_marketplaces.json{ "marketplace-name": { "source": { "source": "github", "repo": "owner/repo" }, "installLocation": "/Users/.../.claude/plugins/marketplaces/marketplace-name", "lastUpdated": "2026-01-09T20:45:55.842Z" } } -
Installed Plugins:
~/.claude/plugins/installed_plugins.json{ "version": 2, "plugins": { "plugin-name@marketplace-name": [ { "scope": "user", "installPath": "/Users/.../.claude/plugins/cache/marketplace/plugin/version", "version": "1.0.0", "installedAt": "2026-01-09T20:45:49.614Z", "lastUpdated": "2026-01-09T20:45:49.614Z" } ] } } -
Marketplace Registry:
~/.claude/plugins/marketplaces/<name>/.claude-plugin/marketplace.json- Contains full plugin definitions with metadata, versions, and component configurations
~/.claude/plugins/
├── installed_plugins.json # Tracks installed plugins
├── known_marketplaces.json # Registered marketplaces
├── cache/ # Installed plugin files
│ └── <marketplace>/
│ └── <plugin>/
│ └── <version>/
│ ├── .claude-plugin/plugin.json
│ ├── .mcp.json # MCP servers (if any)
│ ├── skills/ # Skills (if any)
│ │ └── <skill-name>/
│ │ └── SKILL.md
│ └── agents/ # Custom agents (if any)
│ └── <agent>.md
└── marketplaces/ # Cloned marketplace repos
└── <marketplace-name>/
├── .claude-plugin/marketplace.json
└── plugins/
└── <plugin-name>/
- Skills: Directories containing
SKILL.mdfiles with YAML frontmatter - MCPs: Defined in
.mcp.jsonat plugin root - Agents: Markdown files in
agents/directory with YAML frontmatter - Hooks: Defined in
hooks/hooks.json(not supported by Copilot CLI) - LSP Servers: Defined in
plugin.json(not supported by Copilot CLI)
Naming Convention: <plugin>@<marketplace> (e.g., tmux@scaryrawr-plugins)
- Source:
<plugin-path>/skills/<skill-name>/SKILL.md - Target: Environment variable
COPILOT_SKILLS_DIRS - Format: Comma-separated list of skill directory paths
- Example:
COPILOT_SKILLS_DIRS=/path/to/skill1,/path/to/skill2
Claude Code Format (.mcp.json):
{
"server-name": {
"command": "npx",
"args": ["package@latest", "--option=value"],
"env": {
"VAR_NAME": "value"
}
}
}GitHub Copilot Format (--additional-mcp-config):
{
"mcpServers": {
"server-name": {
"type": "local",
"command": "npx",
"args": ["package@latest", "--option=value"],
"env": {
"VAR_NAME": "value"
},
"tools": ["*"]
}
}
}Transformation Rules:
- Wrap in
mcpServersobject - Add
"type": "local"to each server config - Add
"tools": ["*"]to enable all tools (or allow user to specify) - Keep
command,args,env,cwdas-is - Expand
${CLAUDE_PLUGIN_ROOT}→ actual plugin install path
Copilot CLI Flag: --additional-mcp-config '{"mcpServers":...}'
- Hooks: Claude Code event handlers - not applicable to Copilot CLI
- LSP Servers: Language server configs - Copilot CLI doesn't support these
- Custom Agents: Different format/purpose than Copilot's
--agentflag
- Tool: Use
yargsfor automatic completion generation - Shells: bash, zsh, fish, powershell
- Scope: Complete
constructcommands and plugin names from marketplace scan
-
CLI Setup (yargs)
- Parse
--list,--load, passthrough args - Generate shell completions
- Parse
-
Plugin Scanner
- Read
~/.claude/plugins/installed_plugins.jsonfor installed plugins - For each plugin, locate install path and scan for:
skills/*/SKILL.md→ skill directories.mcp.json→ MCP server configsagents/*.md→ custom agent definitions
- Build plugin registry with component types
- Read
-
Config Manager
- Read/write
.construct.json - Merge CLI flags with saved config
- Read/write
-
Translation Engine
- Build
COPILOT_SKILLS_DIRSfrom enabled plugins' skill paths - Transform MCP configs:
- Parse Claude
.mcp.jsonformat - Add
type: "local"andtools: ["*"] - Wrap in
mcpServersobject - Replace
${CLAUDE_PLUGIN_ROOT}with actual paths
- Parse Claude
- Generate
--additional-mcp-configJSON string
- Build
-
Subprocess Executor
spawnSynccopilotwith:- Modified environment (COPILOT_SKILLS_DIRS, etc.)
- Additional CLI args (--additional-mcp-config)
- Passthrough remaining args
- Forward stdout/stderr/exit code
- Use
inheritfor stdio to allow interactive mode
- Path handling (use
node:pathor Bun equivalents) - Home directory resolution (
Bun.env.HOMEoros.homedir()) - Shell completion installation per platform
- JSON path escaping for Windows command line
yargs- CLI argument parsing and shell completions- Built-in Bun APIs for file system and subprocess
# List available plugins from installed Claude Code marketplaces
construct --list
# Load specific plugins for this session
construct --load tmux@scaryrawr-plugins --load chrome-devtools@scaryrawr-plugins
# Run with saved config
construct
# Pass through args to copilot (everything after -- goes to copilot)
construct -- --continue
# Combine construct flags with copilot passthrough
construct --load tmux@scaryrawr-plugins -- --allow-all-tools --continue
# Pass a prompt directly to copilot
construct -- "fix the failing tests"