Metadata-Version: 2.4
Name: rankforge
Version: 0.1.0
Summary: Honest, local-first SEO autopilot: audit → keywords → briefs → articles → links → publish → track. CLI + MCP, no SaaS required.
Project-URL: Homepage, https://github.com/Makeph/rankforge
Project-URL: Repository, https://github.com/Makeph/rankforge
Author: Aurore Biakou
License: MIT
License-File: LICENSE
Keywords: content,geo,keywords,mcp,rank-tracking,seo,wordpress
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
Classifier: Topic :: Text Processing :: Markup :: HTML
Requires-Python: >=3.10
Requires-Dist: pyyaml>=6.0
Requires-Dist: requests>=2.31
Requires-Dist: rich>=13.0
Requires-Dist: typer>=0.12
Provides-Extra: ai
Requires-Dist: anthropic>=0.40; extra == 'ai'
Provides-Extra: all
Requires-Dist: anthropic>=0.40; extra == 'all'
Requires-Dist: mcp>=1.2; extra == 'all'
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: mcp
Requires-Dist: mcp>=1.2; extra == 'mcp'
Description-Content-Type: text/markdown

# rankforge

<p align="center">
  <a href="https://github.com/Makeph/rankforge/actions/workflows/ci.yml"><img src="https://github.com/Makeph/rankforge/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
  <img src="https://img.shields.io/badge/python-3.10%2B-blue" alt="Python 3.10+">
  <img src="https://img.shields.io/badge/MCP-server-8b5cf6" alt="MCP server">
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-green.svg" alt="License: MIT"></a>
</p>

**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.

```bash
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.

```bash
# typical cron line — one article per weekday morning, as WordPress drafts
0 7 * * 1-5  rankforge tick
```

## MCP (drive it from any MCP client)

```bash
pip install "rankforge[mcp]"
rankforge mcp        # stdio server
```

```json
{
  "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

```bash
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
