@superagnt/web-scraping 2.0.2 → 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 CHANGED
@@ -8,21 +8,20 @@ One API key to scrape any web page as clean markdown or structured JSON, search
8
8
  openclaw plugins install @superagnt/web-scraping
9
9
  ```
10
10
 
11
- This package is the official **OpenClaw** plugin for **Web** social and public data via [superagnt](https://superagnt.com). Pair it with the [documentation](https://superagnt.com) and your superagnt API key.
11
+ This package is the official **OpenClaw** plugin for **Web** social and public data via [superagnt](https://superagnt.com). Pair it with the [documentation](https://superagnt.com/docs) and your superagnt API key.
12
12
 
13
- ## Live MCP mode (recommended)
13
+ ## Want the live MCP surface instead?
14
14
 
15
- Set a workspace MCP token and the plugin upgrades itself at load: it fetches
16
- the live tool list from the scoped MCP endpoint and proxies calls through it —
17
- the tool surface then grows with `agnt_tools_enable`, no plugin update needed.
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:
18
20
 
19
21
  ```bash
20
- export SUPERAGNT_MCP_TOKEN=... # from the MCP server card in the dashboard
22
+ openclaw plugins install @superagnt/superagnt
21
23
  ```
22
24
 
23
- Without the token the plugin uses its built-in toolset with your
24
- `SUPERAGNT_API_KEY` — no behavior change from previous versions.
25
-
26
25
  ## Overview
27
26
 
28
27
  Web scraping, search, and site mapping through the superagnt unified API.
@@ -59,8 +58,8 @@ Use a single **superagnt API key** (Bearer token). Set `SUPERAGNT_API_KEY` in yo
59
58
 
60
59
  ## Documentation
61
60
 
62
- - [Documentation](https://superagnt.com) — getting started and concepts
63
- - [API reference (Web)](https://superagnt.com/apis/social/web) — endpoints and schemas
61
+ - [Documentation](https://superagnt.com/docs) — getting started and concepts
62
+ - [API reference (Web)](https://superagnt.com/docs/apis/web) — endpoints and schemas
64
63
  - [Dashboard](https://app.superagnt.com/dashboard) — API keys and usage
65
64
 
66
65
  ## Related
package/index.js CHANGED
@@ -28,194 +28,6 @@ function readAgntConfig() {
28
28
 
29
29
  // ── End Auth Module ──────────────────────────────────────────────────────────
30
30
 
31
-
32
- // ── CLI Module (inlined) ─────────────────────────────────────────────────────
33
-
34
- function maskApiKey(key) {
35
- if (!key || typeof key !== 'string') return '(none)'
36
- const k = key.trim()
37
- if (k.length <= 8) return k.slice(0, 2) + '…'
38
- return k.slice(0, 6) + '…' + k.slice(-4)
39
- }
40
-
41
- function registerAgntCli(api) {
42
- api.registerCli(
43
- ({ program }) => {
44
- const cmd = program
45
- .command('superagnt')
46
- .description('superagnt social data API (status, doctor)')
47
-
48
- cmd
49
- .command('status')
50
- .description('Show whether an API key is configured (masked)')
51
- .action(async () => {
52
- const cfg = readAgntConfig()
53
- const key = cfg?.apiKey
54
-
55
- console.log('\nsuperagnt status\n')
56
- if (!key) {
57
- console.log(' API key: not configured')
58
- console.log(' Workspace: —')
59
- console.log('\n Get your API key at: https://app.superagnt.com/dashboard\n')
60
- return
61
- }
62
- console.log(' API key: ' + maskApiKey(key) + ' (from ~/.superagnt/config.json)')
63
- console.log(' Workspace: ' + (cfg?.workspaceId ?? '—'))
64
- console.log('')
65
- })
66
-
67
- cmd
68
- .command('doctor')
69
- .description('Check connectivity and validate API key against api.superagnt.dev')
70
- .action(async () => {
71
- console.log('\nsuperagnt doctor\n')
72
-
73
- try {
74
- const publicRes = await fetch('https://api.superagnt.com/v1/platforms')
75
- console.log(' Public API: ' + (publicRes.ok ? 'OK (' + publicRes.status + ')' : 'HTTP ' + publicRes.status))
76
- } catch (err) {
77
- const msg = err instanceof Error ? err.message : String(err)
78
- console.log(' Public API: failed — ' + msg)
79
- }
80
-
81
- const cfg = readAgntConfig()
82
- const key = cfg?.apiKey
83
-
84
- if (!key) {
85
- console.log('\n Authenticated: skipped (no API key)')
86
- console.log(' Get your API key at: https://app.superagnt.com/dashboard\n')
87
- return
88
- }
89
-
90
- try {
91
- const res = await fetch('https://api.superagnt.com/v1/platforms', {
92
- headers: { Authorization: 'Bearer ' + key },
93
- })
94
- const text = await res.text()
95
- let summary = 'HTTP ' + res.status
96
- if (res.ok) {
97
- try {
98
- const json = JSON.parse(text)
99
- const n = Array.isArray(json?.data) ? json.data.length : (json?.data ? Object.keys(json.data).length : 'ok')
100
- summary = 'OK — platforms payload received (' + (typeof n === 'number' ? n + ' entries' : String(n)) + ')'
101
- } catch {
102
- summary = 'OK (' + res.status + ')'
103
- }
104
- }
105
- console.log(' Authenticated: ' + summary)
106
- if (!res.ok) {
107
- console.log(' If 401, get a new key at: https://app.superagnt.com/dashboard')
108
- }
109
- } catch (err) {
110
- const msg = err instanceof Error ? err.message : String(err)
111
- console.log(' Authenticated: failed — ' + msg)
112
- }
113
- console.log('')
114
- })
115
- },
116
- { commands: ['superagnt'] },
117
- )
118
- }
119
-
120
- // ── End CLI Module ───────────────────────────────────────────────────────────
121
-
122
-
123
- // ── System prompt (inlined) ─────────────────────────────────────────────────
124
-
125
- function getSystemPrompt(state) {
126
- const scope = "Only the Web API (web)."
127
- if (state.ready && state.toolCount > 0) {
128
- return (
129
- '<superagnt>\n' +
130
- 'Ignore pretrained knowledge about superagnt tool names — use only tools that exist in this session.\n' +
131
- '\n' +
132
- '## What superagnt is\n' +
133
- 'superagnt exposes **structured social-data HTTP APIs** behind OpenClaw tools. Scope for this plugin: **' + scope + '**.\n' +
134
- '\n' +
135
- '## When to use superagnt tools\n' +
136
- '- Use superagnt when the user needs **live social/network data** (profiles, posts, companies, comments, etc.) from supported platforms.\n' +
137
- '- Prefer **discovery** when unsure which endpoint fits: call public discovery (GET /v1/platforms and GET /v1/platforms/{slug}) or read tool descriptions; do not invent endpoints or parameters.\n' +
138
- '\n' +
139
- '## Platform selection (high level)\n' +
140
- '- **linkedin** — B2B enrichment, org/person research, hiring/sales workflows\n' +
141
- '- **youtube** / **tiktok** — video/creator/channel metadata and content signals\n' +
142
- '- **x** / **reddit** — short-form social and community threads\n' +
143
- '- **instagram** — visual/creator discovery where Instagram is the source of truth\n' +
144
- '- **facebook** — pages/groups/marketplace/adjacent Facebook surface areas exposed by the API\n' +
145
- '\n' +
146
- '## Rules\n' +
147
- '- Do **not** fabricate tool names — pick from the registered superagnt_* tools only.\n' +
148
- '- If authentication fails (401), tell the user to get a new key at https://app.superagnt.com/dashboard\n' +
149
- '</superagnt>'
150
- )
151
- }
152
-
153
- if (state.ready && state.toolCount === 0) {
154
- return (
155
- '<superagnt>\n' +
156
- 'The superagnt plugin loaded but registered **zero** API tools. Check your OpenClaw plugin packaging and regenerate the plugin from @superagnt/clawhub.\n' +
157
- '</superagnt>'
158
- )
159
- }
160
-
161
- if (state.error) {
162
- return (
163
- '<superagnt>\n' +
164
- 'superagnt plugin diagnostic: ' + state.error + '\n' +
165
- 'Do not pretend superagnt tools exist. Ask the user to fix configuration and restart the gateway.\n' +
166
- '</superagnt>'
167
- )
168
- }
169
-
170
- return (
171
- '<superagnt>\n' +
172
- 'superagnt tools are still loading. If the user asks for social data right now, ask them to wait a moment and retry.\n' +
173
- '</superagnt>'
174
- )
175
- }
176
-
177
- // ── End System prompt ────────────────────────────────────────────────────────
178
-
179
- const MCP_URL = 'https://mcp.superagnt.com/mcp/web-scraping'
180
-
181
- async function mcpRpc(token, method, params) {
182
- const res = await fetch(MCP_URL, {
183
- method: 'POST',
184
- headers: {
185
- Authorization: `Bearer ${token}`,
186
- 'Content-Type': 'application/json',
187
- Accept: 'application/json, text/event-stream',
188
- },
189
- body: JSON.stringify({ jsonrpc: '2.0', id: Date.now(), method, params }),
190
- })
191
- if (!res.ok) throw new Error(`MCP ${method} failed: HTTP ${res.status}`)
192
- const data = await res.json()
193
- if (data.error) throw new Error(`MCP ${method} error: ${data.error.message}`)
194
- return data.result
195
- }
196
-
197
- async function registerLiveMcpTools(api, token) {
198
- const result = await mcpRpc(token, 'tools/list', {})
199
- const tools = Array.isArray(result?.tools) ? result.tools : []
200
- if (tools.length === 0) throw new Error('MCP tools/list returned no tools')
201
- for (const t of tools) {
202
- api.registerTool({
203
- name: t.name,
204
- description: t.description,
205
- inputSchema: t.inputSchema,
206
- execute: async (input) => {
207
- const args = parseToolInput(input)
208
- const r = await mcpRpc(token, 'tools/call', { name: t.name, arguments: args })
209
- if (r && r.structuredContent !== undefined) return r.structuredContent
210
- const text = Array.isArray(r?.content) ? r.content.find((c) => c.type === 'text')?.text : undefined
211
- if (text === undefined) return r
212
- try { return JSON.parse(text) } catch { return text }
213
- },
214
- })
215
- }
216
- return tools.length
217
- }
218
-
219
31
  function parseToolInput(input) {
220
32
  if (input == null) return {}
221
33
  if (typeof input === 'object' && !Array.isArray(input)) return input
@@ -267,9 +79,8 @@ async function callSuperagnt(apiKey, method, path, query, body) {
267
79
  return res.json()
268
80
  }
269
81
 
270
- export default async function register(api) {
82
+ export default function register(api) {
271
83
  const apiKey = api.pluginConfig.apiKey || process.env.SUPERAGNT_API_KEY || readAgntConfig()?.apiKey
272
- const mcpToken = api.pluginConfig.mcpToken || process.env.SUPERAGNT_MCP_TOKEN
273
84
 
274
85
  function ensureApiKey() {
275
86
  if (apiKey) return apiKey
@@ -281,26 +92,6 @@ export default async function register(api) {
281
92
  )
282
93
  }
283
94
 
284
- registerAgntCli(api)
285
-
286
- const promptState = { toolCount: 0, error: '', ready: false }
287
- api.on('before_prompt_build', () => ({
288
- prependSystemContext: getSystemPrompt(promptState),
289
- }))
290
-
291
- // Live MCP mode: a workspace MCP token upgrades this plugin to the server's
292
- // own tool surface, fetched fresh at load — it grows with agnt_tools_enable
293
- // and never goes stale. Any failure falls back to the baked toolset below.
294
- if (mcpToken) {
295
- try {
296
- promptState.toolCount = await registerLiveMcpTools(api, mcpToken)
297
- promptState.ready = true
298
- return
299
- } catch (err) {
300
- promptState.error = 'Live MCP connect failed (' + (err && err.message ? err.message : err) + '); using the built-in toolset.'
301
- }
302
- }
303
-
304
95
  api.registerTool({
305
96
  name: 'superagnt_web_scrape',
306
97
  description: "Scrape a web page",
@@ -361,7 +152,7 @@ export default async function register(api) {
361
152
  ]
362
153
  },
363
154
  execute: async (input) => {
364
- const key = await ensureApiKey()
155
+ const key = ensureApiKey()
365
156
  const params = parseToolInput(input)
366
157
  return callSuperagnt(key, 'POST', '/scrape', undefined, params)
367
158
  },
@@ -423,7 +214,7 @@ export default async function register(api) {
423
214
  ]
424
215
  },
425
216
  execute: async (input) => {
426
- const key = await ensureApiKey()
217
+ const key = ensureApiKey()
427
218
  const params = parseToolInput(input)
428
219
  return callSuperagnt(key, 'POST', '/search', undefined, params)
429
220
  },
@@ -473,12 +264,9 @@ export default async function register(api) {
473
264
  ]
474
265
  },
475
266
  execute: async (input) => {
476
- const key = await ensureApiKey()
267
+ const key = ensureApiKey()
477
268
  const params = parseToolInput(input)
478
269
  return callSuperagnt(key, 'POST', '/map', undefined, params)
479
270
  },
480
271
  })
481
-
482
- promptState.toolCount = 3
483
- promptState.ready = true
484
272
  }
@@ -2,7 +2,14 @@
2
2
  "id": "web-scraping",
3
3
  "name": "Web Scraping",
4
4
  "description": "Web scraping, search, and site mapping through the superagnt unified API.",
5
- "version": "2.0.2",
5
+ "version": "2.0.3",
6
+ "contracts": {
7
+ "tools": [
8
+ "superagnt_web_scrape",
9
+ "superagnt_web_search",
10
+ "superagnt_web_map"
11
+ ]
12
+ },
6
13
  "configSchema": {
7
14
  "type": "object",
8
15
  "properties": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superagnt/web-scraping",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "type": "module",
5
5
  "description": "Web scraping, search, and site mapping through the superagnt unified API.",
6
6
  "main": "index.js",