0.0 / 30
What changed in the harness
Selection accuracy 90→88, token cost up 6%, unconfirmed writes 0%→0%.
Category breakdown
Where the score comes from.
Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.
01Safety
02Legibility
16.5 / 30
03Economics
17.2 / 20
04Discoverability
17.2 / 20
Highest-impact fix
Estimated gain +30 pointsAdd explicit identity and permission preflight tools
Expose machine-readable principal/tenant confirmation and a non-mutating permission check so agents can verify both before destructive actions.
Description evidence
Defects and rewrites.
24 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.
| Tool | Defect types | Suggested rewrite |
|---|---|---|
list_subgraphs |
name_restates_behavior no_return_description |
Returns the set of Polymarket subgraphs this server can query, with a short description and key entity types for each — use it to pick a valid subgraph value before calling get_subgraph_schema or query_subgraph. |
get_subgraph_schema |
name_restates_behavior no_return_description |
Fetches the GraphQL schema of the selected Polymarket subgraph via introspection and returns it as raw schema JSON (types, fields, queries), for use in constructing queries for query_subgraph. |
query_subgraph |
name_restates_behavior no_return_description |
Runs a caller-supplied GraphQL query (with optional variables) against the selected Polymarket subgraph and returns the raw GraphQL response data. |
get_market_data |
name_restates_behavior params_unexplained no_return_description |
Fetches Polymarket condition/market records from the Main subgraph, including outcomes and volume figures. Returns a list of markets sorted by the 'orderBy' field (e.g. 'id' or a volume/timestamp field) in 'orderDirection' order, limited to 'first' results. |
get_account_pnl |
no_return_description |
Looks up a trader's profit-and-loss and performance metrics from the Beefy P&L subgraph for the given 'account' address, returning fields like realized/unrealized P&L, volume, and trade counts. |
get_user_positions |
no_return_description |
Looks up a user's current open positions from the Slimmed P&L subgraph for the given 'account' address, returning per-position size and value data; falls back gracefully if indexers are behind. |
get_recent_activity |
name_restates_behavior no_return_description |
Fetches the most recent split, merge, and redemption events from the Activity subgraph, optionally filtered to a single 'account'. Returns a list of up to 'first' events with type, amounts, and timestamps. |
get_orderbook_trades |
no_return_description |
Fetches recent order fill events from the Orderbook subgraph, optionally filtered by 'maker' or 'taker' address. Returns a list of up to 'first' trades with price, size, and counterparties. |
get_global_stats |
no_return_description |
Aggregates platform-wide Polymarket statistics by combining market counts from the Main subgraph with volume/fee/trade data from the Orderbook subgraph, returning a single object with these combined totals. |
get_daily_stats |
no_return_description |
Fetches daily Polymarket platform statistics from the Beefy P&L subgraph for use in trend analysis, returning per-day volume, fees, trader counts, and market activity for the last 'days' days. |
get_top_traders |
no_return_description |
Ranks Polymarket traders from the Beefy P&L subgraph by the chosen 'orderBy' metric (realized P&L, win rate, volume, etc.), excluding accounts below 'minTrades' trades, and returns a list of up to 'first' trader records with their stats. |
get_market_positions |
no_return_description |
Fetches the largest holders of a specific outcome token ('tokenId') from the Beefy P&L subgraph, sorted by 'orderBy'. Returns a list of up to 'first' positions with holder address, value, and P&L. |
get_market_open_interest |
no_return_description |
Ranks Polymarket markets by open interest (USDC locked in outstanding positions) using the Open Interest subgraph, sorted by 'orderBy' in 'orderDirection' order. Returns a list of up to 'first' markets with their OI figures. |
get_oi_history |
no_return_description |
Fetches hourly open interest snapshots for the market identified by 'conditionId', for charting OI trends over time. Returns up to 'first' snapshots (default 168 = one week) sorted by timestamp in 'orderDirection' order. |
get_global_open_interest |
no_return_description |
Computes the total open interest across all Polymarket markets and returns a single aggregate USDC value locked in outstanding positions platform-wide. |
get_market_resolution |
no_return_description |
Fetches UMA oracle resolution records for Polymarket markets, optionally filtered by 'status', sorted by 'orderBy'/'orderDirection'. Returns up to 'first' markets with resolution status, proposed/final prices, and dispute history. |
get_disputed_markets |
no_return_description |
Fetches Polymarket markets that were disputed during UMA oracle resolution, returning up to 'first' disputed markets with dispute details. |
get_market_revisions |
no_return_description |
Fetches moderator revision/update records for Polymarket markets, optionally filtered to a single 'questionId'. Returns up to 'first' revisions showing when and how moderators intervened. |
get_trader_profile |
no_return_description |
Fetches a trader's on-chain profile from the Traders subgraph for the given 'address', returning first-seen timestamp, up to 'eventLimit' recent CTF events (splits, merges, transfers), and USDC flow summary. |
get_trader_usdc_flows |
no_return_description |
Fetches USDC deposit/withdrawal transfer history for the trader at 'address', filtered by 'direction' (inbound/outbound/both). Returns up to 'first' transfer records with amount, direction, and timestamp. |
list_polymarket_events |
no_return_description |
Lists Polymarket events (groups of related markets under one topic) from the Gamma API, filterable by 'active', 'closed', or 'tag' and sortable via 'orderBy'/'ascending'. Returns up to 'limit' event summaries. |
get_polymarket_event |
no_return_description |
Fetches a single Polymarket event by 'eventId' (ID or slug) and returns its metadata along with all markets grouped under it. |
get_live_orderbook |
no_return_description |
Fetches the full live order book from the CLOB for the outcome token 'tokenId', returning all resting bid and ask orders with their prices and sizes. |
get_last_trade |
name_restates_behavior no_return_description |
Queries the CLOB for the most recent executed trade on the outcome token 'tokenId', returning its price, size, and timestamp. |
Selection evidence
Confusable tool pairs.
18 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.
| Tool A | Tool B | Confidence | Why they collide |
|---|---|---|---|
search_markets |
search_markets_enriched |
high | Both search markets by text query with nearly identical params (query/limit/active/closed); a task like 'find Trump markets with current prices' could reasonably be routed to either the plain search (then chained) or the auto-enriching variant. |
get_market_open_interest |
get_global_open_interest |
medium | A vague request like 'what's the open interest on Polymarket?' doesn't specify top-markets-ranked vs platform-wide total, and both tools use the word 'open interest' with overlapping descriptions. |
get_live_prices |
get_live_spread |
medium | 'What's the current price of this token' could be satisfied by best buy/sell price (get_live_prices) or by the bid-ask spread tool, since both return current CLOB pricing for a single/array of tokenIds. |
get_market_resolution |
get_disputed_markets |
medium | get_market_resolution has a status filter that includes 'disputed', directly overlapping with the dedicated get_disputed_markets tool, so 'show me disputed markets' could trigger either. |
get_live_prices |
get_live_orderbook |
low | Both return real-time CLOB data for tokens, but orderbook clearly implies full bid/ask depth vs single best price, reducing but not eliminating confusion for 'show me the market's live pricing'. |
get_global_stats |
get_daily_stats |
medium | Both are 'platform statistics' tools (volume, fees, trades); a request like 'give me Polymarket's stats' doesn't clearly indicate aggregate totals vs a daily/trend breakdown. |
get_live_spread |
get_live_orderbook |
low | Spread (best bid/ask) is technically a subset of the full orderbook, so 'show me the orderbook/spread for this token' could be mis-routed, though the full order book is named distinctly. |
get_market_data |
get_market_info |
medium | Both fetch general market details (outcomes, volumes) from different backends (Main subgraph vs Gamma API); a generic 'get info about this market' task doesn't obviously map to one over the other. |
get_market_info |
get_clob_market |
medium | Both accept a conditionId and return market details including token/price info; a task like 'get market details by condition ID' could plausibly be routed to either the Gamma-based info tool or the CLOB-based tool. |
get_market_resolution |
get_market_revisions |
medium | Both concern how a market's outcome/state changed over time (oracle resolution vs moderator revisions); 'show me the history of changes to this market' is ambiguous between them. |
get_oi_history |
get_price_history |
low | Both return time-series history for a market/token for charting; a vague 'show me the historical trend for this market' doesn't specify OI vs price, though required params (conditionId vs tokenId) differ. |
get_orderbook_trades |
get_last_trade |
medium | Both surface trade/fill data; 'get the recent trade for this market' could mean the single last trade price or the list of recent order fills. |
get_orderbook_trades |
get_live_orderbook |
medium | Both are named around 'orderbook' but return different things (executed trades/fills vs resting bid/ask orders); a task asking for 'the orderbook data' is genuinely ambiguous between them. |
list_polymarket_events |
get_polymarket_event |
medium | Classic list-vs-get pair on the same entity; a task like 'get the events for politics' could ambiguously call the single-event getter instead of the filtered list. |
get_global_stats |
get_global_open_interest |
medium | Both are zero-argument 'aggregate platform-wide' tools; a task like 'give me overall Polymarket numbers' could be routed to either general stats or specifically OI. |
get_trader_profile |
get_trader_usdc_flows |
low | get_trader_profile already includes USDC flows in its description, overlapping with the dedicated flows tool, so 'show this trader's deposits/withdrawals' could go to either. |
get_disputed_markets |
get_market_revisions |
low | Both surface markets where something unusual happened during resolution (disputes vs moderator interventions), so a broad 'show markets with resolution issues' task has some ambiguity. |
get_market_data |
get_clob_market |
low | Both return 'market' data including condition-related info from different subgraphs/APIs, creating mild overlap for a generic 'get market data' request. |
Compare the field