Skip to main content

Charlie - Universal Agent Config Generator

Define once in YAML/Markdown. Generate agent-specific commands, MCP config, and rules.

Charlie is a universal agent configuration generator that produces agent-specific commands, MCP configurations, and rules from a single YAML/Markdown spec.

Tests Coverage Python

Features

  • ✨ Single Definition: Write settings once in YAML or Markdown
  • 🤖 Multi-Agent Support: Generate for different AI agents (Claude, Cursor, and GitHub Copilot supported)
  • ⚙️ Slash Commands Integration: Generate slash commands from a single definition.
  • 🔌 MCP Integration: Generate MCP server configurations with tool schemas
  • 📋 Rules Generation: Create agent-specific rules files with manual preservation
  • 🎯 Auto-Detection: Automatically finds charlie.yaml or .charlie/ directory
  • ⚡ Runtime Targeting: Choose which agents to generate for at runtime
  • 📦 Library & CLI: Use as CLI tool or import as Python library
  • 🔗 Configuration Inheritance: Extend configurations from external Git repositories

Quick Start

Installation

Install via pip

pip install charlie-agents

Use Docker

Charlie is available as a Docker image, so you don't need to install Python dependencies:

# Pull the image from GitHub Container Registry
docker pull ghcr.io/henriquemoody/charlie:latest

# Run charlie commands (mount your project directory)
docker run --rm -v $(pwd):/workspace ghcr.io/henriquemoody/charlie list-agents

# Generate configuration
docker run --rm -v $(pwd):/workspace ghcr.io/henriquemoody/charlie generate claude

Create an alias for convenience:

Add to your .bashrc or .zshrc:

alias charlie='docker run --rm -v $(pwd):/workspace ghcr.io/henriquemoody/charlie'

Then use it like the native CLI:

charlie generate claude
charlie validate
charlie list-agents

Configuration

For advanced features, Charlie supports two configuration approaches:

  1. Monolithic - Single YAML file (good for small projects)
  2. Directory-Based - Modular files in .charlie/ directories (good for large projects)

Monolithic Configuration

For advanced features, create charlie.yaml in your project:

version: "1.0" # Optional: Schema version (defaults to "1.0")

extends: # Optional: Define it when you want to extend another repository's configuration
  - git@github.com:MyOrg/team-config.git#v1.0

project:
  name: "My project" # Optional: Inferred from directory name if omitted
  namespace: "my" # Optional: Used to prefix commands, rules, and MCP servers.

variables:
  mcp_api_token: ~ # It will ask the user to provide an API token, if the environment variable is not set

# Command definitions
commands:
  - name: "commit"
    description: "Analyze changes and create a high-quality git commit"
    prompt: "Check what changed, and commit your changes. The body of the message explains WHY it changed"

  - name: "command-handler"
    description: "Creates a command handler"
    prompt: "Create a command handler using src/examples/handler.py as an reference"

# MCP server definitions
mcp_servers:
  - name: "local_server"
    type: "stdio"
    command: "node"
    args: ["server.js"]
    env:
      KEY: "value"

  - name: "remote_server"
    url: "https://example.com/mcp"
    headers:
      Authorization: "Bearer {{var:mcp_api_token}}"
      Content-Type: "application/json"

# Rules configuration (rules)
rules:
  - description: "Commit message standards"
    prompt: "Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)"

  - description: "Coding standards"
    prompt: "All code should follow PEP 8"

# Ignore patterns (optional) -- will be added to agent-specific ignore files
ignore_patterns:
  - "*.log"
  - "tmp/"
  - "node_modules/"

Charlie will also read charlie.dist.yaml, unless you have a charlie.yaml in the directory.

See examples/ directory for complete examples:

Configuration Inheritance (extends)

Charlie supports inheriting configuration from external Git repositories. This allows you to share common configurations across multiple projects or organizations:

extends:
  - https://github.com/MyOrg/shared-agent-config
  - git@github.com:MyOrg/team-config.git#v1.0

# Local commands, rules, etc. will be merged with extended configs
commands:
  - name: "local-command"
    description: "A project-specific command"
    prompt: "Do something specific to this project"

How it works:

  1. Charlie fetches each repository in the extends list (in order)
  2. Configurations are merged sequentially - later entries override earlier ones
  3. Your local configuration is merged last, taking highest precedence
  4. Duplicate items (commands, rules, MCP servers, variables) are overwritten with a warning

When duplicates are detected, Charlie displays a warning:

⚠ Overwriting command 'init' from https://github.com/MyOrg/shared-config
⚠ Overwriting rule 'coding-standards' from https://github.com/MyOrg/shared-config

Version/Branch Support:

Use URL fragments to specify a branch or tag:

  • https://github.com/Org/Config#main - use the main branch
  • https://github.com/Org/Config#v1.0.0 - use the v1.0.0 tag
  • git@github.com:Org/Config.git#feature-branch - use a specific branch

Directory-Based Configuration

For better organization and collaboration, use the directory-based approach. The charlie.yaml file is optional - if you only have a .charlie/ directory, Charlie will infer the project name from the directory:

project/
├── charlie.yaml                  # Optional: Project metadata (name inferred if omitted)
├── .charlieignore                # Optional: Patterns to exclude from AI agents
└── .charlie/
    ├── commands/
    │   ├── init.yaml             # One file per command (Markdown or YAML supported)
    │   └── deploy.md
    ├── rules/
    │   ├── commit-messages.yaml  # One file per rule (Markdown or YAML supported)
    │   └── code-style.md
    └── mcp-servers/
        └── local-tools.yaml      # MCP servers in YAML

See examples/directory-based/ for a complete example.

Benefits:

  • Clear organization (one file per command/rule)
  • No merge conflicts on single file
  • Easy to add/remove components
  • Better for version control diffs
  • Native markdown support for rich documentation

Generate Agent-specific Configuration

# Generate configuration files for a specific agent (generates commands, MCP, and rules by default)
charlie generate claude

Placeholders

Charlie supports these universal placeholders in commands, rules, and MCP configurations:

Project Placeholders:

  • {{project_dir}} → Resolves to the project root directory
  • {{project_name}} → Replaced with the project name (e.g., My Project)
  • {{project_namespace}} → Replaced with the project namespace (e.g., my)

Agent Placeholders:

  • {{agent_name}} → Replaced with the agent's full name (e.g., Claude Code, Cursor)
  • {{agent_shortname}} → Replaced with the agent's short identifier (e.g., claude, cursor)
  • {{agent_dir}} → Resolves to agent's base directory (e.g., .claude, .cursor)
  • {{commands_shorthand_injection}} → Agent-specific command shorthand (e.g., $ARGUMENTS for supported agents)

Agent Path Placeholders:

  • {{commands_dir}} → Resolves to agent's commands directory (e.g., .claude/commands/)
  • {{rules_dir}} → Resolves to agent's rules directory (e.g., .claude/rules/)
  • {{rules_file}} → Resolves to agent's rules file path (e.g., .claude/rules.md)
  • {{mcp_file}} → Resolves to agent's MCP configuration file name (e.g., mcp.json)
  • {{assets_dir}} → Resolves to agent's assets directory (e.g., .claude/assets)

Variable Placeholders:

  • {{var:VARIABLE_NAME}} → Replaced with the value of a variable defined in your charlie.yaml
    • Variables can be defined in the variables: section
    • Use ~ as value to prompt user for input if not set as environment variable
    • Example: {{var:mcp_api_token}}
    • Charlie will prompt user for input if variable is not set.

Environment Variable Placeholders:

  • {{env:VAR_NAME}} → Replaced with the value of the environment variable
    • Loads from system environment or .env file in root directory
    • Raises EnvironmentVariableNotFoundError if variable doesn't exist
    • System environment variables take precedence over .env file

Custom Replacements:

  • Custom placeholders can be defined per-command or per-rule using the replacements field
  • See the Library API section for examples

These placeholders work in commands, rules, and MCP server configurations (command, args, URL, and headers fields).

Usage

CLI Commands

charlie generate <agent>

Setup agent-specific configurations (generates commands, MCP config, and rules by default):

# Auto-detect charlie.yaml (generates all artifacts)
charlie generate claude

# Setup without MCP config
charlie generate cursor --no-mcp

# Setup without rules (rules)
charlie generate claude --no-rules

# Setup without commands
charlie generate claude --no-commands

# Explicit config file
charlie generate cursor --config my-config.yaml

# Custom output directory
charlie generate cursor --output ./build

charlie validate

Validate YAML configuration:

# Auto-detect charlie.yaml
charlie validate

# Specific file
charlie validate my-config.yaml

charlie list-agents

List all supported AI agents:

charlie list-agents

charlie info <agent>

Show detailed information about an agent:

charlie info claude
charlie info cursor

Library API

Use Charlie programmatically in Python:

from charlie import AgentRegistry, AgentConfiguratorFactory, Tracker
from charlie.schema import Project, Command, Rule, HttpMCPServer, StdioMCPServer, ValueReplacement
from charlie.enums import RuleMode

# Initialize registry and get agent
registry = AgentRegistry()
agent = registry.get("claude")

# Create project configuration
project = Project(
    name="My Project",
    namespace="my",
    dir="/path/to/project",
)

# Create configurator
configurator = AgentConfiguratorFactory.create(
    agent=agent,
    project=project,
    tracker=Tracker()
)

# Generate commands
configurator.commands([
    Command(
        name="commit",
        description="Analyze changes and create a high-quality git commit",
        prompt="Check what changed, and commit your changes. The body of the message explains WHY it changed",
        metadata={
            "allowed-tools": "Bash(git add:*), Bash(git status:*), Bash(git commit:*)"
        },
        replacements={}
    ),
    Command(
        name="deploy",
        description="Deploy the application",
        prompt="Run {{script}}",
        metadata={},
        replacements={
            "script": ValueReplacement(
                type="value",
                value=".claude/assets/deploy.sh"
            )
        }
    )
])

# Generate MCP configuration
configurator.mcp_servers([
    HttpMCPServer(
        name="my-http-server",
        type="http",
        url="https://example.com/mcp",
        headers={
            "Authorization": "Bearer F8417EA8-94F3-447C-A108-B0AD7E428BE6",
            "Content-Type": "application/json"
        },
    ),
    StdioMCPServer(
        name="my-stdio-server",
        type="stdio",
        command="node",
        args=["server.js"],
        env={
            "API_TOKEN": "84EBB71B-0FF8-49D8-84C8-55FF9550CA2C"
        },
    ),
])

# Generate rules (rules)
configurator.rules(
    [
        Rule(
            name="commit-messages",
            description="Commit message standards",
            prompt="Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)",
            metadata={
                "alwaysApply": True,
            },
            replacements={}
        ),
        Rule(
            name="coding-standards",
            description="Coding standards",
            prompt="All code should follow {{standard}}",
            metadata={},
            replacements={
                "standard": ValueReplacement(
                    type="value",
                    value="PEP 8"
                )
            }
        )
    ],
    RuleMode.MERGED
)

# Copy assets to the agent's directory
configurator.assets([
    ".charlie/assets/deploy.sh",
])

Supported Agents

Charlie currently supports the following AI agents:

  • Claude Code (claude) - Claude's AI coding assistant
  • Cursor (cursor) - AI-powered code editor
  • GitHub Copilot (copilot) - GitHub's AI pair programmer

Run charlie list-agents to see all available agents.

Metadata support

Charlie uses pass-through metadata - add any agent-specific metadata to your commands or rules, and Charlie will include them in generated output:

Charlie extracts these fields and includes them in agent-specific output (YAML frontmatter for Markdown agents, TOML fields for TOML agents). See AGENT_FIELDS.md for details on which agents support which fields.

Rules Generation Modes

Rules (rules) can be generated in two modes:

Merged Mode (default) - Single file with all sections:

charlie generate cursor --rules-mode merged

Separate Mode - One file per section:

charlie generate cursor --rules-mode separate

Use merged mode for simple projects, separate mode for better organization in complex projects.

Development

Use Dev Container (optional)

Open the project in VS Code with the Dev Containers extension:

  1. Open the project in VS Code
  2. Press F1 and select "Dev Containers: Reopen in Container"
  3. Wait for the container to build (first time only)
  4. Start coding with all tools pre-configured (pytest, mypy, ruff)

The Dev Container provides a consistent development environment with all dependencies and VS Code extensions pre-installed.

Developer commands

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest # or `make test`

# Run with coverage
pytest --cov=charlie # or `make test-coverage`

# Run ruff
ruff check . # or `make lint` (`make format` to format the code)

# Run mypy
mypy --install-types --non-interactive src/charlie # or `make analyze`

Contributing

Contributions welcome! Key areas:

  • Adding support for new AI agents
  • Improving documentation
  • Adding more examples
  • Bug fixes and tests

License

MIT

Acknowledgments

Charlie was inspired by the need to maintain consistent command definitions across multiple AI agents in the Spec Kit project.

Metadata

Release files for charlie-agents 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for charlie-agents 0.7.0
File Size Uploaded Provenance
charlie_agents-0.7.0.tar.gz 42.0 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for charlie-agents 0.7.0
File Interpreter ABI Platform
charlie_agents-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 72.1 kB

Release files / charlie_agents-0.7.0.tar.gz

Download URL charlie_agents-0.7.0.tar.gz
Size 42.0 kB
Tags Source
SHA-256 checksum
How to use checksums
53b589101cd8251feb40c8ff642755bc4b1eeb9e5cc0e7e6fd90e821ac4f703a
BLAKE2b-256 checksum
How to use checksums
afd9a27dc47e0cfa78fc1c34a0902c7eac1c75b72282d9107daf5e24f4a9a6cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 7, 2026.

Transparency log

Release files / charlie_agents-0.7.0-py3-none-any.whl

Download URL charlie_agents-0.7.0-py3-none-any.whl
Size 30.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1e3f97cdd61968613fa746c001aa4ea2b390d00837af75a663fbc8298ccd2542
BLAKE2b-256 checksum
How to use checksums
19e40a52196ba31af647443d0d38c34e67320b609fb85a981b4ad6283e293b33
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 7, 2026.

Transparency log

Security for charlie-agents 0.7.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for charlie_agents-0.7.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 7, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page