Fix Cursor Composer Losing Context in Large Monorepos

Composer is sharp in a small repo and loses the thread in a 50k-file monorepo. Force focus with @Files, MDC rules, and scoped tasks — not heroic re-indexing.

Composer never reads your whole repo. It works from a few dozen chunks that embedding retrieval handed it. In a small repo, top-K covers nearly everything; in a 10k+ file monorepo where every concept has a dozen variants, retrieval surfaces one or two and the model fills the gaps with guesses. The visible damage is consistent: it edits module A and forgets module B that imports from A, it suggests import paths that don’t exist, and old patterns from packages/old-app leak into packages/new-app.

This is not a setting you flip once. It’s a change in how you feed Composer context.

TL;DR

  • Hand-attach 5-10 relevant files with @Files before you write the prompt. This single move fixes most cases.
  • Open the package folder (apps/web), not the monorepo root — it cuts the retrieval surface and the index by roughly an order of magnitude.
  • Move boundary rules into .cursor/rules/*.mdc files. Legacy .cursorrules is silently ignored in Agent mode as of 2026.
  • Scope every prompt to one package. “Standardize the logger across all microservices” guarantees skipped packages.
  • Composer 2.5 (the default agent model, built on Kimi K2.5) is strong, but a strong model on bad context still guesses. Context wins.

Which model is Composer actually running?

Long-context behavior varies a lot by model, so check the picker before you debug anything else. As of June 2026 Cursor offers these for agentic work:

ModelContext windowStrength on large repos
Composer 2.5 (default agent)Large agent context, file-tree-scale editsFast multi-file refactors; 79.8% SWE-Bench Multilingual (launched May 18 2026)
Claude Sonnet 4.61M tokensReliable workhorse, holds long context well
Claude Opus 4.71M tokensBest reasoning over sprawling code; 80.5% SWE-Bench Multilingual
GPT-5.5~1MStrong agentic tool use
Gemini 3.1 Pro1M tokensLarge-context reads

A bigger window does not mean Composer dumps your whole monorepo into it. The window caps how much retrieved context the model can hold — retrieval still decides what gets in. That is exactly why the fixes below are about what you attach, not which model you pick.

Common causes

1. Retrieval covers top-N, not enough surface

Composer slices the repo into roughly 200-500 line chunks and embeds them. A prompt like “fix auth” pulls the top 10-20 most relevant chunks. In a 100k-LOC auth subsystem that’s like inspecting a room through a keyhole.

How to judge: after a Composer reply, ask List exactly which files you read. If it lists 3-5 files and misses ones you know are relevant, coverage is the problem.

2. The monorepo has multiple same-named patterns

packages/web/utils/fetch.ts and packages/admin/utils/fetch.ts share a name but differ in implementation. Similarity ranking can drop the admin version into a web prompt, and the model copies it verbatim.

How to judge: scan generated import paths for boundary crossings, e.g. a file under packages/web/... importing from packages/admin/internal/....

3. The working directory is the repo root

By default the workspace root is the working directory, so every file sits in the search surface. Narrowing to apps/web shrinks the retrieval surface by roughly an order of magnitude and the quality jump is immediate. Official guidance is blunt here: opening apps/web directly instead of the repo root cuts indexing by an order of magnitude and keeps the agent focused.

How to judge: look at the bottom-left workspace path. If it’s the repo root in a monorepo, it’s too wide.

4. No MDC rules describing package boundaries

Without rules, the model has no map of which path belongs to which package, what’s public API, and what’s internal. It guesses from the file path alone. Note the format shift: a single root .cursorrules file still loads in some surfaces but is silently ignored in Agent mode, which is where Composer runs. The current format is .cursor/rules/*.mdc.

How to judge: check for ls -la .cursor/rules/. No .mdc files there means no boundary map for the agent.

5. One prompt spanning many packages

“Standardize the logger across all microservices” cannot guarantee retrieval covers every package. Composer edits the ones it sees and silently skips the rest.

How to judge: after the edit, run grep -r "old_logger" .. Leftover hits mean packages were missed.

6. Index is stale or .cursorignore is too aggressive

Cursor re-syncs the index automatically every 5 minutes and only reprocesses changed files, but a directory that was excluded at index time, or added while indexing was paused, simply doesn’t exist for retrieval. An over-broad .cursorignore (e.g. **/*.test.ts) hides test files Composer would otherwise use as reference. Note that semantic search only goes live at 80% index completion, so on a fresh open of a giant monorepo, early prompts run on a partial index. A poorly tuned monorepo index can saturate disk IO for several minutes after opening; a well-tuned one with a tight .cursorignore finishes much faster (one public benchmark cut a 1M-file index from ~12 min to under 3).

How to judge: Cursor Settings → Indexing → check the index progress/status. Open .cursorignore and audit what it excludes.

Before you start

  • Confirm whether the issue is in Composer or Cmd+K. Cmd+K skips repo-wide retrieval entirely and behaves differently.
  • Commit or branch before reproducing, so an Apply doesn’t trash unsaved work.
  • Note the Cursor version and the active model. Opus 4.7 and Sonnet 4.6 hold 1M-token context; Composer 2.5 is fast but works through retrieval like everything else.

Info to collect

  • Repo size in files and LOC, and whether it’s a monorepo or a single package.
  • Whether .cursor/rules/*.mdc and .cursorignore exist, plus the last full index time.
  • Active model, whether you’re in Agent mode, and a screenshot of the @Files attached in Composer.
  • The model’s own answer to “Which files did you actually read?”

Shortest fix path

Ordered by return on effort. The first two usually flip the result on the next prompt.

Step 1: Hand-attach 5-10 highly relevant files with @Files

Biggest lever. Before the task, in the Composer input:

@target-file.ts
@reference-pattern-1.ts
@reference-pattern-2.ts
@target-file.test.ts
@types/relevant.ts

Then: “follow the pattern shown in reference-pattern-1.ts exactly.” Attached files bypass retrieval ranking — they go straight into context, which is why this beats every other fix on a confused prompt.

Step 2: Shrink the working directory

Cursor → File → Open Folder → pick apps/web, not the monorepo root. Cursor then treats that subfolder as the project root and indexes only within it, so the retrieval surface and the index shrink to a single package and cross-package pollution basically stops. This is the official monorepo recommendation when the full repo is too unwieldy to index well.

Step 3: Per-package MDC rules

Create packages/web/.cursor/rules/boundaries.mdc:

---
description: Web app package boundaries and conventions
globs: packages/web/**
alwaysApply: false
---

This is the customer-facing web app.
- Imports MUST stay inside packages/web/* or packages/shared/*.
- Never import from packages/admin/* or packages/internal-tools/*.
- Use the Logger from packages/shared/logger, not console.log.
- API calls go through src/api/client.ts; do not call fetch() directly.

The globs field auto-attaches the rule whenever a matching file enters context, so each package stops bleeding into others. Pick one of the four activation modes deliberately: Always Apply (alwaysApply: true), Auto Attached (set globs), Agent Requested (set description, omit globs), or Manual (@rule-name). For boundary rules, Auto Attached via globs is the right default. A nested AGENTS.md in each package folder works too if you’d rather skip frontmatter.

Step 4: Make Composer report context before writing

Two-step prompt:

Step 1: List exactly which files you've loaded into context and explain how each relates to the task. Do NOT write code yet.
Step 2: After I confirm, implement the change.

If the file list is wrong, stop and add @Files. If it’s right, let it continue. This costs ten seconds and catches the silent miss before it writes 200 lines into the wrong package.

Step 5: Decompose cross-package tasks

Don’t say “standardize all microservices.” Say:

Task scope: only packages/auth-service for now.
Goal: replace all usage of old_logger with the shared logger.

Move to the next package in a fresh Composer turn so context doesn’t bleed between packages.

Step 6: Re-index and tune .cursorignore

Commit a tighter .cursorignore first, then rebuild the index so the rebuild is already clean. Open Cursor Settings → Indexing & Docs → Clear Workspace Index, then fully restart Cursor and let it re-index (semantic search comes back at 80% completion). Heavy directories to exclude:

node_modules/
.next/
dist/
build/
vendor/
target/
**/*.snap

Excluding these is what collapses a multi-minute index into a fast one on a large monorepo. (A .cursorignore follows the same syntax as .gitignore, and a per-developer ignore lets each person scope the index to the folders they actually touch.)

How to verify the fix

  • Run the same prompt before and after narrowing the working dir. Cross-package pollution should disappear.
  • Have a teammate open the same workspace with the same prompt; they should see the same improved behavior.
  • Run grep and your linter to physically confirm import paths no longer cross package boundaries.

If it still fails

  • Reduce the prompt to its minimum: one function, one @File, an explicit path.
  • Roll back the most recent Cursor upgrade or rules change.
  • Search forum.cursor.com for “monorepo composer context” and include your version and repo-size numbers.
  • Grab View → Output → Cursor logs and post them to Bug Reports.

Prevention

  • Every package gets its own .cursor/rules/*.mdc spelling out boundaries, conventions, and banned imports.
  • Each package README carries an “if you edit X, also edit Y” section to anchor the model.
  • Pin 5-10 core reference files as workspace tabs; Composer’s retrieval up-ranks open files.
  • For huge refactors, run a CLI agent like Claude Code for whole-repo scanning and reserve Cursor for in-editor spot edits. Don’t ask Cursor to do the impossible alone — and if you do hand it off, scope the refactor tightly.
  • Standardize “list context first, then code” as your team’s prompt template.

FAQ

Does a 1M-token model fix this on its own?

No. Sonnet 4.6, Opus 4.7, and Gemini 3.1 Pro all hold 1M tokens, but the window only caps how much retrieved context fits. Retrieval still decides what enters that window. A bigger model on bad context guesses just as confidently. Attaching the right files matters more than the window size.

Why did my .cursorrules file stop working?

As of 2026, a single root .cursorrules file is silently ignored in Agent mode, which is where Composer operates. Migrate your boundaries into .cursor/rules/*.mdc files with globs so they auto-attach to the right packages, or use nested AGENTS.md files per package.

Is Composer 2.5 better than Sonnet for big repos?

Composer 2.5 launched May 18 2026 (built on Moonshot’s open Kimi K2.5) and scores 79.8% on SWE-Bench Multilingual — essentially tied with Opus 4.7 at 80.5% — while being fast and cheap, with file-tree-scale multi-file editing. For sustained reasoning over a sprawling, ambiguous codebase, Opus 4.7 is still the safer pick; for fast multi-file edits where you’ve already attached the right files, Composer 2.5 is great value. Either way, context discipline matters more than the model choice.

How do I know Composer missed a file?

Ask it directly: List exactly which files you read. If the list omits files you know are relevant, the retrieval missed them — add those files with @Files and re-run. Don’t trust a confident answer that never names its sources.

Should I just turn off indexing for a giant monorepo?

No — turn it off and Composer loses semantic search entirely (the codebase @-search and retrieval that finds related files for you). Instead, tune .cursorignore to exclude node_modules, dist, build, vendor, and target, and open the package subfolder so Cursor indexes only within it. That keeps indexing fast without blinding the agent.

Tags: #Troubleshooting #Cursor #Debug #Composer large project