{"service":"SSH Proxy API","version":"1.0.0","description":"Persistent SSH sessions for LLMs. No more paramiko reinstalls.","base_url":"https://synapse.schaefer.zone (via Synapse gateway)","auth":{"type":"Bearer","token":"Mind Key (verified against Synapse API)","header":"Authorization: Bearer <MIND_KEY>"},"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":[{"method":"POST","path":"/ssh/new","description":"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":"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"},{"method":"POST","path":"/ssh/:id/exec","description":"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":"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"},{"method":"GET","path":"/ssh/:id/output","description":"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_curl":"sleep 3 && curl -H \"Authorization: Bearer $MIND_KEY\" https://synapse.schaefer.zone/ssh/SESSION_ID/output"},{"method":"GET","path":"/ssh/sessions","description":"List all active sessions for this Mind Key","response":{"sessions":"array","count":"number"},"example_curl":"curl -H \"Authorization: Bearer $MIND_KEY\" https://synapse.schaefer.zone/ssh/sessions"},{"method":"DELETE","path":"/ssh/:id","description":"Close SSH session and free resources","response":{"status":"closed","session_id":"UUID"},"example_curl":"curl -X DELETE -H \"Authorization: Bearer $MIND_KEY\" https://synapse.schaefer.zone/ssh/SESSION_ID"},{"method":"GET","path":"/health","description":"Liveness check (no auth required)","response":{"status":"ok"}},{"method":"GET","path":"/help","description":"This documentation (no auth required)","formats":"?format=text or ?format=json for machine-readable, default HTML"}],"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"]}