The common.py
pattern is deprecated. Use standard Python module and package structures instead.
Multiple components often need to share utility functions, client initializations, or Pydantic models. GolfMCP supports standard Python repository structures for organizing shared code.
You can create properly named modules, packages, and organize your code using normal Python conventions. The build system will handle imports correctly regardless of your chosen structure.
Example:
tools/payments/common.py
:
# tools/payments/common.py
import httpx
# Shared HTTP client for payment operations
payment_client = httpx.AsyncClient(base_url="https://api.payments.example.com")
DEFAULT_CURRENCY = "USD"
class PaymentError(Exception):
pass
# Mock payment processing functions for examples
async def create_charge(amount: float, token: str, description: str = "") -> dict:
# In a real implementation, this would call the payment API
return {"id": f"ch_{token[:8]}", "amount": amount, "currency": DEFAULT_CURRENCY}
async def create_refund(charge_id: str, amount: float = None, reason: str = "") -> dict:
# In a real implementation, this would call the payment API
return {"id": f"re_{charge_id[3:11]}", "charge_id": charge_id, "amount": amount}
tools/payments/charge.py
:
# tools/payments/charge.py
"""Tool to process a payment charge."""
from typing import Annotated
from pydantic import BaseModel, Field
from .common import payment_client, create_charge, PaymentError
class ChargeOutput(BaseModel):
success: bool
charge_id: str
message: str
async def charge(
amount: Annotated[float, Field(
description="Amount to charge in USD",
gt=0, # Must be greater than 0
le=10000 # Maximum charge limit
)],
card_token: Annotated[str, Field(
description="Tokenized payment card identifier",
pattern=r"^tok_[a-zA-Z0-9]+$" # Validate token format
)],
description: Annotated[str, Field(
description="Optional payment description",
max_length=200
)] = ""
) -> ChargeOutput:
"""Process a payment charge."""
try:
# Use the shared payment client from common.py
charge_result = await create_charge(
amount=amount,
token=card_token,
description=description
)
return ChargeOutput(
success=True,
charge_id=charge_result["id"],
message=f"Successfully charged ${amount:.2f}"
)
except Exception as e:
raise PaymentError(f"Charge failed: {e}")
export = charge
The GolfMCP build system understands these relative imports and ensures that the common.py
modules are correctly packaged and accessible in the final dist/
output. The ImportTransformer
in golf.core.transformer
handles rewriting these imports to be absolute paths relative to the generated components
directory structure.