README.md

<!--
SPDX-FileCopyrightText: 2026 James Harton

SPDX-License-Identifier: Apache-2.0
-->

# BB.MCP

Model Context Protocol (MCP) server for [Beam Bots](https://github.com/beam-bots/bb) robots.

`bb_mcp` lets AI agents (Claude Desktop, Claude Code, custom LLM agents) drive
your BB-powered robots over the standard [Model Context
Protocol](https://modelcontextprotocol.io/). Every robot you list at startup
exposes its safety controls, declared commands, runtime parameters, and live
state to any connected MCP client.

## Status

Early. Multi-robot, no authentication — assume a trusted local or LAN
environment.

## Installation

Add `bb_mcp` to your dependencies:

```elixir
def deps do
  [
    {:bb_mcp, "~> 0.1"}
  ]
end
```

Or run the installer:

```bash
mix igniter.install bb_mcp
```

## Usage

List the robots to expose in config:

```elixir
# config/config.exs
config :bb_mcp, robots: [MyApp.WX200, MyApp.SO101]
```

Start the server alongside your robots in the supervision tree:

```elixir
children = [
  MyApp.WX200,
  MyApp.SO101,
  {BB.MCP.Server, transport: :streamable_http, streamable_http: [port: 4000]}
]
```

Or mount it in a Phoenix router (Streamable HTTP transport):

```elixir
defmodule MyAppWeb.Router do
  use Phoenix.Router
  import BB.MCP.Router

  scope "/" do
    bb_mcp "/mcp"
  end
end
```

## What gets exposed

For each robot, agents see:

### Tools

Cross-cutting tools — each takes a `robot` string argument selecting
the target robot:

| Tool                | Source                       |
|---------------------|------------------------------|
| `list_robots`       | configured robots index      |
| `get_state`         | `BB.Safety.state/1` + `BB.Robot.Runtime` |
| `force_disarm`      | `BB.Safety.force_disarm/1`   |
| `list_commands`     | `BB.Dsl.Info.commands/1`     |
| `list_parameters`   | `BB.Parameter.list/2`        |
| `get_parameter`     | `BB.Parameter.get/2`         |
| `set_parameter`     | `BB.Parameter.set/3`         |
| `send_joint_positions` | `BB.Motion.send_positions/3` |
| `query_events`      | per-session `BB.PubSub` ring buffer |

Per-command tools (×N) — one tool per `{robot, command}` pair declared
in each robot's Spark DSL, registered at session startup. Tool name is
`{robot}.{command}` (e.g. `wx200.home`); the input schema is derived
from the command's typed arguments. Dispatch goes through
`BB.Robot.Runtime.execute/3` + `BB.Command.await/2`. The built-in
`arm`/`disarm` commands surface as `{robot}.arm` and `{robot}.disarm`.

### Resources

- `bb://robots` — index of configured robots
- `bb://robots/{robot}/topology` — links, joints, sensors, actuators
- `bb://robots/{robot}/state` — operational state, safety state, running commands
- `bb://robots/{robot}/joints` — current joint positions and velocities
- `bb://robots/{robot}/commands` — declared commands and their argument schemas
- `bb://robots/{robot}/parameters` — registered parameters with current values

## Licence

Apache-2.0. See `LICENSES/Apache-2.0.txt`.