Files
homelab-docs/PA-API.md
2026-01-07 00:09:54 -05:00

7.0 KiB

Personal Assistant API

Backend API for the Personal Assistant system - provides Claude-powered voice/text interface to all PA capabilities (calendar, tasks, messages, smart home, etc.).


Quick Reference

Setting Value
Domain pa.htsn.io
Local IP 10.10.10.207:8401
Server docker-host2 (PVE2 VMID 302)
Compose /opt/pa-api/docker-compose.yml
Access Tailscale only (not publicly exposed)
GitHub Private repo: pa-api

Architecture

Android/Telegram
       │
       ▼
┌─────────────────┐
│    PA API       │  ← Claude SDK, model routing
│ docker-host2    │
│ :8401           │
└────────┬────────┘
         │
    ┌────┴────┐
    │         │
    ▼         ▼
┌───────┐  ┌──────────┐
│ Rube  │  │MCP Bridge│  ← Mac Mini (Beeper, Proton, etc.)
│ Exa   │  │ :8400    │
│ etc.  │  └──────────┘
└───────┘

PA API handles:

  • Claude SDK integration (no CLI startup delay)
  • Model routing (Haiku/Sonnet/Opus)
  • Session management
  • Direct API tools (Exa, Ref, Rube, Airtable)

MCP Bridge handles:

  • Tools requiring Mac Mini (Beeper, Proton Bridge, filesystem)
  • Runs on Mac Mini at 10.10.10.125:8400

API Endpoints

Endpoint Method Purpose
/chat POST Main query endpoint (streaming SSE)
/health GET Health check

POST /chat

Request:

{
  "message": "What's on my calendar today?",
  "session_id": "abc123"
}

Response (Server-Sent Events):

data: {"type": "model", "name": "sonnet"}
data: {"type": "chunk", "text": "You have "}
data: {"type": "chunk", "text": "3 meetings today..."}
data: {"type": "done", "full_text": "You have 3 meetings today..."}

Model Routing

Query Type Model Examples
Simple facts Haiku "How old is X?", "What's 15% of 80?"
PA queries Sonnet "What's on my calendar?", "Add task"
Complex reasoning Opus "Help me plan my week"

Override: Say "Use Opus" to force model selection (sticky per session).


Deployment

Docker Compose

Location: /opt/pa-api/docker-compose.yml

version: '3.8'

services:
  pa-api:
    image: pa-api:latest
    build: .
    container_name: pa-api
    restart: unless-stopped
    ports:
      - "8401:8401"
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - MCP_BRIDGE_URL=http://10.10.10.125:8400
      - EXA_API_KEY=${EXA_API_KEY}
      # Add other API keys as needed
    volumes:
      - ./data:/app/data
    networks:
      - pa-network

networks:
  pa-network:
    driver: bridge

Environment Variables

Variable Purpose
ANTHROPIC_API_KEY Claude API access
MCP_BRIDGE_URL Mac Mini bridge endpoint
EXA_API_KEY Exa web search
AIRTABLE_API_KEY Airtable access

Store in /opt/pa-api/.env (not committed to git).


Traefik Configuration

File: /etc/traefik/conf.d/pa-api.yaml (on CT 202)

http:
  routers:
    pa-api:
      rule: "Host(`pa.htsn.io`)"
      entryPoints:
        - websecure
      service: pa-api
      tls:
        certResolver: cloudflare

  services:
    pa-api:
      loadBalancer:
        servers:
          - url: "http://10.10.10.207:8401"

Note: This service is Tailscale-only. The Traefik route exists for convenience but should not be exposed publicly via Cloudflare.


Common Tasks

Start/Stop Service

# SSH to docker-host2
ssh docker-host2

# Start
cd /opt/pa-api && docker-compose up -d

# Stop
cd /opt/pa-api && docker-compose down

# View logs
docker logs -f pa-api

# Restart
docker-compose restart pa-api

Update Service

ssh docker-host2
cd /opt/pa-api
git pull
docker-compose build
docker-compose up -d

Health Check

# From any machine on network
curl http://10.10.10.207:8401/health

# Test chat endpoint
curl -X POST http://10.10.10.207:8401/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "Hello", "session_id": "test"}'

MCP Bridge (Mac Mini)

The MCP Bridge runs on Mac Mini and exposes MCP tools as HTTP endpoints.

Setting Value
Location Mac Mini (10.10.10.125)
Port 8400
Purpose Execute MCP tools (Beeper, Proton, TickTick, HA, etc.)

Bridge Endpoints

Endpoint Method Purpose
/tools GET List available tools
/execute POST Execute a tool
/health GET Health check

Start MCP Bridge

# SSH to Mac Mini
ssh macmini

# Start bridge (managed by launchd)
launchctl load ~/Library/LaunchAgents/com.hutson.mcp-bridge.plist

# Check status
curl http://localhost:8400/health

Integration Points

Service Relationship
n8n Telegram bot uses n8n → Claude CLI (separate path)
MetaMCP PA API does NOT use MetaMCP (direct MCP Bridge)
Home Assistant Controlled via MCP Bridge
Claude-Mem Shared memory database for context

Clients

Client Connection
Android App HTTPS via Tailscale → pa.htsn.io
(Future) Web UI Same endpoint

Monitoring

Health Checks

# PA API
curl -s http://10.10.10.207:8401/health | jq

# MCP Bridge
curl -s http://10.10.10.125:8400/health | jq

Logs

# PA API logs
ssh docker-host2 'docker logs -f pa-api --tail 100'

# MCP Bridge logs (Mac Mini)
ssh macmini 'tail -f ~/Library/Logs/mcp-bridge.log'

Troubleshooting

PA API Not Responding

  1. Check container status:

    ssh docker-host2 'docker ps | grep pa-api'
    
  2. Check logs for errors:

    ssh docker-host2 'docker logs pa-api --tail 50'
    
  3. Verify network:

    curl http://10.10.10.207:8401/health
    

MCP Bridge Not Responding

  1. Check if Mac Mini is reachable:

    ping 10.10.10.125
    
  2. Check bridge process:

    ssh macmini 'pgrep -f mcp-bridge'
    
  3. Restart bridge:

    ssh macmini 'launchctl unload ~/Library/LaunchAgents/com.hutson.mcp-bridge.plist'
    ssh macmini 'launchctl load ~/Library/LaunchAgents/com.hutson.mcp-bridge.plist'
    

Model Routing Issues

  • Check Claude API key is valid
  • Verify Haiku classifier is responding
  • Check session storage for stuck model overrides


Last Updated: 2026-01-07