Skip to main content
Version: 10

Connect an AI Assistant with the MCP Server

The MoveIt Pro MCP server lets a Model Context Protocol client inspect Objectives, Behaviors, Waypoints, runtime state, and logs, and, with the right credential, run local configuration, build, test, and Runtime launch workflows. What a session can do follows the credential it authenticates with, not the transport. The deployment's read-only MCP key, used over authenticated HTTPS, inspects. Your OS user account, used by the local stdio session, can additionally use host configuration, build, test, and Runtime lifecycle tools when an owner-controlled policy grants the corresponding lifecycle scopes.

Choose where the MCP client runs

MoveIt Pro exposes the same declarative tool catalog through two adapters. Pick the setup from what you want the assistant to do and where its client process runs:

What should the assistant do?AI client on another computerAI client on the Runtime computer
Inspect Objectives, Behaviors, Waypoints, robot state, and logsHTTPS with the read-only MCP key (Remote client)moveit_pro mcp install (Same machine)
Create robot configuration packages, build, test, and launch the RuntimeRun the stdio bootstrap over SSH: point the client's server command at ssh <runtime-user>@<runtime-host> moveit_pro mcp serve ... with the Same machine arguments. It authenticates as your account on the Runtime computer and needs the same owner-granted lifecycle policy.moveit_pro mcp install plus an owner-granted lifecycle policy
Command robot motionNot exposed over MCPNot exposed over MCP
Remote client computer

Use authenticated Streamable HTTP when Claude Desktop, Cursor, or another AI client runs on a different computer from the MoveIt Pro workspace and Runtime.

Authenticates as: the deployment's read-only MCP key, a derived credential that inspects but never authors, builds, or launches.

  • Runtime computer: start MoveIt Pro normally. Its REST backend serves https://<runtime-host>:<rest-port>/mcp with TLS, MCP-key authentication, Host/Origin checks, and admission limits.
  • Client computer: configure the MCP URL, trust for the Runtime certificate, and bearer key. A stdio-only client such as Claude Desktop can run mcp-remote locally as its bridge to that authenticated HTTP endpoint.
  • MoveIt Pro Desktop App: Electron pairs with the remote Runtime for the desktop experience only. Its paired certificate, stored key, and local gateway are not shared with the AI client. Provision the AI client separately with the MCP-only key below.

Follow Remote client: connect from another computer.

Same Runtime computer

Use the local stdio bootstrap when the AI client runs on the same computer that owns the MoveIt Pro workspace and runs the Runtime.

Authenticates as: your OS user account on that computer. Workspace reads work immediately; host configuration, build, test, and launch tools also require an owner-granted lifecycle policy.

  • Run moveit_pro mcp install on that computer to add the MCP entry to the AI client's configuration.
  • The AI client starts moveit_pro mcp serve on demand. That command creates a least-privileged ephemeral container and works before the REST backend is running; starting or stopping the backend does not disconnect the session.
  • This setup requires the local workspace, MoveIt Pro installation, and container runtime. Installing it on a separate Electron client computer does not grant access to the remote workspace.

Follow Same machine: install on the Runtime computer.

Transport does not grant authority. In this phase, HTTP uses a domain-separated MCP key derived from the deployment's frontend key. The backend accepts that derived key only at /mcp, where it maps to a read-only deployment principal; it is not accepted by ordinary REST routes and does not authorize source edits, builds, lifecycle actions, or motion. Local stdio derives an OS-user principal, but lifecycle scopes are still off unless an owner-controlled, target-bound policy grants them. Future remote authoring requires a separately authenticated, scoped user or workload principal rather than widening either deployment key.

The HTTP tools also carry the standard MCP read-only, non-destructive, idempotent, and closed-world hints. Clients can therefore keep their normal read-only approval policy; the server's scopes and target checks remain the actual authorization boundary.

Every connection is bound before tool discovery to one deployment, instance, robot, canonical workspace, and robot configuration package. A different target requires a new session. Provider availability can change during the session, but its scopes, visible tools, and target cannot.

What the assistant can see

Tools

ToolReturns
get_capabilitiesCurrent target-bound WORKSPACE, ACTIVE_CONFIG, LOGS, and RUNTIME availability for authorized tools. Local stdio sessions with lifecycle scopes also report TOOLCHAIN and HOST_CONTROL.
list_objectivesEvery Objective in the selected robot configuration.
get_objectiveOne Objective's parsed Behavior Tree and metadata, by ID.
list_behaviorsThe catalog of registered Behaviors, with ports.
get_behavior_detailsOne Behavior's metadata and ports, by ID.
list_waypointsEvery saved Waypoint, with joint state.
get_waypointOne Waypoint, by name.
get_recent_logsA line- and byte-bounded tail of the target's configured ROS log source, with output_truncated when older output was omitted.
get_execution_statusThe matching Objective Server's live state and running Objective.
get_robot_stateThe matching robot's current joint positions and velocities.

These are available to every authorized client, including over authenticated HTTP. A local stdio session additionally exposes:

ToolReturnsRequires
create_configA newly generated package using the session's bound configuration name.granted lifecycle scope
build_workspaceA job handle for a build of your user workspace.granted lifecycle scope
test_workspaceA job handle for the workspace test suite.granted lifecycle scope
get_job_statusState and new output for a build or test job.granted lifecycle scope
launch_runtimeLaunch of the runtime for the bound target.granted lifecycle scope

Stop the Runtime through MoveIt Pro's terminal or application controls. MCP does not stop it because container shutdown cannot atomically prevent a new Objective from starting; exposing that operation would risk removing robot controllers during execution.

build_workspace and test_workspace return immediately with a job_id rather than holding the request open for the length of a build. Poll get_job_status(job_id, output_offset) and pass back the output_offset it returns to read only what is new, so compiler errors are readable while the build is still running.

get_capabilities is advisory. Each tool rechecks its required provider and capabilities immediately before execution. An authorized but unavailable tool returns a structured result containing available: false, its missing capabilities, a remedy, remedy_tool naming the authorized tool that resolves it when one exists, and the immutable target_id.

The default host-network deployment uses a cooperative Agent identity handshake before any ROS-backed result is accepted. It detects a missing, stale, or wrong deployment, but plain DDS cannot prove the identity of a hostile local peer. Named instances use an isolated network namespace and managed DDS configuration. Closing the cooperative deployment's hostile-peer limit requires instance isolation, SROS2, or an authenticated remote runtime provider.

Resources

  • moveit-pro://catalog/behaviors — the Behavior catalog as JSON.
  • moveit-pro://config/current — the selected robot configuration.
  • moveit-pro://robot/urdf — the robot URDF; requires the matching runtime.
  • moveit-pro://objective/{objective_id} — one Objective's parsed JSON.

Remote client: connect from another computer

The HTTP server runs with the REST backend on the Runtime computer. The AI client runs on the client computer and connects with:

  • URL: https://<runtime-host>:<rest-port>/mcp
  • Header: Authorization: Bearer <MOVEIT_MCP_HTTP_KEY>
  • TLS verification for the Runtime certificate or its issuing CA

MOVEIT_MCP_HTTP_KEY is the 64-character lowercase hexadecimal value printed by moveit_pro mcp http-key on the Runtime computer. It is derived from, but is not the same as, the frontend key. Do not give an AI client the frontend key: that credential also authenticates the broader REST backend.

Streamable HTTP is the preferred transport for a remote client. It uses the deployment's existing TLS certificate and requires Authorization: Bearer <MOVEIT_MCP_HTTP_KEY> on every MCP request; browser CORS preflight requests remain unauthenticated. Install or trust the MoveIt Pro Runtime certificate as described in Endpoint Security. HTTP sessions have the read-only deployment tools. They do not receive local workspace, build, or Runtime-lifecycle authority.

Start the server on the Runtime computer

There is no separate HTTP MCP process to install or start. The /mcp endpoint starts automatically with the authenticated REST backend.

Start MoveIt Pro normally. The CLI creates and stores the deployment frontend key automatically. Print its domain-separated MCP credential on the Runtime computer when configuring an AI client:

moveit_pro mcp http-key

Rotating the frontend key also rotates this derived MCP key, so update clients after a rotation. For a direct remote connection, allow the exact Host header that the client will send before starting the Runtime:

export MOVEIT_MCP_ALLOWED_HOSTS="robot.example.com:3200"
moveit_pro run -c my_robot_config

The default REST port is 3200; named instances use their assigned REST port. The discovery service on port 3204 reports those ports. A native MCP client normally omits Origin. If a browser-based client sends one, also set MOVEIT_MCP_ALLOWED_ORIGINS to its exact origin before starting the Runtime.

Configure TLS and authentication on the client computer

Verify TLS before allowing the client to send the MCP HTTP key:

  • For a direct hostname or IP address, use a certificate signed by a CA the client trusts and whose subject alternative names cover the MCP URL.

  • The generated Runtime certificate covers loopback names. For a private or tunneled development connection, copy cert.pem to the client through an authenticated channel such as SSH, trust it only for this connection, and connect through loopback. The generated certificate is at ~/.local/share/moveit_pro/tls/cert.pem by default, or under MOVEIT_TLS_CERT_DIR when that variable is set. For example:

    scp <runtime-user>@<runtime-host>:~/.local/share/moveit_pro/tls/cert.pem \
    /owner-only/path/runtime-cert.pem
    ssh -N -L 13200:127.0.0.1:3200 <runtime-user>@<runtime-host>

    Keep the tunnel open and use https://localhost:13200/mcp. Loopback Host values are allowed without MOVEIT_MCP_ALLOWED_HOSTS.

The MoveIt Pro desktop app performs frontend-key-authenticated certificate pairing automatically for its own Electron gateway. That paired certificate, stored key, and local gateway are deliberately not exported to other processes. An MCP client on the same computer is configured separately with its own TLS trust and MCP-only bearer key. The desktop profile's Alternate hostname or IP address also applies only to Electron; set the MCP URL or SSH tunnel to the route that the MCP client should use.

Native HTTP clients must support MoveIt Pro's sessionless MCP 2026-07-28 protocol. The mcp-remote bridge shown below adapts stdio clients to that HTTP protocol. For example, a Cursor user can create ~/.cursor/mcp.json on the client computer (or .cursor/mcp.json in a project):

{
"mcpServers": {
"moveit-pro": {
"url": "https://robot.example.com:3200/mcp",
"headers": {
"Authorization": "Bearer <MOVEIT_MCP_HTTP_KEY>"
}
}
}
}

Use the client's credential or environment-variable support instead of storing the key in plaintext when available. If the client config contains the key, make the file owner-only.

Claude Desktop's remote connector flow is for internet-reachable servers using authless or OAuth authentication. It does not use the client computer's LAN, VPN, Tailscale route, or SSH tunnel, and Claude Desktop does not load a remote HTTP server directly from claude_desktop_config.json. For a private Runtime protected by a MoveIt Pro MCP bearer key, configure a local stdio-to-HTTP bridge in that file. This example uses mcp-remote; pin and review the bridge version your organization approves:

{
"mcpServers": {
"moveit-pro": {
"command": "npx",
"args": [
"-y",
"mcp-remote@0.1.38",
"https://localhost:13200/mcp",
"--transport",
"http-only",
"--header",
"Authorization:${MOVEIT_MCP_AUTHORIZATION}"
],
"env": {
"MOVEIT_MCP_AUTHORIZATION": "Bearer <MOVEIT_MCP_HTTP_KEY>",
"NODE_EXTRA_CA_CERTS": "/absolute/path/to/copied-runtime-cert.pem"
}
}
}
}

mcp-remote@0.1.38 expands ${MOVEIT_MCP_AUTHORIZATION} in the header argument from the bridge environment. Set it to Bearer followed by the MoveIt Pro MCP HTTP key, as shown above; Claude Desktop only supplies the environment to the local bridge.

This bridge runs on the client computer, so it can use the client's private network and tunnel. Start the SSH tunnel before Claude Desktop. If the tunnel closes, restore it and restart Claude Desktop so the app respawns the bridge. A Server disconnected error with ECONNREFUSED on the forwarded local port means that no tunnel is listening there. Protect the configuration as an owner-only file and restart Claude Desktop after editing it.

On macOS or WSL, Claude Code can import the same client-local bridge instead of duplicating it:

claude mcp add-from-claude-desktop --scope user

Claude Code applies its own permission policy after connecting. An interactive session can approve the read tools when first used. A non-interactive session running with --permission-mode dontAsk must explicitly allow the desired mcp__moveit-pro__... tools with --allowedTools or in Claude Code settings; otherwise Claude Code rejects the calls without asking even though the MCP server marks them read-only.

Codex CLI and the Codex desktop app use the same local MCP configuration. Add the client-local bridge to the owner-only ~/.codex/config.toml file so the key is not placed in shell history or the codex mcp add process arguments:

[mcp_servers.moveit-pro]
command = "npx"
args = [
"-y",
"mcp-remote@0.1.38",
"https://localhost:13200/mcp",
"--transport",
"http-only",
"--header",
"Authorization:${MOVEIT_MCP_AUTHORIZATION}",
]

[mcp_servers.moveit-pro.env]
MOVEIT_MCP_AUTHORIZATION = "Bearer <MOVEIT_MCP_HTTP_KEY>"
NODE_EXTRA_CA_CERTS = "/absolute/path/to/copied-runtime-cert.pem"

Here too, mcp-remote expands the authorization value from its environment; Codex does not need to interpolate the placeholder itself.

Codex also supports env_vars when a separately managed parent environment provides these values. After changing either desktop client's configuration, restart the app and open a new conversation so it discovers the new tool catalog.

Same machine: install on the Runtime computer

Use stdio when the AI client and the MoveIt Pro workspace are on the same computer. Run the install command on that workspace/Runtime computer, not on a separate laptop running only the MoveIt Pro desktop app. The Runtime may be stopped when the MCP session starts; workspace tools remain available and Runtime tools become available when the matching Runtime starts. The generated command needs the local workspace, MoveIt Pro installation, and container runtime. The MoveIt Pro desktop app is not modified by this command.

Run the install and generated serve command as the normal account that owns the workspace and can access Docker directly. Do not use sudo or run either command as root; the launcher refuses elevated callers and maps the bootstrap to the invoking account instead of trusting saved Runtime UID/GID settings.

Install a client entry with an absolute workspace and an explicit robot configuration package:

moveit_pro mcp install \
--client claude-desktop \
--workspace /absolute/path/to/user_ws \
--config-package my_robot_config

For Cursor, use --client cursor. Restart the AI client after installation. MoveIt Pro merges the moveit-pro entry into the existing owner-only client configuration without replacing unrelated entries. The AI client starts the generated moveit_pro mcp serve command; do not start a separate server by hand during normal use.

Claude Code and Codex can register that same Runtime-local bootstrap directly:

claude mcp add --scope user moveit-pro -- \
moveit_pro mcp serve \
--workspace /absolute/path/to/user_ws \
--config-package my_robot_config \
--client-id claude-code

codex mcp add moveit-pro -- \
moveit_pro mcp serve \
--workspace /absolute/path/to/user_ws \
--config-package my_robot_config \
--client-id codex

Run these commands on the Runtime computer, because the spawned bootstrap uses that computer's workspace and container runtime.

Grant local lifecycle tools

Without a policy, local stdio exposes workspace and Runtime reads but not host configuration, build, test, or launch tools. Grant only the operations a client needs with an owner-only, target-bound policy. For example:

{
"version": 1,
"policy_id": "local-authoring",
"resource_audience": "moveit-pro-mcp",
"workspace": "/absolute/path/to/user_ws",
"config_package": "my_robot_config",
"instance": null,
"granted_scopes": [
"runtime:config",
"runtime:build",
"runtime:test",
"runtime:launch"
],
"confirmation": "policy",
"expires_at": "REPLACE_WITH_TIMEZONE_QUALIFIED_ISO_8601"
}

Replace expires_at with a timezone-qualified future timestamp and remove scopes the client does not need. The effective session lifetime is capped at eight hours even if the policy expires later. Create the file under the workspace owner's account with an owner-only umask before editing it:

umask 077
touch /absolute/path/to/mcp-policy.json
chmod 600 /absolute/path/to/mcp-policy.json
$EDITOR /absolute/path/to/mcp-policy.json

Then include it when installing the desktop entry:

moveit_pro mcp install \
--client claude-desktop \
--workspace /absolute/path/to/user_ws \
--config-package my_robot_config \
--policy /absolute/path/to/mcp-policy.json

For Claude Code or Codex, append the same --policy option to the moveit_pro mcp serve command. Rerun mcp install and restart the client after changing the policy. Policy files accept confirmation: "policy" only; a model-supplied confirmation or ordinary client elicitation is not a trusted host grant.

Granting runtime:config, runtime:build, or runtime:test authorizes the workspace's package generators, build files, and tests to execute as the local OS user. Grant these scopes only to a client and workspace whose code you trust.

To print configuration for a project-local file or another MCP client:

moveit_pro mcp install \
--client cursor \
--workspace /absolute/path/to/user_ws \
--config-package my_robot_config \
--print

If the workspace contains exactly one discoverable robot configuration package, --config-package may be omitted. MoveIt Pro refuses to guess when there are zero or multiple candidates. Add --instance <name> to bind a named deployment.

For a named instance, stdio runtime reads never bind to the host DDS graph. They are proxied over the session's authenticated host channel to the exact labeled Agent container of that instance, so get_execution_status, get_robot_state, and the URDF resource work over stdio just as they do over the backend's authenticated HTTP endpoint. RUNTIME remains unavailable until that instance's containers are running.

The generated command runs moveit_pro mcp serve. Each client connection:

  1. creates an immutable OS-user principal and target binding;
  2. creates isolated config and private session state;
  3. starts one docker compose run --rm --no-deps -T container;
  4. reserves stdout for MCP JSON-RPC and sends setup diagnostics to stderr;
  5. verifies the invoking account is non-root, maps that account into the container, and drops entrypoint privileges before the MCP server starts; and
  6. removes its container, credential, and socket on disconnect.

Containers and runtime directories carry a session ID. The next serve removes orphaned sessions left by abnormal termination, and session credentials also have an absolute expiry. Security audit logs are retained separately from the ephemeral credential directory. Authorized host-control intent is recorded before any effect and followed by its outcome. Read-only polling stays quiet; repeated read-side target failures are retained once per session, provider, and reason instead of growing durable storage with request volume.

Workspace, capabilities, and local authority

The stdio session bind-mounts its canonical workspace read-only, plus isolated materialized config, target log directory, DDS inputs, and—when configured—the private typed provider files. It mounts no Docker socket and no devices. The container has a reduced capability set only during setup, clears supplementary groups, enables no-new-privileges, and runs the server as the invoking host-mapped non-root user. Fixed Runtime probes also use that non-root UID/GID; they never rely on the Runtime container's default root exec user.

Different workspaces, robot configuration packages, deployments, and instances receive separate session state. Toolchain and lifecycle operations for the same canonical workspace use a host advisory exclusion lock. A competing session receives a structured TOOLCHAIN unavailable result naming the holder session rather than running a concurrent build.

Local host-shell access is already host-user authority; MCP does not turn an MCP HTTP key, ordinary remote terminal credential, or socket reachability into that authority. Consequential operations require a pre-registered, non-interactive policy. Confirmation is never a model-supplied tool argument.

Protocol version

The server speaks the sessionless MCP 2026-07-28 protocol on both transports.

Privacy considerations

Tool and resource results are sent to the connected AI client, which may be an external service. In particular, get_recent_logs forwards log lines. Avoid writing tokens, passwords, or private endpoint URLs to custom Behavior logs.

Troubleshooting

  • HTTP returns 401 Unauthorized. Send the derived key from moveit_pro mcp http-key as a bearer token.
  • HTTP returns 421 Misdirected Request. Add the exact Host header, including its port, to MOVEIT_MCP_ALLOWED_HOSTS.
  • HTTP returns 503 with "MCP endpoint unavailable". The MCP subsystem failed to start with the rest of the backend — the response body carries the reason (for example a misconfigured target identity, audit location, or transport allowlist). Fix the configuration and restart MoveIt Pro; this is not a transient outage.
  • HTTP returns 403 Invalid Origin header. Add the browser client's exact origin to MOVEIT_MCP_ALLOWED_ORIGINS; native clients should omit Origin.
  • HTTP returns 408 Request Timeout. The full request body must arrive within 30 seconds; check for a slow or unreliable network link between the client and the deployment.
  • HTTP returns 413 Request Entity Too Large. Keep a request at most 1 MiB.
  • HTTP returns 429 Too Many Requests. Respect Retry-After; one worker admits at most 16 concurrent MCP requests.
  • HTTP returns 504 Gateway Timeout. The server bounds how long a single MCP request may spend processing after upload. A healthy deployment answers well inside that bound; a 504 usually points at unresponsive storage backing the robot configuration or log directories.
  • TLS verification fails. Trust the backend certificate or its CA. Do not disable verification for a remote deployment.
  • No stdio tools appear. Run the generated moveit_pro mcp serve command in a terminal and inspect stderr. Rerun mcp install after changing the workspace, robot configuration package, instance, or installation.
  • ACTIVE_CONFIG is unavailable. Run the generated moveit_pro mcp serve command in a terminal and inspect stderr. Fix the reported robot configuration package error, build the package, then restart the MCP connection so a new isolated session can materialize it. Changing the configuration package requires a new session.
  • RUNTIME is unavailable. Start the matching target. A runtime answering with missing or different deployment identity is deliberately ignored.
  • The URDF resource is unavailable. It requires the matching runtime's latched /robot_description.