Skip to main content

Universal command transpiler for AI agents, MCP servers, and rules

Project description

Charlie - Universal Command Transpiler

Define slash commands, MCP servers, and agent rules once in YAML. Generate for any AI agent.

Charlie is a universal command definition system that transpiles YAML configurations into agent-specific formats for AI assistants, MCP servers, and IDE rules.

Tests Coverage Python

Features

  • โœจ Single Definition: Write commands once in YAML
  • ๐Ÿค– Multi-Agent Support: Generate for 15+ AI agents (Claude, Copilot, Cursor, Gemini, Windsurf, and more)
  • ๐Ÿ”Œ 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
  • ๐Ÿš€ Zero Config: Works without any configuration file - infers project name from directory
  • โšก Runtime Targeting: Choose which agents to generate for at runtime
  • ๐Ÿ“ฆ Library & CLI: Use as CLI tool or import as Python library

Quick Start

Installation

pip install charlie-agents

Create Configuration (Optional)

Charlie works without any configuration file! It will infer your project name from the directory name.

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

version: "1.0"  # Optional, defaults to "1.0"

project:
  name: "my-project"      # Optional, inferred from directory name
  command_prefix: "myapp" # Optional, omit for simple command names

mcp_servers:
  - name: "myapp-commands"
    command: "node"
    args: ["dist/mcp-server.js"]

commands:
  - name: "init"
    description: "Initialize a new feature"
    prompt: |
      ## User Input

      {{user_input}}

      ## Instructions

      1. Parse the description
      2. Run: {{script}}
    scripts:
      sh: "scripts/init.sh"
      ps: "scripts/init.ps1"

What's Optional?

  • The entire charlie.yaml file (project name inferred from directory)
  • project.name field (inferred from directory name)
  • project.command_prefix (commands use simple names like init.md instead of myapp.init.md)

Generate Outputs

# Setup for specific agent (generates commands, MCP, and rules by default)
charlie setup claude

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

# Setup without rules
charlie setup claude --no-rules

# Validate configuration
charlie validate

Usage

CLI Commands

setup

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

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

# Explicit config file
charlie setup gemini --config my-config.yaml

# Skip specific artifacts if not needed
charlie setup claude --no-mcp --no-rules  # Only commands
charlie setup cursor --no-commands        # Only MCP and rules

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

validate

Validate YAML configuration:

# Auto-detect charlie.yaml
charlie validate

# Specific file
charlie validate my-config.yaml

list-agents

List all supported AI agents:

charlie list-agents

info

Show detailed information about an agent:

charlie info claude
charlie info gemini

Library API

Use Charlie programmatically in Python:

from charlie import CommandTranspiler

# Initialize with config
transpiler = CommandTranspiler("charlie.yaml")

# Setup for Claude with all artifacts (explicit in Python API)
results = transpiler.generate(
    agent_name="claude",
    commands=True,  # Default: True
    mcp=True,       # Default: False
    rules=True,     # Default: False
    output_dir="./output"
)

# Setup for Gemini with selective generation
results = transpiler.generate(
    agent_name="gemini",
    commands=True,
    mcp=False,
    rules=True,
    output_dir="./output"
)

# Generate only MCP config
mcp_file = transpiler.generate_mcp("./output")

# Generate only rules for an agent
rules_files = transpiler.generate_rules(
    agent_name="cursor",
    output_dir="./output"
)

Note: The Python API defaults to commands=True, mcp=False, rules=False, while the CLI generates all artifacts by default. Use explicit parameters in Python for fine-grained control.

Supported Agents

Charlie supports 15+ AI agents with built-in knowledge of their requirements:

Agent Format Directory Notes
Claude Code Markdown .claude/commands/ โœ… Full support
GitHub Copilot Markdown .github/prompts/ โœ… Full support
Cursor Markdown .cursor/commands/ โœ… Full support
Gemini CLI TOML .gemini/commands/ โœ… Full support
Qwen Code TOML .qwen/commands/ โœ… Full support
Windsurf Markdown .windsurf/workflows/ โœ… Full support
Kilo Code Markdown .kilocode/workflows/ โœ… Full support
opencode Markdown .opencode/command/ โœ… Full support
Codex CLI Markdown .codex/prompts/ โœ… Full support
Auggie CLI Markdown .augment/commands/ โœ… Full support
Roo Code Markdown .roo/commands/ โœ… Full support
CodeBuddy CLI Markdown .codebuddy/commands/ โœ… Full support
Amp Markdown .agents/commands/ โœ… Full support
Amazon Q Developer Markdown .amazonq/prompts/ โœ… Full support

Run charlie list-agents for the complete list.

Configuration

Charlie is zero-config by default - it works without any configuration file and infers the project name from your directory name.

For advanced features, Charlie supports two configuration approaches:

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

Directory-Based Configuration (Recommended)

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)
โ””โ”€โ”€ .charlie/
    โ”œโ”€โ”€ commands/
    โ”‚   โ”œโ”€โ”€ init.md          # One file per command (markdown with frontmatter)
    โ”‚   โ””โ”€โ”€ deploy.md
    โ”œโ”€โ”€ rules/
    โ”‚   โ”œโ”€โ”€ commit-messages.md  # One file per rule section (markdown with frontmatter)
    โ”‚   โ””โ”€โ”€ code-style.md
    โ””โ”€โ”€ mcp-servers/
        โ””โ”€โ”€ local-tools.yaml    # MCP servers still use YAML

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

Command File (.charlie/commands/init.md):

---
name: "init"
description: "Initialize feature"
allowed-tools: Bash(mkdir:*) # Claude-specific
tags: ["init", "setup"]
category: "project"
scripts:
  sh: "scripts/init.sh"
---

## User Input

{{user_input}}

## Instructions

Initialize the feature and run: {{script}}

Rules File (.charlie/rules/code-style.md):

---
title: "Code Style"
order: 1
alwaysApply: true  # Cursor-specific
globs: ["**/*.py"]  # Cursor-specific
priority: "high"    # Windsurf-specific
---

## Formatting

Use Black for formatting with max line length: 100.

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

Monolithic YAML Schema

For simpler projects, use a single charlie.yaml file. All fields are optional:

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

project:
  name: "project-name"     # Optional: Inferred from directory name if omitted
  command_prefix: "prefix" # Optional: Used in /prefix.command-name, omit for simple names

# MCP server definitions (optional)
mcp_servers:
  - name: "server-name"
    command: "node"
    args: ["server.js"]
    env:
      KEY: "value"

# Rules configuration (optional)
rules:
  title: "Custom Title"
  include_commands: true
  include_tech_stack: true
  preserve_manual: true

# Command definitions (required)
commands:
  - name: "command-name"
    description: "Command description"
    prompt: |
      Command prompt template

      User input: {{user_input}}
      Run: {{script}}
    scripts:
      sh: "path/to/script.sh"
      ps: "path/to/script.ps1"
    agent_scripts: # Optional agent-specific scripts
      sh: "path/to/agent-script.sh"

Placeholders

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

Content Placeholders:

  • {{user_input}} โ†’ Replaced with agent-specific input placeholder ($ARGUMENTS or {{args}})
  • {{script}} โ†’ Replaced with the appropriate script path based on platform
  • {{agent_script}} โ†’ Replaced with optional agent-specific script path
  • {{agent_name}} โ†’ Replaced with the agent's name (e.g., Cursor, Claude Code, GitHub Copilot)

Path Placeholders:

  • {{root}} โ†’ Resolves to the project root directory
  • {{agent_dir}} โ†’ Resolves to agent's base directory (e.g., .claude, .cursor)
  • {{commands_dir}} โ†’ Resolves to agent's commands directory (e.g., .claude/commands/)
  • {{rules_dir}} โ†’ Resolves to agent's rules directory (e.g., .claude/rules/)

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

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

Agent-Specific Fields

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

Command Fields:

# Claude-specific
allowed-tools: Bash(git add:*), Bash(git commit:*)

# Generic metadata
tags: ["git", "vcs"]
category: "source-control"

Rules Fields:

# Cursor-specific
alwaysApply: true
globs: ["**/*.py", "!**/test_*.py"]

# Windsurf-specific
priority: "high"
categories: ["style", "formatting"]

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 are generated by default in two modes:

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

charlie setup cursor --rules-mode merged

Separate Mode - One file per section:

charlie setup cursor --rules-mode separate

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

Output Examples

Agent Command (Markdown)

Generated .claude/commands/myapp.init.md:

---
description: Initialize a new feature
---

## User Input

```text
$ARGUMENTS
```

Instructions

  1. Parse the description
  2. Run: scripts/init.sh

### Agent Command (TOML)

Generated `.gemini/commands/myapp.init.toml`:

```toml
description = "Initialize a new feature"

prompt = """
## User Input

{{args}}

## Instructions

1. Parse the description
2. Run: scripts/init.sh
"""

MCP Server Config

Generated mcp-config.json:

{
  "mcpServers": {
    "myapp-commands": {
      "command": "node",
      "args": ["dist/mcp-server.js"],
      "capabilities": {
        "tools": {
          "enabled": true,
          "list": [
            {
              "name": "myapp_init",
              "description": "Initialize a new feature",
              "inputSchema": {
                "type": "object",
                "properties": {
                  "input": { "type": "string" }
                },
                "required": ["input"]
              }
            }
          ]
        }
      }
    }
  }
}

Rules File

Generated .windsurf/rules/charlie-rules.md:

# Development Guidelines

Auto-generated by Charlie from configuration
Last updated: 2025-01-15

## Available Commands

- `/myapp.init` - Initialize a new feature

## Command Reference

### /myapp.init

**Description**: Initialize a new feature

**Usage**: `/myapp.init <input>`

**Scripts**:

- Bash: `scripts/init.sh`
- PowerShell: `scripts/init.ps1`

<!-- MANUAL ADDITIONS START -->
<!-- Your custom rules here - preserved on regeneration -->
<!-- MANUAL ADDITIONS END -->

Examples

See examples/ directory for complete examples:

Development

Running Tests

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

# Run tests
pytest

# Run with coverage
pytest --cov=charlie

Project Structure

charlie/
โ”œโ”€โ”€ src/charlie/          # Main package
โ”‚   โ”œโ”€โ”€ agents/           # Agent adapters
โ”‚   โ”œโ”€โ”€ cli.py            # CLI interface
โ”‚   โ”œโ”€โ”€ transpiler.py     # Core engine
โ”‚   โ”œโ”€โ”€ mcp.py            # MCP generator
โ”‚   โ”œโ”€โ”€ rules.py          # Rules generator
โ”‚   โ”œโ”€โ”€ parser.py         # YAML parser
โ”‚   โ””โ”€โ”€ schema.py         # Pydantic schemas
โ”œโ”€โ”€ tests/                # Test suite
โ”œโ”€โ”€ examples/             # Example configurations
โ””โ”€โ”€ README.md

Use Cases

1. Unified Command Interface

Define commands once, setup for any AI assistant (all artifacts generated by default):

charlie setup claude
charlie setup copilot
charlie setup cursor

2. Selective Artifact Generation

Skip artifacts you don't need:

# Skip MCP if not using MCP servers
charlie setup claude --no-mcp

# Skip rules if you manage them manually
charlie setup cursor --no-rules

# Generate only MCP and rules (no commands)
charlie setup windsurf --no-commands

3. CI/CD Integration

Setup agent-specific configs during build:

from charlie import CommandTranspiler

transpiler = CommandTranspiler("charlie.yaml")

# Setup for Claude (all artifacts by default)
transpiler.generate(
    agent_name="claude",
    mcp=True,
    rules=True,
    output_dir="./dist"
)

# Setup for Copilot with selective generation
transpiler.generate(
    agent_name="copilot",
    commands=True,
    mcp=False,
    rules=True,
    output_dir="./dist"
)

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

charlie_agents-0.2.0.tar.gz (2.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

charlie_agents-0.2.0-py3-none-any.whl (24.4 kB view details)

Uploaded Python 3

File details

Details for the file charlie_agents-0.2.0.tar.gz.

File metadata

  • Download URL: charlie_agents-0.2.0.tar.gz
  • Upload date:
  • Size: 2.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for charlie_agents-0.2.0.tar.gz
Algorithm Hash digest
SHA256 64cc3828ff68c39efb09b9607123249d720d14493722a958baff677f2aed9666
MD5 769c8399324b7d6487e50956cb05cf36
BLAKE2b-256 c51093e78135cb3f0417aa64d94bb29a836c614501dea9464cc02ae925fd9277

See more details on using hashes here.

File details

Details for the file charlie_agents-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: charlie_agents-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 24.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for charlie_agents-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b4f2030c1a7b7ec8ce6404bc2e8ea6980800d146d76780caf8f21f9ca227f45a
MD5 063093986c16fb2084b3f89566759bba
BLAKE2b-256 23bc3de8f8632ef1f6a8b6c869202f5d47572395ac9c8e583174740dcb40652e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page