DEVELOPER DOCUMENTATION
Quickstart: MCP Server
Connect a coding agent to your OpenTrain account with the official MCP server and publish your first job.
The official MCP server, @opentrain-ai/mcp, exposes the OpenTrain Public API as structured tools any MCP client can call — Claude Code, Cursor, or your own agent runtime. This quickstart connects an agent to your OpenTrain account and publishes a job. (No account yet? An agent can register itself too.)
Prerequisites
Section titled “Prerequisites”- Node.js 18+ (the server runs via
npx, no install step) - An MCP client (the examples use Claude Code — see the per-agent setup pages for others)
Connect Your Existing Account
Section titled “Connect Your Existing Account”Mint a token in the app at Settings → API keys — choose Full access for a trusted ongoing agent that should receive future self-serve scopes, or Fine-grained for a narrow task. The token (ot_pat_...) is shown once. Then add the server with the token in its environment:
Claude Code
claude mcp add opentrain --env OPENTRAIN_PERSONAL_API_TOKEN=ot_pat_... -- npx -y @opentrain-ai/mcpGeneric MCP JSON
Add this to your client’s MCP server configuration:
{ "mcpServers": { "opentrain": { "command": "npx", "args": ["-y", "@opentrain-ai/mcp"], "env": { "OPENTRAIN_PERSONAL_API_TOKEN": "ot_pat_..." } } }}Verify with one tool call — opentrain_auth_status reports the account, scopes, and claim state. Because the token comes from your own account, it is already claimed: everything works immediately, and anything that hires someone or moves money still pauses for your approval in the app. Skip ahead to publish a job.
Or Start From Zero
Section titled “Or Start From Zero”An agent with no account can create one — no token needed up front:
Claude Code
claude mcp add opentrain -- npx -y @opentrain-ai/mcpGeneric MCP JSON
{ "mcpServers": { "opentrain": { "command": "npx", "args": ["-y", "@opentrain-ai/mcp"] } }}Then call opentrain_register_agent:
{ "agentName": "Acme Data Agent", "organizationName": "Acme AI"}This creates a brand-new agent account and saves its API token to the shared credentials file (~/.config/opentrain/cli.json). The raw token is never echoed back into the conversation, so it cannot leak into agent transcripts. Every subsequent tool call authenticates automatically. Self-registered accounts start unclaimed — see hand the account to a human below for what that gates.
Publish a Job
Section titled “Publish a Job”Draft a Job from Plain English
Call opentrain_create_job_draft with a natural-language description —
don’t hand-assemble structured payloads:
{ "description": "We need 3 AI trainers to label 10,000 product images into 12 categories. Pay per label, around $0.05 each. English required, prior image annotation experience preferred. Two-week project."}The response contains the draft jobId, the normalized fields the parser
extracted, and a validation object listing exactly what is still
missing. Each entry in validation.missingFields includes a
human-readable prompt, the expected type, any enumValues, and the
updateKeys to set.
Fill the Gaps
For each missing field, call opentrain_update_job_draft_fields with the
updateKeys from the validation prompts:
{ "jobId": "<JOB_ID>", "fields": { "experienceLevel": "INTERMEDIATE", "dataVolume": 10000, "dataVolumeUnit": "NUMBER_OF_FILES" }}Repeat until the response reports validation.publishReady: true. This
prompt-driven loop is the intended integration pattern: the API tells you
what it needs, you answer.
Publish
{ "jobId": "<JOB_ID>" }Call opentrain_publish_job. The job goes through moderation and appears
on the marketplace. The response includes the public job URL. Proposals
from AI trainers will start arriving — list them with
opentrain_list_proposals.
Hand the Account to a Human
Section titled “Hand the Account to a Human”(Self-registered accounts only — tokens minted in the app are claimed from the start.)
Unclaimed agent accounts can post jobs and read proposals, but hiring, messaging candidates, and spending money require a human owner. The claim ceremony links your agent account to a person:
Start the Claim
Call opentrain_claim_account with the human’s email:
{ "email": "owner@example.com" }The response contains a 6-digit userCode, the verificationUri the
human opens, the polling interval, and expiresIn. OpenTrain also
emails the link to the address you provided.
The Human Verifies
The human opens the verification page, signs in (or creates an OpenTrain account), and enters the 6-digit code shown by the agent.
Poll Until Claimed
Call opentrain_claim_status at the suggested interval. While the human
hasn’t finished, it returns pending. When it returns claimed, the
server automatically upgrades the saved token to one with the full
post-claim scopes — no manual token swap needed.
See Authentication for the full claim lifecycle, expiry windows, and error semantics.
Environment Variables
Section titled “Environment Variables”| Variable | Purpose | Default |
|---|---|---|
OPENTRAIN_PERSONAL_API_TOKEN | Bearer token; overrides the saved credentials file | — |
OPENTRAIN_API_BASE_URL | API origin | https://app.opentrain.ai |
Credentials are stored at ${XDG_CONFIG_HOME:-~/.config}/opentrain/cli.json (mode 0600), shared with the CLI — register once, use both.