Reference
Error codes
Every Lumin error follows the same shape: an MCP error object with a stable code, a human-readable reason, and (where useful) a recovery hint.
The error shape
{
"isError": true,
"content": [{
"type": "text",
"text": "Daily limit reached. Resets at 00:00 UTC."
}],
"_meta": {
"code": "rate_limited",
"recoverable": false
}
}All codes
| Code | HTTP | Cause | Recovery |
|---|---|---|---|
| rate_limited | 429 | Daily quota or burst limit reached | Stop reading, surface to user, do not retry |
| invalid_event_name | 400 | Event keyword not recognized | Map to nearest known event or pass house_group override |
| birth_data_missing | 400 | Tool requires birth data and none in context | Call set_birth_profile, then retry once |
| validation_failed | 400 | Schema validation rejected input | Fix input, do not retry blindly |
| auth_invalid | 401 | Bearer token rejected | Refresh OAuth or rotate API key |
| auth_expired | 401 | OAuth token expired | Refresh against /token endpoint |
| tier_insufficient | 403 | Tier does not allow this tool or limit | Upgrade tier or use a free-tier alternative |
| user_suspended | 403 | Account is suspended | Contact support, no automated recovery |
| engine_unavailable | 502 | kp-engine transient failure | Exponential backoff, max 2 retries |
| engine_timeout | 504 | kp-engine slow response | Retry with timeout extension or skip phase |
| internal_error | 500 | Unhandled MCP-side error | Retry once, then escalate with request id |
Idempotency
All Lumin tool calls are pure. Retrying produces the same result, and failed calls do not count against your quota.