Start in 60 seconds
Base URL https://covelightcare.com. No key, no account, JSON back. Every snippet below was run, as written, before it went on this page; the reference shows each full response.
Call the REST API from a server or a script. It sends no CORS headers, so a web page on another site cannot call it from the browser. The MCP server and the discovery files allow any origin.
List homes in an area
Filter by county, city and state care approvals. Alphabetical, paged. Reference and full response
curl "https://covelightcare.com/api/v1/facilities?county=Los%20Angeles&needs=dementia,wheelchair&limit=2"const res = await fetch("https://covelightcare.com/api/v1/facilities?county=Los%20Angeles&needs=dementia,wheelchair&limit=2");
const body = await res.json();
if (!res.ok) throw new Error(`${res.status}: ${body.error}`);
console.log(`${body.data.total} homes; next page: offset=${body.data.offset + body.data.limit}`);
for (const f of body.data.facilities) console.log(f.license_number, f.name.value, f.clearances.dementia.value);import requests
res = requests.get("https://covelightcare.com/api/v1/facilities", params={"county": "Los Angeles", "needs": "dementia,wheelchair", "limit": "2"}, timeout=30)
body = res.json()
if not res.ok:
raise SystemExit(f"{res.status_code}: {body['error']}")
print(body["data"]["total"], "homes; next page: offset =", body["data"]["offset"] + body["data"]["limit"])
for f in body["data"]["facilities"]:
print(f["license_number"], f["name"]["value"], f["clearances"]["dementia"]["value"])One home’s record
Every fact with its source class, date and a stable ref. Reference and full response
curl "https://covelightcare.com/api/v1/facilities/191200037"const res = await fetch("https://covelightcare.com/api/v1/facilities/191200037");
const body = await res.json();
if (!res.ok) throw new Error(`${res.status}: ${body.error}`);
const home = body.data;
console.log(home.name.value, home.license_status.value, "as of", home.license_status.confirmed_on);
for (const [need, fact] of Object.entries(home.clearances)) console.log(need, fact.value);import requests
res = requests.get("https://covelightcare.com/api/v1/facilities/191200037", timeout=30)
body = res.json()
if not res.ok:
raise SystemExit(f"{res.status_code}: {body['error']}")
home = body["data"]
print(home["name"]["value"], home["license_status"]["value"], "as of", home["license_status"]["confirmed_on"])
for need, fact in home["clearances"].items():
print(need, fact["value"])A home’s state documents
Inspection and complaint documents, newest first, with the home’s record on the state’s site. Reference and full response
curl "https://covelightcare.com/api/v1/facilities/191200037/reports"const res = await fetch("https://covelightcare.com/api/v1/facilities/191200037/reports");
const body = await res.json();
if (!res.ok) throw new Error(`${res.status}: ${body.error}`);
console.log("Read them at", body.data.state_record_url);
for (const r of body.data.reports) console.log(r.date, r.title);import requests
res = requests.get("https://covelightcare.com/api/v1/facilities/191200037/reports", timeout=30)
body = res.json()
if not res.ok:
raise SystemExit(f"{res.status_code}: {body['error']}")
print("Read them at", body["data"]["state_record_url"])
for r in body["data"]["reports"]:
print(r["date"], r["title"])The guides
Covelight’s editorial guides, with their review dates. Reference and full response
curl "https://covelightcare.com/api/v1/guides"const res = await fetch("https://covelightcare.com/api/v1/guides");
const body = await res.json();
if (!res.ok) throw new Error(`${res.status}: ${body.error}`);
for (const g of body.data.guides) console.log(g.title, g.url);import requests
res = requests.get("https://covelightcare.com/api/v1/guides", timeout=30)
body = res.json()
if not res.ok:
raise SystemExit(f"{res.status_code}: {body['error']}")
for g in body["data"]["guides"]:
print(g["title"], g["url"])Check up to 100 homes at once
Names or license numbers. A name that fits several licenses returns the candidates, never a guess. Reference and full response
curl -X POST "https://covelightcare.com/api/v1/check" \
-H "Content-Type: application/json" \
-H "X-Client-Name: your-product" \
-d '{"homes":["191200037","Sunrise","Zzqx Nothing"]}'const res = await fetch("https://covelightcare.com/api/v1/check", {
method: "POST",
headers: { "Content-Type": "application/json", "X-Client-Name": "your-product" },
body: JSON.stringify({"homes":["191200037","Sunrise","Zzqx Nothing"]}),
});
const body = await res.json();
if (!res.ok) throw new Error(`${res.status}: ${body.error}`);
for (const r of body.data.results) {
console.log(r.input, r.status, r.home?.name ?? r.candidates.map((c) => c.name).join(" / "));
}import requests
res = requests.post("https://covelightcare.com/api/v1/check", json={"homes": ["191200037", "Sunrise", "Zzqx Nothing"]}, headers={"X-Client-Name": "your-product"}, timeout=30)
body = res.json()
if not res.ok:
raise SystemExit(f"{res.status_code}: {body['error']}")
for r in body["data"]["results"]:
print(r["input"], r["status"], r["home"]["name"] if r["home"] else [c["name"] for c in r["candidates"]])Budgets per IP: 120 requests a minute on /api/v1/*, 30 on POST /api/v1/check. Details: rate limits.
Connect an AI assistant (MCP)
The server is https://covelightcare.com/mcp: Streamable HTTP, stateless, JSON responses. It needs no key and no OAuth. Its tools: find_homes, check_homes, get_home, get_state_documents, compare_homes, homes_near_hospital, explain_care_topic, start_family_request, search, fetch. One check_homes call checks up to 100 homes.
https://covelightcare.com/mcpClaude (claude.ai and Claude Desktop)
Add to ClaudeThe button opens Claude’s “Add custom connector” form with the name and URL filled in. Nothing is added until you confirm. By hand:
- Open Customize, then Connectors.
- Choose +, then Add custom connector.
- Paste the server URL and choose Add. Leave the OAuth fields under Advanced settings empty.
Claude Desktop uses the same Connectors setting; a remote server needs no entry in claude_desktop_config.json. On the Free plan you can add one custom connector. On Team and Enterprise, an Owner adds it under Organization settings, Connectors (prefilled admin link); members then choose Connect.
Claude Code
claude mcp add --transport http covelight https://covelightcare.com/mcpAdd --scope project to share it through .mcp.json, or --scope user for every project. Use --transport http; this server does not serve the older SSE transport. If you sign in to Claude Code with a claude.ai account, a connector you added on claude.ai is already there.
{
"mcpServers": {
"covelight": {
"type": "http",
"url": "https://covelightcare.com/mcp"
}
}
}Cursor
Add to CursorOpens Cursor’s install prompt, if Cursor is installed. Or add it to ~/.cursor/mcp.json (every project) or .cursor/mcp.json (one project):
{
"mcpServers": {
"covelight": {
"url": "https://covelightcare.com/mcp"
}
}
}VS Code
Add to VS CodeOpens VS Code’s install prompt, if VS Code is installed. From a terminal:
code --add-mcp "{\"name\":\"covelight\",\"type\":\"http\",\"url\":\"https://covelightcare.com/mcp\"}"Or in .vscode/mcp.json:
{
"servers": {
"covelight": {
"type": "http",
"url": "https://covelightcare.com/mcp"
}
}
}ChatGPT (developer mode)
- In ChatGPT on the web, open Settings, then Security and login, and turn on Developer mode.
- Go to ChatGPT Plugins and choose the plus button to create a developer-mode app.
- Give it the server URL and choose No Authentication.
- In a chat, choose Developer mode from the + menu and select the app.
Developer mode is for Pro, Plus, Business, Enterprise and Education accounts, on the web. We know of no one-click install link for ChatGPT.
Any other MCP client
Point it at the server URL with the Streamable HTTP transport. Most clients read an mcpServers entry like this:
{
"mcpServers": {
"covelight": {
"type": "http",
"url": "https://covelightcare.com/mcp"
}
}
}Or call it by hand: JSON-RPC with curl.
Where it can’t connect yet
- Not in any directory yet. Covelight Care — California care homes is not listed in Claude’s connector directory or ChatGPT’s plugin directory, so neither host suggests it on its own. You add it by its URL, and Claude labels it “Custom”.
- ChatGPT’s Free plan and mobile apps. Developer mode is web-only, on the plans named above.
- Clients that speak only a revision newer than these. The server speaks
2026-07-28,2025-11-25,2025-06-18,2025-03-26,2024-11-05,2024-10-07— MCP’s 2026-07-28 revision and the 2025initializehandshake, on the same URL. A request that declares a newer version gets a 400 that names the revision to use instead (example). - Clients that need a GET event stream or the old SSE transport. The server is stateless and POST-only; GET answers 405.
- Hosts that only start local (stdio) servers and cannot reach a remote URL.
The data dictionary
The fields a caller must read correctly. The REST API wraps each fact as { value, source_class, confirmed_on, next_due, ref }; the MCP tools return flat records with an as_of date on each group.
Yes, no, and “not on file”
| Value | What the record says | What to tell a family |
|---|---|---|
"true" | The record states it. For a care approval, the license carries it. | State it, with its source and date — unless the license is closed (below). |
"false" | The record states a real negative. For a care approval, the license lacks it. | “Not on file” — never “No”. |
"not_on_file" | The record we hold says nothing either way. | “Not on file” — never “No”. |
These are strings, not booleans, and a value is never left out to imply a negative. “Not on file” is a statement about the record, not about the home: the home can answer it on the phone. The wire keeps "false" apart for software; in words, both non-true values read “not on file”.
A list the state publishes of who takes part, like the Medi-Cal waiver list, can only say “true” or "not_on_file": being absent from a list is not a verified “no”. On MCP records, a fact under a correction review reads "not_on_file" until the review closes, and the full record names it in clearances.under_review.
Dates and provenance
| Field | Where | Meaning |
|---|---|---|
source_class | REST facts | Who asserted the value: state, operator_attested, machine_extracted, third_party. Map coordinates are machine_extracted; the address is the state’s. |
confirmed_on | REST facts | The date the source last confirmed the value: the home’s CDSS record snapshot for roster facts, the DHCS list date for the waiver. null means the source gives no date — not that the value is fresh. |
next_due | REST facts | When a published refresh cadence next re-checks the value. null on every fact today: no cadence is published yet. |
ref | REST facts, reports | A stable address for the fact (roster:…, derived:…, doc:…). On complaint reports, doc: carries the state’s control number; inspection and other reports have none, so it carries Covelight’s own key — stable here, but not a state identifier. |
attribution.retrieved_on | REST envelope | For one home, its record’s snapshot date. For the batch check, when the CDSS record was last loaded. For lists and document lists, the date of Covelight’s newest successful data run, which can be newer than the CDSS record itself — each fact’s confirmed_on is the record’s own date. For the guides, their review date. attribution.source names the agency (California Department of Social Services, Community Care Licensing Division), or Covelight Care for the guides, which are our own words. |
generated_at | REST envelope | When this response was built — not how old the data is. |
as_of, data_dates | MCP records | Each group’s date, and per result state_record_loaded_on (the CDSS load) and alw_list_as_of (the DHCS list date). Dates are ISO; the display text writes them out. |
state_record_url | Reports, MCP documents | The home’s record on the state’s licensing site, where the documents the state currently lists can be read. Link this. get_state_documents can also return older documents Covelight transcribed that the state’s listing no longer shows. |
document url | Reports, MCP documents | null for every document today. The state publishes no stable address per document (its links are positional, and the feed carries placeholders), so none is given rather than a wrong one. Use state_record_url. |
Check the dates rather than polling: a response is only as current as its retrieved_on and confirmed_on say.
License status, including closed licenses
license_status (REST) and license.status (MCP) are the state’s own words, verbatim, with the record’s date. Lists — GET /api/v1/facilities, find_homes and homes_near_hospital — include only licenses whose status is one of LICENSED, LICENSED/PENDING INCREASE, PROBATIONARY LICENSE (any capitalization). Homes on probation are included, and on_probation says so.
A look-up by license or name also finds closed licenses, because a family asking “is this place licensed?” deserves the answer. On MCP records, license.closed (or license_closed) is true for any status containing the word CLOSED. The care approvals and the waiver value stay as the record left them, marked license_closed: true with a dated closed_note: they are history, not current approvals. price is null, and start_family_request refuses the license. The v1 REST record has no closed flag: read license_status.value, and when it contains CLOSED, its clearance and waiver values are what the record held while the license was open — never present them as current.
license_status_live (REST) is the last live check against the state’s site that Covelight Care stored, dated by its own confirmed_on. It can be null. An API call never starts a live check.
Price kinds (MCP)
MCP records carry one monthly starting figure, and price.kind says whose figure it is. Only is_this_homes_own_rate: true makes it a price. Quote price.line, which names the source and date, or the estimate and its range. POST /api/v1/check returns the same records; the other REST endpoints carry no price.
kind | Whose figure | What comes with it |
|---|---|---|
home_listed | The home’s own rate, as its listing on a listing site publishes it. | listing: the site, its URL, seen_on and updated_on. |
home_confirmed | The home’s own rate, which the listing site says the home confirmed. | listing: the site, its URL, seen_on and updated_on. |
covelight_estimate | Covelight’s estimate, modeled on the listed rates of comparable homes nearby. Not the home’s price. | likely_range_usd: the likely low and high. |
area_typical | A typical starting rate for the county, or a broader range where listings are thin. Not the home’s price. | likely_range_usd: the likely low and high. |
find_homes’ max_monthly_budget_usd, in the tool’s own words: “Monthly ceiling in whole dollars, 1000 to 30000. Reads each home’s starting figure — its own listed rate, else Covelight’s estimate or the area’s typical rate; a home with no figure on file stays in. Example: 6000.” price is null when no figure is on file, and always on a closed license.
Medi-Cal Assisted Living Waiver
medi_cal_alw.value (MCP) and alw_participation (REST) are "true" when the home is on the Department of Health Care Services participant list, else "not_on_file" — never "false". The list’s own date is list_as_of (REST: confirmed_on).
Carry the scope sentence with any “true”. MCP records carry it as medi_cal_alw.scope: “The waiver pays for care services, not room and board.”
Neutral order: there is no ranking parameter
REST lists come alphabetically by name, then license number. MCP lists come by straight-line distance from a point when the call gives one, else alphabetically; check_homes keeps the order you sent; compare_homes puts its columns in alphabetical order. No score, tier, price or payment orders anything.
A sort, order or rank parameter is refused with the reason, never ignored (REST, MCP). Every MCP list result carries the sentence to pass on: “No home pays to appear here. Nothing on this page is ranked by quality, popularity or payment.”
What is never in this data
- Availability. No field says whether a home has an open bed, under any name. What every MCP list result says instead: “No website — including this one — knows which homes have an open bed today. Openings change daily and live only inside each home. That is what the phone call is for.”
- Scores, ratings and tiers. None exists to return.
- Business fields. The record’s columns are named one by one, and every payload is scanned for business and availability keys before it is sent.
- Personal data. No family, lead or contact data is reachable. A home’s phone is the number on the state roster.
Markdown pages
Care home pages, and county, city, care-type, Medi-Cal, near-hospital and license-holder pages, each have a short Markdown version: the page’s core facts, in the page’s own words, answer first. Add .md to the page’s URL, or request the page itself with Accept: text/markdown. Every home record from the MCP tools carries its markdown link.
A Markdown version is marked noindex and names the HTML page in a Link: rel="canonical" header. Cite the HTML page, never the .md address. When the page is requested by Accept, the response also varies on Accept.
GET https://covelightcare.com/facility/regency-park-oak-knoll-191200037.mdResponse · 200 · text/markdown; charset=utf-8
HTTP 200
content-type: text/markdown; charset=utf-8
cache-control: s-maxage=86400, stale-while-revalidate=31449600
link: <https://covelightcare.com/facility/regency-park-oak-knoll-191200037>; rel="canonical"
x-robots-tag: noindex
# Regency Park Oak Knoll
License #191200037 · Pasadena, Los Angeles County · Licensed for 206 — Large care community · a licensed care home (RCFE)
Regency Park Oak Knoll is a large care community in Pasadena — a licensed residential care facility for the elderly (RCFE), the licence category behind “assisted living” and “board and care.” It is licensed for 206 residents since 1987. Hospice care and bedridden care are not on file.
- Care approvals on file: Wheelchair · Dementia — State licensing record · September 13, 2026
- Starting rate: $5,950 a month — Listed by the home on Seniorly · September 9, 2026
Full page: <https://covelightcare.com/facility/regency-park-oak-knoll-191200037>
A citation does not make a home unsafe, and an empty file does not make a home good.
## Quick answers about Regency Park Oak Knoll
…Shortened for this page (… marks each cut): body: the first 14 of 89 lines shown.
The family hand-off
An assistant can never agree to contact for a family. Only the family can, on covelightcare.com, with their own click, after reading which homes would receive their name and phone number.
- The assistant calls
start_family_requestwith 1–5 license numbers the family chose, and optionally care needs, timing, an area and a note. It sends no personal details. The tool screens every free-text field for them (names, phone numbers, emails, addresses) and refuses the call when the screen finds one (example), but a screen cannot catch every name: send none. - The tool writes nothing about the family. It returns a signed link, dated to lapse in 7 days,
relay_sentence(one sentence to pass on), a longerfamily_message, each home’s roster phone and questions to ask, andconsent.agent_can_consent: false. - The family opens the link. Covelight Care opens its free plan-calls-and-visits page with those homes already chosen, and a folded note saying an assistant chose them and that opening the link told no home about them. After 7 days the link still opens the homes, without that note, and a request the family later sends is no longer attributed to the assistant.
- What happens next depends on one switch Covelight Care holds.
| Coordination off (this site today) | Coordination on | |
|---|---|---|
mode | self_serve_only | coordination_available |
relay_sentence | Here is a free page to plan calls and visits with the 2 homes you picked — no home hears from you unless you call it: https://covelightcare.com/h/a1.tm7ewv.example-client.191200037-197602925.d.m~… | Here is a free page with the 2 homes you picked, where you can call them yourself or ask Covelight Care to help arrange visits — nothing is sent unless you agree there: https://covelightcare.com/h/a1.tm7ewv.example-client.191200037-197602925.d.m~… |
what_happens_next |
|
|
| The family | Plans calls and visits, keeps notes, and calls the homes. Covelight Care does not arrange calls or visits in this mode, and nothing is sent to any home. | Can also ask Covelight Care to help arrange calls or visits: they keep a list link, offer times, review one request naming each home, read the consent sentence, tick it, type their own name and phone number, and submit. Nothing is sent before they submit. |
The link (hand-off signatures are cut on this page) carries only license numbers, the care needs, a timing choice, an expiry and the MCP client’s own name from its initialize call. Nothing typed in assistant_name or family_note goes into it. A tampered link opens nothing. Both captured calls, in full: the tool reference.
Terms and attribution
The API and the MCP server are free to use, including commercially, on these conditions:
- Attribute. Where you display or pass on this data, credit Covelight Care — CDSS state record with a link to https://covelightcare.com. The facts are California public records; the compilation, refresh and provenance are ours.
- Do not misrepresent it. Do not present it as your own original record. Do not show a “not on file” value as a “no”. Do not attach any claim that a home has an opening. Do not imply that any home pays for its place in this data, to appear or to be ordered: none can, because no business field is read and nothing orders a list but name, distance or your own order.
- Carry the state’s notices. Parts come from the California Health and Human Services open-data portal: credit the California Health and Human Services Agency, and say that what you show is modified data, not official government data. The official record is the state’s own facility search.
Found an error? Every record carries a corrections link (links.corrections). Hand it to your user: corrections are checked against the state’s records and logged at /corrections. We may slow or block traffic that breaks these terms or strains the service.
Discovery files
| Address | What it is |
|---|---|
/mcp/server-card | The MCP server card, at the address the server-card draft reserves: name, version, description, icon, and the remote with the protocol versions it speaks. |
/.well-known/mcp/server-card.json | The same card, where discovery scanners look. |
/.well-known/ai-catalog.json | The site’s AI catalog: one entry, pointing at the server card. |
/.well-known/mcp/server.json | The server in the MCP Registry’s server.json format. |
/openapi.json | The REST contract, OpenAPI 3.1. |
/api/v1 | The REST front door: every endpoint, as JSON. |
/llms.txt | A plain-text map of the site for language models. |
The server-card and catalog formats are an experimental MCP extension. The card, the catalog and server.json each answer with an ETag, allow any origin, and may be cached for an hour.
Support
Email hello@covelightcare.com with the request you sent, the response you got, and when. How the data is built, fact by fact: /methodology. The dataset: /data.
Changelog
The MCP server is at version 1.1.2. Changes are additive; a rename or removal is announced here first, with at least 90 days’ notice (compatibility policy).
- get_state_documents and get_home list one document for every report the state lists. A complaint whose investigation filed several reports under one control number now shows each report; about 1,800 across California were folded into one of their siblings before. A transcription is matched to its listed report by the state's own document id before date and form, so a report the state's list dates differently from its print no longer appears twice. No field changed.
- A one-time correction to a report's ref on /api/v1/facilities/{license}/reports: it is now doc: followed by the state's own document id, one per document and stable from one harvest to the next. It used to be the row's key: a complaint's control number, which every report of that complaint shares, or for other reports a key of ours that moved between harvests although it was documented as stable. A ref stored before 2026-09-28 will not match. A complaint's control number now comes from the new field control_number, which is null on reports the state lists without one. The list now includes every report the state lists, so a home's total can rise.
- start_family_request refuses more names. A name with an apostrophe after its first letter (O’Brien, D’Angelo), typed with a straight or curly apostrophe, is now caught wherever a plain name already was: after “named” or “called”, a title such as Mrs., or a family word. An introduction of a relative’s, friend’s, neighbor’s, patient’s, client’s or resident’s name (“grandma’s name is …”, “my mother-in-law’s name is …”) is caught too, not only a parent’s. The screen still cannot catch every name, so the rule is unchanged: send no personal details.
- service_designations on /api/v1/facilities and /api/v1/facilities/{license} leaves out a state service code that grants a clearance under a correction review: every code while the dementia clearance is held, and "985 - RCFE / HOSPICE" while the hospice clearance is held. The facility page already left out every code under a dementia hold; it now also leaves out the hospice code under a hospice hold.
- A clearance under a correction review now reads "not_on_file" on /api/v1/facilities and /api/v1/facilities/{license}, as it already did on the facility page and in the MCP tools, and it no longer matches a needs filter. Both are CDN-cached for five minutes (was an hour), so a review reaches them within minutes.
- explain is now explain_care_topic. The old name still answers until 2026-12-22, then it is removed. New: search and fetch, the tool pair ChatGPT connectors and deep research call; fetch returns a home’s page as Markdown with its canonical URL. /mcp speaks MCP 2026-07-28 (server/discover, no session) beside the 2025 initialize handshake. Every tool description says when to use it and what it is not for, and every argument names its allowed values with an example. Budget: 60 requests a minute per caller; inside Anthropic’s and OpenAI’s published egress ranges the caller is the session or the ChatGPT user, under a shared per-host ceiling. Over budget, the answer is 429 with Retry-After and a JSON-RPC error. Two names for every home. name is now the name the home goes by: the licensed name without a trailing legal form such as LLC, Inc., Corp. or Ltd. The exception is a fixed list of 22 names that two licences in one city would otherwise share; those keep the form wherever they appear. The new field licensed_name holds the name on the license, verbatim as filed. It appears on home records, summaries, check_homes candidates and get_state_documents. Links are unchanged.
- licensed_name on /api/v1/facilities records and POST /api/v1/check results: the name on the license, verbatim. It is an additive field; name on /api/v1/facilities keeps the record's own string.
- This developer portal: a quickstart in curl, JavaScript and Python, per-host MCP setup, a reference generated from openapi.json and the MCP tool registry with real responses, and a data dictionary. Discovery files: the MCP server card at /mcp/server-card and /.well-known/mcp/server-card.json, and /.well-known/ai-catalog.json.
- First release of the remote MCP server at /mcp: find_homes, check_homes (up to 100 homes a call), get_home, get_state_documents, compare_homes, homes_near_hospital, explain and start_family_request. POST /api/v1/check, the REST twin of check_homes. Markdown versions of pages ({page}.md, or Accept: text/markdown).
- The v1 read API: GET /api/v1, /api/v1/facilities, /api/v1/facilities/{license}, /api/v1/facilities/{license}/reports and /api/v1/guides, with the OpenAPI 3.1 contract at /openapi.json.