Complete guide for using Spec Kit extensions to enhance your workflow.
- Introduction
- Getting Started
- Finding Extensions
- Installing Extensions
- Using Extensions
- Managing Extensions
- Configuration
- Troubleshooting
- Best Practices
Extensions are modular packages that add new commands and functionality to Spec Kit without bloating the core framework. They allow you to:
- Integrate with external tools (Jira, Linear, GitHub, etc.)
- Automate repetitive tasks with hooks
- Customize workflows for your team
- Share solutions across projects
- Clean Core: Keeps spec-kit lightweight and focused
- Optional Features: Only install what you need
- Community Driven: Anyone can create and share extensions
- Version Controlled: Extensions are versioned independently
- Spec Kit version 0.1.0 or higher
- A spec-kit project (directory with
.specify/folder)
specify version
# Should show 0.1.0 or higherLet's install the Jira extension as an example:
# 1. Search for the extension
specify extension search jira
# 2. Get detailed information
specify extension info jira
# 3. Install it
specify extension add jira
# 4. Configure it
vim .specify/extensions/jira/jira-config.yml
# 5. Use it
# (Commands are now available in Claude Code)
/speckit.jira.specstoissuesspecify extension search searches all active catalogs simultaneously, including the community catalog by default. Results are annotated with their source catalog and install status.
specify extension searchShows all extensions across all active catalogs (default and community by default).
# Search for "jira"
specify extension search jira
# Search for "issue tracking"
specify extension search issue# Find all issue-tracking extensions
specify extension search --tag issue-tracking
# Find all Atlassian tools
specify extension search --tag atlassian# Extensions by Stats Perform
specify extension search --author "Stats Perform"# Only show verified extensions
specify extension search --verified# Detailed information
specify extension info jiraShows:
- Description
- Requirements
- Commands provided
- Hooks available
- Links (documentation, repository, changelog)
- Installation status
# By name (from catalog)
specify extension add jiraThis will:
- Download the extension from GitHub
- Validate the manifest
- Check compatibility with your spec-kit version
- Install to
.specify/extensions/jira/ - Register commands with your AI agent
- Create config template
# From GitHub release
specify extension add <extension-name> --from https://github.com/org/spec-kit-ext/archive/refs/tags/v1.0.0.zip# For testing or development
specify extension add --dev /path/to/extension✓ Extension installed successfully!
Jira Integration (v1.0.0)
Create Jira Epics, Stories, and Issues from spec-kit artifacts
Provided commands:
• speckit.jira.specstoissues - Create Jira hierarchy from spec and tasks
• speckit.jira.discover-fields - Discover Jira custom fields for configuration
• speckit.jira.sync-status - Sync task completion status to Jira
⚠ Configuration may be required
Check: .specify/extensions/jira/
If your project was initialized with --ai-skills, extension commands are automatically registered as agent skills during installation. This ensures that extensions are discoverable by agents that use the agentskills.io skill specification.
✓ Extension installed successfully!
Jira Integration (v1.0.0)
...
✓ 3 agent skill(s) auto-registered
When an extension is removed, its corresponding skills are also cleaned up automatically. Pre-existing skills that were manually customized are never overwritten.
Extensions add commands that appear in your AI agent (Claude Code):
# In Claude Code
> /speckit.jira.specstoissues
# Or use a namespaced alias (if provided)
> /speckit.jira.sync
Most extensions require configuration:
# 1. Find the config file
ls .specify/extensions/jira/
# 2. Copy template to config
cp .specify/extensions/jira/jira-config.template.yml \
.specify/extensions/jira/jira-config.yml
# 3. Edit configuration
vim .specify/extensions/jira/jira-config.yml
# 4. Use the extension
# (Commands will now work with your config)Some extensions provide hooks that execute after core commands:
Example: Jira extension hooks into /speckit.tasks
# Run core command
> /speckit.tasks
# Output includes:
## Extension Hooks
**Optional Hook**: jira
Command: `/speckit.jira.specstoissues`
Description: Automatically create Jira hierarchy after task generation
Prompt: Create Jira issues from tasks?
To execute: `/speckit.jira.specstoissues`
You can then choose to run the hook or skip it.
specify extension listOutput:
Installed Extensions:
✓ Jira Integration (v1.0.0)
Create Jira Epics, Stories, and Issues from spec-kit artifacts
Commands: 3 | Hooks: 1 | Status: Enabled
# Check for updates (all extensions)
specify extension update
# Update specific extension
specify extension update jiraOutput:
🔄 Checking for updates...
Updates available:
• jira: 1.0.0 → 1.1.0
Update these extensions? [y/N]:
# Disable without removing
specify extension disable jira
✓ Extension 'jira' disabled
Commands will no longer be available. Hooks will not execute.
To re-enable: specify extension enable jiraspecify extension enable jira
✓ Extension 'jira' enabled# Remove extension (with confirmation)
specify extension remove jira
# Keep configuration when removing
specify extension remove jira --keep-config
# Force removal (no confirmation)
specify extension remove jira --forceExtensions can have multiple configuration files:
.specify/extensions/jira/
├── jira-config.yml # Main config (version controlled)
├── jira-config.local.yml # Local overrides (gitignored)
└── jira-config.template.yml # Template (reference)
Configuration is merged in this order (highest priority last):
- Extension defaults (from
extension.yml) - Project config (
jira-config.yml) - Local overrides (
jira-config.local.yml) - Environment variables (
SPECKIT_JIRA_*)
Project config (.specify/extensions/jira/jira-config.yml):
project:
key: "MSATS"
defaults:
epic:
labels: ["spec-driven"]Local override (.specify/extensions/jira/jira-config.local.yml):
project:
key: "MYTEST" # Override for local developmentEnvironment variable:
export SPECKIT_JIRA_PROJECT_KEY="DEVTEST"Final resolved config uses DEVTEST from environment variable.
File: .specify/extensions.yml
# Extensions installed in this project
installed:
- jira
- linear
# Global settings
settings:
auto_execute_hooks: true
# Hook configuration
# Available events: before_specify, after_specify, before_plan, after_plan,
# before_tasks, after_tasks, before_implement, after_implement,
# before_analyze, after_analyze, before_checklist, after_checklist,
# before_clarify, after_clarify, before_constitution, after_constitution,
# before_taskstoissues, after_taskstoissues
hooks:
after_tasks:
- extension: jira
command: speckit.jira.specstoissues
enabled: true
optional: true
prompt: "Create Jira issues from tasks?"In addition to extension-specific environment variables (SPECKIT_{EXT_ID}_*), spec-kit supports core environment variables:
| Variable | Description | Default |
|---|---|---|
SPECKIT_CATALOG_URL |
Override the full catalog stack with a single URL (backward compat) | Built-in default stack |
GH_TOKEN / GITHUB_TOKEN |
GitHub API token for downloads | None |
# Point to a local or alternative catalog (replaces the full stack)
export SPECKIT_CATALOG_URL="http://localhost:8000/catalog.json"
# Or use a staging catalog
export SPECKIT_CATALOG_URL="https://example.com/staging/catalog.json"Spec Kit uses a catalog stack — an ordered list of catalogs searched simultaneously. By default, two catalogs are active:
| Priority | Catalog | Install Allowed | Purpose |
|---|---|---|---|
| 1 | catalog.json (default) |
✅ Yes | Curated extensions available for installation |
| 2 | catalog.community.json (community) |
❌ No (discovery only) | Browse community extensions |
specify extension catalog listYou can view the main catalog management commands using --help:
specify extension catalog --help
Usage: specify extension catalog [OPTIONS] COMMAND [ARGS]...
Manage extension catalogs
╭─ Options ────────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ───────────────────────────────────────────────────────────────────────╮
│ list List all active extension catalogs. │
│ add Add a catalog to .specify/extension-catalogs.yml. │
│ remove Remove a catalog from .specify/extension-catalogs.yml. │
╰──────────────────────────────────────────────────────────────────────────────────╯
# Add an internal catalog that allows installs
specify extension catalog add \
--name "internal" \
--priority 2 \
--install-allowed \
https://internal.company.com/spec-kit/catalog.json
# Add a discovery-only catalog
specify extension catalog add \
--name "partner" \
--priority 5 \
https://partner.example.com/spec-kit/catalog.jsonThis creates or updates .specify/extension-catalogs.yml.
specify extension catalog remove internalYou can also edit .specify/extension-catalogs.yml directly:
catalogs:
- name: "default"
url: "https://raw.githubusercontent.com/github/spec-kit/main/extensions/catalog.json"
priority: 1
install_allowed: true
description: "Built-in catalog of installable extensions"
- name: "internal"
url: "https://internal.company.com/spec-kit/catalog.json"
priority: 2
install_allowed: true
description: "Internal company extensions"
- name: "community"
url: "https://raw.githubusercontent.com/github/spec-kit/main/extensions/catalog.community.json"
priority: 3
install_allowed: false
description: "Community-contributed extensions (discovery only)"A user-level equivalent lives at ~/.specify/extension-catalogs.yml. Project-level config takes full precedence when it contains one or more catalog entries. An empty catalogs: [] list falls back to built-in defaults.
Organizations customize their catalogs to:
- Control available extensions - Curate which extensions your team can install
- Host private extensions - Internal tools that shouldn't be public
- Customize for compliance - Meet security/audit requirements
- Support air-gapped environments - Work without internet access
Create a catalog.json file with your extensions:
{
"schema_version": "1.0",
"updated_at": "2026-02-03T00:00:00Z",
"catalog_url": "https://your-org.com/spec-kit/catalog.json",
"extensions": {
"jira": {
"name": "Jira Integration",
"id": "jira",
"description": "Create Jira issues from spec-kit artifacts",
"author": "Your Organization",
"version": "2.1.0",
"download_url": "https://github.com/your-org/spec-kit-jira/archive/refs/tags/v2.1.0.zip",
"repository": "https://github.com/your-org/spec-kit-jira",
"license": "MIT",
"requires": {
"speckit_version": ">=0.1.0",
"tools": [
{"name": "atlassian-mcp-server", "required": true}
]
},
"provides": {
"commands": 3,
"hooks": 1
},
"tags": ["jira", "atlassian", "issue-tracking"],
"verified": true
},
"internal-tool": {
"name": "Internal Tool Integration",
"id": "internal-tool",
"description": "Connect to internal company systems",
"author": "Your Organization",
"version": "1.0.0",
"download_url": "https://internal.your-org.com/extensions/internal-tool-1.0.0.zip",
"repository": "https://github.internal.your-org.com/spec-kit-internal",
"license": "Proprietary",
"requires": {
"speckit_version": ">=0.1.0"
},
"provides": {
"commands": 2
},
"tags": ["internal", "proprietary"],
"verified": true
}
}
}Options for hosting your catalog:
| Method | URL Example | Use Case |
|---|---|---|
| GitHub Pages | https://your-org.github.io/spec-kit-catalog/catalog.json |
Public or org-visible |
| Internal web server | https://internal.company.com/spec-kit/catalog.json |
Corporate network |
| S3/Cloud storage | https://s3.amazonaws.com/your-bucket/catalog.json |
Cloud-hosted teams |
| Local file server | http://localhost:8000/catalog.json |
Development/testing |
Security requirement: URLs must use HTTPS (except localhost for testing).
Add to .specify/extension-catalogs.yml in your project:
catalogs:
- name: "my-org"
url: "https://your-org.com/spec-kit/catalog.json"
priority: 1
install_allowed: trueOr use the CLI:
specify extension catalog add \
--name "my-org" \
--install-allowed \
https://your-org.com/spec-kit/catalog.json# In ~/.bashrc, ~/.zshrc, or CI pipeline
export SPECKIT_CATALOG_URL="https://your-org.com/spec-kit/catalog.json"# List active catalogs
specify extension catalog list
# Search should now show your catalog's extensions
specify extension search
# Install from your catalog
specify extension add jiraRequired fields for each extension entry:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Human-readable name |
id |
string | Yes | Unique identifier (lowercase, hyphens) |
version |
string | Yes | Semantic version (X.Y.Z) |
download_url |
string | Yes | URL to ZIP archive |
repository |
string | Yes | Source code URL |
description |
string | No | Brief description |
author |
string | No | Author/organization |
license |
string | No | SPDX license identifier |
requires.speckit_version |
string | No | Version constraint |
requires.tools |
array | No | Required external tools |
provides.commands |
number | No | Number of commands |
provides.hooks |
number | No | Number of hooks |
tags |
array | No | Search tags |
verified |
boolean | No | Verification status |
Host proprietary extensions that integrate with internal systems:
{
"internal-auth": {
"name": "Internal SSO Integration",
"download_url": "https://artifactory.company.com/spec-kit/internal-auth-1.0.0.zip",
"verified": true
}
}Limit which extensions your team can install:
{
"extensions": {
"jira": { "..." },
"github": { "..." }
}
}Only jira and github will appear in specify extension search.
For networks without internet access:
- Download extension ZIPs to internal file server
- Create catalog pointing to internal URLs
- Host catalog on internal web server
{
"jira": {
"download_url": "https://files.internal/spec-kit/jira-2.1.0.zip"
}
}Test new extensions before publishing:
# Start local server
python -m http.server 8000 --directory ./my-catalog/
# Point spec-kit to local catalog
export SPECKIT_CATALOG_URL="http://localhost:8000/catalog.json"
# Test installation
specify extension add my-new-extensionYou can still install extensions not in your catalog using --from:
# From catalog
specify extension add jira
# Direct URL (bypasses catalog)
specify extension add <extension-name> --from https://github.com/someone/spec-kit-ext/archive/v1.0.0.zip
# Local development
specify extension add --dev /path/to/extensionNote: Direct URL installation shows a security warning since the extension isn't from your configured catalog.
Error: `Extension 'jira' not found in catalog
Solutions:
- Check spelling:
specify extension search jira - Refresh catalog:
specify extension search --help - Check internet connection
- Extension may not be published yet
Error: Jira configuration not found
Solutions:
-
Check if extension is installed:
specify extension list -
Create config from template:
cp .specify/extensions/jira/jira-config.template.yml \ .specify/extensions/jira/jira-config.yml
-
Reinstall extension:
specify extension remove jira && specify extension add jira
Issue: Extension command not appearing in AI agent
Solutions:
-
Check extension is enabled:
specify extension list -
Restart AI agent (Claude Code)
-
Check command file exists:
ls .claude/commands/speckit.jira.*.md -
Reinstall extension
Error: Extension requires spec-kit >=0.2.0, but you have 0.1.0
Solutions:
-
Upgrade spec-kit:
uv tool upgrade specify-cli
-
Install older version of extension:
specify extension add <extension-name> --from https://github.com/org/ext/archive/v1.0.0.zip
Error: Tool 'jira-mcp-server/epic_create' not found
Solutions:
- Check MCP server is installed
- Check AI agent MCP configuration
- Restart AI agent
- Check extension requirements:
specify extension info jira
Error: Permission denied when accessing Jira
Solutions:
- Check Jira credentials in MCP server config
- Verify project permissions in Jira
- Test MCP server connection independently
Do commit:
.specify/extensions.yml(project extension config).specify/extensions/*/jira-config.yml(project config)
Don't commit:
.specify/extensions/.cache/(catalog cache).specify/extensions/.backup/(config backups).specify/extensions/*/*.local.yml(local overrides).specify/extensions/.registry(installation state)
Add to .gitignore:
.specify/extensions/.cache/
.specify/extensions/.backup/
.specify/extensions/*/*.local.yml
.specify/extensions/.registryFor teams:
- Agree on which extensions to use
- Commit extension configuration
- Document extension usage in README
- Keep extensions updated together
Example README section:
## Extensions
This project uses:
- **jira** (v1.0.0) - Jira integration
- Config: `.specify/extensions/jira/jira-config.yml`
- Requires: jira-mcp-server
To install: `specify extension add jira`Use local config for development:
# .specify/extensions/jira/jira-config.local.yml
project:
key: "DEVTEST" # Your test project
defaults:
task:
custom_fields:
customfield_10002: 1 # Lower story points for testingUse environment variables for CI/CD:
# .github/workflows/deploy.yml
env:
SPECKIT_JIRA_PROJECT_KEY: ${{ secrets.JIRA_PROJECT }}
- name: Create Jira Issues
run: specify extension add jira && ...Check for updates regularly:
# Weekly or before major releases
specify extension updatePin versions for stability:
# .specify/extensions.yml
installed:
- id: jira
version: "1.0.0" # Pin to specific versionOnly install extensions you actively use:
- Reduces complexity
- Faster command loading
- Less configuration
Document extension usage in your project:
# PROJECT.md
## Working with Jira
After creating tasks, sync to Jira:
1. Run `/speckit.tasks` to generate tasks
2. Run `/speckit.jira.specstoissues` to create Jira issues
3. Run `/speckit.jira.sync-status` to update statusA: Yes! Extensions are designed to work together. Install as many as you need.
A: No. Extensions are loaded on-demand and only when their commands are used.
A: Yes. Install with --dev or --from and keep private. Public catalog submission is optional.
A: Look for the ✓ Verified badge. Verified extensions are reviewed by maintainers. Always review extension code before installing.
A: No. Extensions can only add commands and hooks. They cannot modify core functionality.
A: Extensions use namespaced commands (speckit.{extension}.{command}), so conflicts are very rare. The extension system will warn you if conflicts occur.
A: Yes! Most extensions are open source. Check the repository link in specify extension info {extension}.
A: Go to the extension's repository (shown in specify extension info) and create an issue.
A: Once installed, extensions work offline. However, some extensions may require internet for their functionality (e.g., Jira requires Jira API access).
A: Extension configs are in .specify/extensions/{extension}/. Back up this directory or commit configs to git.
- Extension Issues: Report to extension repository (see
specify extension info) - Spec Kit Issues: https://github.com/statsperform/spec-kit/issues
- Extension Catalog: https://github.com/statsperform/spec-kit/tree/main/extensions
- Documentation: See EXTENSION-DEVELOPMENT-GUIDE.md and EXTENSION-PUBLISHING-GUIDE.md
Last Updated: 2026-01-28 Spec Kit Version: 0.1.0