github Python re-analysis due

PavloSEO/seotools

github

SEO evidence toolkit: analyzes Screaming Frog exports, adds bounded live and infrastructure checks, and produces structured audits, task backlogs, and reports via CLI and local MCP.

maintainer
PavloSEO
license
MIT
first seen
2026-09-04
last seen
2026-09-05
releases · 30d
0
short id

Drift inferred · capture-to-capture

No drift recorded — single capability capture; advisories appear once its surface changes.

capabilities 50 tools
transport stdio counts 50 tools · 0 res · 0 prompts permission surface via code analysis

tools

  • seo_ai_bots_check
  • seo_asset_weight_check
  • seo_backlinks_check
  • seo_cdn_check
  • seo_citability_check
  • seo_compare_crawls
  • seo_crawl_site
  • seo_domain_profile
  • seo_duplicate_check
  • seo_google_keywords
  • seo_google_serp
  • seo_headers_check
  • seo_hreflang_check
  • seo_images_download
  • seo_images_optimize
  • seo_keywords_cluster
  • seo_keywords_exact
  • seo_keywords_expand
  • seo_keywords_seasonality
  • seo_links_check
  • seo_llms_txt_check
  • seo_log_analyze
  • seo_metrika_counters
  • seo_metrika_report
  • seo_metrika_setup
  • seo_mirror_check
  • seo_parse
  • seo_redirects_check
  • seo_redirects_generate
  • seo_regions_check
  • seo_regions_tree
  • seo_render_check
  • seo_report_build
  • seo_robots_check
  • seo_schema_build
  • seo_schema_check
  • seo_security_check
  • seo_serp_fetch
  • seo_site_audit
  • seo_sitemap_crawl
  • seo_social_meta_check
  • seo_soft404_check
  • seo_sources_doctor
  • seo_spend_report
  • seo_tech_detect
  • sf_audit_issues
  • sf_audit_run
  • sf_audit_summary
  • sf_audit_tasks
  • sf_list_exports
skills & danger signals github-tarball
prompt-surface shipped agent-instruction files + hidden-content / dangerous-code findings — quoted from the analyzed source

analyzed commit 0cc5acd · analyzer v33 · 1d ago

skills & prompt files 29

danger signals4

code evidence vHEAD · github-tarball
evidence-backed findings quoted directly from the published source artifact — not inferred

code files: 185

filesystem 63

  • fs (weak) PavloSEO-seotools-0cc5acd/scripts/generate_checks_reference.py :15 from pathlib import Path
  • fs (weak) PavloSEO-seotools-0cc5acd/scripts/render_readme_visuals.py :14 from pathlib import Path
  • fs PavloSEO-seotools-0cc5acd/seohead/cli.py :409 with open(path, "r", encoding="utf-8") as fh: # noqa: UP015 - explicit read-only contract
  • fs PavloSEO-seotools-0cc5acd/seohead/crawl/collect.py :275 handle = stack.enter_context(open(out_path, "w", encoding="utf-8"))
  • fs PavloSEO-seotools-0cc5acd/seohead/crawl/settings.py :359 with open(path, encoding="utf-8") as handle:
  • fs PavloSEO-seotools-0cc5acd/seohead/crawl/spider.py :88 with open(path, encoding="utf-8") as handle:
  • fs PavloSEO-seotools-0cc5acd/seohead/crawl/state.py :57 with open(path, encoding="utf-8") as handle:
  • fs PavloSEO-seotools-0cc5acd/seohead/data_sources/credentials.py :18 from pathlib import Path
  • fs PavloSEO-seotools-0cc5acd/seohead/data_sources/spend.py :22 from pathlib import Path
  • fs PavloSEO-seotools-0cc5acd/seohead/data_sources/yandex_regions.py :21 from pathlib import Path
  • fs PavloSEO-seotools-0cc5acd/seohead/recon/net.py :20 import shutil
  • fs PavloSEO-seotools-0cc5acd/seohead/recon/tech_db.py :74 with open(cat_path, encoding="utf-8") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/reports/__init__.py :21 import pathlib
  • fs PavloSEO-seotools-0cc5acd/seohead/reports/csvfile.py :16 import pathlib
  • fs PavloSEO-seotools-0cc5acd/seohead/reports/docx.py :11 import pathlib
  • fs PavloSEO-seotools-0cc5acd/seohead/reports/md.py :5 import pathlib
  • fs PavloSEO-seotools-0cc5acd/seohead/reports/xlsx.py :10 import pathlib
  • fs PavloSEO-seotools-0cc5acd/seohead/runlog.py :29 from pathlib import Path
  • fs PavloSEO-seotools-0cc5acd/seohead/servers/handlers.py :267 with open(os.path.join(out_dir, "audit.json"), "w", encoding="utf-8") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/servers/sf_mcp.py :79 with open(json_path, encoding="utf-8") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/sf/cli.py :221 with open(resolved, "rb") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/sf/config.py :192 with open(path, encoding="utf-8") as handle:
  • fs PavloSEO-seotools-0cc5acd/seohead/sf/core/audit.py :32 with open(path, "rb") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/sf/core/auth_proxy.py :145 with open(path, encoding="utf-8-sig", newline="") as handle:
  • fs PavloSEO-seotools-0cc5acd/seohead/sf/core/checks_reference.py :13 from pathlib import Path
  • fs PavloSEO-seotools-0cc5acd/seohead/sf/core/heuristics.py :165 with open(path, encoding="utf-8", errors="replace") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/sf/core/runner.py :13 import shutil
  • fs PavloSEO-seotools-0cc5acd/seohead/sf/core/spiderconfig.py :124 with open(source, "rb") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/sf/reporters/jsonfile.py :25 with open(tmp, "w", encoding="utf-8") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/sf/reporters/md.py :139 with open(path, "w", encoding="utf-8") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/sf/tasks.py :231 with open(json_path, "w", encoding="utf-8") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/tools/downloader.py :199 with open(dest, "wb") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/tools/excel.py :67 with open(path, encoding="utf-8-sig", newline="") as fh:
  • fs PavloSEO-seotools-0cc5acd/seohead/tools/logs.py :380 handle = open(path, encoding="utf-8", errors="replace") # noqa: SIM115 - report open errors
  • fs PavloSEO-seotools-0cc5acd/seohead/tools/optimizer.py :8 import shutil
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/conftest.py :6 import shutil
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_check_coverage.py :39 with open(d / "internal_all.csv", "w", encoding="utf-8-sig", newline="") as f:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_check_preconditions.py :14 import shutil
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_context.py :19 with open(p, "w", encoding="utf-8-sig", newline="") as f:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_crawl_list_mode.py :7 from pathlib import Path
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_crawl_resume.py :65 with open(state_path, encoding="utf-8") as fh:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_crawl_state.py :76 with open(path, encoding="utf-8") as fh:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_crawl_validity.py :22 with open(path, "w", encoding="utf-8-sig", newline="") as fh:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_data_sources.py :74 with journal.open("a", encoding="utf-8") as handle:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_docs_drift.py :6 import pathlib
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_html_weight_outliers.py :20 with open(path, "w", encoding="utf-8-sig", newline="") as handle:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_inlinks.py :7 import shutil
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_interface_binding.py :14 import pathlib
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_mcp.py :11 import shutil
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_outlinks_semantics.py :31 with open(path, "w", encoding="utf-8-sig", newline="") as handle:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_public_safety.py :5 from pathlib import Path
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_redirect_type.py :25 with open(path, "w", encoding="utf-8-sig", newline="") as handle:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_registration.py :15 from pathlib import Path
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_repetitive_path.py :39 with open(path, "w", encoding="utf-8-sig", newline="") as handle:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_reporters.py :18 with open(path, encoding="utf-8") as stream:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_robots_directives.py :71 with open(path, "w", encoding="utf-8-sig", newline="") as handle:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_runlog.py :94 with open(journal_path, "a", encoding="utf-8") as handle:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_runner_throttle.py :38 with open(os.path.join(seen["folder"], "internal_all.csv"), "w") as fh:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_sf_config.py :12 with p.open("w", encoding="utf-8") as stream:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_sf_discovery.py :107 with open(d / "internal_all.csv", "w", encoding="utf-8-sig", newline="") as f:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_sf_sitemap_reconciliation.py :17 with open(path, "w", encoding="utf-8-sig", newline="") as handle:
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_sf_timeout.py :85 "import pathlib, subprocess, sys, time; "
  • fs (weak) PavloSEO-seotools-0cc5acd/tests/test_url_encoding.py :25 with open(path, "w", encoding="utf-8-sig", newline="") as handle:

shell / exec 3

  • shell PavloSEO-seotools-0cc5acd/seohead/recon/net.py :22 import subprocess
  • shell PavloSEO-seotools-0cc5acd/seohead/sf/core/runner.py :15 import subprocess
  • shell (weak) PavloSEO-seotools-0cc5acd/tests/test_sf_timeout.py :12 import subprocess

network 36

  • net PavloSEO-seotools-0cc5acd/seohead/audit/site.py :22 from urllib.parse import urlparse
  • net PavloSEO-seotools-0cc5acd/seohead/crawl/collect.py :25 from urllib.parse import urljoin, urlsplit
  • net PavloSEO-seotools-0cc5acd/seohead/crawl/spider.py :24 from urllib.parse import urlsplit, urlunsplit
  • net PavloSEO-seotools-0cc5acd/seohead/data_sources/arsenkin.py :28 import urllib.error
  • net PavloSEO-seotools-0cc5acd/seohead/data_sources/dataforseo.py :25 import urllib.error
  • net PavloSEO-seotools-0cc5acd/seohead/data_sources/metrika.py :26 import urllib.error
  • net PavloSEO-seotools-0cc5acd/seohead/data_sources/yandex_cloud.py :34 import urllib.error
  • net PavloSEO-seotools-0cc5acd/seohead/recon/backlinks.py :19 from urllib.parse import urljoin, urlsplit
  • net PavloSEO-seotools-0cc5acd/seohead/recon/domain.py :18 import socket
  • net PavloSEO-seotools-0cc5acd/seohead/recon/mirrors.py :17 from urllib.parse import urlsplit, urlunsplit
  • net PavloSEO-seotools-0cc5acd/seohead/recon/net.py :21 import socket
  • net PavloSEO-seotools-0cc5acd/seohead/recon/regions.py :27 from urllib.parse import urljoin, urlparse
  • net PavloSEO-seotools-0cc5acd/seohead/recon/security.py :16 from urllib.parse import urlsplit, urlunsplit
  • net PavloSEO-seotools-0cc5acd/seohead/recon/tech.py :730 from urllib.parse import urlsplit
  • net PavloSEO-seotools-0cc5acd/seohead/servers/handlers.py :528 from urllib.parse import urlsplit, urlunsplit
  • net PavloSEO-seotools-0cc5acd/seohead/sf/core/auth_proxy.py :19 from urllib.parse import urlsplit
  • net PavloSEO-seotools-0cc5acd/seohead/sf/core/heuristics.py :13 import urllib.parse
  • net PavloSEO-seotools-0cc5acd/seohead/sf/core/inlinks.py :12 import urllib.parse
  • net PavloSEO-seotools-0cc5acd/seohead/sf/core/rules.py :11 import urllib.parse
  • net PavloSEO-seotools-0cc5acd/seohead/sf/core/runner.py :18 from urllib.parse import urlsplit
  • net PavloSEO-seotools-0cc5acd/seohead/sf/core/sitemap_coverage.py :17 import urllib.parse
  • net PavloSEO-seotools-0cc5acd/seohead/tools/asset_weight.py :38 from urllib.parse import urljoin
  • net PavloSEO-seotools-0cc5acd/seohead/tools/downloader.py :24 from urllib.parse import urlsplit
  • net PavloSEO-seotools-0cc5acd/seohead/tools/hreflang.py :691 from urllib.parse import urljoin
  • net PavloSEO-seotools-0cc5acd/seohead/tools/llms_txt.py :136 from urllib.parse import urlsplit, urlunsplit
  • net PavloSEO-seotools-0cc5acd/seohead/tools/logs.py :37 import socket
  • net PavloSEO-seotools-0cc5acd/seohead/tools/page_facts.py :26 from urllib.parse import urljoin, urlparse
  • net PavloSEO-seotools-0cc5acd/seohead/tools/page_type.py :29 from urllib.parse import urlparse
  • net PavloSEO-seotools-0cc5acd/seohead/tools/parser.py :26 from urllib.parse import urljoin, urlparse
  • net PavloSEO-seotools-0cc5acd/seohead/tools/redirects.py :22 from urllib.parse import urljoin
  • net PavloSEO-seotools-0cc5acd/seohead/tools/render.py :20 from urllib.parse import urljoin, urlparse
  • net PavloSEO-seotools-0cc5acd/seohead/tools/robots.py :11 from urllib.parse import urlparse, urlsplit
  • net PavloSEO-seotools-0cc5acd/seohead/tools/schema_build.py :21 from urllib.parse import urlparse
  • net PavloSEO-seotools-0cc5acd/seohead/tools/sitemap.py :32 from urllib.parse import urljoin, urlsplit, urlunsplit
  • net PavloSEO-seotools-0cc5acd/seohead/tools/soft404.py :24 from urllib.parse import urlsplit, urlunsplit
  • net (weak) PavloSEO-seotools-0cc5acd/tests/test_fetch_error_reporting.py :15 import httpx

tool registrations 50

  • seo_parse PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :48
  • seo_redirects_generate PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :56
  • seo_redirects_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :69
  • seo_crawl_site PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :74
  • seo_sitemap_crawl PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :100
  • seo_images_download PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :106
  • seo_images_optimize PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :114
  • seo_keywords_cluster PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :126
  • seo_robots_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :136
  • seo_headers_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :144
  • seo_asset_weight_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :150
  • seo_links_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :160
  • seo_hreflang_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :166
  • seo_domain_profile PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :172
  • seo_cdn_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :179
  • seo_tech_detect PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :186
  • seo_security_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :193
  • seo_backlinks_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :201
  • seo_schema_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :208
  • seo_schema_build PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :219
  • seo_duplicate_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :232
  • seo_mirror_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :246
  • seo_ai_bots_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :256
  • seo_llms_txt_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :265
  • seo_citability_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :274
  • seo_social_meta_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :284
  • seo_soft404_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :294
  • seo_log_analyze PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :304
  • seo_regions_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :316
  • seo_render_check PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :333
  • seo_site_audit PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :346
  • seo_report_build PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :369
  • seo_compare_crawls PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :379
  • seo_keywords_expand PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :393
  • seo_keywords_seasonality PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :405
  • seo_keywords_exact PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :420
  • seo_serp_fetch PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :430
  • seo_google_keywords PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :443
  • seo_google_serp PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :474
  • seo_metrika_counters PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :493
  • seo_metrika_setup PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :499
  • seo_metrika_report PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :508
  • seo_regions_tree PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :537
  • seo_spend_report PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :544
  • seo_sources_doctor PavloSEO-seotools-0cc5acd/seohead/servers/mcp_server.py :552
  • sf_audit_run PavloSEO-seotools-0cc5acd/seohead/servers/sf_mcp.py :101
  • sf_audit_summary PavloSEO-seotools-0cc5acd/seohead/servers/sf_mcp.py :121
  • sf_audit_issues PavloSEO-seotools-0cc5acd/seohead/servers/sf_mcp.py :139
  • sf_list_exports PavloSEO-seotools-0cc5acd/seohead/servers/sf_mcp.py :161
  • sf_audit_tasks PavloSEO-seotools-0cc5acd/seohead/servers/sf_mcp.py :173

declared dependencies 25

  • mcp@>=1.9,<2
  • pandas@>=2.0,<4
  • openpyxl@>=3.1,<4
  • lxml@>=4.9,<7
  • jsonschema@>=4.0,<5
  • httpx@>=0.27,<1
  • h2@>=4.1,<5
  • beautifulsoup4@>=4.12,<5
  • defusedxml@>=0.7,<1
  • Pillow@>=10.2,<13
  • pydantic@>=2.6,<3
  • advertools@>=0.16,<1
  • python-dateutil@>=2.8,<3
  • playwright@>=1.44,<2
  • python-docx@>=1.1,<2
  • scikit-learn@>=1.4,<2
  • numpy@>=1.26,<3
  • snowballstemmer@>=2.2,<4
  • build@>=1.2,<2
  • pytest@>=8.0,<10
  • pytest-cov@>=5.0,<8
  • PyYAML@>=6,<7
  • respx@>=0.21,<1
  • ruff@>=0.9,<1
  • twine@>=6,<8