Current section
Files
Jump to
Current section
Files
usage-rules.md
<!--
SPDX-FileCopyrightText: 2026 James Harton
SPDX-License-Identifier: Apache-2.0
-->
# BB.MCP Usage Rules
`bb_mcp` is a [Model Context Protocol](https://modelcontextprotocol.io/) server
that exposes running [Beam Bots](https://hexdocs.pm/bb) robots to MCP clients
(Claude Desktop, Claude Code, custom LLM agents). It is **not** a `BB` DSL
component — you never wire it into a robot's `topology`. It runs alongside your
robots and reflects them as MCP tools and resources. For BB framework basics,
see `bb`'s rules (`mix usage_rules.sync <file> bb:all`); this file covers only
how to stand the server up and what it exposes.
## Core principles
1. **The server is a process, not a component.** `BB.MCP.Server` runs as a child
in your supervision tree (or is mounted into a Phoenix endpoint). It reads
the robots it exposes from application config, not from its child-spec
options.
2. **Robots are named by module tail.** Each configured robot is addressed by
the last segment of its module name, underscored and lowercased —
`MyApp.WX200` → `"wx200"`, `MyApp.Robot` → `"robot"`. A collision raises at
startup.
3. **The MCP client can arm and move the robot.** Declared commands (including
`arm`/`disarm`) and `send_joint_positions` are exposed as callable tools.
Treat a connected client as an operator with physical control.
4. **No authentication.** Assume a trusted local or LAN environment only.
## Setting it up
List the robots to expose in config:
```elixir
# config/config.exs
config :bb_mcp, robots: [MyApp.WX200, MyApp.SO101]
```
Then either run the server as a supervision child over Streamable HTTP:
```elixir
children = [
MyApp.WX200,
MyApp.SO101,
{BB.MCP.Server, transport: :streamable_http, streamable_http: [port: 4000]}
]
Supervisor.start_link(children, strategy: :one_for_one)
```
Or mount it into a Phoenix router (the endpoint serves the HTTP; `BB.MCP.Server`
must still be in the supervision tree):
```elixir
defmodule MyAppWeb.Router do
use Phoenix.Router
import BB.MCP.Router
scope "/" do
bb_mcp "/mcp"
end
end
```
`mix igniter.install bb_mcp` wires whichever of the two applies to your app.
## What gets exposed
**Cross-cutting tools** — each takes a `robot` string argument selecting the
target: `list_robots`, `get_state`, `force_disarm`, `list_commands`,
`list_parameters`, `get_parameter`, `set_parameter`, `send_joint_positions`,
`query_events`. `query_events` reads a per-session ring buffer of `BB.PubSub`
events captured since the session connected.
**Per-command tools** — one per `{robot, command}` pair declared in each robot's
DSL, registered at session start, named `{robot}.{command}` (e.g. `wx200.home`,
`wx200.arm`). Input schema is derived from the command's typed arguments;
dispatch goes through `BB.Robot.Runtime.execute/3` + `BB.Command.await/2`.
**Resources** — URI-templated by robot name: `bb://robots`,
`bb://robots/{robot}/topology`, `/state`, `/joints`, `/commands`,
`/parameters`.
## Config
| Key | Default | Meaning |
|---|---|---|
| `:robots` | `[]` | Robot modules to expose (required to expose anything) |
| `:event_buffer_size` | `1000` | Per-session `query_events` ring-buffer capacity |
## Anti-patterns
- **Don't pass `robots:` in the child spec.** The server reads its robot list
from `config :bb_mcp, robots: [...]`; options given to `{BB.MCP.Server, ...}`
are transport options only. Setting `robots:` there does nothing.
- **Don't expose the server on an untrusted network.** There is no auth; any
connected client can invoke `arm` and `send_joint_positions` and drive real
hardware. Bind it to localhost/LAN behind your own access control.
- **Don't expect motion before arming.** A robot starts `:disarmed` and refuses
motion; `send_joint_positions` requires `:armed` + `:idle`. The client arms
via the `{robot}.arm` tool, which runs the robot's prearm checks — the server
never pokes `BB.Safety` to change state. Use `force_disarm` only to clear the
`:error` state.
## Further reading
- [bb_mcp docs](https://hexdocs.pm/bb_mcp)
- `bb`'s safety rules (`bb:safety-and-commands`) and
[Understanding Safety](https://hexdocs.pm/bb/understanding-safety.html)