Set up Kiro in 5 files to keep AI coding tasks focused

a desk with a laptop and a potted plant on it

Kiro is a spec-driven coding agent: you plan the feature, the agent works one task at a time against that plan, and the whole thing stays cheap because tasks stay small. The catch is that the savings come from the setup around the tasks, not the model running them.

This guide covers the minimum viable .kiro/ config. Four files and one setting. Kashif Nazir, a Senior Technical Architect at Cloudhouse, ran this on a real hackathon project and documented the reusable version here. No project-specific details, just the rig you can drop onto any repo.

️ What the finished layout looks like

.kiro/
├── steering/               # standing project knowledge
│   ├── product.md          # 3 generated by Kiro
│   ├── tech.md
│   ├── structure.md
│   └── feature-area.md     # 1+ you add, scoped
├── specs/                  # one folder per feature
│   └── feature-name/
│       ├── requirements.md # EARS notation
│       ├── design.md
│       ├── tasks.md
│       └── tasks.meta.json # test tracker
├── hooks/                  # fire on file save
│   ├── run-tests.json
│   └── validate-data.json
└── settings/
    └── mcp.json            # one MCP server

Prerequisites are minimal: Kiro installed and signed in, a project open (run kiro . from the repo root), and whatever test command your project already uses. Everything below lives in the repo and gets committed with it. Kiro runs one agent across the IDE, the CLI, and the web, all reading the same .kiro/ config.

️ Step 1: Steering docs

Steering files are Markdown that Kiro holds in persistent context, so you’re not re-explaining your stack and conventions on every prompt. Generate the foundation set first: in the Kiro panel, choose Generate Steering Docs. Kiro writes three files into .kiro/steering/: product.md, tech.md, and structure.md.

Read all three and correct anything it got wrong. Everything downstream leans on them.

For large, scoped areas of the codebase, add your own steering file and use fileMatch inclusion mode so it only loads when relevant:

---
inclusion: fileMatch
fileMatchPattern: "src/feature-area/**"
---

# Feature-area vocabulary

Domain terms, rules, and conventions for this part of the codebase.

With fileMatch, that vocabulary block only enters context when you’re touching matching files. It’s absent and free for everything else. The three foundation files default to always-on, which is what you want for them. Use fileMatch for anything large enough that you wouldn’t want it loaded on every prompt.

lines of HTML codes

Step 2: Specs, one per feature

A spec turns a feature idea into three files under .kiro/specs/<feature-name>/: requirements.md written in EARS notation (WHEN… THE SYSTEM SHALL…), design.md covering architecture and interfaces, and tasks.md, a numbered plan where each task cites the requirement it satisfies.

Run one spec per feature or narrative thread. Not one giant backlog. Start a spec from the panel by picking Spec in the workflow picker, describe the feature in a sentence, and let Kiro draft the three phases. It will ask clarifying questions before it writes anything, then produce requirements, design, and tasks one step at a time.

The step most people skip: read the requirements and the design before any task runs. That’s where intent gets pinned. A wrong assumption at this stage is cheap to fix. After ten tasks have built on it, it’s not.

Keep each task scoped to one logical unit. “The one API route” is a task. “The whole API” is not. Small tasks need small prompts, which is the entire point of the rig.

Step 3: Save hooks

Hooks are event-driven automations stored under .kiro/hooks/. Two hooks is enough to start. Both fire on PostFileSave.

The first runs your tests on any source file edit:

{
  "name": "run-tests-on-source-save",
  "event": "PostFileSave",
  "filePattern": "src/**/*",
  "command": "your-test-command"
}

The second validates your data or config on change, so it can’t drift silently:

{
  "name": "validate-data-on-save",
  "event": "PostFileSave",
  "filePattern": "data/**/*",
  "command": "your-validate-command"
}

Swap in your real commands and globs. The value here is timing: hooks fire live during a session, so the agent gets told it broke something before it declares the task done, not after you catch it in review.

Step 4: One MCP server

An MCP server gives the agent a capability it doesn’t have built in. Add servers in .kiro/settings/mcp.json. The Playwright browser MCP is the canonical example: it can render a live JavaScript page and take a screenshot, which the built-in fetch can’t do, so the agent can check its own output against a running app.

{
  "mcpServers": {
    "browser": {
      "command": "npx",
      "args": ["-y", "@playwright/mcp@latest", "--headless"],
      "disabled": false,
      "autoApprove": ["browser_navigate", "browser_snapshot", "browser_take_screenshot"]
    }
  }
}

The rule for picking MCPs is one question: does it extend what the agent can observe or do? A test runner it can call, a browser it can drive, a database it can query all earn their slot. A server that duplicates something already built in does not.

Smiling man editing video on multiple computer monitors

Step 5: Turn autopilot off

This is a setting, not a file. The toggle sits at the bottom of the chat panel, next to the model picker. Kiro’s Autopilot runs the agent autonomously and hands you the diffs afterward. Turn it off.

With autopilot off, the agent stops after each task and waits. Every task ends with you reading the diff, running a fresh check in your own shell, and committing only when it comes back clean.

While you’re in that panel, leave the model set to Auto. It lets Kiro route each task to the cheapest model that can handle it, which is the same low-token discipline the rest of the rig is built on. Pinning a large model on every task fights the whole point.

The reason the human gate matters: tests passing proves the code executes. It does not prove it’s what you specified. Automated green will eventually convince you something is right when it is only running. The human read against the original intent is the only thing that catches a clean run of the wrong thing.

✅ How to verify the rig is wired

Start one task. The agent implements it. Your save-triggered hook runs the tests. The agent reports the task done. You review the diff before committing. If you see test output appear in the session without manually triggering anything, the rig is wired correctly.

If the agent completes a task without tests running, the hook’s filePattern doesn’t match the files the task actually touched. Fix the glob and re-run.

What this setup doesn’t cover

This is the minimum, intentionally. It says nothing about custom agents, multi-repo work, or CI pipelines, where the headless CLI is the right tool and the IDE is not. The .kiro/ config carries over to the CLI untouched, so there’s nothing to migrate when you get there.

Kiro has also shipped a multi-agent layer called Kiro Crew that runs on the CLI and reads the same .kiro/ setup: narrow tasks with rich context around them, scaled from one agent to several. Get one feature through the loop with the four files and the one setting above, then add from there only when a real need shows up.

Stay on top of AI & Automation with BizStack Newsletter
BizStack  —  Entrepreneur’s Business Stack
Logo