{
  "openapi": "3.1.1",
  "info": {
    "title": "Color Blindness Palette Simulator API",
    "version": "1.0.0",
    "summary": "Simulate protan, deutan and tritan vision for a palette and find colors that become confusable.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://luminacvdsimulator.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Simulate protan, deutan and tritan vision for a palette and find colors that become confusable.",
        "description": "Paste 2–24 colors and simulate protanomaly, deuteranomaly and tritanomaly from mild to full dichromacy with the Machado, Oliveira and Fernandes (2009) model. Pairs whose simulated CIEDE2000 difference falls below your threshold are listed, so you can fix chart, map and UI palettes before anyone squints.\n\nMethodology:\n- Each color is gamut-mapped to 8-bit sRGB, decoded to linear light and multiplied by the Machado, Oliveira and Fernandes (2009) simulation matrix. The published matrices cover severities 0–100% in 10% steps; other severities interpolate linearly between the two nearest matrices, as the authors suggest. 100% simulates dichromacy.\n- For normal vision and each simulated type, every pair is compared with CIEDE2000 in CSS Lab (D50). Pairs below the threshold are reported as confusable, together with their normal-vision difference; pairs that are already too close in normal vision are listed once, under normal vision.\n- The threshold is a design heuristic, not a standard: around 10 suits small chart marks and thin lines, larger areas tolerate less. Individual color vision varies; the simulation is an approximation and does not certify accessibility. Do not rely on color alone — add labels, patterns or shapes.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "lumina_cvd_simulator",
        "x-owner-app": "lumina",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LuminaCvdSimulatorInput"
              },
              "examples": {
                "example1": {
                  "summary": "Five classic chart colors",
                  "value": {
                    "colors": "#D62728 #2CA02C #1F77B4 #FF7F0E #9467BD",
                    "type": "all",
                    "severity": 100,
                    "threshold": 10
                  }
                },
                "example2": {
                  "summary": "Red and green status colors, mild deutan",
                  "value": {
                    "colors": "#E53935 #43A047 #FDD835",
                    "type": "deutan",
                    "severity": 60,
                    "threshold": 10
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LuminaCvdSimulatorResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "LuminaCvdSimulatorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "colors": {
            "title": "Palette colors (HEX or CSS colors, one per line or separated by spaces)",
            "type": "string",
            "maxLength": 16384,
            "default": "#D62728 #2CA02C #1F77B4 #FF7F0E #9467BD"
          },
          "type": {
            "title": "Color-vision type",
            "type": "string",
            "enum": [
              "all",
              "protan",
              "deutan",
              "tritan"
            ],
            "default": "all"
          },
          "severity": {
            "title": "Severity (%; 100 = dichromacy)",
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "default": 100
          },
          "threshold": {
            "title": "Confusion threshold (ΔE2000)",
            "type": "number",
            "minimum": 1,
            "maximum": 50,
            "default": 10
          }
        },
        "required": []
      },
      "LuminaCvdSimulatorResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "colors",
              "severity",
              "threshold",
              "normalPairs",
              "modes"
            ],
            "properties": {
              "colors": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "severity": {
                "type": "number"
              },
              "threshold": {
                "type": "number"
              },
              "normalPairs": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "a",
                    "b",
                    "deltaE2000",
                    "normalDeltaE2000"
                  ],
                  "properties": {
                    "a": {
                      "type": "integer"
                    },
                    "b": {
                      "type": "integer"
                    },
                    "deltaE2000": {
                      "type": "number"
                    },
                    "normalDeltaE2000": {
                      "type": "number"
                    }
                  }
                }
              },
              "modes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "mode",
                    "simulated",
                    "confusable",
                    "minDeltaE2000"
                  ],
                  "properties": {
                    "mode": {
                      "type": "string"
                    },
                    "simulated": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "confusable": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "a",
                          "b",
                          "deltaE2000",
                          "normalDeltaE2000"
                        ],
                        "properties": {
                          "a": {
                            "type": "integer"
                          },
                          "b": {
                            "type": "integer"
                          },
                          "deltaE2000": {
                            "type": "number"
                          },
                          "normalDeltaE2000": {
                            "type": "number"
                          }
                        }
                      }
                    },
                    "minDeltaE2000": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}