Small-web feed directory (rssamp.com)
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Say that an author in this directory is you, so you can correct the profile. Verified on the spot, no reviewer: the email behind your credential matches the address the author published about themselves, or the author's own site links back at the profile with rel="openprofile" or rel="me". Needs a credential in the Authorization header: an rssamplifier API key, or an OpenAccess bearer for `openprofile:edit`.
The author's slug.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http rssamplifier https://rssamp.com/api/mcp
Say that an author in this directory is you, so you can correct the profile. Verified on the spot, no reviewer: the email behind your credential matches the address the author published about themselves, or the author's own site links back at the profile with rel="openprofile" or rel="me". Needs a credential in the Authorization header: an rssamplifier API key, or an OpenAccess bearer for `openprofile:edit`.
| Argument | Type | Description |
|---|---|---|
| slug* | string | The author's slug. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "The author's slug."
}
}
}Register an https URL to receive your alerts as signed POSTs (CloudEvents body, Standard Webhooks signature headers, plus x-rssamplifier-signature: sha256=<hex HMAC of the body>). Returns the endpoint and its signing secret (whsec_...), shown here once. Needs one of your rssamplifier API keys in the Authorization header (Bearer rsa_..., from /account).
| Argument | Type | Description |
|---|---|---|
| url* | string | https URL that resolves to a public address. |
| events | array | Event patterns; default ["*"]. The one event is posts.published. |
| description | string | What it is, for your own list. |
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"description": "https URL that resolves to a public address."
},
"events": {
"type": "array",
"items": {
"type": "string"
},
"description": "Event patterns; default [\"*\"]. The one event is posts.published."
},
"description": {
"type": "string",
"description": "What it is, for your own list."
}
}
}Delete an endpoint and its delivery log. Needs one of your rssamplifier API keys in the Authorization header (Bearer rsa_..., from /account).
| Argument | Type | Description |
|---|---|---|
| id* | string | The webhook endpoint id (wh_...), from list_webhooks. |
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "The webhook endpoint id (wh_...), from list_webhooks."
}
}
}How big the directory is, what it is made of, and whether the crawler is keeping up. `stale` is active feeds not read successfully in a day; `due` is a backlog that should drain within a tick or two. Answer this before concluding a feed is missing — it may simply not have been crawled yet.
No arguments.
{
"type": "object",
"properties": {}
}One person: where to find them, and everything in the directory they publish. The feed list is what settles whether two people with the same name are the same person.
| Argument | Type | Description |
|---|---|---|
| slug* | string | The author's slug in this directory. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "The author's slug in this directory."
}
}
}One blog or podcast: its metadata, who writes it, where it can be found elsewhere, the topics it is filed under — including the ones no other feed shares — and its recent posts. `authors` is people; `links` is the blog's own accounts, which is what an unsigned blog has instead. Each post carries the feed slug and guid that read_post takes. Use the slug from search or list_feeds, not the site's own URL.
| Argument | Type | Description |
|---|---|---|
| slug* | string | The feed's slug in this directory. |
| limit | integer | Posts. Default 50. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "The feed's slug in this directory."
},
"limit": {
"type": "integer",
"maximum": 200,
"minimum": 1,
"description": "Posts. Default 50."
}
}
}RSSAmp's weekly email: when it goes (day and hour, UTC), the next send, how many accounts are on it, and the latest issue as sent (subject and text). Every account is on it unless it opted out.
No arguments.
{
"type": "object",
"properties": {}
}The person as a portable profile file (logicsrc.com/openprofile): identity block, Accounts, Topics, a Broadcast section (logicsrc.com/openbroadcast) for every show they publish, corrected by the person once they have claimed it. Returns the Markdown and the parsed sections. Pass either the author's slug or a feed URL; with a feed URL you get the profile of the feed's owner.
| Argument | Type | Description |
|---|---|---|
| feed | string | A feed URL; the owner of that feed is looked up. |
| slug | string | The author's slug in this directory. |
{
"type": "object",
"properties": {
"feed": {
"type": "string",
"description": "A feed URL; the owner of that feed is looked up."
},
"slug": {
"type": "string",
"description": "The author's slug in this directory."
}
}
}A ring's members in ring order, each with its site, feed, status (active, pending or inactive) and, where the site declared them, made_by and disclosure. The same document as /ring/<slug>/openwebring.json. Use ring_next to follow a hop rather than computing one from this list.
| Argument | Type | Description |
|---|---|---|
| slug* | string | The ring slug, from list_rings. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "The ring slug, from list_rings."
}
}
}Every feed filed under one topic. The keyword is normalised, so "Home Lab", "home lab" and "home-lab" all reach the same topic and you can pass a phrase you read anywhere. Each feed says whether it landed here from the publisher's own tag or from a phrase counted across its writing. A comma-separated list ("business, saas, crypto", up to 10) returns the union: every feed filed under any of them, each once, with `topics` naming the known ones and `unknown` the rest.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Default 100. |
| offset | integer | Default 0. |
| keyword* | string | The topic, in any spelling — or several, separated by commas. |
{
"type": "object",
"required": [
"keyword"
],
"properties": {
"limit": {
"type": "integer",
"maximum": 500,
"minimum": 1,
"description": "Default 100."
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Default 0."
},
"keyword": {
"type": "string",
"description": "The topic, in any spelling — or several, separated by commas."
}
}
}The directory's authors and where else they publish — their own sites, Mastodon and Bluesky accounts, GitHub, links pages. Every link was published by the author on their own site as a rel="me" claim, an h-card or JSON-LD; nothing is scraped from a platform or bought. Filter with network to find only people reachable a given way (email, fediverse, bluesky, github, website, linktree), or query to search names. Role mailboxes like info@ are never returned: they are dropped at extraction, so an address here belongs to a person.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Default 50. |
| query | string | Search names. |
| offset | integer | Default 0. |
| network | string | Only people with a link on this network, e.g. "email" or "fediverse". |
| minConfidence | number | How sure the attribution must be, 0 to 1. Default 0.6, which is what the site itself publishes. Lower it for the long tail, and expect some of it to be wrong. |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"maximum": 200,
"minimum": 1,
"description": "Default 50."
},
"query": {
"type": "string",
"description": "Search names."
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Default 0."
},
"network": {
"type": "string",
"description": "Only people with a link on this network, e.g. \"email\" or \"fediverse\"."
},
"minConfidence": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "How sure the attribution must be, 0 to 1. Default 0.6, which is what the site itself publishes. Lower it for the long tail, and expect some of it to be wrong."
}
}
}Page through the whole directory, newest first. Narrow to one category with kind: blog, news, podcast, music, video, comic, live or reel. The category is decided from the feed document on every crawl, never from what the submitter claimed.
| Argument | Type | Description |
|---|---|---|
| kind | string | Only feeds of this category. Omit for all of them. |
| limit | integer | Default 50. |
| offset | integer | Default 0. |
{
"type": "object",
"properties": {
"kind": {
"enum": [
"blog",
"news",
"podcast",
"music",
"video",
"comic",
"live",
"reel"
],
"type": "string",
"description": "Only feeds of this category. Omit for all of them."
},
"limit": {
"type": "integer",
"maximum": 200,
"minimum": 1,
"description": "Default 50."
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Default 0."
}
}
}The OpenWebring rings hosted here (logicsrc.com/openwebring): one per well-covered topic, each an ordered circular list of member sites with next, previous and random hops. Every entry carries the ring page, the ring file, an OPML of the members' feeds, and how many members are listed and active. A member site may declare who makes it (human, ai or both); absent means it has not said.
No arguments.
{
"type": "object",
"properties": {}
}What the directory covers, by how many feeds cover it. Pass query to search the index instead of paging it. Only subjects at least two feeds share are indexed — a topic one blog uses is that blog's own vocabulary, and lives on its page instead. Raise min to find the well-covered subjects.
| Argument | Type | Description |
|---|---|---|
| min | integer | Only topics at least this many feeds cover. Default 2. |
| limit | integer | Default 100. |
| query | string | Search the topic index. A phrase works as well as a slug — "quantum physics" and "quantum-physics" are the same search. Matches are ranked: the exact topic, then topics starting with the term, then topics containing it. |
| offset | integer | Default 0. |
{
"type": "object",
"properties": {
"min": {
"type": "integer",
"maximum": 100,
"minimum": 2,
"description": "Only topics at least this many feeds cover. Default 2."
},
"limit": {
"type": "integer",
"maximum": 500,
"minimum": 1,
"description": "Default 100."
},
"query": {
"type": "string",
"description": "Search the topic index. A phrase works as well as a slug — \"quantum physics\" and \"quantum-physics\" are the same search. Matches are ranked: the exact topic, then topics starting with the term, then topics containing it."
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Default 0."
}
}
}Your webhook endpoints (url, event filters, on/off, failures) and the event types this site emits. Needs one of your rssamplifier API keys in the Authorization header (Bearer rsa_..., from /account).
No arguments.
{
"type": "object",
"properties": {}
}This week's digest as it would be built right now from the directory: new feeds, posts from the most-followed blogs, liked posts, webring activity. Read-only: nothing is stored or sent. `issue` is null when there is nothing to say yet.
No arguments.
{
"type": "object",
"properties": {}
}One feed from the directory, chosen at random, with its recent posts. The web without a ranking function: what is here rather than what is popular.
No arguments.
{
"type": "object",
"properties": {}
}The full text of one post, extracted from the publisher's own page and returned as prose. Takes the feed slug and post guid that search, get_feed and topic_posts return. The first reader pays for the fetch and everyone after them reads it out of the database, so the publisher is asked once rather than once per view. A post behind a paywall, on a site that is down, or by a publisher who asked not to be redistributed (reason publisher-opt-out) comes back with the feed's summary and a reason instead — never an error.
| Argument | Type | Description |
|---|---|---|
| feed* | string | The feed's slug. |
| guid* | string | The post's guid, as returned by the other tools. |
{
"type": "object",
"required": [
"feed",
"guid"
],
"properties": {
"feed": {
"type": "string",
"description": "The feed's slug."
},
"guid": {
"type": "string",
"description": "The post's guid, as returned by the other tools."
}
}
}The copy-paste HTML a site puts in its footer to show it belongs to one or more webrings here: `<< Ring >>` per ring, previous / ring page / next, each hop measured from the member site given as `site` (its homepage). Returns a plain variant (bare links, the page styles them) and a styled one (inline styles), plus the raw links. No script, no images. Rings are slugs from list_rings.
| Argument | Type | Description |
|---|---|---|
| site | string | The member site's homepage, e.g. https://example.com/. Omit for a placeholder. |
| rings* | array | Ring slugs, in the order the rows should appear. |
| random | boolean | Add the random-site link. Default false. |
{
"type": "object",
"required": [
"rings"
],
"properties": {
"site": {
"type": "string",
"description": "The member site's homepage, e.g. https://example.com/. Omit for a placeholder."
},
"rings": {
"type": "array",
"items": {
"type": "string"
},
"description": "Ring slugs, in the order the rows should appear."
},
"random": {
"type": "boolean",
"description": "Add the random-site link. Default false."
}
}
}Which member a hop lands on, without following a redirect: the site after or before `from` in ring order, or a random one. `from` is a member site URL or its slug; omit it for a random active member. Pending and inactive members are listed by get_ring but skipped here, and the ring wraps around. Nothing is recorded about who asked.
| Argument | Type | Description |
|---|---|---|
| from | string | The member site the reader is on: its URL or its slug. |
| slug* | string | The ring slug, from list_rings. |
| direction | string | Default next. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"from": {
"type": "string",
"description": "The member site the reader is on: its URL or its slug."
},
"slug": {
"type": "string",
"description": "The ring slug, from list_rings."
},
"direction": {
"enum": [
"next",
"previous",
"random"
],
"type": "string",
"description": "Default next."
}
}
}Mint a new signing secret for the endpoint and return it; the old one stops working at once. Needs one of your rssamplifier API keys in the Authorization header (Bearer rsa_..., from /account).
| Argument | Type | Description |
|---|---|---|
| id* | string | The webhook endpoint id (wh_...), from list_webhooks. |
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "The webhook endpoint id (wh_...), from list_webhooks."
}
}
}Full-text search across every post and blog in the directory. Returns matching blogs and matching individual posts, each with the identifiers read_post needs. Use mode="any" to match any one of the terms rather than all of them — useful when a thing goes by several names. The directory is mostly blogs, so the best-ranked results for anything are usually blog posts: every reply counts the whole match set by category under `categories`, and `kind` asks for one of them — the podcast episodes on a subject rather than the writing.
| Argument | Type | Description |
|---|---|---|
| kind | string | Only results from feeds of this category. Omit for all of them, and read `categories` in the reply to see what the other kinds hold. |
| mode | string | Require every term (default) or any one of them. |
| limit | integer | Results of each kind. Default 30. |
| query* | string | What to search for. |
{
"type": "object",
"required": [
"query"
],
"properties": {
"kind": {
"enum": [
"blog",
"news",
"podcast",
"music",
"video",
"comic",
"live",
"reel"
],
"type": "string",
"description": "Only results from feeds of this category. Omit for all of them, and read `categories` in the reply to see what the other kinds hold."
},
"mode": {
"enum": [
"all",
"any"
],
"type": "string",
"description": "Require every term (default) or any one of them."
},
"limit": {
"type": "integer",
"maximum": 100,
"minimum": 1,
"description": "Results of each kind. Default 30."
},
"query": {
"type": "string",
"description": "What to search for."
}
}
}Submit one URL or a list of them to RSSAmp. A site URL works as well as a feed URL: the feed is discovered from the page. Anyone may submit; there is no account and no review queue. One URL resolves in the call and the answer carries its page; a list may be queued, and the answer says which. Rate limited per caller.
| Argument | Type | Description |
|---|---|---|
| urls* | array | Feed or site URLs. One is fine. |
{
"type": "object",
"required": [
"urls"
],
"properties": {
"urls": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 200,
"description": "Feed or site URLs. One is fine."
}
}
}Send a signed webhook.test event to the endpoint now and report the HTTP status. Needs one of your rssamplifier API keys in the Authorization header (Bearer rsa_..., from /account).
| Argument | Type | Description |
|---|---|---|
| id* | string | The webhook endpoint id (wh_...), from list_webhooks. |
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "The webhook endpoint id (wh_...), from list_webhooks."
}
}
}What the feeds covering a topic have actually published lately, newest first — the river rather than the roster. Note the difference from get_topic, which lists who covers the subject; this lists what they wrote. Drawn from the feeds most strongly filed under the topic, so a very broad keyword is a sample rather than a census. A comma-separated list ("business, saas, crypto", up to 10) is one river across all of them.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Default 50. |
| keyword* | string | The topic, in any spelling — or several, separated by commas. |
{
"type": "object",
"required": [
"keyword"
],
"properties": {
"limit": {
"type": "integer",
"maximum": 200,
"minimum": 1,
"description": "Default 50."
},
"keyword": {
"type": "string",
"description": "The topic, in any spelling — or several, separated by commas."
}
}
}Subjects English blogs and news sites used in headlines more than the week before, ranked. `count` is feeds, not posts, in a one in four sample, so it measures movement rather than coverage, and `prior_count` is the same figure for the week before. Updated daily. An empty list means the rollup has not got two days to compare yet.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Default 50. |
| window | integer | Days per side of the comparison. Default 7. |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"maximum": 200,
"minimum": 1,
"description": "Default 50."
},
"window": {
"type": "integer",
"maximum": 14,
"minimum": 1,
"description": "Days per side of the comparison. Default 7."
}
}
}Edit a profile you have claimed. Send the whole file as `markdown` (everything in it becomes your word; a section you leave out is dropped) or a patch: `headline`, `identity` {Key: value, or null to remove}, `sections` {name: Markdown body, or null to drop}, `public`. Sections you do not mention stay as generated. Needs a credential in the Authorization header: one of your rssamplifier API keys, or an OpenAccess bearer for `openprofile:edit` (openaccess.logicsrc.com). Claim first with claim_openprofile.
| Argument | Type | Description |
|---|---|---|
| name | string | |
| slug* | string | The author's slug. |
| prose | string | |
| public | boolean | false hides the file; the author page stays. |
| headline | string | |
| identity | object | |
| markdown | string | The whole OpenProfile.md, replacing every section. |
| sections | object |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"name": {
"type": "string"
},
"slug": {
"type": "string",
"description": "The author's slug."
},
"prose": {
"type": "string"
},
"public": {
"type": "boolean",
"description": "false hides the file; the author page stays."
},
"headline": {
"type": "string"
},
"identity": {
"type": "object",
"additionalProperties": {
"type": [
"string",
"null"
]
}
},
"markdown": {
"type": "string",
"description": "The whole OpenProfile.md, replacing every section."
},
"sections": {
"type": "object",
"additionalProperties": {
"type": [
"string",
"null"
]
}
}
}
}Change an endpoint's url, events, description, or switch it on/off (turning it back on clears its failure count). Needs one of your rssamplifier API keys in the Authorization header (Bearer rsa_..., from /account).
| Argument | Type | Description |
|---|---|---|
| id* | string | The webhook endpoint id (wh_...), from list_webhooks. |
| url | string | |
| events | array | |
| enabled | boolean | |
| description | string |
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "The webhook endpoint id (wh_...), from list_webhooks."
},
"url": {
"type": "string"
},
"events": {
"type": "array",
"items": {
"type": "string"
}
},
"enabled": {
"type": "boolean"
},
"description": {
"type": "string"
}
}
}Recent deliveries (status, attempts, last HTTP status or error, payload), for one endpoint or all of yours. Needs one of your rssamplifier API keys in the Authorization header (Bearer rsa_..., from /account).
| Argument | Type | Description |
|---|---|---|
| id | string | Only this endpoint; omit for every endpoint. |
| limit | integer |
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Only this endpoint; omit for every endpoint."
},
"limit": {
"type": "integer",
"maximum": 200,
"minimum": 1
}
}
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 11, 2026.