Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# rssamplifier.com — copy to .env and fill in.
# rssamp.com — copy to .env and fill in.
# Team copy lives in logicsrc: `logicsrc teams pull profullstack rssamplifier-com prod`

# PostgreSQL. `sslmode=require` asks for TLS without verifying the certificate,
Expand All @@ -24,7 +24,7 @@ CRAWL_AUXILIARY_WRITES=1
CRAWL_CATCHUP=0

# Public origin, used for canonical URLs, OPML, llms.txt and JSON-LD.
SITE_URL=https://rssamplifier.com
SITE_URL=https://rssamp.com

# Selling crawl access to AI training crawlers (GPTBot, ClaudeBot, CCBot,
# meta-externalagent, …): a dollar buys a day, settled in USDC by CoinPay. See
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/deploy-dev2.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Ship every merge to dev2, where rssamplifier.com runs since 2026-09-25 (it was
# Ship every merge to dev2, where rssamp.com runs since 2026-09-25 (it was
# two Railway services, which deployed on merge by themselves). The box pulls the
# merged commit, rebuilds the web and poller images from the repo's Dockerfiles
# and restarts the compose stack under /home/anthony/www/rssamplifier.com.
Expand Down Expand Up @@ -52,8 +52,8 @@ jobs:
- name: Verify the site answers
run: |
for i in $(seq 1 10); do
code=$(curl -s -o /dev/null -w '%{http_code}' https://rssamplifier.com/ || true)
if [ "$code" = 200 ]; then echo "rssamplifier.com 200"; exit 0; fi
code=$(curl -s -o /dev/null -w '%{http_code}' https://rssamp.com/ || true)
if [ "$code" = 200 ]; then echo "rssamp.com 200"; exit 0; fi
echo "attempt $i: $code"; sleep 10
done
echo "rssamplifier.com never returned 200"; exit 1
echo "rssamp.com never returned 200"; exit 1
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# rssamplifier.com
# rssamp.com

An open, agent-first directory of independent blogs.

Expand All @@ -9,7 +9,7 @@ The point of difference is the machine-readable half: most of the web now blocks
this directory deliberately does the opposite. Everything is also published as JSON, OPML and plain
text so an agent can read the whole thing in one request.

**Live:** <https://rssamplifier.com>
**Live:** <https://rssamp.com>

## Layout

Expand Down Expand Up @@ -246,11 +246,11 @@ All send `access-control-allow-origin: *` and need no key.
| `/api/authors/{slug}/claim` | `POST` to claim an author as yourself; verified by the address they published or by their site linking back |

```bash
curl -X POST https://rssamplifier.com/api/submit \
curl -X POST https://rssamp.com/api/submit \
-H 'content-type: application/json' \
-d '{"urls":["example.com","another.blog"]}'

curl -X POST https://rssamplifier.com/api/discover \
curl -X POST https://rssamp.com/api/discover \
-H 'content-type: application/json' \
-d '{"keywords":["siberian huskies"]}'
```
Expand Down Expand Up @@ -342,7 +342,7 @@ than scrape it. It runs inside the web app — no second service, no second
deploy — and the endpoint is the same URL as its documentation page:

```bash
claude mcp add --transport http rssamplifier https://rssamplifier.com/mcp
claude mcp add --transport http rssamplifier https://rssamp.com/mcp
```

Ten tools: `search`, `list_feeds`, `get_feed`, `list_topics`, `get_topic`,
Expand Down Expand Up @@ -482,7 +482,7 @@ Talks to the public HTTP API, so it needs no credentials. Point it elsewhere wit
Two Railway services in the shared Profullstack project, both building from this repo with
`RAILWAY_DOCKERFILE_PATH` pointing at their own Dockerfile:

- `rssamplifier.com` → `apps/web/Dockerfile`
- `rssamp.com` → `apps/web/Dockerfile`
- `rssamplifier-poller` → `apps/poller/Dockerfile`

Secrets live in logicsrc: `logicsrc teams pull profullstack rssamplifier-com prod`.
Expand Down
8 changes: 4 additions & 4 deletions apps/cli/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# rssamplifier CLI

The [RSS Amplifier](https://rssamplifier.com) directory, from a terminal. Find feeds by subject,
The [RSSAmp](https://rssamp.com) directory, from a terminal. Find feeds by subject,
search tens of thousands of independent blogs, export OPML, submit a site. No key, no account.

```sh
curl -fsSL https://rssamplifier.com/install.sh | sh
curl -fsSL https://rssamp.com/install.sh | sh
```

That drops one file at `~/.local/bin/rssamp`. Node 22 or newer is the only requirement — there are
Expand Down Expand Up @@ -33,7 +33,7 @@ rssamp opml --topic homelab > homelab.opml
rssamp urls --topic homelab # one feed URL per line
```

Run `rssamp --help` for the rest, or read <https://rssamplifier.com/cli>.
Run `rssamp --help` for the rest, or read <https://rssamp.com/cli>.

## For scripts and agents

Expand All @@ -47,7 +47,7 @@ rssamp search "agentic coding" --json | jq -r '.posts[].url'
rssamp topic homelab --json | jq -r '.feeds[].feedUrl'
```

An agent that can call MCP tools should use <https://rssamplifier.com/mcp> instead: same data,
An agent that can call MCP tools should use <https://rssamp.com/mcp> instead: same data,
no subprocess, and the tools describe their own arguments.

## Pointing it elsewhere
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@profullstack/rssamplifier",
"version": "0.6.0",
"description": "CLI for rssamplifier.com \u2014 find feeds by topic, search the directory, export OPML, submit blogs",
"description": "CLI for rssamp.com \u2014 find feeds by topic, search the directory, export OPML, submit blogs",
"type": "module",
"main": "src/index.js",
"bin": {
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';

export const VERSION = '0.6.0';

const DEFAULT_API = 'https://rssamplifier.com';
const DEFAULT_API = 'https://rssamp.com';

/**
* Every command, in the order they are worth learning.
Expand Down
4 changes: 2 additions & 2 deletions apps/poller/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ const ringIntervalMs = (Number(env['RING_SECONDS']) || 60) * 1000;
const ringRecheckDays = Number(env['RING_RECHECK_DAYS']) || 7;
const ringTopics = Number(env['RING_TOPICS']) || 20;
const ringSeedMs = (Number(env['RING_SEED_SECONDS']) || 21_600) * 1000;
const ringBase = (env['SITE_URL'] || 'https://rssamplifier.com').replace(/\/+$/, '');
const ringBase = (env['SITE_URL'] || 'https://rssamp.com').replace(/\/+$/, '');

// Items keyed for grouping per tick. Each one is a title hashed in process and
// a single-column update, so the batch is bounded by the write round trip
Expand Down Expand Up @@ -1183,7 +1183,7 @@ if (writeWorker) {
* The functions above are the jobs, unchanged; src/daemon.js says which run
* and how often. Its state lives beside ours in Postgres
* (scraper_daemon_runs, scraper_daemon_state), and its status document is what
* https://rssamplifier.com/api/v1/daemon serves.
* https://rssamp.com/api/v1/daemon serves.
*/
const daemonStore = pgStore((text, params) => db.execute(text, params));

Expand Down
4 changes: 2 additions & 2 deletions apps/web/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,8 @@ const nextConfig = {
// straight through.
{
source: '/:path*',
has: [{ type: 'host', value: 'www.rssamplifier.com' }],
destination: 'https://rssamplifier.com/:path*',
has: [{ type: 'host', value: 'www.rssamp.com' }],
destination: 'https://rssamp.com/:path*',
permanent: true,
},

Expand Down
8 changes: 4 additions & 4 deletions apps/web/public/.well-known/openaccess.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"openaccess": "0.1",
"name": "RSS Amplifier",
"url": "https://rssamplifier.com",
"name": "RSSAmp",
"url": "https://rssamp.com",
"operator": "https://logicsrc.com/.well-known/openprofile.md",
"redirect_uris": [
"https://rssamplifier.com/api/v1/openaccess/callback"
"https://rssamp.com/api/v1/openaccess/callback"
],
"jwks": {
"keys": [
Expand All @@ -25,7 +25,7 @@
"honours": [
"profullstack.com/all-access"
],
"webhooks": "https://rssamplifier.com/api/v1/openaccess/events",
"webhooks": "https://rssamp.com/api/v1/openaccess/events",
"hubs": [
"https://openaccess.logicsrc.com"
]
Expand Down
6 changes: 3 additions & 3 deletions apps/web/public/.well-known/openmcp.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"openmcp": "0.1",
"mcp": "https://rssamplifier.com/api/mcp",
"name": "RSS Amplifier",
"mcp": "https://rssamp.com/api/mcp",
"name": "RSSAmp",
"description": "An open directory of independent blogs, podcasts and feeds: search, topics, read a post.",
"url": "https://rssamplifier.com",
"url": "https://rssamp.com",
"auth": {
"kind": "none"
},
Expand Down
2 changes: 1 addition & 1 deletion apps/web/public/manifest.webmanifest
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "RSS Amplifier",
"name": "RSSAmp",
"short_name": "RSSAmp",
"description": "An open, agent-friendly directory of independent blogs. Submit a URL, a list or an OPML file.",
"start_url": "/?source=pwa",
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/app/.well-known/openwebring.json/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ export const dynamic = 'force-dynamic';
export async function GET() {
const rings = await webrings.listRings(db());
const body = {
...hostFile({ base: siteUrl(), siteName: 'RSS Amplifier', rings }),
...hostFile({ base: siteUrl(), siteName: 'RSSAmp', rings }),
// The rings this site is itself a member of, beside the ones it hosts.
made_by: 'both',
rings: [{ ring: 'https://rssamplifier.com/ring/profullstack', slug: 'rssamplifier-com' }],
rings: [{ ring: 'https://rssamp.com/ring/profullstack', slug: 'rssamplifier-com' }],
};

return new Response(JSON.stringify(body, null, 2), {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/.well-known/security.txt/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function GET() {
const expires = new Date(Date.now() + 180 * 24 * 60 * 60 * 1000).toISOString();
const base = siteUrl();

const body = `Contact: mailto:security@rssamplifier.com
const body = `Contact: mailto:security@rssamp.com
Expires: ${expires}
Preferred-Languages: en
Canonical: ${base}/.well-known/security.txt
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/AddSocialSource.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default function AddSocialSource({ network, label, input, canonical }) {
<h1>{label}</h1>

<p>
Nobody has added this {platform.name} source to the directory yet. Add it and RSS Amplifier
Nobody has added this {platform.name} source to the directory yet. Add it and RSSAmp
will start collecting it — usually within a minute.
</p>

Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/CategoryIndex.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export default async function CategoryIndex({ kind, page = 1, view = 'shows' })
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'CollectionPage',
name: `${category.heading} · RSS Amplifier`,
name: `${category.heading} · RSSAmp`,
description: category.lede,
url: `${siteUrl()}${category.path}`,
hasPart: river
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/DockPlayer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ export default function DockPlayer() {
navigator.mediaSession.metadata = new window.MediaMetadata({
title: track.title,
artist: track.show,
album: 'RSS Amplifier',
album: 'RSSAmp',
artwork: track.image ? [{ src: track.image }] : [],
});
} catch {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/PitFooter.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const SNIPPET_URL = 'https://pit.world/snippets/footer.html?site=rssamplifier.com';
const SNIPPET_URL = 'https://pit.world/snippets/footer.html?site=rssamp.com';

/**
* The pit.world global footer: site name, Search, Ring, Publish here — the
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/SignupProfileFields.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function SignupProfileFields({ errors, defaultValues }) {
{/* On by default (the owner's call); unticked, the account starts off the list. */}
<label className="check-row" htmlFor="signup-newsletter">
<input id="signup-newsletter" type="checkbox" name="newsletter" value="1" defaultChecked />{' '}
Send me the weekly RSS Amplifier digest (new feeds, top posts, webrings). One click to stop.
Send me the weekly RSSAmp digest (new feeds, top posts, webrings). One click to stop.
</label>
</>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/[slug]/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export async function generateMetadata({ params }) {
// image here would otherwise drop the site name and the type too.
openGraph: {
type: 'website',
siteName: 'RSS Amplifier',
siteName: 'RSSAmp',
url,
title,
description,
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/app/about/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import Toolbar from '../Toolbar.jsx';

export const metadata = {
title: 'About',
description: 'What RSS Amplifier is, and why it is deliberately open to AI crawlers.',
description: 'What RSSAmp is, and why it is deliberately open to AI crawlers.',
};

export default function AboutPage() {
return (
<>
<h1>About</h1>
<p className="lede">
RSS Amplifier is an open directory of independent blogs. Submit a URL, a list of URLs or an
RSSAmp is an open directory of independent blogs. Submit a URL, a list of URLs or an
OPML file; we find the feed, read it, and give the blog a permanent page.
</p>

Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/app/advertise/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Toolbar from '../Toolbar.jsx';
export const metadata = {
title: 'Advertise',
description:
'What RSS Amplifier reaches, and how to get into the ad rotation. Free to join, no monthly fee, and the creatives are made for you.',
'What RSSAmp reaches, and how to get into the ad rotation. Free to join, no monthly fee, and the creatives are made for you.',
};

// Rendered per request, like every other page here that reads the directory,
Expand Down Expand Up @@ -60,7 +60,7 @@ export default async function AdvertisePage() {
<>
<h1>Advertise</h1>
<p className="lede">
RSS Amplifier is an open directory of {fmt(feeds)} independent feeds. Ads here run through{' '}
RSSAmp is an open directory of {fmt(feeds)} independent feeds. Ads here run through{' '}
<a href="https://crawlproof.com/ads" rel="noopener">
CrawlProof
</a>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/api/dataset/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export function GET() {
source:
'Public feeds their publishers chose to syndicate. The directory is open and anyone may submit to it.',
optOut:
'A publisher may be excluded from the corpus while staying in the directory, on request to hello@rssamplifier.com. Excluded feeds and every post and article belonging to them are absent from every dataset above.',
'A publisher may be excluded from the corpus while staying in the directory, on request to hello@rssamp.com. Excluded feeds and every post and article belonging to them are absent from every dataset above.',
openApi: `Nothing here is a restriction on the open API: ${base}/api/feeds, /api/search, /opml and the MCP server all answer without an account.`,
},
},
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/app/api/following/feed/[format]/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,15 @@ export async function GET(req, { params }) {
// this and the whole thing must be able to tell them apart in a list of
// feeds, and "Following" twice over cannot.
title: kinds
? `Following: ${CATEGORIES[kinds[0]].heading} — RSS Amplifier`
: 'Following — RSS Amplifier',
? `Following: ${CATEGORIES[kinds[0]].heading} — RSSAmp`
: 'Following — RSSAmp',
description: `Recent ${
kinds ? CATEGORIES[kinds[0]].item : 'posts'
} from the ${count(topics.length, 'topic')}, ${count(
authors.length,
'person',
'people',
)} and ${count(feeds.length, 'blog')} this RSS Amplifier account follows.`,
)} and ${count(feeds.length, 'blog')} this RSSAmp account follows.`,
link: `${origin}/following${kinds ? `?kind=${kinds[0]}` : ''}`,
selfUrl: followingFeedUrl(origin, token, format, kinds),
},
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/api/frame/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const dynamic = 'force-dynamic';
*
* A hole in our origin. The response carries `Content-Security-Policy:
* sandbox`, which applies however the document is loaded, so somebody else's
* markup can never run with rssamplifier.com's origin — not in the frame, and
* markup can never run with rssamp.com's origin — not in the frame, and
* not by pasting this URL into the address bar.
*/

Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/api/v1/daemon/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const NO_STORE = { 'cache-control': 'no-store' };
* the one fact a cached copy would hide.
*
* Same shape as every other site on @profullstack/scraper-daemon, so
* `npx @profullstack/scraper-daemon status https://rssamplifier.com` reads it.
* `npx @profullstack/scraper-daemon status https://rssamp.com` reads it.
*/
export async function GET() {
try {
Expand Down
10 changes: 5 additions & 5 deletions apps/web/src/app/contact/page.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export const metadata = {
title: 'Contact',
description:
'How to reach the people who run RSS Amplifier: general questions, corrections to a listing, privacy requests and security reports.',
'How to reach the people who run RSSAmp: general questions, corrections to a listing, privacy requests and security reports.',
};

/**
Expand All @@ -26,7 +26,7 @@ export default function ContactPage() {
<>
<h1>Contact</h1>
<p className="lede">
RSS Amplifier is built and run by{' '}
RSSAmp is built and run by{' '}
<a href="https://profullstack.com">Profullstack, Inc.</a> There is no support queue and no
account system; the addresses below reach people.
</p>
Expand All @@ -38,7 +38,7 @@ export default function ContactPage() {
</p>
<p>
If an entry about your site is wrong, or you would like it removed, email{' '}
<a href="mailto:hello@rssamplifier.com">hello@rssamplifier.com</a> with the address of the
<a href="mailto:hello@rssamp.com">hello@rssamp.com</a> with the address of the
page. We only index public feeds, and we remove on request without asking why.
</p>

Expand All @@ -55,13 +55,13 @@ export default function ContactPage() {
<p>
For access, correction or deletion requests, or any question about{' '}
<a href="/privacy">the privacy policy</a>, email{' '}
<a href="mailto:privacy@rssamplifier.com">privacy@rssamplifier.com</a>.
<a href="mailto:privacy@rssamp.com">privacy@rssamp.com</a>.
</p>

<h2>Security</h2>
<p>
To report a vulnerability, email{' '}
<a href="mailto:security@rssamplifier.com">security@rssamplifier.com</a>. Machine-readable
<a href="mailto:security@rssamp.com">security@rssamp.com</a>. Machine-readable
details are at <a href="/.well-known/security.txt">/.well-known/security.txt</a>. Please
give us a chance to fix it before publishing.
</p>
Expand Down
Loading
Loading