Convert Claude Code configurations (agents, commands, skills, MCPs) to OpenCode and Copilot formats.
Run directly from Git without installing:
# Use latest version
uvx --from git+https://github.com/DylanLIiii/vingineer.git claude-migrate convert opencode
# Pin to specific version (recommended for production)
uvx --from git+https://github.com/DylanLIiii/vingineer.git@v0.1.0 claude-migrate convert opencode
# With options
uvx --from git+https://github.com/DylanLIiii/vingineer.git claude-migrate convert opencode --output ./my-configsNote: Replace YOUR_ORG/YOUR_REPO with the actual GitHub organization and repository name.
If you want to install the tool permanently and use it without --from:
# Install latest from main branch
uv tool install git+https://github.com/DylanLIiii/vingineer.git
# Install specific version
uv tool install git+https://github.com/DylanLIiii/vingineer.git@v0.1.0
# Now you can use it directly (add to PATH if needed)
claude-migrate convert opencodeTo use after installation, you may need to run:
uv tool update-shell # or restart your terminaluvx --from git+https://github.com/DylanLIiii/vingineer.git claude-migrate convert opencodeuv tool install git+https://github.com/DylanLIiii/vingineer.git
# May need to update PATH
uv tool update-shell
# Then use directly
claude-migrate convert opencodegit clone https://github.com/DylanLIiii/vingineer.git
cd YOUR_REPO
pip install -e .pip install claude-migrateUse this if you want to install the tool permanently on your system.
pip install -e .# Auto-detects config scope:
# - If ./.claude exists, uses project config (outputs to ./.opencode)
# - Otherwise uses ~/.claude (outputs to ~/.config/opencode)
claude-migrate convert opencode
# Custom output directory (overrides default)
claude-migrate convert opencode --output ./my-configs
# JSON format (single opencode.json file instead of directories)
claude-migrate convert opencode --format json
# Include installed Claude plugins
claude-migrate convert opencode --plugins# Auto-detects config scope:
# - If ./.claude exists, uses project config (writes .github/... into CWD)
# - Otherwise uses ~/.claude (writes to ./copilot_export)
claude-migrate convert copilot
# Custom output directory (overrides default)
claude-migrate convert copilot --output ./my-configs# Preview changes without writing files
claude-migrate convert opencode --dry-run
# Force overwrite existing files (automatic backups are always created)
claude-migrate convert opencode --force
# Verbose output
claude-migrate convert opencode --verbose
# Explicitly specify config source (overrides auto-detection)
claude-migrate convert opencode --source ~/.claude
# Explicitly choose config scope (user or project level)
claude-migrate convert opencode --scope user
claude-migrate convert opencode --scope project
# Include installed Claude plugins
claude-migrate convert opencode --plugins| Type | Claude Code Location | OpenCode | Copilot |
|---|---|---|---|
| Agents | ~/.claude/agents/*.md or ./.claude/agents/*.md(or plugins, namespaced as pluginName:agent) |
agent/*.md |
.github/agents/*.agent.md (with infer: true, target: vscode) |
| Commands | ~/.claude/commands/*.md or ./.claude/commands/*.md(or plugins, namespaced as pluginName:command) |
command/*.md |
.github/prompts/*.prompt.md |
| Skills | ~/.claude/skills/*/SKILL.md or ./.claude/skills/*/SKILL.md(or plugins, namespaced as pluginName:skill) |
N/A (Natively supported) | .github/skills/*/SKILL.md |
| MCP Servers | ~/.claude/.mcp.json or ./.claude/.mcp.json(or plugins, namespaced as pluginName:server) |
mcp.json |
mcp.json |
Note: Use --plugins flag to include installed Claude plugins (agents, commands, skills, MCPs from ~/.claude/plugins/).
When converting to Copilot format, the tool generates configurations compatible with VS Code's Copilot customization specification.
| Feature | Status | Notes |
|---|---|---|
| Prompt Files | ✅ Full support | Generates .github/prompts/*.prompt.md with name, description, model, agent fields |
| Custom Agents | ✅ Full support | Generates .github/agents/*.agent.md with infer: true and target: vscode defaults |
| Agent Skills | ✅ Full support | Generates .github/skills/*/SKILL.md following Agent Skills standard |
| MCP Servers | ✅ Full support | Generates mcp.json with type mapping (local→stdio, remote→sse) |
The following VS Code Copilot features are not currently supported because Claude Code doesn't provide equivalent fields:
envFilefor MCP servers (useenvfield instead)inputssection for MCP server variables (use environment variables directly)- Custom agent
handoffs(manual configuration required) .github/copilot-instructions.md(create manually if needed)
Directory Format (default):
# Copy to OpenCode config location
cp -r opencode_export/* ~/.config/opencode/
# Or use project-level config
cp -r opencode_export/* .opencode/JSON Format:
# Copy the monolithic opencode.json file
cp opencode_export/opencode.json ~/.config/opencode/
# Or use project-level
cp opencode_export/opencode.json .opencode/# Copy to your GitHub workspace
cp -r copilot_export/.github .github/
# Copy mcp.json
cp copilot_export/mcp.json mcp.json
# Or merge with existing mcp.json
jq -s '.mcpServers += input.mcpServers' mcp.json < copilot_export/mcp.json > mcp.jsonFiles are automatically backed up before overwriting to prevent data loss.
- Location:
~/.claude-migrate/backups/ - Structure: Maintains relative directory structure
- Format:
<filename>.backup_YYYYMMDD_HHMMSS - Retention: Last 5 backups per file (older ones automatically deleted)
- Always active: Backups are created even with
--forceflag
~/.claude-migrate/backups/
├── agent/
│ ├── test-agent.md.backup_20250106_142530
│ └── test-agent.md.backup_20250106_153000
├── command/
│ └── deploy.md.backup_20250106_140000
└── skill/
└── review/SKILL.md.backup_20250106_130000
To restore a file from backup:
# Find backups
ls ~/.claude-migrate/backups/agent/
# Copy backup back
cp ~/.claude-migrate/backups/agent/test-agent.md.backup_20250106_142530 \
~/.config/opencode/agent/test-agent.mdThe tool auto-detects config scope as follows:
- Project scope: If
./.claude/exists in the current working directory, the tool loads project-level config only. - User scope: Otherwise, the tool loads from
~/.claude/.
You can override auto-detection with:
--source PATH- Specify an explicit config directory--scope [user|project]- Explicitly choose user or project scope (errors if the specified scope doesn't exist)
Plugins are loaded from ~/.claude/plugins/installed_plugins.json when you pass --plugins. Plugin items are namespaced as pluginName:itemId to avoid collisions.
When using uvx from Git, you can pin to specific versions using git tags:
| Command | Description |
|---|---|
uvx --from git+https://github.com/DylanLIiii/vingineer.git claude-migrate ... |
Latest on main branch |
uvx --from git+https://github.com/DylanLIiii/vingineer.git@v0.1.0 claude-migrate ... |
Specific version (recommended) |
uvx --from git+https://github.com/DylanLIiii/vingineer.git@main claude-migrate ... |
Latest on main branch (explicit) |
uv tool install git+https://github.com/DylanLIiii/vingineer.git |
Install persistently to system |
Tip: Always pin to a specific version tag in production scripts for reproducibility.
To install the tool permanently and use it like any other CLI command:
# Install latest version
uv tool install git+https://github.com/DylanLIiii/vingineer.git
# Install specific version
uv tool install git+https://github.com/DylanLIiii/vingineer.git@v0.1.0
# Run directly (may need to restart terminal or run `uv tool update-shell`)
claude-migrate convert opencodeTo create a new release tag:
# Tag the release
git tag -a v0.2.0 -m "Release v0.2.0"
# Push the tag
git push origin v0.2.0The CI/CD workflow will verify the build for the tagged version.
Convert Claude Code configurations to target format.
Arguments:
TARGET- Target format:opencodeorcopilot
Options:
-o, --output PATH- Output directory (default depends on target and scope)--source PATH- Claude config directory to read from (overrides auto-detection)-s, --scope [user|project]- Config scope:user(~/.claude) orproject(./.claude). Default: auto-detect (project takes precedence)--plugins- Include installed Claude plugins-f, --format [dir\|json]- Output format (only for OpenCode, default:dir)-n, --dry-run- Preview changes without writing files--force- Overwrite existing files (automatic backups are always created)-v, --verbose- Enable verbose output--version- Show version and exit--help- Show help message and exit
Default output directories (when --output is not specified):
| Target | Scope | Default Output |
|---|---|---|
| opencode | project | ./.opencode |
| opencode | user | ~/.config/opencode |
| copilot | project | ./ (writes .github/... into workspace) |
| copilot | user | ./copilot_export |
claude-migrate convert opencode --format json --output ./opencode-configsclaude-migrate convert copilot --dry-run --verbose# Using --source (original method)
claude-migrate convert opencode --source ~/.claude
# Using --scope (new method, clearer intent)
claude-migrate convert opencode --scope user# Explicitly use project scope (errors if ./.claude doesn't exist)
claude-migrate convert opencode --scope project# Must be run in a directory with ./.claude
claude-migrate convert opencode --pluginsclaude-migrate convert opencode --forceEnsure at least one of the following exists:
./.claude/(for project scope)~/.claude/(for user scope)
If neither exists, run Claude Code at least once to create the configuration.
Use the --force flag to overwrite existing files (automatic backups created):
claude-migrate convert opencode --forceImportant: Files are always backed up before overwriting. Backups are stored at ~/.claude-migrate/backups/ and the last 5 backups per file are retained.
Ensure your Claude Code configuration exists:
ls ~/.claude/agents/
ls ~/.claude/commands/
ls ~/.claude/skills/If using project-level configs, ensure .claude/ exists in your project directory.
The --plugins flag only works in project scope. If you want to include plugins for user-level conversion, use --source ~/.claude and move to a directory with a ./.claude folder first, or copy the plugin contents manually.
Check that your .mcp.json is valid JSON:
cat ~/.claude/.mcp.json | python -m json.toolCheck for conversion errors in the statistics summary. Files with errors are skipped.
Use --verbose to see detailed detection information. If using plugins, check that plugin directory paths are valid and contain the expected .claude/agents, .claude/commands, etc. subdirectories.
# Install in development mode
pip install -e .
# Run all tests
pytest
# Run with coverage
pytest --cov=claude_migrate --cov-report=html
# Run specific test file
pytest tests/test_utils.py# Lint code
ruff check src/claude_migrate
# Format code
ruff format src/claude_migrate
# Type check
mypy src/claude_migrateclaude_migrate/
├── src/
│ └── claude_migrate/
│ ├── __init__.py
│ ├── cli.py
│ ├── models.py
│ ├── utils.py
│ └── formats/
│ ├── __init__.py
│ ├── claude_code.py
│ ├── opencode.py
│ └── copilot.py
├── tests/
│ ├── fixtures/
│ │ ├── claude_minimal/
│ │ ├── claude_typical/
│ │ └── claude_edge_cases/
│ ├── test_cli.py
│ ├── test_formats.py
│ └── test_utils.py
├── pyproject.toml
└── README.md
MIT
Contributions are welcome! Please feel free to submit a Pull Request.