Four new tools transforming the SkyWalker-1 from satellite TV receiver into a general-purpose RF observatory: - skywalker-mcp: FastMCP server exposing 20 tools, 4 resources, 2 prompts. Thread-safe DeviceBridge with motor safety (continuous drive opt-in), input validation on all frequency/symbol rate/step parameters, try/finally on TS capture, path traversal sanitization, and reduced lock scope so emergency motor halt isn't blocked during long surveys. - h21cm.py: Hydrogen 21 cm drift-scan radiometer at 1420.405 MHz with Doppler velocity calculation, control band comparison, and CSV output. - beacon_logger.py: Long-term Ku-band beacon SNR/AGC logger with auto-relock, dual CSV/JSONL output, signal handlers, and systemd unit generation. - arc_survey.py: Multi-satellite orbital arc census with USALS motor control, per-slot catalog persistence, resume support, and defensive motor halt on all error/interrupt paths. Documentation: experimenter's roadmap guide + 4 tool reference pages (48 pages total).
113 lines
3.7 KiB
Plaintext
113 lines
3.7 KiB
Plaintext
---
|
|
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__*"
|
|
```
|