We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/caiovicentino/polymarket-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""
Configuration management for Polymarket MCP server.
Loads and validates environment variables with proper defaults.
"""
import os
from typing import Optional
from pydantic import Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
class PolymarketConfig(BaseSettings):
"""
Configuration settings for Polymarket MCP server.
Loads from environment variables with validation.
"""
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=True,
extra="ignore"
)
# DEMO MODE - Run without real credentials (read-only)
DEMO_MODE: bool = Field(
default=False,
description="Run in demo mode without real wallet (read-only, no trading)"
)
# Required Polygon Wallet Configuration (optional in DEMO_MODE)
POLYGON_PRIVATE_KEY: str = Field(
default="",
description="Polygon wallet private key (without 0x prefix)"
)
POLYGON_ADDRESS: str = Field(
default="",
description="Polygon wallet address"
)
POLYMARKET_CHAIN_ID: int = Field(
default=137,
description="Polygon chain ID (137 for mainnet, 80002 for Amoy testnet)"
)
# Optional L2 API Credentials (auto-created if not provided)
POLYMARKET_API_KEY: Optional[str] = Field(
default=None,
description="L2 API key for authenticated requests"
)
POLYMARKET_PASSPHRASE: Optional[str] = Field(
default=None,
description="API key passphrase"
)
POLYMARKET_API_KEY_NAME: Optional[str] = Field(
default=None,
description="API key name/identifier"
)
# Safety Limits - Risk Management
MAX_ORDER_SIZE_USD: float = Field(
default=1000.0,
description="Maximum size for a single order in USD"
)
MAX_TOTAL_EXPOSURE_USD: float = Field(
default=5000.0,
description="Maximum total exposure across all positions in USD"
)
MAX_POSITION_SIZE_PER_MARKET: float = Field(
default=2000.0,
description="Maximum position size per market in USD"
)
MIN_LIQUIDITY_REQUIRED: float = Field(
default=10000.0,
description="Minimum liquidity required in market before trading (USD)"
)
MAX_SPREAD_TOLERANCE: float = Field(
default=0.05,
description="Maximum spread tolerance (0.05 = 5%)"
)
# Trading Controls
ENABLE_AUTONOMOUS_TRADING: bool = Field(
default=True,
description="Enable autonomous trading without confirmation"
)
REQUIRE_CONFIRMATION_ABOVE_USD: float = Field(
default=500.0,
description="Require user confirmation for orders above this USD amount"
)
AUTO_CANCEL_ON_LARGE_SPREAD: bool = Field(
default=True,
description="Automatically cancel orders if spread exceeds MAX_SPREAD_TOLERANCE"
)
# API Endpoints
CLOB_API_URL: str = Field(
default="https://clob.polymarket.com",
description="Polymarket CLOB API endpoint"
)
GAMMA_API_URL: str = Field(
default="https://gamma-api.polymarket.com",
description="Gamma API endpoint for market data"
)
# Logging
LOG_LEVEL: str = Field(
default="INFO",
description="Log level: DEBUG, INFO, WARNING, ERROR"
)
# Polymarket Constants
USDC_ADDRESS: str = Field(
default="0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
description="USDC token address on Polygon"
)
CTF_EXCHANGE_ADDRESS: str = Field(
default="0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E",
description="CTF Exchange contract address"
)
CONDITIONAL_TOKEN_ADDRESS: str = Field(
default="0x4D97DCd97eC945f40cF65F87097ACe5EA0476045",
description="Conditional Token contract address"
)
@field_validator("POLYGON_PRIVATE_KEY")
@classmethod
def validate_private_key(cls, v: str, info) -> str:
"""Validate private key format (skipped in DEMO_MODE)"""
# Get DEMO_MODE from the data being validated
demo_mode = info.data.get('DEMO_MODE', False)
# In DEMO mode, use a fixed demo private key
if demo_mode:
return "0000000000000000000000000000000000000000000000000000000000000001"
# Normal validation for non-demo mode
if not v:
raise ValueError(
"POLYGON_PRIVATE_KEY is required (or set DEMO_MODE=true for read-only access)"
)
# Remove 0x prefix if present
if v.startswith("0x"):
v = v[2:]
# Check if valid hex
if len(v) != 64:
raise ValueError("POLYGON_PRIVATE_KEY must be 64 hex characters")
try:
int(v, 16)
except ValueError:
raise ValueError("POLYGON_PRIVATE_KEY must be valid hex")
return v
@field_validator("POLYGON_ADDRESS")
@classmethod
def validate_address(cls, v: str, info) -> str:
"""Validate Polygon address format (skipped in DEMO_MODE)"""
# Get DEMO_MODE from the data being validated
demo_mode = info.data.get('DEMO_MODE', False)
# In DEMO mode, use a fixed demo address
if demo_mode:
return "0x0000000000000000000000000000000000000001"
# Normal validation for non-demo mode
if not v:
raise ValueError(
"POLYGON_ADDRESS is required (or set DEMO_MODE=true for read-only access)"
)
if not v.startswith("0x"):
raise ValueError("POLYGON_ADDRESS must start with 0x")
if len(v) != 42:
raise ValueError("POLYGON_ADDRESS must be 42 characters")
return v.lower()
@field_validator("MAX_SPREAD_TOLERANCE")
@classmethod
def validate_spread_tolerance(cls, v: float) -> float:
"""Validate spread tolerance is between 0 and 1"""
if not 0 <= v <= 1:
raise ValueError("MAX_SPREAD_TOLERANCE must be between 0 and 1")
return v
@field_validator("LOG_LEVEL")
@classmethod
def validate_log_level(cls, v: str) -> str:
"""Validate log level"""
valid_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
v = v.upper()
if v not in valid_levels:
raise ValueError(f"LOG_LEVEL must be one of {valid_levels}")
return v
def has_api_credentials(self) -> bool:
"""Check if L2 API credentials are configured"""
return all([
self.POLYMARKET_API_KEY,
self.POLYMARKET_PASSPHRASE,
self.POLYMARKET_API_KEY_NAME
])
def to_dict(self) -> dict:
"""Convert config to dictionary (hiding sensitive data)"""
data = self.model_dump()
# Mask sensitive fields
if data.get("POLYGON_PRIVATE_KEY"):
data["POLYGON_PRIVATE_KEY"] = "***HIDDEN***"
if data.get("POLYMARKET_API_KEY"):
data["POLYMARKET_API_KEY"] = "***HIDDEN***"
if data.get("POLYMARKET_PASSPHRASE"):
data["POLYMARKET_PASSPHRASE"] = "***HIDDEN***"
return data
def load_config() -> PolymarketConfig:
"""
Load configuration from environment variables.
Returns:
PolymarketConfig: Validated configuration object
Raises:
ValidationError: If required variables are missing or invalid
"""
return PolymarketConfig()