Skip to main content

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 transpile
  • target_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 transpile
  • target_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., int where 1 < 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., UserId must be 0 < id < 1000)
  • Protocol verification: Ensure state machines follow valid transitions
  • Security properties: Verify input sanitization pre-conditions

Further Reading:

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

  1. The MCP server receives a request with Python code and target language
  2. Creates a temporary Python file with the code
  3. Runs py2many --{language} (or with --llm flag) on the file
  4. Captures the generated output and any errors
  5. 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

  • py2many - The transpiler this MCP server wraps
  • MCP - Model Context Protocol specification

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_server_py2many-0.1.0.tar.gz (10.0 kB view details)

Uploaded Source

Built Distribution

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

mcp_server_py2many-0.1.0-py3-none-any.whl (8.3 kB view details)

Uploaded Python 3

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

Hashes for mcp_server_py2many-0.1.0.tar.gz
Algorithm Hash digest
SHA256 73e731a12cf2b62eaf7f5fb0a439732d1b679479c20beecf3b56dbb62b3aff95
MD5 b38ff89e78169477bc39c76059d2ee3f
BLAKE2b-256 71d054fa995c8b7cd57ab753c0ca0aad1d9bc32b80ec9fc048335b8997375abd

See more details on using hashes here.

File details

Details for the file mcp_server_py2many-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for mcp_server_py2many-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c630e9e4bd3038ac143f6de5625388864a27ab8a0f83c3f051f077e25db63aa3
MD5 4acdf87f4aa3214b85690adc0b8e0e76
BLAKE2b-256 d5bb3e64f7f122e229d1bd52ad33d0c398881a06d3da4f5fac8f90a82fb7f8ec

See more details on using hashes here.

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