Skip to content

[CHORE]: Replace copier with cookiecutter for template scaffolding #2361

@crivetimihai

Description

@crivetimihai

Summary

Replace copier with cookiecutter for project/plugin template scaffolding.

Current Copier Usage

Copier is used in three main areas:

1. Plugin Templating (/copier.yml)

  • Bootstraps new plugins via mcpplugins bootstrap CLI command
  • Supports two template types: native (in-process Python) and external (MCP-based)
  • Templates located in /plugin_templates/{native,external}/

2. Python MCP Server Scaffolding

  • Config: /mcp-servers/templates/python/copier.yaml
  • Script: /mcp-servers/scaffold-python-server.sh
  • Collects: project_name, package_name, version, author, license, python_min, include_container, include_http_bridge

3. Go MCP Server Scaffolding

  • Config: /mcp-servers/templates/go/copier.yaml
  • Script: /mcp-servers/scaffold-go-server.sh
  • Collects: project_name, module_path, bin_name, version, license, go_version, include_container

Files Requiring Changes

Configuration Files

  • /copier.yml → convert to cookiecutter.json
  • /mcp-servers/templates/python/copier.yamlcookiecutter.json
  • /mcp-servers/templates/go/copier.yamlcookiecutter.json

Template Directories

  • /plugin_templates/native/ - update Jinja2 syntax if needed
  • /plugin_templates/external/ - update Jinja2 syntax if needed
  • /mcp-servers/templates/python/ - update templates
  • /mcp-servers/templates/go/ - update templates

Scripts and CLI

  • /mcp-servers/scaffold-python-server.sh - change copier copy to cookiecutter
  • /mcp-servers/scaffold-go-server.sh - change copier copy to cookiecutter
  • /mcpgateway/plugins/tools/cli.py - replace from copier import run_copy with cookiecutter API

Dependency

  • /pyproject.toml - replace copier>=9.11.3 with cookiecutter in [project.optional-dependencies].templating

Documentation

  • /mcp-servers/AGENTS.md
  • /plugins/AGENTS.md
  • /llms/plugins-llms.md

Migration Notes

Key Differences

Feature Copier Cookiecutter
Config file copier.yaml cookiecutter.json
Template vars {{ var }} {{ cookiecutter.var }}
Directory naming {{ var }}/ {{ cookiecutter.var }}/
Conditionals {% if var %} {% if cookiecutter.var %}
Default values In YAML config In JSON config
Git author lookup Built-in _copier_conf.data Requires hooks or manual
Subdirectory routing _subdirectory N/A (single template per repo)
VCS remote fetch Built-in Built-in

Python API Migration

Current (copier):

from copier import run_copy

run_copy(
    src_path=template_url,
    dst_path=destination,
    answers_file=answers_file,
    defaults=defaults,
    vcs_ref=vcs_ref,
    data={"default_author_name": name, "default_author_email": email},
    pretend=dry_run,
)

New (cookiecutter):

from cookiecutter.main import cookiecutter

cookiecutter(
    template=template_url,
    output_dir=destination,
    no_input=defaults,
    checkout=vcs_ref,
    extra_context={"author_name": name, "author_email": email},
)

Template Syntax Migration Example

Copier:

# {{ package_name }}/server.py.jinja
log = logging.getLogger("{{ package_name }}")

Cookiecutter:

# {{ cookiecutter.package_name }}/server.py
log = logging.getLogger("{{ cookiecutter.package_name }}")

Considerations

  1. Subdirectory routing: Copier's _subdirectory feature (used in plugin templates to select native vs external) doesn't have a direct equivalent in cookiecutter. May need separate template repos or a pre-hook.

  2. File extension: Copier uses .jinja extension; cookiecutter processes all files in template directory (or uses _copy_without_render for exclusions).

Acceptance Criteria

  • All three template systems (plugins, Python MCP, Go MCP) work with cookiecutter
  • mcpplugins bootstrap command works unchanged from user perspective
  • Scaffold scripts work unchanged from user perspective
  • Tests pass
  • Documentation updated

Metadata

Metadata

Assignees

Labels

COULDP3: Nice-to-have features with minimal impact if left out; included if time permitschoreLinting, formatting, dependency hygiene, or project maintenance choresdevopsDevOps activities (containers, automation, deployment, makefiles, etc)

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions