Skip to main content
Version: 0.17.2

Concepts

Agent Layer keeps agent behavior consistent across tools. You edit instructions, skills, approvals, and MCP servers in .agent-layer/, and Agent Layer writes each client's native config from those files.

If you only read one section, start with Single source of truth.

When every client has its own config format, a change in Claude can miss Codex, and VS Code can end up with different tools than the CLI. Agent Layer exists so you update one place instead of several.

Agent Layer is repo-local. Each repository can have different safety rules, tools, and autonomy. Putting that configuration in the repo keeps those decisions next to the code they affect.

In this page

Single source of truth

Agent Layer stores instructions, skills, approvals, and MCP server configuration under .agent-layer/, then writes them into each client's native format. Define the behavior once and regenerate client files instead of copying config by hand.

Every client expects different files and conventions. If you edit those files directly, they fall out of sync. With Agent Layer, you edit .agent-layer/ and treat the generated client files as disposable.

That changes day-to-day work: the same rules apply across tools, changes are reviewable in git, and debugging starts in .agent-layer/ instead of five client formats.

Agent Layer also prefers explicit settings. If something matters, it is usually spelled out (for example enabled = true/false) rather than left to an implicit default. That is what lets teams trust that the same repo and the same pinned version produce the same behavior.

What is canonical

The files you edit live in .agent-layer/:

  • config.toml for structured configuration
  • instructions/ for agent rules and guidance
  • skills/ for repeatable workflows (see Skill Design)
  • commands.allow for approved shell command prefixes
  • .env for secrets

Everything else is derived output and can be overwritten at any time.

Treat .agent-layer/ as project configuration: keep it explicit, keep it small, and review changes the same way you would review application configuration.

Some teams keep .agent-layer/ local while experimenting; others commit it so everyone shares the same agent behavior. In either mode, secrets stay out of git: .agent-layer/.env is always gitignored and loaded at runtime.

What gets generated

When you run al sync or al <client>, Agent Layer generates client-specific config files and launchers, such as:

  • .agents/skills/
  • .agy/antigravity-cli/mcp_config.json, .claude/settings.json, .claude/skills/, .mcp.json
  • .agy/antigravity-cli/settings.json (shared state patched only at Agent Layer-managed paths)
  • .codex/ (generated config and rules)
  • .grok/config.toml
  • .grok/hooks/agent-layer-chime.json when notifications.chime is enabled
  • .vscode/mcp.json and a managed block in .vscode/settings.json
  • AGENTS.md
  • .claude/CLAUDE.md
  • .github/copilot-instructions.md
  • repo-local VS Code launchers under .agent-layer/ when VS Code is enabled (for example open-vscode.command, open-vscode.sh, and open-vscode.app/)

Generated outputs are safe to delete and regenerate, except for the shared-state files al sync patches in place rather than regenerating: .codex/config.toml and .agy/antigravity-cli/settings.json. The Antigravity file can also hold native workspace approval, trust, and other settings. Keep it gitignored, but preserve it during cleanup; Agent Layer patches only its managed model, permissions.allow, and agent_specific paths, and never deletes native values it did not set.

This split is deliberate. You can wipe generated files and rebuild them when something feels off, without losing the .agent-layer/ files you maintain.

Why this prevents drift

In a manual setup, every client becomes its own configuration. You change a rule in one place and forget another. Approvals diverge, MCP servers go missing, and agents behave inconsistently.

Agent Layer avoids that by writing managed values from .agent-layer/ only. Generated outputs can be deleted and recreated; shared client settings keep native values outside Agent Layer's managed paths.

Anti-patterns to avoid

  • Editing Agent Layer-managed values under .agents/skills/, .agy/, .antigravitycli/, .claude/, .codex/, .copilot/, .grok/, or .mcp.json
  • Editing Agent Layer-managed files under .vscode/ (mcp.json and the managed block in settings.json)
  • Copying instructions manually between clients
  • Maintaining separate MCP configs for each agent
  • Treating generated files as the files you edit

If clients disagree, move the change into .agent-layer/ and regenerate.

Agent-specific overrides (escape hatch)

agents.claude.agent_specific and agents.codex.agent_specific are optional escape hatches for client-specific settings that are not first-class Agent Layer keys yet.

Use them sparingly:

  • Colliding keys intentionally override Agent Layer-managed values.
  • Sync emits a warning whenever agent-specific keys overlap managed keys, with one carve-out: Claude permissions.deny is additive and does not warn.
  • Claude agent-specific values are deep-merged into .claude/settings.json for object values; arrays and scalar values are replaced at their key.
  • Codex agent-specific values are patched into .codex/config.toml, which is shared Codex state. al sync refreshes known Agent Layer-managed entries while preserving unrelated Codex/user runtime entries.

If you find yourself carrying many permanent overrides, that is usually a sign the setting should become a first-class key in .agent-layer/config.toml.

Per-repo isolation

Agent Layer gives each repository its own agent configuration so work in one repo never leaks into another. Codex home isolation is opt-in. Claude settings and caches isolation is supported; whether it also isolates login credentials depends on your platform and authentication method (see below).

How it works

Codex home isolation is opt-in. Agent Layer always patches .codex/config.toml with known managed Codex entries from .agent-layer/config.toml, including MCP config and a current repo trust seed when that exact project entry is absent. al codex, al dispatch start --agent codex, and al vscode set CODEX_HOME=<repo>/.codex only when local_config_dir = true is set under [agents.codex] (for al vscode, [agents.vscode] must also be enabled):

[agents.codex]
enabled = true
local_config_dir = true

When agents.codex.local_config_dir is absent or false, Agent Layer does not set or clear CODEX_HOME; Codex uses its normal global/project config layering and any inherited CODEX_HOME remains user-owned.

Grok home isolation is always on. al grok, Grok dispatch, and al vscode set GROK_HOME=<repo>/.grok-config so user auth stays out of generated project .grok/. Auth and sessions are per repository, so the first Grok launch in a repo may require login even when global Grok is authenticated. Agent Layer creates that home with owner-only permissions and tightens an existing real directory that is too open. Sync seeds .grok-config/trusted_folders.toml for the current repo when that exact folder entry is absent.

Claude isolation is opt-in. Set local_config_dir = true under [agents.claude] in .agent-layer/config.toml:

[agents.claude]
enabled = true
local_config_dir = true

When enabled, al claude sets CLAUDE_CONFIG_DIR to a repo-local .claude-config/ directory. For VS Code, CLAUDE_CONFIG_DIR is set only when both local_config_dir = true and [agents.claude_vscode] is enabled.

Authentication isolation varies

Claude Code stores /login credentials in the macOS Keychain on macOS, so CLAUDE_CONFIG_DIR does not isolate them there. On Linux and Windows, it stores them in .credentials.json under CLAUDE_CONFIG_DIR, so a repo-local directory also isolates those credentials. Other authentication modes may use external credential sources. See Claude Code authentication.

Trade-offs

Enabling Codex home isolation means auth, sessions, logs, and other Codex runtime state are scoped to the repository. Enabling Claude isolation scopes settings and caches to the repository; authentication isolation depends on the platform and authentication method described above.

Codex and Claude isolation are opt-in (default false) because always-on isolation duplicates config and runtime state in every existing repo. Teams that want per-repo state can enable it per repo; teams that prefer shared global config keep the default.

When to enable it

  • You want per-repo Codex auth, sessions, logs, or runtime state
  • You want per-repo Claude settings and caches isolation
  • You want different provider defaults or cache state per repository

If none of these apply, the default shared provider config works fine and keeps one shared profile across repositories.

Approvals and safety

Approvals control whether an agent can execute shell commands and MCP tools without prompting. Each repository can choose its own autonomy level.

A personal scratch repository can stay permissive. A production repository can require confirmation. The same CLI supports both.

A prompt can say “I will be careful.” Approvals are what actually limit what the agent can do.

Approvals modes

Set the mode in .agent-layer/config.toml (see Configuration):

[approvals]
mode = "all" # one of: all, mcp, commands, none, yolo
ModeShell commandsMCP toolsExtra flags
allauto-approveauto-approve
mcpprompt/denyauto-approve
commandsauto-approveprompt/deny
noneprompt/denyprompt/deny
yoloauto-approveauto-approveskips all permission prompts where supported (Claude and Antigravity --dangerously-skip-permissions, Codex approval_policy=never + sandbox_mode=danger-full-access + web_search=live, Copilot CLI --yolo, Grok --permission-mode bypassPermissions --always-approve)

The default template sets mode = "all". Change it to match your team's security posture.

Codex may still deny or override these settings if its requirements.toml disallows them.

Approved commands

.agent-layer/commands.allow defines which shell command prefixes are allowed. This list is projected into each client that supports command approvals.

Example:

go test
make test
rg

Keep the list short and explicit. Prefer command prefixes over full commands so tools can add safe arguments.

Client support (best effort)

Not every client supports every approval type. Agent Layer generates the closest supported behavior for each client and applies approvals.mode on a best-effort basis.

note

If a client does not support approvals at all, Agent Layer cannot enforce them. Use instructions and allowlists to compensate.

Recommendations

  • Start with commands or none in sensitive repos.
  • Explicitly whitelist safe command prefixes.
  • Use MCP servers only when you control or trust their runtime.
  • Review .agent-layer/ changes as you would any other config.

MCP servers

Agent Layer writes MCP server configuration into each supported client's native format so the same tools are available everywhere your agents run. MCP (Model Context Protocol) servers are external tool servers. Configure them explicitly so the tool set stays intentional and consistent across clients.

MCP servers let an agent search code, fetch URLs, call APIs, and integrate with your tooling. Because they can do a lot, enable them one at a time.

Each client has its own configuration shape and its own conventions for secrets and headers. You define servers once in .agent-layer/config.toml, and Agent Layer writes the safest supported representation into each client.

Keep credentials in .agent-layer/.env, reference them in config.toml, and let generated outputs either keep safe placeholders or land in gitignored files when a client requires concrete values.

When MCP servers change the experience

Instructions and approvals make agents consistent. MCP servers add tools the model can call.

Without tools, a model is limited to its training and whatever you paste into context. With tools, it can search your repo, read a web page, query an API, or fetch current documentation when it needs it.

Two common first examples:

  • Context7: gives agents access to current library documentation and code examples, which reduces “reasonable sounding” but incorrect API usage. Useful when you are integrating SDKs or frameworks that change quickly.
  • Tavily: provides web search/research so agents can answer “what is the latest” or “what changed recently” questions with real sources instead of guessing from training data.

Why the wizard includes a default MCP library

al init creates an empty [mcp] section. al wizard includes a small catalog of MCP servers that you can add when needed. They are included because they cover the most common high-value agent workflows across repos: up-to-date docs, web research, source fetching, and browser automation.

You do not need all of them. Most repos get the best results by enabling a small, intentional set and expanding only when a real use case shows up.

They are disabled by default because some require sign-ups and secrets, and because tool access is a real capability decision. Enable the smallest set you actually need.

Catalog servers

  • context7 - current library docs and examples; requires AL_CONTEXT7_API_KEY (sign up) and npx.
  • tavily - web search/research for recency; requires AL_TAVILY_API_KEY (sign up).
  • fetch - fetch a URL and return its contents; requires uvx (from uv). Useful alongside search when you want the agent to read the primary source.
  • playwright - browser automation (logins, complex pages, UI flows); requires npx and downloads browser dependencies. Useful for web-focused repos; skip it when you do not need a browser.

GitHub can still be configured as an optional custom HTTP MCP server when your workflow needs PR/issue/actions tooling. If you are deciding between an MCP wrapper and an installed command-line tool, use CLI Skill Design to choose the smaller interface.

Where servers are defined

Servers live in .agent-layer/config.toml under [mcp]:

[[mcp.servers]]
id = "example-api"
enabled = true
transport = "http"
url = "https://example.com/mcp"
headers = { Authorization = "Bearer ${AL_EXAMPLE_TOKEN}" }

Each server requires:

  • id (unique, non-empty)
  • enabled (true or false)
  • transport (http or stdio)

HTTP servers

HTTP servers use url and optional headers. You can also set http_transport:

  • sse (default)
  • streamable

If transport = "http", do not set command, args, or env.

Stdio servers

Stdio servers run a local command:

[[mcp.servers]]
id = "filesystem"
enabled = true
transport = "stdio"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem@2026.1.14", "${AL_REPO_ROOT}"]

If transport = "stdio", do not set url or headers.

Secrets and environment variables

Secrets live in .agent-layer/.env and should be referenced using AL_-prefixed placeholders:

AL_EXAMPLE_TOKEN=your-token-here

Only variables prefixed with AL_ are loaded from .env. See Environment variables for how .env is loaded and when AL_NO_NETWORK applies.

Client targeting

Use clients = ["antigravity", "claude", "codex", "vscode", "copilot", "grok"] to restrict a server to specific clients. If you omit clients, the server is projected to all supported clients.

Built-in path placeholder

${AL_REPO_ROOT} expands to the absolute repo root during sync and doctor checks. Use it when a server needs filesystem access scoped to the current repo.

Doctor checks

al doctor connects to each enabled MCP server, lists available tools, and warns about common issues. It waits up to 30 seconds per server before timing out. For the full checklist, see Doctor.

Skill sync

Skills are synced natively to Agent Skills directories with full subdirectory support (scripts/, references/, assets/). Shared-skill clients use .agents/skills/; Claude uses .claude/skills/. No MCP server is involved. For authoring guidance, use Skill Design and CLI Skill Design.

Common pitfalls

  • npx or uvx not installed when using stdio servers
  • missing AL_ secrets in .agent-layer/.env
  • mixing url with command in the same server block
  • enabling too many servers and overloading context
tip

Start with one or two servers, verify with al doctor, then expand. It is easier to trust your agents when the enabled tools are few and intentional.

Agent Dispatch

Agent Dispatch lets an agent, person, or script start a headless provider conversation and coordinate it asynchronously. Starting work returns a handle immediately; callers use that handle to wait for a result, continue the same conversation, or cancel active work. Independent handles make parallel delegation possible without coupling the conversations. Valid dispatch targets are Codex, Claude, Antigravity, and Grok; other enabled clients can call the tools but are not targets.

Agents access dispatch through Agent Layer's built-in agent-layer MCP server, while humans and scripts use matching al dispatch commands. Both use the same lifecycle and results. See Agent Dispatch for the tools, commands, states, timeouts, and configuration.

Project memory

The optional workflow bundle creates docs/agent-layer/ for repo-specific memory files. These files are long-lived, human-readable context that agents can reference. Keep them current so later work has context instead of guesswork.

Agents work best when they can answer “what are we building,” “what are the constraints,” and “what did we decide last time.” Memory files store that.

They are also for humans. When a new teammate joins or you return to a repo after months, short current entries are easier to trust than a pile of stale notes.

Default memory files

When installed by al wizard, the workflow bundle creates missing files:

  • docs/agent-layer/ISSUES.md
  • docs/agent-layer/BACKLOG.md
  • docs/agent-layer/DECISIONS.md
  • docs/agent-layer/COMMANDS.md
  • docs/agent-layer/CONTEXT.md

The default instructions reference these files, so agents know where to look for project context and workflow commands.

What to commit

Teams can choose to commit these files or keep them local:

  • Commit when you want shared, stable context across the team
  • Ignore when you want per-developer notes only
note

If you commit them, treat these files as shared project context. Keep entries short and current.

How memory is used

Agent Layer does not enforce how you use memory files. Instead, the instruction templates guide agents to read them before planning work, running commands, or making changes.

If you add your own memory files, update your instructions to point to them.

Suggested patterns

  • Keep entries short and actionable
  • Record decisions once and link them from tasks
  • Clear resolved issues so the files stay current

Version pinning

Version pinning keeps a repo locked to a specific Agent Layer release so every developer runs the same behavior. That avoids surprises across laptops, CI, and time, especially when configuration changes have real behavioral impact.

When you upgrade, you do it intentionally, you read the release notes, and the whole team moves together.

If you have used lockfiles in other ecosystems, pinning will feel familiar: it makes the running version explicit instead of whatever happens to be installed.

How pinning works

Agent Layer requires a repo pin file at .agent-layer/al.version. al will:

  1. read the pinned version
  2. download it if missing from the local cache
  3. dispatch to that version automatically

Pin formats:

  • X.Y.Z
  • vX.Y.Z

Pin parser behavior:

  • blank lines and # comments are ignored
  • exactly one non-comment version line is expected
  • empty, invalid, or multi-version pin files trigger a warning and dispatch falls back to the current CLI version until repaired

How to set a pin

  • al init writes a pin when you are running a release build
  • or pass --version X.Y.Z to al init
  • al upgrade updates the pin to match the currently running al binary
  • or edit .agent-layer/al.version directly
  • al upgrade prefetch --version X.Y.Z pre-warms a specific release binary in cache for offline or CI workflows

Upgrading a repo

  1. Install the target al version (Homebrew upgrade, or re-run the install script).
  2. Run al upgrade plan to preview changes.
  3. Run al upgrade to apply changes (for CI-safe non-interactive apply: al upgrade --yes --apply-managed-updates).

For compatibility guarantees, upgrade event categories, and release-versioned migration guidance, see Upgrades.

Overrides and offline mode

VariablePurpose
AL_VERSIONforce a version (overrides the repo pin)
AL_NO_NETWORKdisable downloads (fails if the pinned version is not cached)
AL_CACHE_DIRoverride the cache location

Why pinning is required

Pinning is required so the repo does not silently change behavior when a developer upgrades their global al install.