npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@opentrain-ai/mcp

v0.49.0

Published

OpenTrain MCP server for agent-first LMS retraining, adaptive job Task Checklist authoring, employer-only Reviewer Feedback review/triage/access/settings, jobs, people, work, messaging, payments, and Instructions.

Readme

OpenTrain MCP

MCP server for OpenTrain public API workflows: agent registration, job posting, proposal review, hiring, contracts and milestones, messaging, credits, webhooks, team management, and the canonical rich instructions attached to real jobs. It also exposes Project To-dos, quizzes, and the complete Training/LMS lifecycle over the same canonical records used by the OpenTrain dashboard and public API.

Money never moves from this server. Ordinary hire, milestone funding/approval, and contract-end requests record a pending approval for a signed-in human. The separate default-off admin-balance tools only write $0 internal-funding markers after the server independently verifies every canonical OpenTrain-admin gate; they never expose payout release, which remains human-authorized.

Restricted admin-balance milestone cancellation (0.27.3)

opentrain_cancel_admin_balance_milestone cancels one eligible ADMIN_BALANCE-funded milestone for a verified canonical platform admin. It requires contractId, milestoneId, and a stable idempotencyKey; set notifyCounterparty: true only when a notification is wanted. The strict response always reports fundingDisposition: 'NO_MONEY_MOVED' and moneyMoved: false: no Stripe refund is created and payout release remains human-only. Card- and credit-funded milestones are refused with a typed human approval requirement. Reusing the same key and payload replays the durable result. This tool requires MCP 0.27.3 and the matching serving API.

Install

Add to any MCP-capable client (Claude Code, Claude Desktop, Cursor, etc.):

{
  "mcpServers": {
    "opentrain": {
      "command": "npx",
      "args": ["-y", "@opentrain-ai/mcp@latest"]
    }
  }
}

With Claude Code:

claude mcp add opentrain -- npx -y @opentrain-ai/mcp@latest

When running from a monorepo checkout that already has an @opentrain-ai/mcp workspace, include @latest so npm resolves the published package instead of an unbuilt local workspace.

No credentials are needed to start. For an existing account, use the browser login flow below when the server rollout is enabled. opentrain_register_agent creates a new anonymous account; it is not a login fallback for an existing user.

ChatGPT / Hosted MCP

The npm package above is a local stdio server. For ChatGPT developer mode, the OpenAI API Playground, or MCP Inspector, use the hosted HTTPS MCP endpoint:

https://app.opentrain.ai/mcp

The hosted endpoint exposes the parity-matched remote-safe tool set:

  • opentrain_search_jobs and opentrain_get_job — anonymous public job search and job detail.
  • opentrain_auth_status — protected token/account check.
  • opentrain_create_admin_balance_milestone and opentrain_fund_admin_balance_milestone — restricted canonical-admin-only, request-idempotent creation or in-place internal funding. Hourly/per-label creation accepts or derives volume; in-place funding requires an existing eligible NOT_FUNDED milestone. Both move $0 and create no Stripe charge or PaymentIntent. Scope possession alone is never authority.
  • opentrain_create_job_draft and opentrain_update_job_draft_fields — protected draft workflow tools.
  • opentrain_job_instructions_* — protected reads, no-write previews, image uploads, and confirmed writes against a real job's Instructions tab.
  • Project To-do and quiz tools (opentrain_list_project_todos, opentrain_create_project_todo, opentrain_set_project_todo_future_assignment, opentrain_assign_project_todo_quiz, …) — explicit-audience authoring, request-bound preflight, provider-aware assignment, future-hire policy, results, grading, release, and retakes. opentrain_manage_project_todo_quiz action form_patch_draft changes single draft questions (ordered add / update / remove / move operations keyed by stable question ids) at expectedRevision and returns the new revision and the structural diff.
  • opentrain_export_project_todos_csv — one job's Project To-do assignment CSV (formula-neutralized, worker_email blank). The export is one response with no row cap. delivery: inline (default) returns the CSV in structuredContent. delivery: resource returns only a receipt (rowCount, asOf, filename, redactions, contentType, byteSize, sha256, resourceUri) plus a resource_link. The result schema is closed, one strict variant per delivery, and checked before return: a route body with an undocumented or a missing field is a tool error. Read opentrain://jobs/{jobId}/project-todos/export/csv for the bytes: the route's csv byte for byte, with _meta {rowCount, asOf, byteSize, sha256}. A read re-fetches the live export under your own credential (no snapshot), so a different hash means the rows changed. Both deliveries are bounded by the export route's response, which the hosting platform caps at about 4.5 MB of JSON (HTTP 413 above it); the resource's own 20 MiB ceiling (PROJECT_TODOS_EXPORT_RESOURCE_TOO_LARGE) is not reached in practice. Receipt + read is larger than the inline result; use resource when you need only the receipt or your host keeps resource bytes out of your context.
  • opentrain_read_project_todo_quizzes — job-local quiz reads (forms, form, results, attempt, roster, export-csv). delivery: inline (default) returns the route body in structuredContent. Only resource=attempt and resource=export-csv accept delivery: resource; any other resource refuses delivery. resource returns only a receipt plus a resource_link: for an attempt attemptId, formId, jobId, answerCount, expectedAnswerCount; for the export jobId, formId, formVersionId, filename, rowCount, redactions; for both delivery, resourceUri, contentType, byteSize, sha256. Read opentrain://project-todos/quizzes/attempts/{attemptId} for the attempt as compact JSON, or opentrain://jobs/{jobId}/project-todos/quizzes/forms/{formId}/results/csv{?formVersionId} for the route's csv byte for byte. _meta carries the counts, byteSize and sha256. A read re-fetches the live data under your own credential (no snapshot). A receipt or read whose response names a different attempt, job or form fails closed. The attempt body is checked against one closed schema for either delivery and for the read: a field the contract does not name is an error, and no attempt bytes leave. The forms, form, results and roster bodies are closed and checked the same way. Bounded by the route's response (about 4.5 MB of JSON); the 20 MiB ceiling (PROJECT_TODO_QUIZ_RESOURCE_TOO_LARGE) is not reached in practice. On the hosted service an attempt resource read carries the JSON as an escaped string, so it reaches that cap at a somewhat smaller attempt than the route response does.
  • Selective coaching tools (DEV-2741, action-specific): employer opentrain_quiz_coaching_queue|state|cycles|threads|comments reads, keyed opentrain_quiz_coaching_comment|redo_selection|cancel_draft| resolve_thread|reopen_thread|accept|send_back_confirm writes, the no-write read-scoped opentrain_quiz_coaching_send_back_plan + opentrain_quiz_retake_plan previews, keyed opentrain_quiz_retake_apply. These are employer tools; freelancer API keys cannot read, answer, or submit quizzes. Answer keys and worker personal data never appear.
  • Freelancer API keys are read-only: messages:read is their only private scope, and public job search needs no scope. Message sends and all other mutations remain unavailable.
  • Coaching C4 tools add ungated capability discovery, bounded exports, deterministic queue filters, and private feedback-image prepare/finalize/status/delivery. Delivery returns a short-lived MCP resource_link for agent visual inspection while structured content stays free of the signed URL; image bytes are never accepted as base64 tool arguments. Stdio alone adds a local-file upload convenience over the same canonical prepare/finalize operations.
  • Quiz authoring images (DEV-2678): opentrain_quiz_form_image_prepare, opentrain_quiz_form_image_finalize and opentrain_quiz_form_images_list (same closed contract on hosted MCP) upload a private image for a job-scoped quiz form; stdio adds the local-file one-shot opentrain_quiz_form_image_upload. Finalize returns imageNode: put it into a question's rich content in the draft with alt text or decorative: true. No base64, no storage path, no delivery URL.
  • opentrain_lms_* — course authoring, assessments, private assets, immutable publishing, job linking, Training activation, assignment, review, and hosted visual proof. opentrain_lms_render_preview and opentrain_lms_step_preview return revision-bound PNG/ARIA/diagnostics evidence; verified bounded PNGs may be inline image blocks and otherwise degrade honestly to short-lived resource links. Preview-link tools mint, inspect, list, and revoke navigation-only signed-in employer review links. opentrain_lms_get_preview_audit_plan and opentrain_lms_capture_preview_audit_target let an agent resumably inspect every pinned lesson in canonical order through that same worker renderer. Canonical course trees may persist an advisory authoring intent used by validation and Preview defaults while assignments remain authoritative. opentrain_lms_retraining_scaffold_case turns one DRAFT retraining case into deterministic employer-private authoring guidance and ordered existing operations with strictly zero course, assessment, Preview, assignment, Project To-do, notification, or attempt writes.
  • opentrain_agreements_* — OpenTrain Agreements documents: list/get, create, PDF upload prepare/finalize (one-time signed PUT flagged sensitive), field placement, handle-only page previews, and confirmed publish (see "OpenTrain Agreements documents" below).
  • opentrain_job_checklists_* — adaptive job Task Checklist authoring with full web-builder parity: atomic create, CAS drafts, exact-rule no-write validate/resolve, confirmed publish, versions, submissions, reorder, the worker-visibility toggle, and stateless browser preview grants.
  • opentrain_job_feedback_* — employer-only Reviewer Feedback: list/search, detail + event history, summaries, subject-roster discovery, submit, CAS-fenced triage, subject linking, reviewer access, and the confirmed per-job toggle. Subjects never read feedback through any agent surface.
  • opentrain_people_table_* — a job's People table: describe, query rows, columns, cells, saved views and the changes feed (no export). Names are masked, contact, financial and compliance columns are redacted, and only employer custom columns are written.

Public search works without linking. Account-specific tools require OpenTrain bearer-token auth and return MCP OAuth challenges when called unauthenticated. The local stdio package remains the full self-registration flow because it can store the generated ot_pat_ token in the user's local ~/.config/opentrain/cli.json without exposing secrets in tool output.

Reusable private video library

MCP 0.11+ exposes eleven opentrain_video_library_* tools with parity across stdio and hosted MCP: list/get, upload prepare/status/cancel, draft Instructions/LMS reference attach/detach, MP4 download prepare/status/grant, and playback metadata. Hosted MCP accepts metadata only—never local paths or video bytes. Download grants require the explicitly minted videos:download scope.

For optional stdio file transfer, set readable upload roots with the platform path delimiter (colon on Linux/macOS):

export OPENTRAIN_MCP_VIDEO_UPLOAD_ROOTS="/approved/uploads:/another/read-root"
export OPENTRAIN_MCP_VIDEO_DOWNLOAD_DIR="/approved/downloads"

The download setting is one writable directory, not a root list. Canonical realpath and no-follow checks reject traversal and symlink escapes. Reference tools atomically mutate canonical Instructions/LMS draft content and placement metadata; they never publish immutable worker-visible pins.

OpenTrain Agreements documents (Unreleased)

Eight opentrain_agreements_* tools cover the agreements document operations on stdio (the hosted MCP exposes the same names): tool name = opentrain_ + the registry operation id with dots replaced by underscores.

| Tool | Operation | REST | | ------------------------------------------------ | -------------------------------------- | ------------------------------------------------- | | opentrain_agreements_documents_list | agreements.documents.list | GET /agreements/documents | | opentrain_agreements_documents_get | agreements.documents.get | GET /agreements/documents/{documentId} | | opentrain_agreements_documents_create | agreements.documents.create | POST /agreements/documents | | opentrain_agreements_documents_upload_prepare | agreements.documents.upload_prepare | POST /agreements/documents/uploads/prepare | | opentrain_agreements_documents_upload_finalize | agreements.documents.upload_finalize | POST /agreements/documents/uploads/finalize | | opentrain_agreements_fields_set | agreements.fields.set | PUT /agreements/documents/{documentId}/fields | | opentrain_agreements_preview | agreements.preview | GET /agreements/documents/{documentId}/preview | | opentrain_agreements_versions_publish | agreements.versions.publish | POST /agreements/documents/{documentId}/publish |

Reads need agreements:read; mutations need agreements:write plus an idempotencyKey (sent as Idempotency-Key; a replay returns the stored outcome with replayed: true). The family is default-off (AGENT_SURFACE_AGREEMENTS_ENABLED) and rollout-gated (agreements_native). Inputs and structuredContent.result are the closed contract shapes, validated before any request and on every response. Failures are isError text carrying the HTTP status, code, details.reason (for example REVISION_CONFLICT, UPLOAD_INCOMPLETE, PUBLISH_WARNINGS_UNWAIVED) and request id, with URLs and tokens redacted.

  • Upload is prepare → signed PUT → finalize. The prepare result carries the one-time PUT URL in structuredContent.result.upload.url, flagged by _meta["opentrain/sensitive"] = { paths: ["result.upload.url"], handling } (dot paths inside structuredContent; the hosted MCP uses the same key and shape). Use it once; never log, persist or echo it. It never appears in the text content or in errors. This server never carries PDF bytes.
  • Previews return short-lived resource handles only, never image bytes. Save the PNGs with opentrain agreements preview --out <dir> or an authenticated GET /api/public/v1/agreements/resources/{id}.
  • Publishing freezes an immutable version and requires confirmLive: true; it is refused before any request otherwise (CONFIRMATION_REQUIRED).

Shared folder Instructions (0.27.0+)

Contract tools negotiate the additive dashboardUrl field with X-OpenTrain-Features: contract-dashboard-url-v1; clients may omit the header for the legacy response shape. The MCP client sends this header automatically.

Both stdio and hosted MCP expose the same eight migration operations: opentrain_inspect_folder_instructions, opentrain_preview_folder_instruction_change, opentrain_confirm_folder_instruction_change, opentrain_get_folder_instruction_change, opentrain_apply_folder_instruction_change, opentrain_cancel_folder_instruction_change, opentrain_resume_folder_instruction_change and opentrain_export_folder_instruction_recovery.

Another 25 opentrain_folder_instructions_* tools cover shared canonical page/tree, preview/preflight, history, schema, link, verify and image/video authoring. Discover their closed schemas and per-operation opentrain.ai/authoring-retry metadata rather than assuming every write retries the same way. All require current folder-employer authority and the existing Instructions scopes. Existing job tools remain unchanged.

Preview/status/recovery are read-only. Confirmation binds the reviewed digest and freezes writers; apply waits for drain, preserves originals and commits verified content atomically. Inspect the same operation after uncertainty and require VERIFIED_READBACK. First activation must use this reviewed workflow; ordinary authoring cannot activate an empty folder. Incompatible published-mode folder writes refuse without enabling release/read/ack features. Shared content is visible to all eligible child-job workers; language labels are not access controls. See the folder workflow.

Authentication

Browser login (0.27.0+, rollout-gated)

MCP 0.27.0+ includes opentrain_auth_login_start and opentrain_auth_login_status in the local stdio server. The server migration and agent_browser_login rollout must be delivered before login can succeed. A disabled rollout returns a refusal, not a new account. Package publication does not enable the separate browser-login rollout.

  1. Call opentrain_auth_login_start with an optional deviceLabel, lane (EMPLOYER or WORKER) and space-separated scope request.
  2. Give the returned verificationUriComplete and userCode to the person. They open normal OpenTrain in any browser, match the code, sign in, and explicitly approve their identity/context and permissions. Do not request their password, browser cookie, polling secret or API key.
  3. Resume opentrain_auth_login_status with the same loginId and optional waitSeconds (0–120). Honor intervalSeconds. PENDING, SLOW_DOWN and TIMEOUT preserve the handle; DENIED and EXPIRED are terminal.
  4. After approval, call opentrain_auth_status to check the actual credential source and account. An environment key can shadow the saved browser session. While no credential is configured, opentrain_auth_status also reports an unexpired sign-in started on this machine for this origin (pendingLogin { loginId, expiresAt } plus instructions) so the client finishes it with opentrain_auth_login_status instead of starting another. It only reads the local pending-login file: no poll, no write, and never the polling secret.

The CLI and stdio server share one private local credential provider. A long-lived stdio process picks up a login or access-token rotation without a restart; its configured origin still has to match the session issuer. The CLI can also start/resume the same login and revoke it with opentrain auth logout. Browser logout preserves an unrelated saved key and never revokes an environment key. Pending polling secrets and access/refresh tokens never enter MCP output. The headless-host store uses 0700 directories and 0600 atomic files with a shared cross-process refresh lock; it is not an OS keychain and does not protect against arbitrary code running as the same OS user. Never share the profile directory.

Hosted MCP browser consent (rollout-gated)

The device flow above is for local stdio MCP. Hosted clients use their own HTTP OAuth authorization-code flow with PKCE S256 and resource https://app.opentrain.ai/mcp. They open normal OpenTrain sign-in and explicit consent; opening the link alone does not grant access. Do not forward a hosted MCP access token to the public REST API or ask a user to paste browser cookies.

This source supports HTTPS client-ID metadata documents with validated exact client IDs and registered redirects. Non-URL client IDs require an exact operator registration; an arbitrary client name is not a registration. The server validates metadata through bounded, DNS-pinned HTTPS requests. Discovery and consent preserve opaque state and return the matching authorization-server issuer. This is not a claim that every external client/version has passed testing.

Turning off agent_browser_login refuses new device and hosted login requests. It does not mass-revoke existing sessions or disable API keys; already-issued legacy authorization codes retain their exchange path. Missing/expired credentials and structured scope shortages may require reauthorization. A disabled feature, wrong organization, or other permission denial is a tool error, not a reason to loop through login. Never automatically replay an uncertain mutation after login.

Employer and freelancer Settings expose Connected agents alongside API keys. Users can inspect and explicitly revoke only their own connections, including CLI, local MCP and hosted clients. A failed inventory read is shown as unavailable with a read-only retry, not as an empty list. Final server/migration rollout, browser role tests, and actual hosted-client interoperability remain release gates. Hosted-client compatibility must be verified for the actual connecting product and version; successful local stdio login is not proof that a hosted OAuth client supports the same flow.

Credential precedence and API-key compatibility

The server starts without any credentials. Resolution order:

  1. OPENTRAIN_PERSONAL_API_TOKEN env var (wins outright when set)
  2. A saved browser session in the shared OpenTrain profile ${XDG_CONFIG_HOME:-~/.config}/opentrain/cli.json
  3. The saved static API key in that profile
  4. No credential — explicit browser-login and new-account onboarding remain available; authenticated operations refuse without creating an account

For an existing employer account, create a personal API token from Employer Settings -> Developer -> API keys and provide it as OPENTRAIN_PERSONAL_API_TOKEN or save it with opentrain auth login --api-key .... Static keys remain supported for CI and existing integrations. Browser login preserves each lane's canonical permissions; it does not make freelancer access writable or bypass restricted platform-admin eligibility and human payment approval.

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.
  • OPENTRAIN_PERSONAL_API_TOKEN (optional)
    • Personal OpenTrain API token (ot_pat_…). Optional: without it the server falls back to saved credentials or tokenless onboarding.

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.
  • 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.
  • opentrain_claim_status
    • Polls POST /api/agent/oauth/token (claim grant). Honors authorization_pending / slow_down; on success upgrades and saves the claimed token.

Shared job operations — Work Catalog, coordination modes, external attestations (0.23.0+, DEV-3191):

  • opentrain_list_job_context_work_definitions / opentrain_get_job_context_work_definition / opentrain_list_job_context_work_executions and the opentrain_*_job_context_work_* mutations — the dynamic per-job Work Catalog. Work is PER-JOB catalog data, never a platform enum; every covered response's sync.workCatalog teaches the catalog head/status, the winner-only setup lease, pending human approvals, and this job's work-coordination mode. Definition-bound mutations present the FULL binding (versionNumber + contentHash + coordinationSignature); every execution mints ONE coordinating action (the single claim authority).
  • sync.workCatalog.coordination.mode is the singleton typed policy WORK_COORDINATION_MODE (recorded only by a non-agent human job manager via opentrain_record_job_context_policy): OPEN (default when no row exists), COORDINATED (every guarded mutation — e.g. opentrain_send_managed_job_message — must present a claimed action bound to an OPEN work execution, defined or provisional), MANAGED (that execution must be DEFINED work under an ACTIVE definition). A null mode is fail-closed, never OPEN. A refused guarded mutation surfaces the closed 409 details {reason: JOB_OPS_WORK_COORDINATION_REQUIRED, requirement, mode} in the tool error text: begin defined/provisional work, claim the coordinating action it mints, retry.
  • opentrain_record_job_context_observation accepts a top-level externalAttestation (ATTEST: bounded per-job source.system slug, optional locator/subject, claim, non-future attestedAt, REQUIRED expiresAt ≤ 30 days, optional supersedesObservationId; INVALIDATE: invalidatesObservationId, invalidationSource WEBHOOK|UI|AGENT|HUMAN, reason, invalidatedAt) with authority OBSERVED, plus a top-level actorAgentLabel stored canonically as createdByAgentText (a nested label is refused). The server proves the same-context lineage before writing (readable non-future target, same source + subject, one live ender per target, ONE current head per source + subject). The guide (opentrain_get_job_context_guide / resource opentrain://jobs/{jobId}/operations/guide) carries externalCoverage: everything not CURRENTLY attested is UNKNOWN; each entry carries status, canonical attribution, bounded evidence, and the ending receipt.

Job posting:

  • opentrain_create_job_draft
    • Primary workflow: send a full plain-text jobDescription (or a supported canonicalJob / 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.
  • opentrain_update_job_draft_fields
    • Patches draft fields by name (the gap-filling step after asking the human).
  • opentrain_discard_job_draft
    • Deletes a never-published draft (no proposals, in no folder) so it leaves the job list. Organization owners only; requires confirm: true; published jobs use opentrain_close_job.
  • 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: true for the sanitized AI-interview transcript.
  • 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. Emails, phone numbers and links in employer review comments come back as [REDACTED_*] placeholders, recorded in redactions with source EMPLOYER_REVIEW (DEV-3129); the agency website stays as a public business field.
  • opentrain_get_candidate_dossier — privacy-safe, viewer-scoped candidate dossier for a proposal (masked profile, verification verdicts incl. identity assurance, factual engagement disposition, review/contract roll-ups). Optional strict evidence: "full" adds ten bounded metadata-only evidence families (25-item caps, truthful truncation, typed continuation). Both the input and the response are validated against the exact closed contract schema — a server/tool version mismatch fails as a typed error telling you to upgrade this package, never as silently forwarded unvalidated data. Lockstep rule: every server-side addition to the dossier response ships with a same-batch schema update and release of this package, so an unknown field always means "upgrade", never "pass it through".
  • opentrain_get_candidate_dossier_resume_link — audited LINK-ONLY resume access (DEV-2977 B3.5): a fresh 600-second signed URL when AVAILABLE, or a truthful typed unavailable state. structuredContent IS the raw five-variant {url, expiresAt, availability, reason, provenanceStatus, provenance} response object — no {apiBaseUrl, result} envelope (hosted-MCP parity). Requires BOTH candidate_dossier:read AND candidate_documents:read; every admitted access is audited append-only BEFORE the URL is disclosed; the tool never follows redirects or fetches bytes, and the response is runtime-validated against the exact closed five-variant machine — an AVAILABLE url must be an absolute http(s) URL with no embedded credentials and the expiry a calendar-valid RFC3339 date-time (mismatches are typed upgrade errors). Denials preserve the server's bounded error code, typed reason (e.g. SELF_ACCESS_NOT_SUPPORTED), and request id. Since 0.22.0 (DEV-3024) the response is the five-variant provenance union: AVAILABLE carries provenanceStatus: "AVAILABLE" plus a provenance object observed at issuance (sanitized original file name, allowlisted MIME type, byte size, upload/modified instants, observedAt, an opaque storageEtag that is NOT a checksum, and checksum reserved for an authoritative SHA-256 — null today) or provenanceStatus: "UNAVAILABLE" with provenance: null; every unavailable state carries NOT_APPLICABLE + null. Provenance is an observation, never a binding on the bytes a later download returns.
  • opentrain_list_candidate_dossier_applications — PLATFORM-ADMIN ONLY platform-wide application history for one candidate user id (DEV-2887): PROPOSAL and INVITE rows counted SEPARATELY, exact all-row counts (proposals, invites, distinct jobs, distinct organizations, contracts resulted), a proposal velocity summary, rate-integrity bid statuses, raw outcome flags, and exact offer-linked contract results. Requires candidate_dossier:read plus the named canonical-admin exception; ordinary employers receive the uniform not-found and candidate self a typed SELF_ACCESS_NOT_SUPPORTED denial. nextCursor is bound to the candidate and the ORIGINAL asOf. structuredContent IS the raw validated page.
  • opentrain_list_job_invitations / opentrain_get_job_invitation — canonical invitation state for an owned job (DEV-2846, proposals:read + the hiring feature, inside the default-off proposal_management family — AGENT_SURFACE_PROPOSAL_MANAGEMENT_ENABLED): an invitation a newer one replaced reads EXPIRED with no linkedProposalId (DEV-3285); any other reads HIRED > APPLIED > DECLINED > EXPIRED > INVITED (EXPIRED once the job closes or 30 days after sending, expiresAt on every row), hireAcceptancePending only for a REAL live hire authorization, masked identity, hidden/banned/closed candidates withheld from pages AND totalCount, filters applied before the exact count and keyset cursor; the lookup reads the uniform { invited: false, invitation: null } for unknown, hidden, and never-invited candidates alike. structuredContent IS the raw validated page/lookup.
  • opentrain_list_candidate_dossier_reviews / opentrain_list_candidate_dossier_contract_history — cursor-paged full lists behind the dossier's bounded previews (a non-null nextCursor means more pages; nothing truncates silently). The reviews page redacts contact details and links in employer review comments and lists them as PRIVACY_MASKED redactions (DEV-3129).
  • opentrain_get_participant_work_email — audited managed-work-email read (DEV-3031 B3.6): the canonical @opentrain.work primary address for a participant you manage through EXACTLY ONE of {contractId}, {proposalId}, or {jobId, personUserId} (a bare user id is never accepted; strict own-key input — mixed/unknown keys fail with zero network). structuredContent IS the raw closed eight-state response — no envelope. ONLY ACTIVE carries an address (normalized lowercase, exactly under opentrain.work); the personal signup/login email is NEVER returned, denial text is a bounded projection that never echoes server error text, and every authenticated attempt is audited append-only BEFORE any address is disclosed. Requires the dedicated participant_work_email:read scope.
  • 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 an approvalUrl a 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 job search (no token sent): q, category, domain, language, country, payType, limit (1–25, default 10) and cursor; closed { jobs, nextCursor, generatedAt }.
  • opentrain_get_job — one public job by id or canonical job url (no token sent); { id, status: "closed" } for a closed, private or unknown job.
  • opentrain_update_published_job — patch fields on a live job.
  • opentrain_close_job — close a published job to new proposals.
  • opentrain_discard_job_draft — delete a never-published draft.

Contracts and milestones (co-signed money movement):

  • opentrain_get_contract_history — DEV-2830 canonical engagement history for EXACTLY one contractId or proposalId (view current | timeline): proposal → contract(s) → milestones/payouts. current.access derives only from participationState ACTIVE/REACTIVATED (ACTIVE | NONE | CONFLICT with every such contract listed — nothing is picked silently; the proposal's HIRED label is never access); rehire links only from admin_balance.rehire_created audit rows; purpose only from work-project evidence (a capped/partial set stays UNSPECIFIED, evidenceTruncated); timeline only from durable stored timestamps; bounded with explicit truncated flags, no cursor; unknown/foreign/self selectors are one opaque 404. structuredContent.result is the raw closed response.
  • opentrain_list_contracts / opentrain_get_contract — contract status, milestones with funding/approval state, budget consumption, and the post-hire job DM conversationId. DEV-2839: the list is a bounded page — optional limit (1..100, server default 50) and cursor (opaque nextCursor bound to the ORIGINAL jobId/status/asOf) with truthful totalCount/hasMore/collectedCount/complete; walk pages with the cursor (no unbounded all mode). A job-scoped call without limit/cursor keeps the unchanged unpaged list. structuredContent.result is the raw page validated against the closed contract schema; a database-budget overrun is a typed retryable 503 CONTRACT_LIST_TIMEOUT.
  • opentrain_create_milestone — add an unfunded milestone directly.
  • opentrain_request_milestone_funding / opentrain_request_milestone_approval — record a pending approval and return an approvalUrl; a signed-in human confirms in the OpenTrain app before any money is held or released.
  • opentrain_end_contract — ends only after every milestone is terminal; unresolved drafts, funded/payment, review, or refund states return structured blockers with the required next action.
  • opentrain_get_approval — re-check a pending approval's status.
  • opentrain_cancel_admin_balance_milestone — cancel one eligible internally funded milestone with a keyed, no-money-moved result; notifications are opt-in and card/credit funding remains human-approved.

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). Persist nextCursor between 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 inspection (0.27.2):

  • opentrain_list_messaging_members: paginated current roster; removed history and managed work emails are explicit opt-ins.
  • opentrain_get_messaging_member: exactly one user/contract/managed-address selector and observational add/remove eligibility.
  • opentrain_list_job_conversations: separate proposal DMs, Job DMs and channels, with bounded response evidence. Follow nextCursor; updatedAfter is not a complete message-edit feed.
  • opentrain_audit_notification_emails: job-authorized observations for message IDs, bounded conversation/time range or milestone/recipient. Stored messages and SENT do not establish primary delivery. Missing evidence stays unknown; BCC counts are envelope evidence only.

All four are read-only, require messages:read and canonical access, and expose validated structuredContent plus a response_format text selector. Managed addresses also require participant_work_email:read. No read repairs or creates conversations/memberships. Strict stdio response schemas require the matching API release; published MCP 0.27.3 includes this cancellation operation and the preceding messaging batch.

Messaging and payments:

  • opentrain_read_messages — omit conversationId to 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). This generic tool is intentionally outside shared Job Operations synchronization.
  • opentrain_edit_message / opentrain_delete_message — author-only CAS mutations of a message YOU sent (correct an already-sent instruction or credential; delete is a NON-destructive tombstone — prior values survive only in the append-only server-side revision ledger). Pass expectedRevision = the message readback revision; the required idempotency key uses the canonical 1-128 [A-Za-z0-9._:-] grammar (minimum ONE char). Summaries never echo message content.
  • opentrain_get_message_attachment — retrieve one authorized attachment by the opaque attachmentId returned by message/audit/thread reads. One authenticated, audited delivery=auto request returns a verified PNG/JPEG/WebP/GIF up to 4 MiB as an MCP image block agents can inspect; everything else becomes a resource link at opentrain://messages/{messageId}/attachments/{attachmentId}. Reading that resource returns a verified blob up to 20 MiB. The server and MCP both verify identity, size, SHA-256, sniffed type, and resolved delivery; no storage path, signed URL, bucket, or credential is exposed.
  • opentrain_send_managed_job_message — the required job-manager send: uses a complete claimed-action guard and stable key, rechecks the latest message, and commits the message plus shared-context advance atomically. Requires messages:write and messages:manage.
  • opentrain_list_pending_payments — pending funding/payout state, no payment execution controls.
  • opentrain_verify_payout — retrieves current Stripe transfer state and reports reversal, identity mismatch, or disagreement with OpenTrain.
  • opentrain_preflight_payout_recovery — exhaustively searches matching amount/destination/milestone transfers and tells the operator to stop if an unreversed equivalent already exists. This is a read-only duplicate guard; it never creates or reconciles a transfer.

Team:

  • opentrain_get_team — organization, members, invites.
  • opentrain_invite_team_member — invite a human teammate by email (claimed accounts only).

Instructions (job-first tools over the one canonical source):

  • opentrain_job_instructions_inspect — the exact tree and employer URL for one job.
  • opentrain_job_instructions_capabilities — supported schema, rich nodes, limits, and guarantees.
  • opentrain_job_instructions_read_page — one rich TipTap JSON page plus its checksum.
  • opentrain_job_instructions_page_link — the actor-aware exact-page URL, with optional server-validated stable-node anchor.
  • opentrain_job_instructions_search — the employer editor's ranked full-text search (typo-tolerant fallback) over the job's effective draft scopes (own set + inherited folder set — what inspect/read_page read; never a worker's released view). Page groups with up to five block hits each: stable block ids, anchor ids for deep links, the nearest heading, inert plain-text snippets with code-point highlight ranges. truncated=true means the ranked window filled — narrow the query; hasMore/nextCursor page the ranked page groups (the cursor is bound to the job, the query and the ranked window; a foreign one, or one issued before the Instructions changed, fails with INVALID_CURSOR). Requires instructions:read.
  • opentrain_job_instructions_preview — validate and render a page without writing.
  • opentrain_job_instructions_preflight — validate and sign one exact mutation without writing.
  • opentrain_job_instructions_upload_image — upload a supported image without changing a page.
  • opentrain_job_instructions_plan_image — derive the deterministic final URL without uploading.
  • opentrain_job_instructions_create_page — idempotently create a page in the actual job tab.
  • opentrain_job_instructions_patch_page — checksum-guarded stable-node edits.
  • opentrain_job_instructions_replace_page — explicit checksum-guarded full replacement.
  • opentrain_job_instructions_update_page — rename, reparent, or reorder.
  • opentrain_job_instructions_archive_page — explicitly confirmed archival.
  • opentrain_job_instructions_preflight_tree / opentrain_job_instructions_apply_tree — validate and atomically swap a complete one-level page tree.
  • opentrain_job_instructions_verify — semantic and checksum verification of every canonical page.
  • opentrain_job_instructions_visual_review — authenticated employer/sidebar screenshot plan with an explicit worker-proof boundary.
  • opentrain_job_instructions_schema_upgrade — idempotent v1 → v2 page upgrade with a required quiescence window and canonical readback.
  • opentrain_job_instructions_youtube_node — offline normalization of a supported YouTube URL into the canonical schema-v2 node.
  • opentrain_job_instructions_release_prepare / release_preview / release_publish / release_list — immutable worker releases from the same job-owned draft, with an explicit delivery policy and audited overrides.
  • opentrain_job_instructions_history_list / history_read / history_compare — employer-only draft checkpoints per page: cursor-paged provenance list, one checkpoint's content, and the checkpoint→current (or checkpoint→checkpoint) block diff.
  • opentrain_job_instructions_history_checkpoint — explicit manual restore point, optionally receipt-tracked with an idempotency key.
  • opentrain_job_instructions_history_restore — DESTRUCTIVE replacement of live page content from a checkpoint. The schema requires literal confirmRestore: true + confirmLive: true, a fresh expectedChecksum from compare, and an idempotencyKey; the server records a durable undo baseline first and returns 409 on live drift. History payloads never expose TipTap room identifiers, and success proves storage + checksum readback only — never collaboration sync or browser rendering.

The server advertises job-tree and job-page resources under opentrain://jobs/{jobId}/instructions. Standalone workspaces, manuals, bindings, changesets, and publications were removed; they are not a second instruction source. Job pages support one subpage level. Image uploads accept JPEG, PNG, WebP, GIF, and AVIF up to 4 MB. Every draft mutation requires confirmLive: true and the signed token from its exact no-write preflight; full replacement also requires a fresh checksum and confirmReplace: true. Complete tree apply uses deterministic staging, an exact-active-set fence, one database pointer swap, and idempotent recovery so employers do not see partial page assemblies. Whether workers see a confirmed write at once or only after a separate publish is stated per read by opentrain_job_instructions_capabilities (mutations.workerVisibility: IMMEDIATE, ON_PUBLISH, or MIXED while the worker-read cutover is partially rolled out — treat a draft write as undelivered until published). Release tools return 404 for actors outside that rollout.

Content schema v2 adds details, callouts, YouTube, audio, and attachment nodes. Existing pages remain on their persisted schema until explicitly upgraded. MCP create, preview, patch, replace, tree apply, and readback operations preserve the page schema and reject v2-only nodes on v1 pages. YouTube normalization accepts supported YouTube URL forms, retains only the validated 11-character video id plus safe attributes, and renders through the privacy-enhanced player.

Training/LMS:

  • opentrain_lms_capabilities — canonical schema, content nodes, assessment settings, asset types/limits, and truthful workflow availability. It includes the shared TipTap lmsLesson profile, registry version, per-block author/edit/render support, attributes, and private-media semantics. Agents author that canonical JSON directly and must not invent HTML or an MCP-only lesson model.
  • Course and assessment tools — create/recover, read, validate, update, publish, and bind immutable assessment/course versions.
  • opentrain_lms_prepare_asset_upload / opentrain_lms_finalize_asset_upload — short-lived direct-storage grants plus server-verified checksum, length, MIME, and container finalization for large private media. Never log a grant.
  • Job Training tools — read/set Training and list/link/unlink courses. Linking, enabling, publishing, and assigning are deliberately separate operations.
  • Assignment and review tools — assign an immutable version, report progress, remind/cancel, grade, release results, decide PASS/FAIL, and return work with another attempt.
  • opentrain_lms_list_assignments — page mode (cursor + limit, default 50, max 200) returns the raw page with hasMore and nextCursor; the text says PARTIAL RESULT with the exact next cursor, complete, or INCONSISTENT PAGE (retry-only guidance). all: true collects every page (effective page size on every request, de-duplicated by assignment id, repeated-cursor safe) and returns hasMore, the page-level jobId and authorized links[], and collection {pageSize, pagesFetched, collectedCount, complete, finalCursor, stopReason, duplicatesDropped}; any page error, id-less row, job mismatch, or inconsistent page fails the whole call. Course and version reads (opentrain_lms_get_course, opentrain_lms_list_course_versions, opentrain_lms_get_course_version) carry a privacy-safe attribution block (creator, revision-bound last material updater, version author, publisher; stable ids always, display fields only for current organization identities, explicit notAvailableReason for historical gaps), and the frozen tree in opentrain_lms_get_course_version is the complete immutable inventory.
  • opentrain_lms_export_assignments — masked assignment reporting as csv, json or jsonl. delivery: inline (default) returns one bounded page (cursor + limit, max 5000). delivery: resource walks every page from cursor on and returns only a receipt (rowCount, pages, startCursor, complete from the cursor, nextCursor: null, contentType, byteSize, sha256, resourceUri) plus a resource_link; the rows never enter the result. Read opentrain://lms/jobs/{jobId}/assignments/export/{format} (or …/from/{cursor} for a tail) for the bytes — serialized exactly as the CLI's lms assignments export --output writes the file, so the hashes agree — with _meta {rowCount, pages, startCursor, complete, byteSize, sha256}. A read re-walks the live export under your own credential (the URI grants nothing): there is no snapshot, so _meta.sha256 equals the receipt's only if no row changed in between — a different hash means the rows changed; re-run the tool for a fresh receipt. The whole artifact is bounded at 20 MiB, checked after each page; the page cap (LMS_EXPORT_PAGE_CAP with resumeCursor), a repeated cursor (LMS_EXPORT_CURSOR_REPEATED), an oversized export (LMS_EXPORT_RESOURCE_TOO_LARGE) and a malformed page are typed failures with nothing delivered. Cost: the receipt is a few percent of the inline page walk, but receipt + read is larger than the walk — use resource when you need only the receipt or your host keeps resource bytes out of your context.
  • opentrain_lms_get_attempt_evidence — one assessment attempt's immutable evidence (lms:read): question snapshots, the worker's answers, closed outcomes and manual grades; never answer keys, pass thresholds or attempt policies. One attempt can pass the 25,000-token default MCP output limit (Native Forms allow 500 questions and 10,000-character prompts). delivery: inline (default) returns the evidence in structuredContent. delivery: resource returns only a receipt — the same result without questions, missedQuestionIds and unansweredQuestionIds, plus questionCount, missedQuestionCount, unansweredQuestionCount (null when NOT_SUBMITTED), delivery, resourceUri, contentType, byteSize, sha256 — and a resource_link. Read opentrain://lms/assignments/{assignmentId}/attempts/{attemptId}/evidence for the questions: the route body as compact JSON, checked against the same closed schema, with _meta {evidenceState, questionCount, byteSize, sha256}. A read re-fetches the live evidence under your own credential (no snapshot), so a new manual grade changes the hash. A receipt or read whose response names a different assignment or attempt than the one requested fails closed; nothing is delivered. Both deliveries are bounded by the route's response, which the hosting platform caps at about 4.5 MB of JSON (HTTP 413 above it); the resource's own 20 MiB ceiling (LMS_ATTEMPT_EVIDENCE_RESOURCE_TOO_LARGE) is not reached in practice.
  • opentrain_lms_get_course_answer_key — the employer-only answer key for a course (lms:read): every quiz in course order with the correct choices marked, expected values, points, and each quiz pass rule. Omit versionId for the current draft (quizzes resolved the way publishing would freeze them) or pass one published version id. Never share it with learners; the worker-facing Preview keeps hiding answer keys.

The local stdio package and hosted endpoint expose the same business actions. Local-only orchestration such as filesystem checkout/diff/reconcile remains a CLI concern; all canonical validation, revision fencing, authorization, and mutations stay on the public API.

Shared job operations (manager, MCP 0.27.3+):

Version and schema-drift diagnostics

The stdio server reports its installed package version in the MCP initialize handshake as serverInfo.version. Record that value when diagnosing a client or server mismatch; it is the version that actually handled the session, not the version a global install or lockfile happens to advertise. A bounded job-operations response-schema error also includes the installed @opentrain-ai/mcp version and tells you to upgrade and refresh any cached npx package before retrying. Do not keep retrying an unchanged malformed response.

For a fresh package check, inspect the registry version and then force a fresh one-shot package resolution:

npm view @opentrain-ai/mcp version
printf '%s\n' \\
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"version-probe","version":"1.0"}}}' \\
  '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' \\
  | npx --yes --package=@opentrain-ai/mcp@latest opentrain-mcp

The second command starts the stdio server and returns its initialize response; read serverInfo.version there. Existing MCP hosts may cache an npx package, so refresh that host/package cache after upgrading. A local handshake proves only the installed client version and protocol wiring; it is not an authenticated production-operation retest.

Mutation-tool descriptions and input schemas (MCP 0.16.0+) come from the canonical Job Operations agent-mutation catalog shared with the CLI, hosted MCP, and OpenAPI, so every surface documents the same operation with the same fields, enums, and bounds; cross-surface parity is CI-pinned.

  • opentrain_get_job_context is the MANDATORY first call before managing an existing employer job. The compact snapshot automatically carries the top-10 fresh priority attention signals with their derived claim state, signal counts, per-rule evaluator health, the effective typed policies, and the Agent Guide digest — there is no second bootstrap call. Initialize instructions teach the full context-first protocol to every connected agent — including protocol step 15: durable sync start/resume, the one Agent Guide read the bootstrap envelope directs, the exact delta read recommendation.agent_guide_changed names when the head moved (added/changed sections, removedSectionIds tombstones), acknowledging only delivered context, RECOMMENDED Playbook proposals with human publication, and per-job work types (never fixed grading/retraining enums) are AUTOMATIC; the human never needs to know to ask for the setup.
  • opentrain_list_job_context_signals / opentrain_get_job_context_signal — deterministic attention signals (SHADOW rules are excluded at the database query level; includeShadow: true is an explicit audit read).
  • opentrain_acknowledge/snooze/dismiss_job_context_signal — triage with the exact expectedSignalRevision; triage never claims work and never clears a condition (only the deterministic evaluator clears).
  • opentrain_claim_job_context_signal — the ONLY path that turns a signal into owned work; eligibility is ACTIVE + FRESH + effective OPEN/ACKNOWLEDGED, non-shadow, and the signed claimReceipt comes back with the action.
  • opentrain_get_job_context_effective_policies / opentrain_list_job_context_policy_history / opentrain_record_job_context_policy / opentrain_verify_job_context_policy_enforcement — typed, attributed, superseding durable policies with atomic WORKFLOW/CANONICAL_DB enforcement and evidence-verified EXTERNAL enforcement.
  • opentrain_get_job_context_agent_guide (MCP 0.26.0+) — the Agent Guide, the ONE operational guidance document for agents managing a job (worker-facing Job Instructions are a separate surface): the canonical typed projection plus the human-published Playbook (bounded Markdown sections with stable sectionIds and per-section SHA-256 contentHashes, playbookVersion, publisher) and the open-proposal count under one contextRevision. Bootstrap sync.nextOperations ends with job_operations.agent_guide.get; afterwards recommendation.agent_guide_changed names the exact opentrain_get_job_context_playbook_delta read (added/changed sections, removedSectionIds tombstones). Also the read-only Markdown resource opentrain://jobs/{jobId}/operations/agent-guide.
  • opentrain_get_job_context_playbook, opentrain_list_job_context_playbook_versions, opentrain_get_job_context_playbook_version, opentrain_get_job_context_playbook_delta — the published Playbook head, newest-first history, one exact version, and the exact section delta.
  • opentrain_submit_job_context_playbook_proposal, opentrain_list_job_context_playbook_proposals, opentrain_resolve_job_context_playbook_proposal — agent writes to guidance are PROPOSALS (RECOMMENDED, never enforced; basePlaybookVersion must equal the head). opentrain_publish_job_context_playbook is the HUMAN job-manager court (agent principals are refused); ACCEPT of a proposal is that same court.
  • opentrain_get_job_context_operating_guide — the canonical typed projection of the Agent Guide alone (without the Playbook; structured JSON + deterministic Markdown, guideVersion + SHA-256 checksum), kept for published clients — new work reads opentrain_get_job_context_agent_guide. The Markdown is also the read-only resource opentrain://jobs/{jobId}/operations/guide.
  • opentrain_get_job_setup (MCP 0.15.0+) — the deterministic SHARED guided-setup packet: missing operating brief/typed workflow/required operating choices with canonical evidence, ordered questions, evidence-backed proposed defaults, validated canonical write previews, and the in-progress setup.* dedupe view. While setup is incomplete every covered result's sync.recommendations carries recommendation.job_setup_incomplete, whose chain DRIVES the multi-agent flow in order: read the packet; inspect inProgress (stand down on a truncated view or a foreign ACTIVE setup.* intent / OPEN proposal); declare your own setup.* intent via opentrain_declare_job_context_intent (a DUPLICATE names the live winner — it does not transfer ownership, so the loser stands down). Prove ownership by comparing the intent's non-null sessionId with this result's non-null sync.session.sessionId and matching principalUserId; a visible winner ID is never enough. Only that same-durable-session winner presents the questions/drafts to the responsible human. Immediately before approved writes, re-read setup and prove the binding still holds; then use only the normal brief/policy tools. A null or mismatched session means establish a durable per-agent session or coordinate with the owner; verify, resolve your intent, hand off. A status of INDETERMINATE is fail-closed nonterminal evidence — follow the packet's evidenceRecovery read and retry; never prompt from it. Record an approved postponement as the component's OPERATING_RULE.setup_deferral_* typed policy; once COMPLETE or DEFERRED, stop prompting — completion is shared across the employer team.
  • Every one of these tools advertises AND runtime-validates exact closed input/output schemas; typed-policy payloads are the three closed contract-v1 variants, never a generic object.
  • MCP 0.11.0 automatically threads one private server-minted session credential and the latest per-job sync token across every covered native or bridged tool call. Every covered result includes sync and syncCoverage; inspect conflicts, recommendations, and next operations before acting. Raw signed credentials and tokens never enter model-visible tool results.
  • opentrain_poll_job_context_sync provides a bounded real-time wait. opentrain_declare_job_context_intent, opentrain_list_job_context_intents, and opentrain_resolve_job_context_intent coordinate spontaneous work before it begins.
  • opentrain_submit_job_context_proposal, opentrain_list_job_context_proposals, opentrain_review_job_context_proposal, and opentrain_withdraw_job_context_proposal record non-enforced alternatives when managers disagree. Review links a separately authorized canonical change and never executes one.
  • opentrain_get_job_context_overlays and opentrain_set_job_context_overlay separate owner-controlled TEAM guidance, one manager's PERSONAL memory, and one connection's SESSION scratch. Overlay text is attributed and untrusted; it cannot alter readiness, gates, or policy.
  • opentrain_send_managed_job_message always uses the exact synchronized messaging_management.messages.send operation and requires a full jobOperationsGuard plus an 8-128-character idempotency key matching [A-Za-z0-9._:-]. It requires both messages:manage and messages:write. opentrain_send_message is generic and deliberately cannot accept a guard or advance shared context.
  • Initialize instructions teach this loop automatically. Capability recommendations are product discovery, not write authority: inspect evidence and show a zero-write proposal—such as a focused LMS retraining outline—before creating or assigning anything.

Account and discovery:

  • opentrain_auth_status — calls GET /api/public/v1/auth/me, returns the resolved token owner, access mode, and effective scopes. Full access keys expand live as new self-serve capabilities ship; the storage sentinel is never exposed.
  • 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.

Adaptive job Task Checklists (job_checklists:read/write; default-off agent surface; thirteen opentrain_job_checklists_* tools):

  • opentrain_job_checklists_list / _get / _capabilities — definitions, builder detail with CAS revisions, served operations and limits.
  • opentrain_job_checklists_create / _manage / _publish / _reorder / _set_enabled — receipt-backed mutations: atomic complete-draft create, expectedDraftVersion-fenced saves and retire/restore, confirmed double-CAS publish reporting the applied impact and sweep counts, strict reorder, and the worker-visibility toggle (authoring keeps working while off).
  • opentrain_job_checklists_validate / _resolve — no-write preflights running the EXACT publish rule set / the pure worker-runtime resolver.
  • opentrain_job_checklists_versions / _submissions — immutable history and privacy-filtered submissions.
  • opentrain_job_checklists_preview — stateless revision-exact browser preview link; the secret rides the returned URL fragment.

Job reviewer feedback (job_feedback:read/write; default-off privacy-sensitive agent surface; twelve opentrain_job_feedback_* tools — employer-only, subjects never read feedback through any agent surface):

  • opentrain_job_feedback_settings / _set_enabled — the per-job toggle (readable while off; confirm: true required in both directions). Every other feedback tool is a typed 409 while the toggle is off.
  • opentrain_job_feedback_list / _get / _summary — list/search with authoritative CONCERN-lane status counts plus recordedCount and assessment counts (DEV-3168 filters: assessment, lane — lane=RECORDED cannot combine with a concrete status/severity), full detail with append-only event history, and server-computed aggregates including per-person rating distributions, latest anchored rating, and rated-n-of-m (never average, score, or rank these sparse ratings). Non-concern rows are the "Recorded" lane: stored severity MINOR / status OPEN are compatibility shadows — present them as "Recorded".
  • opentrain_job_feedback_roster — closed canonical subject discovery (the id source for submit/link targeting).
  • opentrain_job_feedback_submit / _triage / _link_subject — receipt-backed (in-transaction) submit (legacy severity+report shape, or the DEV-3168 balanced shape: assessment with optional anchored ratings; severity present ⇔ a concern is flagged), CAS-fenced triage (required expectedUpdatedAt), and one-way legacy subject reconciliation.
  • opentrain_job_feedback_access_list / _access_set / _access_bulk — reviewer-grant management; bulk is one all-or-nothing transaction.

Job People table (people_table:read/write; default-off people_table agent surface; six opentrain_people_table_* tools plus the Agent notes tool opentrain_people_agent_notes). Columns are addressed by id (country, custom:<fieldId>) and people by jobPersonId; names are the public "First L." (else Unnamed candidate) and selectable only: no search, filter, sort or facet runs on a name. Contact, financial and compliance columns are redacted, and naming one is refused like an unknown column (COLUMN_NOT_QUERYABLE); Project To-do columns also need project_todos:read and Screening lms:read. Banned, closed and non-visible candidates never appear:

  • opentrain_people_table_describe — every column with its exposure, capabilities and filter operators, the limits, views and defaults. Start here.
  • opentrain_people_table_query — query (one keyset page: filter AST over column ids, up to fiv