Hands-on · Chapter 25 of 63
Advanced Tutorial
A production-shaped workflow that combines specs, steering, hooks, MCP, custom agents, and skills, written for engineers who already know the basics.
Advanced 9 min read last reviewed 2026-09-04
◎ Learning objective
Assemble Kiro's primitives into a repeatable team workflow: foundation steering, requirements-first specs, scoped hooks, deliberate MCP config, and role-based custom agents.
This chapter assumes you’ve read Core Concepts (or already use Kiro). It builds one coherent workflow you can adapt to a real codebase.
A note on labeling, kept honest: the mechanics below (file locations, commands, config fields, behavior of modes) are verified against official documentation as of the review date. The workflow itself (the order, the discipline, what goes where) is this site’s recommended practice, not an official prescription. Where something is purely opinion, it says so.
The scenario
A small inventory service: a REST API with a database, owned by a three-person team. We’ll wire it up so that:
- The agent permanently knows the project’s shape (steering).
- New features run through reviewed specs.
- Tests and docs maintain themselves (hooks).
- The agent can reach the team’s external tools (MCP).
- Risky work happens through restricted personas (custom agents).
Adapt the nouns to your stack; the pattern carries over.
Step 0: Foundation steering
Before any clever automation, write the three foundational files in .kiro/steering/ (workspace level, committed to the repo so the whole team shares them):
# product.md - one screen, no more
Inventory service for internal warehouse teams. Tracks stock levels,
reservations, and reorder thresholds. Correctness beats speed:
a wrong stock count costs real money.
# tech.md
Python 3.12, FastAPI, PostgreSQL 16, SQLAlchemy 2.x, pytest.
No new dependencies without a design-doc note explaining why.
# structure.md
src/api/ → routers (one file per resource)
src/models/ → SQLAlchemy models
src/services/ → business logic (routers stay thin)
tests/ mirrors src/ one-to-one.
These three load into every interaction by default. Then add narrow rules with conditional inclusion. For example, an API-conventions file can load only when API files are involved, via front matter at the very top of the file: inclusion: fileMatch plus fileMatchPattern: "src/api/**". Keep each file to one domain, and explain why a rule exists so the agent can generalize it sensibly.
A team decision worth making early: Kiro also reads AGENTS.md files as steering, nested anywhere in the tree. They are always included and support no inclusion modes, which makes them right for rules that should apply everywhere and that other AI tools in your team’s stack can read too. Keep the conditional, area-specific rules in .kiro/steering/ where fileMatch can keep them out of unrelated conversations. In a monorepo the split is natural: one root AGENTS.md for house rules, a per-package AGENTS.md for local ones, and .kiro/steering/ for anything that should load only sometimes.
Opinion, clearly labeled: steering is the most valuable hour you will spend setting up Kiro. Teams that skip it re-litigate their conventions in every chat, forever.
Step-by-step versions of both halves of this decision: Create your first steering file and Use AGENTS.md as steering.
Step 1: Features as requirements-first specs
For a real feature, say stock reservations with expiry, start a feature spec using the requirements-first workflow (Kiro also offers design-first and quick-plan variants for smaller work).
Work the EARS notation properly, including the patterns beginners skip:
WHEN a client reserves stock for an order
THE SYSTEM SHALL decrement available count and create a reservation
with a 30-minute expiry
IF a reservation request exceeds available stock
THEN THE SYSTEM SHALL reject it with a 409 and the current available count
WHILE a reservation is active
THE SYSTEM SHALL exclude its quantity from availability calculations
The discipline: WHEN for nominal behavior, IF/THEN for error paths, WHILE for ongoing states. Error paths are where production incidents live. If your requirements have no IF/THEN lines, they’re not done.
Before approving, run Kiro’s optional requirements analysis: it flags acceptance criteria that admit multiple interpretations, contradictions, and gaps. It’s cheap insurance at the cheapest possible moment.
In design.md, review like a senior engineer, not a spell-checker: data model changes, transaction boundaries, failure modes, sequence diagrams. Then execute tasks.md. Kiro runs independent tasks concurrently in waves, so a well-decomposed task list finishes faster than a monolithic one.
Finally, since GA Kiro supports property-based testing to check the implementation against the spec. Use it on anything with invariants (stock can never go negative; reserved + available = total).
Step 2: Regressions as bugfix specs
When a real bug lands (“reservations sometimes never expire”), resist the hotfix reflex. A bugfix spec puts the analysis in bugfix.md (symptoms, root cause, blast radius) and then designs the fix.
Recommended practice: make the first task a failing regression test that reproduces the bug, and only then the fix. The spec records why the bug existed; the test guarantees it can’t quietly return. Keep checkpoints in mind throughout: if an agent session takes a wrong turn mid-fix, roll back to the checkpoint instead of un-picking edits by hand.
The full procedure, including what checkpoints do and do not cover, is in Fix a bug with a bugfix spec and Undo with checkpoints and rewind.
Step 3: Hooks for the boring loop
Automate exactly two kinds of things at first (opinion: more than that, this early, becomes noise):
- Scoped test runs: on save of files under
src/services/, run that module’s tests and summarize failures. - Doc sync: on save of files under
src/api/, check whetherdocs/api.mdstill matches the endpoints’ signatures and propose an update if not.
Create both in natural language from the hooks panel: describe the trigger and action, and Kiro generates the configuration. Hook triggers can also fire on prompt submission, agent-turn completion, before/after tool calls, and before/after spec tasks. The advanced uses, like a before-spec-task validation gate, are worth exploring once the basics earn their keep.
Both hooks have their own recipe: Run tests on save with a hook and Keep docs in sync with a hook.
Step 4: MCP, deliberately
Wire external reach at the workspace level so the whole team shares it: .kiro/settings/mcp.json (workspace beats user-level ~/.kiro/settings/mcp.json on conflict):
{
"mcpServers": {
"docs-search": {
"command": "npx",
"args": ["-y", "example-docs-mcp-server"],
"env": { "DOCS_TOKEN": "${DOCS_TOKEN}" },
"autoApprove": [],
"disabled": false
},
"issue-tracker": {
"url": "https://mcp.example-tracker.com/mcp",
"oauth": { "clientId": "kiro-team-inventory" }
}
}
}
Field notes, all verified: env vars expand with ${VAR} syntax (no secrets in the file itself); remote servers use url plus headers/oauth; disabledTools can mask individual tools; "autoApprove": "*" exists and you should treat it like sudo without a password prompt. Start every server with autoApprove: [], watch what it asks for during a normal week, then approve the read-only tools you actually use. Connection problems? The “Kiro - MCP Logs” output channel is the first stop.
Precedence runs agent over project over global, so the closest scope wins. Add an MCP server walks through both scopes and the fail-fast flag for automation.
Step 5: Custom agents as roles
Generalist agents accumulate generalist permissions. Define roles instead, as JSON in .kiro/agents/ (workspace) or ~/.kiro/agents/ (global):
{
"name": "reviewer",
"description": "Strict review persona - reads everything, changes nothing",
"tools": ["read"],
"allowedTools": ["read"],
"resources": ["file://docs/standards.md", "skill://.kiro/skills/*/SKILL.md"],
"prompt": "You are the team's strictest reviewer. Hunt for correctness bugs, missing error paths, and violations of docs/standards.md. Report; never fix."
}
Create with /agent create reviewer -D "strict reviewer" (add --manual to edit the JSON directly), switch mid-session with /agent swap, or start sessions as a role: kiro-cli --agent reviewer. The payoff is twofold: pre-approved safe tools mean fewer interruption prompts, and a hard permission ceiling means you can run the reviewer in Autopilot with a clear conscience, because it cannot write.
(The JSON above is the CLI format. Since the IDE’s 1.0 release, IDE agents live in the same .kiro/agents/ folders as a Markdown file instead: the same tool and permission fields in YAML front matter, with the prompt as the body. The concept is identical; only the file shape differs by surface.)
Recommended pattern: one read-only reviewer, one implementer with normal tools, and (if you do data work) a migrations agent whose prompt forbids destructive statements and whose tools exclude anything that can execute against production.
Build the first two from Create a custom agent and Build a read-only reviewer agent.
Step 6: Skills and powers to scale knowledge
When you’ve explained the same procedure twice (“how we write release notes”, “how we add a new pipeline source”), it’s a skill: a folder in .kiro/skills/ with a SKILL.md (name + precise description in front matter, then the steps). Commit workspace skills so the team shares them; Kiro activates them when a request matches the description, or explicitly as /skill-name. Keep the SKILL.md actionable and push long reference material into the skill’s auxiliary files.
For third-party technology knowledge, check powers first. A power bundles POWER.md + MCP config (+ optional steering/hooks) and loads on demand, which keeps your default context lean compared to a pile of always-on MCP servers. Read what’s inside before installing, exactly as you’d skim a setup script.
Recipes for both: Write a skill and Add a Power.
Step 7: The terminal and CI edge
Everything above works in kiro-cli too: same steering, hooks, MCP, agents, skills. Two advanced uses earn special mention:
- Remote work: over SSH or in containers, the CLI is the whole experience:
/context add "src/**",!pytest -x,/chat savefor handoffs. Since v2.17.0 there is a second answer to the remote problem:kiro-cli --cloudruns the session in a managed AWS sandbox you can disconnect from and reattach to elsewhere with--resume-id. It is preview-limited (see Core Concepts) and worth knowing your organization’s position on before you reach for it. - Headless automation: the CLI supports headless operation with API-key authentication for CI/CD. Treat it as production automation: pin the custom agent it runs as, restrict its tools, and budget credits. (The capability is verified; the guardrail design is on you.)
Working versions of both: Start a cloud session from the CLI and Run Kiro CLI headless in CI. The full command reference lives in the CLI Guide.
Permissions and safety for the production workflow
Everything above assumes the agent can be told what to do. Permissions decide what it is able to do at all, and that is the part worth setting before you turn on Autopilot. Kiro checks every file read, command run, and MCP call against your rules: user rules live in ~/.kiro/settings/permissions.yaml, and workspace rules live under ~/.kiro/workspace-roots/<hash>/permissions.yaml, deliberately outside the repository so a cloned repo cannot grant itself anything. Effects rank deny over ask over allow, and deny wins regardless of scope, which makes a handful of deny lines the strongest guarantee available to you. Set fs_write and shell to deny for personas that have no business writing or running commands, keep secrets out of reach entirely with a .kiroignore file, and commit to git before any long agent run, because checkpoints only cover files the agent changed with its own built-in tools. Autopilot is a reasonable setting on a workflow shaped like this one, and an unreasonable one without it. See Set up permissions.yaml and Keep secrets out with .kiroignore.
The operating model, on one screen
- Steering = the constitution (rare, reviewed changes).
- Specs = every feature and risky fix (requirements → design → tasks).
- Hooks = the chores (narrow triggers, light actions).
- MCP/powers = reach (workspace-level, least privilege).
- Custom agents = roles (permissions match the job).
- Skills = procedures (written once, activated on demand).
- Supervised vs Autopilot = a dial you set per task risk, not a personality trait.
Frequently asked questions
What is a good Kiro setup for a team?
Commit product.md, tech.md, and structure.md in .kiro/steering/ so everyone shares the same project knowledge. Run features as requirements-first specs and regressions as bugfix specs. Keep hooks narrow. Configure MCP at workspace level with an empty autoApprove list. Define custom agents as roles with the smallest tool set each role needs.
Is it safe to run Kiro in Autopilot?
It is safe when the ceiling is real rather than intended. Deny the fs_write and shell capabilities where they are not needed, keep secrets out of reach with .kiroignore, restrict each agent's tools field, and commit before risky runs. Autopilot with no permission rules is a different proposition entirely.
Should team rules go in AGENTS.md or .kiro/steering/?
Put rules that should always apply, and that other AI tools in your stack should also read, in AGENTS.md. Put conditional, area-specific rules in .kiro/steering/, where inclusion: fileMatch keeps them out of unrelated conversations. Kiro's documentation states no precedence between the two, so do not write contradicting rules in both.
☰ Chapter summary
- Lay foundations first: product.md, tech.md, structure.md in .kiro/steering/, then narrow fileMatch rules.
- Run features as requirements-first specs; use requirements analysis to catch ambiguity before design.
- Run regressions as bugfix specs: analysis in bugfix.md, regression test before the fix.
- Hooks automate the boring loop (tests, doc sync); scope triggers narrowly to avoid noise and loops.
- Configure MCP per workspace with empty autoApprove by default; approve tools deliberately.
- Use restricted custom agents for roles (read-only reviewer); share team know-how as skills in .kiro/skills/.
All chapter summaries are collected on the revision page.
Related chapters
- Core knowledgeCore ConceptsThe twelve ideas that make up Kiro, each in one paragraph with a link to its full page, plus permissions, checkpoints, compaction, and a surface matrix.
- RecipesSet Up permissions.yamlControl what Kiro's agent may do with permissions.yaml: the capability list, the deny over ask over allow order, match and exclude globs, and the six scopes.
- RecipesBuild a Read-Only Reviewer AgentCreate a Kiro agent that can read your codebase but cannot write or run commands, then back the ceiling with deny rules in permissions.yaml.
- RecipesFix a Bug With a Bugfix SpecUse a Kiro bugfix spec so the analysis lands in bugfix.md, a regression test comes before the fix, and the reason for the bug survives in the repo.
- Hands-onKiro CLI GuideInstall kiro-cli, drive sessions with slash commands, manage agents and context, and take the agent into scripts and CI.
- Hands-onBeginner TutorialInstall Kiro, have your first agent conversation, and build a tiny real project with a spec, step by step. No experience assumed.