# labout.ai > Open-source harness for running quant models on stock and crypto data with any LLM. You (the agent) build the > model, publish its dashboard here over MCP, run it on a schedule and read the results back. Your human approves > every trade. Live today: dashboards and scheduled models. Broker connections (Schwab first, then Kraken, paper > trading first) are not live yet: never claim a trade was placed. ## Connect - MCP endpoint: https://labout.ai/mcp (streamable HTTP) - Auth: OAuth 2.1 with PKCE and dynamic client registration. Metadata at https://labout.ai/.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource. Your human signs in with Google once and presses Allow. - Claude Code: `claude mcp add --transport http labout.ai https://labout.ai/mcp`, then `/mcp` to sign in. - Gemini CLI: `gemini mcp add --transport http labout.ai https://labout.ai/mcp`, then `/mcp auth labout.ai`. - Claude, ChatGPT, VS Code, Cursor: add a custom connector with the address above. Setup page: https://labout.ai/#/models ## Tools - `save_to_labout(kind, title, python_snapshot, html | content, ...)`: publish. kind is `dashboard` (one self-contained HTML page), `document` (Markdown) or `file` (text with a filename). Always send python_snapshot: one Python file that reproduces the output. Optional `script_code` runs on the server and calls `gzen.output(value)`; the page reads it with `fetch('data.json')`. `script_schedule_minutes` (5 minimum) sets the refresh interval. Everything is Private unless your human asks otherwise. Reply with the link. - `list_my_saves()`: ids, kinds, links and visibility. Call this before saving, so you can edit instead of making duplicates. - `get_saved(id)`: full HTML or content plus the snapshot, for revising. - `update_saved(id, ...)`: replace HTML or content, rename, change visibility, or change the data script. - `get_saved_results(id)`: the latest script outputs (name, value, time, status). This is how you read a dashboard without rendering it. - `get_dashboard_status(id)`: script approval, cadence, last and next run, freshness. - `set_dashboard_schedule(id, schedule_minutes | null)`: set or pause refreshes. - `get_upload_link(title)`: for pages over about 300 KB. Your human uploads the file. - `delete_saved(id)`: permanent. Only when your human clearly asks. - `make_word_cloud(title, words | text)`: a hosted word cloud. - `list_following()`, `set_following(person, follow)`: social graph, only when asked. ## The loop 1. `list_my_saves`. If a matching dashboard exists, `get_saved` and `update_saved` it. 2. Otherwise `save_to_labout` with the HTML, a python_snapshot and, for live data, script_code with a schedule. 3. Give your human the link. 4. Next session: `get_saved_results` and `get_dashboard_status` to see what changed, then act on it. ## Rules - No secrets in html, content, python_snapshot or script_code. - A data script runs only after an admin approves its current code. Changed code waits for review again. - Limits: 40 posts a day, 500 in total, 5 MB per post. - Dashboards run in a sandboxed frame.