---
title: "Your AI Context Is Locked to One Tool. Here's How to Fix It."
description: "Cursor rules, Claude instructions, Codex agents: every AI tool wants its own config. A practical guide to writing project context once and generating it for every platform."
url: https://gqlteam.com/blog/tool-agnostic-ai-context/
markdown: https://gqlteam.com/blog/tool-agnostic-ai-context/index.md
type: blog
date: 2026-02-27
lastmod: 2026-08-28
tags: ["ai-tools","cursor","claude","development","documentation"]
---

# Your AI Context Is Locked to One Tool. Here's How to Fix It.

> Cursor rules, Claude instructions, Codex agents: every AI tool wants its own config. A practical guide to writing project context once and generating it for every platform.

You've spent hours tuning Cursor with rules, skills, and custom agents. Your AI finally understands your project. Then you try Claude Code. Or Codex. Or Gemini.

None of your context carries over. You're starting from zero.

---

> **TL;DR** Every AI coding tool wants its own config format: Cursor uses
> `.mdc` files, Claude reads `CLAUDE.md`, Codex reads `AGENTS.md`. Write your
> project context once in canonical files under `.context/` and
> `.agents/skills/`, then generate the per-tool configs with a shell script.
> Use JSON schemas to validate structured contracts, like work orders and
> verification reports, consistently across every tool.

---

## The Fragmentation Problem

Five AI coding tools. Five config formats. Zero interoperability.

| Tool | Config File | Format |
|------|------------|--------|
| Cursor | `.cursor/rules/*.mdc` | Markdown + YAML frontmatter |
| Claude Code | `CLAUDE.md` | Plain markdown |
| Codex CLI | `AGENTS.md` | Plain markdown |
| GitHub Copilot | `.github/copilot-instructions.md` | Plain markdown |
| Windsurf | `.windsurfrules` | Plain markdown |

If you maintain all five, they **will** drift. You'll update a safety boundary in one file and forget the others. Now your Claude agent can push to main but your Cursor agent can't. Same project, different rules.

This isn't hypothetical. I hit it on my own site: I had Cursor rules, skills, and agents that worked perfectly, but they were all in `.cursor/` which is invisible to every other tool.

---

## Single Source of Truth

The fix is the same principle we use in code: **don't repeat yourself.**

Write your project context once in a canonical location. Generate tool-specific configs from it.

[SurfContext (ARDS v3.0)](https://www.surfcontext.org/spec) is an open standard that defines this pattern, and the design principles behind everything in this post.

### ARDS Design Principles (from the [spec](https://www.surfcontext.org/spec))

- **Single source of truth**: each fact lives in one file. Other files reference it, never duplicate it.
- **Canonical source, generated output**: edit `.context/`. Never edit generated files directly.
- **Tables over prose**: AI agents parse structured data faster. Use tables for any data with 2+ attributes.
- **Token budget awareness**: root context loads every turn. Everything else loads on demand.

The core idea:

| Canonical (you edit these) | | Generated (script produces these) |
|---|----|---|
| `CONTEXT.md` | → | `CLAUDE.md`, `AGENTS.md` |
| `.context/docs/*.md` | → | `.cursor/rules/*.mdc` |
| `.context/agents/*.md` | → | `.cursor/agents/*.md` |
| `.context/ai-ignore-patterns.md` | → | `.cursorignore` |
| `.agents/skills/*/SKILL.md` | | None (tool-agnostic, no generation needed) |

```mermaid
flowchart LR
    subgraph canonical ["Canonical (you edit)"]
        CONTEXT[CONTEXT.md]
        Docs[.context/docs/]
        Agents[.context/agents/]
        Ignore[ai-ignore-patterns.md]
    end
    subgraph generated ["Generated (script produces)"]
        CLAUDE[CLAUDE.md]
        AGENTSMD[AGENTS.md]
        Rules[.cursor/rules/*.mdc]
        CursorAgents[.cursor/agents/]
        Cursorignore[.cursorignore]
    end
    CONTEXT --> CLAUDE
    CONTEXT --> AGENTSMD
    Docs --> Rules
    Agents --> CursorAgents
    Ignore --> Cursorignore
```

### The file structure

```
project/
  CONTEXT.md                    # Root context (single source of truth)
  surfcontext.json              # Platform targeting config
  .context/
    docs/                       # Knowledge docs (rules content)
    agents/                     # Agent definitions
    schemas/                    # JSON schemas for contracts
    ai-ignore-patterns.md       # What to exclude from AI context
  .agents/skills/               # Tool-agnostic skills (open standard)
    work-order/SKILL.md
    deploy-verify/SKILL.md
  .cursor/rules/*.mdc           # Generated for Cursor
  CLAUDE.md                     # Generated for Claude
  AGENTS.md                     # Generated for Codex
```

### Why `.agents/skills/` for skills?

[Agent Skills](https://agentskills.io/) is an open standard (originally from Anthropic) that Cursor, Claude, and Codex all support. They all load from `.agents/skills/`. No generation needed. Put your skills there once, every tool finds them.

---

## JSON Schemas for Contracts

Here's a problem most people don't think about: when an AI agent produces a work order or a verification report, how do you know the output is consistent?

If you define a work order as "goal, non-goals, constraints, acceptance criteria" in a markdown template, nothing enforces that structure. An agent might skip non-goals, rename fields, or add extra sections.

**JSON schemas fix this.** Define the contract once, validate against it.

**work-order.schema.json**

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Work Order",
  "type": "object",
  "required": ["goal", "nonGoals", "constraints",
               "acceptanceCriteria", "context"],
  "properties": {
    "goal": {
      "type": "array",
      "items": { "type": "string" },
      "minItems": 1
    },
    "nonGoals": {
      "type": "array",
      "items": { "type": "string" }
    },
    "constraints": {
      "type": "array",
      "items": { "type": "string" }
    },
    "acceptanceCriteria": {
      "type": "array",
      "items": { "type": "string" }
    },
    "context": {
      "type": "array",
      "items": { "type": "string" },
      "maxItems": 5
    }
  }
}
```

Now any agent (Cursor, Claude, Codex) that produces a work order can be validated against the same schema. If a field is missing, you catch it immediately.

---

## The Generation Script

A simple shell script bridges canonical and generated:

1. **Root context**: copy `CONTEXT.md` → `CLAUDE.md` and `AGENTS.md` with a "do not edit" header.
2. **Rules**: for each `.context/docs/*.md`, emit `.cursor/rules/*.mdc` with Cursor-specific YAML frontmatter.
3. **Agents**: copy `.context/agents/*.md` → `.cursor/agents/*.md`.
4. **Ignore patterns**: extract patterns from `.context/ai-ignore-patterns.md` → `.cursorignore`.

Every generated file gets a header:

```
<!-- Generated from .context/, do not edit.
     Run ./scripts/generate-ai-context.sh to update. -->
```

This prevents the most common failure mode: someone edits a generated file directly, then the next generation run overwrites their changes.

---

## Practical Migration

If you already have Cursor rules and want to go tool-agnostic:

1. **Create CONTEXT.md**: merge your AGENTS.md and always-on rules into a single root context file. Use tables over prose: AI agents parse structured data faster.
2. **Move rules to `.context/docs/`**: strip Cursor-specific frontmatter (globs, alwaysApply). Keep the content as pure markdown. The generation script adds frontmatter back for Cursor.
3. **Move skills to `.agents/skills/`**: the Agent Skills standard is supported by Cursor, Claude, and Codex. No generation step needed.
4. **Add schemas and generation script**: define JSON schemas for your contracts. Write a generation script that produces tool-specific files from canonical sources.
5. **Commit everything**: both canonical and generated files. Remove `.cursor/` from `.gitignore`. Anyone cloning the repo gets working AI context for any tool.

---

## The No-Contradiction Rule

The hardest part isn't the file structure: it's making sure canonical and generated files never contradict each other.

| Layer | Canonical (edit here) | Generated (do not edit) |
|-------|----------------------|-------------------------|
| Root context | `CONTEXT.md` | `AGENTS.md`, `CLAUDE.md` |
| Rules | `.context/docs/*.md` | `.cursor/rules/*.mdc` |
| Skills | `.agents/skills/*/SKILL.md` | None |
| Agents | `.context/agents/*.md` | `.cursor/agents/*.md` |
| Ignore patterns | `.context/ai-ignore-patterns.md` | `.cursorignore` |

Three safeguards:

- **Generated file headers**: every generated file starts with "do not edit", so anyone opening the file knows immediately.
- **Full overwrite**: the generation script replaces files entirely. Manual edits don't survive the next run.
- **Validation script**: checks that canonical files exist, JSON is valid, and generated files have the expected header.

---

## The Bottom Line

AI tools will keep fragmenting. New ones will appear, each with their own config format. The only sustainable approach is to write your context once and generate the rest.

It takes about 30 minutes to set up. After that, switching between Cursor, Claude, and Codex is just running a script.

---

Related service: https://gqlteam.com/services/mentoring/

Contact: https://gqlteam.com/contact/ | Book: https://cal.com/dan-podina-snqasy/30min | MCP: https://mcp.gqlteam.com/mcp

