If you use Claude Code, you have probably typed the same context into prompts over and over. "Here's my PR diff..." or "The current database schema is..." or "These are the failing tests..."
What if your prompts could fetch that data themselves, automatically, every time you run them?
That is exactly what Dynamic Context Injection does. It is one of Claude Code's most powerful features, and almost nobody knows it exists.
New to DCI? Read our step-by-step companion guide: How to Use Dynamic Context Injection in Claude Code, which walks you through building your first DCI-powered skill from scratch.
What is Dynamic Context Injection?
Dynamic Context Injection lets you embed shell commands directly in your Claude Code skills. When the skill runs, those commands execute first, and their output gets injected into the prompt before Claude sees it.
The syntax is simple: wrap any shell command in !`command` (exclamation mark, then backticks).
Here is a basic example:
---
name: pr-review
description: Review the current pull request
---
## Current PR Diff
!`gh pr diff`
## PR Comments
!`gh pr view --comments`
Review this pull request for code quality and potential issues.
When you invoke this skill, Claude does not receive the literal text !`gh pr diff`. Instead, it receives the actual diff output from GitHub. The shell command runs, captures the result, and injects it into the prompt.
Claude sees something like this:
## Current PR Diff
diff --git a/src/auth.js b/src/auth.js
index 1234567..abcdefg 100644
--- a/src/auth.js
+++ b/src/auth.js
@@ -45,6 +45,12 @@ function validateToken(token) {
+ if (!token) {
+ throw new Error('Token required');
+ }
...
## PR Comments
@reviewer: The token validation looks good but consider edge cases
Review this pull request for code quality and potential issues.
Why Context Engineering Matters
This is not just a convenience feature. It represents a fundamental shift in how we work with AI tools, and a key reason behind Claude Code's rapid growth among non-coders.
"Context engineering is the delicate art and science of filling the context window with just the right information for the next step."
- Andrej Karpathy, on X (June 2025)
When I first read Karpathy's tweet, it crystallised something I had been experiencing but could not articulate. Working with Claude Code had already shown me that the quality of responses depends almost entirely on the quality of context you provide. But manually copying and pasting that context every time? That is where the friction kills productivity.
Dynamic Context Injection solves this elegantly. You define the context sources once, and they refresh automatically every time you run the skill. Your PR review skill always has the latest diff. Your test analysis skill always has the current failures. Your deployment skill always has the live server status.
Practical Examples
Let me show you some real-world uses that have transformed my workflow.
Example 1: PR Review with Full Context
---
name: pr-review
description: Comprehensive pull request review
context: fork
---
## PR Overview
!`gh pr view --json title,body,author,labels --jq '.'`
## Changed Files
!`gh pr diff --name-only`
## Full Diff
!`gh pr diff`
## CI Status
!`gh pr checks`
## Related Issues
!`gh pr view --json closingIssuesReferences --jq '.closingIssuesReferences[]'`
Review this PR thoroughly:
1. Code quality and best practices
2. Potential bugs or edge cases
3. Security considerations
4. Performance implications
5. Test coverage gaps
This single skill replaces what used to be five or six manual copy-paste operations. Every invocation gets fresh data.
Example 2: Database Schema Analysis
---
name: db-analyse
description: Analyse database schema and suggest optimisations
---
## Current Schema
!`mysql -u root -p$DB_PASS -e "SHOW TABLES; DESCRIBE users; DESCRIBE orders; DESCRIBE products;"`
## Table Sizes
!`mysql -u root -p$DB_PASS -e "SELECT table_name, ROUND(data_length/1024/1024, 2) as 'Size (MB)' FROM information_schema.tables WHERE table_schema = DATABASE();"`
## Slow Queries (Last Hour)
!`mysql -u root -p$DB_PASS -e "SELECT * FROM mysql.slow_log WHERE start_time > NOW() - INTERVAL 1 HOUR LIMIT 10;"`
Analyse the database schema and performance data above.
Suggest optimisations for:
- Index improvements
- Query optimisation
- Schema normalisation issues
Example 3: Deployment Verification
---
name: deploy-check
description: Pre-deployment health check
---
## Git Status
!`git status --short`
## Unpushed Commits
!`git log origin/main..HEAD --oneline`
## Test Results
!`npm test 2>&1 | tail -50`
## Build Output
!`npm run build 2>&1 | tail -30`
## Current Production Version
!`curl -s https://api.mysite.com/health | jq '.version'`
Analyse this deployment readiness:
1. Are there uncommitted changes that need attention?
2. Did all tests pass?
3. Did the build succeed?
4. Is it safe to deploy?
The Workflow Transformation
Here is what changes when you adopt Dynamic Context Injection:
| Task | Before (Manual) | After (Dynamic Injection) |
|---|---|---|
| PR Review | Copy diff, copy comments, copy CI status, paste into prompt | Run /pr-review: all context injected automatically |
| Debug Failing Tests | Run tests, copy output, describe what you expected | Run /debug-tests: live failures + related code injected |
| Schema Changes | Export schema, copy into prompt, describe current state | Run /db-migrate: current schema + migration history injected |
| Log Analysis | Tail logs, copy errors, paste into prompt | Run /analyse-logs: last 100 errors injected with timestamps |
| Code Review | Find changed files, read each one, copy relevant sections | Run /review: changed files + their contents injected |
The time savings compound. But more importantly, you stop forgetting to include relevant context. How many times have you got a suboptimal response because you forgot to mention something Claude needed to know?
The Shift in Thinking
"In essence a language model changes you from a programmer who writes lines of code, to a programmer that manages the context the model has access to, prunes irrelevant things, adds useful material to context, and writes detailed specifications."
- Liz Fong-Jones, via Simon Willison's blog
This quote hit me hard. After years of writing code, the shift to "context management" felt strange at first. But Dynamic Context Injection makes it tangible. You are not just writing prompts anymore. You are designing systems that assemble context intelligently.
The skills I have built are not clever prompts. They are context pipelines. Each one defines what information Claude needs and how to fetch it fresh every time. Combined with orchestrating multiple AI CLI agents, DCI turns Claude Code into a full automation platform.
Advanced Patterns
Chaining Commands
You can chain shell commands for more complex data extraction:
## Failed Tests with Source
!`npm test 2>&1 | grep "FAIL" | head -5`
## Git Blame for Failing File
!`git blame $(npm test 2>&1 | grep "FAIL" | head -1 | awk '{print $2}') | head -20`
Conditional Context
Use shell logic to include context conditionally:
## Docker Status (if running)
!`docker ps 2>/dev/null || echo "Docker not running"`
## Package Lock Changes (if any)
!`git diff package-lock.json 2>/dev/null | head -50 || echo "No package changes"`
API Data Injection
Fetch live data from APIs:
## Current API Response
!`curl -s https://api.myservice.com/health | jq '.'`
## Latest Error Logs
!`curl -s -H "Authorization: Bearer $API_KEY" https://api.myservice.com/logs?level=error&limit=10 | jq '.'`
Use Cases by Role
| Role | Skill Idea | Injected Context |
|---|---|---|
| Frontend Developer | Component audit | Component tree, prop types, CSS dependencies |
| Backend Developer | API documentation | OpenAPI spec, current routes, response schemas |
| DevOps Engineer | Incident response | Pod status, recent logs, resource metrics |
| Database Admin | Query optimisation | EXPLAIN output, table stats, index usage |
| Security Engineer | Vulnerability assessment | Dependency audit, security headers, exposed endpoints |
| Tech Lead | Sprint review | Merged PRs, closed issues, deployment history |
Getting Started
Ready to build your first dynamic skill? Here is how:
- Create the skills directory if it does not exist:
mkdir -p .claude/skills/my-skill - Create a SKILL.md file with the frontmatter and your dynamic commands:
touch .claude/skills/my-skill/SKILL.md - Add your skill definition:
--- name: my-skill description: Description of what this skill does --- ## Live Data !`your-shell-command-here` Your instructions for Claude... - Test it by running
/my-skillin Claude Code
Start simple. A skill that injects your current git status and recent commits is a good first project. Once you see it working, you will immediately think of a dozen more uses.
For a more detailed walkthrough with real examples you can copy and adapt, see our full tutorial: How to Use Dynamic Context Injection in Claude Code.
Tips for Effective Context Injection
- Limit output size: Use
| head -50or| tail -30to avoid overwhelming context windows - Handle errors gracefully: Add
2>/dev/null || echo "fallback"for commands that might fail - Use jq for JSON: Format API responses cleanly with
| jq '.' - Cache expensive operations: For slow commands, consider caching output to a temp file
- Document your skills: Future you will thank present you for clear descriptions
- Compare approaches: If you are evaluating Claude against other models, our sister site's Claude vs ChatGPT comparison breaks down the coding and creative writing differences
Frequently Asked Questions
What exactly is Dynamic Context Injection in Claude Code?
Dynamic Context Injection is a feature in Claude Code skills that lets you embed shell commands in your skill files using the !`command` syntax. When the skill runs, these commands execute first, and their output is injected into the prompt before Claude processes it. This means your prompts can include live, fresh data like git diffs, API responses, database queries, or log files without manual copy-pasting.
Where do I put my Claude Code skills?
Skills go in the .claude/skills/ directory in your project root. Each skill lives in its own subfolder with a SKILL.md file. For example: .claude/skills/pr-review/SKILL.md. You can also create global skills in your home directory at ~/.claude/skills/ that work across all projects.
Is it safe to run shell commands in prompts?
The commands execute with your user permissions, so treat them as you would any shell script. Avoid hardcoding sensitive credentials; use environment variables instead. The commands run locally on your machine before anything is sent to Claude, so the actual commands themselves are never transmitted, only their output.
Why are my injected commands not running?
Check that you are using the correct syntax: exclamation mark followed by backticks, like !`command`. Also ensure the commands work in your terminal first. If a command requires specific PATH settings or environment variables, you may need to source your shell profile or set those variables in the skill file.
What if my command output is too long?
Use Unix pipes to limit output. Common patterns include | head -50 (first 50 lines), | tail -30 (last 30 lines), or | grep "pattern" (filter to relevant lines). For JSON output, use | jq '.specific.path' to extract only what you need. Keeping context focused improves Claude's response quality.
Can I use environment variables in my commands?
Yes, environment variables work normally. Use $VARIABLE or ${VARIABLE} syntax. This is the recommended way to handle API keys, database credentials, and other sensitive values. For example: !`curl -H "Authorization: Bearer $API_KEY" https://api.example.com/data`
Can I have multiple dynamic commands in one skill?
Absolutely. You can include as many !`command` blocks as needed. Each one executes independently and injects its output at that position in the prompt. This lets you build full context from multiple sources (git status, test output, API responses, and more) all in a single skill.
Does this work on Windows?
Yes, but your commands need to be Windows-compatible. If you use Git Bash or WSL, Unix commands will work. For native Windows, use PowerShell or CMD syntax. Consider creating platform-specific skills or using cross-platform tools like git and curl that work consistently across operating systems.
Want AI to Find Your Business?
Dynamic Context Injection helps developers work smarter. But what about your customers finding your business through AI? Check if ChatGPT and other AI assistants know who you are.
Check Your AI Visibility