PoseCap Products
Pose CLI Available on PyPI

Pose CLI Documentation

Open motion-analysis toolkit for sports scientists. Analyze 3D skeleton data with 20+ built-in tools, or build your own — all running locally on your machine.

Overview

Pose CLI turns raw 3D body-skeleton data — from ARKit or any pose-estimation system — into actionable sports analytics. It runs entirely on your machine: your data never leaves your computer.

Available on PyPI: Pose CLI is distributed via PyPI. See Installation for details.

Pose Coach Recording → JointData3D CSV → Pose CLI → JSON Output
                                              │
                                              ├── stats
                                              ├── detect_peak_energy
                                              ├── segment_motion_phases
                                              ├── detect_velocity
                                              ├── detect_action_boundaries
                                              ├── detect_highlight
                                              ├── annotate (web UI)
                                              └── ... 15+ more

Built-in Lightweight Backend

Pose CLI includes pose serve — a zero-config local server that turns your computer into a development backend for the Pose Coach iOS app:

pose serve
# → http://0.0.0.0:8000
# → LAN  →  http://192.168.1.x:8000  (configure this on iPhone)

Requires pip install 'pose-platform[server]' (installs fastapi + uvicorn). See Installation →

Record on iPhone → skeleton files arrive on your computer automatically. Analysis, AI coach chat, training plans, and comprehensive reports all work through the same local server. The Pose Coach iOS app connects to pose serve as a full-featured backend. No database, no cloud required. Setup guide →

How Data Gets to Pose CLI

Three ways to get recordings from an iPhone (Pose Coach) to your computer:

Path A — Manual Transfer (zero setup, always works)

iPhone Record → Files App → iCloud Drive or AirDrop → Computer → pose analyze
✅ All regions    ✅ Full session folder (video + skeleton + sidecar)    ⚠ Manual per-session
• iCloud Drive: Export folder via Files App → syncs to computer via iCloud
• AirDrop: Export All Data → ZIP with all session files sent directly (Mac only)

Path B — Local Backend (one command, automatic)

iPhone Record → Your Computer (WiFi, pose serve) → pose analyze
✅ All regions    ✅ Auto upload + analysis + chat    🔧 pip install pose-platform[server,llm]
(TestFlight build required — Researcher Backend in Settings)

Path C — Cloud Backend (US/EU only)

iPhone Record → Staging API (auto upload) → pose data seed-session → Computer → pose analyze
✅ Automated      ❌ CN not accessible    ⚠ .mov not included
Path Setup Network Regions What you get
A. ManualNoneiCloud or AirDropAllFull session (video + skeleton + sidecar)
B. Local Backendpose serveSame WiFiAllSkeleton + sidecar (auto per-recording)
C. StagingBackend accessInternet (US/EU)US/EU onlySkeleton + sidecar (auto per-recording)

Recommended: Start with AirDrop (Path A) for your first session — instant, no setup. For frequent recording, set up Path B with a single command: pose serve. Full local backend setup guide →

Recording for Unsupported Sports

If you want to analyze a sport that Pose Coach doesn't officially support yet (e.g., basketball, golf, tennis):

  1. Open Pose Coach → select Freeplay as the sport
  2. Record as usual — you'll get full 3D skeleton data
  3. Transfer the data to your computer (Path A or B above)
  4. Use Pose CLI's generic tools (stats, segment_motion_phases, detect_action_boundaries, detect_highlight) to analyze
  5. Build sport-specific tools on top — see Contributing

Who is this for?

You are... You can...
Sports scientist / researcher Analyze motion data, publish papers, build new analysis tools
Coach / performance analyst Evaluate technique, track progress, compare athletes
Movement science student Learn biomechanics through hands-on data analysis
Developer / lab Build custom tools, integrate with existing pipelines

Sports as Plugins

Pose CLI uses Python entry_points to auto-discover sport packages. Built-in sports (freeplay, sprint) ship with the base install. Additional sports are installed as independent pip packages:

# Built-in (always available)
pose version
# → sports: freeplay, sprint

# Install badminton — separate package maintained by badminton researchers
pip install pose-platform[badminton]
# → installs pose-sport-badminton (v1.13.4, 8 tools)

# Or install the sport package directly
pip install pose-sport-badminton

# Create your own sport package
pose sports create basketball
# → generates sports/basketball/ scaffold with example tool
# → pip install -e sports/basketball
# → pose tools --sport basketball

# List installed sports
pose sports
Sport Package Install
freeplaybuilt-indefault
sprintbuilt-indefault
badmintonpose-sport-badmintonpip install pose-platform[badminton]
basketball (template)create via pose sports createpip install -e sports/basketball
your sportyour packagepip install pose-sport-<name>

For researchers: Sport packages are independent PyPI packages maintained by domain experts. Each has its own version, release cycle, and maintainer. See Contributing →

Web Annotation Tool

Label recordings interactively in your browser with synchronized video + 2D skeleton overlay:

pose annotate serve data/session.csv
# → opens http://localhost:8001

Click and drag on the timeline to mark actions (sprint phases, swings, shots). Annotations serve as ground truth for calibration and algorithm validation.

Prerequisites

The web annotator needs both the skeleton CSV AND the original video (.mov). Video is included via iCloud Drive or AirDrop (Path A), but NOT via local backend or staging (Paths B/C).

Interface

  • Left panel: Video player with 2D skeleton overlay (15 bones, 21 joints) + playback controls
  • Right panel: Annotations list + creation form (start/end time, label, quality, notes)

CLI Commands

# Create an annotation
pose annotate create data/session.csv --start 2.3 --end 3.1 --label "sprint_drive"

# List all annotations
pose annotate list data/session.csv

# Open the web UI
pose annotate serve data/session.csv

Calibration Workflow

  1. Annotate recordings (web or CLI) — pose annotate serve
  2. Auto-score annotated strokes — pose calib auto-label
  3. Review and correct scores (expert review)
  4. Validate tool agreement — pose calib validate

Key Principles

  • Your data stays local. All analysis runs on your machine. No cloud upload required.
  • Built-in local backend. pose serve gives you a full development backend — iPhone auto-upload, analysis, and AI chat all work locally.
  • One tool, all products. Build a tool once — it works in CLI, Pose Coach app, or your custom app.
  • Extensible by design. Every tool is a Python class. Write your own, register it, and it's available everywhere.
  • Cache built-in. Analysis results are automatically cached. Re-run the same file → instant result.

Quickstart — 5 Minutes

Get from zero to your first analysis.

Step 1: Install

pip install pose-platform
pose version

Step 2: Get sample data

Pose CLI ships with a sample sprint recording — no download needed:

pose sample
# → sample_sprint.csv copied to current directory (438 KB)

Step 3: Run your first analysis

pose analyze sample_sprint.csv --tool stats

You'll see a JSON report with recording duration, frame rate, joint count, jitter ratio, data quality assessment, and per-joint statistics.

  • data_quality: "good" — tracking is reliable
  • tracking_coverage: 0.98 — 98% of frames have valid skeleton data
  • jitter_ratio < 0.1 — excellent stability

Step 4: Try more tools

# Find motion segments (running vs standing)
pose analyze sample_sprint.csv --tool segment_motion_phases

# Detect velocity peaks
pose analyze sample_sprint.csv --tool detect_velocity --param joint=body_position

# Extract highlight moments
pose analyze sample_sprint.csv --tool detect_highlight --param sport_id=sprint

# Measure running speed with athlete profile
pose analyze sample_sprint.csv --tool measure_running_speed \
    --param age=16 --param gender=male --param region=cn

Step 5: Use your own data

pose analyze /path/to/your/data.csv --tool stats

Point pose analyze at your own JointData3D CSV. See Data Format for how to prepare data from other pose-estimation systems.

Step 6: Record your own data with Pose Coach

The easiest way to get JointData3D files is to record with the Pose Coach iOS app.

On Windows? Skip straight to "Automatic uploads" below — pose serve runs natively on Windows and avoids AirDrop entirely.

Quick start (no setup):

  1. Install Pose Coach via TestFlight (ask us for an invitation)
  2. Record a session — select Freeplay as the sport
  3. Transfer data to your computer:
  • AirDrop (fastest, macOS only — Windows has no AirDrop client): playback menu → Export All Data → AirDrop to your Mac
  • iCloud Drive (works on Windows too): tap export → Save to Files → iCloud Drive → install iCloud for Windows (Microsoft Store), sign in with the same Apple ID, then grab the file from the synced local folder
  1. Run pose analyze on the _3d.csv file

Automatic uploads (one command, recommended for Windows):

  1. Install with server extras:
pip install 'pose-platform[server,llm]'
  1. Start the local backend:
pose serve
# → LAN  →  http://192.168.1.x:8000
  1. In Pose Coach Settings → Researcher Backend → Custom URL → enter your computer's LAN IP
  2. Record — skeleton files arrive automatically in your pose-data/ directory
  3. Analysis and AI coach chat work directly in the app (routed to your local server)

Full local backend guide →

Installation

Requirements

Dependency Minimum Recommended
Python3.103.12+
pip22.024.0+
OSmacOS 12+ / Linux (glibc 2.28+) / Windows WSL2
Disk~500 MB (with dependencies)

Method 1: pip (recommended)

pip install pose-platform
pose version

Method 2: From Source (for tool developers)

git clone https://github.com/posecap/pose-platform.git
cd pose-platform
pip install -e .

The -e flag installs in "editable" mode — changes to source take effect immediately.

Method 3: Virtual Environment

python3 -m venv pose-env
source pose-env/bin/activate        # macOS / Linux
# pose-env\Scripts\activate         # Windows

pip install pose-platform

Optional Dependencies

# Sport packages — install domain-specific analysis tools
pip install 'pose-platform[badminton]'         # Badminton: swing detection, stroke classification, scoring
# pip install 'pose-platform[basketball]'     # Basketball (future)

# All sports
pip install 'pose-platform[all-sports]'

# Local backend (pose serve) — receive iPhone uploads + run analysis server
pip install 'pose-platform[server]'

# LLM chat (pose chat) — three modes available
pip install 'pose-platform[llm]'                   # REPL mode (openai SDK)
pip install 'pose-platform[mcp]'                   # Claude Code mode (mcp SDK, >=1.0,<2.0)

# Everything — all sports + backend + AI chat
pip install 'pose-platform[all]'

# Claude Code frontend (optional, for --mode claude / --mode claude-ds)
npm install -g @anthropic-ai/claude-code
Extra Includes Used by
[badminton]pose-sport-badmintonBadminton analysis
[all-sports]all sport packagesMulti-sport research
[server]fastapi, uvicorn, python-multipartpose serve
[llm]openai, anthropicpose chat, pose serve /chat
[mcp]mcp>=1.0,<2.0pose chat --mode claude / --mode claude-ds
[all]all-sports + server + llmFull installation

Troubleshooting

pip: command not found

python3 -m ensurepip --upgrade

error: externally-managed-environment (macOS Homebrew Python)

Use a virtual environment (Method 3) or:

pip install --break-system-packages pose-platform

pose: command not found after pip install

# Add to ~/.zshrc or ~/.bashrc
export PATH="$HOME/.local/bin:$PATH"

# Windows (native install) — locate the Scripts folder:
python -c "import sysconfig; print(sysconfig.get_path('scripts'))"
# → e.g. C:\Users\you\AppData\Roaming\Python\Python312\Scripts
# Add that folder to PATH (System Properties → Environment Variables), then restart the terminal.

# Alternative on any OS — run without the pose command
python3 -m products.pose_cli.cli version   # python on Windows

Apple Silicon (M1/M2/M3)

The platform works natively on ARM. Verify with:

python3 -c "import platform; print(platform.machine())"
# Should print: arm64

Windows

WSL2 is recommended. Native Windows also works — if pose isn't found after pip install, add Python's Scripts folder to PATH (see the "pose: command not found" item above).

wsl --install
wsl
# Then follow Linux instructions above

pose chat starts but exits with "HTTP API key not set"

pose chat needs the openai package and an API key:

pip install openai>=1.50
echo 'POSE_DEEPSEEK_API_KEY=sk-xxx' > .env   # free tier: platform.deepseek.com
pose chat

Full LLM setup →

Data Format — JointData3D

This is the most important concept to understand before using Pose CLI. Every tool reads JointData3D CSV files.

⚠️ Important: Understanding the difference between world coordinates and model coordinates is critical for correct analysis. See below.

The 12-Column Format

Pose CLI expects CSV files without headers. Each row represents one joint at one timestamp.

timestamp, joint, wx, wy, wz, mx, my, mz, ldq_x, ldq_y, ldq_z, ldq_w
# Column Type Description
1timestampfloatSeconds since recording start
2jointint or stringJoint identifier (name or index)
3–5wx, wy, wzfloatWorld position (ARKit world-anchor coordinates)
6–8mx, my, mzfloatModel position (relative to body center-of-mass)
9–12ldq_x … ldq_wfloatLocal rotation quaternion (x, y, z, w)

World vs. Model Coordinates

Coordinate System Source Use Case Stability
wx, wy, wz ARKit world anchor Absolute court position, heatmaps ⚠️ Can drift across sessions
mx, my, mz Body center-of-mass relative Joint angles, relative motion, technique ✅ Stable within a session

Rule of thumb: Use model coordinates (mx/my/mz) for all biomechanical analysis. All built-in tools default to model coordinates.

Data Quality Checklist

  • jitter_ratio < 0.3 (run pose analyze data.csv --tool stats)
  • tracking_coverage > 0.5 (skeleton was tracked for most of the recording)
  • Recording distance 2–8 meters from camera (ARKit optimal range)
  • Full body visible (not occluded by objects or other people)
  • Single person in frame (ARKit only tracks one body)
  • Device is stationary (tripod recommended)

Preparing Data from Other Systems

If you use OpenPose, MediaPipe, BlazePose, or motion capture, convert your data to the 12-column format. Key requirements:

  1. Timestamps: monotonically increasing, seconds from start
  2. Joint order: must match the 19-joint ARKit body skeleton (or use string names)
  3. Model coordinates: if unavailable, set equal to world coords (some tools will have reduced accuracy)
  4. Quaternions: if unavailable, set ldq_x=0, ldq_y=0, ldq_z=0, ldq_w=1 (identity)
import numpy as np

# Your data: timestamps (T,), joint_names list, world_positions (T, J, 3)
for t_idx, t in enumerate(timestamps):
    for j_idx, jname in enumerate(joint_names):
        wx, wy, wz = world_positions[t_idx, j_idx]
        mx, my, mz = world_positions[t_idx, j_idx]  # or compute model coords
        # Identity quaternion: no rotation data
        print(f"{t},{jname},{wx},{wy},{wz},{mx},{my},{mz},0,0,0,1")

CLI Command Reference

All commands run locally. No network required for analysis commands.

pose analyze

Run a tool on a JointData3D CSV file.

pose analyze <file.csv> [--tool <name>] [--no-cache] [--param KEY=VALUE ...]
Option Description
<file.csv>JointData3D CSV file path (required)
--tool <name>Tool to run (default: stats)
--no-cacheSkip cache, force recomputation
--param KEY=VALUEPass parameter to tool (repeatable). Auto-detects type
--env <env>Backend environment: local, staging, or prod (default: auto-detect)
--subject-id <ID>For training plan stagnation detection (requires POSE_API_TOKEN)
# Basic analysis
pose analyze data/session.csv

# Specific tool
pose analyze data/session.csv --tool detect_peak_energy

# With parameters
pose analyze data/session.csv --tool measure_running_speed \
    --param age=16 --param gender=male --param region=cn

# Force recomputation
pose analyze data/session.csv --tool stats --no-cache

pose tools

List all registered tools with version numbers.

pose tools                  # Compact table: Name, Version, Status, Sport, Description
pose tools --detail         # Full parameter details for each tool
pose tools --sport <id>     # Filter by sport (e.g., badminton, sprint)

pose sample

Copy the bundled sample data file (sample_sprint.csv) to the current directory. No network required — the sample is included in the pip package.

pose sample
# → sample_sprint.csv copied to current directory (438 KB)
# → Next: pose analyze sample_sprint.csv --tool stats

pose sports

Manage sports: list installed sports, add custom sports, or create new sport packages.

pose sports list                # Built-in + installed sport packages (default)
pose sports add <id>            # Add a custom sport (writes .pose/config.json)
pose sports remove <id>         # Remove a custom sport
pose sports create <id>         # Generate new sport package scaffold

Installing sport packages: Additional sports are distributed as independent pip packages. Install via pip extras or directly:

pip install pose-platform[badminton]
# or
pip install pose-sport-badminton

Creating a new sport: Use pose sports create to scaffold, then install in editable mode:

pose sports create basketball
# → generates sports/basketball/ with pyproject.toml, example tool, tests
pip install -e sports/basketball
pose tools --sport basketball

pose gaps

Manage the capability gap registry — track feature requests and tool ideas locally.

pose gaps list                           # Active gaps
pose gaps list --all-statuses            # All including resolved
pose gaps submit "<title>"               # Register a new gap
pose gaps show <gap_id>                  # View gap details + temp implementation
pose gaps summary                        # Statistical summary

pose cache

Manage analysis result cache. Cache invalidates automatically when source file or tool version changes.

pose cache list                          # All cached entries
pose cache clear                         # Clear all cache
pose cache clear <file.csv>             # Clear cache for specific file

pose version

Display version information — dynamically detects installed sport packages.

pose version                            # Platform + installed sports
pose version --changelog                # Technical changelog (CHANGELOG.md)
pose version --release-notes            # User-facing release notes

Example output:

{
  "platform": "1.25.10",
  "sports": {
    "freeplay":  {"version": "1.25.10", "builtin": true},
    "sprint":    {"version": "1.25.10", "builtin": true},
    "badminton": {"version": "1.13.4", "builtin": false, "tools_count": 8}
  }
}

pose chat

Start an interactive LLM-powered analysis session. Requires the [llm] extra (pip install openai) and an API key. See LLM Chat for setup.

pose chat [data_dir]                    # Default data dir: ../pose-data

pose annotate

Create, list, and delete annotations for a recording. Also launches the web annotation UI.

pose annotate create <file.csv> --start <s> --end <s> --label <name>
                                [--peak_s <s>] [--hand left|right]
                                [--quality good|acceptable|poor] [--note "text"]
pose annotate list <file.csv>
pose annotate delete <file.csv> <annotation_id>
pose annotate serve <file.csv>       # Web annotation UI

pose calib

Score calibration workflow — compare tool scores against expert annotations to validate algorithm accuracy.

pose calib auto-label                  # Auto-score annotated strokes
pose calib validate                    # Validate tool agreement against expert labels
Metric Description
MAEMean Absolute Error between tool scores and expert labels
Spearman ρRank correlation — how well tool preserves ordering
Grade agreementFraction where tool grade matches expert grade (±1 letter tolerance)

pose feedback

Submit and manage feedback items — bug reports, feature requests, and tool improvement suggestions.

pose feedback list                     # List all feedback
pose feedback stats                    # Summary statistics
pose feedback resolve <id>            # Mark as resolved
pose feedback dismiss <id>            # Dismiss with reason

pose telemetry

pose telemetry stats                    # Today's stats
pose telemetry stats --since 7d         # Last 7 days
pose telemetry stats --since 24h        # Last 24 hours

pose data

Manage local data files.

pose data delete <file> [--yes] [--dry-run]

Tool Reference

Pose CLI has 20+ built-in tools. Below are the three primary general-purpose tools. Sport-specific tools are documented in the full repository.

stats

stable Tier 1 · All sports · Since v1.4.0

Computes comprehensive statistics for a JointData3D recording. Run this first on any new data — it's your data quality report card.

Parameters

Parameter Type Default Description
pathstringJointData3D CSV file path
video_duration_sfloat(auto)Override recording duration

Key Output Fields

Field Description
recording_duration_sTotal recording time
tracking_coverageFraction of frames with valid skeleton (< 0.5 = poor)
jitter_ratioFraction of frames with high jitter (< 0.1 = good, > 0.3 = poor)
data_qualitySummary: "good", "acceptable", or "poor"
per_joint.<name>.motion_stdStandard deviation of model-coordinate movement
pose analyze data/session.csv --tool stats

detect_action_boundaries

stable Tier 1 · All sports · Since v1.1.0

Detects action boundaries — start, peak, and end of discrete movements — using full-body energy analysis. Works on any sport without tuning.

Parameters

Parameter Type Default Description
onset_energy_ratiofloat0.01Energy threshold ratio for action onset
max_filter_win_sfloat1.0Window for max-energy smoothing
prominencefloat0.1Minimum peak prominence
min_action_duration_sfloat0.2Minimum action duration
min_peak_gap_sfloat0.5Minimum time between detected actions

Output Fields

Field Description
actions[].start_sAction onset — when body energy starts rising
actions[].peak_sMoment of maximum energy
actions[].end_sAction ends — energy returns to baseline
actions[].peak_energyNormalized energy at peak (1.0 = max in recording)
actions[].duration_sTotal action duration
# Basketball — find jumps, shots, drives
pose analyze data/basketball_play.csv --tool detect_action_boundaries \
    --param min_action_duration_s=0.2 --param min_peak_gap_s=0.3

# Sprint — find drive phases
pose analyze data/sprint_100m.csv --tool detect_action_boundaries \
    --param onset_energy_ratio=0.01

When to use this vs. sport-specific tools: Use detect_action_boundaries for exploring new data or unsupported sports. Use sport-specific tools when you need per-action classification (smash vs. clear, jump shot vs. layup).

segment_motion_phases

stable Tier 1 · All sports · Since v1.5.0

Decomposes a recording into three hierarchical layers: presence segments, motion/static segments, and pauses. Essential for understanding session rhythm.

Parameters

Parameter Type Default Description
presence_gap_sfloat1.0Max timestamp gap before splitting presence segments
static_thresholdfloat0.03Energy threshold for static classification
min_static_msint500Minimum duration for a valid static segment
min_motion_msint300Minimum duration for a valid motion segment
pause_prominencefloat0.5Sensitivity for detecting pauses within motion
energy_filterstring"mean""mean" or "max" — smoothing filter
max_filter_win_sfloat1.0Window size for energy filter
motion_trailing_pad_sfloat0.3Extra tail padding on motion segments

Output Fields

Field Description
presence_segmentsContinuous periods with a person in frame
motion_segmentsPeriods of activity (swinging, running, jumping)
static_segmentsPeriods of stillness (standing, waiting)
pausesBrief stops within an otherwise active segment
summary.motion_ratioFraction of presence time spent in motion
pose analyze data/basketball_drill.csv --tool segment_motion_phases

Tips: Use energy_filter="max" for explosive sports (sprint, basketball drive). Default "mean" works well for sustained motion. Combine with detect_action_boundaries to find specific action peaks within motion segments.

Environment Variables

Analysis & Data

Variable Default Description
POSE_DATA_DIR../pose-dataDirectory for data files
POSE_ENABLE_WIP_TOOLS0Set to 1 to enable work-in-progress tools
POSE_PLATFORM_SPORTS(empty)Additional platform sports. Format: badminton:v1.0.0,fitness:v1.13.0. Set on Pose Coach backend to expose sports beyond the CLI baseline

LLM Providers (for pose chat)

Variable Provider Description
ANTHROPIC_API_KEYClaude (Anthropic)API key from console.anthropic.com
POSE_DEEPSEEK_API_KEYDeepSeekAPI key from platform.deepseek.com (free tier available)
POSE_DEEPSEEK_API_ENDPOINTDeepSeekOverride base URL (default: https://api.deepseek.com)
POSE_CN_API_KEYQwen (DashScope)API key from dashscope.aliyun.com
POSE_CN_API_ENDPOINTQwen (DashScope)Override base URL. Use https://dashscope-intl.aliyuncs.com/compatible-mode/v1 for international access

Chat Mode

Variable Default Description
POSE_CHAT_MODEreplChat frontend mode: repl (built-in + DeepSeek), claude (Claude Code + Claude), claude-ds (Claude Code + DeepSeek). CLI --mode flag overrides

Region & Language

Variable Default Description
POSE_REGIONusLLM routing region: us, eu, cn, or cloud
POSE_LANG(auto-detect)Output language. Auto-detected from LANG/LC_ALL

Caching

Pose CLI caches tool results to avoid recomputing the same analysis. The cache key is: file identity (mtime + size) + tool name + tool version.

Cache Invalidation

Cache is automatically invalidated when the source file changes (mtime/size) or the tool version changes in pose-manifest.json. Tool upgrades automatically invalidate old caches.

Cache Commands

pose cache list                          # All cached entries
pose cache clear                         # Clear all cache
pose cache clear <file.csv>             # Clear cache for specific file

Skip cache with pose analyze data.csv --tool stats --no-cache. Cache HIT is indicated with [CACHE HIT] in CLI output.

CI/CD Integration

In CI pipelines, cache the .pose/cache/ directory. Cache key on pose-manifest.json hash gives correct invalidation on tool version bumps.

LLM-Powered Analysis (pose chat)

Pose CLI includes an AI chat mode that lets you ask natural-language questions about your data. The default provider is DeepSeek — free tier, email signup, global access.

Quick Setup

Install the LLM extra and create a .env file — Pose CLI loads it automatically. No export, no source needed.

pip install 'pose-platform[llm]'
echo 'POSE_DEEPSEEK_API_KEY=sk-xxx' > .env
pose chat

Get a free DeepSeek API key at platform.deepseek.com.

Providers

DeepSeek (default)

Free tier, email signup. Works globally.

echo 'POSE_DEEPSEEK_API_KEY=sk-xxx' > .env
pose chat

Claude (best quality)

Requires Anthropic API key. Optional Claude Code CLI shell.

export ANTHROPIC_API_KEY=sk-ant-...
pose chat

Claude Code shell (optional): npm install -g @anthropic-ai/claude-code

Qwen / DashScope (Chinese-optimized)

export POSE_REGION=cn
export POSE_CN_API_KEY=sk-xxx
pose chat

Chat Modes

pose chat supports three frontend modes. Switch via --mode flag or POSE_CHAT_MODE environment variable.

Mode Frontend Backend Setup
replBuilt-in REPLDeepSeek[llm] + key
claudeClaude Code CLIClaude nativeClaude Code + [mcp]
claude-dsClaude Code CLIDeepSeekClaude Code + [mcp] + key
# REPL mode (default)
pose chat

# Claude Code + Claude native (best experience)
npm install -g @anthropic-ai/claude-code
pip install 'pose-platform[mcp]'
pose chat --mode claude

# Claude Code + DeepSeek
echo 'POSE_DEEPSEEK_API_KEY=sk-xxx' > .env
pose chat --mode claude-ds

How it works

pose chat reads POSE_DEEPSEEK_API_KEY and automatically injects the following into Claude Code's environment before launching it:

Claude Code env var Value
ANTHROPIC_BASE_URLhttps://api.deepseek.com/anthropic
ANTHROPIC_AUTH_TOKEN$POSE_DEEPSEEK_API_KEY
ANTHROPIC_MODELdeepseek-v4-pro[1m]

This bridges DeepSeek's Anthropic-compatible API endpoint to Claude Code's native authentication model. You only need POSE_DEEPSEEK_API_KEY — the translation is handled transparently.

Note: If you launch Claude Code directly (without pose chat), you must set ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN yourself. pose chat --mode claude-ds does this for you automatically.

When using --mode claude or --mode claude-ds, Pose CLI also automatically generates a temporary .mcp.json that connects Claude Code to the pose-analysis MCP server with all registered tools — no manual setup needed.

Region Routing

The default configuration uses DeepSeek for all regions. You can override via pose-manifest.json or environment variables.

# Default routing:
# US/EU region:  DeepSeek (http_api) → Claude (fallback if configured)
# CN region:     Qwen-Plus (http_api) → DeepSeek (fallback)

# Force a region:
export POSE_REGION=cn    # CN routing (requires manifest config)
export POSE_REGION=us    # US routing (default)

Example Session

> How many action segments are in this recording?
[Tool: detect_action_boundaries] Found 14 action segments

> What was the fastest one?
[Tool: detect_velocity] Peak at 2.3s, 18.5 m/s

> Analyze the running gait pattern
[Tool: analyze_running_gait] Cadence: 180 spm, symmetry: 0.94, ...

Local Backend Setup

Record motion data with Pose Coach on an iPhone and have skeleton files automatically land on your computer — no cloud, no staging server, no Mac required.

iPhone (Pose Coach)
1Record session
Auto-upload CSV
WiFi :8000
Your Computer (Win / Linux / Mac)
1pose serve
Saves to pose-data/
pose analyze data.csv

Prerequisites

  • iPhone with Pose Coach installed via TestFlight (ask us for an invitation link)
  • Computer with Pose CLI installed (pip install -e . in the pose_platform repo)
  • Both devices on the same WiFi network

Step 1: Start the Local Backend

# Install with server extras (if not already)
pip install 'pose-platform[server,llm]'

# Start the backend
pose serve
# → http://0.0.0.0:8000
# → LAN  →  http://192.168.1.x:8000  (configure this on iPhone)
# → data → /Users/you/pose-data

The server listens on all network interfaces by default. Your LAN IP is printed automatically — use it to configure the iPhone. Options: pose serve --port 9000, pose serve --data-dir ~/my-data.

Step 2: Configure Pose Coach on iPhone

  1. Open Pose Coach on your iPhone
  2. Go to Settings (gear icon)
  3. Scroll to Researcher Backend section
  4. Select Custom URL
  5. Enter http://<YOUR_IP>:8000 (e.g., http://192.168.1.42:8000)
  6. Tap Apply
  7. Restart the app when prompted

Note: The Researcher Backend section is visible in TestFlight builds automatically.

Step 3: Record & Analyze

  1. In Pose Coach, select Freeplay as the sport (use this for any sport not yet officially supported)
  2. Record your motion — skeleton CSV is automatically uploaded after stopping
  3. Files land in your pose-data/ directory
# Check what arrived
ls pose-data/*_3d.csv | tail -5

# Run analysis
pose analyze pose-data/20260723T140000_seg_1_iPhone_3d.csv --tool stats
pose analyze pose-data/20260723T140000_seg_1_iPhone_3d.csv --tool segment_motion_phases
pose analyze pose-data/20260723T140000_seg_1_iPhone_3d.csv --tool detect_action_boundaries

Step 4 (Optional): Get the Video File

The .mov video is not uploaded to the backend (privacy guarantee). To get it:

  1. After recording in Pose Coach, tap the export button (share icon)
  2. Choose Save to Files → iCloud Drive
  3. On your computer, download from iCloud Drive
  4. The .mov video pairs with the _3d.csv skeleton (same filename stem)

Supported Endpoints

pose serve implements 20+ API endpoints compatible with the Pose Coach iOS app:

Endpoint Method Purpose
/health /health/strictGETHealth check
/auth/anonymousPOSTAnonymous auth (returns JWT)
/auth/refreshPOSTToken refresh
/user/meGETUser profile
/sportsGETSport list
/capabilitiesGETTool list + gaps
/toolsGETTool definitions
/models/{sport}GETAFM model status
/uploadPOSTReceive recordings
/sessionsGETSession list
/sessions/metadataPOSTAuto-generate title/summary
/analyzePOSTRun analysis tools
/chatPOSTAI coach chat
/chat/streamPOSTSSE streaming chat
/subjectsGETSubject list
/subjects/{id}/sessionsGETSubject's sessions
/subjects/{id}/progressGETProgress data
/generate_reportPOSTComprehensive report
/generate_subject_training_planPOSTCross-session training plan
/annotations/statusPOSTAnnotation status
/correctionsPOSTSkeleton corrections
/ios/feature-flagsGETFeature flags

What pose serve provides vs the cloud backend

Feature pose serve Cloud Backend
File upload
Analysis (all tools)
AI Coach chat✅ (SSE streaming)
Training plan (per-session)
Training plan (comprehensive)
Comprehensive report
Session history✅ (in-memory)✅ (database)
Subject profiles
User accounts
Multi-device
Database

Troubleshooting

"Cannot connect to backend" on iPhone

  • Verify both devices are on the same WiFi network
  • Check firewall: allow incoming connections on port 8000
  • On Windows: allow Python through Windows Firewall

"Upload failed" after recording

Confirm pose serve is still running and the data directory exists and is writable.

Backend not showing in Settings

Make sure you're using the TestFlight version of Pose Coach (not App Store). The Researcher Backend section appears automatically in TestFlight builds.

Switching back to normal use

Settings → Researcher Backend → switch to Staging (or Production) → Apply → restart the app.

Contributing

Pose CLI is designed to be extended. Build new tools, add sport support, or contribute code.

Building a New Tool

A tool is a Python class. Write it once, register it, and it works everywhere — CLI, Pose Coach app, custom apps.

Step 1: Create the tool class in capabilities/tools/my_tool.py

from capabilities.tools.base import DirectTool
from capabilities.tools.loader import load_pose
import json
from pathlib import Path


class MyTool(DirectTool):
    name = "my_tool"
    description = "What this tool does"
    input_schema = {
        "type": "object",
        "properties": {
            "path": {"type": "string", "description": "CSV file path"},
            "my_param": {"type": "number", "default": 1.0},
        },
        "required": ["path"]
    }
    status = "wip"                     # "wip" or "stable"
    supported_sports = []              # [] = all sports
    tier = 1                           # 1 = primary, 2 = fallback
    depends_on = []                    # Optional: tool dependencies
    requires_session_context_by_sport = ["badminton"]  # Optional: sport-specific metadata

    def run(self, tool_input: dict, output_dir: Path) -> str:
        pose = load_pose(tool_input["path"])
        result = {"your_field": 42}
        return json.dumps(result, ensure_ascii=False)

Step 2: Register in capabilities/tools/registry.py — add import and instance to all_tools list.

Step 3: Enable and test:

export POSE_ENABLE_WIP_TOOLS=1
pose tools | grep my_tool
pose analyze data/test.csv --tool my_tool

Extending Sport Support

Add a new sport in 3 lines:

# pose_platform_core/sports_catalog.py
OFFICIAL_SPORTS = [
    # ... existing ...
    SupportedSport(id="basketball", since_version="1.24.0"),
]

Now build tools with supported_sports = ["basketball"]. Generic tools work automatically.

Promoting a Tool to Stable

  1. Write unit tests (≥ 1) — pytest tests/unit/
  2. Test with 10+ real recordings
  3. Test edge cases (empty data, single frame, missing joints)
  4. Add documentation in docs/features/<tool_name>.md
  5. Change status = "stable" in your tool class
  6. Add version entry in pose-manifest.jsontools

Distributing Your Tools

Two ways to distribute your custom tools:

Path 1: Sport Package Path 2: Merge into Platform
Best forSport-specific tool collectionsGeneral-purpose tools
DistributionIndependent PyPI packagePart of pose-platform
VersioningYour own version + release cycleFollows platform releases
How topose sports create <id> then publishPR to posecap/pose-platform

Data Loading Best Practices

  • Use pose.mpoints (model coordinates) for biomechanical analysis
  • Oreason filtering is automatic — load_pose() excludes anomalous frames
  • Use pose.joint_names to look up joint indices dynamically
  • Return data_quality in your output to help users assess reliability
  • Bump the tool version in pose-manifest.json when algorithms change — old cache auto-invalidates

License

Pose CLI — Motion Analysis Toolkit · Copyright © 2026 PoseCap Inc. All rights reserved.

1. Research License (Non-Commercial)

Academic researchers, educational institutions, and individual learners are granted a royalty-free, non-exclusive, non-transferable license to use, modify, and create derivative works for non-commercial research and educational purposes, subject to:

  • Attribution — Any publication must cite the Pose Platform (BibTeX citation below)
  • No Redistribution — You may not redistribute the software or its core algorithms without prior written consent
  • No Commercial Use — You may not embed in commercial products, provide paid services, or sell access to analysis results
  • Modifications — Tools and extensions you develop are your own IP. Contributing grants PoseCap Inc. a license to use and distribute your contributions

2. Commercial License

Any commercial use requires a separate written agreement with PoseCap Inc. Contact contact@posecap.com for commercial licensing.

Citation

If you use Pose CLI in your research, please cite:

@software{pose_platform,
  title = {Pose Platform: Open Motion Analysis Toolkit},
  author = {{PoseCap Inc.}},
  year = {2026},
  url = {https://github.com/posecap/pose-platform},
}

Disclaimer

This software is provided "AS IS", without warranty of any kind, express or implied. In no event shall the authors or copyright holders be liable for any claim, damages or other liability arising from the use of the software.

Ready to analyze your motion data?

Pose CLI is available on PyPI — install and start analyzing in minutes. Email us and tell us what you want to study.