Fetch and deploy AI agent resources from git repos to local tool directories
Project description
agpack
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
# Recommended: install as an isolated tool
pipx install agpack
# or
uv tool install agpack
# Or with plain pip
pip install agpack
Requires Python 3.11+ and git on PATH.
Quick start
agpack init # creates agpack.yml with commented-out examples
Edit agpack.yml:
name: my-project
version: 0.1.0
targets:
- claude
- opencode
dependencies:
skills:
- url: https://github.com/PhilippTh/agent-assets
path: skills/article-review
- url: https://github.com/PhilippTh/agent-assets
path: skills/deep-dive
ref: v1.2.0
commands:
- url: https://github.com/PhilippTh/agent-assets
path: commands/review.md
agents:
- url: https://github.com/PhilippTh/agent-assets
path: agents/backend-expert.md
mcp:
- name: filesystem
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "."]
Then:
agpack sync
That's it. 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.
How dependencies work
The url field takes any valid git clone URL. HTTPS, SSH, local paths -- whatever git understands:
# GitHub over HTTPS
- url: https://github.com/owner/repo
path: skills/my-skill
# GitLab over SSH
- url: git@gitlab.com:myorg/myrepo.git
path: skills/my-skill
# Azure DevOps
- url: https://dev.azure.com/myorg/myproject/_git/myrepo
path: skills/my-skill
# Pinned to a tag
- url: https://github.com/owner/repo
path: skills/my-skill
ref: v1.0.0
# Pinned to a commit
- url: https://github.com/owner/repo
path: skills/my-skill
ref: abc1234
Authentication is handled entirely by your system git config -- SSH keys, credential helpers, whatever you already have set up.
The path field can point to a single file, a single skill folder, or a parent directory containing multiple items. When path points at a directory, agpack figures out what's inside:
- Skills -- a directory with top-level files is deployed as one skill. A directory that only contains subdirectories deploys each subfolder as a separate skill.
- Commands & Agents -- every non-hidden file in the directory is deployed individually. If the top level only has subdirectories, files inside those are collected instead.
skills:
# A single skill folder
- url: https://github.com/owner/repo
path: skills/my-skill
# A directory of skills -- each subfolder becomes its own skill
- url: https://github.com/owner/repo
path: skills
commands:
# A single command file
- url: https://github.com/owner/repo
path: commands/review.md
# A directory of commands -- every file inside is deployed
- url: https://github.com/owner/repo
path: commands
If the directory contains no deployable files, sync fails with an error.
Where things go
| 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 server definitions are merged into each tool's config file without touching servers agpack didn't create.
Commands
agpack sync
Fetches everything and deploys it. Run it again after changing agpack.yml -- removed dependencies get cleaned up automatically.
agpack sync [--dry-run] [--verbose] [--config PATH]
agpack status
Shows what's installed vs what's configured:
Skills:
✓ article-review (https://github.com/PhilippTh/agent-resources @ abc1234)
✗ new-skill (not yet synced)
Commands:
✓ review.md (https://github.com/PhilippTh/agent-resources @ abc1234)
MCP:
✓ filesystem → .mcp.json, opencode.json
agpack init
Creates a starter agpack.yml with commented-out examples.
Environment variables
Use ${VAR_NAME} syntax in config values to reference environment variables. agpack resolves them at sync time.
mcp:
- name: context7
command: npx
args: ["-y", "@context7/mcp-server"]
env:
CONTEXT7_API_KEY: ${CONTEXT7_API_KEY}
Variables are resolved from two sources, in order:
- A
.envfile in the project root (same directory asagpack.yml) - Your shell environment
The .env file takes precedence when a variable is defined in both places. If a referenced variable is not found in either source, sync fails with an error.
Example .env file:
# API keys — add .env to .gitignore!
CONTEXT7_API_KEY=sk-abc123
OPENAI_API_KEY=sk-xyz789
The .env parser supports KEY=VALUE, "quoted" and 'quoted' values, # comments, blank lines, and export prefixes.
How it works under the hood
- Loads
agpack.yml, validates it - Reads
.agpack.lock.ymlto see what was previously installed - Cleans up files from dependencies you've removed
- For each dependency: shallow-clones the repo (with sparse checkout when a
pathis set), copies files to all target directories - Merges MCP configs into each tool's config file
- 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agpack-0.2.1.tar.gz.
File metadata
- Download URL: agpack-0.2.1.tar.gz
- Upload date:
- Size: 92.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
140b071c7894a6f4e25c25480a03e95d10fcfb2b171c406d5f2872d1bfa24861
|
|
| MD5 |
421c48f88021f15754be478ad68737a8
|
|
| BLAKE2b-256 |
9ae14d5335911baeff9937b25fb40d91fb202a8776a73a8d691cda56a61fb0ff
|
Provenance
The following attestation bundles were made for agpack-0.2.1.tar.gz:
Publisher:
release.yml on PhilippTh/agpack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agpack-0.2.1.tar.gz -
Subject digest:
140b071c7894a6f4e25c25480a03e95d10fcfb2b171c406d5f2872d1bfa24861 - Sigstore transparency entry: 1186517206
- Sigstore integration time:
-
Permalink:
PhilippTh/agpack@d32da2d7cdfc46df1f4106635259d61e80404193 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/PhilippTh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d32da2d7cdfc46df1f4106635259d61e80404193 -
Trigger Event:
push
-
Statement type:
File details
Details for the file agpack-0.2.1-py3-none-any.whl.
File metadata
- Download URL: agpack-0.2.1-py3-none-any.whl
- Upload date:
- Size: 35.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a6ab308559e45c7e5c82434876b47f550e259f859aa93a5daed95f0b12c77be
|
|
| MD5 |
c1d0b78e6aea8754e9d2beeda034abba
|
|
| BLAKE2b-256 |
3838026466305658172748d287c7f38a229e2b93aa18c50fa0613f6bcee2bfb6
|
Provenance
The following attestation bundles were made for agpack-0.2.1-py3-none-any.whl:
Publisher:
release.yml on PhilippTh/agpack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agpack-0.2.1-py3-none-any.whl -
Subject digest:
1a6ab308559e45c7e5c82434876b47f550e259f859aa93a5daed95f0b12c77be - Sigstore transparency entry: 1186517222
- Sigstore integration time:
-
Permalink:
PhilippTh/agpack@d32da2d7cdfc46df1f4106635259d61e80404193 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/PhilippTh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d32da2d7cdfc46df1f4106635259d61e80404193 -
Trigger Event:
push
-
Statement type: