seo-desk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- seo_desk-0.1.0/LICENSE +21 -0
- seo_desk-0.1.0/PKG-INFO +426 -0
- seo_desk-0.1.0/README.md +391 -0
- seo_desk-0.1.0/pyproject.toml +61 -0
- seo_desk-0.1.0/seo_desk.egg-info/PKG-INFO +426 -0
- seo_desk-0.1.0/seo_desk.egg-info/SOURCES.txt +47 -0
- seo_desk-0.1.0/seo_desk.egg-info/dependency_links.txt +1 -0
- seo_desk-0.1.0/seo_desk.egg-info/entry_points.txt +3 -0
- seo_desk-0.1.0/seo_desk.egg-info/requires.txt +16 -0
- seo_desk-0.1.0/seo_desk.egg-info/top_level.txt +1 -0
- seo_desk-0.1.0/seodesk/__init__.py +3 -0
- seo_desk-0.1.0/seodesk/__main__.py +329 -0
- seo_desk-0.1.0/seodesk/agent.py +210 -0
- seo_desk-0.1.0/seodesk/audit.py +334 -0
- seo_desk-0.1.0/seodesk/crawl.py +376 -0
- seo_desk-0.1.0/seodesk/dashboard/__init__.py +0 -0
- seo_desk-0.1.0/seodesk/dashboard/auth.py +113 -0
- seo_desk-0.1.0/seodesk/dashboard/server.py +318 -0
- seo_desk-0.1.0/seodesk/dashboard/static/assets/logo.svg +12 -0
- seo_desk-0.1.0/seodesk/dashboard/static/index.html +580 -0
- seo_desk-0.1.0/seodesk/dashboard/static/login.html +86 -0
- seo_desk-0.1.0/seodesk/dataforseo.py +165 -0
- seo_desk-0.1.0/seodesk/db.py +466 -0
- seo_desk-0.1.0/seodesk/demo.py +181 -0
- seo_desk-0.1.0/seodesk/errors.py +10 -0
- seo_desk-0.1.0/seodesk/geo.py +137 -0
- seo_desk-0.1.0/seodesk/llm.py +135 -0
- seo_desk-0.1.0/seodesk/llmstxt.py +67 -0
- seo_desk-0.1.0/seodesk/mcp_server.py +108 -0
- seo_desk-0.1.0/seodesk/pipeline.py +308 -0
- seo_desk-0.1.0/seodesk/probes.py +128 -0
- seo_desk-0.1.0/seodesk/progress.py +280 -0
- seo_desk-0.1.0/seodesk/runlock.py +77 -0
- seo_desk-0.1.0/seodesk/serp.py +100 -0
- seo_desk-0.1.0/seodesk/settings.py +261 -0
- seo_desk-0.1.0/seodesk/stores.py +175 -0
- seo_desk-0.1.0/seodesk/templates/config.yaml +43 -0
- seo_desk-0.1.0/seodesk/templates/env.example +18 -0
- seo_desk-0.1.0/seodesk/templates/example-site.yaml +66 -0
- seo_desk-0.1.0/setup.cfg +4 -0
- seo_desk-0.1.0/tests/test_audit.py +105 -0
- seo_desk-0.1.0/tests/test_checks.py +202 -0
- seo_desk-0.1.0/tests/test_core.py +170 -0
- seo_desk-0.1.0/tests/test_dashboard.py +111 -0
- seo_desk-0.1.0/tests/test_llm.py +53 -0
- seo_desk-0.1.0/tests/test_mcp.py +67 -0
- seo_desk-0.1.0/tests/test_probes.py +85 -0
- seo_desk-0.1.0/tests/test_sites.py +376 -0
- seo_desk-0.1.0/tests/test_stores.py +101 -0
seo_desk-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Syed Anas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
seo_desk-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: seo-desk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Is your site ready for AI search? SEO, AEO and GEO audits from the CLI, CI, Claude Code or MCP: AI crawler access, llms.txt, answer-ready pages, AI visibility tracking, and an AI analyst that writes the to-do list.
|
|
5
|
+
Author: Syed Anas
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Anas660/claude-seo-desk
|
|
8
|
+
Project-URL: Issues, https://github.com/Anas660/claude-seo-desk/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/Anas660/claude-seo-desk/blob/main/CHANGELOG.md
|
|
10
|
+
Keywords: seo,aeo,geo,generative-engine-optimization,answer-engine-optimization,llms-txt,ai-crawlers,robots-txt,seo-audit,ai-visibility,mcp,claude-code
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Environment :: Web Environment
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Information Technology
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
|
|
20
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: httpx>=0.27
|
|
25
|
+
Requires-Dist: beautifulsoup4>=4.12
|
|
26
|
+
Requires-Dist: PyYAML>=6.0
|
|
27
|
+
Requires-Dist: python-dotenv>=1.0
|
|
28
|
+
Requires-Dist: pydantic>=2.7
|
|
29
|
+
Provides-Extra: mcp
|
|
30
|
+
Requires-Dist: mcp<3,>=2; python_version >= "3.10" and extra == "mcp"
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
33
|
+
Requires-Dist: mcp<3,>=2; python_version >= "3.10" and extra == "dev"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
<!--
|
|
37
|
+
SEO Desk (seo-desk): free, open-source SEO, AEO and GEO audit tool for the AI search era.
|
|
38
|
+
Checks AI crawler access in robots.txt (GPTBot, ClaudeBot, PerplexityBot, Google-Extended), llms.txt, answer-ready
|
|
39
|
+
pages, structured data and on-page SEO; tracks AI visibility in ChatGPT, Perplexity, Gemini and Claude; writes a
|
|
40
|
+
prioritised to-do list with an AI analyst. CLI, GitHub Action, Claude Code plugin, MCP server and self-hosted
|
|
41
|
+
dashboard. Python, MIT licensed.
|
|
42
|
+
-->
|
|
43
|
+
<p align="center">
|
|
44
|
+
<img src="https://raw.githubusercontent.com/Anas660/claude-seo-desk/main/docs/assets/hero.png" width="100%" alt="SEO Desk: is your site ready for AI search? SEO, AEO and GEO scores, AI crawler access and llms.txt, from one command: uvx seo-desk audit yoursite.com" />
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
<h1 align="center">SEO Desk</h1>
|
|
48
|
+
|
|
49
|
+
<p align="center">
|
|
50
|
+
<b>Your site ranks on Google. Does ChatGPT cite it?</b><br />
|
|
51
|
+
Open-source SEO, AEO and GEO audits that tell you what to fix first,<br />
|
|
52
|
+
from your terminal, your CI, Claude Code or any MCP client.
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
<p align="center">
|
|
56
|
+
<a href="#quick-start">Quick start</a> ·
|
|
57
|
+
<a href="#use-it-your-way">Use it your way</a> ·
|
|
58
|
+
<a href="#the-dashboard">Dashboard</a> ·
|
|
59
|
+
<a href="#ai-visibility">AI visibility</a> ·
|
|
60
|
+
<a href="#how-it-compares">Compare</a> ·
|
|
61
|
+
<a href="#faq">FAQ</a>
|
|
62
|
+
</p>
|
|
63
|
+
|
|
64
|
+
<p align="center">
|
|
65
|
+
<a href="https://github.com/Anas660/claude-seo-desk/actions/workflows/ci.yml"><img src="https://github.com/Anas660/claude-seo-desk/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
66
|
+
<a href="https://pypi.org/project/seo-desk/"><img src="https://img.shields.io/pypi/v/seo-desk?color=2563eb" alt="PyPI" /></a>
|
|
67
|
+
<a href="https://pepy.tech/project/seo-desk"><img src="https://static.pepy.tech/badge/seo-desk/month" alt="Downloads a month" /></a>
|
|
68
|
+
<a href="https://pypi.org/project/seo-desk/"><img src="https://img.shields.io/pypi/pyversions/seo-desk" alt="Python versions" /></a>
|
|
69
|
+
<a href="#claude-code-plugin"><img src="https://img.shields.io/badge/Claude%20Code-plugin-D97757" alt="Claude Code plugin" /></a>
|
|
70
|
+
<a href="#mcp-server"><img src="https://img.shields.io/badge/MCP-server-6D5DF2" alt="MCP server" /></a>
|
|
71
|
+
<a href="https://github.com/Anas660/claude-seo-desk/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-22c55e" alt="MIT license" /></a>
|
|
72
|
+
<a href="https://github.com/Anas660/claude-seo-desk/stargazers"><img src="https://img.shields.io/github/stars/Anas660/claude-seo-desk?style=social" alt="GitHub stars" /></a>
|
|
73
|
+
</p>
|
|
74
|
+
|
|
75
|
+
## Quick start
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
uvx seo-desk audit yoursite.com
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
No account, no API key, nothing to configure. (No `uv`? `pip install seo-desk`, then `seodesk audit yoursite.com`.)
|
|
82
|
+
|
|
83
|
+
<p align="center">
|
|
84
|
+
<img src="https://raw.githubusercontent.com/Anas660/claude-seo-desk/main/docs/assets/audit.svg" width="820" alt="seodesk audit example.com in a terminal: Overall 34, SEO 60, AEO 0, GEO 42; llms.txt missing; eight quick wins, from publishing a sitemap to adding a canonical link" />
|
|
85
|
+
</p>
|
|
86
|
+
<p align="center"><sub>A real run against example.com, October 2026.</sub></p>
|
|
87
|
+
|
|
88
|
+
Want to see the dashboard first? `uvx seo-desk demo` opens it on eight weeks of sample data.
|
|
89
|
+
|
|
90
|
+
## Why SEO Desk
|
|
91
|
+
|
|
92
|
+
AI assistants answer the question and cite a handful of sources. Ranking on Google doesn't make you one of them;
|
|
93
|
+
being readable, quotable and known does. SEO Desk checks all three, every day if you like:
|
|
94
|
+
|
|
95
|
+
- **Can AI crawlers read you?** robots.txt read the way GPTBot, ClaudeBot and Google read it (RFC 9309 wildcards and
|
|
96
|
+
longest match, which Python's own robots parser gets wrong), plus `llms.txt` and `llms-full.txt`.
|
|
97
|
+
- **Is each page quotable?** Question headings, a 25-90 word answer straight under them, FAQ schema, tables, structured
|
|
98
|
+
data, and every classic on-page check.
|
|
99
|
+
- **Do AI models name you?** Ask ChatGPT, Perplexity, Gemini or Claude what your customers ask and see who they cite
|
|
100
|
+
instead, and whether they repeat something false about you.
|
|
101
|
+
- **What should you do first?** Rule-based quick wins on every audit; with a model key, an AI analyst reads the
|
|
102
|
+
evidence and writes a prioritised to-do list that doesn't repeat itself day after day.
|
|
103
|
+
|
|
104
|
+
## What it checks
|
|
105
|
+
|
|
106
|
+
| | Measures | Checks |
|
|
107
|
+
|---|---|---|
|
|
108
|
+
| **SEO** | Ranking in Google | Every sitemap page: status, title and description length, canonical, noindex, H1s, thin pages, alt text, duplicate titles, slow pages, broken or retired JSON-LD. Google positions for your keywords ([Serper](https://serper.dev)); search volumes and every keyword you rank for ([DataForSEO](https://dataforseo.com)). |
|
|
109
|
+
| **AEO** | Being the quoted answer: snippets, AI Overviews, People also ask | Question headings, answer-first paragraphs, FAQPage schema, tables and lists. |
|
|
110
|
+
| **GEO** | Being named by AI assistants | Which AI crawlers robots.txt lets in, `llms.txt` and `llms-full.txt`, structured data, claims your site must never make, and what AI models actually answer. |
|
|
111
|
+
|
|
112
|
+
Pages are read without running JavaScript, as most AI crawlers read them: a page that only renders in the browser
|
|
113
|
+
shows up thin here, and that's worth knowing.
|
|
114
|
+
|
|
115
|
+
## Use it your way
|
|
116
|
+
|
|
117
|
+
| | Get it | Then |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| **Terminal** | `uvx seo-desk` or `pip install seo-desk` | `seodesk audit yoursite.com` |
|
|
120
|
+
| **Claude Code plugin** | `/plugin marketplace add Anas660/claude-seo-desk` | "audit my site for AI search", and it fixes what it finds |
|
|
121
|
+
| **MCP server** | `claude mcp add seo-desk -- uvx --python ">=3.10" --from "seo-desk[mcp]" seodesk mcp` | Claude, Cursor or any MCP client calls the tools |
|
|
122
|
+
| **GitHub Action** | `uses: Anas660/claude-seo-desk@v0.1.0` | A score on every deploy, in the job summary |
|
|
123
|
+
| **Daily agent** | `seodesk init` | History, trends, AI analyst, dashboard, many sites |
|
|
124
|
+
|
|
125
|
+
### Terminal
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
seodesk audit https://www.example.com # text report
|
|
129
|
+
seodesk audit example.com --format markdown -o report.md # or json
|
|
130
|
+
seodesk audit example.com --keyword "invoice template" # + Google rank (SERPER_API_KEY)
|
|
131
|
+
seodesk audit example.com --brief # + the AI analyst's actions (LLM_API_KEY)
|
|
132
|
+
seodesk audit example.com --fail-under 70 # exit 1 under 70, for CI
|
|
133
|
+
seodesk llms-txt example.com -o llms.txt # draft an llms.txt from the site's pages
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
<details>
|
|
137
|
+
<summary>All audit options</summary>
|
|
138
|
+
|
|
139
|
+
| Option | |
|
|
140
|
+
|---|---|
|
|
141
|
+
| `--format text\|markdown\|json`, `-o FILE` | Report format and where to write it; `--json FILE` also writes the full JSON |
|
|
142
|
+
| `--max-pages 50` | Sitemap pages to crawl |
|
|
143
|
+
| `--keyword K` (repeat), `--country us`, `--language en` | Google rank checks, needs `SERPER_API_KEY` |
|
|
144
|
+
| `--brief`, `--model`, `--base-url`, `--max-usd 0.25` | The AI analyst's brief, needs `LLM_API_KEY` |
|
|
145
|
+
| `--fail-under N` | Exit with 1 when the overall score is under N |
|
|
146
|
+
| `--ignore-robots` | Crawl pages robots.txt disallows for SEODesk (only on a site you run) |
|
|
147
|
+
|
|
148
|
+
</details>
|
|
149
|
+
|
|
150
|
+
### Claude Code plugin
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
/plugin marketplace add Anas660/claude-seo-desk
|
|
154
|
+
/plugin install seo-desk@seo-desk
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Then ask *"audit www.example.com for AI search"* or run `/seo-desk:audit https://www.example.com`. Claude runs the
|
|
158
|
+
audit, explains the scores, and, when you're in the site's repo, finds where robots.txt, titles, structured data and
|
|
159
|
+
llms.txt come from and fixes them with you, then checks the result. `/seo-desk:llms-txt` writes the site's llms.txt
|
|
160
|
+
from its real pages. The bundled MCP server needs [uv](https://docs.astral.sh/uv/).
|
|
161
|
+
|
|
162
|
+
### MCP server
|
|
163
|
+
|
|
164
|
+
Four read-only tools for any MCP client: Claude Code, Claude Desktop, Cursor, Windsurf, VS Code.
|
|
165
|
+
|
|
166
|
+
| Tool | Does |
|
|
167
|
+
|---|---|
|
|
168
|
+
| `audit_site(url, max_pages, keywords)` | The whole audit, sized for a model's context |
|
|
169
|
+
| `inspect_page(url)` | One page in detail, for checking a fix |
|
|
170
|
+
| `check_ai_access(url)` | Which AI crawlers robots.txt lets in; llms.txt files |
|
|
171
|
+
| `draft_llms_txt(url)` | A starting llms.txt from the site's pages |
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
claude mcp add seo-desk -- uvx --python ">=3.10" --from "seo-desk[mcp]" seodesk mcp
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
<details>
|
|
178
|
+
<summary>Claude Desktop, Cursor and other clients</summary>
|
|
179
|
+
|
|
180
|
+
```json
|
|
181
|
+
{
|
|
182
|
+
"mcpServers": {
|
|
183
|
+
"seo-desk": {
|
|
184
|
+
"command": "uvx",
|
|
185
|
+
"args": ["--python", ">=3.10", "--from", "seo-desk[mcp]", "seodesk", "mcp"]
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Or `pip install "seo-desk[mcp]"` (Python 3.10+) and use `"command": "seodesk", "args": ["mcp"]`.
|
|
192
|
+
|
|
193
|
+
</details>
|
|
194
|
+
|
|
195
|
+
### GitHub Action
|
|
196
|
+
|
|
197
|
+
```yaml
|
|
198
|
+
# .github/workflows/seo.yml
|
|
199
|
+
on:
|
|
200
|
+
push:
|
|
201
|
+
branches: [main]
|
|
202
|
+
jobs:
|
|
203
|
+
seo:
|
|
204
|
+
runs-on: ubuntu-latest
|
|
205
|
+
steps:
|
|
206
|
+
- uses: Anas660/claude-seo-desk@v0.1.0
|
|
207
|
+
with:
|
|
208
|
+
url: https://www.example.com
|
|
209
|
+
fail-under: 60 # optional: fail the job under this overall score
|
|
210
|
+
# keywords: | # optional: needs SERPER_API_KEY in env
|
|
211
|
+
# invoice template
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The report lands in the job summary. Outputs: `overall`, `seo`, `aeo`, `geo` and `report` (the JSON file).
|
|
215
|
+
|
|
216
|
+
### Daily agent
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
mkdir my-seo && cd my-seo
|
|
220
|
+
seodesk init # config.yaml, sites/example.yaml, .env.example
|
|
221
|
+
# put your site in sites/example.yaml; copy .env.example to .env and add the keys you have
|
|
222
|
+
seodesk check # keys, and each site's sitemap
|
|
223
|
+
seodesk run # crawl, check, score, brief: every site in config.yaml
|
|
224
|
+
seodesk dashboard --no-password # http://127.0.0.1:5380, this machine only
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Each run lands in `data/seo.db` (SQLite) and compares each week and each month with the one before. The AI analyst
|
|
228
|
+
reads the day's evidence, can read pages and run a few live Google checks, and returns 3-8 specific actions, each
|
|
229
|
+
with the numbers it rests on. An action suggested again tomorrow updates its row instead of piling up; one you mark
|
|
230
|
+
done or dismissed stays that way.
|
|
231
|
+
|
|
232
|
+
Schedule it with cron (`0 7 * * * cd /path/to/my-seo && seodesk run`) or the systemd units in [deploy/](https://github.com/Anas660/claude-seo-desk/tree/main/deploy). To
|
|
233
|
+
reach the dashboard from elsewhere, set a password (`seodesk password`) and put HTTPS (Caddy, nginx) in front of it.
|
|
234
|
+
|
|
235
|
+
<details>
|
|
236
|
+
<summary>Keys (all optional) and what they cost</summary>
|
|
237
|
+
|
|
238
|
+
| Key in `.env` | Adds | Cost |
|
|
239
|
+
|---|---|---|
|
|
240
|
+
| none | Crawl, GEO checks, scores, history, dashboard | $0 |
|
|
241
|
+
| `LLM_API_KEY` | The AI analyst's brief, AI visibility | A brief is about a cent with the default model |
|
|
242
|
+
| `SERPER_API_KEY` | Google ranks for your keywords, People also ask, live checks for the analyst | About $1 per 1,000 searches |
|
|
243
|
+
| `DATAFORSEO_LOGIN`, `DATAFORSEO_PASSWORD` | Real search volumes, and every keyword Google ranks you for | A few cents a site a month |
|
|
244
|
+
|
|
245
|
+
`LLM_API_KEY` is an [OpenRouter](https://openrouter.ai) key by default (one key, hundreds of models; the default is
|
|
246
|
+
`deepseek/deepseek-v4.1-flash`). Any OpenAI-compatible API works: set `llm.base_url` and `llm.model` in config.yaml
|
|
247
|
+
(OpenAI, a local Ollama or LM Studio, your company's gateway). Spending caps stop paid steps per run, per site per
|
|
248
|
+
month and for every site per month, and every cent is recorded and shown on the dashboard.
|
|
249
|
+
|
|
250
|
+
</details>
|
|
251
|
+
|
|
252
|
+
## The dashboard
|
|
253
|
+
|
|
254
|
+
<picture>
|
|
255
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/Anas660/claude-seo-desk/main/docs/assets/dashboard-today-dark.png" />
|
|
256
|
+
<img src="https://raw.githubusercontent.com/Anas660/claude-seo-desk/main/docs/assets/dashboard-today.png" alt="SEO Desk dashboard, Today: the AI analyst's headline and summary, SEO 71, AEO 53, GEO 85 with sparklines, AI answers naming the site 2 of 4, and today's prioritised actions" />
|
|
257
|
+
</picture>
|
|
258
|
+
|
|
259
|
+
| Progress, week by week and month by month | What AI models answer |
|
|
260
|
+
|---|---|
|
|
261
|
+
|  |  |
|
|
262
|
+
|
|
263
|
+
<sub>Sample data from `seodesk demo`: two fictional sites on the reserved .example domain.</sub>
|
|
264
|
+
|
|
265
|
+
## AI visibility
|
|
266
|
+
|
|
267
|
+
Ask AI models the questions your customers ask, the way they ask them:
|
|
268
|
+
|
|
269
|
+
```yaml
|
|
270
|
+
# sites/example.yaml
|
|
271
|
+
ai_visibility:
|
|
272
|
+
models: [perplexity/sonar, openai/gpt-5-mini:online] # OpenRouter names; ":online" adds web search
|
|
273
|
+
prompts:
|
|
274
|
+
- best invoicing software for freelancers
|
|
275
|
+
- how do I make an invoice as a freelancer
|
|
276
|
+
- {prompt: "What is Example invoicing?", branded: true}
|
|
277
|
+
every_days: 7
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
For every answer: does it **name** you, does it **link** to you, which **sites it cites instead**, and does it repeat
|
|
281
|
+
a **false claim** from your claims list. The share of unbranded answers that name you feeds the GEO score; branded
|
|
282
|
+
prompts catch what AI gets wrong about you. Each prompt goes to the model with no system prompt and nothing that
|
|
283
|
+
hints at your site.
|
|
284
|
+
|
|
285
|
+
### Claims your site must never make
|
|
286
|
+
|
|
287
|
+
List what isn't true ("SOC 2 certified", an old price, a dropped feature). SEO Desk scans every live page, both llms
|
|
288
|
+
files and the AI answers for it. Rules can count only sentences about you and skip sentences that deny the claim, so
|
|
289
|
+
"we have no SOC 2 report" and "insist on SOC 2 from any vendor" don't trip them:
|
|
290
|
+
|
|
291
|
+
```yaml
|
|
292
|
+
claims:
|
|
293
|
+
- {id: soc2, pattern: '\bSOC[\s-]?2\b', about_us: true, unless: '\bno\b|\bnot\b', why: there is no SOC 2 report}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## How the scores work
|
|
297
|
+
|
|
298
|
+
Each score is 0-100, the same formula every day on every site ([progress.py](https://github.com/Anas660/claude-seo-desk/blob/main/seodesk/progress.py)). A part with no
|
|
299
|
+
data is left out and the others count for more.
|
|
300
|
+
|
|
301
|
+
- **SEO** = keyword visibility 50% (#1 100 points, #2 90, #3 80, #4-5 65, #6-10 50, #11-15 25, #16-20 15) + pages
|
|
302
|
+
without errors 30% + pages with clean on-page tags 20%. Without rank checks, SEO is the last two.
|
|
303
|
+
- **AEO** = content pages with question headings 30% + an answer-first paragraph 30% + FAQPage schema 20% + tables or
|
|
304
|
+
lists 20%.
|
|
305
|
+
- **GEO** = AI crawlers allowed 25% + llms.txt (60) and llms-full.txt (40) 15% + pages with structured data 20% + no
|
|
306
|
+
false claims 15% + AI models naming you in unbranded answers 25% (a quarter of answers or more scores 100).
|
|
307
|
+
- **Overall** = the mean of the three. Change the formula, then `seodesk rescore` recomputes every stored run.
|
|
308
|
+
|
|
309
|
+
## How it compares
|
|
310
|
+
|
|
311
|
+
| | Typical one-off GEO checker | Paid AI-visibility tracker | SEO Desk |
|
|
312
|
+
|---|---|---|---|
|
|
313
|
+
| Price | Free | Monthly subscription | Free (MIT); you pay only for API calls you turn on |
|
|
314
|
+
| Runs on | Your machine | Their cloud | Your machine or server, one SQLite file |
|
|
315
|
+
| AI crawler and llms.txt checks | ✅ | Some | ✅, robots.txt read per RFC 9309 |
|
|
316
|
+
| On-page SEO and AEO checks | Some | Some | ✅ |
|
|
317
|
+
| What AI models answer about you | ❌ | ✅ | ✅, with the models you choose |
|
|
318
|
+
| History and week/month trends | ❌ | ✅ | ✅ |
|
|
319
|
+
| What to do next | Rule-based | Varies | Quick wins, plus an AI analyst that cites its evidence |
|
|
320
|
+
| CI, Claude Code and MCP | Some | Rarely | ✅ all three |
|
|
321
|
+
|
|
322
|
+
## A polite crawler
|
|
323
|
+
|
|
324
|
+
- One identifiable user agent, `SEODesk/<version> (+https://github.com/Anas660/claude-seo-desk)`, four pages at a time.
|
|
325
|
+
- It skips pages robots.txt disallows for `SEODesk` (or `*`). On your own site you can turn that off.
|
|
326
|
+
- Google results come from Serper's API, never by scraping Google.
|
|
327
|
+
|
|
328
|
+
## FAQ
|
|
329
|
+
|
|
330
|
+
<details>
|
|
331
|
+
<summary><b>What are SEO, AEO and GEO?</b></summary>
|
|
332
|
+
|
|
333
|
+
SEO (search engine optimisation) is ranking in Google's links. AEO (answer engine optimisation) is being the passage
|
|
334
|
+
quoted in featured snippets, AI Overviews and People also ask. GEO (generative engine optimisation) is being named and
|
|
335
|
+
cited by AI assistants like ChatGPT, Perplexity, Gemini and Claude. They overlap: a crawlable, well-structured page
|
|
336
|
+
with a direct answer helps all three.
|
|
337
|
+
</details>
|
|
338
|
+
|
|
339
|
+
<details>
|
|
340
|
+
<summary><b>Do I need API keys?</b></summary>
|
|
341
|
+
|
|
342
|
+
No. Without keys SEO Desk crawls, runs every GEO and AEO check, scores the site, keeps history and serves the
|
|
343
|
+
dashboard. Keys add Google rank checks (Serper), search volumes (DataForSEO), the AI analyst and AI visibility (any
|
|
344
|
+
OpenAI-compatible model API).
|
|
345
|
+
</details>
|
|
346
|
+
|
|
347
|
+
<details>
|
|
348
|
+
<summary><b>Should I block GPTBot and the other AI crawlers?</b></summary>
|
|
349
|
+
|
|
350
|
+
That's your call, and SEO Desk only reports it. Know the split: search and answer crawlers (OAI-SearchBot,
|
|
351
|
+
ChatGPT-User, Claude-SearchBot, PerplexityBot) decide whether AI answers can cite you; training crawlers (GPTBot,
|
|
352
|
+
ClaudeBot, CCBot, Google-Extended, Applebot-Extended) decide whether your pages train future models. Blocking the
|
|
353
|
+
first group usually costs visibility.
|
|
354
|
+
</details>
|
|
355
|
+
|
|
356
|
+
<details>
|
|
357
|
+
<summary><b>Is llms.txt worth it?</b></summary>
|
|
358
|
+
|
|
359
|
+
It's a proposal ([llmstxt.org](https://llmstxt.org)), not a standard. Google has said it doesn't use it; some AI tools
|
|
360
|
+
and agents do read it. It's cheap to publish and keep current, so SEO Desk checks it and counts it for 15% of GEO, and
|
|
361
|
+
`seodesk llms-txt` drafts one from your pages.
|
|
362
|
+
</details>
|
|
363
|
+
|
|
364
|
+
<details>
|
|
365
|
+
<summary><b>Does it render JavaScript?</b></summary>
|
|
366
|
+
|
|
367
|
+
No, on purpose: most AI crawlers don't either. If a page you care about scores thin, it probably renders on the client;
|
|
368
|
+
server-side rendering or prerendering fixes that for every crawler.
|
|
369
|
+
</details>
|
|
370
|
+
|
|
371
|
+
<details>
|
|
372
|
+
<summary><b>Can I audit a site I don't own?</b></summary>
|
|
373
|
+
|
|
374
|
+
Yes, politely: SEO Desk identifies itself, fetches four pages at a time and skips what robots.txt disallows for it.
|
|
375
|
+
</details>
|
|
376
|
+
|
|
377
|
+
<details>
|
|
378
|
+
<summary><b>Where does my data go?</b></summary>
|
|
379
|
+
|
|
380
|
+
Nowhere you didn't choose. Everything is stored in a SQLite file on your machine; page text goes only to the model API
|
|
381
|
+
you configure, and only when you turn on the brief or AI visibility.
|
|
382
|
+
</details>
|
|
383
|
+
|
|
384
|
+
## Contributing
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
git clone https://github.com/Anas660/claude-seo-desk && cd claude-seo-desk
|
|
388
|
+
python -m venv .venv && .venv/bin/pip install -e ".[dev]"
|
|
389
|
+
.venv/bin/pytest -q # offline, a few seconds: every network call is faked
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Ideas that would help most: a Google Search Console connection, optional JavaScript rendering, more answer-engine
|
|
393
|
+
checks, and a native Anthropic API client. See [CONTRIBUTING.md](https://github.com/Anas660/claude-seo-desk/blob/main/CONTRIBUTING.md); issues labelled
|
|
394
|
+
`good first issue` are a good place to start.
|
|
395
|
+
|
|
396
|
+
<details>
|
|
397
|
+
<summary>Project layout</summary>
|
|
398
|
+
|
|
399
|
+
| Module | Does |
|
|
400
|
+
|---|---|
|
|
401
|
+
| `crawl.py` | Sitemap discovery, the page checks, AEO signals |
|
|
402
|
+
| `geo.py` | AI crawler access (RFC 9309 robots.txt), llms.txt, the claims scan |
|
|
403
|
+
| `probes.py` | AI visibility |
|
|
404
|
+
| `audit.py`, `llmstxt.py` | `seodesk audit` and its reports; the llms.txt draft |
|
|
405
|
+
| `mcp_server.py` | The MCP server |
|
|
406
|
+
| `serp.py`, `dataforseo.py`, `stores.py` | Google ranks, search volumes, WordPress.org and Shopify listings |
|
|
407
|
+
| `progress.py` | The scores, and week and month comparisons |
|
|
408
|
+
| `agent.py`, `llm.py` | The AI analyst and the chat-model client |
|
|
409
|
+
| `pipeline.py`, `db.py` | One daily run of one site; the SQLite store |
|
|
410
|
+
| `dashboard/` | The dashboard (standard-library HTTP server, one HTML page) |
|
|
411
|
+
| `skills/`, `.claude-plugin/` | The Claude Code plugin |
|
|
412
|
+
|
|
413
|
+
</details>
|
|
414
|
+
|
|
415
|
+
If SEO Desk saved you an afternoon, a ⭐ helps other people find it.
|
|
416
|
+
|
|
417
|
+
## Star history
|
|
418
|
+
|
|
419
|
+
<a href="https://star-history.com/#Anas660/claude-seo-desk&Date"><img src="https://api.star-history.com/svg?repos=Anas660/claude-seo-desk&type=Date" width="600" alt="Star history of Anas660/claude-seo-desk" /></a>
|
|
420
|
+
|
|
421
|
+
## License
|
|
422
|
+
|
|
423
|
+
[MIT](https://github.com/Anas660/claude-seo-desk/blob/main/LICENSE) © Syed Anas
|
|
424
|
+
|
|
425
|
+
<sub>SEO Desk is an independent open-source project. It isn't made or endorsed by Anthropic; Claude and Claude Code
|
|
426
|
+
are Anthropic's trademarks, named here because SEO Desk works with them.</sub>
|