# SSH Proxy API - Self-Documenting Help Persistent SSH sessions for LLMs. No more paramiko reinstalls. Base URL: https://synapse.schaefer.zone (via Synapse gateway) Auth: Authorization: Bearer ## IMPORTANT NOTES - privateKey must be RAW PEM STRING with real newlines (NOT base64-encoded, NOT \\n-escaped) - Sessions auto-close after 30 min idle - Output is buffered - poll /ssh/:id/output 2-3s after exec - All routes (except /health and /help) require Authorization header ## ENDPOINTS ### POST /ssh/new Create new SSH session Body: - host: string (required) - hostname or IP - port: number (default 22) - SSH port - username: string (required) - SSH user - privateKey: string (required) - RAW PEM private key with real newlines Response: {"status":"connected","session_id":"UUID","host":"string","username":"string"} Example: curl -X POST -H "Authorization: Bearer $MIND_KEY" -H "Content-Type: application/json" -d "$(python3 -c 'import json; print(json.dumps({"host":"vps1.schaefer.zone","port":22,"username":"root","privateKey":open("/path/to/key").read()}))' )" https://synapse.schaefer.zone/ssh/new ### POST /ssh/:id/exec Execute command on active session Body: - command: string (required) - bash command - timeout: number (optional, default 30) - timeout in seconds Response: {"status":"executing","session_id":"UUID"} Example: curl -X POST -H "Authorization: Bearer $MIND_KEY" -H "Content-Type: application/json" -d '{"command":"hostname; whoami"}' https://synapse.schaefer.zone/ssh/SESSION_ID/exec ### GET /ssh/:id/output Poll command output (call 2-3s after exec) Response: {"session_id":"UUID","output":"string (stdout+stderr)","exit_code":"null if running, else number","running":"boolean"} Example: sleep 3 && curl -H "Authorization: Bearer $MIND_KEY" https://synapse.schaefer.zone/ssh/SESSION_ID/output ### GET /ssh/sessions List all active sessions for this Mind Key Response: {"sessions":"array","count":"number"} Example: curl -H "Authorization: Bearer $MIND_KEY" https://synapse.schaefer.zone/ssh/sessions ### DELETE /ssh/:id Close SSH session and free resources Response: {"status":"closed","session_id":"UUID"} Example: curl -X DELETE -H "Authorization: Bearer $MIND_KEY" https://synapse.schaefer.zone/ssh/SESSION_ID ### GET /health Liveness check (no auth required) Response: {"status":"ok"} Example: undefined ### GET /help This documentation (no auth required) Example: undefined ## COMMON ERRORS - "Cannot parse privateKey: Unsupported key format": You sent privateKey as base64. Send it as RAW PEM string. - "All configured authentication methods failed": Your privateKey is malformed or wrong. Make sure newlines are real (\\n in JSON, not double-escaped). - "session_not_found": Session ID is wrong or session already closed (30 min idle timeout). - "invalid_token": Mind Key not provided or invalid. Check Authorization header. ## TYPICAL WORKFLOW 1. POST /ssh/new with privateKey (raw PEM) -> get session_id 2. POST /ssh/SESSION_ID/exec {"command": "..."} -> start command 3. sleep 3; GET /ssh/SESSION_ID/output -> get output 4. Repeat 2-3 for more commands on same session 5. DELETE /ssh/SESSION_ID -> cleanup