Skillwright
 Blog

June 1, 2026 · 10 min read · by Harish Ganapathi

Convert .cursorrules to CLAUDE.md, AGENTS.md & Copilot

You wrote your conventions once, in .cursorrules. Then you opened Claude Code, and it had no idea about any of them. This is the field-by-field mapping for porting .cursorrules (and .mdc) to CLAUDE.md, AGENTS.md, and copilot-instructions.md— what translates cleanly, what doesn’t, and the workflow that stops you from doing this conversion ever again.

Key takeaways

  • A legacy .cursorrules file ports almost verbatim into CLAUDE.md or AGENTS.md — both are always-on Markdown.
  • Cursor globs only translate to Copilot’s applyTo. CLAUDE.md and AGENTS.md have no per-glob field.
  • On-demand procedures aren’t a rules file — they become Claude Code skills (SKILL.md).
  • Converting N times forever is the real cost. Keep one canonical source and compile to each format instead.

Why you end up converting at all

Almost nobody runs a single AI coding tool anymore. You write in Cursor, you let Claude Code handle the big multi-file refactors from the terminal, and your CI reviews come from Copilot. Each one reads its own instructions file, and none of them reads the others’ by default. So the same three sentences — “strict TypeScript, no any, functions under 50 lines” — have to physically exist in .cursorrules, CLAUDE.md, AGENTS.md, and .github/copilot-instructions.md.

That’s the conversion tax. You encode a convention once, then port it three more times, and from that point on every edit is a four-way sync you’ll forget to do. The first half of this guide is the honest mapping between formats. The second half is how to stop paying the tax. If you want the conceptual comparison first, see SKILL.md vs CLAUDE.md vs .cursorrules vs AGENTS.md.

The mapping: what translates and what doesn’t

Before any copy-paste, get the conceptual map straight. The four formats agree on “always-on instructions” and disagree on almost everything else — scoping, on-demand activation, and file references all diverge. Here is concept by concept where each format lands:

Concept.cursorrules / .mdcCLAUDE.mdAGENTS.mdcopilot-instructions
File location.cursorrules (root) or .cursor/rules/*.mdcCLAUDE.md (root + nested)AGENTS.md (root + nested).github/copilot-instructions.md
Always-on conventions.cursorrules body / alwaysApply: trueWhole file (always loaded)Whole file (always loaded)Whole file (chat/agent only)
Glob-scoped rulesglobs: in .mdc frontmatterNo equivalent — nest a file insteadNo equivalent — nest a file insteadapplyTo: in *.instructions.md
On-demand proceduresManual / Agent Requested .mdcA skill (SKILL.md), not CLAUDE.mdNo equivalent (plain doc)A .prompt.md prompt file
@file references@filename.ts in a rule@path/to/file importsNo native import (link by hand)No native import
Frontmatter.mdc only: description, globs, alwaysApplyNoneNone.instructions.md only: applyTo

Three rows do most of the damage. Glob-scoped rules translate cleanly only to Copilot. On-demand procedures aren’t a rules-file concept in Claude Code at all — they’re skills. And @file references survive into CLAUDE.md but evaporate in AGENTS.md and copilot-instructions.md. Keep those three in mind through every worked example below.

.cursorrules → CLAUDE.md

This is the easy direction. A legacy .cursorrules file is plain Markdown with no frontmatter, and CLAUDE.mdis also plain Markdown loaded into every turn. The text moves over essentially unchanged — you’re renaming the file and dropping its contents into the project memory file Claude Code reads automatically.

# .cursorrules  (Cursor, repo root)
# Project: Acme API
## Standards
- Strict TypeScript. No `any`, no unguarded `as` casts.
- Functions under 50 lines, files under 800.
## Testing
- Vitest for unit, Playwright for E2E. 80% line coverage.
## Don't
- Don't run `pnpm install` without asking.

becomes, with no real edits:

# CLAUDE.md  (Claude Code, repo root)
# Project: Acme API
## Standards
- Strict TypeScript. No `any`, no unguarded `as` casts.
- Functions under 50 lines, files under 800.
## Testing
- Vitest for unit, Playwright for E2E. 80% line coverage.
## Don't
- Don't run `pnpm install` without asking.

@docs/architecture.md   # CLAUDE.md supports @imports

The one upgrade to make

CLAUDE.md supports @imports the way Cursor rules support @file references. If your .cursor/rules pulled in a template or doc, recreate that with an @path/to/file line so CLAUDE.md stays small and the referenced file stays the source of truth. Like Cursor rules, keep the always-on body lean — it’s a recurring token cost on every turn.

.cursorrules → AGENTS.md

AGENTS.mdis the “README for agents”: plain Markdown, no required frontmatter, read by roughly two dozen tools — Codex, Cursor, Copilot, Gemini CLI, Aider, Zed, and more. Porting .cursorrules into it is the same near-verbatim copy as the CLAUDE.md case. The payoff is portability: one file most of your tools already read.

# AGENTS.md  (repo root — read by ~24 tools)
# Acme API — agent instructions

## Standards
- Strict TypeScript. No `any`, no unguarded `as` casts.
- Functions under 50 lines, files under 800.

## Testing
- Vitest for unit, Playwright for E2E. 80% line coverage.

## Conventions
- Don't run `pnpm install` without asking.

The Claude Code gap

Here’s the catch: as of mid-2026, Claude Code does not read AGENTS.md natively. If you make AGENTS.md your source of truth, bridge it into Claude Code one of two ways:

1. A thin CLAUDE.md that imports it: @AGENTS.md on its own line.
2. A symlink: ln -s AGENTS.md CLAUDE.md.

Both make the one Markdown file authoritative for Claude Code without duplicating its text. The first is friendlier to version control; the symlink is zero-maintenance until someone on Windows checks it out.

.cursorrules → copilot-instructions.md

GitHub Copilot reads repo-wide instructions from exactly one path: .github/copilot-instructions.md. Get the path wrong and Copilot silently ignores it. The body is plain Markdown again, so the always-on parts of your .cursorrules port directly.

# .github/copilot-instructions.md  (exact path required)
# Acme API

- Strict TypeScript. No `any`, no unguarded `as` casts.
- Functions under 50 lines, files under 800.
- Vitest for unit, Playwright for E2E; 80% line coverage.
- Don't run `pnpm install` without asking.

Copilot also has a second tier that Cursor users will recognize: path-specific instructions in .github/instructions/*.instructions.md, each with an applyToglob in its frontmatter. This is the direct analog to Cursor’s glob-scoped .mdc rules:

# .github/instructions/tests.instructions.md
---
applyTo: "**/*.test.ts"
---
- Use Vitest. One `describe` per unit under test.
- Arrange-Act-Assert; no logic in the assert block.

Gotcha

The number-one reason Copilot instructions look broken: they don’t affect inline ghost-text completions — only chat, agent, and review. If you expected the autocomplete to obey your rules, it never will. See the Copilot instructions guide for the full path-and-settings checklist.

What about glob-scoped rules?

This is where conversion gets lossy, so be honest about it. Cursor’s globs: field — the thing that fires a rule only when you touch src/**/*.ts— has exactly one clean target: Copilot’s applyTo. Same concept, same glob syntax, a true one-to-one port.

TargetPer-glob scoping?How to approximate it
copilot-instructionsYesapplyTo: in .instructions.md — direct port
CLAUDE.mdNoNested CLAUDE.md in the target subdirectory
AGENTS.mdNoNested AGENTS.md — closest file wins

For CLAUDE.md and AGENTS.md there is no per-glob field. Your only real tool is the filesystem: drop a nested CLAUDE.md or AGENTS.mdinto the directory you wanted to scope, and let the “closest file wins” rule do the scoping by location instead of by pattern. It works for packages/api/-style boundaries; it does not work for cross-cutting globs like **/*.test.tsthat span many directories. Those rules either become always-on (and cost you context everywhere) or get duplicated into each relevant nested file. There is no clean answer — which is the first sign you shouldn’t be hand-converting at all.

The one-source-of-truth workflow

Step back and count the work. Four formats, three of them needing manual edits for scoping, and a permanent obligation to re-sync all four every time a convention changes. Doing the conversion once is annoying. Doing it forever is the actual problem — and it’s the problem every small tool in this space (rulesync, rule-porter, and friends) is circling.

The structural fix is to stop treating any IDE’s file as the source. Keep one canonical library of rules and skills, and compileit to each tool’s format on demand. Edit a convention once; regenerate .cursorrules, CLAUDE.md, AGENTS.md, and copilot-instructions.md from the single source. The glob-vs-no-glob lossiness becomes a compiler concern instead of a thing you re-reason about by hand every time.

That’s exactly what Skillwright does: author your rules and skills once in a canonical library, then compile and deploy them to Cursor, Claude Code, Windsurf, and Copilot — across every project at once. Conversion stops being a recurring chore and becomes a build step. For the full strategy, read how to manage AI coding rules across tools, and for the conceptual comparison of the formats themselves, see SKILL.md vs CLAUDE.md vs .cursorrules vs AGENTS.md. If you just want a head start, grab a set of MIT-licensed starter rules from the templates library and compile from there.

Frequently asked questions

Can I automatically convert .cursorrules to CLAUDE.md?

Partly. The body of a legacy .cursorrules file is plain Markdown, so copying it into CLAUDE.md is nearly a straight port — both are always-on instruction files. What doesn't auto-convert is the .mdc system: glob-scoped rules and per-mode activation have no CLAUDE.md equivalent, so a script can move the text but can't preserve the scoping. Small CLIs like rulesync and rule-porter automate the copy; the design decisions are still on you.

Do Cursor globs translate to other formats?

Only to GitHub Copilot. Cursor's globs map cleanly onto Copilot's applyTo frontmatter in a .github/instructions/*.instructions.md file — same idea, same glob syntax. CLAUDE.md and AGENTS.md have no per-glob field at all; the closest you get is placing a nested CLAUDE.md or AGENTS.md inside the subdirectory you want scoped, where the closest file wins.

Should CLAUDE.md or AGENTS.md be my source of truth?

If your team standardizes on Claude Code, CLAUDE.md is the path of least resistance because it loads natively and supports @imports. If you run several agents, AGENTS.md is more portable — roughly two dozen tools read it. The catch: Claude Code does not read AGENTS.md natively as of mid-2026, so an AGENTS.md source of truth needs a CLAUDE.md that @imports it, or a symlink. Either way, pick one canonical file and treat the rest as compiled output.

Does converting lose information?

Yes, if your source used scoping. Always-on conventions port losslessly across all four formats. But Cursor's glob-scoped .mdc rules and on-demand activation don't survive the trip to CLAUDE.md or AGENTS.md, which have no per-glob field — those rules become either always-on (more context cost) or get split into nested files. On-demand procedures map to Claude Code skills, not a rules file at all. Audit anything with globs before you flatten it.

What's the difference between .cursorrules and .cursor/rules when converting?

.cursorrules is the legacy single file at the repo root — plain Markdown, always on, no scoping — so it ports almost verbatim into CLAUDE.md or AGENTS.md. .cursor/rules/ is the newer directory of .mdc files, each carrying description, globs, and alwaysApply frontmatter. Converting .mdc is harder: only the alwaysApply: true rules map straight across, while glob-scoped and Agent-Requested rules need rethinking per target format.