Files
claudetools/.claude/API_SPEC.md
azcomputerguru 565b6458ba fix: Remove all emojis from documentation for cross-platform compliance
Replaced 50+ emoji types with ASCII text markers for consistent rendering
across all terminals, editors, and operating systems:

  - Checkmarks/status: [OK], [DONE], [SUCCESS], [PASS]
  - Errors/warnings: [ERROR], [FAIL], [WARNING], [CRITICAL]
  - Actions: [DO], [DO NOT], [REQUIRED], [OPTIONAL]
  - Navigation: [NEXT], [PREVIOUS], [TIP], [NOTE]
  - Progress: [IN PROGRESS], [PENDING], [BLOCKED]

Additional changes:
  - Made paths cross-platform (~/ClaudeTools for Mac/Linux)
  - Fixed database host references to 172.16.3.30
  - Updated START_HERE.md and CONTEXT_RECOVERY_PROMPT.md for multi-OS use

Files updated: 58 markdown files across:
  - .claude/ configuration and agents
  - docs/ documentation
  - projects/ project files
  - Root-level documentation

This enforces the NO EMOJIS rule from directives.md and ensures
documentation renders correctly on all systems.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 16:21:06 -07:00

927 lines
19 KiB
Markdown

# 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)
```json
{
"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:**
```json
{
"refresh_token": "string"
}
```
**Response:**
```json
{
"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:**
```json
{
"refresh_token": "string"
}
```
**Response:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"client_id": "uuid",
"service_name": "AD2 Administrator",
"username": "sysadmin",
"password": "plaintext-password",
"credential_type": "password",
"requires_vpn": true,
"requires_2fa": false
}
```
**Response:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"comment": "Work completed: configured Veeam backup..."
}
```
**Response:**
```json
{
"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:**
```json
{
"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
```json
{
"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:**
```json
{
"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:**
```json
{
"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`
```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
- [OK] 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