Context Engineering for Coding Agents
Configure Claude Code, Cursor, and Windsurf for better results. Structure your AGENTS.md and .cursorrules files to provide the right context at the right time.
The Real Lever
The biggest improvement most teams can make with coding agents isn’t a model switch or a better prompt; it’s writing a decent configuration file.
Claude Code reads AGENTS.md, Cursor reads .cursorrules, Windsurf reads .windsurfrules. The format differs, but the effect is the same: you’re pre-loading context that persists across every session. A good config file is worth more than any single prompt, because every session starts from a better baseline.
What Goes In the File
Configuration files implement Write Outside the Window: persistent context that survives session boundaries. They also shape how the agent behaves; you’re defining its working persona for your codebase.
The structure matters more than the length. A 200-token config with the right information beats a 2000-token config full of generic advice. Include these, in this order:
Project overview. What the project does, its stack, how it’s deployed. Two to three sentences, following the Pyramid pattern: broad context first.
Coding standards. Be specific. “Use snake_case for functions” is useful. “Follow good naming practices” is not. If you can’t point to a concrete example of the rule, it’s too vague to include.
Code patterns with examples. Don’t describe your error handling; show it. A 5-line code example teaches the agent more than a paragraph of explanation.
Explicit constraints. What you don’t want matters as much as what you do. If the agent keeps reaching for a library you’ve banned, add it here.
Structure for Claude Code
Claude Code reads AGENTS.md or CLAUDE.md from the project root. It also reads AGENTS.md files in subdirectories, so you can scope context to specific parts of the codebase. Start with a single root file and add subdirectory files when you notice the agent needs different context for different areas.
# Project Context
## Overview
This is a Python API service for inventory management. FastAPI backend,
PostgreSQL database, deployed on AWS ECS.
## Architecture
- /app: Main application code
- /routes: API endpoints
- /models: Database models
- /services: Business logic
- /tests: Test files mirror /app structure
- /migrations: Alembic database migrations
## Coding Standards
- Use type hints everywhere
- Write tests for all new code
- Use dependency injection for database sessions
- Handle errors at route level, not in services
## Common Patterns
### Error Handling
from fastapi import HTTPException
def get_item(item_id: int):
item = service.find_item(item_id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
return item
### Database Access
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/items")
def list_items(db: Session = Depends(get_db)):
return db.query(Item).all()
## What to Avoid
- Do not use raw SQL; use SQLAlchemy
- Do not modify migration files after they are committed
- Do not add new dependencies without discussion
Cursor and Windsurf
Cursor uses .cursorrules, Windsurf uses .windsurfrules. The format is similar across both; the main difference is that Windsurf cascades rules at the directory level and can reference other files.
The same principles apply. Keep it concise, lead with the overview, show patterns with code examples, and list explicit constraints. If you already have an AGENTS.md for Claude Code, you can adapt it for Cursor or Windsurf with minimal changes; the content matters more than the format.
Common Mistakes
Too vague. “Write clean code” tells the agent nothing. “Use Result types for error handling, never throw exceptions in service layer” tells it something specific.
Too long. Configuration files over 1000 tokens may themselves cause context issues. If your config needs more than that, split it: root file for project-wide rules, subdirectory files for module-specific patterns.
Outdated. Stale configuration is worse than none. If the config says “use SQLAlchemy 1.4 patterns” and you migrated to 2.0 six months ago, every interaction starts with bad context. Review your config file when you review your code.
Conflicting guidance. “Handle errors in routes” and “handle errors in services” in the same file means the agent picks one arbitrarily. When you find the agent doing something unexpected, check for contradictions before blaming the model.
Testing and Evolving Your Configuration
The fastest test: start a fresh session and ask the agent to explain the project structure. If it gets the architecture wrong, your overview section needs work. Then request a simple change and diff the output against your standards.
Start with a project overview and 3-5 key rules. Add patterns as you notice the agent missing them. The best config files are written reactively: every time the agent produces code that doesn’t match your conventions, add the convention to the config and move on. After a few weeks, you’ll have a config that captures the patterns that actually matter, not the ones you thought would matter.