Skip to main content

skillferry

Your agent workflow, portable across tools and machines.

skillferry turns one versioned, Git-friendly workspace — skills, global instructions, and non-secret MCP connection templates — into the native configurations of Codex, Claude Code, and DeepSeek Harness, on macOS, Windows, and Linux. It never copies credentials or runtime state, and it tells you honestly, per asset, how portable that asset is.

Sync capabilities, not credentials. · Write skills once. Run them across agents. · Your agent capabilities should not be locked inside one client.

Table of contents

30-second demo

$ skillferry import --from codex --output ~/workspaces/demo   # 1. two skills + one MCP server
$ export GITHUB_PERSONAL_ACCESS_TOKEN=...                     # 2. token lives on this machine only
$ skillferry plan --workspace ~/workspaces/demo               # 3. grades for all three agents
SKILL release-checklist
  codex   native
  claude  native
  dsh     native
MCP github
  codex   translated   secret resolved from local env
  claude  translated   secret resolved from local env
  dsh     translated   inserted as dsh-mcp-client entries in the profile cordis.patch.yml
$ skillferry apply --workspace ~/workspaces/demo              # 4. one workspace, three agents
$ skillferry doctor --workspace ~/workspaces/demo             # 5. zero drift
$ skillferry export --shareable ~/workspaces/public           # proof: no secrets, ever
Exported 15 file(s). No secret references were expanded.

The five-beat flow — import, secret references, per-target grades, apply, secret-free export — is rehearsed in CI by the test suite (see tests/test_plan_apply.py, tests/test_importers.py, tests/test_export_audit.py) and was accepted natively on macOS in docs/acceptance/macos-native.md.

Before / after

Before After
Re-author the same skills, rules, and MCP configs per tool, per machine One workspace.toml + assets, git pull, skillferry apply
Tokens copied into configs that end up in Git secret:env/NAME references; each machine supplies real values locally
"Sync succeeded" with no idea what was lost in translation plan prints native / translated / degraded / manual / unsupported per asset with loss notes
Sync tools silently overwrite hand edits Per-path hash ledger: local modifications become conflicts (exit 3), never silent overwrites

Why this matters to real users: cross-machine skill/config loss is one of the most-requested fixes in the official trackers (claude-code #36693, #69231, codex #26691), and the MCP client-configuration split is an open standardization pain point (SEP-2633, MCP IG #2761).

Quick start

$ pipx install skillferry
$ skillferry init my-workspace && cd my-workspace
# add skills/**, edit instructions/global.md and mcp/servers.toml
$ skillferry plan          # read every grade and conflict first
$ skillferry apply         # backs up, writes only owned paths
$ skillferry doctor        # exit 0 = in sync

plan and apply are dry-run-safe by design: plan never writes, and apply refuses to run when any conflict exists. Exit codes: 0 in sync, 1 error, 2 safe drift, 3 conflict needs a human decision (--resolve <id>=adopt|overwrite|keep-local).

Compatibility matrix

Grades are produced by each adapter from an evidence-backed capability table (docs/AGENT_MATRIX.md); nothing is labeled native without a verified loading path.

Asset Codex Claude Code DeepSeek Harness
Skills (SKILL.md dirs) native~/.agents/skills/ native~/.claude/skills/ (docs) native~/.agents/skills/
Global rules native — marker blocks in ~/.codex/AGENTS.md translated — marker blocks in ~/.claude/CLAUDE.md native — marker blocks in $DSH_HOME/AGENTS.md
MCP (stdio) translated[mcp_servers.<name>] in ~/.codex/config.toml; secrets resolved from local env translated — user-level ~/.claude.json mcpServers (docs) translateddsh-mcp-client entries in the profile cordis.patch.yml
MCP (http/sse) manual (per-target instructions printed) manual manual
Extensions/plugins manual — declared expected state, never auto-installed manual manual

What the grades mean

plan grades are a promise about loading: native loads in the target's own format with nothing lost; translated works after a transformation the notes name; degraded works with known limits or unverified behavior; manual prints instructions instead of writing; unsupported does not apply. The full contract — merge order, conflicts, and exit codes — is in docs/PORTABILITY_CONTRACT.md.

Security boundary

The security model is architecture, not documentation. See docs/THREAT_MODEL.md; machine-verifiable highlights:

  • The workspace schema rejects literal secrets: MCP env values must be secret:env/NAME or secret:file/PATH references (src/skillferry/workspace.py, negative tests in tests/test_workspace.py).
  • export --shareable scans every copied file and refuses to export on any credential-shaped content; it never expands a reference (src/skillferry/secrets.py, tests/test_export_audit.py).
  • Backups are raw (0600, local-only, for exact rollback) plus redacted copies for human inspection (src/skillferry/io_ops.py, test_backups_redact_secrets).
  • JSON reports and logs contain references, never resolved values (test_env_secret_lands_only_in_local_config).
  • [protect] declares what a workspace may never manage (auth, sessions, sqlite, caches, embedded servers); mis-declarations fail at schema level.
  • scripts/audit_public_tree.py fails CI when the public tree contains credential patterns, machine paths, or runtime filenames.

Workspace layout

# workspace.toml — target-neutral by construction
schema_version = 1
[skills]                  directory = "skills"
                          default_targets = ["codex", "claude", "dsh"]
[instructions]            common = "instructions/global.md"   # marker | copy | include
[mcp]                     registry = "mcp/servers.toml"       # env: secret refs only
[extensions]              manifest = "extensions/manifest.toml"
[overlays]                platform_dir / target_dir / host_dir  # base < target < platform < host < local
[protect]                 paths = []                          # never-manage declarations

A complete runnable example ships in examples/starter-workspace (validated in CI), together with two seed skills: setup-skillferry and release-checklist.

Merge order is base < target < platform < host < local override; lists replace wholesale and dicts deep-merge, every value's origin is visible to plan, and conflicts are never silent (docs/PORTABILITY_CONTRACT.md).

Not a dotfiles / symlink / GUI tool

skillferry is deliberately a headless CLI. It is not a full-dotfiles synchronizer (it manages only declared, structured assets), it never creates symlinks or Windows junction/reparse points (the schema rejects them), it ships no GUI, it does not switch API providers, sync sessions/history, or "losslessly convert any plugin". The honest comparison with the existing landscape, including what we can and cannot claim about competitors, is in docs/COMPARISON.md.

Adapter development

Adding a target is bounded: implement adapters/base.py's interface (where each asset lands, the capability-backed grades, and the MCP rendering) and register it in adapters/registry.py. See docs/AGENT_MATRIX.md for the evidence bar each grade must meet.

Migrating from codex-profile-sync

skillferry migrate --from codex-profile-sync <bundle> --output <dir> converts the legacy bundle's skills and MCP declarations into a draft workspace (credential values become secret:env/... references; the bundle is never modified). Details in docs/MIGRATION.md.

Documentation map

The docs/ tree is indexed by docs/README.md. For your role, start with:

Role Start with
Everyone docs/PORTABILITY_CONTRACT.md — grades, merge order, conflicts, exit codes
Security review docs/THREAT_MODEL.md + SECURITY.md
Contributors CONTRIBUTING.md + docs/AGENT_MATRIX.md
Comparing alternatives docs/COMPARISON.md
Legacy migration docs/MIGRATION.md
Evidence records docs/acceptance/macos-native.md · docs/acceptance/windows-native.md

Chinese translations: README.zh-CN.md is the entry point, core documents live in docs/zh-CN/. Release history: CHANGELOG.md.

Roadmap

  • A (this release): the portable core — skills/rules/MCP rendering, grades, ownership ledger, import/export/migrate, CI on 3 OS × Python 3.11–3.13.
  • B: Gemini CLI adapter (first v1.x target), lockfile/provenance records.
  • C: team layer (scope/team overlays), SSH/remote targets.
  • D: reference implementations as the SKILL.md/mcp.json standards converge.

License

Apache-2.0. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

skillferry-0.1.0.tar.gz (97.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

skillferry-0.1.0-py3-none-any.whl (67.4 kB view details)

Uploaded Python 3

File details

Details for the file skillferry-0.1.0.tar.gz.

File metadata

  • Download URL: skillferry-0.1.0.tar.gz
  • Upload date:
  • Size: 97.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for skillferry-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9013fbb8e60577dc78ad2545de00cd72da26cedb200b8d1e95eff06adc2913f6
MD5 a88808ae23512428d725d34722419efc
BLAKE2b-256 4b3fb283c6746245a6cd53e871b8d3bd837616ab67f426529fd71fc6d855a542

See more details on using hashes here.

Provenance

The following attestation bundles were made for skillferry-0.1.0.tar.gz:

Publisher: release.yml on GreenLv/skillferry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file skillferry-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: skillferry-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 67.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for skillferry-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3c960615f7422df14c5908bf93ca4ca5d3b32f8777613953d8868f961897807b
MD5 914e727632233699194dad1a3611fd45
BLAKE2b-256 eb4ab5aee4acc10e4b649f1890e0cb3e8e4fb428a745ac5c4393d3c4a2b987af

See more details on using hashes here.

Provenance

The following attestation bundles were made for skillferry-0.1.0-py3-none-any.whl:

Publisher: release.yml on GreenLv/skillferry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page