Invite a friend, get 1 month of Pro freeHow it works

Cursor Agent for Kotlin and Android: A Practical Guide

How to use Cursor Agent in a Kotlin Android project: project setup, AGENTS.md rules, working loop, testing, and pitfalls for Compose and Gradle.

Solviera Teknoloji 6 min read

Cursor Agent, started with cursor-agent in the project folder, is a terminal coding agent that reads project instructions from AGENTS.md or .cursor/rules and can edit Kotlin, Compose, Gradle, and test files directly. For Android work, configure it with the right build, test, and lint commands, then use a loop of small tasks, verification, and diff review. This practical guide shows how to set up, prompt, and verify Cursor Agent on a Kotlin and Android project.

Why Cursor Agent fits Kotlin Android development

Android projects mix Kotlin sources, Compose UI, Gradle build scripts, version catalogs, and test suites. Cursor Agent works well because it can run ./gradlew tasks to get immediate feedback, and it can modify multiple files in one logical change: a ViewModel, its UI state sealed class, and the composable that renders it. Unlike IDE-based suggestions limited to a single file, the agent can coordinate changes across app/src/main, app/src/test, and libs.versions.toml. It also follows explicit AGENTS.md rules, so you can encode project-specific constraints such as viewModelScope instead of GlobalScope, state hoisting in Compose, and version catalog discipline. Because it runs in the terminal, it can also inspect incremental build output and stack traces, which is useful for Kotlin compiler errors or Compose lint warnings. It will not know about device-only behavior unless you describe it, so keep physical device and emulator constraints in the project rules. For a step-by-step terminal workflow, see How to use Cursor CLI: a step-by-step guide.

Configuring AGENTS.md for a Compose and Gradle project

Create an AGENTS.md file at the repo root or a rule file in .cursor/rules. Keep it short but explicit. Include exact Gradle commands, source layout, Kotlin and Compose conventions, and a short list of don’ts. This file is the single most important factor for consistent agent output.

# AGENTS.md

## Build and verification
- Build: ./gradlew assembleDebug
- Unit tests: ./gradlew testDebugUnitTest
- Instrumented tests: ./gradlew connectedDebugAndroidTest
- Lint: ./gradlew lintDebug

## Project layout
- Kotlin sources: app/src/main/java/...
- AndroidManifest: app/src/main/AndroidManifest.xml
- Compose UI: ui/ package, use @Composable functions
- ViewModels: viewmodel/ package, use viewModelScope
- Unit tests: app/src/test/java/...
- Instrumented tests: app/src/androidTest/java/...

## Kotlin and Android rules
- Use Kotlin idioms: data classes, sealed classes for UI state.
- In Compose, hoist state: pass state and callbacks down.
- ViewModel exposes StateFlow or immutable LiveData, not mutableStateOf.
- Use viewModelScope for coroutines, not GlobalScope.
- Keep Gradle dependency versions in libs.versions.toml.
- Follow existing package naming and module boundaries.

## Do not
- Do not add new dependencies without checking the version catalog.
- Do not change minSdk or targetSdk without explicit request.
- Do not run long device tests unless asked.

This tells the agent how to build and test without guessing. The command ./gradlew testDebugUnitTest is the JVM unit test target, while connectedDebugAndroidTest covers Espresso; separating them prevents wasted device runs. Rules like viewModelScope and state hoisting steer the agent toward idiomatic Kotlin Android code. Put any project-specific conventions such as package naming, module boundaries, or custom lint checks in the same file. If you use a monorepo or multi-module setup, add the module path prefix to each Gradle task, such as :feature:profile:testDebugUnitTest. The agent should not guess module names.

A small-step workflow with build and test feedback

Plan the change in a short sentence, ask the agent to implement only that, run the specified Gradle task, then inspect git diff before moving on. Do not ask for large refactors in one turn; Android builds are slow, and a broken Gradle sync can waste more time than a smaller diff. Good example prompts:

  • Add a sealed interface ProfileUiState in the profile feature package and update ProfileViewModel to expose a StateFlow<ProfileUiState> using viewModelScope.
  • Create a ProfileScreen composable that takes uiState and callbacks as parameters; use the existing design system and add testTags for key elements.
  • Write JUnit tests for LoginViewModel using StandardTestDispatcher and runTest; mock the repository with a fake. Run ./gradlew testDebugUnitTest.
  • Fix the failing CheckoutFlowTest Espresso test by adding an IdlingResource for the coroutine and waiting for the success text.
  • Update the Gradle version catalog to bump compose-bom to the latest stable version in libs.versions.toml, then run ./gradlew lintDebug and fix any new Compose lint warnings.

After each prompt, run the relevant Gradle task yourself or ask the agent to run it and paste the output. Review the diff with attention to lifecycle owners, dispatchers, and collectAsStateWithLifecycle usage. If the agent proposes a broad refactor, ask it to split the change into smaller commits or worktrees. Reviewing smaller diffs makes it easier to spot incorrect coroutine context switches or Compose state mutations inside composition. When a test fails, paste the full stack trace and ask for a minimal fix, not a rewrite.

High-value tasks and Android-specific failure modes

Cursor Agent handles repetitive Kotlin and Android work well: converting XML layouts to Compose, adding ViewModel state machines, writing unit tests with Turbine, updating version catalogs, and fixing lint errors. It is less reliable with design-level Compose animation tuning, multi-module dependency graphs, and instrumented test flakiness; watch those closely.

TaskGood promptWatch closely
Add sealed UI state plus ViewModelAdd a sealed interface for profile state and update the ViewModel to expose StateFlow.State hoisting, using viewModelScope, no mutableStateOf in ViewModel.
Create a Compose screenBuild a screen that takes uiState and callbacks, using the design system.Recomposition triggers, remember keys, test tags for Espresso.
Write unit testsTest the ViewModel with runTest and a fake repository.Dispatcher injection, time control, idempotent fakes.
Bump Gradle dependenciesUpdate compose-bom in libs.versions.toml and run lint.Compatibility, build variants, narrow lint suppressions.

Pitfalls specific to Kotlin and Android: the agent may introduce GlobalScope or runBlocking in ViewModel code, use mutableStateOf outside a composable, or add dependencies without updating the version catalog. It can also change build.gradle.kts in ways that break configuration cache. Always build after Gradle edits and run ./gradlew assembleDebug before asking for the next task. For example, a common failure is changing collectAsState() to collectAsStateWithLifecycle() but forgetting to add androidx.lifecycle:lifecycle-runtime-compose to the version catalog. Another is using Dispatchers.IO inside runTest without overriding the main dispatcher, which makes tests hang. Always ask for the exact lines changed and the reason for each dependency change.

Verifying Kotlin, Compose, and Espresso changes

Ask the agent to write both JVM unit tests and Espresso tests, but specify the test class path and the Gradle task. For ViewModel tests, require runTest and StandardTestDispatcher; for Compose UI tests, require createComposeRule and testTags. After the agent generates tests, run them yourself and review for common issues: missing @get:Rule annotations, using the wrong dispatcher, hardcoded delays, or asserting against implementation details. The agent can also run ./gradlew lintDebug and explain lint warnings, but verify that suggested suppressions are scoped narrowly, not at file level. When adding instrumented tests, ensure the agent configures testInstrumentationRunner as AndroidJUnitRunner and adds idlingResource declarations only when needed. If you have a custom test runner, mention it in AGENTS.md. Also ask the agent to run the unit test task with --stacktrace and paste the first failing test, not the whole log.

Coordinating parallel agents with AgentVera

When a Kotlin and Android change spans multiple features, running several agents in parallel with AgentVera helps. Each agent works in its own git worktree, so one agent can edit Compose screens while another updates a ViewModel and a third runs Gradle without overwriting files. Automatic code review when a turn ends links findings to file:line, catching issues like coroutine scope misuse or missing recomposition keys. Checkpoints let you undo a bad Gradle edit and replay the session, and token budgets stop runaway work before it damages a working Android build. See Best tools to run AI coding agents in parallel (2026).

Key takeaways for agent-assisted Android work

Cursor Agent can be a productive part of Kotlin and Android development when you treat it as a junior engineer with good tooling knowledge but no project context. Put your Gradle commands, package rules, and Compose and coroutine conventions in AGENTS.md, work in small verified steps, and always run tests and lint before accepting a diff. For parallel work across features, use AgentVera with git worktrees and code review to keep the build stable.

Questions

How do I start Cursor Agent in a Kotlin and Android project?

Run cursor-agent in the project root. It reads AGENTS.md or .cursor/rules, so add Kotlin and Android build, test, lint commands and Compose conventions first for more reliable edits.

What should I put in AGENTS.md for Kotlin and Android?

Include Gradle commands such as ./gradlew assembleDebug, testDebugUnitTest, and lintDebug, the source and test package layout, and rules for coroutines and Compose, like using viewModelScope and hoisting state.

Can Cursor Agent write and run Android tests?

Yes, it can add JUnit and Espresso tests, but it needs the correct Gradle task for unit versus instrumented tests. Review the generated tests for dispatcher usage, missing test tags, and hardcoded delays.

Does Cursor Agent work with Jetpack Compose and coroutines?

It handles Compose and coroutine code, but verify state hoisting, recomposition safety, and proper use of viewModelScope versus lifecycleScope. Small diff review and lint checks help catch leaks and unnecessary recompositions.

Bring your agents to one desk.

Download AgentVera for free; your installed CLIs are ready to go.

More Cursor Agent guides

Other agents for Kotlin and Android