Skip to content
For AI agents

Agent reference

Everything a person does here — describe, upload, train, evaluate, export — is designed to be done by an AI agent too: discoverable, typed, idempotent, and bounded by a budget a human sets.

The API, MCP server and CLI are planned, not live

This page documents the contract we're building toward. Today, the agent skill hands off to the web app, where jobs are simulated.

Machine-readable, live today: SKILL.mdllms.txtCapability manifestOpenAPI draft

01Where things stand

Where things stand

  • Web app

    Live preview

    Create, train (simulated), test and export in the browser.

    Open
  • Agent skill

    Live

    One pasted line sets it up. Your agent helps you shape the task and prepare examples, then hands off to the web app.

    Read SKILL.md
  • REST API

    Planned

    Draft OpenAPI 3.1 spec, generated from the same schemas the web app uses.

    Draft spec
  • MCP server

    Planned

    Nine tools over streamable HTTP, each with a JSON Schema and a declared side effect.

    Tools
  • CLI

    Planned

    tmc mirrors every tool for scripts, CI and terminal-based agents.

    Commands

02The safe loop

The safe loop

Six calls take an agent from an idea to an exported model — and every step that can cost money is explicit, capped and repeatable.

Simulated session
  1. 01Discover

    Learn what's possible and which interfaces are live.

    agent →tools/list

    ← tmc9 tools · output kinds: single_label, multi_label, extraction · auth: bearer (scoped)

  2. 02Estimate

    Free dry run before committing any money.

    agent →estimate_cost({ output_kind: "single_label", label_count: 6, row_count: 2400, requirements: { min_accuracy: 0.9, max_spend_usd: 25 } })

    ← tmc$1.19–$2.01 · 13–23 min · 4 candidates · within_cap: true

  3. 03Register data

    Data-quality issues surface before training starts.

    agent →create_dataset({ name: "tickets", format: "csv", source_url: "https://…/tickets.csv?sig=…" })

    ← tmcds_8f2k1q · 2,400 rows · 6 labels · 0 errors · 1 note (14 duplicates removed)

  4. 04Create the job

    Idempotency key and a hard spending cap are mandatory.

    agent →create_model_job({ …, dataset_id: "ds_8f2k1q", requirements: { max_spend_usd: 25 }, idempotency_key: "router-2026-10-17-a" })

    ← tmc202 Accepted · job_7hq2m4 · queued · Retry-After: 10

  5. 05Poll

    Long-running: back off as Retry-After asks, or use webhooks.

    agent →get_job({ job_id: "job_7hq2m4" })

    ← tmcrunning · train · 62% · $1.12 of $25.00 spent · eta 9 min

  6. 06Check the bar

    Evaluation on held-out data, against the requirements set.

    agent →get_model({ model_id: "mdl_x91" })

    ← tmcsucceeded · accuracy 92.1% (≥ 90% ✓) · p95 13 ms (≤ 50 ms ✓) · spent $1.61

  7. 07Export

    Signed, short-lived download with a checksum to verify.

    agent →export_model({ model_id: "mdl_x91", format: "onnx" })

    ← tmcsupport-ticket-router-v3.onnx · 155 MB · sha256 9c1e… · expires in 15 min

03MCP tools

MCP tools

Each tool declares its side effect and the scopes it needs. Input schemas are generated from the same contract as the web app.

  • describe_capabilities

    Read-only

    What this service can build, the supported output kinds, export formats, limits and current status of each interface.

    GET /v1/capabilities · tmc capabilities

  • estimate_cost

    Read-onlymodels:read

    Free dry run. Returns a cost range, wall-clock time and whether it fits under the cap. Call this before create_model_job.

    POST /v1/estimates · tmc estimate --task … --rows 2400 --min-accuracy 0.9

  • create_dataset

    Writesdatasets:write

    Register training examples from inline rows or an HTTPS URL. Optionally clean each input (HTML, quoted replies, signatures, repeated lines) and combine labels; models trained on them clean and combine live calls the same way. Returns data-quality issues before anything is trained.

    POST /v1/datasets · tmc datasets create ./tickets.csv --text-column message --label-column team

  • create_model_job

    Can spendjobs:create

    Start a long-running training job. Requires an idempotency key and a spending cap; returns immediately with a queued job.

    POST /v1/jobs · tmc models create --task … --data ./tickets.csv --max-spend 25 --idempotency-key …

  • get_job

    Read-onlymodels:read

    Poll a job. Honour the Retry-After hint; terminal states are succeeded, failed and canceled.

    GET /v1/jobs/{job_id} · tmc jobs watch job_…

  • cancel_job

    Writesjobs:cancel

    Stop a running job. Nothing more is charged. Canceling a finished job returns 409.

    POST /v1/jobs/{job_id}/cancel · tmc jobs cancel job_…

  • get_model

    Read-onlymodels:read

    Metrics on held-out data, requirement checks, per-label scores, confusion matrix and baseline comparison.

    GET /v1/models/{model_id} · tmc models show mdl_…

  • predict

    Can spendmodels:predict

    Run the model on one input. Hosted models bill per call at the price in the model's metrics.

    POST /v1/models/{model_id}/predict · tmc predict mdl_… "Where is my package?"

  • export_model

    Writesmodels:export

    Get a short-lived signed download for an artifact, with its SHA-256 and model card.

    POST /v1/models/{model_id}/exports · tmc models export mdl_… --format onnx --out ./model.onnx

mcp.json · planned server
{  "mcpServers": {    "the-model-company": {      "url": "https://mcp.tmc.example/v1",      "headers": { "Authorization": "Bearer ${TMC_API_KEY}" }    }  }}

04REST & OpenAPI

REST & OpenAPI

The same operations over HTTPS, described by an OpenAPI 3.1 document you can feed to code generators or tool-use frameworks.

Planned REST endpoints
Endpoint
GET /v1/capabilities
POST /v1/estimates
POST /v1/datasets
POST /v1/jobs
GET /v1/jobs/{job_id}
POST /v1/jobs/{job_id}/cancel
GET /v1/models/{model_id}
POST /v1/models/{model_id}/predict
POST /v1/models/{model_id}/exports
request
POST /v1/jobs HTTP/1.1Host: api.tmc.exampleAuthorization: Bearer $TMC_API_KEYIdempotency-Key: router-2026-10-17-aContent-Type: application/json{ "name": "Support ticket router", "task": { … }, "dataset_id": "ds_8f2k1q",  "requirements": { "min_accuracy": 0.9, "max_spend_usd": 25, … }, "mode": "training" }
response
HTTP/1.1 202 AcceptedLocation: /v1/jobs/job_7hq2m4Retry-After: 10{ "id": "job_7hq2m4", "status": "queued", "progress": 0,  "cost": { "cap_usd": 25, "estimated_usd": 2.01, "spent_usd": 0 } }
Open the OpenAPI draft

05CLI

CLI

For terminal-native agents, CI pipelines and people who like scripts. Every command maps onto one tool.

terminal · planned
$ tmc models create \    --task "Route support tickets to the right team" \    --data ./tickets.csv --label-column team \    --min-accuracy 0.90 --max-latency 50 --max-spend 25 \    --idempotency-key router-2026-10-17-a→ job_7hq2m4 queued · estimate $1.61–$2.71 · cap $25.00$ tmc jobs watch job_7hq2m4→ training 4 candidates · 62% · $1.12 spent→ succeeded · accuracy 92.1% (target 90%) · p95 13 ms$ tmc models export mdl_x91 --format onnx --out ./router.onnx

06Long-running jobs

Long-running jobs

Training takes minutes, not milliseconds. Creating a job returns immediately; progress is polled or pushed.

Job states: queued, then running through six stages (validate, prepare, select, train, evaluate, package), ending in succeeded, failed or canceled.
poll · honour Retry-After
GET /v1/jobs/job_7hq2m4 HTTP/1.1HTTP/1.1 200 OKRetry-After: 10{ "status": "running", "current_stage": "train", "progress": 0.62,  "eta_seconds": 540, "cost": { "spent_usd": 1.12, "cap_usd": 25 } }
or receive a signed webhook
POST https://your-agent.example/hooks/tmcTMC-Signature: t=1792234412,v1=5f2c…{ "type": "job.succeeded", "job_id": "job_7hq2m4", "model_id": "mdl_x91",  "metrics": { "accuracy": 0.921, "latency_ms_p95": 13 } }

The web app's job page is a live example: it polls the same Job resource an agent would. Watch one.

07Keys, limits & idempotency

Keys, limits & idempotency

Agents act on someone's behalf. The guardrails are part of the protocol, not an afterthought.

Scoped keys

Keys carry only the scopes an agent needs. Creating jobs and exporting weights are separate permissions.

Hard spending caps

Every job requires max_spend_usd. Keys add a monthly ceiling; jobs above the auto-approve limit wait for a human.

Idempotent creation

Retrying with the same key returns the original job — a flaky network can never buy two training runs.

Planned API key scopes
ScopeAllows
models:readRead models, jobs, estimates and evaluations
datasets:writeRegister training data
jobs:createStart training jobs (spends money, within caps)
jobs:cancelCancel running jobs
models:predictRun predictions (hosted models bill per call)
models:exportDownload weights and containers
idempotency
# Same key + same body → the original job, never a second chargePOST /v1/jobs   Idempotency-Key: router-2026-10-17-a   → 202 job_7hq2m4POST /v1/jobs   Idempotency-Key: router-2026-10-17-a   → 202 job_7hq2m4 (replayed)# Same key + different body → rejected, nothing createdPOST /v1/jobs   Idempotency-Key: router-2026-10-17-a   → 409 idempotency_conflict
402 · approval_required
{  "error": {    "code": "approval_required",    "message": "Estimated cost $38.40 exceeds this key's auto-approve limit of $25.00.",    "details": {      "estimate_usd": { "low": 30.70, "high": 38.40 },      "approval_url": "https://themodelcompany.example/approvals/apr_51k",      "expires_at": "2026-10-18T09:00:00Z"    }  }}

08Artifacts

Artifacts

Exports are short-lived signed URLs with a SHA-256 to verify and a model card describing data, metrics and limits.

export_model
POST /v1/models/mdl_x91/exports  { "format": "onnx" }{ "artifact": { "format": "onnx", "filename": "support-ticket-router-v3.onnx",    "size_mb": 155, "sha256": "9c1e…" },  "download_url": "https://downloads.tmc.example/…?sig=…",  "expires_at": "2026-10-17T10:15:00Z" }

Prefer to click?

The same flow runs in the browser today, with a free simulated job.

Create a model