@superagnt/seo-data 2.0.3

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.
package/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # SEO data for OpenClaw — superagnt plugin
2
+
3
+ Live Google results in classic and AI Mode, keyword volume and difficulty, competitor gap analysis, backlink profiles, instant page audits and AI answer visibility. One API key, MCP tools or REST. Live Google results, keyword research, competitor and backlink gaps, page audits and AI answer visibility, all as agent tools.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ openclaw plugins install @superagnt/seo-data
9
+ ```
10
+
11
+ This package is the official **OpenClaw** plugin for **SEO** social and public data via [superagnt](https://superagnt.com). Pair it with the [documentation](https://superagnt.com/docs) and your superagnt API key.
12
+
13
+ ## Want the live MCP surface instead?
14
+
15
+ This plugin ships a fixed, baked-in toolset that only needs your
16
+ `SUPERAGNT_API_KEY`. For the live workspace tool surface — the full value
17
+ layer (data sources plus workspace Postgres, schedules, canvases,
18
+ enrichment), growing server-side with no plugin update — install the
19
+ primary superagnt plugin instead:
20
+
21
+ ```bash
22
+ openclaw plugins install @superagnt/superagnt
23
+ ```
24
+
25
+ ## Overview
26
+
27
+ SEO and search intelligence through the superagnt unified API.
28
+
29
+ ### Highlights
30
+
31
+ - Live Google organic results with positions, snippets and SERP features
32
+ - Google AI Mode answers with cited sources
33
+ - Keyword ideas, volume, CPC, difficulty and search intent
34
+ - Ranked keywords and keyword gap for any domain
35
+ - Backlink summaries, referring domains and link gap prospecting
36
+ - Instant on-page audits with every detected issue
37
+ - LLM mention metrics for answer engine optimization
38
+ - Technology stack lookup and reverse technology search
39
+
40
+ ### Example use cases
41
+
42
+ - Weekly rank tracking and SEO ops digests
43
+ - Content gap research against competitors
44
+ - Backlink gap outreach lists chained into email finding
45
+ - Site audits page by page
46
+ - AI answer visibility tracking for a brand
47
+ - Prospect lists built from technology stacks
48
+
49
+ ## Authentication
50
+
51
+ Use a single **superagnt API key** (Bearer token). Set `SUPERAGNT_API_KEY` in your environment, or complete browser login when the gateway prompts you. Create and manage keys in the [superagnt dashboard](https://app.superagnt.com/dashboard).
52
+
53
+ ## API coverage
54
+
55
+ | | |
56
+ | --- | --- |
57
+ | **Platform** | `seo` |
58
+ | **REST base** | `https://api.superagnt.com/v1/data/seo` |
59
+ | **OpenAPI operations** | 16 |
60
+ | **OpenClaw tools** | 16 |
61
+
62
+ ## Documentation
63
+
64
+ - [Documentation](https://superagnt.com/docs) — getting started and concepts
65
+ - [API reference (SEO)](https://superagnt.com/docs/apis/seo) — endpoints and schemas
66
+ - [Dashboard](https://app.superagnt.com/dashboard) — API keys and usage
67
+
68
+ ## Related
69
+
70
+ - **Skill (curl-oriented):** `clawhub install seo-data` on [ClawHub](https://clawhub.ai/superagnt/skills/seo-data)
71
+ - **All platforms plugin:** `@superagnt/openclaw-agnt-data` if you need LinkedIn, YouTube, TikTok, X, Instagram, Reddit, and Facebook in one package.
72
+
73
+ ## License
74
+
75
+ MIT
package/index.js ADDED
@@ -0,0 +1,660 @@
1
+ /**
2
+ * SEO Data — OpenClaw plugin
3
+ * Auto-generated by @superagnt/clawhub. Do not edit by hand.
4
+ */
5
+
6
+ import { homedir as _homedir } from 'node:os'
7
+ import { join as _join } from 'node:path'
8
+ import { existsSync as _existsSync, readFileSync as _readFileSync } from 'node:fs'
9
+
10
+ const BASE_URL = 'https://api.superagnt.com/v1/data/seo'
11
+
12
+
13
+ // ── Auth Module (inlined) ────────────────────────────────────────────────────
14
+
15
+ function getConfigPath() {
16
+ return _join(_homedir(), '.superagnt', 'config.json')
17
+ }
18
+
19
+ function readAgntConfig() {
20
+ const configFile = getConfigPath()
21
+ if (!_existsSync(configFile)) return null
22
+ try {
23
+ return JSON.parse(_readFileSync(configFile, 'utf-8'))
24
+ } catch {
25
+ return null
26
+ }
27
+ }
28
+
29
+ // ── End Auth Module ──────────────────────────────────────────────────────────
30
+
31
+ function parseToolInput(input) {
32
+ if (input == null) return {}
33
+ if (typeof input === 'object' && !Array.isArray(input)) return input
34
+ if (typeof input === 'string') {
35
+ const trimmed = input.trim()
36
+ if (trimmed.startsWith('{')) {
37
+ try { const parsed = JSON.parse(trimmed); if (typeof parsed === 'object' && parsed && !Array.isArray(parsed)) return parsed } catch {}
38
+ }
39
+ throw new Error('Invalid tool input: expected a JSON object with named parameters, got string: ' + trimmed.slice(0, 80))
40
+ }
41
+ throw new Error('Invalid tool input: expected a JSON object, got ' + typeof input)
42
+ }
43
+
44
+ function substitutePathParams(path, source) {
45
+ if (!source || typeof source !== 'object' || Array.isArray(source)) {
46
+ return { path, consumed: new Set() }
47
+ }
48
+ const consumed = new Set()
49
+ const next = path.replace(/\{([^/{}]+)\}/g, (_, name) => {
50
+ const v = source[name]
51
+ if (v === undefined || v === null || v === '') return `{${name}}`
52
+ consumed.add(name)
53
+ return encodeURIComponent(String(v))
54
+ })
55
+ return { path: next, consumed }
56
+ }
57
+
58
+ async function callSuperagnt(apiKey, method, path, query, body) {
59
+ const params = (query && typeof query === 'object' && !Array.isArray(query)) ? query : body
60
+ const { path: resolvedPath, consumed } = substitutePathParams(path, params)
61
+ const url = new URL(`${BASE_URL}${resolvedPath}`)
62
+ if (query && typeof query === 'object' && !Array.isArray(query)) {
63
+ for (const [k, v] of Object.entries(query)) {
64
+ if (consumed.has(k)) continue
65
+ if (v !== undefined && v !== '') url.searchParams.set(k, String(v))
66
+ }
67
+ }
68
+ const filteredBody = body && typeof body === 'object' && !Array.isArray(body)
69
+ ? Object.fromEntries(Object.entries(body).filter(([k]) => !consumed.has(k)))
70
+ : body
71
+ const res = await fetch(url.toString(), {
72
+ method,
73
+ headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
74
+ body: filteredBody ? JSON.stringify(filteredBody) : undefined,
75
+ })
76
+ if (res.status === 401) {
77
+ return { error: 'Invalid or expired API key. Get a new key at https://app.superagnt.com/dashboard' }
78
+ }
79
+ return res.json()
80
+ }
81
+
82
+ export default function register(api) {
83
+ const apiKey = api.pluginConfig.apiKey || process.env.SUPERAGNT_API_KEY || readAgntConfig()?.apiKey
84
+
85
+ function ensureApiKey() {
86
+ if (apiKey) return apiKey
87
+ throw new Error(
88
+ '[seo-data] No API key configured. ' +
89
+ 'Get your key at https://app.superagnt.com/dashboard and either:\n' +
90
+ ' 1. Export it as SUPERAGNT_API_KEY, or\n' +
91
+ ' 2. Add apiKey to your plugin config'
92
+ )
93
+ }
94
+
95
+ api.registerTool({
96
+ name: 'superagnt_seo_google_search',
97
+ description: "Live Google search results",
98
+ inputSchema: {
99
+ "type": "object",
100
+ "properties": {
101
+ "keyword": {
102
+ "type": "string",
103
+ "description": "The search query. Supports Google search operators (site:, inurl:, filetype:), which cost roughly 5x."
104
+ },
105
+ "location_code": {
106
+ "type": "integer",
107
+ "description": "Geo target as a location code. Common values: 2840 United States (default), 2826 United Kingdom, 2124 Canada, 2036 Australia, 2276 Germany, 2250 France, 2724 Spain, 2356 India, 2076 Brazil."
108
+ },
109
+ "language_code": {
110
+ "type": "string",
111
+ "description": "Two-letter language code, e.g. 'en' (default), 'de', 'es', 'fr', 'pt'."
112
+ },
113
+ "device": {
114
+ "type": "string",
115
+ "description": "Device type to emulate. Default 'desktop'."
116
+ },
117
+ "depth": {
118
+ "type": "integer",
119
+ "description": "Number of results to return, in steps of 10. Default 10 (cheapest). Each additional 10 results bills as one more results page."
120
+ }
121
+ },
122
+ "required": [
123
+ "keyword"
124
+ ]
125
+ },
126
+ execute: async (input) => {
127
+ const key = ensureApiKey()
128
+ const params = parseToolInput(input)
129
+ return callSuperagnt(key, 'POST', '/serp', undefined, params)
130
+ },
131
+ })
132
+
133
+ api.registerTool({
134
+ name: 'superagnt_seo_google_ai_mode_search',
135
+ description: "Google AI Mode results",
136
+ inputSchema: {
137
+ "type": "object",
138
+ "properties": {
139
+ "keyword": {
140
+ "type": "string",
141
+ "description": "The question or query to run through Google AI Mode."
142
+ },
143
+ "location_code": {
144
+ "type": "integer",
145
+ "description": "Geo target as a location code. Common values: 2840 United States (default), 2826 United Kingdom, 2124 Canada, 2036 Australia, 2276 Germany."
146
+ },
147
+ "language_code": {
148
+ "type": "string",
149
+ "description": "Two-letter language code, e.g. 'en' (default)."
150
+ }
151
+ },
152
+ "required": [
153
+ "keyword"
154
+ ]
155
+ },
156
+ execute: async (input) => {
157
+ const key = ensureApiKey()
158
+ const params = parseToolInput(input)
159
+ return callSuperagnt(key, 'POST', '/serp-ai-mode', undefined, params)
160
+ },
161
+ })
162
+
163
+ api.registerTool({
164
+ name: 'superagnt_seo_keyword_ideas',
165
+ description: "Keyword ideas from seed keywords",
166
+ inputSchema: {
167
+ "type": "object",
168
+ "properties": {
169
+ "keywords": {
170
+ "type": "array",
171
+ "description": "Seed keywords to expand (1-200)."
172
+ },
173
+ "location_code": {
174
+ "type": "integer",
175
+ "description": "Geo target as a location code. Default 2840 (United States)."
176
+ },
177
+ "language_code": {
178
+ "type": "string",
179
+ "description": "Two-letter language code. Default 'en'."
180
+ },
181
+ "limit": {
182
+ "type": "integer",
183
+ "description": "Max keyword ideas to return. Default 100. Cost scales with rows, so raise only when needed."
184
+ },
185
+ "offset": {
186
+ "type": "integer",
187
+ "description": "Pagination offset."
188
+ },
189
+ "filters": {
190
+ "type": "array",
191
+ "description": "Optional filter expression as [field, operator, value] triples joined by 'and'/'or'. Operators: =, <>, <, <=, >, >=, in, not_in, like, not_like (use %% wildcards with like). Recipes: [[\"keyword_info.search_volume\",\">\",100]] · keep only on-topic ideas: [[\"keyword\",\"like\",\"%deliverability%\"]] · combine: [[\"keyword_info.search_volume\",\">\",100],\"and\",[\"keyword_properties.keyword_difficulty\",\"<\",40]]."
192
+ },
193
+ "order_by": {
194
+ "type": "array",
195
+ "description": "Sort rules, e.g. [\"keyword_info.search_volume,desc\"]."
196
+ }
197
+ },
198
+ "required": [
199
+ "keywords"
200
+ ]
201
+ },
202
+ execute: async (input) => {
203
+ const key = ensureApiKey()
204
+ const params = parseToolInput(input)
205
+ return callSuperagnt(key, 'POST', '/keyword-ideas', undefined, params)
206
+ },
207
+ })
208
+
209
+ api.registerTool({
210
+ name: 'superagnt_seo_keyword_overview',
211
+ description: "Metrics for specific keywords",
212
+ inputSchema: {
213
+ "type": "object",
214
+ "properties": {
215
+ "keywords": {
216
+ "type": "array",
217
+ "description": "The exact keywords to look up (1-700). Cost scales with the number of keywords."
218
+ },
219
+ "location_code": {
220
+ "type": "integer",
221
+ "description": "Geo target as a location code. Default 2840 (United States)."
222
+ },
223
+ "language_code": {
224
+ "type": "string",
225
+ "description": "Two-letter language code. Default 'en'."
226
+ }
227
+ },
228
+ "required": [
229
+ "keywords"
230
+ ]
231
+ },
232
+ execute: async (input) => {
233
+ const key = ensureApiKey()
234
+ const params = parseToolInput(input)
235
+ return callSuperagnt(key, 'POST', '/keyword-overview', undefined, params)
236
+ },
237
+ })
238
+
239
+ api.registerTool({
240
+ name: 'superagnt_seo_search_intent',
241
+ description: "Classify keyword search intent",
242
+ inputSchema: {
243
+ "type": "object",
244
+ "properties": {
245
+ "keywords": {
246
+ "type": "array",
247
+ "description": "Keywords to classify (1-1000). Cost scales with the number of keywords."
248
+ },
249
+ "language_code": {
250
+ "type": "string",
251
+ "description": "Two-letter language code. Default 'en'."
252
+ }
253
+ },
254
+ "required": [
255
+ "keywords"
256
+ ]
257
+ },
258
+ execute: async (input) => {
259
+ const key = ensureApiKey()
260
+ const params = parseToolInput(input)
261
+ return callSuperagnt(key, 'POST', '/search-intent', undefined, params)
262
+ },
263
+ })
264
+
265
+ api.registerTool({
266
+ name: 'superagnt_seo_ranked_keywords',
267
+ description: "Keywords a domain ranks for",
268
+ inputSchema: {
269
+ "type": "object",
270
+ "properties": {
271
+ "target": {
272
+ "type": "string",
273
+ "description": "Domain (e.g. 'example.com', no protocol) or full page URL to analyze."
274
+ },
275
+ "location_code": {
276
+ "type": "integer",
277
+ "description": "Geo target as a location code. Default 2840 (United States)."
278
+ },
279
+ "language_code": {
280
+ "type": "string",
281
+ "description": "Two-letter language code. Default 'en'."
282
+ },
283
+ "limit": {
284
+ "type": "integer",
285
+ "description": "Max keywords to return. Default 100. Cost scales with rows."
286
+ },
287
+ "offset": {
288
+ "type": "integer",
289
+ "description": "Pagination offset."
290
+ },
291
+ "filters": {
292
+ "type": "array",
293
+ "description": "Optional filter expression, e.g. [[\"ranked_serp_element.serp_item.rank_absolute\", \"<=\", 20]]."
294
+ },
295
+ "order_by": {
296
+ "type": "array",
297
+ "description": "Sort rules, e.g. [\"keyword_data.keyword_info.search_volume,desc\"]."
298
+ }
299
+ },
300
+ "required": [
301
+ "target"
302
+ ]
303
+ },
304
+ execute: async (input) => {
305
+ const key = ensureApiKey()
306
+ const params = parseToolInput(input)
307
+ return callSuperagnt(key, 'POST', '/ranked-keywords', undefined, params)
308
+ },
309
+ })
310
+
311
+ api.registerTool({
312
+ name: 'superagnt_seo_keyword_gap',
313
+ description: "Keyword gap between two domains",
314
+ inputSchema: {
315
+ "type": "object",
316
+ "properties": {
317
+ "target1": {
318
+ "type": "string",
319
+ "description": "First domain (e.g. your domain), no protocol."
320
+ },
321
+ "target2": {
322
+ "type": "string",
323
+ "description": "Second domain (e.g. a competitor), no protocol."
324
+ },
325
+ "location_code": {
326
+ "type": "integer",
327
+ "description": "Geo target as a location code. Default 2840 (United States)."
328
+ },
329
+ "language_code": {
330
+ "type": "string",
331
+ "description": "Two-letter language code. Default 'en'."
332
+ },
333
+ "limit": {
334
+ "type": "integer",
335
+ "description": "Max intersecting keywords to return. Default 100."
336
+ },
337
+ "offset": {
338
+ "type": "integer",
339
+ "description": "Pagination offset."
340
+ },
341
+ "filters": {
342
+ "type": "array",
343
+ "description": "Optional filter expression as [field, operator, value] triples joined by 'and'/'or'. Operators: =, <>, <, <=, >, >=, in, not_in, like, not_like. Recipe (their wins, your gaps): [[\"first_domain_serp_element.rank_absolute\",\">\",20],\"and\",[\"second_domain_serp_element.rank_absolute\",\"<=\",10]]."
344
+ },
345
+ "order_by": {
346
+ "type": "array",
347
+ "description": "Sort rules."
348
+ }
349
+ },
350
+ "required": [
351
+ "target1",
352
+ "target2"
353
+ ]
354
+ },
355
+ execute: async (input) => {
356
+ const key = ensureApiKey()
357
+ const params = parseToolInput(input)
358
+ return callSuperagnt(key, 'POST', '/keyword-gap', undefined, params)
359
+ },
360
+ })
361
+
362
+ api.registerTool({
363
+ name: 'superagnt_seo_competitors',
364
+ description: "Find a domain's organic competitors",
365
+ inputSchema: {
366
+ "type": "object",
367
+ "properties": {
368
+ "target": {
369
+ "type": "string",
370
+ "description": "Domain to find competitors for, no protocol."
371
+ },
372
+ "location_code": {
373
+ "type": "integer",
374
+ "description": "Geo target as a location code. Default 2840 (United States)."
375
+ },
376
+ "language_code": {
377
+ "type": "string",
378
+ "description": "Two-letter language code. Default 'en'."
379
+ },
380
+ "limit": {
381
+ "type": "integer",
382
+ "description": "Max competitor domains to return. Default 100."
383
+ },
384
+ "filters": {
385
+ "type": "array",
386
+ "description": "Optional filter expression as [field, operator, value] triples. Recipe: [[\"intersections\",\">\",50]] keeps only domains sharing 50+ keywords with the target."
387
+ },
388
+ "order_by": {
389
+ "type": "array",
390
+ "description": "Sort rules, e.g. [\"intersections,desc\"]."
391
+ }
392
+ },
393
+ "required": [
394
+ "target"
395
+ ]
396
+ },
397
+ execute: async (input) => {
398
+ const key = ensureApiKey()
399
+ const params = parseToolInput(input)
400
+ return callSuperagnt(key, 'POST', '/competitors', undefined, params)
401
+ },
402
+ })
403
+
404
+ api.registerTool({
405
+ name: 'superagnt_seo_domain_overview',
406
+ description: "Domain rank and traffic overview",
407
+ inputSchema: {
408
+ "type": "object",
409
+ "properties": {
410
+ "target": {
411
+ "type": "string",
412
+ "description": "Domain to summarize, no protocol."
413
+ },
414
+ "location_code": {
415
+ "type": "integer",
416
+ "description": "Geo target as a location code. Default 2840 (United States)."
417
+ },
418
+ "language_code": {
419
+ "type": "string",
420
+ "description": "Two-letter language code. Default 'en'."
421
+ }
422
+ },
423
+ "required": [
424
+ "target"
425
+ ]
426
+ },
427
+ execute: async (input) => {
428
+ const key = ensureApiKey()
429
+ const params = parseToolInput(input)
430
+ return callSuperagnt(key, 'POST', '/domain-overview', undefined, params)
431
+ },
432
+ })
433
+
434
+ api.registerTool({
435
+ name: 'superagnt_seo_backlinks_summary',
436
+ description: "Backlink profile summary",
437
+ inputSchema: {
438
+ "type": "object",
439
+ "properties": {
440
+ "target": {
441
+ "type": "string",
442
+ "description": "Domain, subdomain or full page URL. Domains without protocol; pages with protocol."
443
+ },
444
+ "include_subdomains": {
445
+ "type": "boolean",
446
+ "description": "Count links to subdomains too. Default true."
447
+ },
448
+ "exclude_internal_backlinks": {
449
+ "type": "boolean",
450
+ "description": "Ignore links from the target to itself. Default true."
451
+ }
452
+ },
453
+ "required": [
454
+ "target"
455
+ ]
456
+ },
457
+ execute: async (input) => {
458
+ const key = ensureApiKey()
459
+ const params = parseToolInput(input)
460
+ return callSuperagnt(key, 'POST', '/backlinks-summary', undefined, params)
461
+ },
462
+ })
463
+
464
+ api.registerTool({
465
+ name: 'superagnt_seo_referring_domains',
466
+ description: "Referring domains for a target",
467
+ inputSchema: {
468
+ "type": "object",
469
+ "properties": {
470
+ "target": {
471
+ "type": "string",
472
+ "description": "Domain, subdomain or full page URL to list referring domains for."
473
+ },
474
+ "limit": {
475
+ "type": "integer",
476
+ "description": "Max referring domains to return. Default 100. Cost scales with rows."
477
+ },
478
+ "offset": {
479
+ "type": "integer",
480
+ "description": "Pagination offset."
481
+ },
482
+ "exclude_internal_backlinks": {
483
+ "type": "boolean",
484
+ "description": "Ignore links from the target to itself. Default true."
485
+ },
486
+ "filters": {
487
+ "type": "array",
488
+ "description": "Optional filter expression as [field, operator, value] triples. Operators: =, <>, <, <=, >, >=, in, not_in, like, not_like. Recipe: [[\"rank\",\">\",100]] keeps stronger referring domains (rank is the referring domain's authority, higher is better)."
489
+ },
490
+ "order_by": {
491
+ "type": "array",
492
+ "description": "Sort rules, e.g. [\"rank,desc\"]."
493
+ }
494
+ },
495
+ "required": [
496
+ "target"
497
+ ]
498
+ },
499
+ execute: async (input) => {
500
+ const key = ensureApiKey()
501
+ const params = parseToolInput(input)
502
+ return callSuperagnt(key, 'POST', '/referring-domains', undefined, params)
503
+ },
504
+ })
505
+
506
+ api.registerTool({
507
+ name: 'superagnt_seo_backlink_gap',
508
+ description: "Domains linking to competitors but not you",
509
+ inputSchema: {
510
+ "type": "object",
511
+ "properties": {
512
+ "targets": {
513
+ "type": "array",
514
+ "description": "Competitor domains whose backlink sources to intersect (1-20)."
515
+ },
516
+ "exclude_targets": {
517
+ "type": "array",
518
+ "description": "Domains the referring sites must NOT already link to. Put your own domain here."
519
+ },
520
+ "limit": {
521
+ "type": "integer",
522
+ "description": "Max referring domains to return. Default 100."
523
+ },
524
+ "offset": {
525
+ "type": "integer",
526
+ "description": "Pagination offset."
527
+ },
528
+ "filters": {
529
+ "type": "array",
530
+ "description": "Optional filter expression, e.g. minimum domain rank."
531
+ },
532
+ "order_by": {
533
+ "type": "array",
534
+ "description": "Sort rules, e.g. [\"1.rank,desc\"]."
535
+ }
536
+ },
537
+ "required": [
538
+ "targets"
539
+ ]
540
+ },
541
+ execute: async (input) => {
542
+ const key = ensureApiKey()
543
+ const params = parseToolInput(input)
544
+ return callSuperagnt(key, 'POST', '/backlink-gap', undefined, params)
545
+ },
546
+ })
547
+
548
+ api.registerTool({
549
+ name: 'superagnt_seo_page_audit',
550
+ description: "Instant on-page audit of a URL",
551
+ inputSchema: {
552
+ "type": "object",
553
+ "properties": {
554
+ "url": {
555
+ "type": "string",
556
+ "description": "The page URL to audit (with protocol)."
557
+ },
558
+ "enable_javascript": {
559
+ "type": "boolean",
560
+ "description": "Render JavaScript before auditing. Slower; only for JS-rendered pages."
561
+ }
562
+ },
563
+ "required": [
564
+ "url"
565
+ ]
566
+ },
567
+ execute: async (input) => {
568
+ const key = ensureApiKey()
569
+ const params = parseToolInput(input)
570
+ return callSuperagnt(key, 'POST', '/page-audit', undefined, params)
571
+ },
572
+ })
573
+
574
+ api.registerTool({
575
+ name: 'superagnt_seo_ai_visibility',
576
+ description: "How often LLMs mention a domain",
577
+ inputSchema: {
578
+ "type": "object",
579
+ "properties": {
580
+ "targets": {
581
+ "type": "array",
582
+ "description": "Domains to measure LLM mention metrics for, no protocol. Pass at least one of targets or keywords."
583
+ },
584
+ "keywords": {
585
+ "type": "array",
586
+ "description": "Keyword phrases to measure LLM mention metrics for, as an alternative or addition to domains."
587
+ },
588
+ "limit": {
589
+ "type": "integer",
590
+ "description": "Max rows to return. Default 100. Cost scales with rows."
591
+ }
592
+ }
593
+ },
594
+ execute: async (input) => {
595
+ const key = ensureApiKey()
596
+ const params = parseToolInput(input)
597
+ return callSuperagnt(key, 'POST', '/ai-visibility', undefined, params)
598
+ },
599
+ })
600
+
601
+ api.registerTool({
602
+ name: 'superagnt_seo_tech_stack',
603
+ description: "Technologies a website runs",
604
+ inputSchema: {
605
+ "type": "object",
606
+ "properties": {
607
+ "target": {
608
+ "type": "string",
609
+ "description": "Domain to inspect, no protocol."
610
+ }
611
+ },
612
+ "required": [
613
+ "target"
614
+ ]
615
+ },
616
+ execute: async (input) => {
617
+ const key = ensureApiKey()
618
+ const params = parseToolInput(input)
619
+ return callSuperagnt(key, 'POST', '/tech-stack', undefined, params)
620
+ },
621
+ })
622
+
623
+ api.registerTool({
624
+ name: 'superagnt_seo_tech_search',
625
+ description: "Find websites by technology",
626
+ inputSchema: {
627
+ "type": "object",
628
+ "properties": {
629
+ "technologies": {
630
+ "type": "array",
631
+ "description": "Technology names the sites must run, e.g. [\"Shopify\", \"Klaviyo\"]. Multiple entries intersect."
632
+ },
633
+ "limit": {
634
+ "type": "integer",
635
+ "description": "Max domains to return. Default 100. Per-row cost is high; raise deliberately."
636
+ },
637
+ "offset": {
638
+ "type": "integer",
639
+ "description": "Pagination offset."
640
+ },
641
+ "filters": {
642
+ "type": "array",
643
+ "description": "Optional filter expression, e.g. [[\"country_iso_code\", \"=\", \"US\"]]."
644
+ },
645
+ "order_by": {
646
+ "type": "array",
647
+ "description": "Sort rules, e.g. [\"domain_rank,desc\"]."
648
+ }
649
+ },
650
+ "required": [
651
+ "technologies"
652
+ ]
653
+ },
654
+ execute: async (input) => {
655
+ const key = ensureApiKey()
656
+ const params = parseToolInput(input)
657
+ return callSuperagnt(key, 'POST', '/tech-search', undefined, params)
658
+ },
659
+ })
660
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "id": "seo-data",
3
+ "name": "SEO Data",
4
+ "description": "SEO and search intelligence through the superagnt unified API.",
5
+ "version": "2.0.3",
6
+ "contracts": {
7
+ "tools": [
8
+ "superagnt_seo_google_search",
9
+ "superagnt_seo_google_ai_mode_search",
10
+ "superagnt_seo_keyword_ideas",
11
+ "superagnt_seo_keyword_overview",
12
+ "superagnt_seo_search_intent",
13
+ "superagnt_seo_ranked_keywords",
14
+ "superagnt_seo_keyword_gap",
15
+ "superagnt_seo_competitors",
16
+ "superagnt_seo_domain_overview",
17
+ "superagnt_seo_backlinks_summary",
18
+ "superagnt_seo_referring_domains",
19
+ "superagnt_seo_backlink_gap",
20
+ "superagnt_seo_page_audit",
21
+ "superagnt_seo_ai_visibility",
22
+ "superagnt_seo_tech_stack",
23
+ "superagnt_seo_tech_search"
24
+ ]
25
+ },
26
+ "configSchema": {
27
+ "type": "object",
28
+ "properties": {
29
+ "apiKey": {
30
+ "type": "string",
31
+ "description": "Your superagnt API key. Get one at https://app.superagnt.com/dashboard or store in ~/.superagnt/config.json via CLI login."
32
+ }
33
+ },
34
+ "additionalProperties": false
35
+ }
36
+ }
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@superagnt/seo-data",
3
+ "version": "2.0.3",
4
+ "type": "module",
5
+ "description": "SEO and search intelligence through the superagnt unified API.",
6
+ "main": "index.js",
7
+ "license": "MIT",
8
+ "homepage": "https://superagnt.com/r/npm-seo-data-docs",
9
+ "keywords": [
10
+ "openclaw",
11
+ "openclaw-plugin",
12
+ "superagnt",
13
+ "mcp",
14
+ "seo",
15
+ "social-data",
16
+ "api",
17
+ "ai-agent",
18
+ "seo api",
19
+ "serp api",
20
+ "keyword research api",
21
+ "backlink api",
22
+ "rank tracking api",
23
+ "ai agent seo tools",
24
+ "answer engine optimization"
25
+ ],
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "files": [
30
+ "index.js",
31
+ "openclaw.plugin.json",
32
+ "README.md"
33
+ ],
34
+ "openclaw": {
35
+ "extensions": [
36
+ "./index.js"
37
+ ],
38
+ "compat": {
39
+ "pluginApi": ">=2026.3.24-beta.2",
40
+ "minGatewayVersion": "2026.3.24-beta.2"
41
+ },
42
+ "build": {
43
+ "openclawVersion": "2026.3.24-beta.2",
44
+ "pluginSdkVersion": "2026.3.24-beta.2"
45
+ }
46
+ }
47
+ }