diff --git a/src/content/docs/getting-started/first-connection.mdx b/src/content/docs/getting-started/first-connection.mdx index 45ae841..72af95f 100644 --- a/src/content/docs/getting-started/first-connection.mdx +++ b/src/content/docs/getting-started/first-connection.mdx @@ -13,7 +13,7 @@ This tutorial walks you through physically connecting to your dish, finding the - A Winegard dish with power supply, plugged in - The correct serial adapter for your variant (see [What You Need](/getting-started/)) -- `birdcage` and `console-probe` installed via `uv sync` +- `birdcage` and `console-probe` installed (`uvx winegard-birdcage --help` to verify, or `uv sync` from source) ## Connect to the firmware console @@ -98,6 +98,10 @@ This tutorial walks you through physically connecting to your dish, finding the ```bash + # uvx (no clone needed) + uvx winegard-birdcage pos --port /dev/ttyUSB0 --firmware hal205 + + # or from source uv run birdcage pos --port /dev/ttyUSB0 --firmware hal205 ``` @@ -110,6 +114,10 @@ This tutorial walks you through physically connecting to your dish, finding the ```bash + # uvx (no clone needed) + uvx winegard-birdcage pos --port /dev/ttyUSB2 --firmware g2 + + # or from source uv run birdcage pos --port /dev/ttyUSB2 --firmware g2 ``` @@ -128,6 +136,10 @@ This tutorial walks you through physically connecting to your dish, finding the To see what the firmware offers, you can use `console-probe` in discover-only mode: ```bash + # uvx (no clone needed) + uvx winegard-birdcage console-probe --port /dev/ttyUSB2 --baud 115200 --discover-only + + # or from source uv run console-probe --port /dev/ttyUSB2 --baud 115200 --discover-only ``` diff --git a/src/content/docs/guides/mcp.mdx b/src/content/docs/guides/mcp.mdx new file mode 100644 index 0000000..3408804 --- /dev/null +++ b/src/content/docs/guides/mcp.mdx @@ -0,0 +1,180 @@ +--- +title: "MCP Server" +description: Control the dish from Claude Code or any MCP client — 37 tools for motor control, signal measurement, satellite tracking, and firmware management. +sidebar: + order: 9 + badge: + text: New + variant: tip +--- + +import { Aside, Steps, Tabs, TabItem, Card, CardGrid, LinkCard } from '@astrojs/starlight/components'; + +The Birdcage MCP server (`mcbirdcage`) exposes the full dish control surface as MCP tools, resources, and prompts. Any MCP-compatible client — Claude Code, Claude Desktop, a custom agent, anything that speaks the protocol — can connect a serial port, slew motors, measure signal strength, query orbital catalogs, and read firmware registers. Demo mode works without hardware. + +The same device layer that backs the [TUI](/guides/tui/) backs the MCP server. The difference is who's driving: a person pressing arrow keys, or a language model calling `move_to(azimuth=180, elevation=45)`. + +## Quick Start + + + + ```bash + # Demo mode — no hardware, no serial port + BIRDCAGE_DEMO=true uvx mcbirdcage + + # Add to Claude Code + claude mcp add mcbirdcage -- uvx mcbirdcage + + # With hardware + BIRDCAGE_PORT=/dev/ttyUSB0 uvx mcbirdcage + ``` + + + ```bash + cd mcp/ + uv sync + + # Demo mode + BIRDCAGE_DEMO=true uv run mcbirdcage + + # Add to Claude Code (local dev) + claude mcp add mcbirdcage -- uv run --directory /path/to/mcp mcbirdcage + ``` + + + +### Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `BIRDCAGE_DEMO` | `false` | Set `true` to use DemoDevice (simulated motors, RSSI, full NVS table) | +| `BIRDCAGE_PORT` | `/dev/ttyUSB0` | Serial port path for hardware mode | +| `BIRDCAGE_FIRMWARE` | `g2` | Firmware variant: `g2`, `hal205`, or `hal000` | +| `BIRDCAGE_CRAFT_URL` | `https://space.warehack.ing` | Orbital catalog API endpoint | + + + +## Tools + +36 tools across 6 modules. Every tool that touches hardware requires a prior `connect` call (or demo mode). + +### Connection + +| Tool | Parameters | Description | +|------|-----------|-------------| +| `connect` | `port?` `firmware?` `skip_init?` | Open serial port, optionally run firmware init sequence | +| `disconnect` | — | Close serial port, return to root menu | +| `status` | — | Connection state, port, firmware variant, current menu | + +### Movement + +| Tool | Parameters | Description | +|------|-----------|-------------| +| `get_position` | — | Current AZ/EL in degrees | +| `move_to` | `azimuth` `elevation` | Move both axes to absolute position (AZ 0-455, EL 18-65 for G2) | +| `move_motor` | `motor_id` `degrees` | Move single axis (0=AZ, 1=EL) to absolute angle | +| `home_motor` | `motor_id` | Stall-detect homing to reference position (audible grinding) | +| `engage_motors` | — | Energize steppers (apply holding torque) | +| `release_motors` | — | De-energize steppers (dish free under wind/gravity) | +| `stow` | — | Move to AZ=0, EL=65 (transport-safe with stock feed) | +| `get_step_positions` | — | Raw step counts (G2: 40000 steps/rev AZ, 24960 EL) | +| `get_el_limits` | — | Firmware EL limits: min, max, home (degrees) | + +### Signal + +| Tool | Parameters | Description | +|------|-----------|-------------| +| `get_rssi` | `iterations?` (default 10) | Averaged DVB tuner RSSI (noise floor ~500) | +| `get_adc_rssi` | — | Single-shot raw ADC count (bypasses DVB averaging) | +| `get_lock_status` | — | DVB signal lock, RSSI, glitch count | +| `enable_lna` | — | Set LNB to 13V / V-pol (powers LNA for radio work) | +| `set_lnb_voltage` | `mode` (`odu` or `stb`) | 13V/V-pol (`odu`) or 18V/H-pol (`stb`). Boot default is 18V. | +| `get_dvb_config` | — | BCM4515 chip ID, revision, firmware version | +| `get_channel_params` | — | Frequency, symbol rate, modulation, LNB polarity | +| `az_sweep` | `start_az` `span` `step_cdeg?` `num_xponders?` `timeout?` | Firmware-accelerated AZ sweep (`azscanwxp`). Returns per-point RSSI/lock/SNR. Requires homed motors. | + +### System + +| Tool | Parameters | Description | +|------|-----------|-------------| +| `get_firmware_id` | — | Full MCU/firmware ID: version, silicon, board, clock, flash layout | +| `get_motor_dynamics` | — | Max velocity and acceleration for both axes | +| `set_max_velocity` | `motor_id` `deg_per_sec` | Set motor max velocity (G2 defaults: AZ=65, EL=45 deg/s) | +| `set_max_acceleration` | `motor_id` `accel` | Set motor max acceleration (G2 default: 400 deg/s^2) | +| `get_motor_life` | — | Lifetime stats: total moves, degrees traveled, uptime hours | +| `get_pid_gains` | — | PID gains for both axes (Kp, Kv, Ki) | +| `set_pid_gains` | `motor_id` `kp` `kv` `ki` | Set PID gains. Bad values cause oscillation or motor damage. | +| `get_a3981_diag` | — | Allegro A3981 stepper driver fault status (OK or FAULT per axis) | +| `get_a3981_modes` | — | Step mode (AUTO/fixed), current mode, step size per driver | +| `nvs_dump` | — | Full 134-entry NVS table: name, current, saved, default | +| `nvs_read` | `index` | Single NVS value (key indices: 20=tracker, 80=AZ vel, 101=min EL) | + +### Satellite + +Satellite tools use the [Craft API](https://space.warehack.ing) for orbital predictions. The API computes AZ/EL server-side from TLE data — no local propagation needed. + +| Tool | Parameters | Description | +|------|-----------|-------------| +| `search_satellites` | `query` `limit?` | Search catalog by name ("ISS", "NOAA", "Moon"). Returns NORAD ID, type, group. | +| `get_passes` | `norad_id` `hours?` | Upcoming passes: AOS/TCA/LOS times, max EL, duration | +| `get_next_pass` | `norad_id` | Single soonest pass prediction | +| `get_visible_targets` | `min_alt?` | All objects currently above horizon with live AZ/EL | + +### Console + +| Tool | Parameters | Description | +|------|-----------|-------------| +| `send_raw_command` | `command` | Send arbitrary firmware command, return raw response. The `q` command is blocked (kills UART shell, requires power cycle). | + +## Resources + +Five read-only MCP resources provide live dish state without tool calls. Clients can subscribe to these for continuous monitoring. + +| URI | Description | +|-----|-------------| +| `birdcage://config` | Connection config: demo mode, port, firmware variant, connected flag | +| `birdcage://position` | Live AZ/EL (queries hardware on each read) | +| `birdcage://firmware` | Firmware identification string | +| `birdcage://motor-dynamics` | Max velocity and acceleration for both axes | +| `birdcage://el-limits` | Elevation min/max/home in degrees | + +## Prompts + +Three guided workflows that walk an LLM through multi-step operations. Call them to get a structured plan with tool names and sequencing. + +| Prompt | Workflow | +|--------|----------| +| `setup_wizard` | Connect to serial port, verify firmware, home both motors, confirm position and EL limits | +| `satellite_tracking_guide` | Search catalog, get passes, wait for AOS, poll `get_visible_targets` + `move_to` at 1 Hz | +| `rf_sweep_guide` | Enable LNA, baseline RSSI, configure and run `az_sweep`, analyze peaks above noise floor | + +## Example Workflows + +These are things an LLM can do with the tool set — not scripts to execute, but descriptions of how the tools compose. + +### Track the ISS + +Search the catalog for "ISS". The result includes NORAD ID 25544. Call `get_passes` with that ID to see upcoming passes — pick one with max elevation above 30 degrees for a decent arc. When the AOS time arrives, start a loop: call `get_visible_targets` to get the ISS's current AZ/EL (computed server-side from fresh TLEs), then `move_to` with those coordinates. Repeat every second. The firmware queues motor commands, so the dish follows the arc smoothly even if individual moves are still in progress. Stop when the satellite drops below the dish's minimum elevation (18 degrees on the G2). The whole sequence is about 5-10 minutes for a typical LEO pass. + +### RF Sky Survey + +Enable the LNA with `enable_lna` (switches LNB from 18V boot default to 13V / V-pol). Call `get_rssi` to read the noise floor — should be around 500 ADC counts with no signal present. Move the dish to a starting position with `move_to(0, 30)`. Run `az_sweep` with a wide span (e.g., 180 degrees, 100 centidegree steps, 1 transponder). The firmware handles the sweep natively — no serial round-trips per point. Repeat at EL 35, 40, 45, ... up to 60, using `move_motor(1, el)` between sweeps. The result is a 2D grid of RSSI values mapped to AZ/EL coordinates. Peaks above the noise floor correspond to geostationary satellites, terrestrial interference, or (at Ku-band) the Sun. + +### Firmware Inspection + +Call `get_firmware_id` for the full MCU identification — version 02.02.48, NXP K60 at 96 MHz, 512 KB flash. Call `get_a3981_diag` to confirm both stepper drivers report OK. Call `nvs_dump` for the complete 134-entry non-volatile storage table, then spot-check critical values: NVS 20 (tracker disabled), NVS 80-81 (motor velocity/acceleration), NVS 101-102 (elevation limits). For anything not covered by a dedicated tool, drop to `send_raw_command` — enter a submenu with `mot` or `dvb`, issue the command, and read the raw response. + + + + + + +