Skip to main content

Fetch and deploy AI agent resources from git repos to local tool directories

Project description

agpack

PyPI CI Python 3.11+ Ruff mypy License: GPL-3.0 Sponsor

Declare your AI agent resources in a YAML file, run agpack sync, and they get deployed to every coding tool you use.

agpack fetches skills, commands, agents, and MCP server configs from git repos and copies them to the right places for Claude Code, OpenCode, Codex, Cursor, and GitHub Copilot.

Why

Every AI coding tool has its own directory structure for skills, its own config format for MCP servers, its own spot for custom commands. If you use more than one tool -- or share resources across projects -- you end up manually copying files and keeping multiple configs in sync.

agpack replaces that with a single agpack.yml that describes what you want and where it comes from.

Install

pipx install agpack   # or: uv tool install agpack

Requires Python 3.11+ and git on PATH.

Quick start

agpack init          # creates agpack.yml with commented-out examples

Edit agpack.yml:

targets:
  - claude
  - opencode

dependencies:
  skills:
    - url: https://github.com/owner/repo
      path: skills/my-skill

  commands:
    - url: https://github.com/owner/repo
      path: commands/review.md

  agents:
    - url: https://github.com/owner/repo
      path: agents/backend-expert.md

  mcp:
    - name: filesystem
      command: npx
      args: ["-y", "@modelcontextprotocol/server-filesystem", "."]
agpack sync

Skills get copied to .claude/skills/, .opencode/skills/, etc. Commands and agents go to their respective directories. MCP server definitions get merged into each tool's config file. Run agpack sync again after editing the config -- removed dependencies get cleaned up automatically.

Dependencies

URLs and pinning

The url field takes any valid git clone URL -- HTTPS, SSH, local paths, whatever git understands. Authentication is handled by your system git config (SSH keys, credential helpers, etc.).

Use ref to pin a dependency to a specific tag or commit:

- url: https://github.com/owner/repo
  path: skills/my-skill
  ref: v1.2.0

- url: git@gitlab.com:myorg/myrepo.git
  path: skills/my-skill
  ref: abc1234

Directory expansion

The path field can point to a single file, a single folder, or a parent directory containing multiple items. When it points at a directory, agpack figures out what's inside:

  • Skills -- a directory with top-level files is deployed as one skill. A directory containing only subdirectories deploys each subfolder as a separate skill.
  • Commands & Agents -- every non-hidden file is deployed individually. If the directory only contains subdirectories, files inside those are collected instead.
skills:
  - url: https://github.com/owner/repo
    path: skills/my-skill       # deploys one skill

  - url: https://github.com/owner/repo
    path: skills                 # deploys each subfolder as a separate skill

commands:
  - url: https://github.com/owner/repo
    path: commands/review.md     # deploys one file

  - url: https://github.com/owner/repo
    path: commands               # deploys every file inside

If the directory contains no deployable files, sync fails with an error.

Environment variables

Use ${VAR_NAME} in any string value to reference environment variables. This works in URLs, paths, refs, MCP commands, args, env values, and server URLs.

dependencies:
  skills:
    - url: https://github.com/${GITHUB_ORG}/shared-skills
      path: skills/my-skill

  mcp:
    - name: context7
      command: npx
      args: ["-y", "@context7/mcp-server"]
      env:
        CONTEXT7_API_KEY: ${CONTEXT7_API_KEY}

Variables are resolved from up to three sources (highest priority first):

  1. .env in the project root (same directory as agpack.yml)
  2. .env in the global config directory (~/.config/agpack/)
  3. Shell environment

If a referenced variable is not found in any source, sync fails with an error. The .env parser supports KEY=VALUE, quoted values, # comments, blank lines, and export prefixes.

Global config

A global config defines dependencies shared across all your projects -- skills, agents, or MCP servers you want everywhere without repeating them in each agpack.yml.

agpack init --global   # creates ~/.config/agpack/agpack.yml

The global config uses the same dependencies block but has no targets (those are always per-project):

# ~/.config/agpack/agpack.yml
dependencies:
  skills:
    - url: https://github.com/owner/shared-skills
      path: skills/my-standard-skill

  mcp:
    - name: context7
      command: npx
      args: ["-y", "@upstash/context7-mcp@latest"]
      env:
        CONTEXT7_API_KEY: ${CONTEXT7_API_KEY}

Global dependencies are merged with the project config during sync. If the same dependency or MCP server appears in both, the project version wins.

To skip the global config, either pass --no-global on the command line or add global: false to your project's agpack.yml. The default path (~/.config/agpack/agpack.yml) can be overridden with the AGPACK_GLOBAL_CONFIG environment variable.

Target mapping

Target Skills Commands Agents MCP Config
Claude .claude/skills/<name>/ .claude/commands/<file> .claude/agents/<file> .mcp.json
OpenCode .opencode/skills/<name>/ .opencode/commands/<file> .opencode/agents/<file> opencode.json
Codex .agents/skills/<name>/ -- -- .codex/config.toml
Cursor .cursor/skills/<name>/ -- .cursor/agents/<file> .cursor/mcp.json
Copilot .github/skills/<name>/ .github/prompts/<file> .github/agents/<file> .vscode/mcp.json

Unsupported resource types are skipped silently. MCP definitions are merged into each tool's config file without touching servers agpack didn't create.

Commands

agpack init    [--config PATH] [--global]       Scaffold a new config file
agpack sync    [--config PATH] [--no-global]    Fetch and deploy all dependencies
               [--dry-run] [--verbose]
agpack status  [--config PATH] [--no-global]    Show installed vs configured state

How it works

  1. Loads agpack.yml and the global config (if present), merges them
  2. Resolves ${VAR} references from .env files and the shell
  3. Reads .agpack.lock.yml to diff against the previous state
  4. Cleans up files from removed dependencies
  5. Shallow-clones each repo (sparse checkout when path is set), copies files to all target directories
  6. Merges MCP configs into each tool's config file
  7. Writes an updated lockfile

Every file write is atomic (write-to-temp-then-rename). agpack never partially writes a file and never deletes anything it didn't create.

License

GPL-3.0 -- see LICENSE.

Project details


Download files

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

Source Distribution

agpack-0.3.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.

agpack-0.3.0-py3-none-any.whl (38.0 kB view details)

Uploaded Python 3

File details

Details for the file agpack-0.3.0.tar.gz.

File metadata

  • Download URL: agpack-0.3.0.tar.gz
  • Upload date:
  • Size: 97.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for agpack-0.3.0.tar.gz
Algorithm Hash digest
SHA256 50f9841698e1dbe51cd92119d07ae415638cb1d5bd446a9f8685ddc2e8b4c2b0
MD5 1c2cf154afc49442851c910840a52ef8
BLAKE2b-256 cfe77b4dc8e79e8d7d362d57f3c8b8633f70b5ba50c898e3e5a171a968737aeb

See more details on using hashes here.

Provenance

The following attestation bundles were made for agpack-0.3.0.tar.gz:

Publisher: release.yml on PhilippTh/agpack

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

File details

Details for the file agpack-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: agpack-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 38.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for agpack-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 795435fd8cd9863a161046dac870bcf34f55a41857598804a1e99ab2dae5a48b
MD5 a4605c9e922019ee6bbb466f75b7bb5f
BLAKE2b-256 50078528a12025aa91be53b5339c5100a2126d6da30da8e9991ebfe5cf0551ae

See more details on using hashes here.

Provenance

The following attestation bundles were made for agpack-0.3.0-py3-none-any.whl:

Publisher: release.yml on PhilippTh/agpack

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 Pingdom Monitoring Sentry Error logging StatusPage Status page