{
  "openapi": "3.1.1",
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "info": {
    "title": "KinToolkit Public Catalog and MCP HTTP API",
    "version": "1.0.0",
    "description": "Educational US liquid medicine label lookup, not a personalized prescription. Use only an exact listed bottle, concentration and published label band. Never send names, exact measurements, medical history or other patient details. Do not interpolate, convert concentrations or infer that a label reference is safe for a particular child. Preserve the age restrictions, directions, maximum and source together; verify the full package label and ask a clinician when unsure. This describes the existing discovery catalog and JSON-RPC MCP endpoint, not a REST dosing API. No authentication or API key is required. Tool calls may append minimal operational telemetry; arguments and results are excluded. No persistent protocol session is required."
  },
  "servers": [
    {
      "url": "https://kintoolkit.com",
      "description": "Production"
    }
  ],
  "security": [],
  "externalDocs": {
    "description": "Client setup, complete tool semantics, privacy and examples",
    "url": "https://kintoolkit.com/developers"
  },
  "tags": [
    {
      "name": "Discovery",
      "description": "Public reference and integration discovery"
    },
    {
      "name": "MCP",
      "description": "Stateless Streamable HTTP JSON-RPC label lookup"
    }
  ],
  "paths": {
    "/api/catalog.json": {
      "get": {
        "operationId": "getKinToolkitCatalog",
        "summary": "Read the public calculator and label-reference catalog",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "description": "Returns calculator URLs, Markdown alternatives, manufacturer sources, canonical public label references and MCP connection metadata. It accepts no patient data or dosing inputs.",
        "responses": {
          "200": {
            "description": "Public discovery catalog",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Catalog"
                }
              }
            }
          }
        }
      }
    },
    "/api/mcp": {
      "post": {
        "operationId": "sendKinToolkitMcpMessage",
        "summary": "Send one MCP JSON-RPC message",
        "tags": [
          "MCP"
        ],
        "security": [],
        "description": "Use a compatible MCP client. Send one UTF-8 JSON-RPC object per POST with Content-Type: application/json and Accept: application/json, text/event-stream. Protocol negotiation supports 2026-07-28 and 2025-11-25; the SDK manages version metadata and headers. Successful protocol requests return JSON or finite SSE depending on the negotiated protocol. Tool failures can have HTTP 200 and result.isError=true; ask_doctor with label_amount=null is a successful reference lookup. GET and DELETE are unsupported (405), and cross-origin browser access is not enabled. Bodies are limited to 16384 bytes; batches are rejected; function execution is limited to ten seconds. Vercel applies 120 HTTP requests per IP per 60-second regional fixed window. Edge 429 responses occur before this application and have provider-controlled bodies. Follow Retry-After when supplied; otherwise wait at least 60 seconds with jitter. Never send patient details.",
        "parameters": [
          {
            "in": "header",
            "name": "MCP-Protocol-Version",
            "required": false,
            "description": "Negotiated protocol version; required after legacy initialization and on modern requests. Legacy initialize may omit it.",
            "schema": {
              "type": "string",
              "examples": [
                "2026-07-28",
                "2025-11-25"
              ]
            }
          },
          {
            "in": "header",
            "name": "Mcp-Method",
            "required": false,
            "description": "Modern MCP clients mirror the JSON-RPC method here. Legacy clients may omit it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Mcp-Name",
            "required": false,
            "description": "Modern tools/call requests mirror params.name here. Legacy clients may omit it.",
            "schema": {
              "type": "string",
              "enum": [
                "list_calculator_bottles",
                "get_label_directions"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "A single protocol message, never a JSON-RPC batch. Tool arguments reuse the exact runtime schemas and must also form a supported bottle/concentration/band combination.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/McpMessage"
              },
              "examples": {
                "listBottles": {
                  "summary": "List supported bottles after protocol setup",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 1,
                    "method": "tools/call",
                    "params": {
                      "name": "list_calculator_bottles",
                      "arguments": {}
                    }
                  }
                },
                "labelReference": {
                  "summary": "Look up a fixed public label row after protocol setup",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 2,
                    "method": "tools/call",
                    "params": {
                      "name": "get_label_directions",
                      "arguments": {
                        "product_id": "motrin-infant",
                        "concentration": "50 mg / 1.25 mL",
                        "label_band": "12-17-lb"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC response, including protocol errors or tool errors; inspect error/result.isError. SSE data fields carry JSON-RPC messages, not a JSON response body.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "const": "no-store"
                },
                "description": "MCP responses are not cached."
              },
              "X-KinToolkit-Request-ID": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                },
                "description": "Optional random request receipt when operational telemetry is enabled; not a client identifier."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Finite server-sent event stream. Parse nonempty data fields as JSON-RPC messages."
                },
                "x-message-schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              }
            }
          },
          "202": {
            "description": "Accepted protocol notification or client response; no response body."
          },
          "400": {
            "description": "Malformed JSON, unsupported batch, invalid protocol message or version. Application-controlled errors include static resolution hints; SDK errors may omit these extensions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcError"
                }
              }
            }
          },
          "403": {
            "description": "Host or Origin rejected. Use the published endpoint with a server or local client.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApplicationProtocolError"
                }
              }
            }
          },
          "406": {
            "description": "Unsupported response media types; advertise application/json and text/event-stream.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcError"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 16384 bytes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApplicationProtocolError"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported request Content-Type; send application/json.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcError"
                }
              }
            }
          },
          "429": {
            "description": "Hosting firewall rate limit. The response body is provider-controlled and is not guaranteed to be JSON. Back off before retrying.",
            "headers": {
              "Retry-After": {
                "description": "Optional provider-supplied retry delay in seconds or HTTP date.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Other transport or hosting failure. Provider responses may not be JSON; do not interpret them as label directions."
          }
        },
        "x-mcp-tools": [
          {
            "name": "list_calculator_bottles",
            "title": "List supported medicine bottles",
            "description": "List the five supported US liquid medicine bottles, exact concentrations and public label-band identifiers. No patient inputs. Minimal operational telemetry records no tool arguments or results.",
            "inputSchema": {
              "$ref": "#/components/schemas/ListCalculatorBottlesInput"
            },
            "outputSchema": {
              "$ref": "#/components/schemas/ListCalculatorBottlesOutput"
            },
            "annotations": {
              "readOnlyHint": false,
              "destructiveHint": false,
              "idempotentHint": false,
              "openWorldHint": false
            }
          },
          {
            "name": "get_label_directions",
            "title": "Get printed label directions",
            "description": "Look up one public label row using identifiers from list_calculator_bottles. Requires an exact bottle/concentration match. Returns label amount or ask_doctor, age and weight restrictions, full directions, source and canonical URL. Does not determine suitability for a child. Minimal operational telemetry records no tool arguments or results.",
            "inputSchema": {
              "$ref": "#/components/schemas/GetLabelDirectionsInput"
            },
            "outputSchema": {
              "$ref": "#/components/schemas/GetLabelDirectionsOutput"
            },
            "annotations": {
              "readOnlyHint": false,
              "destructiveHint": false,
              "idempotentHint": false,
              "openWorldHint": false
            }
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "ListCalculatorBottlesInput": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "ListCalculatorBottlesOutput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "scope",
          "bottles"
        ],
        "properties": {
          "scope": {
            "type": "string"
          },
          "bottles": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "product_id",
                "name",
                "ingredient",
                "concentration",
                "note",
                "source",
                "label_bands"
              ],
              "properties": {
                "product_id": {
                  "type": "string",
                  "enum": [
                    "tylenol-child",
                    "tylenol-infant",
                    "motrin-child",
                    "motrin-infant",
                    "zyrtec-child"
                  ]
                },
                "name": {
                  "type": "string"
                },
                "ingredient": {
                  "type": "string"
                },
                "concentration": {
                  "type": "string",
                  "enum": [
                    "160 mg / 5 mL",
                    "100 mg / 5 mL",
                    "50 mg / 1.25 mL",
                    "1 mg / mL"
                  ]
                },
                "note": {
                  "type": "string"
                },
                "source": {
                  "type": "string",
                  "format": "uri"
                },
                "label_bands": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "label_band",
                      "weight_band",
                      "age_band",
                      "url"
                    ],
                    "properties": {
                      "label_band": {
                        "type": "string"
                      },
                      "weight_band": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "age_band": {
                        "type": "string"
                      },
                      "url": {
                        "type": "string",
                        "format": "uri"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "GetLabelDirectionsInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "product_id",
          "concentration",
          "label_band"
        ],
        "properties": {
          "product_id": {
            "type": "string",
            "enum": [
              "tylenol-child",
              "tylenol-infant",
              "motrin-child",
              "motrin-infant",
              "zyrtec-child"
            ]
          },
          "concentration": {
            "type": "string",
            "enum": [
              "160 mg / 5 mL",
              "100 mg / 5 mL",
              "50 mg / 1.25 mL",
              "1 mg / mL"
            ]
          },
          "label_band": {
            "type": "string",
            "enum": [
              "under-24-lb",
              "24-35-lb",
              "36-47-lb",
              "48-59-lb",
              "60-71-lb",
              "72-95-lb",
              "under-12-lb",
              "12-17-lb",
              "18-23-lb",
              "under-2-years",
              "2-5-years",
              "6-11-years"
            ]
          }
        }
      },
      "GetLabelDirectionsOutput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status",
          "product_id",
          "name",
          "ingredient",
          "concentration",
          "label_band",
          "weight_band",
          "age_band",
          "label_amount",
          "directions",
          "limitations",
          "source",
          "source_checked",
          "source_check_note",
          "url"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "label_reference",
              "ask_doctor"
            ]
          },
          "product_id": {
            "type": "string",
            "enum": [
              "tylenol-child",
              "tylenol-infant",
              "motrin-child",
              "motrin-infant",
              "zyrtec-child"
            ]
          },
          "name": {
            "type": "string"
          },
          "ingredient": {
            "type": "string"
          },
          "concentration": {
            "type": "string",
            "enum": [
              "160 mg / 5 mL",
              "100 mg / 5 mL",
              "50 mg / 1.25 mL",
              "1 mg / mL"
            ]
          },
          "label_band": {
            "type": "string",
            "enum": [
              "under-24-lb",
              "24-35-lb",
              "36-47-lb",
              "48-59-lb",
              "60-71-lb",
              "72-95-lb",
              "under-12-lb",
              "12-17-lb",
              "18-23-lb",
              "under-2-years",
              "2-5-years",
              "6-11-years"
            ]
          },
          "weight_band": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "age_band": {
            "type": "string"
          },
          "label_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "directions": {
            "type": "string"
          },
          "limitations": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "format": "uri"
          },
          "source_checked": {
            "type": "string",
            "format": "date"
          },
          "source_check_note": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        },
        "oneOf": [
          {
            "properties": {
              "status": {
                "const": "label_reference"
              },
              "label_amount": {
                "type": "string",
                "minLength": 1
              }
            }
          },
          {
            "properties": {
              "status": {
                "const": "ask_doctor"
              },
              "label_amount": {
                "type": "null"
              }
            }
          }
        ]
      },
      "Catalog": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "documentation": {
            "type": "string",
            "format": "uri"
          },
          "apiCatalog": {
            "type": "string",
            "format": "uri"
          },
          "openapi": {
            "type": "string",
            "format": "uri"
          },
          "purpose": {
            "type": "string"
          },
          "calculators": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "markdown": {
                  "type": "string",
                  "format": "uri"
                },
                "manufacturerSource": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "required": [
                "title",
                "description",
                "url",
                "markdown",
                "manufacturerSource"
              ]
            }
          },
          "labelReferences": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "markdown": {
                  "type": "string",
                  "format": "uri"
                },
                "manufacturerSource": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "required": [
                "title",
                "description",
                "url",
                "markdown",
                "manufacturerSource"
              ]
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "required": [
                "title",
                "url"
              ]
            }
          },
          "mcp": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string",
                "format": "uri"
              },
              "transport": {
                "const": "streamable-http"
              },
              "authentication": {
                "const": "none"
              },
              "stateless": {
                "const": true
              },
              "tools": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "list_calculator_bottles",
                    "get_label_directions"
                  ]
                }
              },
              "scope": {
                "type": "string"
              },
              "serverCard": {
                "type": "string",
                "format": "uri"
              },
              "documentation": {
                "type": "string",
                "format": "uri"
              },
              "markdown": {
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "url",
              "transport",
              "authentication",
              "stateless",
              "tools",
              "scope",
              "serverCard",
              "documentation",
              "markdown"
            ]
          }
        },
        "required": [
          "name",
          "url",
          "documentation",
          "apiCatalog",
          "purpose",
          "calculators",
          "labelReferences",
          "sources",
          "mcp"
        ]
      },
      "ListCalculatorBottlesRequest": {
        "type": "object",
        "properties": {
          "jsonrpc": {
            "const": "2.0"
          },
          "id": {
            "type": [
              "string",
              "integer"
            ]
          },
          "method": {
            "const": "tools/call"
          },
          "params": {
            "type": "object",
            "properties": {
              "name": {
                "const": "list_calculator_bottles"
              },
              "arguments": {
                "$ref": "#/components/schemas/ListCalculatorBottlesInput"
              },
              "_meta": {
                "type": "object",
                "additionalProperties": true
              }
            },
            "required": [
              "name",
              "arguments"
            ]
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "method",
          "params"
        ]
      },
      "GetLabelDirectionsRequest": {
        "type": "object",
        "properties": {
          "jsonrpc": {
            "const": "2.0"
          },
          "id": {
            "type": [
              "string",
              "integer"
            ]
          },
          "method": {
            "const": "tools/call"
          },
          "params": {
            "type": "object",
            "properties": {
              "name": {
                "const": "get_label_directions"
              },
              "arguments": {
                "$ref": "#/components/schemas/GetLabelDirectionsInput"
              },
              "_meta": {
                "type": "object",
                "additionalProperties": true
              }
            },
            "required": [
              "name",
              "arguments"
            ]
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "method",
          "params"
        ]
      },
      "ProtocolRequest": {
        "type": "object",
        "properties": {
          "jsonrpc": {
            "const": "2.0"
          },
          "id": {
            "type": [
              "string",
              "integer"
            ]
          },
          "method": {
            "type": "string",
            "not": {
              "const": "tools/call"
            }
          },
          "params": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "method"
        ],
        "description": "Other protocol requests such as initialize, server/discover, tools/list or ping. The MCP SDK validates their method-specific parameters; unsupported methods return protocol errors."
      },
      "ProtocolNotification": {
        "type": "object",
        "properties": {
          "jsonrpc": {
            "const": "2.0"
          },
          "method": {
            "type": "string",
            "pattern": "^notifications/"
          },
          "params": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "jsonrpc",
          "method"
        ]
      },
      "McpMessage": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/ListCalculatorBottlesRequest"
          },
          {
            "$ref": "#/components/schemas/GetLabelDirectionsRequest"
          },
          {
            "$ref": "#/components/schemas/ProtocolRequest"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProtocolNotification"
              },
              {
                "not": {
                  "properties": {
                    "id": {}
                  },
                  "required": [
                    "id"
                  ]
                }
              }
            ]
          },
          {
            "$ref": "#/components/schemas/JsonRpcResponse"
          }
        ]
      },
      "ToolResult": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "content": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "const": "text"
                    },
                    "text": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "type",
                    "text"
                  ]
                }
              },
              "structuredContent": {
                "$ref": "#/components/schemas/ListCalculatorBottlesOutput"
              },
              "isError": {
                "const": false
              },
              "_meta": {
                "type": "object",
                "additionalProperties": true
              }
            },
            "required": [
              "content",
              "structuredContent"
            ]
          },
          {
            "type": "object",
            "properties": {
              "content": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "const": "text"
                    },
                    "text": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "type",
                    "text"
                  ]
                }
              },
              "structuredContent": {
                "$ref": "#/components/schemas/GetLabelDirectionsOutput"
              },
              "isError": {
                "const": false
              },
              "_meta": {
                "type": "object",
                "additionalProperties": true
              }
            },
            "required": [
              "content",
              "structuredContent"
            ]
          },
          {
            "type": "object",
            "properties": {
              "isError": {
                "const": true
              },
              "content": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "const": "text"
                    },
                    "text": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "type",
                    "text"
                  ]
                }
              },
              "_meta": {
                "type": "object",
                "additionalProperties": true
              }
            },
            "required": [
              "isError",
              "content"
            ]
          }
        ]
      },
      "JsonRpcSuccess": {
        "type": "object",
        "properties": {
          "jsonrpc": {
            "const": "2.0"
          },
          "id": {
            "type": [
              "string",
              "integer"
            ]
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ToolResult"
              },
              {
                "type": "object",
                "not": {
                  "anyOf": [
                    {
                      "properties": {
                        "structuredContent": {}
                      },
                      "required": [
                        "structuredContent"
                      ]
                    },
                    {
                      "properties": {
                        "content": {}
                      },
                      "required": [
                        "content"
                      ]
                    }
                  ]
                },
                "description": "SDK protocol result such as server capabilities, tools/list or ping."
              }
            ]
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "result"
        ]
      },
      "JsonRpcError": {
        "type": "object",
        "properties": {
          "jsonrpc": {
            "const": "2.0"
          },
          "id": {
            "type": [
              "string",
              "integer",
              "null"
            ]
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "integer"
              },
              "message": {
                "type": "string"
              },
              "data": {}
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "jsonrpc",
          "error"
        ]
      },
      "JsonRpcResponse": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/JsonRpcSuccess"
          },
          {
            "$ref": "#/components/schemas/JsonRpcError"
          }
        ]
      },
      "ApplicationProtocolError": {
        "type": "object",
        "properties": {
          "jsonrpc": {
            "const": "2.0"
          },
          "id": {
            "type": "null"
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "integer"
              },
              "message": {
                "type": "string"
              },
              "data": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "enum": [
                      "invalid_host",
                      "invalid_origin",
                      "body_too_large",
                      "batch_not_supported",
                      "invalid_json"
                    ]
                  },
                  "resolution": {
                    "type": "string"
                  },
                  "documentation": {
                    "type": "string",
                    "format": "uri"
                  }
                },
                "required": [
                  "reason",
                  "resolution",
                  "documentation"
                ]
              }
            },
            "required": [
              "code",
              "message",
              "data"
            ]
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "error"
        ]
      }
    }
  }
}
