skywalker-1/site/src/content/docs/tools/mcp-server.mdx

113 lines
3.7 KiB
Text
Raw Normal View History

---
title: MCP Server
description: Model Context Protocol server that exposes the SkyWalker-1 hardware API to LLMs for autonomous RF exploration.
---
import { Aside, Steps } from '@astrojs/starlight/components';
The `skywalker-mcp` package wraps the entire SkyWalker-1 Python API as an MCP (Model Context Protocol)
server, making every hardware function accessible to LLMs. This enables natural-language signal analysis,
autonomous RF exploration, and scheduled observation campaigns.
## Installation
```bash
cd mcp/skywalker-mcp
uv sync
```
## Running
```bash
# Local development
uv run --directory mcp/skywalker-mcp skywalker-mcp
# Add to Claude Code
claude mcp add skywalker-mcp -- uv run --directory mcp/skywalker-mcp skywalker-mcp
```
## Tools (20)
### Device Status
| Tool | Description |
|---|---|
| `get_device_status` | Firmware version, config bits, USB speed, serial, last error |
| `get_signal_quality` | SNR, AGC, power, lock status |
| `get_stream_diagnostics` | Poll count, overflows, sync loss |
### Spectrum & Tuning
| Tool | Description |
|---|---|
| `sweep_spectrum` | Full-band power measurement with peak detection |
| `tune_frequency` | Tune to specific freq/modulation/FEC, read signal |
| `run_blind_scan` | Symbol rate sweep at single frequency |
### Survey & Catalog
| Tool | Description |
|---|---|
| `run_carrier_survey` | Six-stage pipeline: sweep → peaks → blind → TS → catalog |
| `compare_surveys` | Diff two saved catalogs for changes |
| `list_surveys` | List saved survey files with metadata |
### Dish Motor
| Tool | Description |
|---|---|
| `move_dish` | Halt, east, west, goto slot, USALS GotoX (continuous drive requires explicit opt-in) |
| `jog_dish` | Small steps (1-30) + signal quality readback |
| `store_position` | Save current position to memory slot |
### LNB & I2C
| Tool | Description |
|---|---|
| `set_lnb_config` | Voltage (13V/18V), 22 kHz tone, power off |
| `scan_i2c_bus` | Enumerate all I2C devices |
| `read_i2c_register` | Read single byte from I2C address |
### Transport Stream & Identification
| Tool | Description |
|---|---|
| `capture_transport_stream` | Capture + parse PAT/PMT/SDT for service names |
| `identify_frequency` | Look up frequency against allocation tables |
## Resources
| URI | Description |
|---|---|
| `skywalker://status` | Live device state (firmware, config, signal) |
| `skywalker://catalog/latest` | Most recent survey catalog as JSON |
| `skywalker://allocations/lband` | L-band frequency allocation table |
| `skywalker://modulations` | Supported modulations and FEC rates |
## Prompts
| Prompt | Description |
|---|---|
| `explore_rf_environment` | Strategy for autonomous RF discovery |
| `hydrogen_line_observation` | Guided 21 cm observation procedure |
## Architecture
<Aside type="note" title="Thread safety">
The BCM4500 demodulator cannot handle overlapping USB control transfers. The MCP server
uses the same `DeviceBridge` pattern as the TUI — a `threading.RLock` serializes all
hardware access. Async MCP handlers use `asyncio.to_thread()` to avoid blocking the
event loop during USB I/O.
</Aside>
The server uses FastMCP's lifespan pattern: the USB device opens on server startup and
closes on shutdown. All tools receive the device bridge through the lifespan context.
## Testing
```bash
# Verify the server starts and can talk to hardware
claude -p "What firmware version is loaded?" \
--mcp-config .mcp.json \
--allowedTools "mcp__skywalker-mcp__*"
# Run a spectrum sweep via natural language
claude -p "Sweep the full IF band and tell me what you find" \
--mcp-config .mcp.json \
--allowedTools "mcp__skywalker-mcp__*"
```