Kempton Watch Tip

Connect an AI client

The case file is available as an MCP server, so Claude, ChatGPT, Cursor, VS Code or your own script can read the record directly: every victim, statement, arrest, count and conflict, each with its source. It is the same public record this website shows, nothing more.

Anonymous, read-only

No account. Add this URL to your client as a remote (Streamable HTTP) MCP server.

https://kempton.watch/mcp/public

Limits: 60 requests a minute and 3,000 a day per address; search 30 a minute; the whole-bundle resource 6 a minute. Data refreshes about every two hours.

Signed in

For account holders with a verified email and an authenticator app. Your client registers itself and asks you to approve it once (OAuth 2.1; desktop clients may use claude://, cursor:// or vscode:// callbacks). Today it reads the same record; the ability to submit tips and your own analysis will arrive here first.

https://kempton.watch/mcp

Limit: 240 requests a minute. Revoke a client any time under Settings → Security → Connected AI clients.

Tools

Every tool answers with the data as structured content plus a short text rendering, stamped with as_of and bundle_version. Lists page with cursor and limit.

case_overview Where the case stands: the official tally as last reported (with its source), how many victims are in the reco... details

Where the case stands: the official tally as last reported (with its source), how many victims are in the reconciled register and how many are named, dated or disputed, how many official statements, arrests and source conflicts are recorded, when the data was last refreshed, and what changed in the last seven days. Start here.

victims_list The reconciled register of victims, one row per body, in the order found. Each row carries the confidence stat... details

The reconciled register of victims, one row per body, in the order found. Each row carries the confidence status of the date (confirmed = an official source or two independent on-the-ground sources; reported = fewer), the suburb (coordinates are suburb centroids; the location text is quoted as written and may name a street or landmark), which fields outlets dispute, and the source URLs. Names appear only as published by an official statement or an on-the-ground or wire outlet (tier 1 or 2); names carried only by rewrites are withheld. Photos are not included here: use the kempton://victims/{slug}/photo resource.

named_only
Only victims whose name has been published.
disputed_only
Only victims where outlets disagree on at least one field.
suburb
Case-insensitive match on the suburb or location text, e.g. "Kempton Park".
from
Earliest date found, YYYY-MM-DD.
to
Latest date found, YYYY-MM-DD.
sort
date (default): by date found, undated last; n: by register number. [date, n]
cursor
Opaque cursor from a previous response's next_cursor. Omit for the first page.
limit
Items per page, default 50, maximum 200.
victims_get Everything published about one victim: the register row, the quoted sentence and source behind each key field... details

Everything published about one victim: the register row, the quoted sentence and source behind each key field (date found, location, name, condition, identification), the photo credit if an outlet published a photo under her name or the editor pinned one, the arrest items linked to her, and statements_mentioning: official statements whose quote or topic contains her published name (a text-match heuristic, not an editorial link). Identify her by slug (from victims_list) or by register number n.

slug
Her slug from victims_list, e.g. "busisiwe-mahlangu" or "victim-5".
n
Her register number, an alternative to slug.
statements_list What officials and named experts have said, one row per distinct statement with the verbatim quote, who said i... details

What officials and named experts have said, one row per distinct statement with the verbatim quote, who said it (name, role, agency), the date, the outlet and URL, the source tier (1 official, 2 on-the-ground or wire, 3 rewrite) and signal tags such as linkage_unconfirmed, arrest, reward, public_warning. Syndicated copies are folded into the first appearance. Newest first.

official
Case-insensitive match on the official's name, e.g. "Mthombeni".
agency
Case-insensitive match on the agency, e.g. "SAPS".
signal
Only statements tagged with this signal. [linkage_confirmed, linkage_unconfirmed, serial_possible, serial_ruled_out, multiple_perpetrators, arrest, charge, reward, public_warning, count_update, task_team, identification, cause_of_death, modus_operandi, other]
from
Earliest statement date, YYYY-MM-DD.
to
Latest statement date, YYYY-MM-DD.
q
Words that must all appear in the quote or topic.
cursor
Opaque cursor from a previous response's next_cursor. Omit for the first page.
limit
Items per page, default 50, maximum 200.
arrests_list Arrests, charges and court appearances as reported: suspects described (never named unless a court named them)... details

Arrests, charges and court appearances as reported: suspects described (never named unless a court named them), charges, court, next court date, latest status, which victim the item is linked to (body_n and her slug when published), and the source. Oldest first.

body_n
Only items linked to this victim's register number.
from
Earliest item date, YYYY-MM-DD.
to
Latest item date, YYYY-MM-DD.
cursor
Opaque cursor from a previous response's next_cursor. Omit for the first page.
limit
Items per page, default 50, maximum 200.
conflicts_list Where outlets disagree: every victim field (date found, suburb, name, age, nationality) with more than one pub... details

Where outlets disagree: every victim field (date found, suburb, name, age, nationality) with more than one published value, each value with the outlets that carry it. The pipeline resolves nothing here, with three mechanical exceptions: identification status takes the latest published value, nested place names are folded into one place ("Villa Liza, Dawn Park" and "Dawn Park"), and spelling variants of one name are folded. An editor may settle a field, in which case the register shows status "settled by editor". Use this before treating a disputed value as fact.

field
Only conflicts on this field, e.g. date_found, suburb, victim_name, victim_age, victim_nationality.
victim
Case-insensitive match on the victim's name or key.
counts_list How the published body count evolved: every explicit tally of victims in this case with its date, what exactly... details

How the published body count evolved: every explicit tally of victims in this case with its date, what exactly was being counted, who it was attributed to, and the source. Counts of arrests or national statistics are excluded. Oldest first.

from
Earliest date, YYYY-MM-DD.
to
Latest date, YYYY-MM-DD.
cursor
Opaque cursor from a previous response's next_cursor. Omit for the first page.
limit
Items per page, default 50, maximum 200.
sources_list The outlets behind the record and how many on-topic articles each contributed, with the trust tier used in con... details

The outlets behind the record and how many on-topic articles each contributed, with the trust tier used in confidence scoring: 1 = official (SAPS, gov.za), 2 = on-the-ground reporting or wire copy, 3 = rewrites, aggregators and any outlet not yet classified. Tiers are assigned per domain. Also explains how a value becomes "confirmed".

changelog_list What each data refresh added, newest first: new victims in the register, new statements, arrest items, conflic... details

What each data refresh added, newest first: new victims in the register, new statements, arrest items, conflicts and count changes, with the refresh timestamp. Use it to see what is new since a date. The bundle carries only the last 20 refreshes (a day or two at the two-hourly cadence), so a larger `days` cannot reach further back than that.

days
Only refreshes within the last N days (default 30). The bundle holds at most the last 20 refreshes.
cursor
Opaque cursor from a previous response's next_cursor. Omit for the first page.
limit
Items per page, default 50, maximum 200.
search Find anything on the record that mentions given words: victims (name, suburb, location, condition), official s... details

Find anything on the record that mentions given words: victims (name, suburb, location, condition), official statements (quote, topic, who), arrest items, conflicts and published counts. All words must occur. Each hit names its collection and a ref you can pass to the matching *_get or *_list tool, plus a snippet and source. Public content only; article texts are not searchable.

q*
Words to look for, e.g. "cable ties" or "Tembisa cemetery".
in
Restrict to these collections; default all.
limit
Maximum hits, default 25.

Resources

  • kempton://case

    Where the case stands: official tally, register counts, statements, arrests, conflicts, last refresh and recent changes. Same content as the case_overview tool.

  • kempton://methodology

    How the record is built and what it deliberately withholds: source tiers, the confidence rule, how outlets are reconciled, the guardrails on names and locations, retention, and how to pass information to the police instead. Read this before drawing conclusions from the data.

  • kempton://victims/{slug}

    One victim's full published record by slug: register row, quoted evidence per field, linked arrests and the statements that mention her name (a text-match heuristic). Same content as the victims_get tool.

  • kempton://victims/{slug}/photo

    A victim's photo as a small JPEG, only where an outlet published it under her name or the editor pinned one, credited as such; the credit is in victims_get under image_source. Absent for most victims. Only JPEG is ever served, so the declared mime type is always the real one.

  • kempton://bundle/public

    The whole public bundle in one document (about 500 KB): register, statements, arrests, counts, conflicts, changelog, outlets and map, as the website receives it, minus the inline photos (read kempton://victims/{slug}/photo for those). For scripts and one-shot analysis; the tools return the same data in pages. Because of its size this resource has its own limit of a few reads a minute per address.

Prompts

  • brief_the_case

    A status brief on the case for a given audience, built only from the record, with one source per claim and disputed values marked as disputed.

  • check_a_claim

    Check a claim about the case against the record and answer supported, disputed or not found, with the sources either way.

What the server will and will not tell you

  • Victims are named only as published by an official statement or an on-the-ground or wire outlet (tier 1 or 2); names carried only by rewrites are withheld. Locations are body-discovery sites, never homes: coordinates are suburb centroids; the location text is quoted as written, which may name a street or landmark.
  • Suspects are described, never named, unless a court named them. Officials have said linkage between the deaths is not confirmed; the record does not draw lines between them.
  • Where outlets disagree, every version is shown and none is picked for you. Read kempton://methodology first.
  • Reading the server stores nothing about you beyond a short-lived rate-limit counter keyed by a salted, day-scoped hash of your address.
  • The server cannot take tips yet. Use the tip page, or SAPS Crime Stop 08600 10111. If someone is in danger now, call 10111.