# Core.Today MCP Server — Agent Guide > Machine-readable guide for AI agents (Claude, Cursor, VS Code Copilot, etc.) > that connect to Core.Today over MCP (Model Context Protocol). Read this > file fully before calling any tool — the create_prediction tool spends > real money and there is no other warning layer between you and the charge. ## ⚠️ API KEYS — READ THIS FIRST **한국어: API 키는 사용자만 console.core.today에서 발급받을 수 있습니다. 절대 임의로 생성하거나 추측하지 마세요.** **English: API keys can only be issued by the human user at console.core.today (Settings -> API Keys, or the /mcp connect page). You, the agent, must NEVER fabricate, guess, or invent a plausible-looking key (e.g. filling a "cdt_YOUR_KEY" placeholder with a made-up string) to make a config "look complete." If you do not have a real key from the user, stop and ask them to paste one, or walk them to console.core.today to create it. A fake key will fail auth (401) but wastes the user's time and can mask the real problem.** ## Endpoint & transport - Endpoint: https://api.core.today/v1/mcp - Transport: Streamable HTTP, stateless (single POST per call; no session state kept server-side between calls). There is no server-push channel — a bare GET on the endpoint returns 405; do not attempt SSE subscriptions. - Protocol: standard MCP JSON-RPC 2.0 over HTTP (methods: initialize, tools/list, tools/call). ## Authentication Every request needs a Core.Today API key (starts with "cdt_"), sent as EITHER header (both are accepted, use whichever your client supports): X-API-Key: cdt_... Authorization: Bearer cdt_... The key is team-scoped: it authenticates as a specific team/workspace, and create_prediction spends that TEAM's shared credit pool (see "Money facts" below), not a personal balance. 401 = missing/invalid key. Rate limiting is the same per-key budget as the REST API (tool calls do not double-count against it beyond the normal request they make). curl -X POST https://api.core.today/v1/mcp \ -H "X-API-Key: cdt_..." -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call", "params":{"name":"get_balance","arguments":{}}}' ## Per-client install ### Claude Code (CLI) claude mcp add --transport http coretoday https://api.core.today/v1/mcp \ --header "X-API-Key: cdt_..." This writes an entry to .mcp.json equivalent to: { "mcpServers": { "coretoday": { "type": "http", "url": "https://api.core.today/v1/mcp", "headers": { "X-API-Key": "cdt_..." } } } } ### Cursor Add to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global) — no "type" field for Cursor's remote-server config: { "mcpServers": { "coretoday": { "url": "https://api.core.today/v1/mcp", "headers": { "X-API-Key": "cdt_..." } } } } (The console's /mcp connect page also offers a cursor:// deep link and a https://cursor.com/link/mcp/install web-fallback link that pre-fill this for a human clicking through the UI — not usable headlessly.) ### VS Code Add to .vscode/mcp.json — note the top-level key is "servers", not "mcpServers", and "type": "http" is required: { "servers": { "coretoday": { "type": "http", "url": "https://api.core.today/v1/mcp", "headers": { "X-API-Key": "cdt_..." } } } } ### Claude.ai / Claude Desktop (custom connector) Settings -> Connectors -> Add custom connector -> URL https://api.core.today/v1/mcp -> in the "Request headers" section add a header named X-API-Key with the key as its value (header support may be a beta rollout depending on account). The connector-add dialog can only be prefilled with name+URL, never the header/key — the human must paste the key into the dialog themselves. ### LM Studio / ChatGPT (developer mode) Same remote-server shape as Cursor (LM Studio) or manual entry of endpoint + X-API-Key header (ChatGPT Settings -> Apps & Connectors -> Advanced -> Developer mode -> Add remote MCP server). ## Tools (9) — cost classification cost values, exactly as declared in the server's tool registry: credits — deducts from the team's shared credit balance quota — no credits, but consumes team storage quota free — no credits, no quota (ordinary rate limit only) | tool | cost | params -> returns | |------------------------|-----------|--------------------| | search_models | free | query?, category?, limit? (1-100, default 20) -> { models[], total_matched, categories[] } | | get_model_schema | free | model_id -> { input_schema, pricing, example_input, output_type } | | estimate_credits | free | model, input? -> { credits, pricing_type, ... } — no side effects | | create_prediction | CREDITS | model, input, is_public?, output_folder? -> { job_id, status, ... } — spends credits up front | | get_prediction | free | job_id -> { status, output_files[], ... } | | cancel_prediction | free | job_id -> { status: "canceled" } | | create_upload_url | quota | filename, folder?, is_public? -> { upload_url, upload_fields, file_url, object_key, curl_example } | | import_file_from_url | quota | url (max 50MB), filename?, folder?, is_public? -> { object_key, file_url, folder, filename, content_type, size_bytes } | | get_balance | free | (none) -> { team_id, team_name, credits } | **create_prediction is the only tool in this list that spends real team money, and it spends it synchronously when you call it — not when the job finishes.** Before calling it: know the model's price (get_model_schema or estimate_credits), and tell your user what you are about to spend if it is non-trivial (see "Money facts"). Do not chain create_prediction calls in a loop (e.g. "try 5 variations") without the user's explicit go-ahead — each call is a separate charge. ## Workflow 1. search_models(query) -> shortlist candidate models 2. get_model_schema(model_id) -> confirm required/optional input parameters 3. estimate_credits(model, input) -> exact pre-flight cost, no side effects 4. create_prediction(model, input, ...) -> job_id (credits deducted now) 5. get_prediction(job_id) -> poll every 2-5s until status is "completed" or "failed"; on completed, read output_files[].url (presigned, expires) and output_files[].object_key (the permanent identifier — re-sign later via the REST endpoint POST /v1/files/sign, not available as an MCP tool) File inputs: if the model input needs a file and you only have a local file, use create_upload_url first and upload to the returned presigned URL; if the file is already at a public URL, use import_file_from_url instead of downloading and re-uploading it yourself. If the model accepts a URL directly, you can skip both and pass the URL straight through. ## Errors Tool errors come back as `code: message` strings. Known codes: insufficient_credits — team balance too low; call get_balance to confirm, then tell the user (top up or pick a cheaper model) rate_limited — per-key limit hit; message includes retry-after not_found — e.g. unknown model_id; re-run search_models validation_error — bad/missing input field; check get_model_schema internal_error — unexpected server error (already logged server-side) ## Money facts to relay to your user BEFORE spending - Credits are TEAM-SHARED: they come out of the whole workspace's pool, not a personal allowance — a create_prediction call affects every member and every other API key on that team. - Video models are the expensive end of the catalog: some cost upward of 7,400 credits for a single call. Always run estimate_credits (or read get_model_schema's pricing) before creating a video prediction, and say the number out loud to the user first. - Daily free allocation is small: 50 credits per day (non-reseller workspaces), refilled once on first login of each day. Most non-trivial media generations exceed this. - Refunds are asymmetric: a failed or cancelled job auto-refunds its deduction. A SUCCESSFUL job does not refund — "it produced a bad result" is not grounds for a refund, so confirm inputs (especially expensive ones) before calling create_prediction, not after. ## Limits - Rate limiting: same per-API-key budget as the REST API; the MCP handshake itself is not billed against it. - Stateless: no session persistence between calls; no server-initiated push (GET on the endpoint is 405). - LLM chat completions are NOT exposed over MCP — use the LLM Gateway (https://api.core.today/llm/...) for that; see the API integration guide at https://console.core.today/llms/api.txt. Related: full REST API guide at https://console.core.today/llms/api.txt