diff --git a/tools/REGISTRY.md b/tools/REGISTRY.md index 3b430be..85a6cec 100644 --- a/tools/REGISTRY.md +++ b/tools/REGISTRY.md @@ -26,6 +26,7 @@ Quick reference for AI agents to discover tool capabilities and integration meth | ahrefs | SEO | ✓ | - | [✓](clis/ahrefs.js) | - | [ahrefs.md](integrations/ahrefs.md) | | dataforseo | SEO | ✓ | - | [✓](clis/dataforseo.js) | ✓ | [dataforseo.md](integrations/dataforseo.md) | | keywords-everywhere | SEO | ✓ | - | [✓](clis/keywords-everywhere.js) | - | [keywords-everywhere.md](integrations/keywords-everywhere.md) | +| rankparse | SEO | ✓ | ✓ | [✓](clis/rankparse.js) | - | [rankparse.md](integrations/rankparse.md) | | clearbit | Data Enrichment | ✓ | - | [✓](clis/clearbit.js) | ✓ | [clearbit.md](integrations/clearbit.md) | | apollo | Data Enrichment | ✓ | - | [✓](clis/apollo.js) | - | [apollo.md](integrations/apollo.md) | | zoominfo | Data Enrichment | ✓ | ✓ | [✓](clis/zoominfo.js) | - | [zoominfo.md](integrations/zoominfo.md) | @@ -127,8 +128,9 @@ Search engine optimization tools for keyword research, rank tracking, and site a | **ahrefs** | Backlink analysis, content research | Best for links | | **dataforseo** | SERP tracking, backlinks, on-page audits | Comprehensive API | | **keywords-everywhere** | Quick keyword research, traffic estimates | Credit-based | +| **rankparse** | Cheap, agent-friendly backlinks + domain data | Credit-based, MCP available | -**Agent recommendation**: Google Search Console is essential (free). Add Semrush or Ahrefs for competitive research. DataForSEO for programmatic SERP data. Keywords Everywhere for quick keyword lookups. +**Agent recommendation**: Google Search Console is essential (free). Add Semrush or Ahrefs for competitive research. DataForSEO for programmatic SERP data. Keywords Everywhere for quick keyword lookups. RankParse for agent workflows where per-call cost matters — backlinks, domain authority, and tech stack at a fraction of enterprise pricing. ### CRM diff --git a/tools/clis/rankparse.js b/tools/clis/rankparse.js new file mode 100755 index 0000000..5a561a0 --- /dev/null +++ b/tools/clis/rankparse.js @@ -0,0 +1,196 @@ +#!/usr/bin/env node + +const API_KEY = process.env.RANKPARSE_API_KEY +const BASE_URL = 'https://api.rankparse.com/v1' + +if (!API_KEY) { + console.error(JSON.stringify({ error: 'RANKPARSE_API_KEY environment variable required' })) + process.exit(1) +} + +async function api(method, path, body) { + if (args['dry-run']) { + return { _dry_run: true, method, url: `${BASE_URL}${path}`, headers: { 'X-API-Key': '***', 'Content-Type': 'application/json' }, body } + } + const init = { + method, + headers: { + 'X-API-Key': API_KEY, + 'Content-Type': 'application/json', + }, + } + if (body) init.body = JSON.stringify(body) + const res = await fetch(`${BASE_URL}${path}`, init) + const text = await res.text() + try { + return JSON.parse(text) + } catch { + return { status: res.status, body: text } + } +} + +function parseArgs(args) { + const result = { _: [] } + for (let i = 0; i < args.length; i++) { + const arg = args[i] + if (arg.startsWith('--')) { + const key = arg.slice(2) + const next = args[i + 1] + if (next && !next.startsWith('--')) { + result[key] = next + i++ + } else { + result[key] = true + } + } else { + result._.push(arg) + } + } + return result +} + +const args = parseArgs(process.argv.slice(2)) +const [cmd, sub, ...rest] = args._ + +function requireDomain() { + if (!args.domain) return { error: '--domain required' } + return null +} + +function requireUrl() { + if (!args.url) return { error: '--url required' } + return null +} + +async function main() { + let result + + switch (cmd) { + case 'domain-authority': + case 'domain-rank': + case 'tech-stack': + case 'site-health': + case 'similar-domains': + case 'link-audit': + case 'site-explorer': + case 'crawl-history': { + const err = requireDomain(); if (err) { result = err; break } + result = await api('GET', `/${cmd}?domain=${encodeURIComponent(args.domain)}`) + break + } + + case 'backlinks': { + const err = requireDomain(); if (err) { result = err; break } + const params = new URLSearchParams({ domain: args.domain }) + if (args.limit) params.set('limit', args.limit) + if (args.sort) params.set('sort', args.sort) + if (args['from-domain']) params.set('from_domain', args['from-domain']) + if (args['link-type']) params.set('link_type', args['link-type']) + if (args.score) params.set('score', 'true') + result = await api('GET', `/backlinks?${params}`) + break + } + + case 'referring-domains': + case 'outbound-links': + case 'anchor-text': + case 'top-pages': + case 'sitemap': { + const err = requireDomain(); if (err) { result = err; break } + const params = new URLSearchParams({ domain: args.domain }) + if (args.limit) params.set('limit', args.limit) + result = await api('GET', `/${cmd}?${params}`) + break + } + + case 'domain-overlap': { + if (!args.domains) { result = { error: '--domains required (comma-separated, 2-5 domains)' }; break } + const params = new URLSearchParams({ domains: args.domains }) + if (args.limit) params.set('limit', args.limit) + result = await api('GET', `/domain-overlap?${params}`) + break + } + + case 'link-intersect': { + if (!args['domain-a'] || !args['domain-b']) { result = { error: '--domain-a and --domain-b required' }; break } + const params = new URLSearchParams({ domain_a: args['domain-a'], domain_b: args['domain-b'] }) + if (args.limit) params.set('limit', args.limit) + result = await api('GET', `/link-intersect?${params}`) + break + } + + case 'competitor-gap': { + const err = requireDomain(); if (err) { result = err; break } + if (!args.vs) { result = { error: '--vs required (competitor domain)' }; break } + const params = new URLSearchParams({ domain: args.domain, vs: args.vs }) + if (args.limit) params.set('limit', args.limit) + result = await api('GET', `/competitor-gap?${params}`) + break + } + + case 'page-seo': { + const err = requireUrl(); if (err) { result = err; break } + result = await api('GET', `/page-seo?url=${encodeURIComponent(args.url)}`) + break + } + + case 'page-performance': { + const err = requireUrl(); if (err) { result = err; break } + const params = new URLSearchParams({ url: args.url }) + if (args.strategy) params.set('strategy', args.strategy) + result = await api('GET', `/page-performance?${params}`) + break + } + + case 'batch': { + if (!args.domains) { result = { error: '--domains required (comma-separated)' }; break } + const domains = args.domains.split(',').map(d => d.trim()).filter(Boolean) + result = await api('POST', '/batch', { domains }) + break + } + + case 'me': + result = await api('GET', '/me') + break + + case 'credits': + result = await api('GET', '/credits') + break + + default: + result = { + error: 'Unknown command', + usage: { + 'domain-authority': 'domain-authority --domain ', + 'domain-rank': 'domain-rank --domain ', + 'backlinks': 'backlinks --domain [--limit ] [--sort importance|recent] [--from-domain ] [--link-type ] [--score]', + 'referring-domains': 'referring-domains --domain [--limit ]', + 'outbound-links': 'outbound-links --domain [--limit ]', + 'anchor-text': 'anchor-text --domain [--limit ]', + 'top-pages': 'top-pages --domain [--limit ]', + 'domain-overlap': 'domain-overlap --domains [--limit ]', + 'link-intersect': 'link-intersect --domain-a --domain-b [--limit ]', + 'competitor-gap': 'competitor-gap --domain --vs [--limit ]', + 'similar-domains': 'similar-domains --domain ', + 'tech-stack': 'tech-stack --domain ', + 'site-health': 'site-health --domain ', + 'sitemap': 'sitemap --domain [--limit ]', + 'crawl-history': 'crawl-history --domain ', + 'page-seo': 'page-seo --url ', + 'page-performance': 'page-performance --url [--strategy mobile|desktop]', + 'link-audit': 'link-audit --domain ', + 'site-explorer': 'site-explorer --domain ', + 'batch': 'batch --domains ', + 'me': 'me (account info + credit balance)', + 'credits': 'credits (credit balance)', + } + } + } + + console.log(JSON.stringify(result, null, 2)) +} + +main().catch(err => { + console.error(JSON.stringify({ error: err.message })) + process.exit(1) +}) diff --git a/tools/integrations/rankparse.md b/tools/integrations/rankparse.md new file mode 100644 index 0000000..80479b4 --- /dev/null +++ b/tools/integrations/rankparse.md @@ -0,0 +1,257 @@ +# RankParse + +Agent-friendly SEO data API for backlinks, domain authority, tech stack, and on-page metadata. Designed as a low-cost alternative to enterprise SEO suites. + +## Capabilities + +| Integration | Available | Notes | +|-------------|-----------|-------| +| API | ✓ | REST API at `api.rankparse.com` | +| MCP | ✓ | Hosted MCP server for agent use | +| CLI | [✓](../clis/rankparse.js) | Node CLI wrapper | +| SDK | - | API-only (SDKs in progress) | + +## Authentication + +- **Type**: API Key +- **Header**: `X-API-Key: rp_...` +- **Get key**: Sign up at https://rankparse.com and create a key in the dashboard +- **Billing**: Credit-based (one-time credit packs, no subscription). Each endpoint deducts a fixed number of credits per call. + +## Common Agent Operations + +### Domain authority + +```bash +GET https://api.rankparse.com/v1/domain-authority?domain=example.com + +X-API-Key: rp_... +``` + +Returns authority score, registered date, registrar, and popularity rank. + +### Backlinks + +```bash +GET https://api.rankparse.com/v1/backlinks?domain=example.com&limit=100 + +X-API-Key: rp_... +``` + +Optional params: `sort=importance|recent`, `from_domain=`, `link_type=`, `score=true`. + +### Referring domains + +```bash +GET https://api.rankparse.com/v1/referring-domains?domain=example.com&limit=100 + +X-API-Key: rp_... +``` + +### Outbound links + +```bash +GET https://api.rankparse.com/v1/outbound-links?domain=example.com&limit=100 + +X-API-Key: rp_... +``` + +### Anchor text profile + +```bash +GET https://api.rankparse.com/v1/anchor-text?domain=example.com&limit=100 + +X-API-Key: rp_... +``` + +### Top pages + +```bash +GET https://api.rankparse.com/v1/top-pages?domain=example.com&limit=50 + +X-API-Key: rp_... +``` + +### Domain overlap + +```bash +GET https://api.rankparse.com/v1/domain-overlap?domains=a.com,b.com,c.com + +X-API-Key: rp_... +``` + +Compare 2–5 domains. + +### Link intersect + +```bash +GET https://api.rankparse.com/v1/link-intersect?domain_a=a.com&domain_b=b.com + +X-API-Key: rp_... +``` + +Domains that link to both targets. + +### Competitor gap + +```bash +GET https://api.rankparse.com/v1/competitor-gap?domain=mysite.com&vs=competitor.com + +X-API-Key: rp_... +``` + +### Similar domains + +```bash +GET https://api.rankparse.com/v1/similar-domains?domain=example.com + +X-API-Key: rp_... +``` + +### Tech stack + +```bash +GET https://api.rankparse.com/v1/tech-stack?domain=example.com + +X-API-Key: rp_... +``` + +### Page SEO + +```bash +GET https://api.rankparse.com/v1/page-seo?url=https://example.com/page + +X-API-Key: rp_... +``` + +Returns title, meta description, OG tags, canonical, and structured metadata for a single URL. + +### Page performance + +```bash +GET https://api.rankparse.com/v1/page-performance?url=https://example.com/page&strategy=mobile + +X-API-Key: rp_... +``` + +Core Web Vitals via Google PageSpeed Insights. Daily quotas apply. + +### Site health + +```bash +GET https://api.rankparse.com/v1/site-health?domain=example.com + +X-API-Key: rp_... +``` + +### Sitemap + +```bash +GET https://api.rankparse.com/v1/sitemap?domain=example.com&limit=100 + +X-API-Key: rp_... +``` + +### Crawl history + +```bash +GET https://api.rankparse.com/v1/crawl-history?domain=example.com + +X-API-Key: rp_... +``` + +Wayback Machine snapshots for the domain. + +### Link audit + +```bash +GET https://api.rankparse.com/v1/link-audit?domain=example.com + +X-API-Key: rp_... +``` + +Combined health score, risk flags, anchor profile, and top backlinks. + +### Site explorer + +```bash +GET https://api.rankparse.com/v1/site-explorer?domain=example.com + +X-API-Key: rp_... +``` + +All-in-one snapshot of a domain. + +### Batch lookup + +```bash +POST https://api.rankparse.com/v1/batch +Content-Type: application/json +X-API-Key: rp_... + +{ "domains": ["a.com", "b.com", "c.com"] } +``` + +Bulk domain summaries in one call. + +## Free Tools (Unauthenticated) + +Public, IP-rate-limited endpoints for quick lookups without an API key: + +- `GET /v1/tools/backlinks?domain=` +- `GET /v1/tools/domain-authority?domain=` +- `GET /v1/tools/tech-stack?domain=` +- `GET /v1/tools/similar-websites?domain=` +- `GET /v1/tools/domain-age?domain=` +- `GET /v1/tools/meta-tag-analyzer?url=` +- `GET /v1/tools/link-intersect?domain_a=&domain_b=` +- `GET /v1/tools/page-speed?url=` + +## Key Response Fields + +### Domain Metrics +- `authority` - Domain authority score +- `popularity_rank` - Tranco popularity rank +- `registered_at` - Domain registration date +- `registrar` - Registrar name + +### Backlink Fields +- `from_url` - Source URL +- `to_url` - Target URL +- `anchor` - Anchor text +- `link_type` - dofollow / nofollow / ugc / sponsored +- `first_seen` - First discovery date + +## When to Use + +- Backlink discovery and analysis +- Competitor link research and gap analysis +- Domain authority lookups at scale +- Tech stack detection +- On-page SEO audits +- Sitemap and crawl history discovery +- Agent-driven SEO workflows where per-call cost matters + +## Pricing Model + +- Pay-as-you-go credit packs (no subscription) +- Most domain endpoints: 1–2 credits per call +- Aggregated endpoints (overlap, intersect, similar, gap): 5 credits +- Link audit: 8 credits +- Site explorer: 10 credits +- Batch: 1 credit per domain +- Free tier available for unauthenticated endpoints + +## MCP Server + +RankParse ships a hosted MCP server exposing all endpoints as tools — connect from Claude, Cursor, or any MCP-compatible agent. See https://rankparse.com for connection details. + +## Relevant Skills + +- seo-audit +- content-strategy +- competitors +- competitor-profiling +- ai-seo +- site-architecture +- schema