Skip to main content

Starter CLI for generating MCP wrappers around existing command-line tools.

Project description

MCP Templates

Production-style starter templates for turning existing CLIs into MCP servers quickly, safely, and with minimal deployment friction.

If you already have a useful command-line tool, script, or internal binary, this repo helps you expose it to MCP clients without rewriting the tool from scratch.

The path is intentionally simple:

existing CLI -> generated MCP wrapper -> validation -> client config -> working tool

Who This Is For

This repo is built for:

  • platform teams exposing internal tools to MCP clients
  • developers with a working CLI who want MCP support fast
  • AI enablement teams that need safe, debuggable tool wrappers
  • consultants or builders packaging an existing workflow for Claude Desktop, Claude Code, or similar clients

If MCP is new to you, start with docs/MCP_PRIMER.md.

Positioning

Most MCP examples prove that a server can run. This repo is aimed at the harder problem: getting a real internal tool wrapped, validated, and ready to ship without rebuilding it from scratch.

The core bet is simple:

  • reuse the CLI you already have
  • add safety guardrails by default
  • keep the server transport/client agnostic
  • make local setup and deployment boring

Why This Is Different

  • Safer than toy examples: templates start with path allowlists, timeout handling, arg validation, and structured JSON output.
  • Faster than framework-heavy rewrites: wrap an existing binary instead of reimplementing business logic in a new server stack.
  • More portable than client-specific setups: the same server can be registered in Claude Desktop, Claude Code, and other MCP clients.
  • Closer to production: examples are designed around real subprocess execution, explicit env configuration, and predictable failure modes.

Why This Beats Existing Options

For the right audience, this is better than most existing MCP starter options because it optimizes for migration, not greenfield demos.

  • Most examples show how to build an MCP server from scratch. This helps you keep the CLI you already trust.
  • Many wrappers stop at "it runs." This repo includes validation, generated configs, CI smoke tests, and packaging paths.
  • Client-specific examples often trap you in one setup. This stays transport- and client-agnostic.
  • Framework-heavy approaches can force a rewrite too early. This keeps the MCP layer thin until the workflow proves valuable.

If someone already has a working CLI, the comparison should not be "template versus template." It should be:

rewrite the tool vs wrap the tool safely and ship sooner

What You Get In Practice

With the current Python template, you can:

  • generate a project-specific MCP wrapper with renamed placeholders
  • point it at a real binary instead of a toy example
  • get project-specific sample client config files during bootstrap, already pointed at the generated mcp_server.py
  • get a starter .gitignore in the copied wrapper
  • keep the main MCP file visually obvious as mcp_server.py
  • move secondary tooling into support/
  • get a generated .env.example with the renamed runtime variables, and auto-load .env if present
  • get a generated START_HERE.md with first-run steps for the copied wrapper
  • validate setup with doctor.py before opening a client
  • validate setup with doctor.py before opening a client, including machine-readable --json output for CI or setup tooling
  • use a real mcp-template command from the repo root instead of calling an internal script path
  • package it with Docker
  • verify the template itself in CI with bootstrap, syntax, and smoke checks

30-Second Quickstart

If you already have a CLI, the basic flow is:

./mcp-template generate /path/to/your-project/mcp \
  --server-name your-project \
  --tool-name run_profile \
  --binary-name your-cli

Repeat --tool-name if your CLI needs more than one MCP tool stub:

mcp-template generate /path/to/your-project/mcp \
  --server-name factorlens \
  --tool-name analyze_csv \
  --tool-name analyze_compare \
  --tool-name explain_analyze

If a generated function name should map to a different CLI subcommand, opt in explicitly:

mcp-template generate /path/to/your-project/mcp \
  --server-name factorlens \
  --tool-name analyze_compare \
  --tool-subcommand analyze_compare=analyze-compare

If you want a different env namespace than the server slug, add:

--env-prefix YOUR_TEAM_TOOL

If you want to preview the generated output first, add:

--dry-run

If you already know the real executable path, add:

--bin-path /abs/path/to/your-cli

If you want the generated client config to use a specific Python interpreter, add:

--python-path /abs/path/to/python

If you want to prefill allowed directories too, add:

--read-dirs /abs/path/to/data,/abs/path/to/profiles \
--write-dirs /abs/path/to/artifacts

Then:

  1. replace the placeholder command mapping in mcp_server.py
  2. replace the stub binary in support/bin/
  3. fill in .env.example
  4. read START_HERE.md
  5. adapt one of the generated sample configs in examples/
  6. run support/doctor.py
  7. call version and paths
  8. validate with healthcheck

Install Options

Use one of these depending on how you want to adopt the tool:

  • From a clone right now: ./mcp-template generate ...
  • Local pip install from a clone: python -m pip install .
  • Local isolated install from a clone: pipx install .

After the package is published, the intended install command is:

pipx install mcp-template

Then the command stays the same everywhere:

mcp-template generate /path/to/your-project/mcp --server-name your-project

How It Fits Together

flowchart LR
    A["Existing CLI or binary"] --> B["Generated MCP wrapper"]
    B --> C["support/doctor.py validation"]
    B --> D["Claude Desktop / Claude Code / other MCP client"]
    D --> B
    B --> E["Allowed read/write dirs"]
    B --> F["Structured JSON results"]

Included

  • python-cli-template/: production-style Python MCP wrapper for any CLI tool
  • python-cli-template/bin/project-cli: stub binary used only for template smoke testing
  • python-cli-template/doctor.py: preflight checker for Python, env vars, paths, and client config JSON
  • python-cli-template/Dockerfile: minimal container target for packaging the Python template
  • mcp-template: repo-local launcher for the public CLI
  • src/mcp_template_cli/: installable mcp-template CLI package
  • scripts/init_python_cli_template.py: compatibility shim for the public CLI
  • .github/workflows/python-template-smoke.yml: CI smoke test for syntax, preflight validation, and container build
  • examples/claude_desktop_config.sample.json: local Claude Desktop config example
  • examples/claude_code_mcp.sample.json: generic Claude Code-style config example
  • docs/QUICKSTART.md: 10-minute setup flow
  • docs/MCP_PRIMER.md: short explanation of what MCP is and why this repo exists
  • docs/EXAMPLE_ADAPTER.md: concrete walkthrough for wrapping a real CLI command
  • docs/LAUNCH_CHECKLIST.md: rollout checklist for validating a wrapper before production use

How To Use

  1. Run the repo-local generator with ./mcp-template generate.
  2. Generate a project-specific copy.
  3. Replace the stub binary and adjust the command mapping.
  4. Adapt one of the generated sample configs in examples/ for your client.
  5. Set env vars (*_BIN, allowed read/write dirs).
  6. Run support/doctor.py to catch binary, Python, path, and config issues early.
  7. Register server in your MCP client config.
  8. Test with version, paths, and healthcheck first.

Best Fit

This repo is a strong fit when you already have:

  • a working CLI or script that solves the real problem
  • a need to expose it to an MCP client without a full rewrite
  • requirements around file access boundaries, predictable execution, and debuggable failures

It is less useful if you want a full hosted platform, a managed registry, or opinionated cloud infrastructure out of the box.

When Not To Use This

This repo is probably the wrong fit if:

  • you need a hosted control plane, not a local or self-managed MCP server
  • you do not already have a working CLI, script, or binary to wrap
  • you want a full product UI before you have validated the tool workflow
  • your use case requires broad unrestricted filesystem access with minimal guardrails

In those cases, a different architecture may be a better starting point than a thin wrapper around an existing command.

Quick Example

If you already have something like:

  • inventory-cli run --input profiles/acme.toml --out artifacts/report.json

you can use this repo to generate an MCP wrapper, map that command shape in mcp_server.py, lock access to the right directories, and expose it to an MCP client with a minimal config entry.

That is the core use case: keep the real tool, add a thin MCP layer, and make the setup repeatable.

For a more concrete walkthrough, see docs/EXAMPLE_ADAPTER.md. Before rollout, use docs/LAUNCH_CHECKLIST.md.

Design Principles

  • strict arg validation
  • path allowlists
  • no shell=True
  • subprocess timeout
  • structured JSON responses

Notes

  • Template is transport/runner-agnostic: same server can be used by Claude Desktop, Claude Code, and other MCP clients.
  • Each client still needs its own config entry pointing to the server command.
  • The included Dockerfile is intentionally minimal: you still need to copy your real CLI into the image and set PROJECT_BIN.
  • The smoke-test workflow uses a stub CLI so the template can be validated in CI without your real binary.
  • The repo now includes package metadata and bundled template assets so mcp-template can be distributed as a pip package, not only used from source.

FAQ

Do I need a desktop app for this?

No. The template is designed to stay headless and MCP-focused. A desktop app could be a future companion for setup or demos, but it is not required to use the template.

Can this wrap a compiled binary instead of a Python tool?

Yes. The template wraps a command-line executable through subprocess calls. Your real tool can be a Python CLI, shell-backed binary, Rust binary, Go binary, or another executable, as long as you map the command shape correctly.

Why not just build a custom MCP server from scratch?

If you already trust the CLI, a thin wrapper is usually faster to ship, easier to debug, and less likely to create a second implementation that drifts from the original tool.

CI Coverage

The starter workflow currently verifies the template in three layers:

  • bootstrap generation rewrites the template as expected
  • Python files compile cleanly
  • doctor.py passes in a normal runner environment
  • the Docker image builds and can run doctor.py inside the container

Near-Term Roadmap

To make this easier to deploy than other MCP starter options, the next high-value additions are:

  • example hosting configs for common runtimes
  • more reference adapters for common CLI patterns so users copy less and customize less

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

mcp_template-0.1.1.tar.gz (19.2 kB view details)

Uploaded Source

Built Distribution

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

mcp_template-0.1.1-py3-none-any.whl (18.4 kB view details)

Uploaded Python 3

File details

Details for the file mcp_template-0.1.1.tar.gz.

File metadata

  • Download URL: mcp_template-0.1.1.tar.gz
  • Upload date:
  • Size: 19.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mcp_template-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e4e51bee8542db2e890ac449453c91cc8a9605c8c5f0701b010488ba8f40a717
MD5 ab452253d89fdfaeba1450278a9adc4b
BLAKE2b-256 1d52bca9889c33f1cf64766d06d2bac4e48cf56684ed8ee775e12c55c73c90ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_template-0.1.1.tar.gz:

Publisher: release.yml on kraftaa/mcp-templates

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_template-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: mcp_template-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 18.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mcp_template-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 15e7e8ec1e9543da9b7efdf40d5bf9b19eac2fc086797bc09cc5940ce5a0092d
MD5 58e7d19c23dfdcca4fdf93719175131e
BLAKE2b-256 c31fabac1618a9edabf06d4737a77bb6258b74890b52f46c0bba3b80df54f73d

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_template-0.1.1-py3-none-any.whl:

Publisher: release.yml on kraftaa/mcp-templates

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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