@seungchan.m/swik
v0.8.4
Published
Migrate agent setup between Claude Code and OpenAI Codex CLI — CLAUDE.md/AGENTS.md, MCP servers, and skills. Safe and reversible.
Maintainers
Readme
swik
Move agent setup between Claude Code and OpenAI Codex CLI: instructions, MCP servers, and skills. Preview first, back up every write, restore when needed.
swik is a zero-dependency CLI for switching projects between Claude Code and OpenAI Codex CLI without rebuilding the same setup by hand. It migrates only portable agent config and reports anything that needs manual attention. It never touches accounts, sessions, chat history, or secret values.
Try It
Run once without installing:
npx @seungchan.m/swik status
npx @seungchan.m/swik convert cc codex --dry-runInstall globally:
npm install -g @seungchan.m/swikThen use swik:
swik status
swik sync --compile --dry-runCommon Workflows
Keep Both Tools in Sync
Create anything missing on either side, merge safe MCP/skill additions, and report conflicts without overwriting them:
swik sync --compile --dry-run
swik sync --compile --yesClaude Code to Codex
Preview first:
swik audit
swik convert cc codex --compile --dry-runApply after reviewing the plan:
swik convert cc codex --compile --yesUse --compile when you want Claude's instruction hierarchy folded into AGENTS.md:
CLAUDE.md
.claude/CLAUDE.md
.claude/rules/*.md
safe @include filesCodex to Claude Code
swik convert codex cc --dry-run
swik convert codex cc --yesUndo a Migration
swik backups
swik restore latestCreate a Handoff File
swik handoff --stdout
swik handoff --from codex --to cc
swik handoffhandoff creates CODEX-HANDOFF.md from git metadata only. It does not read raw chat, sessions, or file contents.
Home-Level Config
Use --global only when you intentionally want to inspect or migrate ~/.claude / ~/.codex allowlisted config:
swik status --global
swik convert cc codex --global --dry-run
swik convert cc codex --global --yes
swik restore latest --globalWhat It Moves
| Surface | Claude Code | Codex | Notes |
| --- | --- | --- | --- |
| Instructions | CLAUDE.md | AGENTS.md | --compile can fold Claude's hierarchy into one file |
| MCP servers | .mcp.json, .claude/settings.json | .codex/config.toml | stdio and HTTP URL servers; auth reviewed manually |
| Skills | .claude/skills/ | .agents/skills/ | copied as local skill folders |
Compatibility
swik is intentionally fixture-pinned instead of claiming full Claude/Codex compatibility. The 0.8.x contract is tested in this repo against Claude Code 2.1.162 and Codex CLI 0.136.0 project config shapes as of 2026-06.
| Config surface | Auto-converted | Manual/report only |
| --- | --- | --- |
| Codex MCP in .codex/config.toml | command, args, inline or nested env, HTTP url | cwd, enabled, required, timeout, tool allow/deny fields, OAuth, bearer_token_env_var, http_headers, unknown fields |
| Claude MCP in .mcp.json / .claude/settings.json#mcpServers | stdio command/args/env, HTTP type: "http" + url | sse/ws/SDK/proxy transports, OAuth, auth headers, duplicate names, local absolute paths |
| Instructions | CLAUDE.md; Claude hierarchy with --compile | local/private files unless --include-local, unsafe @include targets |
| Skills | local skill folders copied as files | runtime behavior, tool permissions, hooks, model choices |
Unknown fields are preserved only when swik appends to an existing config. They are not semantically translated unless listed above.
Out of scope by design:
- accounts and login state
- remote chat history and private sessions
- API keys and literal secret values
- Claude-only surfaces with no clean Codex equivalent
Example Output
$ swik convert cc codex --compile --dry-run
create AGENTS.md
create .codex/config.toml
copy .claude/skills -> .agents/skills
report swik-report.md$ swik audit
Migrated automatically:
✓ CLAUDE.md — root instructions → AGENTS.md
✓ MCP servers — 2 server(s) (stdio/http) → .codex/config.toml
✓ .claude/skills — → .agents/skills
Needs manual migration:
! .claude/agents — 1 custom agent(s) use tools/model/hooks; rebuild in Codex manually
! .claude/settings.json — non-MCP keys not migrated: hooks, permissions
Not portable:
✗ .claude/output-styles — no Codex equivalentCommand Reference
| Command | Copy-paste example |
| --- | --- |
| Inspect project | swik status |
| Machine-readable detection | swik detect |
| Full Claude surface audit | swik audit |
| Health check | swik doctor |
| Sync both tools safely | swik sync --compile --dry-run |
| Preview Claude Code -> Codex | swik convert cc codex --compile --dry-run |
| Apply Claude Code -> Codex | swik convert cc codex --compile --yes |
| Preview Codex -> Claude Code | swik convert codex cc --dry-run |
| Apply Codex -> Claude Code | swik convert codex cc --yes |
| List backups | swik backups |
| Restore latest backup | swik restore latest |
| Generate handoff | swik handoff |
| Print handoff only | swik handoff --stdout |
| Global status | swik status --global |
Provider aliases:
cc = claude = claude-code
codex = codexUseful flags:
| Flag | Meaning |
| --- | --- |
| --dry-run | preview changes and write nothing |
| --yes | allow a migration to write files |
| --force | allow overwriting files that are otherwise protected |
| --compile | synthesize Claude's instruction hierarchy into AGENTS.md |
| --include-local | include CLAUDE.local.md during --compile |
| --global | operate on allowlisted home-level config |
| --stdout | print handoff content instead of writing it |
Safety Model
Conservative by default:
--dry-runprints the plan and writes nothing.- Migration writes require
--yes. - Existing files are not overwritten without
--force. - Every migration snapshots originals to
.swik-backups/<timestamp>/. - In Git worktrees, project writes add
.swik-backups/andswik-report.mdto.git/info/excludebefore writing. restore latestrestores originals and removes files created by the migration.- Restore refuses to delete migration-created files you edited after migration unless you pass
--force.
.codex/config.toml is the only overwrite-rule exception: migrations preserve existing content and only append new, non-conflicting MCP servers.
Credentials and Secrets
MCP servers often need API keys or tokens. swik migrates the wiring — server names, commands, args, and env-var names — but never copies secret values into the other tool's config or the report.
If the source config has a literal env value, swik rewrites it as a $NAME reference in the target config and lists that variable in swik-report.md.
Backups preserve original files for exact rollback. If your source config already contains literal secrets, the local backup may contain them too. Project backups live in .swik-backups/; project writes inside Git add .swik-backups/ and swik-report.md to .git/info/exclude before writing. Global backups live outside the project at ~/.swik/backups/global/.
Compile Instructions
By default, cc -> codex copies only the root CLAUDE.md.
With --compile, swik writes a traceable AGENTS.md with source labels:
swik convert cc codex --compile --dry-run
swik convert cc codex --compile --yes
swik convert cc codex --compile --include-local --yesThe compiled output includes sections like:
# Project Instructions
Compiled from Claude Code by swik (--compile).
## From CLAUDE.md
...
## From .claude/rules/style.md
...Safe @path includes are inlined with source markers. Absolute paths, ~ paths, missing files, unsupported file types, oversized files, and circular includes are kept in place and reported.
Handoff
swik handoff writes a standalone CODEX-HANDOFF.md scaffold for the next agent:
swik handoff
swik handoff --stdout
swik handoff --from codex --to ccAuto-filled from git:
- current branch
- changed files from
git status - diff summary from
git diff --stat - recent commits from
git log --oneline
Left blank for you:
- goal
- decisions
- open TODO
- how to test
- known risks
- notes
Only the project basename is recorded, not your absolute local path.
Limitations
- Auto MCP conversion covers stdio (
command/args/env) and HTTP (url) servers. - Auth headers and bearer tokens are flagged for manual setup, not copied.
- Claude custom agents, commands, hooks, permissions, and output styles are reported rather than pretended to be portable.
- Raw chat history and private sessions are never migrated.
--globalis allowlist-only and never touches auth/session/state/log/cache files.- Codex TOML writing is append-oriented. The current zero-dependency parser handles the supported MCP subset; comment-preserving rewrites require an AST-backed TOML parser before that roadmap item should ship.
Roadmap
- [x] Credential inventory + multi-line TOML parsing (0.2.0)
- [x] Global
convert --global, allowlist-only (0.3.0) - [x]
.agents/skills+ HTTP MCPurlconversion (0.4.0) - [x]
audit— classify surfaces migrated / manual / not-portable (0.5.0) - [x]
convert --compile— flatten the CLAUDE.md hierarchy (0.6.0) - [x]
handoff— git-derived context scaffold (0.7.0) - [x]
sync— safe bidirectional project config reconcile (0.8.0) - [x] Project-local
.git/info/excludeprotection for backups and reports (0.8.2) - [ ] Adapters for Gemini CLI and Cursor
- [ ] Move Codex TOML editing to an AST-backed parser before preserving comments / unknown fields
- [ ] Opt-in
--include-env-valuesbehind an explicit danger warning
Contributing
Issues and PRs welcome. Built from public behavior and documented file formats only. Please do not add proprietary, leaked, or reverse-engineered source. See CONTRIBUTING.md and SECURITY.md.
