Loading image...Kiro

Product

  • About Kiro
  • IDE
  • CLI
  • Web
  • Mobile
  • Crew
  • Pricing
  • Downloads

For

  • Enterprise
  • Startups
  • Students

Community

  • Overview
  • Ambassadors
  • Discord
  • Events
  • Powers
  • Shop
  • Showcase

Resources

  • Docs
  • Blog
  • Changelog
  • FAQs
  • Report a bug
  • Suggest an idea
  • Billing support

Social

Site TermsLicenseResponsible AI PolicyLegalPrivacy PolicyCookie Preferences
Loading image...Kiro
  • Enterprise
  • Pricing
  • Docs
SIGN INDOWNLOADS
Loading image...Kiro

Get Started

InstallationAuthenticationYour first project

Models

OverviewAvailable modelsReasoning effort

Features

How Kiro works
Specs
Steering
Hooks
MCP
Permissions
Custom agents
Agent Skills
Powers
CompactionKiroignoreCheckpoints and rewind
Built-in tools
Configuration scopes

IDE 1.x

What's new in 1.0
Setup & First Run
Editor
Chat
Experimental
Troubleshooting0.x reference

CLI

What's new in 3.0
Setup & First Run
Terminal UI
Chat
Headless modeACPAuto complete
Experimental
2.x reference

Crew

Quick startInstallationRunning 24/7
Chat
Agent Capabilities
Features
Interfaces
Apps
Build your first app
Manifest reference
SDK / API reference
Publishing & guidelines
ConfigurationSecurityTroubleshooting

Web - Preview

Setup & First RunIdentity Center
Connect your repositories
Working with the agent
Autonomous modeAutomations
Sandbox

Mobile - Preview

Overview

Commands and Reference

CLI commandsSlash commandsBuilt-in toolsExit codesSettingsIDE keyboard shortcuts

Billing

OverviewManaging your subscriptionUpgrading your planDowngrading your planCancelling your planPurchasing add-on creditsManaging your paymentsManaging usage notificationsManaging your taxesContacting billing supportDeleting your accountRelated questions

Enterprise

ConceptsOnboarding quickstart
Connecting your identity provider
Subscribe your teamManage subscriptions
Governance
Monitor and track
SettingsManaged updatesBillingIAMSupported regions

Privacy and Security

OverviewData protectionCode referencesCompliance validationInfrastructure securityIAM permissionsFirewalls, proxies, and data perimetersVPC endpoints (AWS PrivateLink)

Guides

Overview
Language support
Learn by playing

Migration

Migrating from Q DeveloperMigrating from VSCodeUpgrading from Q CLI
  1. Docs
  2. Crew
  3. Apps
  4. Manifest reference

Manifest reference


The app manifest (app.json) declares your app's identity, resources, and requirements. It lives at the repo root — or under a subdirectory if the registry entry specifies one.

Required fields

FieldTypeDescription
namestringUnique identifier, kebab-case (e.g. "oncall-watchtower")
versionstringSemver version (e.g. "1.0.0")
displayNamestringHuman-readable name shown in the App Store
descriptionstringShort description of what the app does

Recommended fields

FieldTypeDescription
authorstringAuthor name or team
licensestringLicense identifier
minCrewVersionstringMinimum Gateway version required
tagsstring[]Discovery tags (e.g. ["oncall", "monitoring"])
jobFamiliesstring[]Job families this app is relevant to

Resources

FieldTypeDescription
agentsstring[]Paths to agent JSON files (relative to app root)
skillsstring[]Paths to skill directories
sopsstring[]Paths to SOP (Standard Operating Procedure) files
mcpServersobjectMCP server definitions (same format as mcp.json)

Store listing

FieldTypeDescription
repostringGit repository name. Used by the blob proxy to serve images
iconPathstringPath to app icon (PNG, square, min 256×256)
screenshotsstring[]Paths to screenshots (PNG/JPG, max 5)
highlightsstring[]Feature bullet points shown on the detail page (max 10)

Hero images

Hero art is rendered on Discover list rows, featured spotlight, feature cards, and the detail-page banner.

FieldPurposeRecommended size
heroImageLight-theme hero1200×675 (16:9)
heroImageDarkDark-theme variant1200×675 (16:9)
heroImageDetail / heroImageDetailDarkDetail-page banner only (preferred over heroImage there)1200×288 (25:6)

Resolution order on every surface: current theme's art → opposite theme's → first screenshot → deterministic gradient with app icon. A missing hero degrades cleanly.

Path form depends on distribution:

  • Builtin apps — absolute served URL under /apps/{name}/ui/
  • Federated / registry apps — repo-relative (ui/hero-light.svg); the registry rewrites it to a blob-proxy URL

Scheduling

crons

json
{ "crons": [ { "name": "ticket-refresh", "every": 300, "message": "Check for new high-severity tickets" }, { "name": "daily-digest", "cron_expr": "0 9 * * 1-5", "message": "Generate daily digest", "agent": "digest-agent" } ] }
FieldDescription
nameJob identifier
everyInterval in seconds (mutually exclusive with cron_expr)
cron_exprCron expression (mutually exclusive with every)
messagePrompt sent to the agent on each run
agentAgent to run (optional, uses default if omitted)
enabledDefault true. Must be a JSON boolean. false registers the cron paused (visible, resumable) — for jobs that need user configuration first
Info

Disabling an app deletes its registered cron jobs; re-enabling re-registers them from the manifest. A cron shipped with "enabled": false that a user later resumed will be reset back to paused after a disable → re-enable cycle.

Frontend UI

ui

json
{ "ui": { "entry": "dist/index.mjs", "pages": [ { "route": "/apps/my-app", "label": "My App", "icon": "Shield", "entryPoint": "dist/page.mjs", "mountFunction": "mount" } ], "sidebar": { "section": "Apps", "order": 10 } } }
FieldDefaultDescription
ui.entryPath to ESM bundle (relative to app root)
ui.pages[].routeURL path for the page
ui.pages[].labelSidebar label
ui.pages[].iconLucide icon name (e.g. "Shield", "Package")
ui.pages[].iconUrlCustom icon image path (relative to ui/)
ui.pages[].entryPointPer-page ESM bundle (overrides ui.entry)
ui.pages[].mountFunction"mount"Exported function name in the ESM bundle
ui.sidebar.section"Apps"Sidebar section name
ui.sidebar.order10Sort order within section

Backend

backend

json
{ "backend": { "entryPoint": "backend/server.py", "port": "auto", "healthCheck": "/health", "routes": "/api/apps/oncall-watchtower" } }
FieldDefaultDescription
backend.entryPointScript to run (relative to app root), or a dotted Python module path launched via python -m
backend.port"auto"Port number or "auto" for auto-assignment
backend.healthCheck"/health"Health check endpoint path
backend.routesBase route path for the backend
backend.type""Runtime: "python", "asgi", "node", "exec", or "" (auto-detect from entryPoint)

App backends are accessible through the gateway's reverse proxy at /apps/{name}/api/{path}, which avoids CORS issues for dashboard UI pages.

Info

The shell-launcher auto-detect reads the entry point's shebang, so a compiled binary launcher cannot be auto-detected — declare "type": "exec" explicitly for those. Exec backends are POSIX-only: on native Windows the backend is refused at spawn with a logged error.

backend.hooks — in-gateway Python entry points

Instead of (or alongside) a standalone backend process, register Python entry points that run inside the gateway process:

json
{ "backend": { "hooks": { "routes": "backend.routes:register_routes", "on_startup": "backend.hooks:on_startup", "on_shutdown": "backend.hooks:on_shutdown" } } }
FieldDescription
backend.hooks.routesRegisters handlers into the gateway's in-process RouteRegistry
backend.hooks.on_startupInvoked when the app's hooks are wired up
backend.hooks.on_shutdownInvoked when the app is disabled

Hooks are wired up on app enable (via on_app_enable, also re-run on gateway startup) — no gateway restart needed.

Permissions

json
{ "permissions": { "api": ["/api/crons", "/api/status", "/api/agents"], "events": ["notification", "slots"], "mcpTools": ["cron_add", "cron_list"], "storage": true, "cron": true, "memory": "app-scoped", "network": false } }
FieldTypeDescription
permissions.apistring[]Allowed API path prefixes (enforced today)
permissions.eventsstring[]Allowed WebSocket event types
permissions.mcpToolsstring[]Allowed MCP tool names
permissions.storagebooleanCan use app-scoped storage
permissions.cronbooleanCan create cron jobs
permissions.memorystringMemory access: "", "app-scoped", or "shared"
permissions.networkbooleanCan make external network requests
Info

Advisory today, not fully enforced. Only permissions.api is enforced right now (via the app-token scope check — deny-by-default on out-of-scope paths). The other fields are declarative markers; enforcement is on the roadmap. Design defensively — declare only what you use.

Lifecycle hooks

setup

json
{ "setup": { "onInstall": "cd ui && npm install && npm run build", "onUninstall": "echo cleanup done", "onUpdate": "cd ui && npm install && npm run build", "onEnable": "echo enabled", "onDisable": "echo disabled", "configSchema": {} } }
FieldDefaultDescription
setup.onInstall""Shell command run after install
setup.onUninstall""Shell command run before uninstall
setup.onUpdate""Shell command run after update
setup.onEnable""Shell command run when app is enabled
setup.onDisable""Shell command run when app is disabled
setup.onEnableTimeout30Timeout in seconds for onEnable
setup.onDisableTimeout30Timeout in seconds for onDisable
setup.configSchema{}JSON Schema for app configuration

Scripts run with set -euo pipefail enforced by Crew. Unset variables and pipe failures cause immediate exit — no silent errors.

Timeout limits: onInstall / onUpdate = 300s, onUninstall = 120s, onEnable / onDisable = configurable (default 30s).

If onEnable fails, the enable is rolled back — the app stays disabled and any registered resources are deregistered. onDisable failures are logged as warnings but do not block the disable.

onUninstall receives KEEP_DATA=1 or KEEP_DATA=0 in the environment — if the user chose "Keep app data", the script should skip deleting user data directories.

Dependencies

json
{ "dependencies": { "managedBy": "gateway", "capabilities": { "mcp": [ { "id": "some-mcp-server", "source": "registry" } ], "skills": [ { "id": "some-skill", "source": "registry" } ] }, "commands": ["jq", "node", "python3"] } }
FieldDefaultDescription
dependencies.managedBy"gateway"Who manages dependency lifecycle: "gateway" or "app"
dependencies.capabilities.mcp[]Required MCP server dependencies
dependencies.capabilities.skills[]Required skill dependencies
dependencies.capabilities.agents[]Deprecated for managedBy: "gateway" — always reported unresolved
dependencies.commands[]System commands that must be on PATH (checked via which)
Info

The open-source edition ships no capability manager, so capabilities entries are reported as unresolved — the app still installs, but the entries appear in the install result's failed list. Design for graceful degradation.

Dependencies are tracked in a reference-counting ledger. On uninstall, Crew shows which deps can be safely removed vs. which are shared with other apps.

Lifecycle & resource management

FieldDefaultDescription
lifecycle"gateway""gateway" (managed), "app" (self-managed), or "locked" (cannot uninstall)
resources"gateway""gateway" (Crew registers agents/skills/MCP) or "app" (app handles its own)

Platform

json
{ "platform": { "os": ["macos", "linux"], "arch": [], "installMode": "server", "clientInstall": { "shell": "curl -fsSL https://example.com/install.sh | bash", "postInstall": "open ~/Applications/MyApp.app" } } }
FieldDefaultDescription
platform.os["macos", "linux"]Supported platforms
platform.arch[] (any)Supported architectures
platform.installMode"server""server" or "client"
platform.clientInstall.shellOne-liner for local install
platform.clientInstall.postInstallCommand to run after install

When installMode: "client", the App Store shows copy-paste terminal instructions instead of running the install on the server. Use for apps that must run on the user's local machine (e.g. Electron apps when Crew runs on a remote host).

Open command

json
{ "openCommand": "open ~/Applications/MyApp.app" }

For apps that run outside the dashboard, the openCommand declares how to launch them. POST /api/apps/{name}/open runs it in the background. On a headless remote environment, the endpoint returns the command for you to run locally instead.

Validation rules

Enforced at install time:

  • name must match /^[a-z0-9]+(?:-[a-z0-9]+)*$/ (kebab-case)
  • version must match semver (X.Y.Z)
  • Paths in agents, skills, sops, ui.entry, ui.pages[].entryPoint, backend.entryPoint must be relative and stay inside the app root (absolute paths and .. traversal are rejected via canonical resolve + containment)
  • backend.hooks.* are format-checked (module.path:callable, no traversal expressible) and containment-checked at load time
  • mcpServers entries use command / args / url / env — not app-relative file paths — and are not path-checked
  • All required fields must be non-empty strings
  • Each cron entry must specify either every or cron_expr
  • Each UI page must have route and label

Forward compatibility

Unknown fields in app.json are preserved during parsing and round-tripped through to_dict() / to_json(). Newer manifest features can coexist with older Crew versions without breaking validation.

Full example

json
{ "name": "oncall-watchtower", "version": "1.0.0", "displayName": "Oncall Watchtower", "description": "Monitor tickets, pipelines, and alarms for your on-call rotation", "author": "kirocrew", "tags": ["oncall", "monitoring"], "agents": ["agents/ticket-analyst.json"], "skills": ["skills/oncall-runbook"], "crons": [ { "name": "ticket-refresh", "every": 300, "message": "Check for new high-severity tickets" } ], "ui": { "entry": "dist/index.mjs", "pages": [ { "route": "/apps/oncall-watchtower", "label": "Oncall", "icon": "Shield" } ] }, "permissions": { "api": ["/api/crons", "/api/status"], "events": ["notification"] }, "platform": { "os": ["macos", "linux"] } }
Page updated: August 4, 2026
Build your first app
SDK / API reference