Claude Code Convex CLAUDE.md AGENTS.md AI Coding TypeScript 2026

CLAUDE.md for Convex: The ai-files Auto-Sync System, Managed Sections, and What Still Needs Manual Rules (2026)

The Prompt Shelf ·

Most CLAUDE.md guides assume you’re the one writing every line. Convex breaks that assumption: since version 1.34.0 (shipped March 20, 2026), the Convex CLI installs and maintains a section of your CLAUDE.md and AGENTS.md for you, and updates it whenever Convex’s own best practices change. Run npx convex ai-files install and it drops a block between <!-- convex-ai-start --> and <!-- convex-ai-end --> markers, plus a full rules file at convex/_generated/ai/guidelines.md, without touching anything else in the file. That’s a genuinely different model from every other framework’s CLAUDE.md — and it means the useful question isn’t “what should my Convex CLAUDE.md say,” it’s “what does the managed section already cover, and what’s still on me to write.”

Out of the box, without either the managed section or a project-specific rules file, Claude Code working on a Convex codebase will:

  • Reach for .filter() inside a query because it reads like array filtering, instead of .withIndex() — which means every query scans the full table before filtering in application code
  • Call ctx.db directly from an action, which fails outright since actions can’t touch the database — only queries and mutations can
  • Skip the args/returns validators on a function because plain TypeScript types compile fine without them, even though Convex’s runtime validation depends on the validators being present
  • Use v.bigint() for a 64-bit integer, a validator that’s deprecated in favor of v.int64()
  • Invent an auth pattern that matches whatever it saw most in training data, rather than whatever your project actually uses (Convex Auth, Clerk, or a custom scheme)

The first four of those are exactly what Convex’s own managed guidelines file is designed to prevent. The fifth is not — and that gap is the actual subject of this guide.

Convex Ships Its Own CLAUDE.md Manager

The npx convex ai-files command family, added in Convex 1.34.0, has six subcommands:

npx convex ai-files install   # creates/refreshes the managed section + guidelines.md + skills
npx convex ai-files update    # brings all managed components to their latest version
npx convex ai-files status    # checks each component's hash against version.convex.dev
npx convex ai-files enable    # sets aiFiles.enabled: true in convex.json, then installs
npx convex ai-files disable   # sets aiFiles.enabled: false — stops dev-server prompts, leaves files as-is
npx convex ai-files remove    # deletes the managed section and convex/_generated/ai/, uninstalls skills

aiFiles.enabled lives in convex.json, and with it set to true, npx convex dev checks for staleness on every run and can prompt you to update. This is the detail worth internalizing: Convex’s CLAUDE.md guidance isn’t a one-time template you copy in — it’s a dependency that can drift out of date, the same way a lockfile can, and the CLI treats it that way.

install and update touch four things: convex/_generated/ai/guidelines.md (the actual rules), the Convex section inside AGENTS.md, the Convex section inside CLAUDE.md, and any agent skills configured through convex.json. remove is scoped tightly — if stripping the managed section leaves AGENTS.md or CLAUDE.md completely empty, the now-empty file gets deleted; otherwise, everything you wrote outside the markers survives untouched.

What the Managed Section Actually Looks Like

Here’s the real thing, pulled from get-convex/convex-helpers — an official Convex repository that runs ai-files install on itself:

<!-- convex-ai-start -->

This project uses [Convex](https://convex.dev) as its backend.

When working on Convex code, **always read `convex/_generated/ai/guidelines.md` first**
for important guidelines on how to correctly use Convex APIs and patterns. The file
contains rules that override what you may have learned about Convex from training data.

Convex agent skills for common tasks can be installed by running
`npx convex ai-files install`.

<!-- convex-ai-end -->

Notice what it doesn’t do: it doesn’t inline the actual rules. It’s a pointer, not a payload. The real content — function syntax, validators, index usage — lives in convex/_generated/ai/guidelines.md, a generated file that gets regenerated wholesale on update rather than hand-edited. That separation is deliberate: it means the pointer text in your CLAUDE.md barely ever needs to change, while the substance underneath it can be revised as often as Convex’s team runs new evals against it, without you doing anything.

What’s Actually Inside the Guidelines Convex Ships

You don’t have to guess at the substance — Convex’s own repositories publish CLAUDE.md files built from the same rule set. get-convex/agent’s CLAUDE.md documents the pattern directly:

## Function Syntax
- Always use the new function syntax with explicit `args` and `returns` validators:

```typescript
import { query } from "./_generated/server";
import { v } from "convex/values";

export const getUser = query({
  args: { userId: v.id("users") },
  returns: v.union(v.object({ name: v.string() }), v.null()),
  handler: async (ctx, args) => {
    return await ctx.db.get(args.userId);
  },
});

Function Registration

  • query, mutation, action — public, callable from clients.
  • internalQuery, internalMutation, internalAction — private, callable only from other Convex functions via ctx.runQuery / ctx.runMutation / ctx.runAction.
  • A function f in convex/example.ts is referenced as api.example.f (public) or internal.example.f (internal).

Indexes over Filters

  • Use .withIndex(), not .filter(), for any query against a table with more than a handful of rows. .filter() scans every document; .withIndex() uses a defined index to jump straight to matches.
  • Name indexes after every field they cover, in order: an index on ["userId", "status"] is by_userId_and_status.

Actions and the Database

  • Actions cannot access ctx.db directly — only query and mutation functions can. An action that needs data calls ctx.runQuery / ctx.runMutation against a query or mutation that does.
  • Actions requiring Node.js built-ins (fs, crypto, etc.) need "use node"; as the first line of the file.

Validators

  • v.int64() for 64-bit integers — v.bigint() is deprecated.
  • Functions with no return value still declare returns: v.null() explicitly; Convex’s client sees undefined returns as null regardless.

This is close to what `convex/_generated/ai/guidelines.md` contains after an `install` — and it lines up with the community `.cursorrules` file already in [our rules collection](/rules/convex-backend), which independently documents the same function-syntax and validator conventions from the older, pre-`ai-files` era of Convex tooling. The two sources agreeing is itself informative: this is Convex's stable, load-bearing API surface, not a moving target.

## What ai-files Doesn't Cover — And Why That's the Part You Have to Write

The managed section is scoped to Convex's own API surface. It has no way to know your project's domain, and it isn't trying to. Four gaps show up immediately on any real project:

**Auth provider.** Convex supports [Convex Auth](https://stack.convex.dev/convex-auth), Clerk, and fully custom auth via `ctx.auth.getUserIdentity()`. The managed guidelines don't pick one for you — without a project rule, an agent will guess based on whatever pattern is most common in its training data, which as of 2026 is more likely to be Clerk-shaped code than your actual setup.

```markdown
## Auth
This project uses Convex Auth. Get the current user's identity with
`await ctx.auth.getUserIdentity()` inside queries/mutations — never trust
a userId passed as a plain argument from the client for anything that
gates access to another user's data.

Ownership checks. Convex’s type system won’t stop a mutation from updating a document that belongs to someone else — that’s an application-level rule, not a schema-level one.

## Mutations
Every mutation that updates or deletes an existing document must first
fetch it and verify `doc.userId === identity.subject` (or the equivalent
ownership field) before writing. Do not skip this check for admin-only
mutations either — gate those with a separate role check instead.

Schema domain modeling. convex/schema.ts conventions — table naming, which fields get indexes beyond what a specific query needs, how you handle soft deletes — are yours to document, the same way they would be for any ORM.

## Schema Conventions
Tables: plural, camelCase (`userProfiles`, not `UserProfile`).
Soft deletes: a `deletedAt: v.optional(v.number())` field, filtered out at
the query layer. Never `ctx.db.delete()` on user-facing content — only on
data admins explicitly purge.

Testing. Convex ships convex-test for mocking the backend in unit tests, but whether you use it, npx convex dev against a real dev deployment, or both, is a project decision.

## Testing
Unit tests for Convex functions use `convex-test` (`convexTest(schema)`)
to run against an in-memory implementation — no real deployment needed.
Integration tests that exercise auth or scheduled functions run against a
real dev deployment via `npx convex dev --once` in CI.

None of this is a criticism of the ai-files system — a generated file that tried to guess your auth provider or schema conventions would be wrong more often than it was right. The design keeps the auto-managed section narrow on purpose, which is exactly why your own CLAUDE.md content still needs to exist alongside it.

CLAUDE.md vs AGENTS.md for Convex Projects

The ai-files install command writes the same managed pointer section into both files, which sidesteps the usual CLAUDE.md-vs-AGENTS.md decision for the Convex-specific part. Where they diverge is everything you add yourself:

AGENTS.md   → the managed Convex section (shared with Codex, Cursor) +
              your schema/auth/ownership rules, since those apply
              regardless of which agent is generating the code
CLAUDE.md   → the managed Convex section + Claude Code-specific behavior:
              how much to explain before running `npx convex deploy`,
              whether to run `npx convex dev --once` before considering a
              task done

If you only maintain one file, AGENTS.md is the safer default for a Convex project specifically — the official plugin ecosystem (Claude Code, Cursor, Codex) all target it, and npx convex ai-files keeps both in sync anyway if both exist.

Complete CLAUDE.md Template

# CLAUDE.md

<!-- convex-ai-start -->
(Managed by `npx convex ai-files install` — do not hand-edit this block.
Run `npx convex ai-files update` to refresh it.)
<!-- convex-ai-end -->

## Project Overview
[Framework, if any — Next.js/React/etc.] with Convex as the backend.
TypeScript throughout, including `convex/schema.ts`.

## Commands
- Dev (backend + codegen): `npx convex dev`
- Deploy: `npx convex deploy`
- Check ai-files staleness: `npx convex ai-files status`
- Run tests: [test command]

## Auth
[Convex Auth / Clerk / custom] — describe how `ctx.auth.getUserIdentity()`
is used and where identity checks are required.

## Schema Conventions
- Tables: [naming convention].
- [Soft delete pattern, if used].
- Every field used in a `.withIndex()` call is covered by a named index in
  `convex/schema.ts` — index names list every field they cover, in order.

## Mutations
Every mutation touching an existing document verifies ownership before
writing. State the exact field checked (e.g. `doc.userId === identity.subject`).

## Actions
Actions cannot access `ctx.db`. Data access from an action goes through
`ctx.runQuery`/`ctx.runMutation` against a query/mutation that can.

## Testing
[convex-test for unit tests / real dev deployment for integration tests —
specify which, and how CI invokes each.]

## What to Avoid
- `.filter()` on any table query — use `.withIndex()`.
- `ctx.db` access from inside an `action`.
- Functions missing `args`/`returns` validators.
- Trusting a client-supplied user ID for access control instead of
  `ctx.auth.getUserIdentity()`.

How Different AI Tools Read These Files

Claude Code reads CLAUDE.md natively, and with the official Convex plugin (/plugin install convex@claude-plugins-official) installed, also gets dev-server sync hooks and Convex-specific skills layered on top of the plain managed section.

Cursor reads AGENTS.md when enabled, and Convex’s official Cursor integration recommends indexing Convex’s docs directly via the @Convex symbol in addition to the managed rules file.

OpenAI Codex reads AGENTS.md with the same directory-walking resolution as Claude Code reads CLAUDE.md, so the managed section and your own additions apply without modification.

GitHub Copilot doesn’t read AGENTS.md natively. If Copilot is in your toolchain, copy the index-vs-filter rule and the actions-can’t-touch-ctx.db rule into .github/copilot-instructions.md directly — those two catch the failure modes with the widest blast radius.

Putting It Together

Convex’s ai-files system changes the shape of the work, not the amount of it. You’re no longer writing the function-syntax and validator rules by hand, and you don’t need to re-check them every time Convex revises its guidance — npx convex ai-files status tells you when a refresh is available, and update applies it. What you still own is everything specific to your project: which auth provider you use, how ownership checks work on your mutations, how your schema models your actual domain, and how your tests exercise it.

Treat the managed section as a dependency, not a template: run npx convex ai-files status periodically the same way you’d check for outdated packages, and keep your own rules in the space it deliberately leaves alone. The community .cursorrules example in our rules collection is a useful reference for the pre-ai-files version of these same conventions, if you want to see how closely the generated guidelines track what the community had already converged on by hand.

FAQ

Does Convex automatically write my CLAUDE.md file?

Only a section of it. npx convex ai-files install inserts a managed block between <!-- convex-ai-start --> and <!-- convex-ai-end --> markers; everything else in the file is yours and stays untouched by update or remove.

What is convex/_generated/ai/guidelines.md and do I need to read it?

It’s the actual rules file — function syntax, validators, index usage — that the managed CLAUDE.md section points Claude Code toward. You don’t need to read it yourself line by line, but knowing it exists explains why the visible managed section in your CLAUDE.md looks so short: the substance lives in that separate, auto-regenerated file.

Why does Claude Code write Convex queries with .filter() instead of an index?

.filter() looks like ordinary array filtering, which is the pattern most training data reinforces. Convex’s actual behavior is the opposite of what that pattern implies: .filter() scans every document before filtering, while .withIndex() jumps straight to matches — a difference that’s invisible in a demo and expensive on a real table.

Should I still write my own Convex rules if ai-files already generates some?

Yes. The managed section only covers Convex’s own API surface — auth provider choice, ownership checks, schema domain modeling, and testing conventions are all outside its scope by design, and still need to be in your CLAUDE.md or AGENTS.md for an agent to get them right.

Does the Convex CLAUDE.md section work the same for Cursor and other tools?

The underlying files are tool-agnostic — AGENTS.md is read by Cursor (when enabled) and Codex, CLAUDE.md by Claude Code. Official plugins for each tool add more on top (dev-server hooks, skills), so the experience is richer with a plugin installed than with the plain markdown files alone.

Related Articles

Explore the collection

Browse all AI coding rules — CLAUDE.md, .cursorrules, AGENTS.md, and more.

Browse Rules