# Embodify (pypi · embodify-mcp)

Give your agent a body: observe and control simulated robots (LIBERO, RoboDojo) over MCP.

- Trust score: 77/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-05

## Components

- pypi · `embodify-mcp`: 77/100 (this document), [markdown](https://verifymcp.io/servers/yidayang-embodify/embodify-mcp.md), [page](https://verifymcp.io/servers/yidayang-embodify/embodify-mcp)

## Channel facts

- Registry: `pypi`
- Package: `embodify-mcp`
- Version: `0.1.0a2`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-05.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs setuptools.build_meta at install time, a recognised build step with no custom scripting around it.
  - 0 of 1 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 87/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to YidaYang/embodify).
  - License check failed: no license is declared.
  - Actively maintained (last published 3 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 68/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 1707 tokens (~243/item across 7 items; 7 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 95/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 86% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 7 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 7 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### How do I install the Embodify MCP server?

Embodify runs locally as a PyPI package, launched with uvx embodify-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add yidayang-embodify -- uvx embodify-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "yidayang-embodify": {
      "command": "uvx",
      "args": [
        "embodify-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "yidayang-embodify": {
      "command": "uvx",
      "args": [
        "embodify-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add yidayang-embodify -- uvx embodify-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "yidayang-embodify": {
      "type": "local",
      "command": [
        "uvx",
        "embodify-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add yidayang-embodify --command uvx --arg embodify-mcp
```

### Hermes

```yaml
mcp_servers:
  yidayang-embodify:
    command: "uvx"
    args: ["embodify-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "yidayang-embodify": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "embodify-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add yidayang-embodify -t stdio -c uvx -a embodify-mcp
```

### Other

```json
{
  "mcpServers": {
    "yidayang-embodify": {
      "command": "uvx",
      "args": [
        "embodify-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-03 (score 77, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-10-02 (score 62)

First indexed and scored.

## MCP tools (7)

### `reset_task` (~369 tokens)

Start a new FakeSim episode. **All three arguments are optional**: omit them all to use the server's default scene (usually task 0 of the suite with initial layout 0), which is the most common use.
To switch tasks, use list_tasks first: without arguments it lists the suites, with suite it gives the task_index and instruction of every task in that suite; then pass the chosen suite / task_index. init_state_index picks another object layout of the same task. If the server was started with --lock-task (task_locked is true in get_session_info), passing any of these arguments returns a task_locked error.
If an episode is already running, returns already_running; call stop_episode first.
Returns run (short run ID), task (suite, task_index, name, instruction, init_state_index), images (agentview and robot0_eye_in_hand: two separate PNGs), state (eef_pos_m is the end-effector XYZ position in meters; eef_rpy_rad.roll_x, pitch_y and yaw_z are the orientation about the robot base X/Y/Z axes in radians; gripper.command is the open/close target and gripper.opening_m the gripper opening in meters), step (simulation steps used) and steps_left (simulation steps left in this episode).

Input parameters:

- `init_state_index` (integer): Which initial layout of the task; 0 if omitted. Must be below the task's n_init_states.
- `suite` (string): Switch to another suite; omit to keep the current one. See list_tasks (without arguments) for the suites.
- `task_index` (integer): Which task of the suite; omit to use the server's default scene (task 0 when switching suites). See list_tasks with suite for the options.

### `observe` (~111 tokens)

Read the current RGB images from two cameras and the end-effector/gripper state, without advancing the simulation or using the step budget. Returns images (agentview and robot0_eye_in_hand: two separate PNGs), state (eef_pos_m is the end-effector XYZ position in meters, eef_rpy_rad the orientation about the base XYZ axes in radians, gripper holds the target command and opening_m in meters), step (simulation steps used), steps_left (simulation steps left) and status (running).

### `move_relative` (~472 tokens)

Move the end effector by delta_xyz meters in the FakeSim world frame (z up, table surface at z=0.80 m), optionally rotating by delta_rpy about the robot base X/Y/Z axes (radians). The server approaches the target step by step with P control and returns only when a definite stop condition triggers, not after a fixed number of steps.
action.stop_reason says why the call stopped, one of four:
\- reached: Within the target tolerance (8 mm in position, 0.02 rad in orientation); the motion is complete.
\- stalled: Barely moved for 3 consecutive steps (less than 1 mm in total) without reaching the target, which usually means something is blocking it: the table, an object, or a joint limit. Repeating the same command has no effect; change direction, or lift or back off first. This is the main signal of contact.
\- step_cap: Hit the per-call internal step limit while the end effector was still moving toward the target. Call again with the remaining displacement in the same direction to continue.
\- budget: The episode's total step budget ran out during the motion; only stop_episode can be called afterwards.
Motion is a best-effort approach and may fall short of the requested delta: judge progress by action.achieved_delta_xyz (actual displacement of this call, meters) and action.remaining_distance_m (meters still missing to the requested target), and do not assume the request was achieved.
Returns images (two separate PNGs), state (eef_pos_m is the end-effector XYZ position in meters, eef_rpy_rad the RPY orientation in radians, gripper holds command/opening_m), action (the requested delta_xyz/delta_rpy, executed_steps, stop_reason, achieved_delta_xyz, remaining_distance_m), step (simulation steps used after the call), steps_left (simulation steps left) and status (running). When the budget is already 0, returns a step_limit error instead of silently doing nothing.

Input parameters:

- `delta_rpy` (array): [droll, dpitch, dyaw], increments about the robot base X/Y/Z axes in radians; omit to keep the current orientation.
- `delta_xyz` (array, required): [dx, dy, dz] in meters.

### `set_gripper` (~355 tokens)

Open or close the gripper. The server keeps sending the command and watches the opening width, and returns only when a definite stop condition triggers, not after a fixed number of steps.
action.stop_reason says why the call stopped, one of four:
\- settled: After at least 10 internal steps of the same command, the opening varied by less than 0.5 mm over the last 2 steps. This only means the opening is momentarily stable, possibly because something blocks it; it does not guarantee a fully open gripper, a firm grasp or a released object. Check state.gripper.opening_m and the images.
\- step_cap: Hit the per-call internal step limit before the opening was confirmed stable; the gripper may still be starting or moving. Repeat the same command to continue.
\- budget: The episode's total step budget ran out during the action; only stop_episode can be called afterwards.
\- no_op: The request matches the current gripper target and no gripper call is pending; nothing was executed and no budget was used. It does not mean an object was released.
Returns images (two separate PNGs), state (eef_pos_m is the end-effector XYZ position in meters, eef_rpy_rad the RPY orientation in radians, gripper.command the gripper target and gripper.opening_m the opening in meters), action (the requested gripper target, executed_steps, stop_reason, opening_m before and after), step (simulation steps used after the call), steps_left (simulation steps left) and status (running). When the budget is already 0, returns a step_limit error and the gripper target stays unchanged.

Input parameters:

- `state` (string, required)

### `stop_episode` (~58 tokens)

End the current simulation and save its frames, event log and summary. Returns run (short run ID), status (stopped) and artifacts (events: path of events.jsonl, frames: PNG frame directory, summary: path of summary.json).

### `get_session_info` (~201 tokens)

Read the state of **the current run**: task context, instruction, step count and robot state. Renders no images and uses no step budget; callable at any time, including before the first reset_task.
This only says where you are now. To see which tasks are available, use list_tasks.
Returns run (short run ID), status (idle/running/stopped), step (simulation steps used), max_steps (the episode limit), steps_left (simulation steps left), task (suite, task_index, name, instruction, init_state_index), task_locked (true means the server fixed this run's scene, and reset_task accepts no scene arguments), and state (eef_pos_m is the XYZ position in meters, eef_rpy_rad the RPY orientation in radians, gripper holds command/opening_m). While status is idle there is no task or state; instead it returns default_scene (the scene a reset_task without arguments starts).

### `list_tasks` (~141 tokens)

List the tasks FakeSim offers. **Independent of the current run**: callable at any time, renders no images, uses no step budget and does not change a running episode.
Without arguments: returns suites, the name and task count of every suite, plus the total task count. Start here, pick a suite, then look inside it.
With suite: returns task_index, instruction and n_init_states (the number of initial layouts of the same task) for every task in that suite.
Pass the chosen suite and task_index to reset_task to start.

Input parameters:

- `suite` (string): The suite whose tasks to list; omit to get only the suite overview.

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/yidayang-embodify/embodify-mcp#diagnostics

## Score history

- 2026-10-05: 77
- 2026-10-04: 77
- 2026-10-03: 77
- 2026-10-02: 62

## Common questions

### What is the Embodify MCP server?

Embodify is an MCP server listed in the public MCP registry as io.github.YidaYang/embodify. Give your agent a body: observe and control simulated robots (LIBERO, RoboDojo) over MCP. This page covers its PyPI package (embodify-mcp).

### Is the Embodify MCP server safe to use?

Embodify scores 77 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 October 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Embodify MCP server expose?

Embodify exposes 7 tools: reset_task, observe, move_relative, set_gripper, stop_episode, and 2 more. Their descriptions and schemas cost roughly 1,707 tokens of context every time the server is loaded.

### Is the Embodify MCP server still maintained?

Embodify is still listed as active in the MCP registry. We last reached this channel on 5 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- PyPI project: https://pypi.org/project/embodify-mcp/
- Socket report: https://socket.dev/pypi/package/embodify-mcp
- Repository: https://github.com/YidaYang/embodify
- Changelog RSS feed: https://verifymcp.io/servers/yidayang-embodify/embodify-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/yidayang-embodify/embodify-mcp.json
- HTML version of this page: https://verifymcp.io/servers/yidayang-embodify/embodify-mcp
