Skip to content

agent-persona is a system for front-loading AGENTS.md files, permissions, and MCP tools, as well as repo-wide meta.AGENTS.md ontop to build a suite of custom agents.

License

Notifications You must be signed in to change notification settings

GoodFarming/agent-persona

Repository files navigation

agent-persona

Switch AI agent behaviors instantly. Apply persona defaults and policies (strict enforcement optional).

Define reusable instruction profiles for AI coding agents. Share them across repos, switch personas on the fly, and lock down what agents can do. Works with Claude, Codex, Gemini, and OpenCode.

Why Use This?

Problem Solution
Different tasks need different agent instructions Swap personas instantly without editing files
AGENTS.md changes clutter git history Overlay system leaves no on-disk changes (Linux)
Need safe defaults but occasional overrides Policy applies by default; CLI args can override (use --strict-policy to enforce)
MCP servers configured per-project Portable MCP definitions in persona.json
Team conventions scattered across repos Shared personas and includes for consistency

Quick Start

# Install
git clone https://github.com/GoodFarming/agent-persona.git
cd agent-persona && ./install.sh

# Launch Claude with the "blank" persona
agent-persona claude blank

# See what personas are available
agent-persona --list

# Check everything is working
agent-persona doctor

Core Concepts

What's a Persona?

A persona is a folder containing instructions (and optional config) for an AI agent:

.personas/
  my-persona/
    AGENTS.md       # Instructions the agent sees (required)
    CLAUDE.md       # Claude-specific instructions (optional)
    GEMINI.md       # Gemini-specific instructions (optional)
    persona.json    # Defaults, MCP servers, policy (optional)

When you run agent-persona claude my-persona, the launcher:

  1. Finds your persona
  2. Overlays the instructions onto the target file (CLAUDE.md)
  3. Injects any MCP servers and defaults
  4. Launches Claude with everything configured

How the Overlay Works

┌─────────────────────────────────────────────────────────────────┐
│                         agent-persona                           │
├─────────────────────────────────────────────────────────────────┤
│  1. Find persona (repo → home → system)                         │
│  2. Merge repo-wide meta instructions                           │
│  3. Expand include directives                                   │
│  4. Inject MCP servers from persona.json                        │
│  5. Translate policy to tool-specific flags                     │
│  6. If `--strict-policy`, filter user args that conflict        │
│  7. Overlay composed file onto working directory                │
│  8. Launch tool with: defaults + policy + user_args             │
└─────────────────────────────────────────────────────────────────┘
  • Normal mode: user args override policy.
  • Strict mode (--strict-policy): policy overrides user args.

On Linux: Uses bind-mount via unshare — your actual AGENTS.md is never modified.

Elsewhere: Swaps the file, runs the tool, restores on exit. If a crash occurs, run agent-persona recover.


Creating Personas

Option 1: Repo-Local Personas

Best for project-specific instructions that travel with your repo:

cd your-project
agent-persona init                     # Creates .personas/ scaffold
mkdir .personas/dev
cat > .personas/dev/AGENTS.md << 'EOF'
# Development Persona

You are helping with active development on this project.

## Guidelines
- Write tests for new functionality
- Keep changes focused and minimal
- Explain trade-offs when relevant
EOF

Option 2: Global Personas

Best for personal preferences that apply everywhere:

mkdir -p ~/.personas/reviewer
cat > ~/.personas/reviewer/AGENTS.md << 'EOF'
# Code Reviewer

Focus on code quality, security, and best practices.
Be thorough but constructive.
EOF

Adding Tool-Specific Instructions

Claude and Gemini can have their own instruction files:

.personas/my-persona/
  AGENTS.md    # Default (used by Codex, OpenCode)
  CLAUDE.md    # Used by Claude (if present)
  GEMINI.md    # Used by Gemini (if present)

The Policy System

Policies define baseline constraints in persona.json (tools/paths/network) that agent-persona translates into tool-specific flags/config.

By default, user tool flags override policy. This lets you keep safe defaults in persona.json, while still allowing power users to push boundaries for a single run (for example, --yolo on Codex).

To enforce policies (non-overridable), run with --strict-policy (or AGENT_PERSONA_STRICT_POLICY=1).

Defining a Policy

Add a policy block to persona.json:

{
  "policy": {
    "tools": {
      "allow": ["bash", "read", "edit", "write", "glob", "grep"],
      "deny": ["webfetch", "websearch", "task"]
    },
    "paths": {
      "allow": ["./src", "./tests", "/tmp"],
      "deny": [".env", "credentials.json", "~/.ssh/**"]
    },
    "network": {
      "deny": ["*"]
    }
  }
}

Precedence Rules

  • Normal mode (default): defaultspolicy → user tool args
  • Strict mode (--strict-policy): defaults → user tool args (filtered) → policy
  • Auto-bypass defaults (codex --full-auto, claude --permission-mode bypassPermissions) are suppressed when a policy exists; pass them explicitly if you want them.

Policy-Controlled Overrides (Strict Mode)

When --strict-policy is used, these user tool flags are ignored/filtered so policy can’t be overridden:

Tool User Tool Flags Controlled by --strict-policy
Claude --permission-mode, --tools, --allowedTools, --disallowedTools, --settings, --dangerously-skip-permissions
Codex --full-auto, --yolo, --dangerously-bypass-*, -c sandbox_mode=*, -c sandbox_workspace_write.*
Gemini Strict mode forces GEMINI_CLI_SYSTEM_SETTINGS_PATH to the generated settings file
OpenCode Strict mode forces OPENCODE_CONFIG to the generated config file

Previewing Policy Translation

See exactly how your policy will be translated:

agent-persona print-policy claude my-persona
agent-persona print-policy codex my-persona

Strict Mode

Enforce policy and fail if it can't be reliably enforced:

agent-persona claude my-persona --strict-policy

This catches issues like:

  • Using network.deny while bash is allowed (shell can curl/wget)
  • Using paths.deny with Codex (not supported)
  • Using paths restrictions with Gemini (not supported)

Enforcement Capability Matrix (Strict Mode)

Policy Element Codex Claude Gemini OpenCode
tools.allow Strong Strong Strong
tools.deny Partial (websearch only) Strong Strong Strong
paths.allow Strong None
paths.deny None Partial (Claude settings) None
network.deny ("*") Strong None None None

Legend: Strong = sandbox/config enforced, Partial = has known gaps, None = not supported, = not implemented

Notes:

  • Codex tools.deny: only websearch is translated today (features.web_search_request=false).
  • No-network on non-Codex tools: deny network-capable tools (e.g., websearch/webfetch) and deny bash if you need “no network” guarantees.
  • Claude paths.deny: Partial via --settings deny rules; has edge-cases with MCP tools
  • Non-Codex network.deny: No sandbox-level network isolation exists; see Hardening Guidance below

Hardening Guidance

For "no network access" on Claude, Gemini, or OpenCode:

These tools lack OS-level network sandboxing. To achieve network isolation:

  1. Deny bash AND deny web tools — prevents curl/wget in shell and blocks webfetch/websearch:

    {
      "policy": {
        "tools": {
          "deny": ["bash", "webfetch", "websearch"]
        }
      }
    }
  2. Or run inside an external network sandbox (container, VM, network namespace)

  3. Use --strict-policy to fail fast when guarantees aren't possible:

    agent-persona claude my-persona --strict-policy

    This fails if network.deny: ["*"] is set but bash is allowed.

Bash command restrictions are not reliably enforceable. Once bash is in tools.allow, the agent can run arbitrary shell commands. There is no cross-tool mechanism to restrict specific commands (e.g., git clean). If you need command-level control, deny bash entirely or use an OS-level sandbox.

Use Codex for strongest isolation. Codex's sandbox mode provides actual OS-level path and network restrictions that other tools cannot match.


Includes and Composition

Shared Snippets

Create reusable blocks in .personas/.shared/:

# .personas/.shared/security-rules.md
## Security Requirements
- Never expose credentials
- Validate all user input
- Use parameterized queries

Include them in any persona:

# My Persona

<!-- include {"file":"security-rules.md"} -->

## Additional Guidelines
...

Inheriting from Other Personas

# Extended Persona

<!-- include {"persona":"base-persona"} -->

## My Additions
...

Composing Policy Fragments

persona.json supports includes too:

{
  "include": [
    { "file": "policy-base.json" },
    { "persona": "secure-base" }
  ],
  "policy": {
    "tools": {
      "deny": ["task"]
    }
  }
}

Includes merge additively. Conflicts (e.g., same tool in both allow and deny) cause errors.


Repo-Wide Meta Instructions

Add context that applies to all personas in a repo:

# .personas/.shared/meta.AGENTS.md

## Project Context
This is a TypeScript monorepo using pnpm workspaces.

## Conventions
- Use vitest for tests
- Run `pnpm lint` before committing

## Off-Limits
- Don't modify `packages/legacy/`

Meta is merged at the top of every persona (or bottom with --meta-position=bottom).

The template created by agent-persona init is ignored until you edit it.


MCP Server Injection

Define MCP servers in persona.json and they're automatically configured:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@anthropic/mcp-filesystem"],
      "env": { "ALLOWED_PATHS": "/home/user/projects" }
    },
    "database": {
      "command": "mcp-postgres",
      "args": ["--connection-string", "postgres://..."]
    }
  }
}
  • Claude: Generates temp --mcp-config JSON file
  • Codex: Emits -c mcp_servers.*=... overrides
  • Disable with --no-mcp or AGENT_PERSONA_MCP=0

Defaults and Overrides

Per-Tool Defaults

{
  "defaults": {
    "*": ["--verbose"],
    "codex": ["--model", "o3"],
    "claude": ["--model", "sonnet"]
  }
}

Global defaults (*) apply first; tool-specific defaults append after.

Built-in Defaults

Unless policy exists, agent-persona adds sensible defaults:

  • Codex: --full-auto (auto-approve safe operations)
  • Claude: --permission-mode bypassPermissions (skip prompts)

These are suppressed when a policy exists (policy controls permissions).

User Args Always Win

# persona.json: "claude": ["--model", "opus"]
agent-persona claude my-persona --model sonnet
# Result: only --model sonnet is passed

Disabling Defaults

agent-persona claude my-persona --no-defaults

Persona Discovery

Resolution order (first match wins):

  1. Repo-local: .personas/<name>/ in current directory or parent directories
  2. Extra paths: AGENT_PERSONA_PATHS environment variable (colon-separated)
  3. Home: ~/.personas/<name>/
  4. User: ~/.local/share/agent-persona/.personas/<name>/
  5. System: /usr/local/share/agent-persona/.personas/<name>/
agent-persona which my-persona  # Show where persona resolves from

Set AGENT_PERSONA_PREFER_REPO=0 to check home/user before repo.


Commands

Command Description
agent-persona <tool> <persona> Launch tool with persona
agent-persona init Scaffold .personas/ in current repo
agent-persona doctor Verify installation and check for issues
agent-persona recover Restore files after hard-kill (swap mode)
agent-persona which <persona> Show where persona resolves from
agent-persona print-overlay <tool> <persona> Preview composed instructions
agent-persona print-policy <tool> <persona> Show policy translation summary
agent-persona --list List all available personas

Tool Shims

Symlinks let you skip specifying the tool:

claude-persona my-agent    # same as: agent-persona claude my-agent
codex-persona my-agent
gemini-persona my-agent
opencode-persona my-agent

Flags

Flag Description
--no-meta Skip repo meta merge
--no-mcp Skip MCP injection
--no-defaults Skip all defaults
--meta-file=<path> Override meta file location
--meta-position=top|bottom Where to merge meta (default: top)
--force-swap Force swap-and-restore (skip bind-mount)
--strict-policy Fail if policy cannot be reliably enforced
--version Show version
-h, --help Show help

Environment Variables

Input (Configure agent-persona)

Variable Description Default
AGENT_PERSONA_DEBUG Enable debug logging off
AGENT_PERSONA_META Enable meta merge 1
AGENT_PERSONA_MCP Enable MCP injection 1
AGENT_PERSONA_DEFAULTS Enable persona/tool defaults 1
AGENT_PERSONA_STRICT_POLICY Fail on unenforced policy 0
AGENT_PERSONA_FORCE_SWAP Force swap mode 0
AGENT_PERSONA_PATHS Extra search paths (colon-separated) empty
AGENT_PERSONA_HOME User persona directory ~/.local/share/agent-persona
AGENT_PERSONA_PREFER_REPO Prefer repo-local personas 1
AGENT_PERSONA_INCLUDE_DEPTH Max include recursion depth 10
AGENT_PERSONA_GEMINI_DISABLE_IDE Disable Gemini IDE mode 0
AGENT_PERSONA_GEMINI_FORCE_TTY Force pseudo-TTY for Gemini auto

Output (Exported to Tool Process)

Useful for hooks, scripts, memory, and logging:

Variable Description Example
AGENT_PERSONA_NAME Persona slug code-reviewer
AGENT_PERSONA_PATH Resolved persona directory /home/user/.personas/code-reviewer
AGENT_PERSONA_TOOL Tool being launched claude
AGENT_PERSONA_OVERLAY_FILE Target overlay file CLAUDE.md
AGENT_PERSONA_RUN_MODE Launch mode unshare or swap

Use Cases

Task-Specific Agents

agent-persona claude researcher  # Deep research, thorough exploration
agent-persona codex fixer        # Quick fixes, minimal changes
agent-persona claude reviewer    # Code review, security focus

Secure Sandboxed Development

{
  "policy": {
    "tools": { "allow": ["bash", "read", "edit", "write", "glob", "grep"] },
    "paths": { "allow": ["./src", "./tests"] },
    "network": { "deny": ["*"] }
  }
}

Multi-Tool Workflows

Same persona, different tools:

agent-persona codex architect   # Planning with Codex
agent-persona claude architect  # Implementation with Claude

Team Standards

Share personas via dotfiles or a team repo:

export AGENT_PERSONA_PATHS="$HOME/team-personas:$AGENT_PERSONA_PATHS"

Per-Project MCP Configuration

// frontend/.personas/dev/persona.json
{
  "mcpServers": {
    "browser": { "command": "mcp-browser-tools" }
  }
}

// backend/.personas/dev/persona.json
{
  "mcpServers": {
    "postgres": { "command": "mcp-postgres", "args": ["--local"] }
  }
}

Overlay Safety

Environment Method On-Disk Changes Hard-Kill Risk
Linux with unshare Bind-mount None None
Other / --force-swap Swap-and-restore Temporary Use recover

If a session is killed unexpectedly (SIGKILL, crash, power loss) while in swap mode:

agent-persona recover  # Restores from backup
agent-persona doctor   # Shows any orphaned backups

Installation

See INSTALL.md for detailed instructions.

git clone https://github.com/GoodFarming/agent-persona.git
cd agent-persona && ./install.sh
agent-persona doctor

Requirements

  • Linux (tested on Ubuntu, should work on most distros)
  • Bash 4.0+ (required for policy features)
  • Python 3 (required for policy enforcement, persona.json parsing, include expansion)
  • One or more AI tools: codex, claude, gemini, opencode

Uninstall

./uninstall.sh
# or manually:
rm -f ~/.local/bin/agent-persona ~/.local/bin/*-persona
rm -rf ~/.local/share/agent-persona

Testing

# Core functionality
bash tests/smoke.sh

# CLI argument/env translation (no model calls)
bash tests/integration-cli-parse.sh

# Real CLI tests (requires credentials, may incur cost)
AGENT_PERSONA_RUN_REAL_TESTS=1 bash tests/integration-real.sh

For full test options and manual test procedures, see tests/MANUAL-TESTS.md.


Supported Tools

Tool Overlay File Policy Support
Claude / Claude Code CLAUDE.md Full
Codex AGENTS.md Full (sandbox-based)
Gemini GEMINI.md Full (settings-based)
OpenCode AGENTS.md Full (config-based)
Any executable on PATH AGENTS.md None

Contributing

Issues and PRs welcome at github.com/GoodFarming/agent-persona.

License

MIT

About

agent-persona is a system for front-loading AGENTS.md files, permissions, and MCP tools, as well as repo-wide meta.AGENTS.md ontop to build a suite of custom agents.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages