MCP Server for competitive programming problem creation, based on AutoCode paper
Project description
AutoCode MCP Server
An MCP Server for competitive programming problem creation, implementing the Validator-Generator-Checker framework from the AutoCode paper.
AutoCode MCP Server provides 14 atomic tools that enable AI assistants to create, validate, and test competitive programming problems. It handles compilation, execution, stress testing, and test data generation—letting the AI focus on problem design and solution logic.
Features
- Validator-Generator-Checker Framework — Automated validation of input correctness, multi-strategy test generation, and output verification based on the AutoCode paper
- 14 Atomic Tools — File operations, solution building, stress testing, validator/generator/checker construction, and more
- testlib.h Support — Full integration with the competitive programming standard library for validators, generators, and checkers
- Multi-Strategy Generation — Four generation strategies: tiny (exhaustive), random, extreme (edge cases), and TLE-inducing
- Stress Testing — Automated comparison between optimal and brute-force solutions with configurable trial counts
- MCP Protocol — Native support for Claude Code, Cursor, and other MCP-compatible AI tools
- Safe Execution — Timeout control, memory limits (Linux), and temporary directory isolation
- Polygon Packaging — Export problems in Polygon format for Codeforces-style platforms
Installation
From PyPI (Recommended)
pip install autocode-mcp
Using uv
uv tool install autocode-mcp
From Source
git clone https://github.com/your-repo/autocode-mcp.git
cd autocode-mcp
uv sync
Prerequisites
- Python 3.14+
- g++ compiler with C++20 support (GCC 10+ recommended)
- testlib.h (included in templates/)
Verify your setup:
# Check Python version
python --version
# Check g++ version
g++ --version
# Run tests
uv run pytest tests/ -v
Quick Start
1. Configure Your MCP Client
Add to your Claude Code configuration (~/.config/claude-code/config.json):
{
"mcpServers": {
"autocode": {
"command": "autocode-mcp"
}
}
}
2. Create Your First Problem
In Claude Code, simply ask:
"Create a competitive programming problem: Given two integers A and B, output their sum."
Claude will use AutoCode tools to:
- Generate problem statement
- Implement solutions (optimal + brute force)
- Build validator and generator
- Run stress tests
- Generate final test data
3. Manual Tool Usage
You can also call tools directly:
# Build a solution
solution_build(
problem_dir="problems/ab",
solution_type="sol",
code="#include <iostream>\nint main() { int a, b; std::cin >> a >> b; std::cout << a + b; }"
)
# Run stress test
stress_test_run(problem_dir="problems/ab", trials=100)
MCP Client Setup
Claude Code
Edit ~/.config/claude-code/config.json:
{
"mcpServers": {
"autocode": {
"command": "autocode-mcp"
}
}
}
Cursor
Add to your Cursor settings (Settings → MCP):
{
"mcp": {
"servers": {
"autocode": {
"command": "autocode-mcp"
}
}
}
}
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"autocode": {
"command": "autocode-mcp"
}
}
}
From Source (Development)
For development or custom installations:
{
"mcpServers": {
"autocode": {
"command": "uv",
"args": ["run", "--directory", "/path/to/autocode-mcp", "autocode-mcp"]
}
}
}
Verify Installation
After configuration, restart your MCP client and check that tools are available. You should see 14 tools prefixed with autocode_.
Tools Reference
AutoCode provides 14 atomic tools organized into 7 groups. All tools return a unified format:
{
"success": true,
"error": null,
"data": { ... }
}
File Operations
| Tool | Description | Key Parameters |
|---|---|---|
file_save |
Save content to a file | path, content |
file_read |
Read file content | path |
Solution Tools
| Tool | Description | Key Parameters |
|---|---|---|
solution_build |
Compile solution code | problem_dir, solution_type ("sol"/"brute"), code |
solution_run |
Execute compiled solution | problem_dir, solution_type, input_data, timeout |
Validator Tools
| Tool | Description | Key Parameters |
|---|---|---|
validator_build |
Build and test validator | problem_dir, code, test_cases |
validator_select |
Select best validator from candidates | candidates |
Generator Tools
| Tool | Description | Key Parameters |
|---|---|---|
generator_build |
Compile generator | problem_dir, code |
generator_run |
Generate test inputs | problem_dir, strategies, test_count, validator_path |
Checker Tools
| Tool | Description | Key Parameters |
|---|---|---|
checker_build |
Build output checker | problem_dir, code, test_scenarios |
Interactor Tools
| Tool | Description | Key Parameters |
|---|---|---|
interactor_build |
Build interactor for interactive problems | problem_dir, code, test_scenarios |
Stress Testing
| Tool | Description | Key Parameters |
|---|---|---|
stress_test_run |
Compare sol vs brute outputs | problem_dir, trials, n_max, timeout |
Problem Management
| Tool | Description | Key Parameters |
|---|---|---|
problem_create |
Initialize problem directory | problem_dir, title, time_limit, memory_limit |
problem_generate_tests |
Generate final test data | problem_dir, test_count |
problem_pack_polygon |
Package for Polygon platform | problem_dir, output_dir |
Workflow Tutorial: A+B Problem
This tutorial walks through creating a simple A+B problem using AutoCode tools.
Step 1: Initialize Problem
problem_create(
problem_dir="problems/ab",
title="A + B",
time_limit=1000,
memory_limit=256
)
Step 2: Implement Solutions
Optimal Solution (sol.cpp):
#include <iostream>
int main() {
int a, b;
std::cin >> a >> b;
std::cout << a + b << std::endl;
return 0;
}
Brute Force (brute.cpp):
#include <iostream>
int main() {
int a, b;
std::cin >> a >> b;
// Same as optimal for A+B, but could be slower for complex problems
std::cout << a + b << std::endl;
return 0;
}
Build both:
solution_build(problem_dir="problems/ab", solution_type="sol", code="...")
solution_build(problem_dir="problems/ab", solution_type="brute", code="...")
Step 3: Build Validator
#include "testlib.h"
int main(int argc, char* argv[]) {
registerValidation(argc, argv);
int a = inf.readInt(-1000, 1000, "a");
inf.readSpace();
int b = inf.readInt(-1000, 1000, "b");
inf.readEoln();
inf.readEof();
return 0;
}
Build with test cases:
validator_build(
problem_dir="problems/ab",
code="...",
test_cases=[
{"input": "1 2\n", "expected_valid": True},
{"input": "0 0\n", "expected_valid": True},
{"input": "-1000 1000\n", "expected_valid": True},
{"input": "1001 0\n", "expected_valid": False}, # out of range
{"input": "1 2 3\n", "expected_valid": False}, # extra number
]
)
Step 4: Build Generator
#include "testlib.h"
#include <iostream>
int main(int argc, char* argv[]) {
registerGen(argc, argv, 1);
int seed = atoi(argv[1]);
int type = atoi(argv[2]);
rnd.setSeed(seed);
int a = rnd.next(-1000, 1000);
int b = rnd.next(-1000, 1000);
std::cout << a << " " << b << std::endl;
return 0;
}
Build and run:
generator_build(problem_dir="problems/ab", code="...")
generator_run(
problem_dir="problems/ab",
strategies=["random", "extreme"],
test_count=20,
validator_path="problems/ab/val.exe"
)
Step 5: Stress Test
stress_test_run(
problem_dir="problems/ab",
trials=1000,
n_max=100,
timeout=30
)
Expected output:
All 1000 rounds passed
Step 6: Generate Final Tests
problem_generate_tests(
problem_dir="problems/ab",
test_count=50
)
Step 7: Package for Polygon
problem_pack_polygon(
problem_dir="problems/ab",
output_dir="polygon/ab"
)
Architecture
Validator-Generator-Checker Framework
┌─────────────────┐
│ Problem Design │
└────────┬────────┘
│
▼
┌─────────────────┐ ┌──────────────┐
│ Solution Build │────►│ Validator │ Verify input constraints
│ (sol + brute) │ └──────────────┘
└────────┬────────┘
│
▼
┌─────────────────┐ ┌──────────────┐
│ Generator │────►│ Stress Test │ Compare sol vs brute
│ Multi-strategy │ └──────────────┘
└────────┬────────┘
│
▼
┌─────────────────┐
│ Checker │ Verify output correctness
└────────┬────────┘
│
▼
┌─────────────────┐
│ Polygon Pack │ Export for platforms
└─────────────────┘
Design Principles
-
Tool-Only, No LLM — Server provides compilation, execution, and validation. All code generation is done by the client LLM.
-
Stateless — Each tool call is independent. State is managed via
problem_dirparameter. -
Unified Return Format — All tools return
{success, error, data}for consistent error handling. -
Safe Execution — Timeout control, memory limits (Linux via prlimit), and temporary directory isolation.
Generation Strategies
| Strategy | Type Code | Purpose |
|---|---|---|
tiny |
1 | Small exhaustive tests (N ≤ 10) |
random |
2 | Random data within constraints |
extreme |
3 | Edge cases: overflow, precision, hash collisions |
tle |
4 | TLE-inducing data for performance testing |
File Structure
problems/your-problem/
├── sol.cpp # Optimal solution
├── brute.cpp # Brute force (for validation)
├── val.cpp # Input validator
├── gen.cpp # Test generator
├── chk.cpp # Output checker (optional)
├── interactor.cpp # Interactor (for interactive problems)
├── statements/
│ └── README.md # Problem statement
├── tests/
│ ├── input/
│ └── output/
└── config.json # Problem configuration
Development
Setup
git clone https://github.com/your-repo/autocode-mcp.git
cd autocode-mcp
uv sync
Running Tests
# Run all tests
uv run pytest tests/ -v
# Run with coverage
uv run pytest tests/ --cov=src/autocode_mcp --cov-report=html
# Run specific test file
uv run pytest tests/test_compiler.py -v
Code Quality
# Linting
uv run ruff check .
# Type checking
uv run mypy src/
# Format
uv run ruff format .
Project Structure
autocode-mcp/
├── src/autocode_mcp/
│ ├── tools/ # MCP tool implementations
│ │ ├── base.py # Tool base class
│ │ ├── solution.py # Solution tools
│ │ ├── validator.py # Validator tools
│ │ ├── generator.py # Generator tools
│ │ ├── checker.py # Checker tools
│ │ ├── stress_test.py
│ │ └── ...
│ ├── utils/
│ │ ├── compiler.py # C++ compilation utilities
│ │ └── platform.py # Platform-specific helpers
│ ├── prompts/ # Workflow prompt templates
│ ├── resources/ # Template resources
│ └── server.py # MCP server entry point
├── templates/ # C++ templates (testlib.h, etc.)
├── tests/ # Test suite
└── pyproject.toml
Adding New Tools
- Create a new file in
src/autocode_mcp/tools/ - Inherit from
Toolbase class - Implement
name,description,input_schema, andexecute() - Register in
server.py - Add tests in
tests/
Contributing
See CONTRIBUTING.md for guidelines.
Troubleshooting
See TROUBLESHOOTING.md for common issues and solutions.
License
MIT License - see LICENSE for details.
Acknowledgments
- Based on the paper "AutoCode: LLMs as Problem Setters for Competitive Programming"
- Uses testlib.h for competitive programming utilities
- Built on the Model Context Protocol
Links
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file autocode_mcp-0.1.0.tar.gz.
File metadata
- Download URL: autocode_mcp-0.1.0.tar.gz
- Upload date:
- Size: 117.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5786976daf57e9d56014e661b86c6c3b8bcb8d779bcc633f714bbd3a8332083
|
|
| MD5 |
39e4cbdd8710e5a6484d267b98dc5b15
|
|
| BLAKE2b-256 |
05e843b9f2aae76e5118b46e0846e87dfc8858bc75fa75efe1dcd87ebb4e6c02
|
File details
Details for the file autocode_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: autocode_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 37.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1daba37762fef76cae9d0bc511ebec5e7cf43307adfbc34a911c83e617c42f7a
|
|
| MD5 |
1678a3ebd67a0ca0cd5943355d27e865
|
|
| BLAKE2b-256 |
6cb0ea04ef764040a90cbb0362210e0fc8d32487754da457bfebb6fe184f7237
|