Python SDK for the Musher bundle distribution platform. Pull versioned AI agent asset bundles — prompts, tool definitions, agent specs, and skills — into your Python applications.
Requires Python 3.13+.
pip install musher-sdkSet your API key as an environment variable:
export MUSHER_API_KEY="msk_..."The SDK resolves credentials automatically in this order:
MUSHER_API_KEYenvironment variable- OS keyring (
musher/{hostname}) - Credential file (
<data_dir>/credentials/<host_id>/api-key, must be0600)
You can also pass a token directly:
musher.configure(token="msk_...")importmusherbundle=musher.pull("myorg/my-bundle:1.0.0")
forfinbundle.files():
print(f"{f.logical_path}: {len(f.text())} chars")importmusherasyncwithmusher.AsyncClient() asclient:
bundle=awaitclient.pull("myorg/my-bundle:1.0.0")importmusherwithmusher.Client() asclient:
bundle=client.pull("myorg/my-bundle:1.0.0")
result=client.resolve("myorg/my-bundle:1.0.0")
asset=client.fetch_asset(
"prompts/system.md",
namespace="myorg",
slug="my-bundle",
version="1.0.0",
)Bundles provide typed accessors for each resource type:
bundle=musher.pull("myorg/my-bundle:1.0.0")
# Promptsprompt=bundle.prompt("system")
print(prompt.text())
# Skillsforskillinbundle.skills():
print(skill.name, skill.description)
# Toolsets and agent specstoolset=bundle.toolset("search-tools")
data=toolset.parse_json()
spec=bundle.agent_spec("reviewer")
config=spec.parse_json()Filter to a subset of resources with select():
selection=bundle.select(skills=["code-review"], prompts=["system"])The SDK integrates with popular AI agent frameworks:
- Claude — export bundles as Claude plugins or install skills to
.claude/skills/(examples) - OpenAI Agents — export skills as local directories or inline zips for the OpenAI shell tool (examples)
- PydanticAI — use bundle prompts as agent instructions with structured output (examples)
export MUSHER_API_URL="https://custom-registry.example.com"Default: https://api.musher.dev
frompathlibimportPathimportmushermusher.configure(
token="msk_...",
registry_url="https://custom-registry.example.com",
cache_dir=Path("/tmp/musher-cache"),
verify_checksums=True,
timeout=30.0,
max_retries=2,
)All parameters are optional — omitted values are auto-discovered.
See Configuration for the full reference (directory layout, credential chain, cache structure, TTL defaults).
The SDK uses a content-addressable disk cache:
- Blobs stored by SHA-256 hash, shared across registries
- Manifests and refs partitioned by registry hostname
- Manifests TTL: 24h; refs TTL: 5min
cache_clean()removes expired entries and garbage-collects unreferenced blobs
Cache management functions are available at the module level and on the Client:
importmusherinfo=musher.cache_info() # cache statisticsmusher.cache_remove("myorg/my-bundle:1.0.0") # remove cached metadata for a bundle versionmusher.cache_clean() # reclaim expired entries and unreferenced blobsmusher.cache_clear() # remove all cached datapath=musher.cache_path() # cache directory pathpull()/pull_async()— resolve + fetch all assets + verify checksumsresolve()/resolve_async()— resolve bundle references to manifestsfetch_asset()— fetch individual assets by logical path- Sync (
Client) and async (AsyncClient) clients - Typed handles:
SkillHandle,PromptHandle,ToolsetHandle,AgentSpecHandle bundle.select()— filter resources by type- Content-addressable cache with TTL and garbage collection
- Cache management:
cache_info(),cache_remove(),cache_clear(),cache_clean(),cache_path() export_claude_plugin()/install_claude_skills()— Claude integrationexport_openai_local_skill()/export_openai_inline_skill()— OpenAI Agents integration
See the examples/ directory for runnable code samples covering basic usage, Claude, OpenAI Agents, and PydanticAI integrations.
Apache-2.0