{"name":"io.github.Jorgeperez0825/v12-dfs","slug":"jorgeperez0825-v12-dfs","title":null,"description":"AI-driven DFS lineup optimizer for MLB & NBA — build FanDuel & DraftKings lineups via MCP.","url":"https://mcp.market/server/jorgeperez0825-v12-dfs","rating":null,"grade":"C","score":64,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":5,"stars":null,"forks":null,"downloads_week":null,"last_push_at":null,"license":null},"uptime":{"percent":100,"checks":28,"ok":28,"last_checked_at":"2026-09-27T09:40:41.906Z","last_ok_at":"2026-09-27T09:40:41.906Z","latency_ms":249},"claimed":false,"transport":"remote","callable_via_gateway":true,"default_price_micros":0,"repository":null,"website":null,"version":"1.0.0","remotes":[{"type":"streamable-http","url":"https://v12dfs-production.up.railway.app/mcp","headers":[{"description":"Your V12 API key — get one at https://www.v12dfs.com","isRequired":true,"isSecret":true,"name":"X-API-Key"}]}],"packages":[],"tools":[{"name":"admin_issue_key","description":"Issue Key\n\nIdempotently issue a user's API key and ALWAYS return the paste-able\nconnect block. Returns the email's existing active key (or mints one) so a\nuser keeps a single key across dashboard reloads; with rotate=true, revokes\nthe existing keys and mints a fresh one. Admin-gated — the dashboard's\nper-user provision route (which verifies the user's Firebase token) calls\nthis server-side, never the browser.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"api_key\": \"Api Key\",\n  \"tier\": \"Tier\",\n  \"limits\": {}\n}\n```\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"email":{"type":"string","maxLength":200,"minLength":5,"title":"email"},"tier":{"type":"string","pattern":"^(starter|personal|business)$","title":"tier","default":"personal"},"rotate":{"type":"boolean","title":"rotate","description":"Revoke existing keys and mint a fresh one.","default":false}},"required":["email"],"title":"admin_issue_keyArguments"}},{"name":"agent_guide","description":"Agent Guide\n\nSelf-serve onboarding: connect any agent (Claude/MCP or REST) to drive the\nV12 motor, the same engine the dashboard agent uses. No auth. Returns\ncopy-paste MCP + REST config with a PLACEHOLDER key, the endpoint map, and the\ngenerate body fields. Operators: issue each user their OWN key via\nPOST /v1/admin/create-key — never share one key.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"title":"agent_guideArguments"}},{"name":"betting_agent_guide","description":"Betting Agent Guide\n\nHow any agent uses the MLB betting tools + how to read the output.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"title":"betting_agent_guideArguments"}},{"name":"betting_analyze_prop","description":"Analyze Prop\n\nModel a single player's prop vs tonight's FanDuel line -> edge.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"name":{"type":"string","title":"name"},"prop":{"type":"string","default":"home_run","title":"prop"},"threshold":{"type":"integer","default":2,"title":"threshold"},"season":{"type":"integer","default":2026,"title":"season"}},"required":["name"],"title":"betting_analyze_propArguments"}},{"name":"betting_best_bets","description":"Best Bets\n\nTHE board sweep — scans EVERY main prop market (HR/RBI/hit/total_bases/\n2+hits/stolen_base) in one call and returns the top edges across all of them,\nnot just home runs. Power props carry the Savant validation (CONFIRMED power\nranked above neutral/noise). Use this for an open 'what's hot / best plays /\nwhat do you recommend tonight' so you NEVER conclude off a single-market scan.\nA SCREEN vs the vig line — validate with CLV; game-side value is separate\n(betting_sharp / betting_game_model).\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"min_edge":{"type":"number","default":2,"title":"min_edge"},"limit":{"type":"integer","default":12,"title":"limit"}},"title":"betting_best_betsArguments"}},{"name":"betting_build_parlay","description":"Build Parlay\n\nDeterministic parlay analysis for BOTH leg shapes. Body:\n{legs:[...], ticket_odds?}. PROP legs {name, prop, threshold} keep the\nlegacy correlation-aware EV. GAME-side legs (ML / run line / total / team\ntotal / F5, selected by the `market` field) — the slips users actually\npaste — are priced from the CURRENT de-vigged market at that exact market/\nline (canonical team resolution), falling back to the market-anchored run\nmodel for totals; per-leg fair prob + edge vs the slip's price, combined\npayout / breakeven / fair prob / EV under a documented independence\nassumption. Legs sharing a game are flagged correlated=true and get a\ncorrelation_warning INSTEAD of a combined edge. ticket_odds (the slip's\nprinted combined price) is verified vs the leg product — >2% off flags\nticket_odds_mismatch (the slip was misread; do not trust the numbers).\nNEVER estimate a parlay in prose — this endpoint is the math.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"legs":{"items":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"prop":{"type":"string","title":"Prop","default":"home_run"},"threshold":{"type":"integer","title":"Threshold","default":2},"market":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Market"},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team"},"side":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Side"},"line":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Line"},"american_odds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"American Odds"}},"type":"object","title":"_ParlayLeg","description":"One parlay leg — TWO shapes, discriminated by the `market` field.\n\nPROP leg (legacy):   {name, prop, threshold?}\nGAME-side leg (C12): {market: moneyline|run_line|total|team_total|\n                      f5_moneyline|f5_total, team, side: over/under/home/\n                      away/<team>, line?, american_odds (the SLIP's price —\n                      authoritative for the payout math)}."},"type":"array","title":"legs"},"ticket_odds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"ticket_odds","type":"integer"}},"required":["legs"],"title":"betting_build_parlayArguments"}},{"name":"betting_cross_book","description":"Cross Book\n\nCross-book value: FanDuel vs DraftKings (DK pulled via ESPN's public API,\nno key/WS). LINE_SHOP (the books hang different numbers — take the easier\nside) and PRICE_SHOP (better price, same line) are CONFIRMED edges, no model\nneeded. Arbitrage is NOT auto-reported (needs over/under sides, which ESPN\ndoesn't label). Overnight only pitcher_strikeouts overlaps; richer markets\nappear near game time.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"prop":{"type":"string","default":"pitcher_strikeouts","title":"prop"}},"title":"betting_cross_bookArguments"}},{"name":"betting_game_lines","description":"Game Lines\n\nGAME markets — moneyline / run total / run line for today's MLB games. This\nanswers the 'quién gana / cuántas carreras / pronóstico Yankees vs Toronto'\nquestions that player props CAN'T (V12 used to just refuse them). Optional\nteam filter ('Yankees', 'NYY'). MARKET data from ESPN's public scoreboard,\nsurfaced as-is — V12 has NO game-outcome model, so this is the book's own\nnumber, never a fabricated prediction. A book may not have posted a game yet\n(fields null) — say so, don't invent a line.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"team","type":"string"},"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"date","type":"string"}},"title":"betting_game_linesArguments"}},{"name":"betting_game_model","description":"Game Model\n\nMODEL the GAME run markets — TEAM TOTALS (over/under) and NRFI/YRFI — vs\nthe FanDuel line, MARKET-ANCHORED: expected_runs = the book's de-vigged\nimplied mean + 0.25×(structural model − book), and every edge is computed vs\nthe FAIR (de-vigged) probability, never the raw vig price. The structural\ninputs (season runs/game, opposing STARTER + BULLPEN run factors, park;\nnegative-binomial tails) supply only the tilt. Entries with anchored=false /\nmodel_only=true carry edge=null — present them as context, NEVER as value.\nA SCREEN vs the market, not a lock — validate with CLV. For raw lines on\nevery market use betting_market.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"team":{"type":"string","title":"team"},"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"date","type":"string"}},"required":["team"],"title":"betting_game_modelArguments"}},{"name":"betting_log_bet","description":"Log Bet\n\nRecord a bet you placed (per user) so we can track P&L + CLV over time.\nBody: {uid, market, selection, odds (American), stake, line?, prop?, team?,\ngame?, book?}. Append-only — this is the evidence base that PROVES edge.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"uid":{"type":"string","title":"uid"},"market":{"type":"string","title":"market"},"selection":{"type":"string","title":"selection"},"odds":{"type":"integer","title":"odds"},"stake":{"type":"number","title":"stake"},"line":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"line","type":"number"},"prop":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"prop","type":"string"},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"team","type":"string"},"game":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"game","type":"string"},"book":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"book","type":"string"}},"required":["uid","market","selection","odds","stake"],"title":"betting_log_betArguments"}},{"name":"betting_market","description":"Market\n\nFULL FanDuel market board for a team's game — EVERY market with real odds +\nde-vig fair price, so NO market question goes unanswered. Game lines (ML /\ntotal / run line), FIRST 5 INNINGS (F5), TEAM TOTALS, NRFI/YRFI, alternate\nlines, AND the full player-prop menu (HR / 2+ HR / hit / 2+ hits / RBI /\n2+ RBI / run / single / double / triple / total bases / stolen base / K).\nThe book's market surfaced as-is (no model). For our model edge on a prop,\nfollow up with betting_analyze_prop.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"team":{"type":"string","title":"team"},"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"date","type":"string"}},"required":["team"],"title":"betting_marketArguments"}},{"name":"betting_market_movers","description":"Market Movers\n\nMARKET pattern (not model opinion): how FanDuel lines MOVED today, from the\ncaptured snapshots. A line that shortened = money coming in (sharp/news); a\ndrift = money off. This is the 'obvious opportunity' signal — market-confirmed,\nindependent of our unproven model. Needs accumulated capture; thin → thin.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"prop":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"prop","type":"string"},"min_move":{"type":"number","default":3,"title":"min_move"},"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"date","type":"string"}},"title":"betting_market_moversArguments"}},{"name":"betting_matchup","description":"Matchup\n\nGROUNDING — the real game for a team today: probable pitchers + the POSTED\nlineup (ACTUAL player names from MLB statsapi) + the market line + the CONTEXT\na pro reasons with: home-plate UMPIRE (strike zone → totals/Ks), the INJURY\nreport (who's OUT / Day-To-Day), and BULLPEN health (ERA / blown saves). Call\nthis BEFORE naming any player or discussing a game. Name ONLY the players this\nreturns — never a roster from memory (that is how the agent ends up naming\nplayers who aren't on the team).\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"team":{"type":"string","title":"team"},"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"date","type":"string"}},"required":["team"],"title":"betting_matchupArguments"}},{"name":"betting_my_bets","description":"My Bets\n\nA user's bet history + P&L / CLV summary. avg_clv_pct > 0 over time = you're\nbeating the closing line = real edge (the only durable proof).\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"uid":{"type":"string","title":"uid"}},"required":["uid"],"title":"betting_my_betsArguments"}},{"name":"betting_player_form","description":"Player Form\n\nStreak / splits / recent form for any player ('racha de X').\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"name":{"type":"string","title":"name"},"season":{"type":"integer","default":2026,"title":"season"}},"required":["name"],"title":"betting_player_formArguments"}},{"name":"betting_scan_edges","description":"Scan Edges\n\nTonight's prop board ranked by model edge (VALUE first).\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"prop":{"type":"string","default":"home_run","title":"prop"},"min_edge":{"type":"number","default":2,"title":"min_edge"},"limit":{"type":"integer","default":15,"title":"limit"},"threshold":{"type":"integer","default":2,"title":"threshold"},"coors":{"type":"boolean","default":false,"title":"coors"},"season":{"type":"integer","default":2026,"title":"season"}},"title":"betting_scan_edgesArguments"}},{"name":"betting_settle_bet","description":"Settle Bet\n\nSettle a logged bet. Body: {uid, bet_id, result: won|lost|push,\nclosing_odds?}. closing_odds lets us compute CLV (did you beat the close).\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"uid":{"type":"string","title":"uid"},"bet_id":{"type":"string","title":"bet_id"},"result":{"type":"string","title":"result"},"closing_odds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"closing_odds","type":"integer"}},"required":["uid","bet_id","result"],"title":"betting_settle_betArguments"}},{"name":"betting_sharp","description":"Sharp\n\nSHARP value — FanDuel vs PINNACLE (the sharpest book, ~2% hold). Pinnacle's\nde-vigged line ≈ TRUE probability, so this is the most reliable value signal in\nthe kit, NO model needed: edge_vs_sharp = FD's price minus the sharp's true\nprob; POSITIVE means FanDuel pays MORE than fair (real value vs the market).\nPlus total line-shop. Pinnacle only lists UPCOMING games (gone once started).\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"team":{"type":"string","title":"team"},"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"date","type":"string"}},"required":["team"],"title":"betting_sharpArguments"}},{"name":"contest_advice","description":"Contest Advice\n\nAdvice for a concrete contest name. Resolves the name against the LIVE\nlobby FIRST so a real live contest is never reported missing (the curated\nregistry is only a subset — that was the \"$800 Wed MLB Home Run no existe\"\nbug), then layers registry strategy advice on top when a template matches.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"name":{"type":"string","title":"name"},"platform":{"type":"string","default":"fd","title":"platform"},"sport":{"type":"string","default":"MLB","title":"sport"}},"required":["name"],"title":"contest_adviceArguments"}},{"name":"contest_semaforo","description":"Contest Semaforo\n\nVIP-only: per-contest play/skip verdict from the owner's verified P&L\nbands + structure gates + rake/fill math. See core/data/contest_semaforo.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"platform":{"type":"string","default":"fd","title":"platform"},"sport":{"type":"string","default":"MLB","title":"sport"},"limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":60,"title":"limit","type":"integer"}},"title":"contest_semaforoArguments"}},{"name":"fill_template","description":"Fill Template\n\nFill a downloaded FanDuel/DK entries-template with already-generated\nlineups WITHOUT re-running the optimizer — the MCP-callable equivalent of the\ndashboard's fill_template. Keeps each entry row's leading columns (entry_id,\ncontest_id, fee) and replaces the roster-slot columns with a lineup's upload\ntokens, cycling lineups if there are more entry rows than lineups.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"template_csv":{"type":"string","maxLength":8000000,"title":"template_csv","description":"Raw CSV of the entries-template (headers + entry rows)."},"lineups":{"items":{"items":{"type":"string"},"type":"array"},"type":"array","maxItems":200,"title":"lineups","description":"Each lineup = upload tokens in template roster-slot order."}},"required":["template_csv","lineups"],"title":"fill_templateArguments"}},{"name":"generate_lineups","description":"Generate Lineups\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"status\": \"Status\",\n  \"generated_at\": \"Generated At\",\n  \"warnings\": [],\n  \"exposures\": {},\n  \"lineups\": []\n}\n```\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","title":"date","description":"Slate date YYYY-MM-DD"},"sport":{"anyOf":[{"type":"string","pattern":"^(nba|mlb|NBA|MLB)$"},{"type":"null"}],"title":"sport","description":"Sport engine to run: nba or mlb.","default":"nba","type":"string"},"preset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"preset","description":"Strategy preset key.","default":"gpp_pro_pattern","type":"string"},"platform":{"anyOf":[{"type":"string","pattern":"^(fd|dk|fanduel|draftkings)$"},{"type":"null"}],"title":"platform","description":"V12 platform profile: fd or dk.","default":"fd","type":"string"},"slate_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"slate_id","description":"Specific slate ID from /v1/slates. Overrides date-based lookup.","type":"integer"},"contest_id":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"contest_id","description":"Optional contest handle for building an entry-update CSV from the user's existing contest entries.","type":"string"},"entry_template_csv":{"anyOf":[{"type":"string","maxLength":4000000},{"type":"null"}],"title":"entry_template_csv","description":"Raw CSV of a FanDuel entries-upload-template the operator already downloaded. When present, the entry-upload is filled from its OWN entry_ids locally — no FanDuel API / session / PerimeterX call. Fixes fd_entry_template_auth_expired when the user already has the template in hand.","type":"string"},"contest_max_entries":{"anyOf":[{"type":"integer","maximum":150,"minimum":1},{"type":"null"}],"title":"contest_max_entries","description":"Max entries per user for the selected contest. Used to identify multi-entry mass GPPs (>=4) which keep the caller's preset. Field SIZE, not this, governs the MLB objective — see contest_field_size.","type":"integer"},"contest_field_size":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"title":"contest_field_size","description":"Total entries (field size) of the selected contest. Governs the MLB objective: field <= 10 -> max-mean (mlb_small_field_se); field > 10 -> ceiling (mlb_se_ceiling) with a continuous ceiling tilt and the real field size fed into contest simulation. A matched contest_id lobby row is authoritative; this value is the fallback when that row is unavailable.","type":"integer"},"contest_fallback":{"anyOf":[{"type":"string","pattern":"^(slate_only)$"},{"type":"null"}],"title":"contest_fallback","description":"Escape hatch when a contest_id cannot be mapped to a slate (contest_slate_unresolved). 'slate_only' + an explicit slate_id builds on THAT slate and skips contest-specific behavior (field-size routing, entry-template mapping) instead of failing the whole generate. Requires slate_id; without it the request still fails closed. Omit for normal contest-anchored builds.","type":"string"},"plan_only":{"type":"boolean","title":"plan_only","description":"When true, the server resolves preset / contest / authoritative slate / top-run-env / locks but does NOT run the optimizer. Returns a Plan response so the user can review and confirm before spending credits on a real generate. Costs 0 credits; normal slate-open safety checks still apply.","default":false},"fd_user_id":{"anyOf":[{"type":"string","maxLength":32,"pattern":"^\\d+$"},{"type":"null"}],"title":"fd_user_id","description":"DEPRECATED on /v1/generate: fd_user_id is bound server-side to your API key (see /v1/admin/bind-fd-user). Body value is IGNORED on the public route unless X-Internal-Secret matches. Kept on the schema for the internal admin path only.","type":"string"},"lineups":{"anyOf":[{"type":"integer","maximum":150,"minimum":1},{"type":"null"}],"title":"lineups","description":"Number of lineups (overrides preset default)","type":"integer"},"strategy":{"anyOf":[{"type":"string","pattern":"^(gpp|cash)$"},{"type":"null"}],"title":"strategy","description":"GPP or cash game strategy","type":"string"},"style":{"anyOf":[{"type":"string","pattern":"^(aggressive|balanced|safe)$"},{"type":"null"}],"title":"style","type":"string"},"runs":{"type":"integer","maximum":10,"minimum":1,"title":"runs","description":"Accepted for tier limits and response metadata. Portfolio quality is controlled by preset, candidate_pool_size, pool_oversample_multiplier, and simulation settings.","default":5},"seed":{"type":"integer","maximum":999999,"minimum":0,"title":"seed","description":"Random seed for reproducibility","default":42},"locks":{"items":{},"type":"array","maxItems":15,"title":"locks","description":"Players to lock in","default":[]},"avoids":{"items":{},"type":"array","maxItems":100,"title":"avoids","description":"Players to avoid","default":[]},"exposure_caps":{"additionalProperties":true,"type":"object","title":"exposure_caps","description":"Per-player exposure caps {name: 0.0-1.0}","default":{}},"max_hitter_exposure":{"anyOf":[{"type":"number","maximum":1,"exclusiveMinimum":0},{"type":"null"}],"title":"max_hitter_exposure","description":"Portfolio cap: max share of delivered lineups any ONE hitter may appear in (0.4 = 40%). Pitchers exempt.","type":"number"},"max_pitcher_exposure":{"anyOf":[{"type":"number","maximum":1,"exclusiveMinimum":0},{"type":"null"}],"title":"max_pitcher_exposure","description":"Portfolio cap: max share of delivered lineups any ONE pitcher may appear in.","type":"number"},"auto_team_exposure_cap":{"anyOf":[{"type":"number","maximum":1,"exclusiveMinimum":0},{"type":"null"}],"title":"auto_team_exposure_cap","description":"Default per-team portfolio cap (share of lineups containing ANY given team). Per-team entries in team_exposure_caps win over it.","type":"number"},"team_exposure_caps":{"anyOf":[{"items":{"prefixItems":[{"type":"string"},{"type":"number"}],"type":"array","maxItems":2,"minItems":2},"type":"array"},{"additionalProperties":{"type":"number"},"type":"object"},{"type":"null"}],"title":"team_exposure_caps","description":"Per-team portfolio caps, as [[\"COL\",0.5],...] pairs or {\"COL\":0.5} dict.","type":"object"},"focus_games":{"items":{"type":"string"},"type":"array","maxItems":30,"title":"focus_games","description":"Game keys to emphasize, e.g. ['PHI@BOS']. Applies a small documented projection nudge.","default":[]},"projection_overrides":{"items":{"additionalProperties":true,"type":"object"},"type":"array","maxItems":2000,"title":"projection_overrides","description":"User-uploaded projection/ownership rows. Supports name/player_id/team/position/projection/ownership/ceiling/floor/stddev.","default":[]},"sim_mode":{"anyOf":[{"type":"string","pattern":"^(off|mvn|on)$"},{"type":"null"}],"title":"sim_mode","description":"Simulation mode. NBA: mvn/off. MLB: on/off.","type":"string"},"n_sims":{"anyOf":[{"type":"integer","maximum":100000,"minimum":100},{"type":"null"}],"title":"n_sims","description":"Monte Carlo iterations when simulation is enabled.","type":"integer"},"candidate_pool_size":{"anyOf":[{"type":"integer","maximum":5000,"minimum":0},{"type":"null"}],"title":"candidate_pool_size","description":"Exact candidate pool size for Pool→Rank→Keep-N selection. 0/None uses preset multiplier.","type":"integer"},"pool_oversample_multiplier":{"anyOf":[{"type":"number","maximum":10,"minimum":1},{"type":"null"}],"title":"pool_oversample_multiplier","description":"Candidate pool multiplier when candidate_pool_size is not set.","type":"number"},"refresh_data":{"type":"boolean","title":"refresh_data","description":"Force a fresh V12 data refresh for user-facing generation. Backtests should set false.","default":true},"allow_locked":{"type":"boolean","title":"allow_locked","description":"Explicit replay/late-swap override. Default false blocks slate_id generation once any game has started.","default":false}},"required":["date"],"title":"generate_lineupsArguments"}},{"name":"get_slate_players","description":"Get Slate Players Endpoint\n\nGet the V12 player pool for a specific slate ID.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"slate_id":{"type":"integer","title":"slate_id"},"compact":{"type":"boolean","default":false,"title":"compact"},"limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"limit","type":"integer"}},"required":["slate_id"],"title":"get_slate_playersArguments"}},{"name":"health_check","description":"Health\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"status\": \"Status\",\n  \"version\": \"Version\",\n  \"timestamp\": \"Timestamp\"\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"title":"health_checkArguments"}},{"name":"health_v12","description":"Health V12\n\nDeep health check for the V12 pipeline. Surfaces:\n  - last nightly regression run (pass/fail + per-slate deltas)\n  - regression baseline metadata\n  - recent preflight blockers (if any cached)\nNo auth required — monitoring endpoint.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"title":"health_v12Arguments"}},{"name":"list_contests","description":"Contest Registry\n\nList contest strategy registry entries for agents and the dashboard.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"platform":{"type":"string","default":"fd","title":"platform"},"sport":{"type":"string","default":"MLB","title":"sport"}},"title":"list_contestsArguments"}},{"name":"list_live_contests","description":"Live Contests\n\nReturn latest V12 contest context without backend identifiers.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"platform":{"type":"string","default":"fd","title":"platform"},"sport":{"type":"string","default":"MLB","title":"sport"},"compact":{"type":"boolean","default":true,"title":"compact"},"limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":250,"title":"limit","type":"integer"}},"title":"list_live_contestsArguments"}},{"name":"list_presets","description":"Get Presets\n\nList the available strategy presets (gpp_pro_pattern, gpp_sniper, gpp_balanced, gpp_volume, cash_grinder, gpp_contrarian, gpp_mass_entry) with their configurations. No auth required.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"sport":{"type":"string","default":"nba","title":"sport"}},"title":"list_presetsArguments"}},{"name":"list_slates","description":"Get Slates\n\nList available V12 slates for today. Returns slate IDs, game counts, and lock times.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"site":{"type":"string","default":"fd","title":"site"},"sport":{"type":"string","default":"NBA","title":"sport"},"playable":{"type":"boolean","default":false,"title":"playable"},"compact":{"type":"boolean","default":false,"title":"compact"},"limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"limit","type":"integer"}},"title":"list_slatesArguments"}},{"name":"run_mlb_postmortem","description":"Run Mlb Postmortem\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"status\": \"Status\",\n  \"generated_at\": \"Generated At\",\n  \"date\": \"Date\",\n  \"game_id\": \"Game Id\",\n  \"entries\": 1,\n  \"field_lineups\": 1,\n  \"training_rows\": 1,\n  \"missing_sources\": [\n    \"string\"\n  ],\n  \"results\": {},\n  \"history_validation\": {},\n  \"field\": {},\n  \"diagnostics\": {},\n  \"simulator_feed\": {},\n  \"warnings\": [\n    \"string\"\n  ]\n}\n```\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","title":"date","description":"Slate date YYYY-MM-DD"},"game_id":{"type":"string","maxLength":32,"minLength":3,"title":"game_id","description":"V12 slate/game handle, e.g. 129715."},"history_csv":{"type":"string","minLength":1,"title":"history_csv","description":"Raw FanDuel contest-history CSV content."},"history_filename":{"type":"string","maxLength":240,"title":"history_filename","default":"contest-history.csv"},"upload_csvs":{"items":{"properties":{"filename":{"type":"string","maxLength":240,"title":"Filename","default":"upload.csv"},"content":{"type":"string","minLength":1,"title":"Content","description":"Raw FanDuel upload/template CSV content."}},"type":"object","required":["content"],"title":"PostmortemUploadCsv"},"type":"array","maxItems":20,"title":"upload_csvs","default":[]},"sabersim_csv":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"sabersim_csv","description":"Optional external lineup export for comparison.","type":"string"},"top_field_rank":{"type":"integer","maximum":1000,"minimum":1,"title":"top_field_rank","default":200},"sync_supabase":{"type":"boolean","title":"sync_supabase","description":"Upsert simulator training rows to production store when configured.","default":true}},"required":["date","game_id","history_csv"],"title":"run_mlb_postmortemArguments"}},{"name":"scout_field","description":"Scout Field\n\nVIP-only (owner order 8/16): opponent-scouting profiles for the small\nsingle-entry band. The owner's $65 table runs the SAME regulars nightly;\nthis returns each regular's fingerprint — days seen, avg score,\nchalkiness (overlap with field consensus), favorite pitchers/bats and\nhead-to-head vs the owner — built from harvested full fields\n(brain/scout_profiles.json, refreshed by the local scouting pipeline;\npackaged snapshot as fallback so the endpoint never 500s on a fresh\nvolume). Same fail-closed allowlist as the semaforo.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"contest":{"type":"string","default":"Knuckleball","title":"contest"},"min_days":{"type":"integer","default":3,"title":"min_days"}},"title":"scout_fieldArguments"}},{"name":"slate_diff","description":"Slate Diff\n\nCompute what changed since a previously-stored snapshot.\n\nBody shape:\n  {\n    \"slate_id\": 32867,\n    \"date\": \"2026-05-11\",\n    \"sport\": \"NBA\",\n    \"site\": \"FD\",\n    \"previous\": {\n      \"v\": \"v1\",\n      \"players\": [{\"id\",\"name\",\"status\",\"salary\",\"proj\"}, ...],\n      \"odds\":    [{\"game\",\"ou\",\"spread\",\"home_ml\",\"away_ml\"}, ...]\n    }\n  }\n\nReturns a structured diff: which players changed status / salary /\nprojection, which games moved spread or O/U, which players were added\nor removed from the pool. The thresholds for \"changed\":\n  - status: any non-empty difference (Q→OUT, ''→OUT, GTD→IN, etc.)\n  - salary: any integer delta\n  - projection: |delta| >= 0.5 fantasy points\n  - odds spread: |delta| >= 0.5\n  - odds ou: |delta| >= 0.5\n  - odds ml: |delta| >= 10 (American odds noise floor)\n\nNo auth required — read-only computation off in-memory current snapshot\nplus the caller-supplied previous one.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"title":"slate_diffArguments"}},{"name":"slate_health","description":"Slate Health\n\nPre-flight diagnostic for a slate. Returns whether odds, projections,\nmatchup, and FD master-session are ready BEFORE the agent invokes\n/v1/generate.\n\nEither slate_id or date is required. When slate_id is given, the slate\nmetadata is also returned (games list, lock times). When only date is\ngiven, the data-pillar checks still run but game coverage cannot be\ncomputed (returned as null).\n\nREADING THE PROJECTION FRESHNESS (MLB especially): `stokastic.age_min` is the\nage of the cached snapshot FILE, NOT a data-quality signal. For MLB the cache\nis refreshed only twice a day, so mid-afternoon it routinely reads several\nhours old AND THAT IS FINE — a user-facing generate fetches projections LIVE\n(refresh_data=true), and `stokastic.generate_fetches_live=true` flags this.\nA stale `age_min` with a loaded, populated pool is NOT \"projections broken /\naces at 0 / no edge\": probable pitchers are set days ahead (non-zero), and\nonly confirmed BATTING lineups firm up ~1-2h before lock. Do NOT treat a stale\ncache age as a blocker or tell the user to wait/re-refresh — check the actual\npool (get_slate_players) for non-zero pitcher projections instead.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"slate_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"slate_id","type":"integer"},"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"date","type":"string"},"site":{"type":"string","default":"fd","title":"site"},"sport":{"type":"string","default":"NBA","title":"sport"},"last_known_fingerprint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"last_known_fingerprint","type":"string"},"include_snapshot":{"type":"boolean","default":false,"title":"include_snapshot"}},"title":"slate_healthArguments"}},{"name":"slate_refresh","description":"Slate Refresh\n\nRe-fetch projections + odds + slate metadata for a date.\n\nWrites to the configured store (Supabase in prod). Returns a summary\ndict (date, slate_id, n_games, n_players, n_upserted, n_odds, backend).\n\nAuth: requires X-API-Key OR X-Internal-Secret (cron use). This is a\nwrite op that costs one Stokastic + one ESPN API call.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n**422**: Validation Error\nContent-Type: application/json\n\n**Example Response:**\n```json\n{\n  \"detail\": [\n    {\n      \"loc\": [],\n      \"msg\": \"Message\",\n      \"type\": \"Error Type\",\n      \"ctx\": {}\n    }\n  ]\n}\n```","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"date","type":"string"},"sport":{"type":"string","default":"NBA","title":"sport"},"site":{"type":"string","default":"FD","title":"site"}},"title":"slate_refreshArguments"}}],"scan":{"score":64,"grade":"C","scanned_at":"2026-09-26T21:23:08.510Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-26T21:23:08.470Z","components":{"code":{"score":-1,"max":25,"notes":["remote-only server, no package to scan"]},"reliability":{"score":20,"max":20,"notes":["remote reachable in 624ms"]},"poisoning":{"score":15,"max":15,"notes":["34 tool descriptions checked"]},"auth":{"score":8,"max":15,"notes":["API key sent as a header"]},"maintenance":{"score":3,"max":15,"notes":["no repository listed"]},"identity":{"score":2,"max":10,"notes":["no repository or website to verify"]}},"findings":[{"id":"maint.no-repo","severity":"low","component":"maintenance","title":"No source repository listed"}],"inputs":{"probes":[{"url":"https://v12dfs-production.up.railway.app/mcp","reachable":true,"authRequired":false,"latencyMs":624,"serverInfo":{"name":"V12 DFS Optimizer","version":"1.0.0"}}],"packages":[],"repo":{"found":false},"icon":{"url":null,"source":"none"},"presence":{"stars":null,"forks":null,"downloadsWeek":null,"license":null,"lastPushAt":null,"score":5}}}},"grade_history":[],"reviews":[]}