Honest, local-first SEO autopilot: audit → keywords → briefs → articles → links → publish → track. CLI + MCP, no SaaS required.
Project description
rankforge
Honest, local-first SEO autopilot. Audit your site → research keywords → brief the SERP → write scored articles → weave internal links → publish → track rankings. One shared Python core, two front-ends: a CLI and an MCP server you can drive from any MCP client.
No SaaS, no account, no required API keys. Your site data and your .env
never leave your machine — it's a single SQLite file you can delete and
rebuild.
git clone https://github.com/Makeph/rankforge && cd rankforge
pip install -e ".[all]" # or `pip install -e .` for the lean core
rankforge init
RANKFORGE_SITE=https://your-site.com rankforge audit
rankforge keywords research "your topic"
rankforge write "your best keyword" # scored SEO + GEO before you ever publish
rankforge tick --dry-run # see what the autopilot would do
Why this exists
The "AI SEO autopilot" category (AutoSEO, Oscar AI, and friends) charges ~$150/month for a loop you can run on your own machine: pick a keyword, read the SERP, write an article, add links, publish, track. rankforge is that loop, rebuilt small and honest:
| Idea | Seen in | How rankforge does it |
|---|---|---|
| "Connect your site, get daily articles on autopilot" | AutoSEO-style tools | tick worker with a daily cap and a quality gate — cron it, or don't |
| Real-time SEO/GEO article scoring | Oscar-style tools | A deterministic rubric (score) — every point traceable to a named check, same input → same score |
| Keyword research + competitor analysis | everyone | Zero-key: autocomplete expansion + DuckDuckGo SERP + competitor scrape |
| Auto internal linking | Oscar-style tools | Anchors matched against your crawled pages, idempotent insertion |
| Publishes to your CMS | everyone | WordPress REST (app password) or markdown export for any static site |
| Rank tracking incl. AI engines | AutoSEO-style tools | DuckDuckGo position history in SQLite; the GEO score covers the AI-answer side |
Everything degrades gracefully: no key → article generation falls back through local agent CLIs to a deterministic outline; no WordPress → markdown export; no network → audit/score/link still work on stored data. Nothing publishes without passing the quality gate, and nothing publishes at all unless you configured a target.
The engine trick
Article writing is pluggable, and three of the engines are agent CLIs you may already pay for — so generation costs nothing extra and no API key ever enters this tool:
RANKFORGE_ENGINE = auto | anthropic | codex | kimi | qwen | outline
anthropic— the Anthropic API (ANTHROPIC_API_KEY).codex/kimi/qwen— driven via their non-interactive prompt modes.outline— offline, deterministic: expands the brief into a structured skeleton with TODOs. Never publishable, never blocking.
auto walks whatever is actually available (rankforge engines shows the
order). Every draft is scored; if it lands under RANKFORGE_MIN_SCORE, the
engine gets one revision pass listing the exact named checks that failed —
then the article is either ready or held as a local draft.
SEO score + GEO score
rankforge score <id> prints two rubrics, check by check:
- SEO 0–100 — keyword in H1/intro/headings, structure, length vs the SERP-derived target, density, internal + external links, readability, lists.
- GEO 0–100 — will an answer engine (ChatGPT, Perplexity, AI Overviews) quote you? Question-phrased H2s, ≤60-word direct answers under them, an FAQ block, a liftable definition, lists/steps, concrete figures.
No magic, no vibes: the scorer is ~150 lines you can read, and the writer never sees it — only its plain-language feedback.
The pipeline
rankforge audit # crawl + on-page issues + site-wide findings
rankforge keywords research <seed> # autocomplete → cluster → opportunity 0-100
rankforge brief <keyword> # live SERP: target length, questions, outline
rankforge write <keyword> # engine of your choice, scored, stored
rankforge links <id> --apply # internal links from YOUR crawled pages
rankforge publish <id> [--dry-run] # WordPress draft or markdown front-matter
rankforge track / report # DuckDuckGo positions + movement over time
rankforge tick # all of the above, once a day, guardrailed
The autopilot's guardrails mirror the rest of the tool: RANKFORGE_DAILY_ARTICLES
(default 1), RANKFORGE_MIN_SCORE (default 70, below = held as draft),
WordPress posts land as drafts unless you say otherwise, and --dry-run
always shows the plan first.
# typical cron line — one article per weekday morning, as WordPress drafts
0 7 * * 1-5 rankforge tick
MCP (drive it from any MCP client)
pip install "rankforge[mcp]"
rankforge mcp # stdio server
{
"mcpServers": {
"rankforge": { "command": "rankforge", "args": ["mcp"] }
}
}
Tools exposed: audit_site, research_keywords, build_brief,
write_article, score_article, suggest_internal_links, check_rank.
Configuration
Everything is optional — rankforge init drops a commented env.example.
| Variable | Purpose | Without it |
|---|---|---|
RANKFORGE_SITE |
your site (audit, linking, tracking) | pass URLs explicitly |
RANKFORGE_LANG |
keyword/article language (en, fr, …) |
en |
RANKFORGE_ENGINE |
writing engine | auto |
ANTHROPIC_API_KEY |
the API engine | CLI engines / outline |
WP_URL / WP_USER / WP_APP_PASSWORD |
WordPress publishing | markdown export |
RANKFORGE_DAILY_ARTICLES / MIN_SCORE / MAX_PAGES |
guardrails | 1 / 70 / 200 |
Install from source
git clone https://github.com/Makeph/rankforge
cd rankforge
pip install -e ".[dev]"
pytest # offline test suite, no keys needed
Responsible use
rankforge is a content system, not a spam cannon: one article a day by default, a quality gate that refuses to publish weak drafts, WordPress drafts by default so a human stays in the loop, polite crawling with a real user-agent and jittered pacing, and rank checks kept to a minimum. Generated content is your responsibility — review it before it ships.
License
MIT © 2026 Aurore Biakou
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rankforge-0.1.0.tar.gz.
File metadata
- Download URL: rankforge-0.1.0.tar.gz
- Upload date:
- Size: 47.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f12d3bf6ce9599e8210a8f962901fb5812fd5689f809a47120b3e4840a6c3bb7
|
|
| MD5 |
5cb1d9ca4c529be24fd09340f17f4008
|
|
| BLAKE2b-256 |
0d0e9dac5ff4d80ba539e51ebd51ec8c25b3af9e5f8b6d7abd592cb630281ef5
|
Provenance
The following attestation bundles were made for rankforge-0.1.0.tar.gz:
Publisher:
pypi.yml on Makeph/rankforge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rankforge-0.1.0.tar.gz -
Subject digest:
f12d3bf6ce9599e8210a8f962901fb5812fd5689f809a47120b3e4840a6c3bb7 - Sigstore transparency entry: 2226465519
- Sigstore integration time:
-
Permalink:
Makeph/rankforge@649cbc303c6731edde6fdf545255f30536ccb937 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Makeph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@649cbc303c6731edde6fdf545255f30536ccb937 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rankforge-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rankforge-0.1.0-py3-none-any.whl
- Upload date:
- Size: 42.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5974e86158060ad7ce0821e402e027278c1f8d64ec2511938529cf846f9e705
|
|
| MD5 |
fb3633844a46ff5ab2214bc39ff256a0
|
|
| BLAKE2b-256 |
c2488675bafc270ee2d63357fbf1fe61b45af76ff09e207eb9d78a7e00185efb
|
Provenance
The following attestation bundles were made for rankforge-0.1.0-py3-none-any.whl:
Publisher:
pypi.yml on Makeph/rankforge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rankforge-0.1.0-py3-none-any.whl -
Subject digest:
d5974e86158060ad7ce0821e402e027278c1f8d64ec2511938529cf846f9e705 - Sigstore transparency entry: 2226465910
- Sigstore integration time:
-
Permalink:
Makeph/rankforge@649cbc303c6731edde6fdf545255f30536ccb937 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Makeph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@649cbc303c6731edde6fdf545255f30536ccb937 -
Trigger Event:
push
-
Statement type: