The Full McGinnis Stack: An Opinionated Python Developer Setup
Over the past year or so I’ve been building tools to solve specific annoyances in my development workflow. A task manager here, an MCP server there, a CLI for a thing that bugged me. At some point I looked up and realized I’d accidentally built an entire stack.
This post ties it all together. If you’re a Python developer who uses Claude Code (or another MCP-compatible agent), here’s how to set up everything I’ve built into a single coherent workflow, what each piece does, and how they talk to each other.
The Pieces
Here’s the full inventory, roughly in the order you’d encounter them during a project:
Task Management:
- ContextSwitch - Native macOS kanban board with built-in MCP server. Your agent reads and writes tasks to the same board you see.
- todolist-mcp - The open-source, cross-platform alternative. SQLite-backed with a web kanban UI. Same idea, runs anywhere.
Reusable Expertise:
- python-skills - 12 Claude skills covering Python library development: project setup, testing, packaging, security auditing, performance, API design, and more.
- Lexicon - Personal prompt library served via MCP. Your best prompts become slash commands.
Guardrails:
- Claude Code hooks for uv - A PreToolUse hook that intercepts bare
pipandpythoncommands and redirects Claude to use uv instead.
Build and Test:
- makefile-mcp - Exposes your Makefile targets as MCP tools. The agent runs
make test,make lint,make buildthrough proper channels instead of constructing shell commands. - mutmut-mcp - Mutation testing via MCP. Finds the gaps your line coverage metrics miss.
Writing and Content (if applicable):
- writing-tools-mcp - Readability scoring, keyword extraction, style checking, AI content detection.
- hugo-frontmatter-mcp - Hugo-specific frontmatter management (only relevant if you blog with Hugo).
Repository Governance:
- Rampart - CLI for auditing and enforcing GitHub branch protection rules across repos. Define rules in YAML, audit compliance, auto-fix violations.
Bonus Tools:
- ReleaseRadar - TUI for monitoring GitHub releases across your dependencies.
- Vanity - Syncs GitHub contribution graphs across multiple accounts.
The Core Setup for Python Development
You don’t need all of these. Here’s the subset that matters most for a Python developer working with Claude Code, and the configuration to wire them together.
Step 1: Install the MCP Servers
Add these to your Claude Code MCP configuration (in ~/.claude/settings.json or your project’s .mcp.json):
{
"mcpServers": {
"makefile": {
"command": "uvx",
"args": ["--from", "git+https://github.com/wdm0006/makefile-mcp", "makefile-mcp"]
},
"mutmut": {
"command": "uvx",
"args": ["--from", "git+https://github.com/wdm0006/mutmut-mcp", "mutmut-mcp"]
},
"todolist": {
"command": "uvx",
"args": ["--from", "git+https://github.com/wdm0006/todolist-mcp", "todolist-mcp"]
}
}
}
If you’re on macOS, replace todolist-mcp with ContextSwitch from the Mac App Store. It registers its own MCP server automatically.
Step 2: Add the uv Hook
If you’re all-in on uv (and you should be – I wrote about why), add the PreToolUse hook that forces uv. It intercepts bare pip install, python, pytest, and similar commands, blocks them, and tells Claude the uv equivalent. It only activates in projects with a pyproject.toml, so your non-Python work is unaffected.
This is more reliable than putting “use uv” in your CLAUDE.md. The hook is enforcement, not suggestion.
Step 3: Install the Python Skills
# Add the marketplace
/plugin marketplace add wdm0006/python-skills
# Install everything at once
/plugin install python-library-complete@wdm0006-python-skills
# Or pick what you need
/plugin install python-library-foundations@wdm0006-python-skills
/plugin install python-library-quality@wdm0006-python-skills
This gives Claude Code built-in expertise on project setup (uv, ruff, pytest, pre-commit), testing patterns (fixtures, parametrization, Hypothesis), packaging (pyproject.toml, trusted publishing), security auditing (Bandit, pip-audit, Semgrep), and more. I wrote a whole post about these and there’s a comprehensive guide behind them.
Step 4: Write a Makefile
The Makefile is the contract between you and the agent. makefile-mcp turns each target into a tool the agent can call, so you want targets for the things you’d actually want an agent to do:
.PHONY: test lint format build clean
test: ## Run the test suite
uv run pytest tests/ -v
lint: ## Run ruff linter
uv run ruff check .
format: ## Auto-format code
uv run ruff format .
build: ## Build the package
uv build
clean: ## Remove build artifacts
rm -rf dist/ build/ *.egg-info
The ## comments become tool descriptions in the MCP server. The agent sees “Run the test suite” next to the make_test tool and knows what it does.
Step 5: Set Up Task Management
If you’re using ContextSwitch, just create a new project in the app. The MCP server picks it up automatically.
If you’re using todolist-mcp, it creates its SQLite database on first run. You can access the kanban web UI to see tasks visually while the agent manages them programmatically.
Either way, you now have an agent that can manage its own work queue. When working on a multi-step feature, it creates tasks with dependencies, picks them up in order, marks them done, and moves to the next one. I wrote about how this works in practice when building Evergreen.
How a Session Actually Works
With everything wired up, here’s what a typical session looks like when I ask Claude Code to add a feature to a Python library:
- Agent checks the task board for existing work. If the feature is already broken down into tasks, it picks up the next ready one. If not, it creates the breakdown.
- Agent implements the change using expertise from python-skills. It knows to use uv, write Google-style docstrings, structure tests with fixtures and parametrization.
- Agent runs the test suite via makefile-mcp (
make_test). Fixes any failures. - Agent runs the linter and formatter via makefile-mcp (
make_lint,make_format). - Agent runs mutation testing via mutmut-mcp on the changed code. Writes targeted tests to kill surviving mutants.
- Agent marks the task done and picks up the next one.
The key thing: none of this requires my intervention. The agent has the tools to run the full development loop and the expertise to do it well. I review the results, not each step.
Adding Lexicon for Repeated Workflows
If you find yourself kicking off the same workflows repeatedly (“run the linter and fix everything”, “do a security audit”, “review the test suite for gaps”), Lexicon turns those into saved prompts served via MCP.
Your prompts become slash commands in Claude Code. Instead of typing out “run mutation testing on the auth module, prioritize surviving mutants by severity, and write tests for the top 5,” you save it once and invoke it with /lexicon:mutation_review.
Governance with Rampart
For teams or anyone managing multiple repos, Rampart handles the branch protection side of things. Define your rules in YAML:
rules:
require_pull_request: true
required_approving_review_count: 1
require_status_checks: true
required_status_checks:
- "tests"
- "lint"
Then audit across your org:
# Check compliance
rampart audit --org your-org --config rampart.yaml
# Auto-fix violations
rampart apply --org your-org --config rampart.yaml --dry-run
It’s a Homebrew install: brew install wdm0006/tap/rampart.
What’s Worth Starting With
If this feels like a lot, here’s the minimum viable setup:
- makefile-mcp + a Makefile with
test,lint, andformattargets. This alone changes how much an agent can accomplish autonomously. - python-skills foundations bundle. Gets you the project setup and testing expertise.
- Either ContextSwitch or todolist-mcp. Once the agent can manage its own task queue, multi-step work gets dramatically more reliable.
Add mutmut-mcp when you care about test quality beyond line coverage. Add Lexicon when you’re tired of retyping the same prompts. Add Rampart when you’re managing more than a handful of repos.
The whole point of building these as separate, composable tools is that you don’t have to adopt them all at once. Each one solves a specific problem. Together they form something more complete than any of them alone.
Links:
Stay in the loop
Get notified when I publish new posts. No spam, unsubscribe anytime.