Research & implementation report

LeRobot MCP 0.2.0 migration

Updated LeRobot contracts and migrated to official MCP SDK 2.2.0. Real v0.6.1 dataset/CLI checks, modern and legacy stdio, concurrency checks, source audits of main, and isolated wheel startup passed.

validatedGenerated 2026-09-25T21:26:55+00:004 completed integration experiments; adaptive scope

Contract

User outcome
Current LeRobot dataset, policy processor, and CLI contracts; MCP SDK 2.x; release on main.
Acceptance target
Preserve existing tools and scalar arguments, accept nested JSON, inspect a real v3 dataset, expose current processor artifacts, pass MCP protocol and package checks.
Compatibility
Tool names and result payloads retained with additive fields. Metadata targets LeRobot >=0.6.1. MCP 2026-07-28 and legacy 2025-11-25 clients tested.
Safety
No hardware motion, dataset upload, or model execution during validation. Conversion remains opt-in and local by default.
Experiment mandate
Adaptive correctness checks; no performance target.
Non-goals
Training policies, calibrating physical robots, HTTP transport, and migrating existing user datasets.

Research

SourceFindingImplementation impactLink
LeRobot v0.6.1 releaseLatest stable GitHub release inspected on 2026-09-25; commit 7e241bd630a3719a56157a497ce5d08f244784f1.Use as the real-runtime validation target.Open
LeRobot package and extrasFeature-scoped dataset/training/core_scripts/evaluation extras and dynamically declared console scripts.Keep source discovery; document extras instead of hardcoding all commands or installing every policy.Open
Dataset metadata and typed infoMetadata exposes DatasetInfo attributes, authoritative totals, depth keys, and dataset/bucket repo types. Format remains v3.0.Replace obsolete dict access, add total frames and modality keys, and expose bucket selection.Open
Policy processor serializationPipeline configs contain steps with optional state_file references. Factory defaults are policy_preprocessor.json and policy_postprocessor.json.Inspect pipelines, separate processor state from policy weights, and report missing artifacts.Open
Dataset converterConverter still uses argparse flags for v2.1-to-v3.0; branch is an upload destination.Retain conversion implementation and verify flags against source; correct parameter documentation.Open
Current main sourceCurrent source includes new policies, inference and rollout registries, and additional commands.AST registration discovery and CI contract checks track source evolution without importing robotics modules.Open
Official MCP SDK migration guideSDK 2 uses MCPServer, snake_case types, worker threads, explicit ToolError messages, and a modern Client discovery flow.Migrate imports, annotations, clients and errors; protect shared mutable state; test both protocol eras.Open

Architecture decision

Keep one dynamic CLI/inspection interface. Concentrate serialization and subprocess behavior in the runner, static source contracts in introspection, and checkpoint declarations in Hub inspection.

Interface

Existing MCP tools plus nested JSON options, scoped help, version metadata, dataset bucket selection, and additive policy processor/action fields.

Seams and adapters

  • LeRobot checkout and subprocess runtime remain separate from the MCP Python environment.
  • Hub listing and lightweight JSON reads use one commit snapshot; processor configurations never overwrite policy features.
  • Official MCPServer handles protocol framing; one registration adapter preserves expected errors and local locks protect configuration and jobs.

Alternatives

AlternativeDecision
Per-command hardcoded wrappersRejected: duplicate evolving LeRobot configuration contracts and lag newly registered commands.
Import all LeRobot registries into MCPRejected: introduces heavy dependencies and optional hardware/model imports at discovery time.
Standalone FastMCP frameworkRejected: official SDK MCPServer covers the existing tool surface without a second framework.

Baseline

MetricBaselineContext
Existing suite21 passedOriginal repository tests; no real upstream metadata or SDK 2 checks.

Experiments

IDFamilyHypothesisChangeResultEvidence signalDecisionRaw evidence
E01LeRobot runtimeCurrent typed metadata can replace obsolete dict access without changing existing outputs.Use DatasetInfo attributes and public totals; add bucket/modality fields; create/finalize/read a three-frame dataset.improvedReal v0.6.1 metadata and CLI help passed.promoteOpen
E02Contract discoverySource parsing and processor-aware inspection cover modern configs without importing models.AST registries, nested JSON serialization, upstream draccus parse, commit-pinned processor inspection and feature precedence.improvedNested split mapping parsed by real LeRobot; source contracts pass stable and main; policy regressions pass.promoteOpen
E03Dependency compatibilityA dependency-only SDK upgrade might preserve the old server imports.Resolved MCP 2.2.0 before migrating server imports.failedCollection failed: mcp.server.fastmcp was removed.retireOpen
E04MCP protocol migrationOfficial SDK 2 migration can preserve existing tools and support concurrent callers.MCPServer, Client, annotations, version, expected errors and state locks. Initial wire tests exposed sanitized ValueError messages; ToolError adapter fixed them.improvedModern/legacy stdio, foreground responsiveness, concurrent setup/cancel, all 35 tests and isolated wheel startup passed.promoteOpen

Validation

CheckStatusEvidence
Ruff, mypy, full suite with real v0.6.1 runtimepassOpen
Current main source contractspassOpen
Clean wheel and source distribution build; isolated wheel stdio startuppassOpen
Physical robots, training, hosted buckets and real policy inferencelimitedOpen

Limitations and blockers

  • No physical robots, model inference, remote storage buckets, or dataset conversion writes were exercised.
  • Policy inspection reports declared schemas and artifact presence; it does not prove joint order, units, or safe runtime compatibility.
  • Current main was validated statically; real runtime validation used v0.6.1 on macOS arm64.
  • Managed installation continues to follow main by default; select ref=v0.6.1 for the stable validation baseline.
  • Browser URL policy blocked opening the local HTML report. HTML headings, tables, evidence links, and overflow CSS were checked statically; visual layout was not reviewed.

Reproduction

  • uv sync --extra dev --frozen
  • uv run ruff check . && uv run mypy
  • uv run pytest -q
  • In a LeRobot v0.6.1 checkout: uv sync --locked --no-default-groups --extra dataset --python 3.12
  • LEROBOT_CONTRACT_ROOT=/path/to/lerobot LEROBOT_CONTRACT_RUNTIME=1 uv run pytest -q
  • With a main checkout: LEROBOT_CONTRACT_ROOT=/path/to/main uv run pytest tests/test_upstream_contract.py -q
  • uv build; install the resulting wheel into a clean environment and run a Client(StdioServerParameters(command="lerobot-mcp")) discovery/config smoke check.