@opentrain-ai/mcp
v0.2.2
Published
OpenTrain MCP server: gives MCP-capable agents tools to register an OpenTrain account, draft and publish jobs, review proposals, hire freelancers, manage contracts and milestones, send messages, poll updates or register webhooks, and manage credits and te
Maintainers
Readme
OpenTrain MCP
MCP server for OpenTrain public API workflows: agent registration, job posting, proposal review, hiring, contracts and milestones, messaging, credits, webhooks, and team management.
Money never moves from this server: hire, milestone funding/approval, and
contract-end requests record a pending approval and return an approvalUrl
that a signed-in human must open and confirm in the OpenTrain app.
Install
Add to any MCP-capable client (Claude Code, Claude Desktop, Cursor, etc.):
{
"mcpServers": {
"opentrain": {
"command": "npx",
"args": ["-y", "@opentrain-ai/mcp"]
}
}
}With Claude Code:
claude mcp add opentrain -- npx -y @opentrain-ai/mcpNo credentials are needed to start — call opentrain_register_agent to create
an agent account on the fly.
Authentication
The server starts without any credentials. Token resolution order:
OPENTRAIN_PERSONAL_API_TOKENenv var (wins outright when set)- The shared OpenTrain config file
${XDG_CONFIG_HOME:-~/.config}/opentrain/cli.json— the same file the OpenTrain CLI writes, so registering through either surface makes the credentials available to both - No token — only the onboarding tools work until
opentrain_register_agentis called
Environment
OPENTRAIN_API_BASE_URL- Base URL for the OpenTrain app/API. Defaults to
https://app.opentrain.ai. - Example local development value:
http://127.0.0.1:3000.
- Base URL for the OpenTrain app/API. Defaults to
OPENTRAIN_PERSONAL_API_TOKEN(optional)- Personal OpenTrain API token (
ot_pat_…). Optional: without it the server falls back to saved credentials or tokenless onboarding.
- Personal OpenTrain API token (
Tools
Onboarding (no token needed):
opentrain_register_agent- Registers a brand-new anonymous agent account via
POST /api/agent/identity. - Persists the token + claim token to the shared config file (mode 0600); raw secrets are not echoed in tool output.
- Refuses to overwrite existing credentials unless
force: true.
- Registers a brand-new anonymous agent account via
opentrain_claim_account- Emails the human owner a claim invite via
POST /api/agent/identity/claim. - Returns the verification URI + user code to relay to the human.
- Emails the human owner a claim invite via
opentrain_claim_status- Polls
POST /api/agent/oauth/token(claim grant). Honorsauthorization_pending/slow_down; on success upgrades and saves the claimed token.
- Polls
Job posting:
opentrain_create_job_draft- Primary workflow: send a full plain-text
jobDescription(or a supportedcanonicalJob/importPayload); OpenTrain parses it server-side. - Returns validation state; each missing field carries an "ask:" question to relay to the human plus the field name(s) to set.
- Primary workflow: send a full plain-text
opentrain_update_job_draft_fields- Patches draft fields by name (the gap-filling step after asking the human).
opentrain_publish_job- Publishes a publish-ready draft live (same validation + moderation pipeline as the in-app flow; per-account daily limits).
Proposals and hiring:
opentrain_list_jobs— own jobs with status filter + pagination.opentrain_list_proposals— candidates for a job with bid/status/AI-interview and match-score signals (the hire-decision surface).opentrain_get_proposal— full candidate evaluation: bid, AI-interview score- summary, location/identity verification, Open Label assessment, and
contract state. Pass
includeInterview: truefor the sanitized AI-interview transcript.
- summary, location/identity verification, Open Label assessment, and
contract state. Pass
opentrain_get_freelancer_profile— masked freelancer profile by id or slug: skills, stats, work/label experience, education, reviews, languages. Names stay masked and personal contact details are never returned.opentrain_invite_freelancer— invite a freelancer to a published job.opentrain_hire_proposal— request a hire with a first escrow milestone. Does NOT hire or move money: records a pending approval and returns anapprovalUrla signed-in human must confirm in the OpenTrain app (~72h expiry). Requires a claimed account + payment method or covering credit balance.opentrain_start_proposal_conversation— open the pre-hire DM thread for a proposal so messages can flow before hiring.
Jobs (beyond drafting):
opentrain_search_jobs— public marketplace search (no token needed).opentrain_update_published_job— patch fields on a live job.opentrain_close_job— close a published job to new proposals.
Contracts and milestones (co-signed money movement):
opentrain_list_contracts/opentrain_get_contract— contract status, milestones with funding/approval state, budget consumption, and the post-hire job DM conversationId.opentrain_create_milestone— add an unfunded milestone directly.opentrain_request_milestone_funding/opentrain_request_milestone_approval— record a pending approval and return anapprovalUrl; a signed-in human confirms in the OpenTrain app before any money is held or released.opentrain_end_contract— direct when no funded milestones exist, otherwise returns an approval the human must confirm.opentrain_get_approval— re-check a pending approval's status.
Updates feed and webhooks:
opentrain_poll_updates— cursor-based delta feed of account events (new proposals, messages, contract/milestone changes, approval confirmations, budget state changes). PersistnextCursorbetween polls.opentrain_create_webhook/opentrain_list_webhooks/opentrain_get_webhook/opentrain_delete_webhook— signed HMAC push deliveries of the same events instead of polling. The signing secret is shown once at creation.
Credits (prepaid balance):
opentrain_get_credits— available/reserved balance.opentrain_create_credit_top_up— returns a Stripe Checkout URL a human completes; the agent cannot pay.opentrain_get_credit_top_up— top-up status.opentrain_list_credit_ledger— append-only ledger entries.
Messaging and payments:
opentrain_read_messages— omitconversationIdto list conversation summaries; provide it to read messages. Read-only.opentrain_send_message— send a message in a conversation the token owner participates in (claimed accounts only).opentrain_list_pending_payments— pending funding/payout state, no payment execution controls.
Team:
opentrain_get_team— organization, members, invites.opentrain_invite_team_member— invite a human teammate by email (claimed accounts only).
Account and discovery:
opentrain_auth_status— callsGET /api/public/v1/auth/me, returns the resolved token owner + scopes.opentrain_capabilities— feature/scope map for the current token: which tool families are enabled for this account.opentrain_list_tokens/opentrain_revoke_token— manage the account's API tokens.
Local smoke
Start the app locally, then run the MCP server over stdio (no token needed):
OPENTRAIN_API_BASE_URL=http://127.0.0.1:3000 \
npx -y [email protected] packages/opentrain-mcp/src/index.tsExample zero-to-registered probe:
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"1.0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"opentrain_register_agent","arguments":{"agentName":"Local Smoke Agent"}}}' \
'{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"opentrain_auth_status","arguments":{}}}' \
| OPENTRAIN_API_BASE_URL=http://127.0.0.1:3000 npx -y [email protected] packages/opentrain-mcp/src/index.tsExample primary job-draft call (uses saved or env credentials):
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"1.0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"opentrain_create_job_draft","arguments":{"title":"Image Annotation Specialist","jobDescription":"We need experienced image annotation specialists to draw bounding boxes around retail products in catalog photos. The dataset has about 1,200 JPG files. Contributors should have prior image-labeling QA experience, write short edge-case notes, and report daily throughput. Pay is $25 per hour.","externalId":"catalog-boxes-001","idempotencyKey":"catalog-boxes-001-local-smoke"}}}' \
| OPENTRAIN_API_BASE_URL=http://127.0.0.1:3000 npx -y [email protected] packages/opentrain-mcp/src/index.ts