# FeedHound - RSS Feed Finder, Reader & Health Check (`abusch500/feedhound-rss-feed-finder`) Actor

Give it a website and it finds the RSS, Atom, RDF and JSON feeds behind it, checks that each one really works, and returns the posts in one clean shape. Podcast tags included. You never need to know the feed URL. A site with no working feed is never charged for.

- **URL**: https://apify.com/abusch500/feedhound-rss-feed-finder.md
- **Developed by:** [Alex Busch](https://apify.com/abusch500) (community)
- **Categories:** Developer tools, Automation, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$20.00 / 1,000 website or feed checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## FeedHound - RSS Feed Finder, Reader & Health Check

![FeedHound](https://api.apify.com/v2/key-value-stores/c5wow5LQjb4XACmkM/records/cover.png)

**Give it a website. It gives you the feeds.** Paste `bbc.co.uk/news` or
`stripe.com/blog` or just `someblog.com` and FeedHound finds the RSS, Atom, RDF
and JSON feeds behind it, checks that each one actually works, and returns the
posts. You get **36 fields about the feed, a 31-field health report, and 15
fields on every post** - all four feed formats flattened into one identical
shape.

**$0.02 per website or feed URL checked.** That is the whole price. Not per
feed, not per post: a site with five feeds and 500 posts costs the same two
cents as a site with one. **A site where no feed with posts was found costs
$0.00.** There is no platform charge on top.

The feed tools on this store start by asking you for the feed URL. That is the
part nobody knows.

***

### 🔎 What makes this different

**1. You do not need the feed address.** FeedHound reads the page's own
`<link rel="alternate">` tags, follows footer links, applies a rule for
platforms that hide their feeds, and - only if a site advertises nothing at all

- tries up to 14 standard addresses. On 45 real blogs, news sites and podcasts,
  **80% gave up at least one feed**, and **9% of those feeds were found only by
  guessing the address**, which a tool that only reads the page's link tags would
  miss.

**2. It tells you whether the feed actually works.** This is the half that
does not exist anywhere else. A feed can return HTTP 200, parse perfectly, and
still be broken in ways no reader shows you:

| What FeedHound catches | Why it matters | Seen in the 57 feeds tested |
|---|---|---|
| Stale or abandoned | You are monitoring a dead source | **9 of 57.** Quanta Magazine still advertises a feed whose last post was **4,802 days ago** |
| Missing or illegal dates | Nothing can be sorted newest-first | **1 of 57.** Google's own developer blog: **20 of 20 posts have no date** |
| The feed parses but is empty | Looks alive, delivers nothing | **2 of 57**, including GitHub's own comments feed |
| The advertised link has gone stale | The `<link>` tag points at an address that has moved | 0 of 57 |
| Duplicate item IDs | Every reader shows the same post twice | 0 of 57 |
| Relative links (`/post/1`) | The link opens nothing in a reader | 0 of 57 |
| Served as `text/html` | Some readers refuse the feed outright | 0 of 57 |

Those zeros are the honest result on 57 mostly well-run feeds, printed rather
than hidden. The point of the report is what happens when one of them is not
zero: the row says so, in plain English, and nothing else on this store will
tell you.

**3. It never guesses on a site that said no.** Every address FeedHound asks
for - including the guesses - is checked against the `robots.txt` of the host
that serves it, before it is fetched. Redirects are followed the way a browser
follows them, and the host it lands on gets its policy read too. GitHub bans
`/*.atom` and YouTube bans `/feeds/videos.xml`, so FeedHound will not read those
and tells you exactly why instead of quietly scraping them anyway.

**4. Four formats, one shape.** RSS 2.0, Atom, RSS 1.0 (RDF) and JSON Feed all
come back with the same field names. Dates are normalised to ISO 8601 -
including the RFC 822 timezone names (`EST`, `CEST`) that most parsers drop, and
including a date with no timezone at all, which is pinned to UTC so the same
feed never yields two different timestamps.

**5. The best feed is first.** When a site has several, they are ranked and the
live one is `rank: 1`. Quanta Magazine's page advertises an abandoned 2013 feed
*before* its real one; take the first row from any other tool and you get the
dead one.

***

### 📋 What comes back

One row per feed found. One charge per source, however many feeds that is.

#### About the feed

| Field | What it is | Blogs & news | Ordinary business sites |
|---|---|---|---|
| `feedUrl` | The working feed address, after redirects | 100% | 100% |
| `feedTitle` | The feed's own title | 98% | 100% |
| `feedType` | `rss`, `atom`, `rdf` or `json` | 100% | 100% |
| `feedVersion` | e.g. `2.0`, `1.1` | 100% | 100% |
| `discoveredVia` | `direct`, `autodiscovery`, `page-link`, `common-path` or `platform:*` | 100% | 100% |
| `rank` / `isPrimary` | Which of this site's feeds is the live one | 100% | 100% |
| `description` | The feed's own description | 91% | 63% |
| `siteUrl` | The website the feed belongs to | 100% | 100% |
| `language` | e.g. `en-gb` | 77% | 63% |
| `imageUrl` | Feed logo or cover art | 45% | 25% |
| `generator` | WordPress, Ghost, Hugo, Squarespace... | 52% | 50% |
| `categories` | Feed-level tags | 11% | 0% |
| `hubUrl` | WebSub hub, if the feed supports push | 2% | 0% |
| `itemCount` | Posts in the feed | 100% | 100% |
| `lastItemAt` | Date of the newest post | 95% | 88% |
| `daysSinceLastItem` | How quiet it has gone | 95% | 88% |
| `postsPerMonth` | Real publishing cadence from the item dates | 93% | 88% |
| `isPodcast`, `podcastAuthor`, `episodeCount` | Apple podcast tags, only when there is real audio | 5 podcasts found | 0 |
| `feedsFoundForSource` | How many feeds this one source had | 100% | 100% |
| `candidatesChecked` | How many addresses were tried | 100% | 100% |
| `robotsRespected`, `crawlDelaySecs` | The policy that was obeyed | 100% | 100% |

#### The health report (`health`, 31 fields)

`score` 0-100 · `verdict` (healthy / minor issues / needs attention / empty /
broken) · `issues` (defects, in plain English) · `notes` (facts that are not
faults) · `moved` · `requestedUrl` · `finalUrl` · `httpStatus` · `contentType` ·
`contentTypeOk` · `secure` · `sizeBytes` · `truncated` · `responseMs` ·
`itemCount` · `itemsMissingDate` · `itemsWithUnparseableDate` ·
`itemsMissingLink` · `itemsMissingTitle` · `itemsMissingGuid` ·
`duplicateGuids` · `duplicateTitles` · `itemsWithRelativeLink` ·
`itemsWithInsecureLink` · `fullContentRatio` · `firstItemAt` · `lastItemAt` ·
`daysSinceLastItem` · `postsPerMonth` · `stale` · `dormant`

#### Every post (`items`, 15 fields each)

`title` · `link` · `guid` · `publishedAt` · `updatedAt` · `author` · `summary`
(plain text, always) · `contentHtml` (markup kept) · `contentChars` (length of
that markup) · `textChars` (length of the text inside it) · `categories` ·
`imageUrl` · `enclosure` (url, type, size) · `durationSecs` · `commentsUrl`

***

### ⚙️ How to use it

1. Paste your list into **Websites or feed URLs**. Bare domains
   (`arstechnica.com`), sections (`stripe.com/blog`) and feed URLs
   (`https://news.ycombinator.com/rss`) can all be mixed in one run.
2. Leave everything else alone. The defaults are 5 feeds and 50 posts per
   source.
3. Press **Start**.
4. Take **Feed health table (CSV)** for the one-row-per-feed spreadsheet, or
   **Every post, one per row (CSV)** for the posts.

**Speed, measured:** 45 blogs and news sites took 42 seconds at 8 at a time -
1.8 seconds per source. Ordinary business sites average 2.9 seconds each,
because having no feed means every standard address gets tried. At the default
5 at a time, a 50-site list of ordinary businesses takes about 30 seconds.

***

### 💵 Pricing

| | |
|---|---|
| Per source where a feed with posts was found | **$0.02** |
| Per feed found on that site | $0.00 |
| Per post returned | $0.00 |
| A source with no feed, or only an empty one | **$0.00** |
| Apify platform usage on top | **$0.00** |

| Your list | You pay |
|---|---|
| 10 sites | $0.20 |
| 100 sites | $2.00 |
| 1,000 sites | $20.00 |

The nearest alternative on this store charges **$0.035 per run plus about
$0.001 per post** - $0.00115 on the free plan, less on the largest paid ones
(its live pricing, checked 2026-09-03) - and requires you to already know every
feed URL. One site with 100 posts costs $0.135 there and $0.02 here, and here
you did not have to know the address.

***

### 📄 Example output

A real row, saved in full at `examples/example-row.json`:

```json
{
  "source": "github.blog",
  "ok": true,
  "rank": 1,
  "isPrimary": true,
  "discoveredVia": "autodiscovery",
  "feedUrl": "https://github.blog/feed/",
  "feedTitle": "The GitHub Blog",
  "feedType": "rss",
  "feedVersion": "2.0",
  "siteUrl": "https://github.blog/",
  "description": "Updates, ideas, and inspiration from GitHub to help developers build and design software.",
  "language": "en-us",
  "generator": "WordPress 7.1",
  "itemCount": 10,
  "lastItemAt": "2026-09-02T21:00:00.000Z",
  "daysSinceLastItem": 0,
  "postsPerMonth": 14.06,
  "healthScore": 100,
  "verdict": "healthy",
  "issues": [],
  "notes": ["items carry the full post, not just a summary"],
  "candidatesChecked": 3,
  "robotsRespected": true,
  "items": [
    {
      "title": "Decoding the new AI lingo: Loops, harnesses, squads, hill climbing… oh my!",
      "link": "https://github.blog/ai-and-ml/decoding-the-new-ai-lingo-loops-harnesses-squads-hill-climbing-oh-my/",
      "publishedAt": "2026-09-02T21:00:00.000Z",
      "author": "Cassidy Williams",
      "summary": "From loop engineering to harnesses, squads, and open weights, the GitHub Podcast breaks down the AI terms showing up in developer conversations. The post Decoding the new AI lingo: Loops, harnesses, squads, hill climbing… oh my! appeared first on The GitHub Blog.",
      "contentChars": 9150,
      "textChars": 6403
    }
  ]
}
```

And two feeds with a real problem, from the same run:

```json
{
  "source": "developers.googleblog.com",
  "feedTitle": "Google Developers Blog",
  "healthScore": 80,
  "verdict": "minor issues",
  "issues": ["20 of 20 items have no date, so readers cannot sort them"]
}
{
  "source": "quantamagazine.org",
  "feedTitle": "Quanta Magazine - Illuminating science",
  "isPrimary": false,
  "daysSinceLastItem": 4802,
  "healthScore": 70,
  "verdict": "needs attention",
  "issues": ["no new item for 4802 days - this feed looks abandoned"]
}
```

That second one is `rank: 2`. Quanta's page lists it *first*; the live feed is
the row you get at `rank: 1`.

***

### 🎯 What people use it for

- **Building a reader, aggregator or newsletter.** Hand it 500 sites, get back
  every feed plus every post, in one shape, without writing four parsers.
- **Competitor and category monitoring.** Which of these 200 companies still
  publishes, how often, and when did they last post?
- **Auditing your own feeds.** Ship a feed with duplicate GUIDs or no dates and
  nobody tells you. This does.
- **Podcast directories.** Apple's `itunes:` tags, episode counts, enclosure
  URLs and durations, only flagged as a podcast when there is real audio.
- **Cleaning an old OPML or subscription list.** Which of these 300 feeds are
  dead, which are empty, which are still worth polling?

***

### 💻 Run it from code

**JavaScript**

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('abusch500/feedhound-rss-feed-finder').call({
    sources: ['arstechnica.com', 'stripe.com/blog', 'https://news.ycombinator.com/rss'],
    maxItemsPerFeed: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("abusch500/feedhound-rss-feed-finder").call(run_input={
    "sources": ["arstechnica.com", "stripe.com/blog"],
    "maxItemsPerFeed": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["feedUrl"], item["healthScore"], item["issues"])
```

**curl**

```bash
curl -X POST "https://api.apify.com/v2/acts/abusch500~feedhound-rss-feed-finder/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"sources":["arstechnica.com"],"maxItemsPerFeed":10}'
```

**n8n / Make / Zapier** - use the Apify app's "Run an Actor" step, pick this
actor, and map `sources` to your list column.
**MCP** - available through Apify's MCP server as
`abusch500/feedhound-rss-feed-finder`.

***

### 🎛️ Input

| Field | Default | What it does |
|---|---|---|
| `sources` | required | Websites, sections or feed URLs, one per line |
| `maxFeedsPerSource` | 5 | Most feeds to return per source. Raising it costs nothing extra |
| `maxItemsPerFeed` | 50 | Posts per feed. `0` returns feed details and health only |
| `includeItems` | true | Turn off for a smaller result |
| `probeCommonPaths` | true | Guess standard addresses, but only when a site advertises none |
| `maxConcurrency` | 5 | Sources at a time. Requests to one site are always spaced out |
| `requestTimeoutSecs` | 20 | Per request |
| `respectRobotsTxt` | true | Leave it on unless you own every site in the list |

***

### 🌐 Where the data comes from

| Source | What is read |
|---|---|
| The page you named | `<link rel="alternate">` tags and footer links |
| `robots.txt` | Of every host that serves an address, checked before it is fetched |
| The feed itself | The publisher's own RSS / Atom / RDF / JSON Feed document |
| Platform feed rules | Medium, Substack, Blogger and Shopify publish feeds at fixed addresses |

Nothing behind a login, a paywall or a cookie wall is touched, and no page is
crawled: FeedHound reads the address you gave it plus, at most, a short list of
standard feed addresses on the same site. **Every address it asks for -
including the guesses - is checked against the `robots.txt` of the host that
serves it, before it is fetched.** Redirects are followed the way a browser
follows them, and the host they land on gets its policy read too.
**`Crawl-delay` is obeyed** - per host, and a site asking for more than 2
seconds between requests gets no address guessing at all, only what it
advertises itself. The `Obey robots.txt` switch exists for your own domains.

***

### 🤖 For site owners

FeedHound identifies itself as:

```
FeedHoundBot/0.1 (+https://apify.com/abusch500/feedhound-rss-feed-finder; finds and validates public RSS/Atom/JSON feeds)
```

To block it, add this to your `robots.txt`:

```
User-agent: FeedHoundBot
Disallow: /
```

It will then be skipped, and the person who ran it is not charged. A typical
visit is **3 requests** - `robots.txt`, your page, your feed - and at most about
**17** if your site advertises no feed at all: `robots.txt`, your page, and up
to 14 standard addresses. A feed found by guessing stops the guessing there.

***

### ❓ FAQ

**I already know my feed URL. Is this still worth it?**
Then you are paying $0.02 for the health report and the normalised posts. If
all you want is items from a feed URL you already have, a plain feed reader is
cheaper.

**Why did it find no feed on my site?**
Most sites genuinely have none. Of 20 ordinary business and product sites -
Figma, Notion, Atlassian, Mailchimp, Webflow, Basecamp among them - **8 had a
feed, and 7 of those had posts in it**. You are not charged for the other 13.

**What does the health score mean?**
100 is a feed with no defects. Points come off for things that break a reader:
no items (0 outright), missing or unparseable dates, missing links, relative
links, missing or duplicate IDs, missing titles, a feed that has gone quiet for
much longer than usual, a wrong content type, plain http, and an advertised
link that has gone stale. Choices that are not defects - summaries instead of
full text, a declared poll interval, a feed served through a podcast host - go
in `notes` and cost nothing.

**What does `verdict: empty` mean, and am I charged for it?**
The feed is real and works; there is just nothing in it yet. GitHub's own
comments feed is one. You are **not** charged for a source whose only feeds are
empty, and the row still comes back, because "this one is dead" is exactly what
you want when you are cleaning a subscription list.

**Why is `issues` empty but `notes` full?**
Because they are different things. `issues` are faults. `notes` are facts worth
knowing about a feed that is working correctly.

**Why won't it read a GitHub or YouTube feed?**
Both explicitly disallow them: GitHub's `robots.txt` bans `/*.atom` and
YouTube's bans `/feeds/videos.xml`. FeedHound obeys that and says so in the
`error` column rather than fetching anyway.

**Does it follow redirects?**
Yes, and it tells you which kind. A redirect to `https` or to `www` on the same
path is a note. A guessed address resolving to the real one is a note - the
address you get back in `feedUrl` is always the working one. A feed served
through another host (a podcast on Megaphone or Libsyn, say) is a note, because
that is how the publisher meant it. Only an address you gave it, or a `<link>`
tag on the page, pointing somewhere that has actually moved is reported as a
problem.

**My blog only posts a few times a year. Will it be called stale?**
No. "Quiet" is measured against that feed's own rhythm - three times its usual
gap between posts, and never sooner than 90 days. A feed that posts quarterly
and last posted four months ago scores 100. After a full year with nothing, any
feed is called abandoned.

**Some sites return 403. Why?**
A minority of large publishers block automated clients outright, whoever is
asking. 2 of 45 did in testing, and that test ran from a home connection - this
actor runs from a datacenter, where the rate is higher. Those rows come back
with the reason and are **not charged**. If a site refuses the guessed
addresses, the row says the site refused rather than claiming there is no feed.

**Does it work with podcasts?**
Yes. Apple's `itunes:` tags, episode counts, audio URLs and durations. A feed is
only labelled a podcast when it has both the namespace and real audio
enclosures - plenty of ordinary blogs carry `itunes:` tags from a plugin, and
calling those podcasts would be a lie.

**What about JSON Feed?**
Fully supported, including `application/json` as the content type, which the
spec allows and most publishers use.

**How fresh is the data?**
It is fetched live at the moment you run it. Nothing is cached.

**Can it find every feed on a site?**
No tool can. It finds the ones the site advertises, the ones its platform
publishes at a known address, and the ones sitting at a standard address. A feed
at `/nature.rss` with nothing linking to it will be missed.

**Will it hammer my site?**
No. Requests to one host are serialised and spaced by that host's declared
`Crawl-delay`, no matter how high `maxConcurrency` is set.

**What is the biggest feed it can read?**
8 MB. Beyond that it reads what it can and says `truncated: true` rather than
pretending it saw everything, and a note says how many posts it did see. One
feed of the 57 in testing hit this - a podcast archive with 868 episodes - and
it is not counted as a defect, because it is our limit and not the
publisher's.

**Can I get the posts as one row each?**
Yes - the **Every post, one per row (CSV)** output link does exactly that.

***

### ⚠️ Notes and limits

- **2 of 45** large publishers answered 403 in testing, from a home
  connection. Expect somewhat more from a datacenter IP, which is where this
  actor runs. Never charged.
- **Ordinary business sites usually have no feed** - 12 of 20 had none in
  testing. Point this at blogs, news, docs and podcasts, where 80% had one.
- Path guessing tries at most 14 addresses, only when a site advertises none,
  and stops at the first one that answers with posts.
- The health report is calculated on **every** post in the feed - up to 2,000
  posts, or the first 8 MB - even when you ask for fewer back.
- Feeds are de-duplicated: `/feed`, `/feed/`, `/rss` and `/?feed=rss2` on a
  default WordPress install are one feed, and come back once.

***

### 📮 Support and changelog

Something missed or a health flag that looks wrong? Open an issue on the actor
page with the URL - missed sites become test cases.

**0.1** (2026-09-04) - first release. Feed discovery from a website URL,
RSS 2.0 / Atom / RSS 1.0 (RDF) / JSON Feed parsing, the 31-field health report,
podcast tags, robots.txt enforced per host on every request including guesses.
159 automated tests. Verified against 75 real sources.

# Actor input Schema

## `sources` (type: `array`):

One per line. A website (bbc.com), a section (bbc.com/news), or a feed URL you already have - all three work. If you give a website, FeedHound finds its feeds for you.

## `maxFeedsPerSource` (type: `integer`):

Many sites publish several feeds - all posts, one per category, a podcast. The price is per source, not per feed, so raising this costs nothing extra.

## `maxItemsPerFeed` (type: `integer`):

How many posts come back in each row. Set it to 0 for feed details and health only. The health report is always calculated on every post in the feed, not just the ones returned.

## `includeItems` (type: `boolean`):

Leave this on to get the posts themselves. Turn it off for a smaller result when you only want to know which feeds exist and whether they are healthy.

## `probeCommonPaths` (type: `boolean`):

Tries the standard addresses (/feed, /rss, /index.xml and a few more) only when a site links to no feed at all. Every guess still obeys that site's robots.txt.

## `maxConcurrency` (type: `integer`):

How many sources to work through in parallel. Requests to the same site are always spaced out no matter what this is set to.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for each request before giving up. Raise it for slow sites, lower it to move faster through a big list.

## `respectRobotsTxt` (type: `boolean`):

Leave this on. It is the reason this actor is safe to point at sites you do not own. Turn it off only for your own domains.

## Actor input object example

```json
{
  "sources": [
    "blog.cloudflare.com"
  ],
  "maxFeedsPerSource": 5,
  "maxItemsPerFeed": 50,
  "includeItems": true,
  "probeCommonPaths": true,
  "maxConcurrency": 5,
  "requestTimeoutSecs": 20,
  "respectRobotsTxt": true
}
```

# Actor output Schema

## `feeds` (type: `string`):

One row per feed found, with its details, its health report and its posts.

## `healthCsv` (type: `string`):

One row per feed, no posts: address, type, post count, last post, posts per month, health score, verdict and the problems found. Opens straight in a spreadsheet.

## `postsCsv` (type: `string`):

The posts flattened out of the feeds, one post per row, for dropping into a spreadsheet or a database.

## `summary` (type: `string`):

How many sources had feeds, how many did not, how many feeds have problems, and how many sources were charged for.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "sources": [
        "blog.cloudflare.com",
        "https://news.ycombinator.com/rss",
        "github.blog"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("abusch500/feedhound-rss-feed-finder").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "sources": [
        "blog.cloudflare.com",
        "https://news.ycombinator.com/rss",
        "github.blog",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("abusch500/feedhound-rss-feed-finder").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "sources": [
    "blog.cloudflare.com",
    "https://news.ycombinator.com/rss",
    "github.blog"
  ]
}' |
apify call abusch500/feedhound-rss-feed-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abusch500/feedhound-rss-feed-finder"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/CrBn79uryqJ337uqb/builds/iJbAILOLfoHppQS0a/openapi.json
