You built a slash command that saves you twenty minutes a day. Great. But your teammate is still doing the same task by hand, and the new hire on the platform team has never heard of it.
This is the gap between personal automation and organizational leverage. A /deploy skill tucked inside your .claude/ directory helps exactly one person. A properly packaged plugin — with parameterized context files, MCP connections, and marketplace distribution — helps every engineer on your team the moment they type /.
This guide walks through the complete lifecycle: spotting the right workflow to abstract, building the skill, parameterizing it so any engineering manager can customize the output, packaging it with the correct directory structure, and shipping it through a marketplace your team already uses.
Step Zero: Spotting the Right Workflow
Not every repeated task deserves a plugin. Here's how to find the ones that do.
The best plugin candidates share three traits. They're frequent — someone on the team runs the workflow at least weekly. They're variable — the inputs change, but the structure stays the same. And they're high-context — they require knowledge that lives in people's heads rather than in documentation.
Stand-ups, sprint briefs, incident post-mortems, onboarding checklists, release notes — these are all workflows where the skeleton is predictable but the details shift every time. The worst candidates are one-off tasks or anything that genuinely requires novel judgment each run.
One-off migration scripts
Tasks that change shape every time
Workflows requiring manual approvals mid-stream
Processes only one person ever runs
Weekly team briefs with consistent structure
PR review checklists with team-specific rules
Sprint planning summaries across repos
Onboarding context generation for new hires
Concrete Example: The /team-brief Plugin
Walking through a real plugin from first idea to marketplace submission.
Let's ground this in something tangible. Your engineering org has six teams. Every Monday, each EM writes a brief covering what shipped last week, what's in progress, and what's blocked. They pull from GitHub PRs, Jira tickets, and Slack threads — all manually. It takes 30-45 minutes per manager per week.
This is a textbook plugin candidate: frequent, variable, high-context. The output format is stable (a summary document), but the inputs are unique per team and per week. Here's how to build /team-brief from scratch.
- 1
Start with a standalone skill
Create .claude/commands/team-brief.md in your own project. Write the instructions as if you're explaining the task to a competent colleague: pull merged PRs from the last 7 days, summarize Jira status changes, flag anything blocked for more than 48 hours, and format the result as a Slack-ready brief.
- 2
Abstract the team-specific parts
Your first draft likely hardcodes your GitHub org, Jira project key, Slack channel, and team name. Pull those out. Every value that differs between teams becomes a parameter, and every assumption about tooling becomes an MCP connection.
- 3
Write parameterized context files
Create a context file template that each EM fills out with their team's specifics: repo names, Jira board IDs, team members, reporting preferences. The skill reads this at runtime so the same plugin serves every team differently.
- 4
Package as a plugin with plugin.json
Move everything out of .claude/ and into a proper plugin directory structure. Add the manifest, configure MCP connections, and write a SKILL.md with frontmatter that lets Claude invoke it on schedule or by slash command.
- 5
Distribute through a marketplace
Push the plugin to your team's marketplace repo or submit it to the official Anthropic marketplace. Other EMs install it with a single command and configure their context file once.
Anatomy of the Plugin
Directory structure, SKILL.md, and manifest configuration.
team-brief plugin structure
treeteam-brief/
├── .claude-plugin/
│ └── plugin.json
├── skills/
│ └── generate-brief/
│ ├── SKILL.md
│ ├── template.md
│ └── examples/
│ └── sample-brief.md
├── context/
│ ├── team-config.template.yaml
│ └── README.md
├── .mcp.json
├── settings.json
└── README.md.claude-plugin/plugin.json{
"name": "team-brief",
"description": "Generate weekly team briefs from GitHub, Jira, and Slack data",
"version": "1.2.0",
"author": {
"name": "Platform Team"
},
"homepage": "https://github.com/your-org/team-brief-plugin",
"repository": "https://github.com/your-org/team-brief-plugin",
"license": "MIT"
}skills/generate-brief/SKILL.md---
name: generate-brief
description: Generate a weekly team brief from GitHub PRs, Jira tickets, and Slack threads. Use when preparing Monday standups or weekly status reports.
argument-hint: "[team-name]"
allowed-tools: Bash(gh *), Bash(jq *), Read, Grep
---
# Weekly Team Brief Generator
Generate a concise weekly brief for the team specified in $ARGUMENTS.
## Steps
1. Read the team config from `context/teams/$ARGUMENTS.yaml`
2. Pull merged PRs from the last 7 days using `gh pr list`
3. Fetch Jira ticket transitions via the configured MCP server
4. Identify blocked items (>48 hours without status change)
5. Format using the template in [template.md](template.md)
6. Include metrics: PRs merged, tickets completed, cycle time
## Output Format
Produce a Slack-ready markdown brief. Keep it under 500 words.
Highlight blockers at the top. Group shipped items by epic.
For a sample output, see [examples/sample-brief.md](examples/sample-brief.md).The Critical Piece: Context File Design
Parameterized context files are what make a plugin work for any team, not just yours.
This is where most plugin builders cut corners, and where the leverage either materializes or falls apart. A context file is a per-team (or per-user) configuration that the skill reads at runtime to customize its behavior. Without it, you end up with either a plugin so generic it's useless or one so specific it only works for the team that built it.
The key insight: context files are not settings files. Settings control behavior ("use bullet points"). Context files carry domain knowledge ("our repos are api-gateway, user-service, and billing-core, and our Jira project key is PLAT"). This distinction matters because settings can have sensible defaults, but context requires input from the person who knows the team.
context/team-config.template.yaml# Team Brief Plugin — Team Configuration
# Copy this file to context/teams/<team-name>.yaml and fill in your values.
team:
name: "Platform Team" # Display name in the brief header
slack_channel: "#platform-eng" # Where the brief gets posted
manager: "@jordan" # EM handle for attribution
sources:
github:
org: "your-org" # GitHub organization
repos: # Repositories to scan for PRs
- api-gateway
- user-service
- billing-core
label_filter: "team:platform" # Optional: only PRs with this label
jira:
project_key: "PLAT" # Jira project key
board_id: 42 # Board ID for sprint data
blocked_statuses: # Statuses that indicate a blocker
- "Blocked"
- "Waiting for Review"
slack:
channels: # Channels to scan for relevant threads
- "platform-eng"
- "platform-incidents"
preferences:
brief_style: "concise" # concise | detailed
include_metrics: true # Show velocity and cycle time
highlight_new_hires: true # Call out contributions from recent joins
blockers_first: true # Lead with blockers sectionEach team member who uses the plugin copies the template, fills in their team's specifics, and saves it as context/teams/<team-name>.yaml. The skill reads the right file based on the argument passed: /team-brief:generate-brief platform loads context/teams/platform.yaml.
This pattern — a single skill backed by per-team context files — is how you get org-level coverage from a single codebase. The plugin never needs to know how many teams exist or what their repos are called. It just reads whatever context file it's pointed at.
Wiring Up MCP Connections
Connecting your plugin to external systems without hardcoding credentials.
A team brief plugin is useless without data. MCP (Model Context Protocol) servers give your plugin authenticated access to external systems — GitHub, Jira, Slack, databases — without embedding credentials in the plugin itself.
The .mcp.json file at your plugin root declares which MCP servers the plugin needs. When someone installs the plugin, Claude Code connects to these servers using the credentials already configured on their machine.[1]
.mcp.json{
"mcpServers": {
"github": {
"command": "gh",
"args": ["mcp-server"],
"description": "GitHub data for PR and commit history"
},
"jira": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-jira"],
"env": {
"JIRA_URL": "https://your-org.atlassian.net"
},
"description": "Jira ticket and sprint data"
}
}
}Testing Before You Ship
Local testing, edge cases, and the feedback loop that makes plugins reliable.
Before you push a plugin to any marketplace, test it locally with the --plugin-dir flag. This loads your plugin directly without requiring installation, so you can iterate fast.
- 1
Load the plugin in development mode
bashclaude --plugin-dir ./team-brief - 2
Invoke the skill with test arguments
bash/team-brief:generate-brief platform - 3
Reload after changes without restarting
bash/reload-plugins - 4
Test with a second team's context file
bash/team-brief:generate-brief payments
Plugin testing checklist
Test with at least two different context files
A plugin that only works with your team's config is just a fancy script.
Verify missing fields produce helpful errors
When a required field is missing from the context file, the skill should tell the user what's missing and where to add it.
Check output length stays within bounds
A brief that runs to 2,000 words defeats the purpose. Validate your output constraints.
Run it on a week with no activity
Edge cases matter. The plugin should handle a quiet week gracefully, not throw errors.
Distribution and Versioning
Getting your plugin into the hands of every team that needs it.
Once your plugin is tested and solid, you have two distribution paths. For internal teams, the simplest approach is a team marketplace — a Git repository that serves as a plugin registry. Add your plugin directory, and anyone on the team can install it directly.
For broader distribution, submit to the official Anthropic marketplace through the submission forms at claude.ai/settings/plugins/submit or platform.claude.com/plugins/submit.
Either way, versioning matters. Use semantic versioning in your plugin.json. Bump the patch version for bug fixes, minor for new features that don't break existing context files, and major for changes that require users to update their configuration.
| Change type | Version bump | Example |
|---|---|---|
| Fix a typo in the brief template | Patch (1.2.0 → 1.2.1) | Template formatting correction |
| Add optional metrics section | Minor (1.2.0 → 1.3.0) | New preferences.include_velocity field |
| Rename context file fields | Major (1.2.0 → 2.0.0) | sources.github.org → sources.github.organization |
| Add new required MCP server | Major (1.2.0 → 2.0.0) | Slack MCP required for thread scanning |
Patterns That Scale
Lessons from teams running plugins across dozens of engineering groups.
What works at scale
- ✓
One plugin per workflow, not one plugin per team — let context files handle the differences
- ✓
Ship example context files for common setups (monorepo, microservices, single-app)
- ✓
Pin MCP server versions in .mcp.json to avoid breaking changes on update
- ✓
Use the SKILL.md description field aggressively — it's what triggers automatic invocation
- ✓
Keep supporting files (templates, examples) small and focused
Common mistakes to avoid
Hardcoding team names, repo lists, or project keys in the skill itself
Putting configuration inside .claude-plugin/ instead of at the plugin root
Skipping the template file and expecting users to figure out the schema
Building monolithic plugins that try to cover five different workflows
Beyond /team-brief: Other High-Leverage Plugins
The same pattern applies to dozens of team workflows.
The /team-brief example is just one application of this pattern. Once you've built one plugin with parameterized context files, the same architecture applies everywhere. Here are workflows that teams have successfully turned into shared plugins using the exact same approach — a SKILL.md with clear instructions, context files that carry team-specific knowledge, and MCP connections for external data.
| Plugin | What it does | Key context file fields |
|---|---|---|
| /incident-retro | Generates post-incident reviews from PagerDuty + Slack data | Service map, escalation policies, SLA thresholds |
| /release-notes | Compiles user-facing release notes from merged PRs | Product areas, audience segments, changelog format |
| /onboard-engineer | Creates onboarding context docs for new team members | Tech stack, key repos, team rituals, contact list |
| /sprint-health | Weekly sprint health dashboard from Jira data | Velocity targets, definition of done, risk thresholds |
| /pr-review | Runs team-specific code review against your standards | Style guide, security rules, test coverage minimums |
Getting Started Today
You don't need to build the whole thing at once. Start with a personal skill in .claude/commands/ that solves your own problem. Run it for a week. Pay attention to what you hardcode and what changes between runs. Those variable parts become your context file schema.
Once the skill works reliably for you, spend an hour converting it to a plugin: create the directory structure, write the manifest, and move the skill into skills/. Test it with --plugin-dir. Hand it to one teammate and watch where they get stuck — that's where your template file needs better comments.
The gap between a personal shortcut and a team-wide plugin is smaller than it looks. Most of the work is the skill itself. Packaging and distribution are mechanical steps. The real investment is in context file design, and that investment pays back every time a new team picks up your plugin and is running in five minutes instead of building their own from scratch.
Plugin launch readiness
Skill works reliably for at least two different teams
Context file template is complete with field-level comments
MCP connections declared in .mcp.json (no hardcoded credentials)
plugin.json has correct name, version, and description
README includes setup instructions and a quick-start example
Tested with --plugin-dir and /reload-plugins workflow
Semantic version tagged and ready for marketplace submission
Can I use a plugin across multiple projects without reinstalling?
Yes. Personal plugins installed at the user level (~/.claude/plugins/) are available in every project. For project-specific plugins, install them in the project's .claude/ directory or reference them in a team marketplace that all projects point to.
How do I update a plugin that's already installed by my team?
Bump the version in plugin.json and push to your marketplace repository. Team members can update through the plugin manager or by running /plugin update. Major version bumps should include migration notes in the README.
What happens if two plugins define a skill with the same name?
Plugin skills are namespaced by the plugin name (e.g., /team-brief:generate-brief vs /sprint-tools:generate-brief), so naming conflicts between plugins are impossible. Within a single plugin, each skill needs a unique name.
Can context files reference environment variables?
The context files themselves are YAML that the skill reads. You can design your skill to resolve environment variables from the context file values, but the YAML is not automatically interpolated. Use the !command syntax in SKILL.md for dynamic values.
- [1]Claude Code Docs — Plugins(code.claude.com)↩
- [2]Claude Code Docs — Skills(code.claude.com)↩
- [3]Claude Code Docs — Plugin Marketplaces(code.claude.com)↩
- [4]Medium — Packaging Team Conventions Into a Claude Skill(guillaume-r.medium.com)↩
- [5]Dev.to — Claude Code Configuration Blueprint for Production Teams(dev.to)↩
- [6]Medium — Configure Claude Code to Power Your Agent Team(medium.com)↩