Docs menu

Share stacks

Pull other stacks into yours with include, from a folder, a git repo, or a zip, and approve the MCPs they bring.

Any pegboard.yaml can be included by another one. That’s how a team shares one set of MCPs and skills across repos, or how you keep your own setup in a repo and use it on every machine.

version: 1
include:
  - ./stacks/web                      # a folder
  - acme/agent-stack//web?ref=v3      # a git repo, with an optional path and ref
  - https://acme.dev/agent-stack.zip  # a zip, local or over https

Sources

Source What it is
./path, ../path, ~/path, /path A folder, used as-is, without cache or lock
owner/repo, github.com/owner/repo//path?ref=v1, https://…, git@… A git repo, with the same conventions as skill sources. owner/repo@skill doesn’t apply
./stack.zip, https://…/stack.zip A zip. The stack is at its root or inside its single top-level folder

The included folder needs a pegboard.yaml at its root. Git repos download with your system git, so private repos work with the credentials you already have.

How stacks merge

Included stacks merge in order, and then your own file:

  • MCPs. A later entry with the same name replaces the whole entry. Nothing is deep-merged.
  • Skills. Sources are joined. Two sources that provide a skill with the same name are an error, unless remove.skills drops one.
  • remove. It applies to the stack’s own subtree: what it declares and what it includes. Your root remove applies to everything.
  • policy. Every policy in the tree is checked against the final result, so an included policy can’t be relaxed.
  • agents, inherit, context. The root stack decides these. In an included stack they’re ignored, with a warning.

Includes can include other stacks, up to 10 levels deep. A cycle is an error, and so is including the same repo and path with two different refs. If the same stack is included twice, it’s loaded once, at its first position.

The plan shows where each resource comes from:

claude-code · global
  + mcp github   (~/.claude.json) npx -y @modelcontextprotocol/server-github
                 via acme/agent-stack//web?ref=v3
  + skill web    (~/.claude/skills/web → cache@a4f4bd7)
                 via acme/agent-stack//web?ref=v3

Approve MCPs from shared stacks

An MCP from a git or zip stack runs someone else’s code on your machine, so Pegboard asks first. The first time it appears, and whenever its command, URL, args, or variable names change, it’s a conflict:

claude-code · global
  ! mcp github  new MCP from included stack acme/agent-stack//web?ref=v3; review the command, then run with --approve
                npx -y @modelcontextprotocol/server-github  via acme/agent-stack//web?ref=v3

Read the command, then:

pegboard apply --approve

apply records what you approved in pegboard.lock. Commit the lock, and teammates who apply it aren’t asked again: the review happened once, in your pull request. --force doesn’t approve anything. MCPs from local folders are your own files and don’t need approval.

Trust boundaries

A stack from git or a zip can only point inside itself. In its skills, includes, and ${file:…} references, it can’t use ~/, absolute paths, or .. that leaves its folder. Otherwise a shared stack could read files from your machine and pass them to an MCP.

It can use ${env:…}, which reads variables you’ve exported.

Lock and update

pegboard.lock pins each git or zip stack by commit and content hash, under includes. With a complete lock and cache, apply doesn’t need the network, and if downloaded content doesn’t match its hash, apply fails.

To move to newer versions:

pegboard update

It lists what changed before writing the lock, including any new or changed MCP command:

~ include acme/agent-stack//web?ref=v3 4015f56 → 81f4ebe
~ mcp github npx -y @modelcontextprotocol/server-github → npx -y @modelcontextprotocol/[email protected] (via acme/agent-stack//web?ref=v3)

A changed MCP then needs --approve again.