extensions/EXTENSION-USER-GUIDE.md
Complete guide for using Spec Kit extensions to enhance your workflow.
Extensions are modular packages that add new commands and functionality to Spec Kit without bloating the core framework. They allow you to:
.specify/ folder)specify version
# Should show 0.1.0 or higher
Let'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.specstoissues
specify 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 search
Shows 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 jira
Shows:
# By name (from catalog)
specify extension add jira
This will:
.specify/extensions/jira/# 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 uses a skills-based integration (e.g., --integration claude, --integration codex) or was initialized with --integration-options="--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 coding 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 list
Output:
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 jira
Output:
🔄 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 jira
specify 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 --force
Extensions 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.yml)jira-config.yml)jira-config.local.yml)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 development
Environment 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 token for authenticated requests to GitHub-hosted URLs (raw.githubusercontent.com, github.com, api.github.com, codeload.github.com). Required when your catalog JSON or extension ZIPs are hosted in a private GitHub repository. | 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"
# Authenticate with a token (gh CLI, PAT, or GITHUB_TOKEN in CI)
export GITHUB_TOKEN=$(gh auth token)
# Search a private catalog added via `specify extension catalog add`
specify extension search jira
# Install from a private catalog
specify extension add jira-sync
The token is attached automatically to requests targeting GitHub domains. Non-GitHub catalog URLs are always fetched without credentials.
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 list
You 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.json
This creates or updates .specify/extension-catalogs.yml.
specify extension catalog remove internal
You 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:
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: true
Or 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 jira
Required 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:
{
"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-extension
You 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/extension
Note: Direct URL installation shows a security warning since the extension isn't from your configured catalog.
Error: `Extension 'jira' not found in catalog
Solutions:
specify extension search jiraspecify extension search --helpError: 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 coding agent
Solutions:
Check extension is enabled: specify extension list
Restart coding 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:
specify extension info jiraError: Permission denied when accessing Jira
Solutions:
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/.registry
For teams:
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 testing
Use 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 update
Pin versions for stability:
# .specify/extensions.yml
installed:
- id: jira
version: "1.0.0" # Pin to specific version
Only install extensions you actively use:
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 status
A: 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.
specify extension info)Last Updated: 2026-01-28 Spec Kit Version: 0.1.0