Source code for polymarket_mcp.models.data
"""Typed Data API domain and tool I/O models.
Purpose:
Define normalized wallet, activity, and trade models for the Polymarket
Data API along with MCP input and output contracts.
Design:
These models separate raw upstream payloads from normalized internal models
and MCP-facing tool outputs.
Attributes:
WalletArgs:
Input model for wallet-scoped queries.
TradesArgs:
Input model for trade queries.
Position:
Normalized wallet position model.
ActivityItem:
Normalized wallet activity model.
Trade:
Normalized trade model.
WalletPositionsOutput:
MCP output envelope for current positions.
WalletActivityOutput:
MCP output envelope for activity.
TradesOutput:
MCP output envelope for trades.
"""
from __future__ import annotations
from pydantic import BaseModel, ConfigDict, Field, computed_field
[docs]
class WalletArgs(BaseModel):
"""Arguments for wallet-scoped Data API queries.
Args:
user: Wallet address, usually in ``0x...`` format.
Returns:
WalletArgs: Validated wallet arguments.
Raises:
ValueError: If validation fails.
Examples:
>>> args = WalletArgs(user="0xabc")
>>> args.user
'0xabc'
"""
model_config = ConfigDict(extra="forbid")
user: str = Field(min_length=1)
[docs]
class TradesArgs(BaseModel):
"""Arguments for Data API trade queries.
Args:
market: Optional market identifier or slug when supported upstream.
user: Optional wallet address to scope trades.
limit: Maximum number of trades to return.
Returns:
TradesArgs: Validated trade query arguments.
Raises:
ValueError: If validation fails.
Examples:
>>> args = TradesArgs(user="0xabc", limit=10)
>>> args.limit
10
"""
model_config = ConfigDict(extra="forbid")
market: str | None = None
user: str | None = None
limit: int = Field(default=25, ge=1, le=200)
[docs]
class Position(BaseModel):
"""Normalized wallet position model."""
model_config = ConfigDict(extra="allow")
market_slug: str | None = None
title: str | None = None
outcome: str | None = None
size: float | None = None
avg_price: float | None = None
current_value: float | None = None
realized_pnl: float | None = None
unrealized_pnl: float | None = None
[docs]
class ActivityItem(BaseModel):
"""Normalized wallet activity model."""
model_config = ConfigDict(extra="allow")
activity_type: str | None = None
market_slug: str | None = None
title: str | None = None
outcome: str | None = None
price: float | None = None
size: float | None = None
timestamp: int | None = None
[docs]
class Trade(BaseModel):
"""Normalized trade model."""
model_config = ConfigDict(extra="allow")
market_slug: str | None = None
outcome: str | None = None
price: float | None = None
size: float | None = None
side: str | None = None
user: str | None = None
timestamp: int | None = None
[docs]
class WalletPositionsOutput(BaseModel):
"""Tool output for current or closed wallet positions."""
model_config = ConfigDict(extra="forbid")
user: str
positions: list[Position] = Field(default_factory=list)
@computed_field
@property
def count(self) -> int:
"""Return the number of positions.
Returns:
int: Number of returned positions.
"""
return len(self.positions)
[docs]
class WalletActivityOutput(BaseModel):
"""Tool output for wallet activity."""
model_config = ConfigDict(extra="forbid")
user: str
activity: list[ActivityItem] = Field(default_factory=list)
@computed_field
@property
def count(self) -> int:
"""Return the number of activity rows.
Returns:
int: Number of returned rows.
"""
return len(self.activity)
[docs]
class TradesOutput(BaseModel):
"""Tool output for trade queries."""
model_config = ConfigDict(extra="forbid")
trades: list[Trade] = Field(default_factory=list)
@computed_field
@property
def count(self) -> int:
"""Return the number of trades.
Returns:
int: Number of returned trades.
"""
return len(self.trades)