Files
claudetools/.claude/API_SPEC.md
Mike Swanson 390b10b32c Complete Phase 6: MSP Work Tracking with Context Recall System
Implements production-ready MSP platform with cross-machine persistent memory for Claude.

API Implementation:
- 130 REST API endpoints across 21 entities
- JWT authentication on all endpoints
- AES-256-GCM encryption for credentials
- Automatic audit logging
- Complete OpenAPI documentation

Database:
- 43 tables in MariaDB (172.16.3.20:3306)
- 42 SQLAlchemy models with modern 2.0 syntax
- Full Alembic migration system
- 99.1% CRUD test pass rate

Context Recall System (Phase 6):
- Cross-machine persistent memory via database
- Automatic context injection via Claude Code hooks
- Automatic context saving after task completion
- 90-95% token reduction with compression utilities
- Relevance scoring with time decay
- Tag-based semantic search
- One-command setup script

Security Features:
- JWT tokens with Argon2 password hashing
- AES-256-GCM encryption for all sensitive data
- Comprehensive audit trail for credentials
- HMAC tamper detection
- Secure configuration management

Test Results:
- Phase 3: 38/38 CRUD tests passing (100%)
- Phase 4: 34/35 core API tests passing (97.1%)
- Phase 5: 62/62 extended API tests passing (100%)
- Phase 6: 10/10 compression tests passing (100%)
- Overall: 144/145 tests passing (99.3%)

Documentation:
- Comprehensive architecture guides
- Setup automation scripts
- API documentation at /api/docs
- Complete test reports
- Troubleshooting guides

Project Status: 95% Complete (Production-Ready)
Phase 7 (optional work context APIs) remains for future enhancement.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-17 06:00:26 -07:00

19 KiB

MSP Mode API Specification

Version: 1.0.0 Last Updated: 2026-01-16 Status: Design Phase


Overview

FastAPI-based REST API providing secure access to MSP tracking database on Jupiter server. Designed for multi-machine access with JWT authentication and comprehensive audit logging.


Base Configuration

Base URL: https://msp-api.azcomputerguru.com API Version: /api/v1/ Protocol: HTTPS only (no HTTP) Authentication: JWT Bearer tokens Content-Type: application/json


Authentication

JWT Token Structure

Access Token (Short-lived: 1 hour)

{
  "sub": "mike@azcomputerguru.com",
  "scopes": ["msp:read", "msp:write", "msp:admin"],
  "machine": "windows-workstation",
  "exp": 1234567890,
  "iat": 1234567890,
  "jti": "unique-token-id"
}

Refresh Token (Long-lived: 30 days)

  • Stored securely in Gitea config
  • Used to obtain new access tokens
  • Can be revoked server-side

Permission Scopes

  • msp:read - Read sessions, clients, work items
  • msp:write - Create/update sessions, work items
  • msp:admin - Manage clients, credentials, delete operations

Authentication Endpoints

POST /api/v1/auth/token

Obtain JWT access token.

Request:

{
  "refresh_token": "string"
}

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "bearer",
  "expires_in": 3600,
  "scopes": ["msp:read", "msp:write"]
}

Status Codes:

  • 200 - Token issued successfully
  • 401 - Invalid refresh token
  • 403 - Token revoked

POST /api/v1/auth/refresh

Refresh expired access token.

Request:

{
  "refresh_token": "string"
}

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "expires_in": 3600
}

Core API Endpoints

Machine Detection & Management

GET /api/v1/machines

List all registered machines.

Query Parameters:

  • is_active (boolean) - Filter by active status
  • platform (string) - Filter by platform (win32, darwin, linux)

Response:

{
  "machines": [
    {
      "id": "uuid",
      "hostname": "ACG-M-L5090",
      "friendly_name": "Main Laptop",
      "platform": "win32",
      "has_vpn_access": true,
      "vpn_profiles": ["dataforth", "grabb"],
      "has_docker": true,
      "powershell_version": "7.4",
      "available_mcps": ["claude-in-chrome", "filesystem"],
      "available_skills": ["pdf", "commit", "review-pr"],
      "last_seen": "2026-01-16T10:30:00Z"
    }
  ]
}

POST /api/v1/machines

Register new machine (auto-detection on first session).

Request:

{
  "hostname": "ACG-M-L5090",
  "machine_fingerprint": "sha256hash",
  "platform": "win32",
  "os_version": "Windows 11 Pro",
  "username": "MikeSwanson",
  "friendly_name": "Main Laptop",
  "has_vpn_access": true,
  "vpn_profiles": ["dataforth", "grabb"],
  "has_docker": true,
  "powershell_version": "7.4",
  "preferred_shell": "powershell",
  "available_mcps": ["claude-in-chrome"],
  "available_skills": ["pdf", "commit"]
}

Response:

{
  "id": "uuid",
  "machine_fingerprint": "sha256hash",
  "created_at": "2026-01-16T10:00:00Z"
}

GET /api/v1/machines/{fingerprint}

Get machine by fingerprint (for session start auto-detection).

Response:

{
  "id": "uuid",
  "hostname": "ACG-M-L5090",
  "friendly_name": "Main Laptop",
  "capabilities": {
    "vpn_profiles": ["dataforth", "grabb"],
    "has_docker": true,
    "powershell_version": "7.4"
  }
}

PUT /api/v1/machines/{id}

Update machine capabilities.

Sessions

POST /api/v1/sessions

Create new MSP session.

Request:

{
  "client_id": "uuid",
  "project_id": "uuid",
  "machine_id": "uuid",
  "session_date": "2026-01-16",
  "start_time": "2026-01-16T10:00:00Z",
  "session_title": "Dataforth - DOS UPDATE.BAT enhancement",
  "technician": "Mike Swanson",
  "status": "in_progress"
}

Response:

{
  "id": "uuid",
  "session_date": "2026-01-16",
  "start_time": "2026-01-16T10:00:00Z",
  "status": "in_progress",
  "created_at": "2026-01-16T10:00:00Z"
}

Status Codes:

  • 201 - Session created
  • 400 - Invalid request data
  • 401 - Unauthorized
  • 404 - Client/Project not found

GET /api/v1/sessions

Query sessions with filters.

Query Parameters:

  • client_id (uuid) - Filter by client
  • project_id (uuid) - Filter by project
  • machine_id (uuid) - Filter by machine
  • date_from (date) - Start date range
  • date_to (date) - End date range
  • is_billable (boolean) - Filter billable sessions
  • status (string) - Filter by status
  • limit (int) - Max results (default: 50)
  • offset (int) - Pagination offset

Response:

{
  "sessions": [
    {
      "id": "uuid",
      "client_name": "Dataforth",
      "project_name": "DOS Machine Management",
      "session_date": "2026-01-15",
      "duration_minutes": 210,
      "billable_hours": 3.5,
      "session_title": "DOS UPDATE.BAT v2.0 completion",
      "summary": "Completed UPDATE.BAT automation...",
      "status": "completed"
    }
  ],
  "total": 45,
  "limit": 50,
  "offset": 0
}

GET /api/v1/sessions/{id}

Get session details with related work items.

Response:

{
  "id": "uuid",
  "client_id": "uuid",
  "client_name": "Dataforth",
  "project_name": "DOS Machine Management",
  "session_date": "2026-01-15",
  "start_time": "2026-01-15T14:00:00Z",
  "end_time": "2026-01-15T17:30:00Z",
  "duration_minutes": 210,
  "billable_hours": 3.5,
  "session_title": "DOS UPDATE.BAT v2.0",
  "summary": "markdown summary",
  "work_items": [
    {
      "id": "uuid",
      "category": "development",
      "title": "Enhanced UPDATE.BAT with version checking",
      "status": "completed"
    }
  ],
  "tags": ["dos", "batch", "automation", "dataforth"],
  "technologies_used": ["dos-6.22", "batch", "networking"]
}

PUT /api/v1/sessions/{id}

Update session (typically at session end).

Request:

{
  "end_time": "2026-01-16T12:30:00Z",
  "status": "completed",
  "summary": "markdown summary",
  "billable_hours": 2.5,
  "notes": "Additional session notes"
}

Work Items

POST /api/v1/work-items

Create work item for session.

Request:

{
  "session_id": "uuid",
  "category": "troubleshooting",
  "title": "Fixed Apache SSL certificate expiration",
  "description": "Problem: ERR_SSL_PROTOCOL_ERROR\nCause: Cert expired\nFix: certbot renew",
  "status": "completed",
  "priority": "high",
  "is_billable": true,
  "actual_minutes": 45,
  "affected_systems": ["jupiter", "172.16.3.20"],
  "technologies_used": ["apache", "ssl", "certbot"]
}

Response:

{
  "id": "uuid",
  "session_id": "uuid",
  "category": "troubleshooting",
  "title": "Fixed Apache SSL certificate expiration",
  "created_at": "2026-01-16T10:15:00Z"
}

GET /api/v1/work-items

Query work items.

Query Parameters:

  • session_id (uuid) - Filter by session
  • category (string) - Filter by category
  • status (string) - Filter by status
  • date_from (date) - Start date
  • date_to (date) - End date

Clients

GET /api/v1/clients

List all clients.

Query Parameters:

  • type (string) - Filter by type (msp_client, internal, project)
  • is_active (boolean) - Active clients only

Response:

{
  "clients": [
    {
      "id": "uuid",
      "name": "Dataforth",
      "type": "msp_client",
      "network_subnet": "192.168.0.0/24",
      "is_active": true
    }
  ]
}

POST /api/v1/clients

Create new client record.

Request:

{
  "name": "Client Name",
  "type": "msp_client",
  "network_subnet": "192.168.1.0/24",
  "domain_name": "client.local",
  "primary_contact": "John Doe",
  "notes": "Additional information"
}

Requires: msp:admin scope

GET /api/v1/clients/{id}

Get client details with infrastructure.

Response:

{
  "id": "uuid",
  "name": "Dataforth",
  "network_subnet": "192.168.0.0/24",
  "infrastructure": [
    {
      "hostname": "AD2",
      "ip_address": "192.168.0.6",
      "asset_type": "domain_controller",
      "os": "Windows Server 2022"
    }
  ],
  "active_projects": 3,
  "recent_sessions": 15
}

Credentials

GET /api/v1/credentials

Query credentials (encrypted values not returned by default).

Query Parameters:

  • client_id (uuid) - Filter by client
  • service_id (uuid) - Filter by service
  • credential_type (string) - Filter by type

Response:

{
  "credentials": [
    {
      "id": "uuid",
      "client_name": "Dataforth",
      "service_name": "AD2 Administrator",
      "username": "sysadmin",
      "credential_type": "password",
      "requires_vpn": true,
      "last_rotated_at": "2025-12-01T00:00:00Z"
    }
  ]
}

Note: Password values not included. Use decrypt endpoint.

POST /api/v1/credentials

Store new credential (encrypted).

Request:

{
  "client_id": "uuid",
  "service_name": "AD2 Administrator",
  "username": "sysadmin",
  "password": "plaintext-password",
  "credential_type": "password",
  "requires_vpn": true,
  "requires_2fa": false
}

Response:

{
  "id": "uuid",
  "service_name": "AD2 Administrator",
  "created_at": "2026-01-16T10:00:00Z"
}

Requires: msp:write scope

GET /api/v1/credentials/{id}/decrypt

Decrypt and return credential value.

Response:

{
  "credential_id": "uuid",
  "service_name": "AD2 Administrator",
  "username": "sysadmin",
  "password": "decrypted-password",
  "accessed_at": "2026-01-16T10:30:00Z"
}

Side Effects:

  • Creates audit log entry
  • Records access in credential_audit_log table

Requires: msp:read scope minimum

Infrastructure

GET /api/v1/infrastructure

Query infrastructure assets.

Query Parameters:

  • client_id (uuid) - Filter by client
  • asset_type (string) - Filter by type
  • hostname (string) - Search by hostname

Response:

{
  "infrastructure": [
    {
      "id": "uuid",
      "client_name": "Dataforth",
      "hostname": "D2TESTNAS",
      "ip_address": "192.168.0.9",
      "asset_type": "nas_storage",
      "os": "ReadyNAS OS",
      "environmental_notes": "Manual WINS install, SMB1 only",
      "powershell_version": null,
      "has_gui": true
    }
  ]
}

GET /api/v1/infrastructure/{id}/insights

Get environmental insights for infrastructure.

Response:

{
  "infrastructure_id": "uuid",
  "hostname": "D2TESTNAS",
  "insights": [
    {
      "category": "custom_installations",
      "title": "WINS: Manual Samba installation",
      "description": "WINS service manually installed via Samba nmbd...",
      "examples": ["ssh root@192.168.0.9 'ps aux | grep nmbd'"],
      "priority": 9
    }
  ],
  "limitations": ["no_native_wins_service", "smb1_only"],
  "recommended_commands": {
    "check_wins": "ssh root@192.168.0.9 'ps aux | grep nmbd'"
  }
}

Commands & Failures

POST /api/v1/commands

Log command execution (with failure tracking).

Request:

{
  "work_item_id": "uuid",
  "session_id": "uuid",
  "command_text": "Get-LocalUser",
  "host": "old-server-2008",
  "shell_type": "powershell",
  "success": false,
  "exit_code": 1,
  "error_message": "Get-LocalUser : The term Get-LocalUser is not recognized",
  "failure_category": "compatibility"
}

Response:

{
  "id": "uuid",
  "created_at": "2026-01-16T10:00:00Z",
  "failure_logged": true
}

Side Effects:

  • If failure: Triggers Failure Analysis Agent
  • May create failure_patterns entry
  • May update environmental_insights

GET /api/v1/failure-patterns

Query known failure patterns.

Query Parameters:

  • infrastructure_id (uuid) - Patterns for specific infrastructure
  • pattern_type (string) - Filter by type

Response:

{
  "patterns": [
    {
      "id": "uuid",
      "pattern_signature": "PowerShell 7 cmdlets on Server 2008",
      "error_pattern": "Get-LocalUser.*not recognized",
      "root_cause": "Server 2008 only has PowerShell 2.0",
      "recommended_solution": "Use Get-WmiObject Win32_UserAccount",
      "occurrence_count": 5,
      "severity": "major"
    }
  ]
}

Tasks & Todo Items

GET /api/v1/pending-tasks

Query open tasks.

Query Parameters:

  • client_id (uuid) - Filter by client
  • priority (string) - Filter by priority
  • status (string) - Filter by status

Response:

{
  "tasks": [
    {
      "id": "uuid",
      "client_name": "Dataforth",
      "title": "Create Datasheets share",
      "priority": "high",
      "status": "blocked",
      "blocked_by": "Waiting on Engineering",
      "due_date": "2026-01-20"
    }
  ]
}

POST /api/v1/pending-tasks

Create pending task.

Request:

{
  "client_id": "uuid",
  "project_id": "uuid",
  "title": "Task title",
  "description": "Task description",
  "priority": "high",
  "due_date": "2026-01-20"
}

External Integrations

GET /api/v1/integrations

List configured integrations (SyncroMSP, MSP Backups, etc.).

Response:

{
  "integrations": [
    {
      "integration_name": "syncro",
      "integration_type": "psa",
      "is_active": true,
      "last_tested_at": "2026-01-15T08:00:00Z",
      "last_test_status": "success"
    }
  ]
}

POST /api/v1/integrations/{name}/test

Test integration connection.

Response:

{
  "integration_name": "syncro",
  "status": "success",
  "message": "Connection successful",
  "tested_at": "2026-01-16T10:00:00Z"
}

GET /api/v1/syncro/tickets

Search SyncroMSP tickets.

Query Parameters:

  • customer (string) - Filter by customer name
  • subject (string) - Search ticket subjects
  • status (string) - Filter by status

Response:

{
  "tickets": [
    {
      "ticket_id": "12345",
      "ticket_number": "T12345",
      "subject": "Backup configuration for NAS",
      "customer": "Dataforth",
      "status": "open",
      "created_at": "2026-01-10T12:00:00Z"
    }
  ]
}

POST /api/v1/syncro/tickets/{id}/comment

Add comment to SyncroMSP ticket.

Request:

{
  "comment": "Work completed: configured Veeam backup..."
}

Response:

{
  "comment_id": "67890",
  "created_at": "2026-01-16T10:00:00Z"
}

Side Effects:

  • Creates external_integrations log entry
  • Links to current session

Health & Monitoring

GET /api/v1/health

Health check endpoint.

Response:

{
  "status": "healthy",
  "database": "connected",
  "timestamp": "2026-01-16T10:00:00Z",
  "version": "1.0.0"
}

Status Codes:

  • 200 - Service healthy
  • 503 - Service unavailable

GET /api/v1/metrics

Prometheus metrics (optional).

Response: Prometheus format metrics


Error Handling

Standard Error Response Format

{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "Client ID is required",
    "details": {
      "field": "client_id",
      "constraint": "not_null"
    }
  },
  "timestamp": "2026-01-16T10:00:00Z",
  "request_id": "uuid"
}

HTTP Status Codes

  • 200 - Success
  • 201 - Created
  • 400 - Bad Request (invalid input)
  • 401 - Unauthorized (missing/invalid token)
  • 403 - Forbidden (insufficient permissions)
  • 404 - Not Found
  • 409 - Conflict (duplicate record)
  • 429 - Too Many Requests (rate limit)
  • 500 - Internal Server Error (never expose DB errors)
  • 503 - Service Unavailable

Error Codes

  • INVALID_REQUEST - Malformed request
  • UNAUTHORIZED - Missing or invalid authentication
  • FORBIDDEN - Insufficient permissions
  • NOT_FOUND - Resource not found
  • DUPLICATE_ENTRY - Unique constraint violation
  • RATE_LIMIT_EXCEEDED - Too many requests
  • DATABASE_ERROR - Internal database error (details hidden)
  • ENCRYPTION_ERROR - Credential encryption/decryption failed

Rate Limiting

Default Limits:

  • 100 requests per minute per token
  • 1000 requests per hour per token
  • Credential decryption: 20 per minute

Headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1234567890

Exceeded Response:

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Retry after 60 seconds.",
    "retry_after": 60
  }
}

Agent Coordination Patterns

Agent API Access

All specialized agents use the same API with agent-specific tokens:

Agent Token Claims:

{
  "sub": "agent:context-recovery",
  "agent_type": "context_recovery",
  "scopes": ["msp:read"],
  "parent_session": "uuid",
  "exp": 1234567890
}

Agent Communication Flow

Main Claude (JWT: user token)
  ↓
  Launches Agent (JWT: agent token, scoped to parent session)
  ↓
  Agent makes API calls (authenticated with agent token)
  ↓
  API logs agent activity (tracks parent session)
  ↓
  Agent returns summary to Main Claude

Example: Context Recovery Agent

Request Flow:

  1. Main Claude: POST /api/v1/agents/context-recovery
  2. API issues agent token (scoped: msp:read, session_id)
  3. Agent executes:
    • GET /api/v1/sessions?client_id=X&limit=5
    • GET /api/v1/pending-tasks?client_id=X
    • GET /api/v1/infrastructure?client_id=X
  4. Agent processes results, generates summary
  5. Agent returns to Main Claude (API logs all agent activity)

Agent Audit Trail:

  • All agent API calls logged with parent session
  • Agent execution time tracked
  • Agent results cached (avoid redundant queries)

Security Considerations

Encryption

  • In Transit: HTTPS only (TLS 1.2+)
  • At Rest: AES-256-GCM for credentials
  • Key Management: Environment variable or vault (not in database)

Authentication

  • JWT tokens with short expiration (1 hour access, 30 day refresh)
  • Token rotation supported
  • Revocation list for compromised tokens

Audit Logging

  • All credential access logged (credential_audit_log)
  • All API requests logged (api_audit_log)
  • User ID, IP address, timestamp, action recorded

Input Validation

  • Pydantic models validate all inputs
  • SQL injection prevention via SQLAlchemy ORM
  • XSS prevention (JSON only, no HTML)

Rate Limiting

  • Per-token rate limits
  • Credential access rate limits (stricter)
  • IP-based limits (optional)

Configuration Storage

Gitea Repository

Repo: azcomputerguru/msp-config

File: msp-api-config.json

{
  "api_url": "https://msp-api.azcomputerguru.com",
  "refresh_token": "encrypted_token_value",
  "database_schema_version": "1.0.0",
  "machine_id": "uuid"
}

Encryption: git-crypt or encrypted JSON values


Implementation Status

  • API Design (this document)
  • FastAPI implementation
  • Database schema deployment
  • JWT authentication flow
  • Agent token system
  • External integrations (SyncroMSP, MSP Backups)

Version History

v1.0.0 (2026-01-16):

  • Initial API specification
  • Machine detection endpoints
  • Core CRUD operations
  • Authentication flow
  • Agent coordination patterns
  • External integrations design