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) translated — dsh-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.

Metadata

Release files for skillferry 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for skillferry 0.1.0
File Size Uploaded
skillferry-0.1.0.tar.gz 97.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for skillferry 0.1.0
File Interpreter ABI Platform
skillferry-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 165.2 kB

Release files / skillferry-0.1.0.tar.gz

Download URL skillferry-0.1.0.tar.gz
Size 97.7 kB
Tags Source
SHA-256 checksum
How to use checksums
9013fbb8e60577dc78ad2545de00cd72da26cedb200b8d1e95eff06adc2913f6
BLAKE2b-256 checksum
How to use checksums
4b3fb283c6746245a6cd53e871b8d3bd837616ab67f426529fd71fc6d855a542
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Release files / skillferry-0.1.0-py3-none-any.whl

Download URL skillferry-0.1.0-py3-none-any.whl
Size 67.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3c960615f7422df14c5908bf93ca4ca5d3b32f8777613953d8868f961897807b
BLAKE2b-256 checksum
How to use checksums
eb4ab5aee4acc10e4b649f1890e0cb3e8e4fb428a745ac5c4393d3c4a2b987af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page