rule-porter: Convert Cursor rules to CLAUDE.md, AGENTS.md, and Copilot

# devchallenge# weekendchallenge# showdev
rule-porter: Convert Cursor rules to CLAUDE.md, AGENTS.md, and CopilotNed C

This is a submission for the DEV Weekend Challenge: Community The Community Cursor AI...

This is a submission for the DEV Weekend Challenge: Community

The Community

Cursor AI users who also use Claude Code, GitHub Copilot, or any combination of AI coding tools.

Right now, if you've invested time writing good .mdc rules in Cursor, those rules are locked in. Cursor uses its own format with YAML frontmatter, glob patterns, and alwaysApply flags. None of that translates to Claude Code's CLAUDE.md, Copilot's .github/copilot-instructions.md, or the AGENTS.md format.

People switching between tools (or using more than one) have to manually rewrite everything. I know because someone told me so directly. Matthew Hou left a comment on my cursor-doctor launch post asking:

Have you thought about an export/convert feature? Something that could take validated Cursor rules and output an equivalent AGENTS.md or CLAUDE.md?

That comment kicked this off.

What I Built

rule-porter is a zero-dependency CLI that reads your .cursor/rules/ directory and converts every .mdc file into the format your target tool expects.

Three target formats:

  • AGENTS.md (global vs conditional sections, glob patterns preserved as comments)
  • CLAUDE.md (flat markdown with file-specific rules separated)
  • .github/copilot-instructions.md (merged flat markdown)

It auto-detects your Cursor rules, handles edge cases (empty files, broken frontmatter, missing body content), and warns you about anything that can't convert cleanly. Glob patterns and alwaysApply flags don't have equivalents in flat markdown formats, so rule-porter keeps them as human-readable annotations and tells you exactly what was lost.

npx rule-porter --to agents-md
Enter fullscreen mode Exit fullscreen mode

That's it. No install, no config, no dependencies.

Demo

Here's rule-porter running against a real project with 6 Cursor rules (a Chrome extension with TypeScript, i18n, and UI rules):

  rule-porter v1.2.0

  Source:  .cursor/rules/ (6 rules)
  Target:  AGENTS.md

  ✓ 1 global  5 conditional

  Warnings:
  ⚠  comment: Glob pattern "*.tsx, *.js, *.ts" converted to comment.
     AGENTS.md has no native file scoping.
  ⚠  i18n: Glob pattern "locales/**/*.json" converted to comment.
     AGENTS.md has no native file scoping.
  ⚠  typescript: Glob pattern "*.tsx" converted to comment.
     AGENTS.md has no native file scoping.
  ⚠  ui: Glob pattern "*.tsx" converted to comment.
     AGENTS.md has no native file scoping.
  ⚠  ai: No glob pattern and not alwaysApply.
     This was a manual-attach rule in Cursor — review placement.

  ✓ Written to AGENTS.md

  6 rules converted · 5 warnings
Enter fullscreen mode Exit fullscreen mode

The output preserves your rule structure:

# AGENTS.md

> Generated by rule-porter from .cursor/rules/

## Global Rules

### Chrome extension development standards

You are an expert Chrome extension developer...
[full rule body preserved]

## Conditional Rules

### i18n, internationalization, translation

*Applies to: `locales/**/*.json`*

Internationalization (i18n) Guidelines:
[full rule body preserved]
Enter fullscreen mode Exit fullscreen mode

Global rules (ones marked alwaysApply: true in Cursor) get their own section. Conditional rules keep their glob patterns as readable annotations. Code blocks, markdown formatting, even non-English content all come through intact.

--dry-run lets you preview without writing anything:

npx rule-porter --to claude-md --dry-run
Enter fullscreen mode Exit fullscreen mode

Code

GitHub logo nedcodes-ok / rule-porter

Convert AI IDE rules between Cursor, Claude Code, Copilot, Windsurf, and AGENTS.md. Bidirectional. Zero dependencies.

rule-porter

npm version npm downloads license contributions welcome

Convert AI IDE rules between Cursor, Claude Code, GitHub Copilot, Windsurf, and AGENTS.md. Bidirectional. Zero dependencies.

npx rule-porter --to agents-md
Enter fullscreen mode Exit fullscreen mode

Why?

Your AI coding rules are locked into whatever tool you wrote them for. Cursor uses .mdc files with YAML frontmatter and glob patterns. Claude Code uses CLAUDE.md. Copilot uses .github/copilot-instructions.md. Windsurf uses .windsurfrules. None of them understand each other's format.

rule-porter converts between all of them, preserving as much structure as possible and warning you about anything that can't convert cleanly.

Supported Formats
















































Format As Source As Target File
Cursor .cursor/rules/*.mdc
Cursor (legacy) .cursorrules
AGENTS.md AGENTS.md
Claude Code CLAUDE.md
GitHub Copilot .github/copilot-instructions.md
Windsurf .windsurfrules

Usage

Run from your project root:

# Convert Cursor rules to other formats
npx rule-porter --to agents-md
npx rule-porter --to claude-md
npx rule-porter --to copilot
npx rule-porter --to windsurf
Enter fullscreen mode Exit fullscreen mode

475 lines across 5 files. Zero dependencies.

  • src/parser.js — .mdc frontmatter parser and rule discovery
  • src/cli.js — argument parsing, output formatting, file writing
  • src/formats/agents-md.js — AGENTS.md format writer
  • src/formats/claude-md.js — CLAUDE.md format writer
  • src/formats/copilot.js — Copilot instructions format writer

How I Built It

I already had a .mdc parser from cursor-doctor (a linter/diagnostic tool for Cursor rules). The parser handles YAML frontmatter extraction, glob pattern reading, and alwaysApply flag detection. I extracted the relevant parts and built the conversion layer on top.

The core problem is that Cursor's .mdc format is the only one with real structure. Every other format is just a flat markdown file. So converting from Cursor to anything else means making decisions about what to preserve and what to lose.

My approach:

  1. Parse all .mdc files into an intermediate representation (name, description, globs, alwaysApply, body)
  2. Split rules into global (alwaysApply) and conditional (everything else)
  3. Each format writer decides how to represent that split
  4. Anything that can't convert 1:1 produces a warning

The tricky part was handling real-world rules honestly. I tested against three actual GitHub repos with .cursor/rules/ directories and found things like: empty description fields, conditional rules with no glob patterns (manual-attach only in Cursor), Chinese content in rule bodies, and files with only frontmatter and no body. All of those needed to either convert cleanly or fail loudly.

Tech stack: Node.js, zero dependencies, var and require (no build step, runs on Node 12+).