---
title: mcpositioner Overview
description: MCP server for ESP32 dual-axis antenna positioner
---

import { Aside } from '@astrojs/starlight/components';

mcpositioner gives AI assistants control of an ESP32-based dual-axis antenna positioner over WiFi. It drives two NEMA 17 stepper motors via TMC2209 drivers for theta (polar, 0-180°) and phi (azimuth, 0-360°) rotation.

## Purpose

Automated 3D antenna radiation pattern measurement. The positioner physically rotates an antenna under test through a theta/phi grid while a VNA measures transmission (S21) at each position.

## Capabilities

- **Absolute positioning**: Move to any theta/phi coordinate
- **Relative moves**: Offset from current position
- **StallGuard homing**: Sensorless homing using TMC2209 stall detection
- **Emergency stop**: Immediate motor halt
- **Motion tuning**: Configurable speed, acceleration, microstepping

## Hardware Requirements

| Component | Specification |
|-----------|--------------|
| Controller | ESP32 DevKit (any variant) |
| Drivers | 2x TMC2209 in UART mode |
| Motors | 2x NEMA 17 (0.9° or 1.8° step) |
| Power | 24V for motors, 5V for ESP32 |

<Aside type="tip">
Full build instructions and KiCad schematics are in the [Hardware section](/hardware/positioner-build/).
</Aside>

## Architecture

```
┌─────────────────────────────────────────────────────────┐
│                    Claude Code                          │
│                         │                               │
│                    MCP Protocol                         │
│                         ▼                               │
│  ┌─────────────────────────────────────────────────┐   │
│  │            mcpositioner server                   │   │
│  │  ┌─────────────┐      ┌─────────────────────┐  │   │
│  │  │  tools.py   │      │   positioner.py     │  │   │
│  │  │  5 tools    │─────▶│   httpx client      │  │   │
│  │  └─────────────┘      └──────────┬──────────┘  │   │
│  └─────────────────────────────────────────────────┘   │
│                                     │                   │
│                              WiFi HTTP                  │
│                                     ▼                   │
│              ┌──────────────────────────────────────┐  │
│              │         ESP32 Firmware                │  │
│              │  ┌─────────┐  ┌──────────────────┐   │  │
│              │  │AccelStep│  │ESPAsyncWebServer │   │  │
│              │  └────┬────┘  └────────┬─────────┘   │  │
│              │       │               HTTP API       │  │
│              │       ▼                              │  │
│              │  ┌─────────────────────────────┐    │  │
│              │  │  TMC2209 UART (StallGuard)  │    │  │
│              │  └──────────┬──────────────────┘    │  │
│              └─────────────│────────────────────────┘  │
│                            ▼                           │
│              ┌──────────────────────────────────────┐  │
│              │   NEMA 17 Steppers (θ and φ axes)    │  │
│              └──────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘
```

## Network Discovery

The ESP32 firmware advertises itself via mDNS as `positioner.local`. Override with the `MCPOSITIONER_HOST` environment variable if your network doesn't support mDNS or you have multiple positioners.

```bash
# Use IP address instead of mDNS
MCPOSITIONER_HOST=192.168.1.100 uvx mcpositioner
```

## Cross-Server Workflow

mcpositioner works with [mcnanovna](/mcnanovna/overview/) for automated pattern measurement:

1. **mcpositioner**: Move antenna to theta/phi position
2. **mcnanovna**: Measure S21 transmission
3. **Repeat** across the measurement grid
4. **Assemble** pattern from collected data

The `measure_pattern_grid` prompt guides this workflow step by step.
