MCP Server for py2many - transpile Python to multiple languages
Project description
mcp-server-py2many
A Model Context Protocol (MCP) server that provides tools for transpiling Python code to multiple programming languages using py2many.
Overview
This MCP server exposes tools that allow LLMs to transpile Python code to various target languages including C++, Rust, Go, Kotlin, Dart, Julia, Nim, V, Mojo, D, SMT, and Zig.
Installation
Using uv (recommended)
# Clone the repository
git clone <repository-url>
cd mcp-server-py2many
# Install dependencies
uv sync
# Run the server
uv run mcp-server-py2many
Using pip
pip install mcp-server-py2many
Configuration
Add this server to your MCP client configuration:
Claude Desktop Config
Add to your claude_desktop_config.json:
{
"mcpServers": {
"py2many": {
"command": "uvx",
"args": ["mcp-server-py2many"]
}
}
}
Or with a local installation:
{
"mcpServers": {
"py2many": {
"command": "uv",
"args": ["run", "--directory", "/path/to/mcp-server-py2many", "mcp-server-py2many"]
}
}
}
Available Tools
1. transpile_python
Transpile Python code to another programming language using deterministic rules-based translation.
Parameters:
python_code(string, required): The Python code to transpiletarget_language(string, required): Target language (cpp, rust, go, kotlin, dart, julia, nim, vlang, mojo, dlang, smt, zig)
2. transpile_python_with_llm
Transpile Python code using py2many with LLM assistance for better handling of complex idioms.
Parameters:
python_code(string, required): The Python code to transpiletarget_language(string, required): Target language (cpp, rust, go, kotlin, dart, julia, nim, vlang, mojo, dlang, smt, zig)
3. list_supported_languages
List all supported target languages for transpilation.
When to Use Deterministic vs LLM-Assisted Translation
Use Deterministic Translation (transpile_python) when:
✅ Simple, idiomatic Python code
- Basic control flow (if/else, for/while loops)
- Standard library functions with direct equivalents
- Data structures (lists, dicts, sets)
- Simple functions and classes
✅ Well-tested patterns
- Mathematical computations
- String manipulations
- File I/O operations
- Algorithmic implementations
✅ When reproducibility matters
- Same input always produces same output
- No external dependencies or API calls
- Clear, deterministic behavior
Example cases for deterministic:
# Simple functions
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
# Data processing
def sum_even_numbers(numbers):
return sum(n for n in numbers if n % 2 == 0)
# Basic algorithms
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
Use LLM-Assisted Translation (transpile_python_with_llm) when:
🧠 Complex Python idioms
- Decorators and metaclasses
- Complex comprehensions with multiple clauses
- Generator expressions and coroutines
- Dynamic typing patterns
🧠 Language-specific features need translation
- Python-specific libraries (numpy, pandas patterns)
- Duck typing and protocol implementations
- Monkey patching and runtime modifications
- Context managers with complex behavior
🧠 Deterministic translation fails or produces non-idiomatic code
- Type errors that need semantic understanding
- Non-idiomatic output in target language
- Missing imports or dependencies
- Complex inheritance patterns
🧠 Target language best practices differ significantly
- Rust ownership and borrowing patterns
- C++ memory management
- Go concurrency patterns
- Functional programming in target language
Example cases for LLM-assisted:
# Complex decorators
def memoize(func):
cache = {}
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
# Complex data transformations
def process_data(data):
return [
{
'name': item['name'].upper(),
'values': [x * 2 for x in item['values'] if x > 0]
}
for item in data
if item.get('active') and len(item.get('values', [])) > 5
]
# Dynamic behavior
class DynamicClass:
def __getattr__(self, name):
return lambda *args: f"Called {name} with {args}"
Decision Flowchart
Is your Python code...
│
├─ Simple functions/algorithms?
│ └─ Yes → Use deterministic ✓
│
├─ Standard data structures and control flow?
│ └─ Yes → Use deterministic ✓
│
├─ Complex decorators, metaclasses, dynamic behavior?
│ └─ Yes → Use LLM-assisted 🧠
│
├─ Heavy use of Python-specific idioms?
│ └─ Yes → Use LLM-assisted 🧠
│
├─ Did deterministic translation fail?
│ └─ Yes → Try LLM-assisted 🧠
│
└─ Need idiomatic target language output?
└─ Yes → Use LLM-assisted 🧠
Supported Languages
| Language | Code | Notes |
|---|---|---|
| C++ | cpp |
Full support with STL containers |
| Rust | rust |
Ownership-aware translation |
| Go | go |
Idiomatic Go code generation |
| Kotlin | kotlin |
JVM-compatible output |
| Dart | dart |
Flutter-friendly |
| Julia | julia |
Scientific computing focus |
| Nim | nim |
Systems programming |
| V | vlang |
Simple, fast compilation |
| Mojo | mojo |
AI/ML performance computing |
| D | dlang |
Systems programming |
| Zig | zig |
Modern systems programming |
Design by Contract with SMT
SMT (Satisfiability Modulo Theories) support in py2many enables Design by Contract programming—writing specifications that can be formally verified using Z3 or other SMT solvers. Unlike other target languages, SMT output is not meant to be a direct end-user programming language, but rather a specification language for verification.
Key Concepts:
- Pre-conditions: Constraints that must hold before a function executes
- Post-conditions: Constraints that must hold after a function executes
- Refinement types: Types with additional constraints (e.g.,
intwhere1 < x < 1000)
Example: Mathematical Equations with Constraints
Python source with pre-conditions:
from py2many.smt import check_sat, default_value, get_value
from py2many.smt import pre as smt_pre
x: int = default_value(int)
y: int = default_value(int)
z: float = default_value(float)
def equation(x: int, y: int) -> bool:
if smt_pre:
assert x > 2 # pre-condition
assert y < 10 # pre-condition
assert x + 2 * y == 7 # constraint equation
True
def fequation(z: float) -> bool:
if smt_pre:
assert 9.8 + 2 * z == z + 9.11
True
assert equation(x, y)
assert fequation(z)
check_sat()
get_value((x, y, z))
Generated SMT-LIB 2.0 output:
(declare-const x Int)
(declare-const y Int)
(declare-const z Real)
(define-fun equation-pre ((x Int) (y Int)) Bool
(and
(> x 2)
(< y 10)
(= (+ x (* 2 y)) 7)))
(define-fun equation ((x Int) (y Int)) Bool
true)
(assert (and
(equation-pre x y)
(equation x y)))
(check-sat)
(get-value (x y z))
When run with z3 -smt2 equations.smt, the solver proves the constraints are satisfiable and returns values: x = 7, y = 0, z = -0.69.
Use Cases:
- Static verification: Prove correctness before deployment
- Refinement types: Enforce range constraints on integers (e.g.,
UserIdmust be0 < id < 1000) - Protocol verification: Ensure state machines follow valid transitions
- Security properties: Verify input sanitization pre-conditions
Further Reading:
- PySMT: Design by Contract in Python - How py2many enables refinement types and formal verification
- Agentic Transpilers - Architecture for multi-level transpilation with verification
- equations.py source - Python test case
- equations.smt output - Generated SMT-LIB
Examples
Example 1: Simple Function (Deterministic)
# Python input
def greet(name):
return f"Hello, {name}!"
# C++ output (via transpile_python)
#include <iostream>
#include <string>
std::string greet(std::string name) {
return "Hello, " + name + "!";
}
Example 2: Complex Data Processing (LLM-Assisted)
# Python input with complex comprehensions
def analyze_sales(data):
return {
region: {
'total': sum(s['amount'] for s in sales),
'count': len(sales),
'avg': sum(s['amount'] for s in sales) / len(sales)
}
for region, sales in data.items()
if any(s['amount'] > 1000 for s in sales)
}
# Better results with LLM-assisted translation for idiomatic target language
Development
# Install development dependencies
uv sync
# Run the server
uv run mcp-server-py2many
# Test the server manually
uv run python -m mcp_server_py2many
How It Works
- The MCP server receives a request with Python code and target language
- Creates a temporary Python file with the code
- Runs
py2many --{language}(or with--llmflag) on the file - Captures the generated output and any errors
- Returns the transpiled code to the LLM client
Limitations
- Not all Python features are supported in all target languages
- Some Python standard library functions may not have direct equivalents
- Complex dynamic Python code may require manual adjustments after transpilation
- LLM-assisted mode requires an LLM API key configured for py2many
License
MIT License - See LICENSE file for details.
Contributing
Contributions welcome! Please open issues and pull requests on the repository.
Related Projects
Project details
Release history Release notifications | RSS feed
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 mcp_server_py2many-0.1.0.tar.gz.
File metadata
- Download URL: mcp_server_py2many-0.1.0.tar.gz
- Upload date:
- Size: 10.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73e731a12cf2b62eaf7f5fb0a439732d1b679479c20beecf3b56dbb62b3aff95
|
|
| MD5 |
b38ff89e78169477bc39c76059d2ee3f
|
|
| BLAKE2b-256 |
71d054fa995c8b7cd57ab753c0ca0aad1d9bc32b80ec9fc048335b8997375abd
|
File details
Details for the file mcp_server_py2many-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcp_server_py2many-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c630e9e4bd3038ac143f6de5625388864a27ab8a0f83c3f051f077e25db63aa3
|
|
| MD5 |
4acdf87f4aa3214b85690adc0b8e0e76
|
|
| BLAKE2b-256 |
d5bb3e64f7f122e229d1bd52ad33d0c398881a06d3da4f5fac8f90a82fb7f8ec
|