MCP Server Make
by wrale
- docs
# Creating Custom Makefiles for MCP Server Make
This guide provides detailed information on creating effective custom Makefiles specifically designed to work well with MCP Server Make and Large Language Models (LLMs).
## Table of Contents
1. [Design Principles](#design-principles)
2. [Structure and Organization](#structure-and-organization)
3. [Target Naming Conventions](#target-naming-conventions)
4. [Output Formatting](#output-formatting)
5. [Error Handling](#error-handling)
6. [Example Templates](#example-templates)
7. [Working with LLMs](#working-with-llms)
8. [Advanced Techniques](#advanced-techniques)
## Design Principles
When creating Makefiles for use with MCP Server Make and LLMs, focus on these core principles:
### 1. Clarity
LLMs understand context best when it's explicit. Your Makefile should be self-explanatory with clear target names and comments.
### 2. Feedback
Ensure commands provide meaningful, structured output that an LLM can parse and interpret.
### 3. Robustness
Commands should handle errors gracefully and be idempotent (safe to run multiple times).
### 4. Discoverability
Include self-documentation, help text, and descriptive comments to help the LLM understand available capabilities.
### 5. Target Introduction
Remember that Claude cannot automatically discover the targets in your Makefile. You must explicitly tell Claude about available targets at the beginning of each conversation. Always include a help target to make this easier.
## Structure and Organization
A well-structured Makefile typically includes:
### Header Section
Start with essential information about your Makefile:
```makefile
# Project: My Project Name
# Author: Your Name
# Description: This Makefile provides commands for development workflow
# Usage: Run 'make help' to see available commands
.DEFAULT_GOAL := help
```
### Help Target (Required)
The `help` target is especially important for working with LLMs. It enables Claude to discover other available targets:
```makefile
help: ## Display available commands
@echo "Available Commands:"
@echo
@awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
```
Always include this as your first interaction when introducing Claude to a new Makefile:
```
Human: Please run make help to see what commands we have available.
```
### Variable Definitions
Define variables at the top for easy configuration:
```makefile
# Project settings
PROJECT_NAME = my-project
SRC_DIR = src
TESTS_DIR = tests
BUILD_DIR = build
```
### Target Groups
Organize targets into logical groups with comments:
```makefile
# -----------------------------
# Development commands
# -----------------------------
build: ...
test: ...
# -----------------------------
# Utility commands
# -----------------------------
clean: ...
help: ...
```
## Target Naming Conventions
Use clear, descriptive target names following these conventions:
### Common Standard Names
Standard targets that LLMs will easily recognize:
- `help`: Display available commands
- `build`: Build the project
- `test`: Run tests
- `clean`: Remove build artifacts
- `lint`: Check code style/quality
- `format`: Auto-format code
- `install`: Install the project
- `deploy`: Deploy the project
### Compound Names
For related tasks, use consistent prefixes:
```makefile
test: ## Run all tests
test-unit: ## Run only unit tests
test-integration: ## Run only integration tests
```
### Task-Specific Names
For specialized tasks, be descriptive and use hyphens for multi-word names:
```makefile
generate-docs: ## Generate documentation
update-dependencies: ## Update project dependencies
```
## Output Formatting
Format your command output to be easily parsable by LLMs:
### Structured Output
```makefile
test:
@echo "=== Running Tests ==="
@python -m pytest $(TESTS_DIR)
@echo "=== Tests Complete ==="
```
### Status Headers
Use clear section headers:
```makefile
build:
@echo "STEP 1: Cleaning old builds"
rm -rf $(BUILD_DIR)
@echo "STEP 2: Compiling source files"
# compilation commands
@echo "STEP 3: Packaging artifacts"
# packaging commands
@echo "BUILD SUCCESSFUL: Output available in $(BUILD_DIR)"
```
### Progress Indicators
Show progress for long-running tasks:
```makefile
deploy:
@echo "[1/3] Building application..."
# build commands
@echo "[2/3] Running tests..."
# test commands
@echo "[3/3] Deploying to server..."
# deploy commands
@echo "DEPLOY COMPLETE"
```
## Error Handling
Ensure your Makefile handles errors gracefully:
### Error Checking
```makefile
test:
@echo "Running tests..."
@if python -m pytest $(TESTS_DIR); then \
echo "Tests passed successfully"; \
else \
echo "Tests failed with status $$?"; \
exit 1; \
fi
```
### Conditional Logic
Handle different environments or configurations:
```makefile
install:
@if [ -f requirements.txt ]; then \
echo "Installing from requirements.txt"; \
pip install -r requirements.txt; \
elif [ -f pyproject.toml ]; then \
echo "Installing from pyproject.toml"; \
pip install -e .; \
else \
echo "ERROR: No installation files found"; \
exit 1; \
fi
```
## Example Templates
Here are some template Makefiles for different project types:
### Basic Development Makefile
```makefile
.DEFAULT_GOAL := help
# Project settings
PROJECT_NAME = my-project
# Colors for output
YELLOW := \033[1;33m
GREEN := \033[1;32m
RED := \033[1;31m
RESET := \033[0m
help: ## Display available commands
@echo "Available Commands:"
@echo
@awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_-]+:.*?##/ { printf " $(YELLOW)%-20s$(RESET) %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
clean: ## Clean build artifacts
@echo "Cleaning build artifacts..."
rm -rf build/ dist/ *.egg-info
test: ## Run tests
@echo "Running tests..."
pytest tests/
@echo "$(GREEN)Tests completed successfully$(RESET)"
lint: ## Lint code
@echo "Linting code..."
flake8 src/
@echo "$(GREEN)Lint check completed$(RESET)"
format: ## Format code
@echo "Formatting code..."
black src/ tests/
@echo "$(GREEN)Code formatted successfully$(RESET)"
build: clean ## Build package
@echo "Building package..."
python -m build
@echo "$(GREEN)Build completed successfully$(RESET)"
install: ## Install package locally
@echo "Installing package..."
pip install -e .
@echo "$(GREEN)Installation completed successfully$(RESET)"
.PHONY: help clean test lint format build install
```
### Python Project Makefile
```makefile
.DEFAULT_GOAL := help
# Project settings
PROJECT_NAME = python-project
SRC_DIR = src
TESTS_DIR = tests
VENV_DIR = .venv
PYTHON = python3
help: ## Display available commands
@echo "Available Commands:"
@echo
@awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
venv: ## Create virtual environment
@echo "Creating virtual environment..."
$(PYTHON) -m venv $(VENV_DIR)
@echo "Virtual environment created at $(VENV_DIR)"
@echo "Activate with: source $(VENV_DIR)/bin/activate"
install-dev: ## Install development dependencies
@echo "Installing development dependencies..."
pip install -e ".[dev]"
@echo "Development dependencies installed"
test: ## Run tests
@echo "Running tests..."
pytest $(TESTS_DIR)
@echo "Tests completed"
lint: ## Lint code
@echo "Linting code with flake8..."
flake8 $(SRC_DIR)
@echo "Linting code with mypy..."
mypy $(SRC_DIR)
@echo "Lint checks completed"
format: ## Format code
@echo "Formatting code with black..."
black $(SRC_DIR) $(TESTS_DIR)
@echo "Formatting code with isort..."
isort $(SRC_DIR) $(TESTS_DIR)
@echo "Code formatting completed"
check: lint test ## Run all checks (lint, test)
@echo "All checks completed successfully"
clean: ## Clean build artifacts
@echo "Cleaning build artifacts..."
rm -rf build/ dist/ *.egg-info __pycache__/
find . -type d -name __pycache__ -exec rm -rf {} +
find . -type f -name "*.pyc" -delete
@echo "Clean completed"
.PHONY: help venv install-dev test lint format check clean
```
## Working with LLMs
When using your custom Makefile with Claude through MCP Server Make, follow these practices:
### Introducing Your Makefile
1. **Start each new conversation with target discovery**:
```
Human: I'm working with a custom Makefile. Let's first see what targets are available by running make help.
```
2. **Explain custom targets**:
```
Human: The "analyze-code" target runs static analysis tools. The "benchmark" target measures performance.
```
3. **Share important context about your build system**:
```
Human: This is a multi-stage build process. We need to run "make deps" before "make build".
```
### Iterative Conversations
LLMs don't retain knowledge of your Makefile between sessions. For efficient collaboration:
- Begin each session with `make help`
- Reference target descriptions whenever using non-standard targets
- If switching projects or Makefiles, be explicit about the change
### Remembering Session Limitations
Each time you start a new conversation with Claude, it won't remember previously discovered make targets. Plan your conversations to include necessary context at the beginning of each session.
## Advanced Techniques
### Self-Discovery
Enable targets that help LLMs understand your codebase:
```makefile
project-info: ## Display project information
@echo "PROJECT INFORMATION"
@echo "==================="
@echo "Project: $(PROJECT_NAME)"
@echo "Version: $(shell cat VERSION 2>/dev/null || echo 'unknown')"
@echo "Source files: $(shell find $(SRC_DIR) -type f -name "*.py" | wc -l) Python files"
@echo "Test files: $(shell find $(TESTS_DIR) -type f -name "test_*.py" | wc -l) test files"
list-sources: ## List all source files
@echo "SOURCE FILES:"
@find $(SRC_DIR) -type f -name "*.py" | sort
list-tests: ## List all test files
@echo "TEST FILES:"
@find $(TESTS_DIR) -type f -name "test_*.py" | sort
```
### Interactive Targets
Create targets that provide interactive diagnostics:
```makefile
diagnose: ## Run interactive diagnostics
@echo "Running system diagnostics..."
@echo "Python version: $(shell python --version 2>&1)"
@echo "Operating system: $(shell uname -a)"
@echo "Dependencies status:"
@pip list | grep -E 'pytest|black|flake8|mypy'
@echo "Project structure:"
@find . -type d -not -path "*/\.*" -not -path "*/venv*" | sort
@echo "Diagnostics complete"
```
### Integration with LLM Tools
Create targets specifically for LLM interaction:
```makefile
llm-context: ## Generate context for LLM
@echo "REPOSITORY INFORMATION"
@echo "======================"
@echo "Recent commits:"
@git log -n5 --oneline
@echo "\nModified files:"
@git status --short
@echo "\nProject structure:"
@find . -type d -maxdepth 2 -not -path "*/\.*" | sort
@echo "\nKey files:"
@ls -la *.md *.py 2>/dev/null || echo "No key files found"
```
By following these guidelines, you can create Makefiles that work seamlessly with MCP Server Make and enable LLMs to assist more effectively with your development workflow.