<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael</title>
    <description>The latest articles on DEV Community by Michael (@scraperslat).</description>
    <link>https://dev.to/scraperslat</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4060702%2Fe5e03df3-6536-4412-a769-83b2cfdb8118.webp</url>
      <title>DEV Community: Michael</title>
      <link>https://dev.to/scraperslat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/scraperslat"/>
    <language>en</language>
    <item>
      <title>I let an AI agent reconcile a drug's FDA label against its real-world reports. The mismatch was the point.</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:25:58 +0000</pubDate>
      <link>https://dev.to/scraperslat/i-let-an-ai-agent-reconcile-a-drugs-fda-label-against-its-real-world-reports-the-mismatch-was-the-35lj</link>
      <guid>https://dev.to/scraperslat/i-let-an-ai-agent-reconcile-a-drugs-fda-label-against-its-real-world-reports-the-mismatch-was-the-35lj</guid>
      <description>&lt;p&gt;This is a story about an experiment that went the right kind of wrong. Naomi, a pharmacovigilance analyst at a health-tech company, wanted to see whether an AI agent could do the least glamorous part of drug-safety work: take a medicine, pull what people actually report about it, pull what its official label already warns about, and lay the two side by side. Not to reach a verdict. To surface where they agree, where they diverge, and where a human needs to look harder.&lt;/p&gt;

&lt;p&gt;Everything below is a real setup with real output. Every report ID, reaction count, boxed warning, and run ID is a live lookup against FDA data, captured from an actual chat. Nothing is mocked. And because this touches drug safety, one rule is stated up front and never bent: FDA adverse-event reports are unverified and do not establish causation. This is research and triage, not medical advice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Naomi's job is signal triage. A drug comes across her desk and she needs two pictures of it, fast. The first is the field picture: the FDA Adverse Event Reporting System (FAERS), a public database of what patients, clinicians, and manufacturers have reported after someone took a drug. The second is the reference picture: the drug's approved FDA label, the manufacturer's own document of what the drug is for and what it warns against, including the boxed warning at the top.&lt;/p&gt;

&lt;p&gt;The hard part was never fetching either one. It was holding them in the same frame. A recurring reaction in the reports is only interesting if you know whether the label already flags it. A reaction the label features heavily is only reassuring if it actually shows up in the reports. Doing that by hand means two portals, two exports, and a spreadsheet where the columns never quite line up. It is exactly the mechanical work that gets skipped when a queue is deep.&lt;/p&gt;

&lt;p&gt;So Naomi wired both data sources directly into Claude as tools, using the &lt;strong&gt;official Apify MCP server&lt;/strong&gt;, and let the model do the fetching and the lining-up. Setup was one config block and a restart.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flp66x1ssgvxunmpp1o18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flp66x1ssgvxunmpp1o18.png" alt="The openFDA Drug Adverse Events &amp;amp; Recalls Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The two tools she connected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/openfda-drug-events-scraper" rel="noopener noreferrer"&gt;openFDA Drug Adverse Events &amp;amp; Recalls Scraper&lt;/a&gt; returns FAERS safety reports as structured records: the report ID, patient sex and age, the reactions, the seriousness flag and its reasons, and the full drug list, each drug marked &lt;strong&gt;suspect&lt;/strong&gt; or &lt;strong&gt;concomitant&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/openfda-drug-labels-scraper" rel="noopener noreferrer"&gt;openFDA Drug Labels &amp;amp; Ingredients Scraper&lt;/a&gt; returns the structured FDA label: boxed warning, contraindications, warnings and precautions, and the adverse reactions the manufacturer already lists.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both exposed to Claude through one MCP endpoint. Nothing else changed about how she works: she opens a chat and asks in plain English. The drug she picked to test the idea was metformin, the most-prescribed type 2 diabetes medicine in the country and a drug she knew well enough to catch the agent if it drifted.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the reports actually say
&lt;/h2&gt;

&lt;p&gt;She started with the field picture. Not "is metformin dangerous" (a question no honest tool should answer), but the concrete triage questions: how many reports are serious, which reactions recur, and, crucially, in how many is metformin the drug the reporter actually blamed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz23685vwdj00i6kw8o0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz23685vwdj00i6kw8o0e.png" alt="Claude pulling live FAERS reports for metformin and separating reactions from causation" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Claude called the FAERS tool, pulled forty live reports (run &lt;code&gt;LJtWYBdN8DahaKbWK&lt;/code&gt;), and came back with a picture that was more honest than a headline. Twenty-six of the forty were flagged serious. The recurring reactions were not the ones a layperson would guess: &lt;strong&gt;off-label use&lt;/strong&gt; appeared six times, &lt;strong&gt;maternal exposure during pregnancy&lt;/strong&gt; five, then fatigue, headache, and a cluster of gastrointestinal complaints and acute renal events.&lt;/p&gt;

&lt;p&gt;Then the part that made the exercise worth running. The agent flagged, on its own, that in nearly every one of those reports metformin was marked &lt;strong&gt;concomitant&lt;/strong&gt;, not &lt;strong&gt;suspect&lt;/strong&gt;. It was on the patient's medication list, but the reporter pointed at a different drug. In report 10004089, a hospitalized 46-year-old man with acute renal failure, the suspect was Ampyra. In a fatal report, 10004186, the suspect was Jakafi. In report 10005223, a physician's report of diarrhoea and abdominal pain, the suspect was Humira. Metformin was a bystander in all three.&lt;/p&gt;

&lt;p&gt;This is the distinction that a summary from memory flattens and a keyword search hides. A naive count of "reports mentioning metformin" would have inflated every one of these into a metformin signal. The structured &lt;code&gt;characterization&lt;/code&gt; field let the agent say the honest thing: the reactions are real in the data, but this batch does not pin them on the drug. Every claim carried a &lt;code&gt;safetyReportId&lt;/code&gt; you can open in the FAERS record.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the label warns about
&lt;/h2&gt;

&lt;p&gt;Next, the reference picture. Naomi asked the agent to pull metformin's official FDA label and tell her what it actually warns about.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnto7e3mnr8521h9f9sc1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnto7e3mnr8521h9f9sc1.png" alt="Claude fetching the official FDA label and reading out the boxed warning and common reactions" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One tool call later (run &lt;code&gt;S5ILrX5tSt5q5Dbks&lt;/code&gt;), the agent read back the prescription label, effective 2024-08-21. The headline is a &lt;strong&gt;boxed warning for lactic acidosis&lt;/strong&gt;, rare, potentially fatal, with a deliberately subtle onset: malaise, myalgia, abdominal pain, somnolence. Its named risk factors are renal impairment, age 65 and over, and contrast imaging. Below that, contraindications (severe renal impairment, hypersensitivity, metabolic acidosis), further warnings for vitamin B12 deficiency and hypoglycemia when combined with insulin, and the most common adverse reactions the manufacturer lists at over five percent: diarrhea, nausea and vomiting, flatulence, asthenia, indigestion, abdominal discomfort, and headache.&lt;/p&gt;

&lt;p&gt;That is the manufacturer's own reference, pulled live, not a paraphrase from training data that might be a label revision or two out of date.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reconciliation
&lt;/h2&gt;

&lt;p&gt;Then the payoff, and the reason the experiment was bolder than a single lookup. Naomi asked the agent to reconcile the two: for each reaction, did it show up in the FAERS pull, and does the label already flag it? And to say honestly where they diverge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fri1d64324rkjbs326gio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fri1d64324rkjbs326gio.png" alt="Claude reconciling the FAERS reports against the label into a single reaction-by-reaction table" width="800" height="892"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agent built the table from both runs and did not smooth over the seams. The middle of the table agrees cleanly: the diarrhoea, abdominal pain, nausea, headache, and fatigue in the reports are all reactions the label already lists as common. Reassuring, and exactly what you would hope to see: the field data and the reference document telling the same story about the routine stuff.&lt;/p&gt;

&lt;p&gt;The edges are where it earned its keep. &lt;strong&gt;Acute renal impairment&lt;/strong&gt; turned up in three reports; it is not a listed adverse reaction, but it is both a contraindication and the top risk factor for the boxed-warning event, so the agent marked it &lt;em&gt;partly&lt;/em&gt; on the label rather than forcing a yes or no. &lt;strong&gt;Off-label use&lt;/strong&gt; and &lt;strong&gt;pregnancy exposure&lt;/strong&gt;, the two most frequent signals in the pull, are not adverse reactions at all. The label treats them as prescribing context. And the single most important row: &lt;strong&gt;lactic acidosis, the label's headline boxed warning, did not appear once&lt;/strong&gt; in the forty-report sample.&lt;/p&gt;

&lt;p&gt;That last mismatch is the finding, and it cuts both ways honestly. The rarest, most serious risk the manufacturer leads with was invisible in a small recent sample, which is exactly what you would expect from a rare event, and exactly why you never read absence in FAERS as safety. Meanwhile the sample's loudest signals were things the label does not frame as reactions at all. Neither document is wrong. They are answering different questions, and the value of the agent was making that legible in one table instead of two disconnected exports.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is the honest version
&lt;/h2&gt;

&lt;p&gt;It would have been easy to build a flashier demo, an agent that "detects safety signals" or "audits a drug label." That agent would be a liability. The reason this one is worth showing is that it is bounded by what the data can actually support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It separates mention from cause.&lt;/strong&gt; The suspect-versus-concomitant read is baked into every answer, so a report is never silently upgraded into a signal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It refuses to over-read absence.&lt;/strong&gt; Zero lactic-acidosis reports in a small sample is reported as a fact about the sample, not a claim about the drug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It cites everything.&lt;/strong&gt; Every reaction points back to a &lt;code&gt;safetyReportId&lt;/code&gt;; every label claim to a run and an effective date. An analyst can open the source in one click.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It stays in its lane.&lt;/strong&gt; The output is triage over unverified reports to help a trained reviewer look in the right place. It is not a diagnosis, a verdict, or medical advice, and the agent says so.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Naomi's judgment never moved to the machine. What moved was the reconciliation grind: the two portals, the mismatched columns, the reaction she would have had to manually check against the label one at a time. The agent did the lining-up in under a minute and handed her a table she could defend line by line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the same agent
&lt;/h2&gt;

&lt;p&gt;Everything here is reproducible today with a free Apify account and any MCP-capable client (Claude Desktop, Cursor, or your own agent):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your Apify API token from the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt; under &lt;strong&gt;Settings → Integrations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the official Apify MCP server to your client and list both Actors in the &lt;code&gt;tools&lt;/code&gt; parameter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/openfda-drug-events-scraper,scrapers_lat/openfda-drug-labels-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the client and ask it, in plain English, to pull the FAERS reports and the label for a drug and reconcile them. It picks the right tool for each step.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; each tool call is a real Actor run billed to your Apify account (both are pay-per-result, a fraction of a cent per lookup). For continuous monitoring across many drugs, run the Actors on a schedule through the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API&lt;/a&gt; instead of one call per chat.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;A word on interpretation:&lt;/strong&gt; FAERS is a spontaneous-reporting system. A report means someone submitted it, not that the drug caused the event; many reports come from consumers, the same case can list a dozen drugs, and duplicates exist. Absence of a reaction in a sample is not evidence of safety, and presence is not evidence of harm. The agent's job here is fast, auditable access to the raw reports and the label so a qualified reviewer can do the interpreting. Keep that framing and the tool earns its place. This is not medical advice.&lt;/p&gt;

&lt;p&gt;The Actors used in this story: &lt;a href="https://apify.com/scrapers_lat/openfda-drug-events-scraper" rel="noopener noreferrer"&gt;openFDA Drug Adverse Events &amp;amp; Recalls Scraper&lt;/a&gt; and &lt;a href="https://apify.com/scrapers_lat/openfda-drug-labels-scraper" rel="noopener noreferrer"&gt;openFDA Drug Labels &amp;amp; Ingredients Scraper&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>healthcare</category>
    </item>
    <item>
      <title>Is this flat overpriced? I let Claude check the asking price against what actually sold.</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:25:12 +0000</pubDate>
      <link>https://dev.to/scraperslat/is-this-flat-overpriced-i-let-claude-check-the-asking-price-against-what-actually-sold-11gf</link>
      <guid>https://dev.to/scraperslat/is-this-flat-overpriced-i-let-claude-check-the-asking-price-against-what-actually-sold-11gf</guid>
      <description>&lt;p&gt;Every property listing is a number with a story attached. "Renovated." "Huge." "Near the MRT." "Priced to sell." The one thing the story never tells you is whether the number is fair, because the only honest answer to that lives somewhere the seller has no incentive to show you: the record of what flats exactly like this one have &lt;em&gt;actually&lt;/em&gt; changed hands for.&lt;/p&gt;

&lt;p&gt;So I ran an experiment. I gave Claude two live data sources through the official Apify MCP server, pointed it at a real HDB flat on the market in Singapore, and asked it to do the one thing a buyer never has time to do properly at a viewing: compare the asking price against genuine recent transactions for the same segment, and tell me the truth. Not a mortgage calculator. Not a vibe. A verdict backed by numbers.&lt;/p&gt;

&lt;p&gt;Everything below is real. A live listing pulled from the market, six hundred real resale transactions, actual run IDs. No mocked screens, no invented comps. I picked the flat, wired the tools, and let the agent make the call.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Here is the problem with buying a resale flat. You stand in someone's living room for fifteen minutes. The agent is friendly, the place smells like fresh paint, and there is a number on the table. Is it fair? You genuinely do not know. You have a gut feeling shaped by whatever three listings you half-remember from scrolling last night, and the agent has every transacted comparable in the district memorised. It is not a fair fight.&lt;/p&gt;

&lt;p&gt;The data to level it exists and is public. Singapore's HDB publishes every resale transaction: town, flat type, block, floor area, lease year, storey, and the exact price it sold for. The problem was never access. The problem is that nobody, in the pressure of a viewing, opens a spreadsheet of six hundred sales, filters it down to the flats that genuinely match the one in front of them, and works out a median. So I wired that work into Claude and let it do the fetching and the maths.&lt;/p&gt;

&lt;p&gt;The two tools I connected, both through one &lt;strong&gt;official Apify MCP&lt;/strong&gt; endpoint:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjaxjj1hiuq26fhuy8rw4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjaxjj1hiuq26fhuy8rw4.png" alt="The Singapore HDB Resale Flat Prices Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/singapore-hdb-resale-prices-scraper" rel="noopener noreferrer"&gt;Singapore HDB Resale Flat Prices Scraper&lt;/a&gt; returns real transacted resale prices for any town and flat type: block, street, storey, floor area, remaining lease, resale price, and price per square foot.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/singapore-propertyguru-scraper" rel="noopener noreferrer"&gt;Singapore PropertyGuru Listings Scraper&lt;/a&gt; returns live asking listings: title, asking price, floor area, price per square foot, property type, and location.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One is the market's &lt;em&gt;asking&lt;/em&gt;. The other is the market's &lt;em&gt;reality&lt;/em&gt;. The whole experiment is putting them side by side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step one: pull the live listing
&lt;/h2&gt;

&lt;p&gt;I did not want to argue with a screenshot, so the first thing I asked Claude to do was fetch the flat's real, current listing figures straight from the market rather than trust my typing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffbcvx0ys390o7sqwhk7e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffbcvx0ys390o7sqwhk7e.png" alt="Claude pulling the live Tampines HDB listing through the Apify MCP server" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two seconds of tool call, and the flat was on the table with its numbers locked: a 4-room HDB in Tampines, near Tampines East MRT, &lt;strong&gt;asking S$620,000&lt;/strong&gt; for &lt;strong&gt;1,087 sqft&lt;/strong&gt;, a headline &lt;strong&gt;S$570.38 per square foot&lt;/strong&gt;. That last figure is the one that matters, because price alone tells you nothing when floor areas differ. Price per square foot is how you compare a 1,087 sqft flat to one that is 1,000 or 1,200.&lt;/p&gt;

&lt;p&gt;And here is where the trap opens. S$570 psf, for Tampines, &lt;em&gt;sounds&lt;/em&gt; cheap. If your mental benchmark is "4-room flats in mature towns go for six-something a foot," this looks like a flat priced under the market, the kind of listing you rush to view before someone else grabs it. Claude flagged exactly that instinct and refused to trust it: "cheap only means something against what flats like this one actually sold for." Then it offered to go and find out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step two: compare it to what actually sold
&lt;/h2&gt;

&lt;p&gt;This is the part I could never do at a viewing, and the part the agent does in one tool call. I told it to pull the recent transacted resale prices for the same segment and give me a straight answer: fair, or overpaying?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0bhwea2gtt0sijjj0r96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0bhwea2gtt0sijjj0r96.png" alt="Claude comparing the asking price against 600 real transactions and returning an evidence-based verdict" width="800" height="963"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It pulled &lt;strong&gt;600 real Tampines 4-room transactions&lt;/strong&gt; spanning January 2025 to July 2026, and then it did the thing that separates an analyst from a calculator: it noticed the naive comparison was a trap and controlled for it.&lt;/p&gt;

&lt;p&gt;Against &lt;em&gt;every&lt;/em&gt; 4-room flat in Tampines, the median was &lt;strong&gt;S$608.63 psf&lt;/strong&gt;. Measured that way, the listing's S$570 looked like a 6% discount, confirmation that this was a steal. But most of those 600 sales are newer flats with 90-plus years left on the lease, and lease age is the single biggest lever on an HDB flat's price per foot. The flat I was looking at is a &lt;strong&gt;1980s-vintage, ~1,087 sqft&lt;/strong&gt; unit, an older, larger Model A. Comparing it to a decade-newer flat is not a comparison at all.&lt;/p&gt;

&lt;p&gt;So Claude filtered to the genuine like-for-like set: same size band, same lease era. &lt;strong&gt;218 real sales&lt;/strong&gt; of 1,000 to 1,200 sqft, 1980s-lease 4-room flats in Tampines. The median for &lt;em&gt;that&lt;/em&gt; group (the flats that actually resemble the one on offer) is &lt;strong&gt;S$566.36 psf&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And the whole picture flips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Against all 4-room flats: &lt;strong&gt;−6.3%&lt;/strong&gt;, a bargain.&lt;/li&gt;
&lt;li&gt;Against its true comparables: &lt;strong&gt;+0.7%&lt;/strong&gt;, dead-on market.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The "discount" was never a discount. It was the older-lease haircut that every flat of this vintage carries. Priced against its actual peers, S$570 psf is the market clearing price, not a gift.&lt;/p&gt;

&lt;p&gt;Claude backed the verdict with the receipts, three near-identical flats in the same cluster of blocks that sold in July 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;886 Tampines St 83&lt;/strong&gt; (1988 lease, 1,119 sqft) → S$635,888 at S$568 psf&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;852 Tampines St 82&lt;/strong&gt; (1985 lease, 1,119 sqft) → S$650,000 at S$581 psf&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;418 Tampines St 41&lt;/strong&gt; (1985 lease, 1,130 sqft) → S$620,000 at S$549 psf&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same size, same era, same town, sold within the last month. The asking flat sits right in that band, near the top of it. At the median psf of its true comps, the flat is worth about &lt;strong&gt;S$615,600&lt;/strong&gt;, so the S$620k ask is roughly &lt;strong&gt;S$4,000 over fair value&lt;/strong&gt;, sitting at the top of the recent range rather than the middle.&lt;/p&gt;

&lt;h2&gt;
  
  
  The verdict, and what it's worth
&lt;/h2&gt;

&lt;p&gt;The honest answer was not the exciting one. The flat is &lt;strong&gt;not&lt;/strong&gt; the underpriced steal the headline psf implies, and it is &lt;strong&gt;not&lt;/strong&gt; overpriced either. It is priced about right, arguably S$4k rich, sitting at the ceiling of what its true comparables have fetched. That is genuinely useful, because it changes how you walk into the room. You are not chasing a bargain that will vanish, and you are not being fleeced. You have a specific, defensible number (around &lt;strong&gt;S$610,000&lt;/strong&gt;) and three real recent sales to point at if you want to negotiate toward it.&lt;/p&gt;

&lt;p&gt;That is the whole shift. A viewing usually runs on the seller's information and your gut. Here the buyer walks in with the same transacted data the agent has, distilled to a one-line verdict and a table of comps, in the time it takes to read a chat reply.&lt;/p&gt;

&lt;p&gt;I want to be precise about what this is and is not. It is a &lt;strong&gt;data-driven estimate from live transactions, not a formal valuation.&lt;/strong&gt; Price per square foot captures size and lease and town, but it cannot see the things that move the last few thousand dollars: which storey the unit is on, which way it faces, whether the renovation is genuinely done or lipstick, how motivated the seller is. A bank valuer weighs those. What the agent gives you is the evidence base those judgments should sit on top of, the difference between "I think it feels a bit high" and "it's 0.7% above the median of 218 real comparable sales, here are the closest three." One of those sentences wins a negotiation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the same agent
&lt;/h2&gt;

&lt;p&gt;Everything above is reproducible today with a free Apify account and any MCP-capable client (Claude Desktop, Cursor, or your own agent).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffzylfl6xmw1egoolu2zw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffzylfl6xmw1egoolu2zw.png" alt="The Singapore PropertyGuru Listings Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your Apify API token from the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt; under &lt;strong&gt;Settings → Integrations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the official Apify MCP server to your client and list both Actors in the &lt;code&gt;tools&lt;/code&gt; parameter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/singapore-hdb-resale-prices-scraper,scrapers_lat/singapore-propertyguru-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the client, then hand it a listing in plain English: paste the asking price, floor area, town and flat type, and ask whether it is fair against recent transactions. The agent picks the listing tool to confirm the asking figures, then the resale tool to fetch the comps, and does the maths.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 &lt;strong&gt;The key instruction is "compare like for like."&lt;/strong&gt; The single most valuable thing the agent did was refuse the all-flats median and filter to the same size and lease era. Tell it explicitly to match floor area and lease year, or it may hand you the flattering 6% "discount" instead of the real 0.7%. The data is only as honest as the segment you compare against.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;Extend it.&lt;/strong&gt; The same pattern scales to any town or flat type: query &lt;code&gt;town: "BEDOK"&lt;/code&gt; and &lt;code&gt;flatType: "5 ROOM"&lt;/code&gt;, or point it at a whole shortlist and ask for the one priced furthest below its comps. Add the &lt;a href="https://apify.com/scrapers_lat/singapore-propertyguru-scraper" rel="noopener noreferrer"&gt;Singapore Property Guru rental&lt;/a&gt; angle to check rental yield, or the broader &lt;a href="https://apify.com/scrapers_lat" rel="noopener noreferrer"&gt;Singapore data set of registry and market Actors&lt;/a&gt; to layer in more context. Every extra tool is one more line in the &lt;code&gt;tools&lt;/code&gt; list and zero new code.&lt;/p&gt;

&lt;p&gt;The Actors used in this experiment: &lt;a href="https://apify.com/scrapers_lat/singapore-hdb-resale-prices-scraper" rel="noopener noreferrer"&gt;Singapore HDB Resale Flat Prices Scraper&lt;/a&gt; and &lt;a href="https://apify.com/scrapers_lat/singapore-propertyguru-scraper" rel="noopener noreferrer"&gt;Singapore PropertyGuru Listings Scraper&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>api</category>
    </item>
    <item>
      <title>Paste the VIN. The agent reads a used car's secrets back to you in plain English.</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:20:18 +0000</pubDate>
      <link>https://dev.to/scraperslat/paste-the-vin-the-agent-reads-a-used-cars-secrets-back-to-you-in-plain-english-4fdf</link>
      <guid>https://dev.to/scraperslat/paste-the-vin-the-agent-reads-a-used-cars-secrets-back-to-you-in-plain-english-4fdf</guid>
      <description>&lt;p&gt;Buying a used car is one of the biggest checks most people write without a second opinion. The seller knows more than you do. The listing is written to sell. And the two databases that would actually tell you the truth about the car sitting in the driveway are public, free, and completely unreadable to a normal human being.&lt;/p&gt;

&lt;p&gt;This is a story about closing that gap with one sentence: &lt;em&gt;"Here's the VIN."&lt;/em&gt; No mocked screens, no toy data. Every specification and recall campaign below is a real lookup against live U.S. government records, captured from an actual chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with buying used
&lt;/h2&gt;

&lt;p&gt;Marcus is a first-time EV buyer. He found a 2018 Tesla Model 3 on a marketplace, priced a little under the others, and he has exactly one advantage the seller doesn't expect him to use: the seller texted him the VIN.&lt;/p&gt;

&lt;p&gt;A VIN is the car's fingerprint. Two U.S. government databases can turn those seventeen characters into the truth about the vehicle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The NHTSA vPIC database&lt;/strong&gt; decodes the VIN into the real make, model, year, trim, drivetrain and factory-installed safety equipment. It settles what the car actually &lt;em&gt;is&lt;/em&gt;, regardless of what the listing claims.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The NHTSA recalls database&lt;/strong&gt; lists every open safety recall for that make, model and year, including the ones that never got fixed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both are free. Both are also built for engineers and insurers, not for a nervous buyer standing in someone's driveway on a Saturday. The data exists; the plain-English answer doesn't.&lt;/p&gt;

&lt;p&gt;So instead of learning to read government JSON, Marcus did the thing anyone with a Claude account can do in twenty minutes: he wired both databases into Claude as tools using the &lt;strong&gt;official Apify MCP server&lt;/strong&gt;, and then just talked to it like a knowledgeable friend.&lt;/p&gt;

&lt;p&gt;The first tool he connected:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdjtk4b14see6mdjmlhfn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdjtk4b14see6mdjmlhfn.png" alt="The NHTSA VIN Decoder &amp;amp; Vehicle Specs Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/nhtsa-vin-decoder-scraper" rel="noopener noreferrer"&gt;NHTSA VIN Decoder &amp;amp; Vehicle Specs Scraper&lt;/a&gt; turns a VIN into the full factory spec sheet.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/nhtsa-recalls-scraper" rel="noopener noreferrer"&gt;NHTSA Recalls Scraper&lt;/a&gt; returns every recall campaign on record for a given make, model and year, with the safety consequence and the fix.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two public databases, one chat window. Nothing to install on the car, no subscription, no salesperson. Marcus opens Claude and types the way he'd text a friend who happens to know cars.&lt;/p&gt;

&lt;h2&gt;
  
  
  "What is it, in plain English?"
&lt;/h2&gt;

&lt;p&gt;He starts with the only fact he has. He pastes the VIN and asks what the car actually is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuvj9706xbnbe8f6aogxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuvj9706xbnbe8f6aogxy.png" alt="The buyer pastes a VIN and Claude decodes it warmly in plain English" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agent doesn't lecture. It runs the decode, then translates seventeen characters into a picture a human can hold: a &lt;strong&gt;2018 Tesla Model 3&lt;/strong&gt;, a single-motor Standard Range electric sedan, built in Fremont, California, that stickered around &lt;strong&gt;$46,000&lt;/strong&gt; new. It reads back the safety equipment that came standard on the car (automatic emergency braking, blind-spot monitoring, lane-keep assist, a backup camera, stability control) and notes, plainly, that this is a strong set for the model year.&lt;/p&gt;

&lt;p&gt;Then it does the thing a good second opinion does: it flags something small but real. The VIN's built-in check digit doesn't validate cleanly. The agent doesn't dress it up as fraud. It explains that this is common for early-production and sample VINs, and gives Marcus one concrete action: confirm the VIN on the door-jamb sticker and the title &lt;em&gt;exactly&lt;/em&gt; matches the one the seller texted. That is the difference between a data dump and advice.&lt;/p&gt;

&lt;p&gt;Every field in that answer came from a real Actor run (&lt;code&gt;2AbJcEVY9gWPpHAeD&lt;/code&gt;), not from the model's memory of what a Model 3 usually is. If the seller had quietly listed a base car as a Long Range, or fudged the year, the decode would have contradicted the listing on the spot.&lt;/p&gt;

&lt;p&gt;Marcus didn't have to know that the vPIC database exists, or what "electrification level" means. He asked a question in English and got an answer in English. But identity is only half of a safe purchase. The agent knows that, and offers the second half itself: &lt;em&gt;want me to check whether this car has any open safety recalls?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  "Are there recalls, and what do I say to the seller?"
&lt;/h2&gt;

&lt;p&gt;This is the question that actually protects Marcus's money and, more to the point, his safety. He says yes, and asks the thing every buyer is too polite or too unsure to ask: what does he actually &lt;em&gt;say&lt;/em&gt; to the seller?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmlowjpum1k24y2xf3u3z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmlowjpum1k24y2xf3u3z.png" alt="Claude surfaces the open recalls and hands the buyer a concrete script to send the seller" width="800" height="891"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agent runs the recalls lookup (&lt;code&gt;7YfhB7mRkYSTgqQ4x&lt;/code&gt;) and comes back with a number that would scare anyone off cold: &lt;strong&gt;18 recall campaigns on record.&lt;/strong&gt; And here is where the agent stops being a search box and starts being a second opinion. It doesn't dump eighteen scary paragraphs. It &lt;em&gt;reasons about the data on Marcus's behalf&lt;/em&gt; and sorts it into what matters and what doesn't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;14 of the 18 were fixed over the air&lt;/strong&gt;: software updates the car downloads on its own. If the car has been online, they're already done. Nothing to chase.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4 need a physical shop repair.&lt;/strong&gt; These do not fix themselves, and these are the only ones Marcus has to care about.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it names the four in plain terms, leading with the scary one: a &lt;strong&gt;front suspension&lt;/strong&gt; recall (campaign 23V235000) where a lateral link fastener can loosen and let the suspension separate from the frame. It is safety-critical, and specific to 2018-2019 Model 3s. Plus a &lt;strong&gt;front seat-belt&lt;/strong&gt; fastener recall (21V389000), a &lt;strong&gt;rear seat-belt anchor&lt;/strong&gt; recall (22V798000), and a &lt;strong&gt;rearview camera&lt;/strong&gt; cable recall (21V00D000). All four repaired free at any Tesla service center.&lt;/p&gt;

&lt;p&gt;And then the payoff, the part no database gives you. The agent writes the exact message to send the seller:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Hi, before I come see the car, can you send me the service records showing recalls &lt;strong&gt;23V235000&lt;/strong&gt; (front suspension) and &lt;strong&gt;21V389000&lt;/strong&gt; (front seat belt) were completed? If you're not sure, I can look up the VIN's recall status together, or we can swing by a Tesla service center. Just want to make sure the safety recalls are closed out."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the whole product. A used-car buyer with no mechanical knowledge now has a specific, polite, informed ask (with campaign numbers in it) that turns "I guess it's fine" into leverage. As the agent points out: if the seller can't prove those two repairs were done, that's not a dealbreaker, it's a discount. The fixes are free. What Marcus can't afford is to drive off not knowing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cheat sheet in his pocket
&lt;/h2&gt;

&lt;p&gt;Before he leaves for the viewing, Marcus asks for one thing he can keep on his phone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feob7wkwtktwcnf4r4y4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feob7wkwtktwcnf4r4y4f.png" alt="Claude consolidates everything into a one-glance dossier the buyer can keep on their phone" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agent consolidates both lookups into a single dossier: what it checked, what the official record says, and what Marcus should do about each line. Identity confirmed. Safety features solid for the year. Fourteen recalls already handled by software. Four that need proof of repair. One VIN check-digit to verify against the door jamb. Two databases, one glance, every row traceable to a real government record rather than anyone's opinion.&lt;/p&gt;

&lt;p&gt;The bottom line the agent gives him is the one a trusted friend would: the car is what the seller says it is, the safety kit is good, and the only real homework is the suspension and seat-belt recalls. Do that, and he's buying with his eyes open.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters beyond one buyer
&lt;/h2&gt;

&lt;p&gt;Marcus is the obvious audience, but he's not the only one. The interesting reader here is the &lt;strong&gt;marketplace or insurer&lt;/strong&gt; who could embed this exact agent.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A used-car marketplace could put a "paste the VIN" box on every listing and hand every buyer this second opinion automatically, closing the information gap that makes people distrust private-party sales in the first place.&lt;/li&gt;
&lt;li&gt;An insurer or a warranty provider could screen a VIN for open safety recalls at quote time, in plain language, without building a data pipeline against two government sources.&lt;/li&gt;
&lt;li&gt;A neighborhood mechanic could run it on a customer's behalf and print the dossier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point of the experiment isn't that the data was hard to get. It's public. It's that the &lt;em&gt;judgment layer&lt;/em&gt; on top of the data used to require a human who knew cars, knew which recalls fix themselves, and knew what to say to a seller. That layer is now a conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the same agent
&lt;/h2&gt;

&lt;p&gt;Everything above is reproducible today with a free Apify account and any MCP-capable client (Claude Desktop, Cursor, or your own app):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your Apify API token from the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt; under &lt;strong&gt;Settings → Integrations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the official Apify MCP server to your client and list both Actors in the &lt;code&gt;tools&lt;/code&gt; parameter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/nhtsa-vin-decoder-scraper,scrapers_lat/nhtsa-recalls-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the client, paste a VIN, and ask it, in plain English, to decode the car and check for recalls. It will pick the right tool for each step and reason across both.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; each tool call is a real Actor run billed to your Apify account (both are pay-per-result, a fraction of a cent per lookup). To offer this at scale on a marketplace, call the Actors through the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API&lt;/a&gt; behind your own "paste the VIN" box instead of one call per chat.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;Extend it:&lt;/strong&gt; the same pattern grows into a full pre-purchase agent. Add a used-car listings source to compare the asking price against the market, or a title and odometer source, and the agent goes from "what is this car" to "should you buy this car, at this price", all over live data, by adding one more Actor to the &lt;code&gt;tools&lt;/code&gt; list, with no new code.&lt;/p&gt;

&lt;p&gt;The Actors used in this story: &lt;a href="https://apify.com/scrapers_lat/nhtsa-vin-decoder-scraper" rel="noopener noreferrer"&gt;NHTSA VIN Decoder &amp;amp; Vehicle Specs Scraper&lt;/a&gt; and &lt;a href="https://apify.com/scrapers_lat/nhtsa-recalls-scraper" rel="noopener noreferrer"&gt;NHTSA Recalls Scraper&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>api</category>
    </item>
    <item>
      <title>I asked an AI agent whether NVIDIA insiders were selling. It read the filings and found one director.</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:19:31 +0000</pubDate>
      <link>https://dev.to/scraperslat/i-asked-an-ai-agent-whether-nvidia-insiders-were-selling-it-read-the-filings-and-found-one-4lp8</link>
      <guid>https://dev.to/scraperslat/i-asked-an-ai-agent-whether-nvidia-insiders-were-selling-it-read-the-filings-and-found-one-4lp8</guid>
      <description>&lt;p&gt;I run a small event-driven book, and the question I get asked most on any big name is also the one that's hardest to answer honestly: &lt;em&gt;are the insiders selling?&lt;/em&gt; Not "is there a scary headline about insider sales," but the real thing. Who sold, how much, was it a decision or a formality, and does it actually mean anything.&lt;/p&gt;

&lt;p&gt;If you ask a language model that question cold, you get a fluent paragraph that is worse than useless: confidently phrased, months out of date, and occasionally invented. Insider transactions are a matter of public record, filed on SEC Form 4 within two business days of the trade. There is a right answer sitting in the filings. So this time I didn't ask Claude to &lt;em&gt;know&lt;/em&gt; the answer. I gave it the filings and asked it to &lt;em&gt;read&lt;/em&gt; them for me.&lt;/p&gt;

&lt;p&gt;What follows is a real session. Every number below came out of live SEC data during the chat, through the &lt;strong&gt;official Apify MCP server&lt;/strong&gt;. No mocked screens, no cherry-picked record. The interesting part is not that the agent fetched some data. It's what it did with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one thing I wired up beforehand
&lt;/h2&gt;

&lt;p&gt;The setup is embarrassingly small. Apify's Store has an Actor that reads SEC Form 4 filings and returns each insider transaction as a clean, structured record. I connected it to Claude as a tool through the official Apify MCP server, which turns any Apify Actor into something the model can call mid-conversation. One line of config, one restart. After that, Claude can pull insider filings on its own whenever a question needs them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbu555phbi6fwcoae2e51.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbu555phbi6fwcoae2e51.png" alt="The SEC Form 4 Insider Trading Transactions Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Actor is the &lt;a href="https://apify.com/scrapers_lat/sec-form4-insider-trades-scraper" rel="noopener noreferrer"&gt;SEC Form 4 Insider Trading Transactions Scraper&lt;/a&gt;. Give it a ticker and it returns, per transaction: the insider's name and role, the transaction code and type (open-market buy, open-market sale, grant, gift, tax withholding), the number of shares, the price, the total value, how much of the insider's stake it moved, and whether it ran under a Rule 10b5-1 plan. That last field is the one that separates a real signal from noise, and I'll come back to it. The point is that the agent doesn't get a headline. It gets the same fields a filing does, and it has to reason over them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Asking the real question
&lt;/h2&gt;

&lt;p&gt;So I asked it the real question, the way I'd ask a junior analyst: don't guess, pull the filings, and tell me what's genuine trading versus routine noise.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo9gk09pjuytmbji31fha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo9gk09pjuytmbji31fha.png" alt="Claude pulling NVIDIA's Form 4 filings and separating real open-market sales from grants, gifts and tax withholding" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first thing it did was the thing most people skip. It pulled 40 real transactions and, before saying anything about a "signal," sorted them by transaction code. This matters more than it sounds. A Form 4 marked as a "disposal" is very often not someone choosing to sell:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;11 were code A&lt;/strong&gt;: stock grants to the board and officers, zero cash. Not selling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8 were code F&lt;/strong&gt;: shares handed back to cover taxes when awards vested, all on the same day, including CEO Jensen Huang and CFO Colette Kress. This is payroll mechanics, not a market call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 were code G&lt;/strong&gt;: gifts, including a 400,000-share gift by the CEO. A transfer, not a sale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;18 were code S&lt;/strong&gt;: actual open-market sales. This is the only bucket that carries information.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An analyst who reads "insider disposed of shares" across all 40 of those and panics has misread the filing. The agent didn't. It said, in effect: strip the housekeeping, and the honest headline isn't "insiders are dumping," it's that there are eighteen genuine sales worth looking at, and they look concentrated. Then it offered to go deeper. That framing (noise first, signal second) is exactly what I want and rarely get from an automated tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making it characterize the pattern
&lt;/h2&gt;

&lt;p&gt;A count of sales is still not an answer. Eighteen sales could be the whole C-suite trimming a little, or one person doing something unusual. Those mean opposite things. So I asked it to roll the open-market selling up by person, and to tell me for each whether the sale was discretionary or ran on a pre-set Rule 10b5-1 plan.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4jj0ewrqec8jq5nyq13i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4jj0ewrqec8jq5nyq13i.png" alt="Claude rolling up the open-market sellers into a table by person, role, size and 10b5-1 plan status" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the shot that changed my read of the name. Rolled up by person, five insiders sold on the open market since January, but the values are wildly lopsided: Mark A. Stevens at roughly &lt;strong&gt;$445.6M&lt;/strong&gt; across 2,106,682 shares, then a steep drop to Aarti S. Shah at $3.36M, Stephen C. Neal at $3.34M, Donald F. Robertson Jr at $0.94M, and John Dabiri at $0.13M. Next to each name, the agent put the field that actually carries the signal: was the sale discretionary, or run on a pre-scheduled Rule 10b5-1 plan.&lt;/p&gt;

&lt;p&gt;The characterization the agent gave was sharper than "insiders sold $460M of stock," which is the kind of line that ends up in a scary headline. It said: this is not a broad insider exodus. It is essentially &lt;strong&gt;one director&lt;/strong&gt;. Mark A. Stevens accounts for about &lt;strong&gt;99%&lt;/strong&gt; of the open-market sale dollars, seven trades, all &lt;strong&gt;off-plan&lt;/strong&gt; (discretionary, not on a 10b5-1 schedule), clustered in two waves: a bit in late March, then a heavy June (500,000 shares on the 2nd, another 500,000 on the 4th, 885,000 on the 18th). One June block alone trimmed 6.76% of his own position. Everyone else who sold was small, and three of the four sold under pre-scheduled 10b5-1 plans, which carry little signal by construction. The CEO and CFO you might expect to see selling into a high? Not one open-market sale between them. They appear only for tax withholding.&lt;/p&gt;

&lt;p&gt;That is a genuinely different story than the aggregate number tells. "The board is bailing" would be wrong. "One director has been selling large, discretionary blocks" is right, and it's specific enough to actually do something with, like read his filing history, or check whether it's a known diversification pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context, and being honest about the limits
&lt;/h2&gt;

&lt;p&gt;The last thing I did was the part that keeps this from turning into a conspiracy board. I asked whether any of the selling lined up with company disclosures, and (explicitly) to be blunt about what this signal does and doesn't tell me. Because the same MCP connection can expose more than one Actor, the agent reached for a second tool without being told which one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F32jme77gfu3mtq1jrjv9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F32jme77gfu3mtq1jrjv9.png" alt="Claude chaining the EDGAR filings tool for context and then stating plainly what the signal is not: not investment advice and not a claim of wrongdoing" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It pulled NVIDIA's recent 8-Ks and noted one honest timing coincidence: Stevens' largest single-day selling, roughly $186M across two blocks on 2026-06-18, fell on the same day the company filed an 8-K (Item 8.01, Other Events). It flagged the date and immediately declined to draw a line through it. Then it said the thing I most needed it to say, unprompted:&lt;/p&gt;

&lt;p&gt;This is a faster way to read the public record. It is &lt;strong&gt;not&lt;/strong&gt; investment advice, and it is &lt;strong&gt;not&lt;/strong&gt; a claim that anyone did anything wrong. Off-plan open-market sales by a director are legal and ordinary: people sell for taxes, diversification, estate planning, a new house, and a hundred reasons that have nothing to do with a view on the stock. "Discretionary versus 10b5-1" is a factual box on the filing, not an accusation. A sale that happens to land on an 8-K date is a coincidence worth a footnote, not evidence of anything. Do your own diligence.&lt;/p&gt;

&lt;p&gt;I want to be equally blunt in print: nothing here is a recommendation, and nothing here implies illegality. The value of the exercise is not a verdict. It's that a task that used to mean opening EDGAR, pulling every Form 4, decoding transaction codes by hand, and rolling them up in a spreadsheet became a three-message conversation, with the noise stripped, the outlier named, and the caveats stated out loud.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the agent actually did
&lt;/h2&gt;

&lt;p&gt;Strip the theatrics and the useful pattern is this: the agent didn't fetch a fact, it &lt;em&gt;reasoned over a filing set&lt;/em&gt;. Three moves, in order, that I'd want from a human:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It separated signal from noise before interpreting.&lt;/strong&gt; Grants, gifts, and tax withholding got sorted out first, so an $8-figure "disposal" that was really a payroll tax event never got mistaken for a bearish sale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It characterized rather than aggregated.&lt;/strong&gt; "One director is 99% of the selling, all discretionary" is an insight. "$460M of insider sales" is a number that misleads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It stated its own limits.&lt;/strong&gt; It named a timing coincidence and then refused to make it mean something, and it labeled the whole output as public-record summarization, not advice.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of my judgment moved to the machine. I still decide whether Stevens' selling matters for the thesis. What moved was the mechanical, error-prone middle (the fetching and decoding and de-noising), which is exactly the part a person under time pressure gets wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the same agent
&lt;/h2&gt;

&lt;p&gt;You can reproduce this today with a free Apify account and any MCP-capable client (Claude Desktop, Cursor, or your own agent):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your Apify API token from the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt; under &lt;strong&gt;Settings → Integrations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the official Apify MCP server and list the Actors you want in the &lt;code&gt;tools&lt;/code&gt; parameter. For the insider-activity agent above, that's the Form 4 Actor plus the EDGAR filings Actor for context:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/sec-form4-insider-trades-scraper,scrapers_lat/sec-edgar-filings-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the client and ask it, in plain English, whether a company's insiders have been buying or selling, and to separate real open-market trades from grants and tax withholding. It will pick the right tool, pull the filings, and characterize the pattern.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; each tool call is a real Actor run billed to your Apify account (this one is pay-per-result, a fraction of a cent per lookup). To watch a whole basket of tickers continuously, run the Actor on a schedule through the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API&lt;/a&gt; instead of one call per chat.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;Extend it:&lt;/strong&gt; widen the window with &lt;code&gt;dateFrom&lt;/code&gt; on a name with heavier activity, or pin the agent to one behaviour by passing &lt;code&gt;transactionCode&lt;/code&gt; (&lt;code&gt;P&lt;/code&gt; for open-market buys, &lt;code&gt;S&lt;/code&gt; for open-market sales) so it never sees the housekeeping in the first place. Add more Actors to the &lt;code&gt;tools&lt;/code&gt; list and the same agent covers more of the disclosure surface without a line of new code.&lt;/p&gt;

&lt;p&gt;The Actors used in this piece: &lt;a href="https://apify.com/scrapers_lat/sec-form4-insider-trades-scraper" rel="noopener noreferrer"&gt;SEC Form 4 Insider Trading Transactions Scraper&lt;/a&gt; and &lt;a href="https://apify.com/scrapers_lat/sec-edgar-filings-scraper" rel="noopener noreferrer"&gt;SEC EDGAR Filings Scraper&lt;/a&gt;. Everything shown is real output from live runs, and none of it is investment advice.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>finance</category>
    </item>
    <item>
      <title>I gave Claude four compliance tools and one prompt. It built the due-diligence memo itself.</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:14:34 +0000</pubDate>
      <link>https://dev.to/scraperslat/i-gave-claude-four-compliance-tools-and-one-prompt-it-built-the-due-diligence-memo-itself-1866</link>
      <guid>https://dev.to/scraperslat/i-gave-claude-four-compliance-tools-and-one-prompt-it-built-the-due-diligence-memo-itself-1866</guid>
      <description>&lt;p&gt;This is an experiment, and I want to be precise about what it does and does not prove. I connected Claude to four live compliance data sources through the official Apify MCP server, gave it a single plain-English instruction, and watched to see whether it could run a real due-diligence check end to end: decide which sources to query, run them, cross-reference the results, score the risk, and hand back a memo where every claim points at a source.&lt;/p&gt;

&lt;p&gt;No mocked screens. Every registry record, sanctions hit, and SEC filing below is a real lookup against a live source, captured from an actual chat, with the Apify run ID printed next to it so you can reproduce it. The interesting part is not that a tool returned data. It is that nobody told Claude &lt;em&gt;which&lt;/em&gt; tools to call or &lt;em&gt;in what order&lt;/em&gt;. It read the request, picked the checks, and organized the evidence on its own.&lt;/p&gt;

&lt;p&gt;The bold version of the pitch: &lt;strong&gt;due diligence in one prompt.&lt;/strong&gt; You name a company, the agent builds the dossier.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four tools I wired in
&lt;/h2&gt;

&lt;p&gt;A due-diligence check on a counterparty is really four separate questions, each answered by a different authority:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Is the legal entity real and currently active?&lt;/strong&gt; A name on an invoice proves nothing. Companies dissolve, get wound up, or never existed under the name on the paperwork.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is the party on a US sanctions list?&lt;/strong&gt; Wiring money to an entity on the US Treasury's OFAC list is a strict-liability federal offense. "We didn't know" is not a defense.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is it on the EU list too?&lt;/strong&gt; A second jurisdiction either corroborates a hit or widens the exposure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does it file publicly, and do the identifiers match?&lt;/strong&gt; A company that files a 10-K with the SEC leaves a paper trail you can cross-check against the registry.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I connected one Apify Actor for each, all exposed to Claude through a single MCP endpoint:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4d06nkjet9e3iui625fp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4d06nkjet9e3iui625fp.png" alt="The OFAC Sanctions List Screening Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Sunbiz Florida Business Registry &amp;amp; Officers Scraper&lt;/strong&gt; (the full registry record: legal name, status, document number, officers, registered agent, and event history).&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;OFAC Sanctions List Screening Scraper&lt;/strong&gt; screens a name against the Specially Designated Nationals (SDN) list and returns programs, aliases, addresses, and linked entities.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;EU Consolidated Sanctions List Scraper&lt;/strong&gt; (the same screening against the European list, with regulation references and identifiers).&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;SEC EDGAR Filings Scraper&lt;/strong&gt; pulls a company's filings (10-K, 10-Q, 8-K) with the CIK, accession numbers, and filing dates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Four tools, one config line, no glue code. Then I opened a chat and typed a sentence.&lt;/p&gt;

&lt;h2&gt;
  
  
  One prompt, and the agent decided the rest
&lt;/h2&gt;

&lt;p&gt;I picked a clean subject on purpose for the first run: &lt;strong&gt;Publix Super Markets&lt;/strong&gt;, the Florida grocery chain. A real, active, Florida-incorporated company that also happens to file with the SEC, a good test of whether the agent would reach for the right combination of tools without being told.&lt;/p&gt;

&lt;p&gt;Here is the entire instruction I gave it, and what happened next:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgj4gl9beuyycnig4cyu2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgj4gl9beuyycnig4cyu2.png" alt="Claude running four compliance tools in sequence from a single due-diligence prompt" width="800" height="1129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I did not name a single tool. Claude decomposed the request into four checks and ran them in a sensible order (registry first to establish the entity, then both sanctions lists, then SEC filings), narrating its reasoning between calls. Every call is a real Apify run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sunbiz → run &lt;code&gt;pDNlZeA1aBU6oCQrS&lt;/code&gt;: &lt;strong&gt;ACTIVE&lt;/strong&gt;, PUBLIX SUPER MARKETS, INC., Florida Profit Corporation, document #112252, filed in 1921, with named officers (CEO Kevin S. Murphy, President John L. Goff, Jr., CFO David P. Phillips).&lt;/li&gt;
&lt;li&gt;OFAC → run &lt;code&gt;GSsSWcL3Kd2CoN63s&lt;/code&gt;: &lt;strong&gt;0 matches&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;EU consolidated list → run &lt;code&gt;mOYdsujWKycKzbakB&lt;/code&gt;: &lt;strong&gt;0 matches&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;SEC EDGAR → run &lt;code&gt;PDMwwh0FVfgzytjCu&lt;/code&gt;: a &lt;strong&gt;10-K filed 2026-03-02&lt;/strong&gt; for the fiscal year ending 2025-12-27, under CIK 0000081061.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it did the thing I was actually watching for. It noticed that the EIN on the SEC filing (59-0324412) is an &lt;em&gt;exact match&lt;/em&gt; to the FEI number on the Florida registry record. The same legal entity, confirmed by two independent government sources. Nobody asked it to reconcile identifiers across databases. It reasoned that a cross-check was worth doing and did it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scored dossier
&lt;/h2&gt;

&lt;p&gt;Data is not a decision. The last step, and the one that usually eats an analyst's afternoon, is turning four raw results into something you can attach to a file and defend to an auditor. I asked Claude to score the risk and write it up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy8go9ep06k2kl8kee8v2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy8go9ep06k2kl8kee8v2.png" alt="Claude producing a scored due-diligence dossier with a LOW risk band and per-line evidence" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It scored Publix &lt;strong&gt;LOW&lt;/strong&gt; and laid out the reasoning as a table where every row carries the run ID behind it: registry PASS, OFAC CLEAR, EU CLEAR, SEC VERIFIED, and the identity cross-check MATCH. The recommendation is "proceed with onboarding," explicitly &lt;em&gt;subject to human sign-off&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That last clause is not decoration. The score is a heuristic the agent applies to evidence it gathered; it is a starting point for a human, not a verdict that replaces one. What the agent removed was the mechanical labor (the tab-switching, the copy-paste, the risk of skipping a check under deadline pressure), not the judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The contrast: what a bad name looks like
&lt;/h2&gt;

&lt;p&gt;A clean result only means something if the same workflow catches a dirty one. So I ran the identical instruction against a name I knew would be a problem: &lt;strong&gt;Rosoboronexport&lt;/strong&gt;, a Russian state arms exporter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F988mhvjmdk95ff1xp65d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F988mhvjmdk95ff1xp65d.png" alt="Claude screening Rosoboronexport, hitting both the OFAC and EU sanctions lists, and scoring the counterparty HIGH risk" width="800" height="932"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agent screened the US list first, hit a match, and (instead of stopping) reasoned that a second jurisdiction was worth confirming before it reported. Both runs came back positive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OFAC → run &lt;code&gt;MLnvX5XE9E8vZYPK7&lt;/code&gt;: &lt;strong&gt;1 SDN match&lt;/strong&gt;. Listed as ROSOBORONEKSPORT OAO, under three programs (UKRAINE-EO13662, RUSSIA-EO14024, IRAN-CON-ARMS-EO), linked to State Corporation Rostec, at 27 Stromynka Ul., Moscow.&lt;/li&gt;
&lt;li&gt;EU consolidated list → run &lt;code&gt;wEU9R9n6McPW5SAfh&lt;/code&gt;: &lt;strong&gt;1 match&lt;/strong&gt;, reference EU.7808.66, programme UKR, designated 2022-03-15.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And again the agent did the cross-reference on its own. It noticed that both lists carry the &lt;strong&gt;same tax ID (7718852163) and the same registration number (1117746521452)&lt;/strong&gt;, meaning this is not a fuzzy name coincidence but the same legal entity, corroborated by two independent authorities. It scored the counterparty &lt;strong&gt;HIGH&lt;/strong&gt;, returned a STOP verdict, and recommended blocking the party and escalating to legal. Everything a compliance officer needs to act, with the evidence already attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the agent actually did, and what it didn't
&lt;/h2&gt;

&lt;p&gt;I want to be honest about the boundary, because the interesting claim here is narrow and the overselling would be easy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the agent did:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chose the tools.&lt;/strong&gt; From one sentence, it decomposed the task into the right four checks and picked the matching source for each. It was not following a script.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sequenced the work.&lt;/strong&gt; Registry before sanctions before filings; on the sanctions hit, it confirmed a second jurisdiction before reporting rather than firing everything blindly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-referenced identifiers.&lt;/strong&gt; It matched an EIN to an FEI across two databases, and a tax ID across two sanctions lists, without being asked, the kind of corroboration that separates a real check from a name lookup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scored and cited.&lt;/strong&gt; It turned raw records into a risk band with a source run ID on every line.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What the agent did not do:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It did not make the final call.&lt;/strong&gt; LOW and HIGH are recommendations. A human still signs off on onboarding or blocking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It did not invent anything.&lt;/strong&gt; Every figure came from a live source in the last few minutes, printed with its run ID. When OFAC and EU returned nothing for Publix, the agent reported "no match," not "clean," an important distinction it kept straight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It did not replace a compliance program.&lt;/strong&gt; Fuzzy-name edge cases, beneficial-ownership tracing, and adverse-media checks are still human work. This automates the first, mechanical pass.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That division (the fetch and the first-pass scoring are automated, the judgment and sign-off stay human) is exactly the right one, and it is why the output is audit-ready by default instead of a black box.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the same agent
&lt;/h2&gt;

&lt;p&gt;Everything above is reproducible today with a free Apify account and any MCP-capable client (Claude Desktop, Cursor, or your own agent):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your Apify API token from the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt; under &lt;strong&gt;Settings → Integrations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the official Apify MCP server and list the four Actors in the &lt;code&gt;tools&lt;/code&gt; parameter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/sunbiz-florida-scraper,scrapers_lat/ofac-sanctions-scraper,scrapers_lat/eu-sanctions-list-scraper,scrapers_lat/sec-edgar-filings-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the client and ask it, in plain English, to run due diligence on a company. It will pick the right tool for each question, run them, and score the result.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; each tool call is a real Actor run billed to your Apify account, and each of these Actors is pay-per-result, a fraction of a cent per lookup. For continuous screening of thousands of counterparties, run the Actors on a schedule through the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API&lt;/a&gt; instead of one call per chat.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;Extend it:&lt;/strong&gt; the same pattern scales to any jurisdiction or check. Add &lt;a href="https://apify.com/scrapers_lat/uk-companies-house-scraper" rel="noopener noreferrer"&gt;UK Companies House&lt;/a&gt; for British entities, or a company-registry Actor for whatever market your counterparties sit in, to the &lt;code&gt;tools&lt;/code&gt; list, and your agent covers more ground without a single new line of code.&lt;/p&gt;

&lt;p&gt;The point of the experiment was never that a scraper can pull a record; that has been true for years. It is that a capable model, handed the right tools and one clear instruction, can now do the &lt;em&gt;assembly&lt;/em&gt; (decide what to check, reconcile it, score it, and cite it) and leave a human with the one thing that should stay human: the decision.&lt;/p&gt;

&lt;p&gt;The Actors used in this experiment: &lt;strong&gt;Sunbiz Florida Business Registry &amp;amp; Officers Scraper&lt;/strong&gt;, &lt;strong&gt;OFAC Sanctions List Screening Scraper&lt;/strong&gt;, &lt;strong&gt;EU Consolidated Sanctions List Scraper&lt;/strong&gt;, and &lt;strong&gt;SEC EDGAR Filings Scraper&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>compliance</category>
    </item>
    <item>
      <title>The morning an AI agent caught a Takata airbag before the car hit the lot</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:13:47 +0000</pubDate>
      <link>https://dev.to/scraperslat/the-morning-an-ai-agent-caught-a-takata-airbag-before-the-car-hit-the-lot-1gie</link>
      <guid>https://dev.to/scraperslat/the-morning-an-ai-agent-caught-a-takata-airbag-before-the-car-hit-the-lot-1gie</guid>
      <description>&lt;p&gt;This is a story about a used-car dealership that stopped losing an hour a day to browser tabs, because someone spent twenty minutes wiring two Apify Actors into Claude the week before. No mocked screens, no toy VINs. Every decoded spec and recall campaign below is a real lookup against a live source, captured from an actual chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Rosa runs inventory at a mid-size used-car dealer. Every vehicle that comes in the door (auction buys, trade-ins, wholesale lots) has to clear two checks before it can be photographed, priced, and put on the lot:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Is this actually the car the paperwork says it is?&lt;/strong&gt; A title that reads "2003 Honda Accord" tells you almost nothing. Is it the four-cylinder sedan or the V6 coupe? Was the VIN re-stamped or transposed? The make on the door jamb is not proof of the make, the model, or the year.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does it have an open safety recall?&lt;/strong&gt; Retailing a used car with an unremedied recall is a liability the moment something goes wrong, and in several states it is a disclosure problem too. The Takata airbag recalls alone still cover millions of older cars sitting on lots and in auction lanes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For years this meant Rosa kept two browser tabs open. One on a VIN decoder, one on the NHTSA recall lookup. For every car she typed the VIN, read the spec sheet, copied the make and model into the recall page, and read the campaign list. A ten-car auction run was most of a morning. The check was only as reliable as her patience on a busy day, and intake is always a busy day.&lt;/p&gt;

&lt;p&gt;So the week before this story, she did something different. She wired both data sources directly into Claude as tools, using the &lt;strong&gt;official Apify MCP server&lt;/strong&gt;, and let the model do the fetching. Setup was one config file and a restart.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuen1x20j2l1b3i233us4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuen1x20j2l1b3i233us4.png" alt="The NHTSA VIN Decoder and Vehicle Specs Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The two tools she connected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/nhtsa-vin-decoder-scraper" rel="noopener noreferrer"&gt;NHTSA VIN Decoder &amp;amp; Vehicle Specs Scraper&lt;/a&gt; turns any VIN into the full spec sheet: make, model, year, trim, body class, engine, cylinders, horsepower, fuel type, and assembly plant, with a check-digit validation on the VIN itself.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/nhtsa-recalls-scraper" rel="noopener noreferrer"&gt;NHTSA Recalls Scraper&lt;/a&gt; returns every safety recall campaign for a make, model, and year: campaign number, affected component, the official summary, the remedy, and the date the recall began.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both exposed to Claude through one MCP endpoint. Nothing else changed about how Rosa works: she still opens a chat and types in plain English.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first car
&lt;/h2&gt;

&lt;p&gt;Monday morning, four vehicles came off the weekend auction run. Rosa started with the one whose title told her the least (a plain "2003 Honda Accord") and asked Claude to decode the VIN before she wrote a word of the listing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6u4aw64v39h95l07xdaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6u4aw64v39h95l07xdaj.png" alt="Claude decoding a VIN off the inbound list and confirming the exact trim and drivetrain" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One tool call, and the car had an identity. The VIN decoded &lt;strong&gt;clean&lt;/strong&gt;. The check digit in the ninth position was correct, which is the first guard against a re-stamped or transposed number. And it was not a generic Accord. It was a &lt;strong&gt;2003 Honda Accord EX-V6 Coupe&lt;/strong&gt;: a two-door body, a 3.0-liter V6 (engine model J30A4), 240 horsepower, five-speed automatic, built in Marysville, Ohio. That is a different listing and a different price band than the four-cylinder sedan someone might have assumed from the title.&lt;/p&gt;

&lt;p&gt;This is the quiet part that matters. A make on a title is not a car. The decode caught the real trim and drivetrain in two seconds, and it did it the same way for every VIN, whether it was car one or car forty.&lt;/p&gt;

&lt;h2&gt;
  
  
  The catch
&lt;/h2&gt;

&lt;p&gt;Then the check that actually stops cars from being sold. Rosa asked Claude to pull open safety recalls for that same Accord before it went anywhere near the lot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzeuedqlmnp7p2ben02ce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzeuedqlmnp7p2ben02ce.png" alt="Claude surfacing the open Takata airbag recall campaigns for the 2003 Accord and recommending a hold" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The answer put the car on hold.&lt;/p&gt;

&lt;p&gt;The 2003 Accord is covered by multiple recall campaigns, and the ones that matter are the &lt;strong&gt;Takata airbag&lt;/strong&gt; inflators. Claude surfaced them with campaign numbers, components, and remedies attached:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;19V182000&lt;/strong&gt;: driver frontal airbag inflator. Remedy: a dealer replaces the driver airbag inflator, free of charge. The recall began April 10, 2019, and covers roughly 1.1 million vehicles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;19V501000&lt;/strong&gt;: passenger frontal airbag inflator. Remedy: a dealer replaces the passenger inflator, free of charge. Began August 12, 2019, roughly 1.66 million vehicles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;10V364000&lt;/strong&gt;: ignition switch interlock lever wear. Remedy: a dealer replaces the interlock pin and lever, free of charge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Takata inflators can rupture and fire metal fragments at the people in the car; they are the defect behind multiple U.S. fatalities. Selling a used vehicle with that recall still open is exactly the exposure Rosa's manager wants avoided. Claude's recommendation was the right one: route the Accord to a Honda dealer for the free inflator replacement, get the campaigns closed, and only then list it. Nobody had to remember to run this as a separate ritual. It was one sentence in the same conversation, backed by the live recall list rather than anyone's memory of which years Takata covered.&lt;/p&gt;

&lt;h2&gt;
  
  
  The batch
&lt;/h2&gt;

&lt;p&gt;The last step is the one that used to eat the most time: doing the same thing for the rest of the run and writing it up. Rosa asked Claude to consolidate all four inbound vehicles into a single lot / hold table she could paste straight into the intake sheet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8qf559b4hda6tncsutkr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8qf559b4hda6tncsutkr.png" alt="Claude producing a consolidated lot / hold table for the four inbound vehicles with the campaign numbers behind each decision" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Four cars, four decisions, each traceable to a campaign number or a run ID:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2003 Honda Accord EX-V6&lt;/strong&gt;: Takata airbag (19V182000, 19V501000) and ignition switch (10V364000). &lt;strong&gt;No, hold off lot&lt;/strong&gt; until the airbag remedy is confirmed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2013 Ford F-150&lt;/strong&gt;: brake master cylinder (16V345000) and transmission control module (19V075000). &lt;strong&gt;Hold&lt;/strong&gt; and book the service; the brake recall is a physical repair.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2018 Tesla Model 3&lt;/strong&gt;: seat-belt fastener (21V389000) and front suspension link (23V235000), plus software recalls that apply over the air. &lt;strong&gt;Hold&lt;/strong&gt; and verify the two physical items at a service center.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2003 Toyota Sienna&lt;/strong&gt;: a structure recall (10V160000). &lt;strong&gt;Hold&lt;/strong&gt; and verify the remedy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The headline was uncomfortable and completely real: &lt;strong&gt;not one of the four inbound cars was clean.&lt;/strong&gt; Every vehicle carried at least one open safety recall. On a busy morning, with the old two-tab process, at least one of those (probably the Accord's airbag) had a real chance of being missed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually changed
&lt;/h2&gt;

&lt;p&gt;Nothing about Rosa's &lt;em&gt;judgment&lt;/em&gt; moved to the machine. She still decides what to list, what to send for service, and what to send back. What moved was the mechanical part: the tab-switching, the copy-paste between a VIN decoder and a recall page, the risk of skipping a check when the lane is full. That is the right division of labor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The fetch is automated.&lt;/strong&gt; Claude decodes the VIN and pulls the recall campaigns on its own, the moment the conversation needs them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The evidence is preserved.&lt;/strong&gt; Every line cites a campaign number or a run ID, so the intake sheet is audit-ready by default, useful the day a buyer, an insurer, or a regulator asks how the car was cleared.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The check is consistent.&lt;/strong&gt; The agent runs the same decode-and-recall screen on every car, at 9am or 6pm, whether it is the first of the day or the fortieth.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dissolved-shell equivalent here (a life-threatening airbag on a twenty-year-old coupe) was caught before the car ever reached a customer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the same agent
&lt;/h2&gt;

&lt;p&gt;Everything in this story is reproducible today with a free Apify account and any MCP-capable client (Claude Desktop, Cursor, or your own agent):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your Apify API token from the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt; under &lt;strong&gt;Settings → Integrations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the official Apify MCP server to your client and list the two Actors in the &lt;code&gt;tools&lt;/code&gt; parameter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/nhtsa-vin-decoder-scraper,scrapers_lat/nhtsa-recalls-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the client and ask it, in plain English, to decode a VIN and check the car for open recalls. It will pick the right tool for each step.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; each tool call is a real Actor run billed to your Apify account (both are pay-per-result, a fraction of a cent per lookup). For continuous screening of a full lot or a fleet, run the Actors on a schedule through the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API&lt;/a&gt; and feed a whole VIN list at once instead of one call per chat.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;Extend it:&lt;/strong&gt; the same pattern scales past intake. A marketplace can screen every new listing at upload; a fleet operator can re-run the recall check monthly against its VIN list; an insurer can flag open safety recalls at quote or renewal. Point the agent at a VIN list and it decodes and screens the whole book without a line of new code.&lt;/p&gt;

&lt;p&gt;The Actors used in this story: &lt;a href="https://apify.com/scrapers_lat/nhtsa-vin-decoder-scraper" rel="noopener noreferrer"&gt;NHTSA VIN Decoder &amp;amp; Vehicle Specs Scraper&lt;/a&gt; and &lt;a href="https://apify.com/scrapers_lat/nhtsa-recalls-scraper" rel="noopener noreferrer"&gt;NHTSA Recalls Scraper&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>api</category>
    </item>
    <item>
      <title>The cross-border vendor that almost got paid against a VAT number that did not exist</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:08:54 +0000</pubDate>
      <link>https://dev.to/scraperslat/the-cross-border-vendor-that-almost-got-paid-against-a-vat-number-that-did-not-exist-4j70</link>
      <guid>https://dev.to/scraperslat/the-cross-border-vendor-that-almost-got-paid-against-a-vat-number-that-did-not-exist-4j70</guid>
      <description>&lt;p&gt;This is a story about a contract that nearly went out clean, and the twenty minutes of setup that stopped it. No mocked screens, no toy data. Every registry record, UEN, and VAT result below is a real lookup against a live official source, captured from an actual chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Marcus runs revenue operations at a US software company. When the business signs a new vendor, he owns the last gate before legal countersigns and finance sets up the payee. Most of the time that gate is a formality. This week it was not.&lt;/p&gt;

&lt;p&gt;The vendor was a cross-border one, which is where these deals get slippery. The contracting party was a &lt;strong&gt;Singapore entity&lt;/strong&gt;. The invoices, though, would come from a &lt;strong&gt;separate EU entity&lt;/strong&gt; in France, with a VAT number on them so finance could handle the tax treatment. Two legal entities, two jurisdictions, one signature about to bind them all.&lt;/p&gt;

&lt;p&gt;Marcus had learned the hard way that a name on a contract is not proof of anything, and a VAT number on an invoice is just a string of digits until something authoritative says otherwise. Before he would move the contract forward, two things had to be true:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Singapore company has to be a live, registered entity&lt;/strong&gt;, and he needs its UEN (Unique Entity Number) to set up the payee correctly, not a similarly named shell.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The EU VAT number on the invoice has to be valid and resolve to the entity that is actually billing us.&lt;/strong&gt; If it does not, finance cannot reclaim the input VAT, and the contract is exposed at the next audit.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For years this meant two government websites, two search boxes, and a lot of squinting at screens in languages he does not read. It was reliable exactly as long as he was not rushed. Onboarding is always rushed.&lt;/p&gt;

&lt;p&gt;So a couple of weeks earlier, Marcus had done something different. He wired both data sources directly into Claude as tools, using the &lt;strong&gt;official Apify MCP server&lt;/strong&gt;, and let the model do the fetching. It took one config block and a restart.&lt;/p&gt;

&lt;p&gt;The two tools he connected:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyqfo79u1rykbxynl0ygx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyqfo79u1rykbxynl0ygx.png" alt="The Singapore ACRA Company Registry Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/singapore-acra-entities-scraper" rel="noopener noreferrer"&gt;Singapore ACRA Company Registry Scraper&lt;/a&gt; looks up any Singapore company on the official ACRA corporate register and returns the UEN, entity status, incorporation date, registered address, industry codes, and former names.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/eu-vat-vies-validation-scraper" rel="noopener noreferrer"&gt;EU VAT VIES Validation Scraper&lt;/a&gt; validates one or many EU VAT numbers against the European Commission's VIES service and, where the member state provides it, returns the registered trader name and address.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq1re82lcf0gmmgno9vl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq1re82lcf0gmmgno9vl8.png" alt="The EU VAT VIES Validation Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both exposed to Claude through a single MCP endpoint. Nothing else changed about how Marcus works: he opens a chat and types in plain English.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check one: is the Singapore company real?
&lt;/h2&gt;

&lt;p&gt;The contracting entity on the paperwork was "DBS Bank Ltd". Marcus pasted the name into Claude and asked it to confirm the company was live and pull the UEN.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foo0loe4oza0c5g8ddna9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foo0loe4oza0c5g8ddna9.png" alt="Claude verifying the Singapore vendor on the ACRA register and capturing its UEN and Live status" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two seconds of tool call, and he had a clean answer straight off the official register. &lt;strong&gt;DBS BANK LTD.&lt;/strong&gt; came back as a &lt;strong&gt;Live Company&lt;/strong&gt;, UEN &lt;strong&gt;196800306E&lt;/strong&gt;, a Public Company Limited by Shares incorporated on 16 July 1968, registered at 12 Marina Boulevard, and even carrying its former name (The Development Bank of Singapore) in the record.&lt;/p&gt;

&lt;p&gt;But the useful part was the thing Marcus would not have thought to look for. The same search surfaced a near-namesake, &lt;strong&gt;DBS PTE. LTD.&lt;/strong&gt;, UEN 197700546G, that was &lt;strong&gt;Dissolved&lt;/strong&gt; through a members' voluntary winding up. Claude flagged it unprompted: a different legal entity with a confusingly similar name, and it warned him to make sure the payee and the contract were set up under &lt;strong&gt;196800306E&lt;/strong&gt;, the live one, not the dead namesake sitting one row away in the register.&lt;/p&gt;

&lt;p&gt;This is exactly the trap that catches busy teams. The name matches. The UEN does not. Set finance up against the wrong one and you have wired money to an entity that legally no longer exists. The agent caught it and said which UEN to trust, with the register as evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check two: does the VAT number hold up?
&lt;/h2&gt;

&lt;p&gt;The Singapore side cleared. Now the EU billing entity. The invoice draft carried a French VAT number, and the vendor's master-data form listed two more numbers for good measure. Marcus asked Claude to run all of them through VIES and tell him which one finance could actually pay against.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F663zmxmg38q9sqnv1w3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F663zmxmg38q9sqnv1w3o.png" alt="Claude validating three EU VAT numbers against VIES, catching an invalid one and resolving the valid one to a registered trading name" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The answer stopped the invoice.&lt;/p&gt;

&lt;p&gt;The number &lt;strong&gt;printed on the invoice&lt;/strong&gt;, FR99999999999, came back &lt;strong&gt;INVALID&lt;/strong&gt;. VIES had no such registration. In plain terms: if finance had paid that invoice as it stood, the input VAT would not have been reclaimable and the document would have failed audit. It was not a live registration at all, just a plausible-looking string of the right length.&lt;/p&gt;

&lt;p&gt;The corrected French number, &lt;strong&gt;FR40303265045&lt;/strong&gt;, came back &lt;strong&gt;VALID&lt;/strong&gt; and, better still, resolved to a real registered trader: &lt;strong&gt;SA SODIMAS&lt;/strong&gt;, at 11 Rue Ampere, 26600 Pont de l'Isere. That is the piece that makes VIES more than a yes/no check. The name and address it returns are the thing Marcus can reconcile against the EU entity written into the contract. Valid &lt;em&gt;and&lt;/em&gt; matching is the bar, not valid alone.&lt;/p&gt;

&lt;p&gt;The third number, a German VAT (DE811193231), was &lt;strong&gt;VALID&lt;/strong&gt; too, though Claude was careful to note that Germany does not return a trader name through VIES, only the confirmation, so that one has to be matched to the contract by number rather than by name. An honest caveat, surfaced without being asked, rather than a false sense of a name match that VIES never actually provided.&lt;/p&gt;

&lt;p&gt;So the picture was: the vendor genuinely holds a valid EU VAT registration, but the number their own invoice carried was not it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The memo
&lt;/h2&gt;

&lt;p&gt;The last step is the one that used to eat the most time: writing it up so someone else can trust the decision. Marcus asked Claude to consolidate everything into a single go/no-go table he could staple to the contract approval.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ux3gd87flothgrkaxn6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ux3gd87flothgrkaxn6.png" alt="Claude producing a consolidated go/no-go table citing the UEN and VAT number behind each decision" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Five lines, each tied to the identifier it rests on. The Singapore counterparty: GO, under UEN 196800306E. The dissolved namesake: do not use. The EU entity SA SODIMAS: GO, on a valid VAT that returns a matching name. The number actually on the invoice: NO-GO, reject and re-issue. The secondary German VAT: fine, match by number.&lt;/p&gt;

&lt;p&gt;The bottom line the agent wrote was not "approved" and it was not "blocked." It was the precise, defensible thing: &lt;strong&gt;cleared to sign once the vendor re-issues the invoice against the valid VAT number.&lt;/strong&gt; Both lookups had run against official sources that morning, and both run IDs were in the memo, so the approval file was audit-ready the moment it was written.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually changed
&lt;/h2&gt;

&lt;p&gt;Nothing about Marcus's judgment moved to the machine. He still decides which vendors to onboard and when to hold a signature. What moved was the mechanical part that fails under time pressure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The fetch is automated.&lt;/strong&gt; Claude pulls the live ACRA record and runs the VAT numbers through VIES on its own, the moment the conversation needs them, in jurisdictions and languages Marcus does not have to navigate by hand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The evidence is preserved.&lt;/strong&gt; Every answer cites a UEN or a VAT number and the run it came from, so the output is audit-ready by default instead of a screenshot someone took and lost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The check is consistent.&lt;/strong&gt; The same two-part screening happens on vendor one and vendor fifty, whether or not anyone is watching the clock.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two problems got caught before the contract went out: a dissolved namesake that could have become the payee, and an invalid VAT number that would have surfaced months later as an audit finding. On a rushed onboarding, with the old two-tab process, at least one of them slips through.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the same agent
&lt;/h2&gt;

&lt;p&gt;Everything in this story is reproducible today with a free Apify account and any MCP-capable client (Claude Desktop, Cursor, or your own agent):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your Apify API token from the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt; under &lt;strong&gt;Settings → Integrations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the official Apify MCP server to your client and list the two Actors in the &lt;code&gt;tools&lt;/code&gt; parameter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/singapore-acra-entities-scraper,scrapers_lat/eu-vat-vies-validation-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the client and ask it, in plain English, to verify a Singapore counterparty and validate the VAT number on its invoice. It will pick the right tool for each step.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; each tool call is a real Actor run billed to your Apify account (both are pay-per-result, a fraction of a cent per lookup). For continuous screening of a whole vendor master, run the Actors on a schedule through the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API&lt;/a&gt; instead of one call per chat.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;Extend it:&lt;/strong&gt; the same pattern scales to any jurisdiction or check. Add &lt;a href="https://apify.com/scrapers_lat/uk-companies-house-scraper" rel="noopener noreferrer"&gt;UK Companies House&lt;/a&gt; for British counterparties, or the &lt;a href="https://apify.com/scrapers_lat/ofac-sanctions-scraper" rel="noopener noreferrer"&gt;OFAC Sanctions List Screening Scraper&lt;/a&gt; to screen the same party against the US Treasury list, and your onboarding agent covers more ground without a single line of new code.&lt;/p&gt;

&lt;p&gt;The Actors used in this story: &lt;a href="https://apify.com/scrapers_lat/singapore-acra-entities-scraper" rel="noopener noreferrer"&gt;Singapore ACRA Company Registry Scraper&lt;/a&gt; and &lt;a href="https://apify.com/scrapers_lat/eu-vat-vies-validation-scraper" rel="noopener noreferrer"&gt;EU VAT VIES Validation Scraper&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>compliance</category>
    </item>
    <item>
      <title>The hour before the call: how an analyst built a company one-pager from the filings, not the model's memory</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:08:06 +0000</pubDate>
      <link>https://dev.to/scraperslat/the-hour-before-the-call-how-an-analyst-built-a-company-one-pager-from-the-filings-not-the-74</link>
      <guid>https://dev.to/scraperslat/the-hour-before-the-call-how-an-analyst-built-a-company-one-pager-from-the-filings-not-the-74</guid>
      <description>&lt;p&gt;This is a story about the last hour before an investment call, and the two Apify Actors that turned a scramble into a five-minute job. No mocked screens, no toy numbers. Every filing date, accession number, and insider trade below is a real lookup against the live SEC, captured from an actual chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Daniel does buy-side research at a fund that moves fast. When a name lands on the calendar, he has to walk into the call already fluent in it: what the company most recently told the SEC, and what the people who run it have been doing with their own shares. Two questions, both boring, both non-negotiable, and both easy to get subtly wrong under time pressure.&lt;/p&gt;

&lt;p&gt;The trap is obvious once you have been burned by it. Ask a language model "what was in NVIDIA's latest 10-K" and it will answer confidently from training data that may be a year stale, with a fiscal period that quietly does not match the filing on record. For a one-pager that a portfolio manager will act on, "roughly right, from memory" is worse than useless. Daniel needs facts that trace back to a document with an accession number, not a plausible paragraph.&lt;/p&gt;

&lt;p&gt;For years the manual version of this was two browser tabs. One on SEC EDGAR's full-text search, hunting for the most recent annual report and copying the filing date and period. One on the Form 4 feed, scrolling insider transactions and trying to eyeball whether the selling meant anything. Ten minutes if the site was fast and he knew exactly what he was looking for. Longer when he didn't, which was most of the time on a name he was meeting cold.&lt;/p&gt;

&lt;p&gt;So the week before this call, he did it differently. He wired the two SEC data sources directly into Claude as tools, using the &lt;strong&gt;official Apify MCP server&lt;/strong&gt;, and let the model do the fetching. Setup was one config block and a restart.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2kaynx2rwk3p8wh129wm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2kaynx2rwk3p8wh129wm.png" alt="The SEC EDGAR 10-K, 10-Q and 8-K Filings Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The two Actors he connected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/sec-edgar-filings-scraper" rel="noopener noreferrer"&gt;SEC EDGAR 10-K, 10-Q &amp;amp; 8-K Filings Scraper&lt;/a&gt; returns a company's filings of record by ticker or CIK: form type, filing date, period of report, accession number, filer category, and the direct link to the document on sec.gov.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://apify.com/scrapers_lat/sec-form4-insider-trades-scraper" rel="noopener noreferrer"&gt;SEC Form 4 Insider Trading Transactions Scraper&lt;/a&gt; returns insider trades as structured rows: insider name, role, transaction code (buy, sell, grant, gift), shares, price per share, transaction value, and shares owned afterward.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both exposed to Claude through one MCP endpoint. Nothing else changed about how he works: he opens a chat and types in plain English.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sixty minutes out: the filing
&lt;/h2&gt;

&lt;p&gt;An hour before the call, Daniel opened a chat and asked for the one thing he refuses to take from memory: the latest annual report on file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fygmgtwtspc69d6cogjem.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fygmgtwtspc69d6cogjem.png" alt="Claude pulling NVIDIA's latest 10-K straight from SEC EDGAR" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One tool call, and the filing came back as a record, not a recollection. The latest &lt;strong&gt;10-K&lt;/strong&gt; for NVIDIA Corp was &lt;strong&gt;filed 2026-02-25&lt;/strong&gt;, covering the &lt;strong&gt;fiscal year ended 2026-01-25&lt;/strong&gt;, under accession number &lt;strong&gt;0001045810-26-000021&lt;/strong&gt;. Claude also handed back the CIK (0001045810), the filer status (large accelerated filer), the Nasdaq listing, and the four prior 10-Ks going back to fiscal 2022, so Daniel had a clean five-year annual trail if the call turned historical.&lt;/p&gt;

&lt;p&gt;The distinction that matters: the agent did not tell Daniel what NVIDIA earned. It told him &lt;em&gt;which document to trust&lt;/em&gt;, with the exact period and accession, so any figure he cites on the call traces to that filing rather than to a model's guess about last year. That is the honest division of labor. The tool finds and identifies the primary source; the analyst reads it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The insider question
&lt;/h2&gt;

&lt;p&gt;Filing in hand, Daniel asked the second question, the one that separates a real read from a headline. Insider selling at NVIDIA had been in the news, big dollar figures attached. He wanted to know what was actually underneath the number.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbu555phbi6fwcoae2e51.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbu555phbi6fwcoae2e51.png" alt="The SEC Form 4 Insider Trading Transactions Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;He didn't want a total. He wanted the composition.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmqh0kpa6xiskv3v04rzf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmqh0kpa6xiskv3v04rzf.png" alt="Claude breaking down NVIDIA Form 4 activity and separating the signal from the noise" width="800" height="901"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One tool call pulled forty Form 4 transactions filed since January, and Claude did the part that a raw dollar sum hides: it separated the flow into buckets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Almost all the dollar volume came from one person.&lt;/strong&gt; Director Mark A. Stevens sold roughly &lt;strong&gt;$446 million&lt;/strong&gt; of stock on the open market across the window: 565,615 shares at $210.44 and 319,385 at $209.70 on a single day in June, half a million more shares at $222.38 earlier that month, and so on. Enormous, but it is &lt;em&gt;one&lt;/em&gt; insider, and the sales are staggered across dates in a way that reads as a pre-arranged plan rather than a reaction to anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The executives' "selling" was mostly not selling at all.&lt;/strong&gt; The CFO and the EVPs appear under transaction code &lt;strong&gt;F&lt;/strong&gt;: shares automatically surrendered to cover taxes when equity awards vest, all at the same $207.41 on the same day. That is a mechanical event, not a market call. Colette Kress, the CFO, shows 40,746 shares withheld this way, not sold into a decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The CEO made no open-market sale at all.&lt;/strong&gt; Jensen Huang's only entries in the window are a 400,000-share gift and tax withholding on vesting. And across all forty transactions, there was &lt;strong&gt;not a single open-market insider buy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Claude's read, stated plainly: this is not a broad executive exodus. The scary headline is one director's programmatic sales plus routine vesting mechanics, and the person running the company did not sell a share on the market. Then the line that keeps the tool in its lane: &lt;em&gt;this is the structure of the insider flow, not a buy or sell recommendation; the judgment call is yours.&lt;/em&gt; That is exactly right. The agent organized the evidence. It did not tell Daniel what to think of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five minutes out: the dossier
&lt;/h2&gt;

&lt;p&gt;With both pieces gathered, Daniel asked for the deliverable: a single one-pager he could drop into his call notes, with the source run cited for each block so anyone reviewing it later could reproduce every line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk1nbdal9063b8yjf6lz5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk1nbdal9063b8yjf6lz5.png" alt="Claude consolidating the filing facts and insider read into a single traceable one-pager" width="800" height="923"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two tables and a two-sentence read. The company and its latest annual filing at the top, the insider composition below, and under each block the Actor and run ID it came from. An analyst reading this six months from now can re-run either pull and get the same rows. That is the difference between a note that says "insiders are selling" and a note that says "insider selling is concentrated in one director's plan; here is the run that proves it."&lt;/p&gt;

&lt;p&gt;The whole thing (filing, insider breakdown, consolidated one-pager) took the length of a coffee. The old version of this hour was two tabs, a lot of scrolling, and a quiet worry that the fiscal period on the slide didn't quite match the filing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually changed
&lt;/h2&gt;

&lt;p&gt;Nothing about Daniel's &lt;em&gt;analysis&lt;/em&gt; moved to the machine. He still decides what the company is worth and what to say on the call. What moved was the fetching and the sorting, the mechanical layer that used to eat the hour and occasionally introduced a stale fact:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The source is authoritative.&lt;/strong&gt; Every filing fact carries an accession number and every insider figure carries a run ID. The one-pager is audit-ready by construction, not by cleanup afterward.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The signal is separated from the noise.&lt;/strong&gt; A raw "insiders sold $500M" is a trap. Splitting it into one director's plan, mechanical tax withholding, and zero buys is the actual read, and the agent did that sorting in seconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The model's memory never touched the numbers.&lt;/strong&gt; The point of wiring in the tools is precisely so Claude answers from today's filings, not from whatever it absorbed in training. On a name that reports every quarter, that is the whole ballgame.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Daniel walked into the call working from the record. On a busy morning, with the old two-tab process, the fiscal period might have been last year's and the insider story might have been the headline instead of the truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the same agent
&lt;/h2&gt;

&lt;p&gt;Everything in this story is reproducible today with a free Apify account and any MCP-capable client (Claude Desktop, Cursor, or your own agent):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your Apify API token from the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt; under &lt;strong&gt;Settings → Integrations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the official Apify MCP server to your client and list the two Actors in the &lt;code&gt;tools&lt;/code&gt; parameter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/sec-edgar-filings-scraper,scrapers_lat/sec-form4-insider-trades-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the client and ask it, in plain English, for a company's latest 10-K and its recent Form 4 activity. It will pick the right tool for each question and cite the run.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; each tool call is a real Actor run billed to your Apify account (both are pay-per-result, a fraction of a cent per lookup). For a watchlist rather than one name, run the Actors on a schedule through the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API&lt;/a&gt; and have the agent read the latest results, instead of one call per chat.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;Extend it:&lt;/strong&gt; the same pattern covers the rest of a diligence sheet. Add &lt;a href="https://apify.com/scrapers_lat/sec-13f-holdings-scraper" rel="noopener noreferrer"&gt;SEC 13F Institutional Holdings&lt;/a&gt; to see who owns the stock, or &lt;a href="https://apify.com/scrapers_lat/sec-edgar-financials-scraper" rel="noopener noreferrer"&gt;SEC Financial Statements&lt;/a&gt; to pull the actual line items behind the 10-K, and your research agent builds the whole one-pager from filings of record, without a single line of new code.&lt;/p&gt;

&lt;p&gt;The Actors used in this story: &lt;a href="https://apify.com/scrapers_lat/sec-edgar-filings-scraper" rel="noopener noreferrer"&gt;SEC EDGAR 10-K, 10-Q &amp;amp; 8-K Filings Scraper&lt;/a&gt; and &lt;a href="https://apify.com/scrapers_lat/sec-form4-insider-trades-scraper" rel="noopener noreferrer"&gt;SEC Form 4 Insider Trading Transactions Scraper&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>finance</category>
    </item>
    <item>
      <title>The provider roster that would have failed in the claims system, caught before it loaded</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:03:14 +0000</pubDate>
      <link>https://dev.to/scraperslat/the-provider-roster-that-would-have-failed-in-the-claims-system-caught-before-it-loaded-7m7</link>
      <guid>https://dev.to/scraperslat/the-provider-roster-that-would-have-failed-in-the-claims-system-caught-before-it-loaded-7m7</guid>
      <description>&lt;p&gt;This is a story about a task nobody puts on a slide: checking a list of doctors before it goes into the system that pays them. It is dull, it is repetitive, and when it goes wrong the failure shows up weeks later as a pile of rejected claims and angry providers. Every registry record below is a real lookup against the live national provider registry, captured from an actual chat. No mocked screens, no toy data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Priya runs provider-network operations at a regional health plan. When the contracting team signs a new group or a batch of clinicians, the roster lands on her desk as a spreadsheet: an NPI for each provider, a name, and a claimed specialty. Her job is to verify each row and then load it into the claims system so the plan can actually pay those providers.&lt;/p&gt;

&lt;p&gt;The verification is not glamorous, but it is load-bearing. For every NPI she has to confirm three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Is the NPI Active?&lt;/strong&gt; A deactivated or non-existent NPI that slips into the claims system rejects every claim tied to it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is it the right entity type?&lt;/strong&gt; An individual clinician is a Type 1 NPI; a facility or group is Type 2. Load one where the other belongs and claims edit out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does the registry taxonomy match the specialty the contracting sheet claims?&lt;/strong&gt; If the roster says "ophthalmologist" and the registry says something else, the claim edits that key off specialty will reject the claim downstream.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For years this meant one browser tab on the national NPI registry, one row at a time: type the number, read the record, eyeball the specialty, copy the status into the load file. Twenty providers was a morning. And it was reliable exactly as long as she was not rushed, which, at roster-load time, she always is. The rejects that follow a bad load are expensive: reworked claims, provider abrasion, and a network-adequacy report that no longer matches reality.&lt;/p&gt;

&lt;p&gt;So she changed the mechanical part. She wired the national provider registry directly into Claude as a tool, using the &lt;strong&gt;official Apify MCP server&lt;/strong&gt;, and let the model do the lookups. Setup was one config block and a restart. Nothing about how she works changed: she still opens a chat and types in plain English.&lt;/p&gt;

&lt;p&gt;The tool she connected:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fefa1zmccho8uqr0ka4d9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fefa1zmccho8uqr0ka4d9.png" alt="The NPPES NPI Healthcare Provider Data Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://apify.com/scrapers_lat/nppes-npi-scraper" rel="noopener noreferrer"&gt;NPPES NPI Healthcare Provider Data Scraper&lt;/a&gt; returns the full registry record for any US provider: NPI status, entity type, legal name, credential, the full taxonomy (specialty) list with license numbers, and practice address. Exposed to Claude through one MCP endpoint, it turns a tab-and-type chore into a sentence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The batch
&lt;/h2&gt;

&lt;p&gt;Monday morning, a new roster: six providers to verify and load. A multi-specialty facility, a couple of dentists, a cardiologist, an oncologist, and an eye doctor. Instead of opening the registry six times, Priya pasted the list into Claude and asked it to check each NPI for status, type, and a taxonomy match against the specialty her sheet claimed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1exohl56roix8bzipyiv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1exohl56roix8bzipyiv.png" alt="Claude verifying six provider NPIs against the national registry and flagging one taxonomy mismatch" width="800" height="1143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few seconds of tool calls, and the picture was clear. Five of the six came back clean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mayo Clinic&lt;/strong&gt; (NPI 1881018208): Active, Type 2 (Organization), Clinic/Center, Multi-Specialty, Rochester, MN. Matches "facility."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dr. Steven Aaker&lt;/strong&gt; (1538202965): Active, Type 1, Dentist (DDS, license D8075), Prior Lake, MN. Matches "general dentist."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dr. John Aamodt&lt;/strong&gt; (1790723302): Active, Type 1, Dentist, Orthodontics, Eagan, MN. Matches "orthodontist."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dr. Michael Aaron, MD&lt;/strong&gt; (1790762623): Active, Type 1, Internal Medicine, Cardiovascular Disease, West Islip, NY. Matches "cardiologist."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dr. Laurent Gressot, MD&lt;/strong&gt; (1215930367): Active, Type 1, Hematology &amp;amp; Oncology, Houston, TX. Matches "oncologist."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The sixth is the reason the check exists. &lt;strong&gt;Dr. Steven Sheiner&lt;/strong&gt; (NPI 1417918293) came back Active (so a naive "is the NPI good?" check would have waved it through), but the registry listed him as an &lt;strong&gt;Optometrist&lt;/strong&gt;, while Priya's sheet claimed &lt;strong&gt;ophthalmologist&lt;/strong&gt;. Claude flagged it and offered to pull the detail.&lt;/p&gt;

&lt;p&gt;This is the part that matters. A live, Active NPI is not the same as a correct roster row. The registry check catches the difference and says &lt;em&gt;why&lt;/em&gt;, so the flag is auditable, not a hunch.&lt;/p&gt;

&lt;h2&gt;
  
  
  The catch
&lt;/h2&gt;

&lt;p&gt;Priya asked Claude to open up row six: why the flag, and what exactly to tell contracting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8byhdd69iph2en0gjhcv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8byhdd69iph2en0gjhcv.png" alt="Claude showing the full registry record for the flagged provider and explaining the taxonomy mismatch" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The detail made the problem concrete. The registry record for NPI 1417918293 shows the provider's credential is &lt;strong&gt;OD&lt;/strong&gt; (Doctor of Optometry) and the primary taxonomy is &lt;strong&gt;152W00000X, Optometrist&lt;/strong&gt;, licensed OPC3172 in Florida. The roster claimed &lt;strong&gt;Ophthalmology (207W00000X)&lt;/strong&gt;. Those are two different professions: an optometrist (OD) and an ophthalmologist (MD) are not interchangeable, and they carry different billable service sets.&lt;/p&gt;

&lt;p&gt;Loaded as an ophthalmologist, this row would have sailed past a basic eligibility check and then rejected the moment a claim came in with a procedure code restricted to that specialty, a taxonomy edit denial. The provider disputes the denial, and it lands right back on Priya's desk weeks later, harder to trace. Caught at load time, it is one line in an email to contracting: the registry shows this NPI belongs to an optometrist, not an ophthalmologist, so either the wrong NPI was pulled for the intended physician or the specialty column is wrong. Confirm which, fix it, then load.&lt;/p&gt;

&lt;p&gt;Nobody had to remember the OD-versus-MD distinction, or hold the taxonomy codes in their head. The check was one sentence, backed by the live registry rather than anyone's memory of what Dr. Sheiner does.&lt;/p&gt;

&lt;h2&gt;
  
  
  The load ticket
&lt;/h2&gt;

&lt;p&gt;The last step used to eat the most time: writing it all up so the load could proceed and an auditor could follow it later. Priya asked Claude to consolidate the morning's verification into a go/load table she could attach to the ticket.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs1qfwxo8z7hb7cf7x7a8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs1qfwxo8z7hb7cf7x7a8.png" alt="Claude producing a consolidated go/load table with the registry evidence for each provider" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Six providers, six decisions, each with the NPI status, entity type, and registry taxonomy it was based on. Five cleared to load, one on hold pending a specialty correction. The whole thing traces back to the official registry, so the load ticket carries its own evidence. If a claim on any of these providers is questioned six months from now, the reasoning is right there.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually changed
&lt;/h2&gt;

&lt;p&gt;Priya still owns the judgment. She still decides what loads and what goes back to contracting. What moved to the machine was the mechanical part: the tab-switching, the copy-paste, the risk of skimming a taxonomy under deadline. That is the right division of labor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The lookup is automated.&lt;/strong&gt; Claude pulls the live registry record the moment the conversation needs it, one NPI or fifty.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The evidence is preserved.&lt;/strong&gt; Every verdict cites a status, a type, and a taxonomy code, so the load ticket is audit-ready by default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The check is consistent.&lt;/strong&gt; The same three tests run on row six as on row one, at 9am or at 6pm, whether or not it is a busy morning.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The mismatched provider was caught before a single claim rejected. On the old one-tab process, an Active NPI with the wrong specialty is exactly the kind of thing that gets waved through under time pressure, and surfaces later as a denial report.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the same agent
&lt;/h2&gt;

&lt;p&gt;Everything in this story is reproducible today with a free Apify account and any MCP-capable client (Claude Desktop, Cursor, or your own agent):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your Apify API token from the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt; under &lt;strong&gt;Settings → Integrations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the official Apify MCP server to your client and list the Actor in the &lt;code&gt;tools&lt;/code&gt; parameter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/nppes-npi-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the client and paste a roster in plain English. Ask it to confirm each NPI is Active, the right type, and a taxonomy match. It will pick the tool and do the lookups.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; each tool call is a real Actor run billed to your Apify account (the NPPES Actor is pay-per-result, a fraction of a cent per lookup). For a nightly re-verification of an entire loaded network (catching providers who deactivate or change taxonomy after you loaded them), run the Actor on a schedule through the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API&lt;/a&gt; instead of one call per chat.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;Extend it:&lt;/strong&gt; the same pattern covers the rest of a provider-file check. Add &lt;a href="https://apify.com/scrapers_lat/sam-gov-scraper" rel="noopener noreferrer"&gt;SAM.gov exclusions&lt;/a&gt; to screen each provider against federal exclusion and debarment lists, or the &lt;a href="https://apify.com/scrapers_lat/ofac-sanctions-scraper" rel="noopener noreferrer"&gt;OFAC sanctions list&lt;/a&gt; for a sanctions check, to the &lt;code&gt;tools&lt;/code&gt; list, and your roster agent verifies more of the file without a line of new code.&lt;/p&gt;

&lt;p&gt;The Actor used in this story: &lt;a href="https://apify.com/scrapers_lat/nppes-npi-scraper" rel="noopener noreferrer"&gt;NPPES NPI Healthcare Provider Data Scraper&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>healthcare</category>
    </item>
    <item>
      <title>How to give Claude a US restaurant inspection lookup tool with the Apify MCP server</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:02:27 +0000</pubDate>
      <link>https://dev.to/scraperslat/how-to-give-claude-a-us-restaurant-inspection-lookup-tool-with-the-apify-mcp-server-3oo0</link>
      <guid>https://dev.to/scraperslat/how-to-give-claude-a-us-restaurant-inspection-lookup-tool-with-the-apify-mcp-server-3oo0</guid>
      <description>&lt;p&gt;AI agents are confident and forgetful. Ask Claude whether a specific Chicago cafe passed its last health inspection, and it will answer from training data that is months stale, or invent a plausible-sounding result. For a trust and safety team deciding whether to activate a restaurant on a delivery marketplace, or an insurer pricing a food-service policy, "probably fine" is not an answer you can put your name on.&lt;/p&gt;

&lt;p&gt;In this guide we fix that. We connect Claude to the &lt;strong&gt;official Apify MCP server&lt;/strong&gt;, expose a single Actor that reads US food-establishment health inspections, and turn "did this place pass its last inspection?" from a guess into a live lookup against the public inspection record. By the end you will have a working food-safety tool that Claude, Cursor, or any MCP client can call mid-conversation, and you will understand exactly where in the run the tool fires and what it returns.&lt;/p&gt;

&lt;p&gt;Everything below is a real setup with real output. No mocked responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Apify MCP server?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;Model Context Protocol&lt;/a&gt; (MCP) is an open standard that lets AI clients call external tools. The &lt;strong&gt;Apify MCP server&lt;/strong&gt; (&lt;code&gt;https://mcp.apify.com&lt;/code&gt;) implements that standard on top of the Apify platform, which means every one of the thousands of Actors in the &lt;a href="https://apify.com/store" rel="noopener noreferrer"&gt;Apify Store&lt;/a&gt; becomes a tool an agent can invoke.&lt;/p&gt;

&lt;p&gt;Why route an Actor through MCP instead of hard-coding an API call?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The agent decides when to fetch.&lt;/strong&gt; Claude reads the conversation, notices it needs a fact it does not have, and calls the tool on its own. You do not write glue code for every question.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured input and output.&lt;/strong&gt; The MCP server hands Claude the Actor's input schema, so the model fills in the parameters correctly, and returns a clean dataset it can reason over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One connection, many tools.&lt;/strong&gt; The same MCP endpoint exposes &lt;code&gt;search-actors&lt;/code&gt;, &lt;code&gt;fetch-actor-details&lt;/code&gt;, and &lt;code&gt;call-actor&lt;/code&gt;, so an agent can discover and run any Actor without new configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No infrastructure.&lt;/strong&gt; The server is hosted. You add a few lines to a config file and you are done.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Actor we will use
&lt;/h2&gt;

&lt;p&gt;We will expose the &lt;a href="https://apify.com/scrapers_lat/usa-restaurant-inspections-scraper" rel="noopener noreferrer"&gt;US Restaurant Inspections Scraper: Food Establishments&lt;/a&gt;. It searches public US food-establishment inspection records and returns, per inspection: the business name (DBA and AKA), license number, facility type, risk level, full address with geo coordinates, inspection date and type, the pass/fail result, a violation count, and a full violations summary with the inspector's comments.&lt;/p&gt;

&lt;p&gt;That field set is exactly what a food-safety or marketplace-trust check needs. You can filter by establishment name, city, result, and date range, so a query can be as narrow as "every failed inspection for this one cafe" or as broad as "all inspections in this city last month."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsnz5gwhg5i56059be5kn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsnz5gwhg5i56059be5kn.png" alt="The US Restaurant Inspections Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Get your Apify API token
&lt;/h2&gt;

&lt;p&gt;Sign in to the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt;, open &lt;strong&gt;Settings → Integrations&lt;/strong&gt;, and copy your personal API token. The MCP server uses it to authenticate and to bill Actor runs to your account.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; the token is a secret. Keep it in the client config only, never in a prompt or a committed file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Point Claude Desktop at the Apify MCP server
&lt;/h2&gt;

&lt;p&gt;Open Claude Desktop's config file (&lt;code&gt;Settings → Developer → Edit Config&lt;/code&gt;, or &lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&lt;/code&gt; on macOS) and add the Apify server. The &lt;code&gt;tools&lt;/code&gt; query parameter is the important part: it tells the server which Actor to expose, so Claude gets one focused tool instead of the entire Store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/usa-restaurant-inspections-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cursor uses the same JSON in &lt;code&gt;.cursor/mcp.json&lt;/code&gt;. If you prefer to run it locally over stdio instead of the hosted endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@apify/actors-mcp-server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--tools"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scrapers_lat/usa-restaurant-inspections-scraper"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"APIFY_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Claude Desktop so it picks up the new server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Confirm the tool is loaded
&lt;/h2&gt;

&lt;p&gt;After the restart, the Actor shows up as a callable tool. If you list the tools the Apify server exposes, you will see the storage helpers plus the Actor itself, named after its Store handle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get-actor-run, get-dataset-items, get-key-value-store-record,
abort-actor-run, scrapers_lat--usa-restaurant-inspections-scraper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last entry, &lt;code&gt;scrapers_lat--usa-restaurant-inspections-scraper&lt;/code&gt;, is our food-safety tool. Claude now knows it exists, what it does (from the Actor's README), and what inputs it takes (from the input schema the server passes along).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Ask Claude to check an establishment
&lt;/h2&gt;

&lt;p&gt;Now the payoff. In a normal chat, ask a question that requires ground truth:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We're onboarding a Starbucks-branded cafe at the Palmer House in Chicago onto our delivery marketplace. Pull its latest health inspection record so I can check for any recent failures."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude recognizes it cannot answer this reliably from memory, selects the inspections tool, and fills in the input from your question. Under the hood the client sends a &lt;code&gt;tools/call&lt;/code&gt; with the Actor's parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scrapers_lat--usa-restaurant-inspections-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"searchQueries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Starbucks"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CHICAGO"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"maxInspections"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Apify MCP server starts the Actor, waits for it to finish, and returns the dataset. Here is the real run metadata it produced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"runId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"7NUszN8Ahes7pybfI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actorName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scrapers_lat/usa-restaurant-inspections-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SUCCEEDED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"startedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-30T17:47:30.797Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"finishedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-30T17:47:35.233Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stats"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"runTimeSecs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under five seconds, live against the public inspection record.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Read the real output
&lt;/h2&gt;

&lt;p&gt;The dataset the tool returns is structured inspection data, one object per inspection. This is an actual record from the run (trimmed to the fields that matter for a trust check):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inspectionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2632789"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dbaName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"STARBUCKS PALMER HOUSE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"licenseNumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2948168"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"facilityType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Restaurant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"risk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Risk 2 (Medium)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fail"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inspectionType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Complaint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inspectionDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-03-19T00:00:00.000Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"17 E MONROE ST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CHICAGO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"zip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"60603"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"violationCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"violationsSummary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"38. INSECTS, RODENTS, &amp;amp; ANIMALS NOT PRESENT - Comments: OBSERVED EVIDENCE OF 3 LIVE ROACHES ... (CITATION ISSUED) | 2. CITY OF CHICAGO FOOD SERVICE SANITATION CERTIFICATE - Comments: OBSERVED NO CERTIFIED FOOD MANAGER ON DUTY WHILE TCS FOODS ARE BEING PREPARED ... (CITATION ISSUED)"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude reads that and answers in plain language: the Palmer House Starbucks (17 E Monroe St) &lt;strong&gt;failed&lt;/strong&gt; its 2026-03-19 complaint inspection with &lt;strong&gt;14 violations&lt;/strong&gt;, three of them carrying citations, including live roaches, no certified food manager on duty, and an employee handling food without washing hands after mopping. A previous core violation was flagged as not corrected. Every one of those facts is traceable to an official inspection report, not the model's memory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F26iygrdfwga8itjc77ym.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F26iygrdfwga8itjc77ym.png" alt="Claude calling the inspections tool and answering with the live Palmer House record" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The full-history view is just as important. The same query returns the follow-up re-inspections on 03-26 and 03-30 that also failed, so an analyst can see at a glance that the problems were not resolved on the first re-check. The single most recent record can look clean; the inspection trail tells the real story.&lt;/p&gt;

&lt;h2&gt;
  
  
  A real use case: a marketplace onboarding agent
&lt;/h2&gt;

&lt;p&gt;Put this in context. A trust and safety analyst at a food-delivery marketplace is activating a batch of new restaurant listings and needs to confirm, before any of them go live, that each establishment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;has a real, current inspection on file,&lt;/li&gt;
&lt;li&gt;is not sitting on an unresolved failed inspection, and&lt;/li&gt;
&lt;li&gt;does not have a pattern of repeat critical violations (pests, no certified manager, temperature abuse).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without a tool, the analyst opens the city inspection portal, types each name, reads the latest report, and copies the result into an onboarding sheet, once per restaurant. With the tool wired into Claude, the analyst pastes the batch into the chat and asks the agent to check each one. Claude calls the Actor per establishment, sorts the returned inspections by date, flags any recent &lt;code&gt;Fail&lt;/code&gt; or &lt;code&gt;Pass w/ Conditions&lt;/code&gt;, counts repeat violations, and produces a short activate/hold note with the inspection ID as evidence. The manual lookup step disappears; the judgment stays with the human.&lt;/p&gt;

&lt;p&gt;The same shape works for an insurer pricing food-service coverage, a franchisor auditing licensees, or a consumer-facing app that wants to show a live safety badge next to each listing. The mechanical fetch is removed; the decision is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going further: chain a second tool
&lt;/h2&gt;

&lt;p&gt;Inspection history answers "is this kitchen clean," but food-safety risk does not stop at the door. A brand can pass every inspection and still be shipping a product under recall. The same MCP connection can expose more Actors by extending the &lt;code&gt;tools&lt;/code&gt; parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp.apify.com?tools=scrapers_lat/usa-restaurant-inspections-scraper,scrapers_lat/openfda-food-recalls-scraper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the agent can check an establishment's inspection record &lt;strong&gt;and&lt;/strong&gt; screen the brands or products it serves against the &lt;a href="https://apify.com/scrapers_lat/openfda-food-recalls-scraper" rel="noopener noreferrer"&gt;openFDA Food Recall &amp;amp; Enforcement Scraper&lt;/a&gt; in the same conversation, then combine both into one risk summary: local hygiene from the inspection record, product-level recalls from the federal enforcement feed. Because each Actor is a separate tool, the agent picks the right one for each step on its own.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;Troubleshooting:&lt;/strong&gt; if the tool does not appear in Claude, the two usual causes are a missing or misspelled Actor handle in the &lt;code&gt;tools&lt;/code&gt; parameter (it must be the exact &lt;code&gt;username/actor-name&lt;/code&gt; from the Store URL) and a config that was edited while Claude was running. Fix the handle, save, and fully restart the client.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; each tool call is a real Actor run billed to your Apify account (this Actor is pay-per-result). For a single onboarding check the cost is a fraction of a cent; if you plan to sweep thousands of establishments on a schedule, run the Actor directly through the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API&lt;/a&gt; or a scheduled task instead of one call per chat message. Coverage is strongest in jurisdictions that publish inspection data openly, such as Chicago and New York City, so match your &lt;code&gt;cities&lt;/code&gt; filter to where the establishment actually operates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;You now have an AI agent that can check a US food establishment against its official inspection record, on demand, mid-conversation, with the violation detail and pass/fail history a real trust decision needs. The pattern is reusable: pick an Actor that returns authoritative structured data, expose it through the Apify MCP server with the &lt;code&gt;tools&lt;/code&gt; parameter, and let the agent decide when to call it.&lt;/p&gt;

&lt;p&gt;To take it further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Narrow or widen the query with the &lt;code&gt;cities&lt;/code&gt;, &lt;code&gt;results&lt;/code&gt;, and date-range filters to build anything from a single-store check to a citywide sweep.&lt;/li&gt;
&lt;li&gt;Add the food-recall Actor above, or a business-registry Actor, to build a multi-signal food-safety and vendor-vetting agent.&lt;/li&gt;
&lt;li&gt;Read the &lt;a href="https://docs.apify.com/platform/integrations/mcp" rel="noopener noreferrer"&gt;Apify MCP server docs&lt;/a&gt; for OAuth setup, resource reads, and the &lt;code&gt;search-actors&lt;/code&gt; / &lt;code&gt;call-actor&lt;/code&gt; tools that let an agent discover Actors it was not preconfigured with.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Actor used in this guide: &lt;a href="https://apify.com/scrapers_lat/usa-restaurant-inspections-scraper" rel="noopener noreferrer"&gt;US Restaurant Inspections Scraper: Food Establishments&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>api</category>
    </item>
    <item>
      <title>How to give Claude a Singapore government-tender tool with the Apify MCP server</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:57:36 +0000</pubDate>
      <link>https://dev.to/scraperslat/how-to-give-claude-a-singapore-government-tender-tool-with-the-apify-mcp-server-3bni</link>
      <guid>https://dev.to/scraperslat/how-to-give-claude-a-singapore-government-tender-tool-with-the-apify-mcp-server-3bni</guid>
      <description>&lt;p&gt;If you sell to the Singapore public sector, the single most useful thing you can know is what the government already buys, from whom, and for how much. That information exists, it is public, and it sits in GeBIZ, the Singapore Government e-procurement register. The problem is not access. The problem is that GeBIZ is a portal built for one-off human lookups, not for the "read fifty awards and tell me the pattern" question a bid or capture team actually asks.&lt;/p&gt;

&lt;p&gt;Ask Claude the same question from memory and it will happily invent an answer. It does not know that Workforce Singapore awarded a S$2.17M SaaS contract to AvePoint in May 2025, and if you press it, it will guess. For anything that feeds a bid decision, a confident guess is worse than no answer.&lt;/p&gt;

&lt;p&gt;In this guide we fix that. We connect Claude to the &lt;strong&gt;official Apify MCP server&lt;/strong&gt;, expose a single Actor that reads GeBIZ awarded contracts, and turn "who is winning Singapore government software work?" from a guess into a live query against the register. By the end you will have a working market-intelligence tool that Claude, Cursor, or any MCP client can call mid-conversation, and you will understand exactly where in the run the tool fires and what it returns.&lt;/p&gt;

&lt;p&gt;Everything below is a real setup with real output. No mocked responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Apify MCP server?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;Model Context Protocol&lt;/a&gt; (MCP) is an open standard that lets AI clients call external tools. The &lt;strong&gt;Apify MCP server&lt;/strong&gt; (&lt;code&gt;https://mcp.apify.com&lt;/code&gt;) implements that standard on top of the Apify platform, which means every one of the thousands of Actors in the &lt;a href="https://apify.com/store" rel="noopener noreferrer"&gt;Apify Store&lt;/a&gt; becomes a tool an agent can invoke.&lt;/p&gt;

&lt;p&gt;Why route an Actor through MCP instead of hard-coding an API call?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The agent decides when to fetch.&lt;/strong&gt; Claude reads the conversation, notices it needs a fact it does not have, and calls the tool on its own. You do not write glue code for every question.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured input and output.&lt;/strong&gt; The MCP server hands Claude the Actor's input schema, so the model fills in the parameters correctly, and returns a clean dataset it can reason over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One connection, many tools.&lt;/strong&gt; The same MCP endpoint exposes &lt;code&gt;search-actors&lt;/code&gt;, &lt;code&gt;fetch-actor-details&lt;/code&gt;, and &lt;code&gt;call-actor&lt;/code&gt;, so an agent can discover and run any Actor without new configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No infrastructure.&lt;/strong&gt; The server is hosted. You add a few lines to a config file and you are done.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Actor we will use
&lt;/h2&gt;

&lt;p&gt;We will expose the &lt;a href="https://apify.com/scrapers_lat/singapore-gebiz-contracts-scraper" rel="noopener noreferrer"&gt;Singapore GeBIZ Government Contracts Scraper&lt;/a&gt;. It reads awarded tenders from GeBIZ and returns a structured record for each one: the tender number, the procuring agency, the awarded supplier, the awarded amount and currency, the award date, and the tender status. You can pull the newest awards, filter by a keyword like "software" or "cleaning" or "consultancy," and set a minimum award value to skip the small stuff.&lt;/p&gt;

&lt;p&gt;That field set is exactly what a market-research or capture team needs: who buys, who wins, and at what price. GeBIZ is a good first source because it is public, authoritative, and covers the whole of Singapore central government.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2bxlhzuoq908nnr5sydi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2bxlhzuoq908nnr5sydi.png" alt="The Singapore GeBIZ Government Contracts Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Get your Apify API token
&lt;/h2&gt;

&lt;p&gt;Sign in to the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt;, open &lt;strong&gt;Settings → Integrations&lt;/strong&gt;, and copy your personal API token. The MCP server uses it to authenticate and to bill Actor runs to your account.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; the token is a secret. Keep it in the client config only, never in a prompt or a committed file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Point Claude Desktop at the Apify MCP server
&lt;/h2&gt;

&lt;p&gt;Open Claude Desktop's config file (&lt;code&gt;Settings → Developer → Edit Config&lt;/code&gt;, or &lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&lt;/code&gt; on macOS) and add the Apify server. The &lt;code&gt;tools&lt;/code&gt; query parameter is the important part: it tells the server which Actor to expose, so Claude gets one focused tool instead of the entire Store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/singapore-gebiz-contracts-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cursor uses the same JSON in &lt;code&gt;.cursor/mcp.json&lt;/code&gt;. If you prefer to run it locally over stdio instead of the hosted endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@apify/actors-mcp-server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--tools"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scrapers_lat/singapore-gebiz-contracts-scraper"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"APIFY_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Claude Desktop so it picks up the new server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Confirm the tool is loaded
&lt;/h2&gt;

&lt;p&gt;After the restart, the Actor shows up as a callable tool. If you list the tools the Apify server exposes, you will see the storage helpers plus the Actor itself, named after its Store handle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get-actor-run, get-dataset-items, get-key-value-store-record,
abort-actor-run, scrapers_lat--singapore-gebiz-contracts-scraper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last entry, &lt;code&gt;scrapers_lat--singapore-gebiz-contracts-scraper&lt;/code&gt;, is our procurement tool. Claude now knows it exists, what it does (from the Actor's README), and what inputs it takes (from the input schema the server passes along).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Ask Claude about the market
&lt;/h2&gt;

&lt;p&gt;Now the payoff. In a normal chat, ask a question that requires ground truth:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We sell SaaS to the Singapore public sector. Pull recent GeBIZ software awards so I can see who's winning, which agency, and the contract values."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude recognizes it cannot answer this reliably from memory, selects the GeBIZ tool, and fills in the input from your question. Under the hood the client sends a &lt;code&gt;tools/call&lt;/code&gt; with the Actor's parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scrapers_lat--singapore-gebiz-contracts-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"searchQuery"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"software"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"maxContracts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sortByNewest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Apify MCP server starts the Actor, waits for it to finish, and returns the dataset. Here is the real run metadata it produced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"runId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yzPcUrUNdDn1pHyH6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actorName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scrapers_lat/singapore-gebiz-contracts-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SUCCEEDED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"startedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-30T17:47:24.601Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"finishedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-30T17:47:28.043Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stats"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"runTimeSecs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just over three seconds, live against the register.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Read the real output
&lt;/h2&gt;

&lt;p&gt;The dataset the tool returns is structured award data, one object per contract. This is an actual record from the run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tenderNo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WSG000ETT25000003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Provision of Public Cloud Integrated Training and Learning Management System (ITLMS) Software as a Service (SaaS)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"agency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Workforce Singapore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"supplier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AVEPOINT SINGAPORE PTE. LTD."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"awardedAmount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2177024.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SGD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"awardDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"16/5/2025"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"awardYear"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2025&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Awarded to Suppliers"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude reads that and answers in plain language: Workforce Singapore awarded a public-cloud learning-management SaaS contract to &lt;strong&gt;AvePoint Singapore&lt;/strong&gt; for &lt;strong&gt;S$2,177,024.50&lt;/strong&gt; in May 2025, under tender &lt;strong&gt;WSG000ETT25000003&lt;/strong&gt;. Every one of those facts is traceable to the register, not the model's memory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnxbwh8zk6mglo324jxj0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnxbwh8zk6mglo324jxj0.png" alt="Claude calling the GeBIZ tool and answering with live award data" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The value of the tool is in the set, not the single row. Across the same 25 awards you can see that Workforce Singapore is a repeat SaaS buyer, that award values cluster in the S$0.5M to S$5M band, and that incumbents such as ST Engineering Mission Software win, and re-win, similar iBPMS work over multiple years. That is a competitive map, assembled in one query, that a person would have paged through GeBIZ for an afternoon to build by hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  A real use case: a bid-qualification agent
&lt;/h2&gt;

&lt;p&gt;Put this in context. A capture manager at a SaaS vendor is deciding which Singapore government opportunities are worth pursuing this quarter. Before committing a bid team, they need to know:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;which agencies actually buy software in their category,&lt;/li&gt;
&lt;li&gt;what the winning contracts have been worth, and&lt;/li&gt;
&lt;li&gt;who the incumbent supplier is, because unseating one is a different bid than an open field.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without a tool, the analyst opens GeBIZ, searches a keyword, clicks into each award, and copies the agency, supplier, and value into a spreadsheet, one row at a time. With the tool wired into Claude, the analyst asks the agent to pull recent awards for a keyword, group them by agency, and rank suppliers by total value won. Claude calls the Actor, reasons over the returned dataset, and produces a short target list with an incumbent named against each agency. The manual paging disappears; the qualification call stays with the human.&lt;/p&gt;

&lt;p&gt;This is the shape of every good agent tool: it removes the mechanical fetch, not the decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going further: chain a second tool
&lt;/h2&gt;

&lt;p&gt;Knowing who won a contract is the first question. The obvious next one is "who exactly is that supplier?" The same MCP connection can expose more Actors by extending the &lt;code&gt;tools&lt;/code&gt; parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp.apify.com?tools=scrapers_lat/singapore-gebiz-contracts-scraper,scrapers_lat/singapore-acra-entities-scraper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the agent can pull an award from GeBIZ &lt;strong&gt;and&lt;/strong&gt; look the winning supplier up on the official Singapore ACRA corporate register in the same conversation, resolving "AVEPOINT SINGAPORE PTE. LTD." to its UEN, incorporation date, registered address, and current status. The result is a single briefing that ties a contract to a verified legal entity. Because each Actor is a separate tool, the agent picks the right one for each step on its own: GeBIZ for the award, ACRA for the company behind it.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;Troubleshooting:&lt;/strong&gt; if the tool does not appear in Claude, the two usual causes are a missing or misspelled Actor handle in the &lt;code&gt;tools&lt;/code&gt; parameter (it must be the exact &lt;code&gt;username/actor-name&lt;/code&gt; from the Store URL) and a config that was edited while Claude was running. Fix the handle, save, and fully restart the client.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; each tool call is a real Actor run billed to your Apify account (this Actor is pay-per-result). Award amounts are reported by the register in Singapore dollars, and some legacy records carry rounded or estimated values, so treat a single figure as an indicator and read the set for the trend. For a one-off market pull the cost is a fraction of a cent; if you plan to sweep every category on a schedule, run the Actor directly through the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API&lt;/a&gt; or a scheduled task instead of one call per chat message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;You now have an AI agent that can survey the Singapore government procurement market on demand, mid-conversation, with the agency, supplier, and contract-value detail a bid decision actually needs. The pattern is reusable: pick an Actor that returns authoritative structured data, expose it through the Apify MCP server with the &lt;code&gt;tools&lt;/code&gt; parameter, and let the agent decide when to call it.&lt;/p&gt;

&lt;p&gt;To take it further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change the &lt;code&gt;searchQuery&lt;/code&gt; to your own category, or set a minimum award value to focus on the contracts worth bidding.&lt;/li&gt;
&lt;li&gt;Chain the ACRA Actor to turn a winning supplier name into a verified company profile.&lt;/li&gt;
&lt;li&gt;Read the &lt;a href="https://docs.apify.com/platform/integrations/mcp" rel="noopener noreferrer"&gt;Apify MCP server docs&lt;/a&gt; for OAuth setup, resource reads, and the &lt;code&gt;search-actors&lt;/code&gt; / &lt;code&gt;call-actor&lt;/code&gt; tools that let an agent discover Actors it was not preconfigured with.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Actor used in this guide: &lt;a href="https://apify.com/scrapers_lat/singapore-gebiz-contracts-scraper" rel="noopener noreferrer"&gt;Singapore GeBIZ Government Contracts Scraper&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>api</category>
    </item>
    <item>
      <title>How to give Claude a Singapore healthcare-credential verification tool with the Apify MCP server</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:56:49 +0000</pubDate>
      <link>https://dev.to/scraperslat/how-to-give-claude-a-singapore-healthcare-credential-verification-tool-with-the-apify-mcp-server-3a2l</link>
      <guid>https://dev.to/scraperslat/how-to-give-claude-a-singapore-healthcare-credential-verification-tool-with-the-apify-mcp-server-3a2l</guid>
      <description>&lt;p&gt;AI agents are good at reasoning and terrible at facts. Ask Claude whether "Dr Alex Tanoto Lim" is a doctor registered to practise in Singapore, and it will give you a confident answer from its training data that may be months or years stale, or simply invented. For anything credentialing-related, "probably correct" is not good enough. A locum with a lapsed practising certificate, or a name that never appears on the register at all, is exactly the case you cannot afford to wave through.&lt;/p&gt;

&lt;p&gt;In this guide we fix that. We connect Claude to the &lt;strong&gt;official Apify MCP server&lt;/strong&gt;, expose a single Actor that reads Singapore's Ministry of Health (MOH) public register of healthcare professionals, and turn "is this clinician actually registered?" from a guess into a live lookup against the source of record. By the end you will have a working verification tool that Claude, Cursor, or any MCP client can call during a conversation, and you will understand exactly where in the run the tool fires and what it returns.&lt;/p&gt;

&lt;p&gt;Everything below is a real setup with real output. No mocked responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Apify MCP server?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;Model Context Protocol&lt;/a&gt; (MCP) is an open standard that lets AI clients call external tools. The &lt;strong&gt;Apify MCP server&lt;/strong&gt; (&lt;code&gt;https://mcp.apify.com&lt;/code&gt;) implements that standard on top of the Apify platform, which means every one of the thousands of Actors in the &lt;a href="https://apify.com/store" rel="noopener noreferrer"&gt;Apify Store&lt;/a&gt; becomes a tool an agent can invoke.&lt;/p&gt;

&lt;p&gt;Why route an Actor through MCP instead of hard-coding an API call?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The agent decides when to fetch.&lt;/strong&gt; Claude reads the conversation, notices it needs a fact it does not have, and calls the tool on its own. You do not write glue code for every question.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured input and output.&lt;/strong&gt; The MCP server hands Claude the Actor's input schema, so the model fills in the parameters correctly, and returns a clean dataset it can reason over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One connection, many tools.&lt;/strong&gt; The same MCP endpoint exposes &lt;code&gt;search-actors&lt;/code&gt;, &lt;code&gt;fetch-actor-details&lt;/code&gt;, and &lt;code&gt;call-actor&lt;/code&gt;, so an agent can discover and run any Actor without new configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No infrastructure.&lt;/strong&gt; The server is hosted. You add a few lines to a config file and you are done.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Actor we will use
&lt;/h2&gt;

&lt;p&gt;We will expose the &lt;a href="https://apify.com/scrapers_lat/singapore-moh-health-professionals-scraper" rel="noopener noreferrer"&gt;Singapore MOH Healthcare Professionals Register Scraper&lt;/a&gt;. It searches Singapore's MOH public register and returns the full record for a registered professional: full name, registration number, profession type and register, registration type and start date, practising certificate start and end dates, qualifications with awarding institution and year, and current place of practice.&lt;/p&gt;

&lt;p&gt;MOH is the authority behind the professional boards that register clinicians in Singapore, covering doctors (SMC), dentists (SDC), nurses and midwives (SNB), pharmacists (SPC), and traditional Chinese medicine practitioners (TCMPB). That field set is exactly what a credentialing, panel-onboarding, or insurer network-admission check needs. Singapore is a useful jurisdiction because the register is public, authoritative, and has no login wall.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmdh71c7vk8rmyniz9c14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmdh71c7vk8rmyniz9c14.png" alt="The Singapore MOH Healthcare Professionals Register Scraper on the Apify Store" width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Get your Apify API token
&lt;/h2&gt;

&lt;p&gt;Sign in to the &lt;a href="https://console.apify.com" rel="noopener noreferrer"&gt;Apify Console&lt;/a&gt;, open &lt;strong&gt;Settings → Integrations&lt;/strong&gt;, and copy your personal API token. The MCP server uses it to authenticate and to bill Actor runs to your account.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; the token is a secret. Keep it in the client config only, never in a prompt or a committed file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Point Claude Desktop at the Apify MCP server
&lt;/h2&gt;

&lt;p&gt;Open Claude Desktop's config file (&lt;code&gt;Settings → Developer → Edit Config&lt;/code&gt;, or &lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&lt;/code&gt; on macOS) and add the Apify server. The &lt;code&gt;tools&lt;/code&gt; query parameter is the important part: it tells the server which Actor to expose, so Claude gets one focused tool instead of the entire Store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.apify.com?tools=scrapers_lat/singapore-moh-health-professionals-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cursor uses the same JSON in &lt;code&gt;.cursor/mcp.json&lt;/code&gt;. If you prefer to run it locally over stdio instead of the hosted endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"apify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@apify/actors-mcp-server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--tools"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scrapers_lat/singapore-moh-health-professionals-scraper"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"APIFY_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_APIFY_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Claude Desktop so it picks up the new server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Confirm the tool is loaded
&lt;/h2&gt;

&lt;p&gt;After the restart, the Actor shows up as a callable tool. If you list the tools the Apify server exposes, you will see the storage helpers plus the Actor itself, named after its Store handle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get-actor-run, get-dataset-items, get-key-value-store-record,
abort-actor-run, scrapers_lat--singapore-moh-health-professionals-scraper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last entry, &lt;code&gt;scrapers_lat--singapore-moh-health-professionals-scraper&lt;/code&gt;, is our verification tool. Claude now knows it exists, what it does (from the Actor's README), and what inputs it takes (from the input schema the server passes along).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Ask Claude to verify a professional
&lt;/h2&gt;

&lt;p&gt;Now the payoff. In a normal chat, ask a question that requires ground truth:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A locum doctor named 'Alex Tanoto Lim' is applying to join our clinic panel. Confirm he's on Singapore's MOH register, and give me his registration number, qualification, and whether his practising certificate is currently valid."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude recognizes it cannot answer this reliably from memory, selects the MOH tool, and fills in the input from your question. Under the hood the client sends a &lt;code&gt;tools/call&lt;/code&gt; with the Actor's parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scrapers_lat--singapore-moh-health-professionals-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"council"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"doctors"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"searchName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"withDetails"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Apify MCP server starts the Actor, waits for it to finish, and returns the dataset. Here is the real run metadata it produced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"runId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vP5udmMb50cVuwGe1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actorName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scrapers_lat/singapore-moh-health-professionals-scraper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SUCCEEDED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"startedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-30T17:47:20.805Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"finishedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-30T17:47:31.987Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stats"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"runTimeSecs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;11.2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eleven seconds, live against the MOH register.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Read the real output
&lt;/h2&gt;

&lt;p&gt;The dataset the tool returns is structured register data. This is an actual record from the run (trimmed to the fields that matter for credentialing):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ALEX TANOTO LIM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"registrationNo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"M66411A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"professionType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Doctor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typeOfRegister"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Medical Practitioner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"registrationType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Full Registration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"registrationStartDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"27/04/2021"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"practisingCertStartDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"01/01/2025"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"practisingCertEndDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"31/12/2026"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"qualifications"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"qualification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MBBS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"institution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NTU-Imperial College London, Singapore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2020"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"placesOfPractice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TAN TOCK SENG HOSPITAL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"11 JALAN TAN TOCK SENG Singapore 308433"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"council"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SMC"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude reads that and answers in plain language: yes, Alex Tanoto Lim holds registration number &lt;strong&gt;M66411A&lt;/strong&gt; on the Singapore Medical Council register, with &lt;strong&gt;Full Registration&lt;/strong&gt;, an MBBS from NTU-Imperial College London (Singapore, 2020), and a practising certificate valid from 01/01/2025 through &lt;strong&gt;31/12/2026&lt;/strong&gt;, so he is cleared to practise today. His listed place of practice is Tan Tock Seng Hospital. Every one of those facts is traceable to the official register, not the model's memory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhe7tq3rbguovt9ak7ztk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhe7tq3rbguovt9ak7ztk.png" alt="Claude calling the MOH register tool and answering with live credential data" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The counter-example is just as important. Suppose the applicant's name returns no match, or returns a record whose &lt;code&gt;practisingCertEndDate&lt;/code&gt; has already passed. A doctor can be validly &lt;em&gt;registered&lt;/em&gt; yet not hold a current practising certificate, which means they are not cleared to see patients. An agent doing credentialing needs to see that distinction, and the practising-certificate dates surface it directly. The tool shows the gap; the model alone would not.&lt;/p&gt;

&lt;h2&gt;
  
  
  A real use case: a credentialing intake agent
&lt;/h2&gt;

&lt;p&gt;Put this in context. A clinic network, a telehealth platform, or an insurer's provider-network team is onboarding clinicians and needs to confirm, before granting panel access or network admission, that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the named professional is actually on the MOH register,&lt;/li&gt;
&lt;li&gt;their registration type is appropriate (full versus conditional or provisional), and&lt;/li&gt;
&lt;li&gt;their practising certificate is current, not lapsed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without a tool, an intake officer opens the MOH website, selects the right board, types the name, opens the matching record, and copies fields into a credentialing form, once per applicant. With the tool wired into Claude, the officer pastes the applicant list into the chat and asks the agent to verify each one. Claude calls the Actor per name, reads back the registration number and register, checks the &lt;code&gt;practisingCertEndDate&lt;/code&gt; against today, flags anyone whose certificate has expired or who does not appear at all, and produces a short pass/refer note with the registration number as evidence. The manual lookup step disappears; the judgment stays with the human.&lt;/p&gt;

&lt;p&gt;This is the shape of every good agent tool: it removes the mechanical fetch, not the decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going further: chain a second tool
&lt;/h2&gt;

&lt;p&gt;Credentialing rarely stops at the individual clinician. You often need to confirm the &lt;em&gt;practice&lt;/em&gt; that employs or engages them is a real, live Singapore entity too. The same MCP connection can expose more Actors by extending the &lt;code&gt;tools&lt;/code&gt; parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp.apify.com?tools=scrapers_lat/singapore-moh-health-professionals-scraper,scrapers_lat/singapore-acra-entities-scraper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the agent can verify the clinician on the MOH register &lt;strong&gt;and&lt;/strong&gt; confirm the employing clinic or medical group on the &lt;a href="https://apify.com/scrapers_lat/singapore-acra-entities-scraper" rel="noopener noreferrer"&gt;Singapore ACRA Company Registry Scraper&lt;/a&gt; in the same conversation, pulling the entity's UEN, status, and registered address, then combine both results into one onboarding summary. Because each Actor is a separate tool, the agent picks the right one for each step on its own: MOH for the person, ACRA for the corporate entity behind them.&lt;/p&gt;

&lt;p&gt;🏹 &lt;strong&gt;Troubleshooting:&lt;/strong&gt; if the tool does not appear in Claude, the two usual causes are a missing or misspelled Actor handle in the &lt;code&gt;tools&lt;/code&gt; parameter (it must be the exact &lt;code&gt;username/actor-name&lt;/code&gt; from the Store URL) and a config that was edited while Claude was running. Fix the handle, save, and fully restart the client.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt; each tool call is a real Actor run billed to your Apify account (this Actor is pay-per-result). Search by a specific surname and set the profession (&lt;code&gt;council&lt;/code&gt;) so the run returns the record you want rather than a broad list. For one-off verification the cost is a fraction of a cent; if you plan to verify thousands of professionals on a schedule, run the Actor directly through the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API&lt;/a&gt; or a scheduled task instead of one call per chat message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;You now have an AI agent that can verify a Singapore healthcare professional against the official MOH register, on demand, mid-conversation, with the registration number, register type, qualification, and practising-certificate validity a credentialing check actually needs. The pattern is reusable: pick an Actor that returns authoritative structured data, expose it through the Apify MCP server with the &lt;code&gt;tools&lt;/code&gt; parameter, and let the agent decide when to call it.&lt;/p&gt;

&lt;p&gt;To take it further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Switch the &lt;code&gt;council&lt;/code&gt; input to check dentists, nurses, pharmacists, or TCM practitioners with the same tool.&lt;/li&gt;
&lt;li&gt;Add the ACRA company registry, sanctions, or licensing Actors to build a multi-step provider-onboarding agent.&lt;/li&gt;
&lt;li&gt;Read the &lt;a href="https://docs.apify.com/platform/integrations/mcp" rel="noopener noreferrer"&gt;Apify MCP server docs&lt;/a&gt; for OAuth setup, resource reads, and the &lt;code&gt;search-actors&lt;/code&gt; / &lt;code&gt;call-actor&lt;/code&gt; tools that let an agent discover Actors it was not preconfigured with.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Actor used in this guide: &lt;a href="https://apify.com/scrapers_lat/singapore-moh-health-professionals-scraper" rel="noopener noreferrer"&gt;Singapore MOH Healthcare Professionals Register Scraper&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>apify</category>
      <category>healthcare</category>
    </item>
  </channel>
</rss>
