cd /news/developer-tools/agent-agnostic-repository-guide · home topics developer-tools article
[ARTICLE · art-9420] src=gist.github.com ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Agent-Agnostic Repository Guide

Here is a 2-3 sentence factual summary of the article: This guide explains how to configure software repositories to work with any AI coding agent without vendor lock-in by organizing agent configurations into three categories: portable instructions (AGENTS.md), shared skills, and agent-specific settings. The recommended approach uses symlinks to share portable skills across agent directories, sync scripts to generate agent-native configurations from canonical sources, and keeps agent-specific files in their native locations without modification. The system relies on the AAIF/Linux Foundation AGENTS.md standard for universal instructions and the agentskills.io SKILL.md format for reusable workflows, both supported by multiple AI coding agents.

read11 min views23 publishedApr 21, 2026

A practical guide for making any repository work with any AI coding agent without vendor lock-in. Covers creating new repos agent-agnostic from day one (Part A) and transforming existing repos (Part B).


The Core Principle #

Every piece of agent configuration falls into exactly one of three categories:

Category Strategy Examples
Portable (same format across agents) Store once in .agents/, symlink to agent dirs AGENTS.md, SKILL.md files
Generated (same data, different format) Canonical source in .agents/, sync script renders per-agent MCP config (JSON vs TOML)
Agent-specific (no cross-agent equivalent) Leave in agent-native directory .cursor/rules/*.mdc, .claude/settings.json

If you remember nothing else: portable things get symlinks, generated things get a sync script, agent-specific things stay put.


Part A: New Repo Template #

A.1 Directory Layout

repo/
  AGENTS.md                           # Universal instructions (AAIF standard)
  CLAUDE.md                           # Pointer: "@AGENTS.md" + Claude-only overrides

  .agents/
    AGENTS.md                         # Self-management doc for this directory
    skills/                           # Shared skills (committed)
      <skill-name>/
        SKILL.md                      # agentskills.io spec format
        references/                   # Optional supporting docs
        scripts/                      # Optional automation
    skills-local/                     # Private skills (gitignored)
      .gitkeep
    mcp/
      servers.json                    # Canonical MCP server definitions
    scripts/
      link-skills.sh                  # Symlink skills to agent-native dirs
      sync-mcp.sh                    # Generate agent-native MCP configs

  .claude/                            # Generated + agent-specific
    skills/<name> -> ../../.agents/skills/<name>   # Symlinks
    settings.json                     # Agent-specific (hooks, etc.)
  .cursor/                            # Generated + agent-specific
    skills/<name> -> ../../.agents/skills/<name>   # Symlinks
    rules/                            # Agent-specific (MDC format, not portable)
    mcp.json                          # Generated from .agents/mcp/servers.json
  .codex/
    config.toml                       # Generated from .agents/mcp/servers.json
  .mcp.json                           # Generated: Claude project-level MCP

A.2 Layer 1: Instructions (AGENTS.md)

What: Project context, conventions, routing, coding standards. Portable? Yes. AGENTS.md is the AAIF/Linux Foundation standard, read by 20+ agents including Codex, Cursor, Copilot, Gemini CLI, Devin, and more. Sync mechanism: None needed. Most agents read it natively.

Setup:

  1. Create AGENTS.md at repo root with project overview, directory structure, setup commands, coding standards, git conventions.
  2. Create CLAUDE.md as a pointer:
@AGENTS.md

This repo keeps reusable agent assets in `.agents/` and syncs tool-specific
adapters with `.agents/scripts/`.
  1. For nested packages, create sub-AGENTS.md files (e.g., src/package/AGENTS.md). Both Claude Code and Codex support hierarchical AGENTS.md — deeper files provide directory-scoped context.

Sources: AGENTS.md spec, AAIF / Linux Foundation

A.3 Layer 2: Skills (SKILL.md)

What: Reusable workflows agents can invoke — /rally, /learn, /deploy, etc. Portable? Yes. The Agent Skills spec defines a universal SKILL.md format adopted by 16+ agents. Canonical location: .agents/skills/<skill-name>/SKILL.md Sync mechanism: Symlinks from agent-native dirs.

SKILL.md format (agentskills.io spec):

---
name: my-skill
description: What this skill does and when to use it.
---

Step-by-step instructions for the agent...

Required fields: name (lowercase, hyphens, matches directory name), description. Keep SKILL.md under 500 lines. Use references/ for detailed docs.

The link script (.agents/scripts/link-skills.sh):

#!/usr/bin/env bash
set -euo pipefail

AGENTS_DIR="$(cd "$(dirname "$0")/.." && pwd)"
REPO_ROOT="$(cd "$AGENTS_DIR/.." && pwd)"
TARGETS=(".claude/skills" ".cursor/skills")
declare -A valid_skills

for target_dir in "${TARGETS[@]}"; do
    mkdir -p "$REPO_ROOT/$target_dir"

    for skill_dir in "$AGENTS_DIR"/skills/*/; do
        [ -d "$skill_dir" ] || continue
        name="$(basename "$skill_dir")"
        valid_skills["$name"]=1
        link_target="../../.agents/skills/$name"
        link_path="$REPO_ROOT/$target_dir/$name"

        if [ -L "$link_path" ]; then
            [ "$(readlink "$link_path")" = "$link_target" ] && continue
            rm "$link_path"
        elif [ -e "$link_path" ]; then
            echo "ERROR: $link_path exists but is not a symlink." >&2; exit 1
        fi

        ln -s "$link_target" "$link_path"
        echo "Linked: $link_path -> $link_target"
    done

    for link in "$REPO_ROOT/$target_dir"/*/; do
        [ -L "${link%/}" ] || continue
        link="${link%/}"
        target="$(readlink "$link")"
        if [[ "$target" == *"/.agents/"* ]]; then
            name="$(basename "$link")"
            [ -z "${valid_skills[$name]+x}" ] && rm "$link" && echo "Pruned: $link"
        fi
    done
done

Installing third-party skills (Vercel skills CLI):

npx skills add <repo>@<skill-name> -y

The Vercel CLI natively understands the .agents/skills/ convention and creates symlinks to .claude/skills/ automatically. The link script is a safety net for manual skill creation.

Private skills: .agents/skills-local/ is gitignored. The link script creates symlinks for these too, but those symlinks are machine-local and should not be committed.

Sources: Agent Skills spec, Client implementation guide, npx skills, SSW Rules: symlink agents to claude

A.4 Layer 3: MCP Configuration

What: Model Context Protocol server definitions — which external tools the agent can call. Portable? No. Same data, different format per agent. Canonical location: .agents/mcp/servers.json Sync mechanism: Generation script renders per-agent files.

Why generation, not symlinks:

Agent File Format difference
Claude Code .mcp.json JSON. URL servers need "type": "http"
Cursor .cursor/mcp.json JSON. Direct copy, no type field needed
Codex .codex/config.toml TOML. [mcp_servers.<name>] tables

Canonical format (.agents/mcp/servers.json):

{
  "figma": {
    "type": "http",
    "url": "https://mcp.figma.com/mcp"
  },
  "stacks": {
    "type": "http",
    "url": "https://stacksmcp.int.stackoverflow.net/mcp"
  }
}

Codex special case: Codex does not auto-load repo-local .codex/config.toml. The sync script should support an install-codex command that merges a managed block into ~/.codex/config.toml with sentinel comments (# BEGIN <repo> managed MCP / # END <repo> managed MCP).

Sources: MCP specification, AAIF

A.5 Layer 4: Agent-Specific (Leave As-Is)

These have no cross-agent equivalent. Do not try to abstract them.

File Agent Why not portable
.cursor/rules/*.mdc Cursor MDC format with glob scoping (globs: "**/*.py"), conditional (alwaysApply) — no equivalent elsewhere
.claude/settings.json Claude Code Hooks, metadata updaters — Claude-specific harness features
.claude/settings.local.json Claude Code Machine-local permissions — always gitignored
.claude/agents/*.md Claude Code Subagent definitions — Claude-specific feature

If you want the same knowledge available in multiple agents, put it in AGENTS.md (universally read) rather than trying to sync between .cursor/rules/ and .claude/ formats.

A.6 Automation

Pre-commit hooks (.pre-commit-config.yaml):

- repo: local
  hooks:
    - id: link-agent-skills
      name: "Sync .agents/skills symlinks"
      entry: .agents/scripts/link-skills.sh
      language: script
      pass_filenames: false
      files: ^\.agents/skills/|^\.claude/skills/|^\.cursor/skills/
    - id: check-agent-mcp
      name: "Verify MCP configs are current"
      entry: .agents/scripts/sync-mcp.sh check
      language: script
      pass_filenames: false
      files: ^\.agents/mcp/

A.7 .gitignore

.agents/skills-local/*
!.agents/skills-local/.gitkeep

.claude/settings.local.json
.claude/worktrees/

For whitelist repos (meta workspace pattern where * ignores everything):

!.agents/
!.agents/**
!.claude/
!.claude/**
!.codex/
!.codex/**
!.cursor/
!.cursor/**
!.mcp.json
!AGENTS.md
!CLAUDE.md

A.8 .agents/AGENTS.md Template

This is the self-management doc that lets any agent maintain the directory:


Agent-agnostic configuration following the [Agent Skills](https://agentskills.io)
open standard and [AGENTS.md](https://agents.md) conventions.

## Layout

- `skills/` — Shared skills (committed). Each is a directory with `SKILL.md`.
- `skills-local/` — Private skills (gitignored).
- `mcp/servers.json` — Canonical MCP server config.
- `scripts/` — Sync and validation scripts.

## Adding a skill

1. Create `.agents/skills/<name>/SKILL.md` with `name` + `description` frontmatter
2. Run `.agents/scripts/link-skills.sh`
3. Commit the skill directory and the new symlink

## Installing third-party skills

    npx skills add <repo>@<skill> -y

## Adding an MCP server

1. Edit `.agents/mcp/servers.json`
2. Run `.agents/scripts/sync-mcp.sh`
3. Commit all generated files

## Rules

- Edit skills in `.agents/skills/`, never in `.claude/skills/` or `.cursor/skills/`
- Edit MCP in `.agents/mcp/servers.json`, never in `.mcp.json` or `.cursor/mcp.json`
- Pre-commit hooks enforce sync automatically

A.9 New Repo Checklist

  1. Create AGENTS.md at repo root
  2. Create CLAUDE.md with @AGENTS.md pointer
  3. Create .agents/ with skills/, skills-local/.gitkeep, mcp/servers.json, scripts/, AGENTS.md
  4. Create initial skills in .agents/skills/
  5. Run link-skills.sh to create symlinks
  6. Create or adapt sync script for MCP
  7. Run sync to generate .mcp.json, .cursor/mcp.json, .codex/config.toml
  8. Add pre-commit hooks
  9. Update .gitignore
  10. Verify: symlinks resolve, sync check passes, skills discoverable

Part B: Migration Guide #

B.1 Assessment: Audit What You Have

find . -maxdepth 3 \( \
  -name "AGENTS.md" -o -name "CLAUDE.md" -o \
  -name ".mcp.json" -o -name "mcp.json" -o \
  -name "*.mdc" -o -name "SKILL.md" -o \
  -name "settings.json" -o -name "settings.local.json" -o \
  -name "config.toml" \
\) -not -path "*/.venv/*" -not -path "*/node_modules/*"

For each file, classify as Portable, Generated, or Agent-specific.

B.2 Classification Matrix

Asset Category Action
AGENTS.md Portable Keep at root. Create if missing.
CLAUDE.md (full instructions) Portable Move content to AGENTS.md, replace with @AGENTS.md pointer
.claude/skills/*/SKILL.md (real files) Should be portable git mv to .agents/skills/, replace with symlinks
.agents/skills/*/SKILL.md Already portable No change needed
.cursor/commands/*.md (from skills) Generated Mark as generated output, or leave if hand-authored
.cursor/rules/*.mdc Agent-specific Leave in place. MDC format not portable.
.mcp.json Generated Create .agents/mcp/servers.json as canonical, generate from it
.cursor/mcp.json Generated Generate from canonical source
.codex/config.toml Generated Generate from canonical source
.claude/settings.json Agent-specific Leave (committed hooks)
.claude/settings.local.json Agent-specific Leave (gitignored permissions)

B.3 Migration Steps by Layer

Order matters. Start with the lowest-risk layer:

Step 1: Instructions (lowest risk)

  • If AGENTS.md exists: review, keep as canonical
  • If only CLAUDE.md exists with full instructions: rename to AGENTS.md, create pointer CLAUDE.md
  • If both exist with different content: merge into AGENTS.md, reduce CLAUDE.md to pointer + overrides

Step 2: Skills

  • Inventory: check .claude/skills/, .cursor/commands/, .agents/skills/
  • If real files in .claude/skills/: git mv to .agents/skills/, replace with symlinks
  • If already in .agents/skills/: add link-skills.sh and symlinks
  • Add pre-commit hook

Step 3: MCP

  • Find the most complete MCP config (usually .mcp.json)
  • Copy to .agents/mcp/servers.json as canonical
  • Create or adapt sync script
  • Run sync, diff outputs against originals to verify
  • Add to pre-commit or CI

Step 4: Cleanup

  • Add .agents/AGENTS.md and .agents/README.md
  • Update .gitignore
  • Verify with sync check

B.4 Archetype-Specific Guidance

Archetype 1: Code Project (already partially migrated)

Pattern: meta-stack, sofa — Python/UV repos with some .agents/ structure already.

Typical state: Has .agents/skills/, maybe a sync script that copies (not symlinks), AGENTS.md at root.

Migration:

  • Replace copy-based sync with symlinks for skills
  • Add link-skills.sh and pre-commit hook
  • Ensure MCP generation covers all agents
  • Single atomic commit

Reference implementation: sofa PR #94 demonstrates the full migration.

Archetype 2: Cursor-Heavy with Submodules

Pattern: meta-salley — .cursor/rules/ with MDC files, git submodules each with their own agent config.

Key decisions:

  1. Do NOT migrate Cursor rules. The .cursor/rules/*.mdc files use MDC-specific features (glob scoping, alwaysApply, description for context-aware ) that have no cross-agent equivalent. Leave them in .cursor/rules/. If you want Claude Code to see the same knowledge, put it in AGENTS.md — don't create a new abstraction layer.

  2. Each submodule manages its own config. Don't centralize submodule agent config in the parent repo. Apply the migration independently to each submodule that needs it. The parent's .cursor/rules/ handles meta-level navigation only.

  3. MCP across submodules. If submodules need different MCP servers, each gets its own .agents/mcp/servers.json. If they share the same set, the parent's config applies in the multi-root workspace context.

Archetype 3: Meta Workspace / Coordination Hub

Pattern: iCloud Documents — portfolio coordination with 27+ sub-projects, not a code project.

Key decisions:

  1. Whitelist .gitignore needs explicit allows for every agent directory. When a new agent tool appears, add it to the whitelist.

  2. Skills are operational workflows, not code-generation — /rally triages tickets, /route dispatches to sub-projects. The SKILL.md format works identically for these.

  3. AGENTS.md is a router, not a code guide:

## Routing
- **gear tools**: See `gear/AGENTS.md`
- **Jira tasks**: Read `sherpa/guides/career-sherpa/gear/jira-ticket-template.md`
  1. MCP servers are workspace-wide. Individual sub-projects have their own repos with their own MCP configs.

B.5 Decision Tree

Is this file read identically by multiple agents?
  YES -> Portable. Move to .agents/ or root, symlink from agent dirs.

  NO -> Is the underlying data the same, just different format?
    YES -> Generated. Canonical source in .agents/, sync script renders.

    NO -> Agent-specific. Leave where it is.

B.6 Ongoing Maintenance

Task How
Add a skill Create in .agents/skills/, run link-skills.sh, commit both
Install third-party skill npx skills add <repo>@<name> -y
Add MCP server Edit .agents/mcp/servers.json, run sync, commit all generated files
Add new agent tool Add rendering to sync script, add target to link-skills.sh TARGETS array
Validate skills skills-ref validate .agents/skills/<name>
Check sync freshness sync-mcp.sh check (exits non-zero if stale)

Sources #

Standard What it governs Link
Agent Skills spec SKILL.md format, skill discovery agentskills.io/specification
AGENTS.md / AAIF Universal agent instructions agents.md, AAIF (Linux Foundation)
Model Context Protocol MCP server definitions modelcontextprotocol.io
Vercel Skills CLI npx skills add, skill marketplace github.com/vercel-labs/skills
skills-ref Skill validation CLI github.com/agentskills/agentskills
SSW Rules Symlink best practices ssw.com.au/rules/symlink-agents-to-claude
Claude Code Skills Docs Claude-specific skill discovery code.claude.com/docs/en/skills
Client Implementation Guide How agents should scan .agents/skills/ agentskills.io/client-implementation
Claude Code .agents/ support request Community request for native scanning github.com/anthropics/claude-code#31005
── more in #developer-tools 4 stories · sorted by recency
── more on @claude 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/agent-agnostic-repos…] indexed:0 read:11min 2026-04-21 ·