Spec v1 · draft 0.1 · live
standalone · OpenCastor optional
§ Getting started · one line APRIL 18, 2026

A robot should introduce itself to the agent.
ROBOT.md is how.

~/bob · robot-md v0.6.3 ● one command · manifest + MCP + skill + auto-calibrate + arm.pick
$pip install robot-md && robot-md init my-bob --preset so-arm101 \ --register --manufacturer acme --contact-email [email protected]
[1/5]scaffold manifest
scan /dev/ttyUSB0 · feetech @ 1 Mbps · ids 1–20 ....... 6 servos
detect OAK-D · pulled factory intrinsics from DepthAI ... ok
write ROBOT.md · frontmatter + body · 1.8 kb, 55 lines
write CLAUDE.md · intent → verb table, sentinel-wrapped
[2/5]register · POST rcan.dev/api/v1/robots
mint ...................................................... RRN-000000000173
api key ................................ ~/.robot-md/keys/<rrn>.apikey (0600)
validate · schema v1 draft 2020-12 ......................... 55 / 55 valid
[3/5]install MCP server into Claude Code · tty detected
claude mcp add robot-md -- npx -y robot-md-mcp "$(pwd)/ROBOT.md"
6 resources · 6 tools (validate, render, estop, estop_clear, execute_capability, execute_task) · 4 prompts ... ok
[4/5]install using-robot-md skill
copy → ~/.claude/skills/using-robot-md/SKILL.md ....... ok
[5/5]calibrate · arm plugged in
Run encoder-sign test move on joints 1–6? [Y/n] y
sign check j1…j6 ........................................... 6 / 6 confirmed
Pose arm at declared zero and press Enter to record zero_pose_steps.
zero_pose_steps written · comments preserved by ruamel ...... ok
auto-calibrate ready from DH + IK · solved for (200, 0, 50)mm ... 6 joints
hint: robot-md dashboard serve opens 127.0.0.1:8091 for live servo + OAK-D + tool-call log.
$claude
bob is online. ready pose auto-calibrated. What should I pick?
pick the red lego and place it in the bowl
ROBOT.md
v0.6.3 · one command → actuatable robot. Manifest, MCP server, skill, calibration, and an auto-solved ready pose — all from robot-md init. Then arm.pick(target) closes the loop: descriptor → vision → IK → motion. Headless? same command, --non-interactive.
How it works →
§ 01 — The file itself

A robot is what its ROBOT.md says it is.

Every robot today drifts across five files — a YAML config, a P66 manifest, a CLAUDE.md, a firmware manifest, a README. Add a joint, update three. Miss one, ship a lie. ROBOT.md collapses the stack into a single source of truth.

bob.ROBOT.md VALID · RCAN 3.0
---
rcan_version: "3.0"
metadata:
  robot_name: bob
  rrn:        RRN-000000000001
  manufacturer: craigm26
physics:
  type: arm+camera
  dof:  6
drivers:
  - { id: arm,    protocol: feetech, port: /dev/ttyUSB0 }
  - { id: camera, protocol: depthai, model: OAK-D       }
capabilities:
  - arm.pick
  - arm.place
  - vision.describe
  - status.report
safety:
  payload_kg: 0.5
  estop:      { software: true, response_ms: 100 }
  hitl_gates:
    - { scope: destructive, require_auth: true }
brain:
  planning:  { provider: anthropic, model: claude-opus-4-7 }
  reactive:  { provider: local,     model: openvla-7b     }
---

# bob

## Identity
Bob is a 6‑DOF SO‑ARM101 arm with an OAK‑D camera. Stationary,
reach ≈ 60 cm, payload ≤ 0.5 kg. RRN‑000000000001.

## What bob Can Do
Pick, place, describe what the camera sees. Arm only — no
navigation. Inverse kinematics handled by the runtime.

## Safety Gates
Software E‑stop, 100 ms. Destructive actions route through
RCAN §8 AUTHORIZE. Bounds enforced per‑joint before servo bus.
§ 02 — The stack

Four layers. Each independent. Each composable.

Four independent standards. ROBOT.md declares what the robot is. RCAN is the signed wire protocol fleets speak. Robot Registry Foundation (RRF) is the neutral authority where robots live. OpenCastor is the visual agent-harness editor and swarm orchestrator — optional. Tier 0 runtime is Claude Code itself. Adopt one layer or all four.

Layer 4 · DeclarationROBOT.md
This specYAML + markdown. One file at the robot's root. Read at session start by the planner; consumed by every layer below.
FormatFrontmatter validated by JSON Schema draft 2020‑12. Body read by Claude Code, Desktop, Mobile.
StatusDraft v1 shipped 2026‑04‑17. v1.0 frozen spec targeted Q3 2026.
Layer 3 · ProtocolRCAN 3.0+
WireSigned envelopes between planner, gateway, and driver. Level‑of‑Assurance enforcement on every call. Manifests declare rcan_version: "3.0" — minor-version increments (3.1, 3.2, …) are backward-compatible.
CryptoPQC‑primary: ml-dsa-65 at L2+. Ed25519 accepted at L1 only, sunset mid‑cycle. Per-manifest via network.signing_alg.
Compliance§23–§27 cover EU AI Act Annex III audit trails, FRIA refs, ISO 42001 self‑assessment.
Layer 2 · RegistryRobot Registry Foundation
IdentityAssigns an RRN — a permanent, globally‑unique robot identifier. Mint with one command: robot-md register ROBOT.md. Resolvable via rrn:// URIs.
NeutralA foundation, not a vendor. Cloudflare Pages + Workers + D1. No seat fees, no per‑robot tax.
PublicPublic endpoint at rcan.dev/r/<rrn>. Self‑hosted mode supported.
Layer 1 · RuntimeClaude Code is enough. OpenCastor for harness authoring & swarms.
Tier 0Claude Code is already a runtime. Drop ROBOT.md in a repo with shell access to your robot — USB, serial, HTTP, MQTT — and the Bash tool dispatches. No SDK to install.
Tier 1Add your own driver scripts for sub‑second loops. Still no "runtime" in the traditional sense — just Claude plus the scripts you'd write anyway.
Tier 2OpenCastor — a visual agent-harness editor plus multi-robot swarm orchestration. ROBOT.md is its native robot format, but Claude Code reads the same file standalone. Opt-in when you need to compose harnesses visually or run a fleet.
Layer 3 · Wire protocol

RCAN 3.0+ — Robot Communication & Addressing Network

An open protocol that lets robots, gateways, and planners exchange signed, authority‑aware messages without vendor coupling.

  • Signed envelopes with ML‑DSA‑65 primary + Ed25519 legacy (L1 only, sunset mid‑cycle).
  • Level‑of‑Assurance ladder — every call is classified L0 / L1 / L2, enforced gateway‑side.
  • Section 8: AUTHORIZE message for human‑in‑the‑loop gates declared in ROBOT.md.
  • Sections 23–27: EU AI Act Annex III audit trails, FRIA URI binding, ISO 42001 self‑assessment.
  • Published and version‑tagged at rcan.dev. Apache‑2.0. Governed by the RCAN working group.
rcan.dev → read the protocol spec
Layer 2 · Registry

Robot Registry Foundation — permanent, neutral robot identity

RRF issues an RRN (Robot Registration Number) the same way a VIN identifies a car — one robot, one number, forever.

  • RRN format: RRN‑000000000001 (12‑digit numeric) and rrn://org/category/model/id URI form.
  • Public resolver at rcan.dev/r/<rrn> — returns the robot's ROBOT.md, its compliance block, its registry metadata.
  • Mint in one command: robot-md register ROBOT.md reads your manifest's metadata.manufacturer/model/version/device_id, POSTs to RRF, writes the assigned RRN back into the file, saves the issued API key at ~/.robot-md/keys/<rrn>.apikey (mode 600).
  • Edge‑served via Cloudflare Pages + Workers + D1. Zero downtime at the identifier layer.
  • Foundation‑governed, not vendor‑owned. Self‑hosted mode for private fleets.
  • RRF is the authority ROBOT.md points at when metadata.rrn_uri is populated.
robotregistryfoundation.org → register a robot

Claude Code is already a runtime. ROBOT.md is the file that makes it a robot runtime.

§ 03 — Claude, three surfaces (and every other MCP‑aware harness)

Wherever the planner runs, the robot is legible.

A ROBOT.md is meant to be picked up by a planning LLM at the start of every session — from a developer's terminal, from a desktop chat, from a phone in the field. Planner‑agnostic by design: the same file, the same MCP server, works with Claude Code, Claude Desktop, OpenAI Codex CLI, Google Gemini CLI, Cursor, Zed, Cline, Continue.dev — anything that speaks MCP.

● Shipping

Claude Code · CLI

Zero flags. robot-md init — Claude Code drives the rest.

Built for operators at a terminal. pip install robot-md && robot-md init autodetects your hardware, picks the right preset, writes ROBOT.md and CLAUDE.md, installs the robot-md MCP server, and drops the using-robot-md skill. Open Claude Code next and the planner reads your robot's frontmatter, capabilities, safety gates, and prose body as MCP resources. Claude asks follow-ups — register? calibrate zero? hand-eye? — in English.

Two commands. Zero flags. Claude Code recognizes the robot.
● Shipping

Claude Desktop · macOS / Windows

One command. robot-md install-desktop ROBOT.md

Merges a robot-md entry into claude_desktop_config.json on the right OS path (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%/Claude/), preserving any other MCP servers. Restart Claude Desktop and the full MCP surface loads: the same 6 resources, 3 tools (validate, render, doctor_summary), and 4 slash commands — /check-safety action="…" gates motion before a driver ever moves.

Idempotent · --force to replace · safe with existing servers
● Shipping

Claude Mobile · iOS / Android

URL fetch. Paste the manifest URL into the chat.

iOS has no local MCP, but it fetches URLs and reasons over what it finds. Host ROBOT.md + .well-known/robot-md.json at any public HTTPS URL (GitHub Pages works today), paste the link, and Claude Mobile answers from the manifest. The auto-generated CLAUDE.md makes the safety posture explicit so the gate-check logic survives the trip to mobile. Use robot-md publish-discovery ROBOT.md --url <URL> to emit the discovery doc.

Works today · no native app · no Anthropic change
§ 04 — Field reference

The frontmatter, in one table.

Excerpted from spec v1 §3. Full normative text, JSON Schema, and extension rules live in the repo.

Field Type Required Purpose
rcan_versionstringRCAN wire-protocol version — "3.0" covers the 3.x line. 2.1+ accepted; 1.x rejected for EU AI Act gap. See rcan.dev/spec.
metadata.robot_namestringShort display name. Must match the body H1. Used in every planner citation.
metadata.rrnstringRRF-assigned identifier (e.g. RRN-000000000001). Empty until robot-md register mints one. Resolves via rcan.dev/r/<rrn>.
metadata.rrn_uristringOptional URI form: rrn://<org>/<category>/<model>/<id> — dereferenceable by any RCAN-aware client.
physics.typeenumarm · wheeled · tracked · legged · arm+camera · humanoid · sensor · other
physics.dofintDegrees of freedom. 0 permitted for purely sensory nodes.
physics.kinematics[]arrayPer-joint geometry. Each entry: id, axis (x/y/z), a_mm/d_mm DH params, limits_deg, servo_id, encoder_sign, zero_pose_steps.
physics.solvermapBaseline FK/IK config so any planner can reach a target from the manifest alone — no URDF, no MoveIt. Fields: convention, base_frame, encoder.steps_per_rev, gripper (tip offset, open/close steps), camera (mount + extrinsic).
drivers[]arrayAt least one. Each declares id + protocol (feetech, dynamixel, depthai, ros2, …).
capabilities[]array✓*Required when dof > 0. Namespaces: nav.*, arm.*, vision.*, status.*, system.*, vendor <prefix>.*.
safety.estopmapAt minimum: software: true + response_ms. Hardware button recommended for Annex III systems.
safety.hitl_gatesarrayScopes (destructive, system, …) that require human authorization via RCAN §8 AUTHORIZE.
brainmapPlanner + reactive model declaration. Task‑routing overrides. Required if the robot uses an LLM in the loop.
network.rrf_endpointstringRRF resolver — defaults to https://robotregistryfoundation.org. Serves the signed manifest at /r/<rrn> and FRIA at /api/v1/robots/<rrn>/fria.
network.signing_algstringRCAN 3.0 primary: ml-dsa-65 (PQC). ed25519 accepted at Level-of-Assurance 1 only; sunset mid-3.x.
compliancemapFRIA URI, ISO 42001 self‑assessment, EU AI Act audit retention. Required for EU deployments.
extensions.x-*mapVendor‑specific. Unknown x-* keys must NOT fail validation.
required recommended optional
§ 05 — Try it in sixty seconds

Zero flags. One command. Claude does the rest.

Bare robot-md init scans PCI/USB//dev/tty*, actively probes for Feetech servo buses, matches against the 10-preset library — so-arm101, so-arm101-leader, turtlebot4, picar-x, franka-panda, ur5e, koch-arm, aloha2 (bimanual), unitree-go2 (quadruped), minimal — and emits a validated draft with full DH kinematics + safety defaults already populated. For known robots, ~85 % of the manifest is pre-filled automatically. Follow-ups (register, calibrate, hand-eye) happen inside Claude Code in English — or as flags if you'd rather script them.

▶ Path A — On your machine (terminal)

You're at a shell on the robot (or a laptop with the robot plugged in). Type robot-md init — no flags. Autodetect fills in the rest. Demo at left.

▶ Path B — Inside Claude Code (ask Claude)

You already have Claude Code open. Paste one English sentence; Claude runs the same commands via its Bash tool and wires up MCP for you. Walkthrough →

Path A · terminal · ~/projects/my-bob · zsh
# Zero flags. Claude Code drives the follow-up.
$ pip install robot-md
$ robot-md init

✓ autodetect     feetech bus on /dev/ttyACM0 (6 servos)
✓ preset matched so-arm101 (protocol +10)
✓ wrote ROBOT.md  preset: so-arm101 · 6 DoF · 5 capabilities
✓ wrote CLAUDE.md # agent reads it at session start
✓ installed MCP   robot-md (claude mcp add …)
✓ installed skill ~/.claude/skills/using-robot-md/SKILL.md
✓ zero calibration skipped (safe default — ask Claude to run it)

# That's the whole setup. Now boot the agent:
$ claude
· 6 resources loaded: robot-md://bob/{identity, context, frontmatter,
                                       capabilities, safety, body}
· 3 tools: validate, render, doctor_summary
· 4 slash commands: /brief-me  /check-safety  /explain-capability  /manifest-status

› bob is online. `ready` pose auto-calibrated from DH + IK. What should I pick?
pick up the red lego and place it in the bowl
✓ vision.find(red_lego) → (−62, +25, +522) mm · vision.find(white_bowl) → (−210, +10, +480) mm
✓ execute_capability arm.pick(target: red_lego) · approach → descent → grasp → lift · ok
✓ execute_capability arm.place(target: white_bowl) · approach → descent → open → lift · ok
# Claude operates the robot via the Bash tool + MCP — English in, motion out.
After init · Every Claude surface recognizes the robot

robot-md init writes both ROBOT.md and CLAUDE.md. From there, three one-command paths to each Claude surface:

Claude Code
claude mcp add robot-md …
Claude Desktop
robot-md install-desktop ROBOT.md
Claude Mobile
paste manifest URL into chat

All three give Claude six live resources + three tools + four slash commands (Mobile gets the resources as a static URL fetch instead of live MCP):

Slash commands
  • /brief-me — operator briefing
  • /check-safety action="…" — gate-check before motion
  • /explain-capability capability="…"
  • /manifest-status — quick health report
Resources
  • robot-md://bob/identity
  • robot-md://bob/context — Claude-ready
  • /frontmatter · /capabilities · /safety · /body

Optional: robot-md install-skill drops the using-robot-md skill into ~/.claude/skills/ — superpowers-aware harnesses auto-invoke the robot-md flow on the operator's first robot-related message.

Custom hardware? (no preset yet)
Three escape hatches:
  • robot-md autodetect --bus feetech:/dev/ttyACM0 — pings every ID on a Feetech servo bus and emits a physics.kinematics[] block with real angle limits + present positions, ready to paste into a draft.
  • robot-md calibrate --hand-eye --marker-pos 300,0,0 ROBOT.md — prints one ArUco marker on paper, places it at a known spot on the table, and solves the OAK-D↔arm-base extrinsic via solvePnP. Writes physics.solver.camera.extrinsic so a planner can project pixel coords into the arm's frame without URDF or external calibration files.
  • robot-md init --wizard — interactive 7-step flow: name, physics type, preset or custom, scan, calibrate zero + sign, optional hand-eye. Resume-safe via a ROBOT.md.init state file.
§ 06 — The rest of the ecosystem

Four standards. Separate roles. Adopt à la carte.

ROBOT.md stands alone — Claude Code reads it directly, no OpenCastor required. Three siblings extend it: RCAN (the signed wire protocol fleets speak), the Robot Registry Foundation (permanent identity, neutral authority), and OpenCastor (visual agent-harness editor + swarm orchestration). Mix and match.

Declaration · this site
ROBOT.md

What a robot is. A single file, YAML + markdown. Designed for Claude's agent harnesses (Code / Desktop / Mobile) but readable by any planner.

github.com/RobotRegistryFoundation/robot-md →
v0.2 design draft — signing + registry ingestion →
Wire protocol · rcan.dev
RCAN 3.0+

What a robot speaks. Signed envelopes, LoA enforcement, ml-dsa-65 primary crypto, EU AI Act compliance blocks (§23–§27). Open, Apache‑2.0, community‑governed.

rcan.dev →
Registry · robotregistryfoundation.org
Robot Registry Foundation

Where a robot lives. Permanent, globally‑unique RRNs. Resolvable rrn:// URIs. Neutral foundation; Cloudflare Pages + Workers + D1.

robotregistryfoundation.org →
Agent harness · opencastor.com
OpenCastor

Optional. Visual editor for Claude agent harnesses plus multi-robot swarm orchestration. Compose MCP stacks, wire tools, scale from one robot to a fleet. ROBOT.md is its native robot format — but Claude Code reads the same file standalone. Pick it up when you outgrow a single terminal.

github.com/craigm26/OpenCastor →