@mrscraper/opencode 0.0.0-stage → 0.2.0
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/CHANGELOG.md +25 -0
- package/LICENSE +21 -0
- package/README.md +251 -2
- package/index.ts +93 -0
- package/package.json +51 -4
- package/skills/mrscraper/SKILL.md +327 -0
- package/skills/mrscraper-fetch/SKILL.md +213 -0
- package/skills/mrscraper-scrape/SKILL.md +206 -0
- package/skills/mrscraper-serp/SKILL.md +123 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the MrScraper OpenCode plugin are documented here. The
|
|
4
|
+
project follows [Semantic Versioning](https://semver.org/).
|
|
5
|
+
|
|
6
|
+
## 0.2.0 - 2026-10-12
|
|
7
|
+
|
|
8
|
+
- Added OpenCode 2 support. OpenCode 2 does not run OpenCode 1 plugins; the
|
|
9
|
+
package now default-exports one object with an OpenCode 2 `setup()`, which
|
|
10
|
+
registers the `mrscraper` MCP server and the four skills through MCP and
|
|
11
|
+
skill transforms, and an OpenCode 1 `server()`, which keeps the existing
|
|
12
|
+
config hook.
|
|
13
|
+
- OpenCode 1 now needs 1.18.29 or later (the first release that loads the
|
|
14
|
+
object form). On older releases, pin `@mrscraper/opencode@0.1.0`.
|
|
15
|
+
- The `MrScraperPlugin` named export was removed; use the default export.
|
|
16
|
+
- Documented OpenCode 2 install, sign-in, API-key configuration
|
|
17
|
+
(`mcp.servers`), and update commands.
|
|
18
|
+
|
|
19
|
+
## 0.1.0 - 2026-10-05
|
|
20
|
+
|
|
21
|
+
- Added the initial `@mrscraper/opencode` plugin: registers the hosted
|
|
22
|
+
MrScraper MCP server (`https://mcp.mrscraper.com/mcp`, OAuth 2.1) as
|
|
23
|
+
`mrscraper` unless the user already defines that server, and loads the
|
|
24
|
+
`mrscraper`, `mrscraper-fetch`, `mrscraper-scrape`, and `mrscraper-serp`
|
|
25
|
+
skills from the MrScraper Claude plugin 0.1.4.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MrScraper
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,3 +1,252 @@
|
|
|
1
|
-
#
|
|
1
|
+
# MrScraper for OpenCode
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
MrScraper connects [OpenCode](https://opencode.ai) to a hosted MCP server for
|
|
4
|
+
fetching public web pages, managed structured extraction, Google discovery,
|
|
5
|
+
saved scraper reruns, stored results, and account usage. The plugin also
|
|
6
|
+
includes four focused skills that help OpenCode choose the right workflow and
|
|
7
|
+
preserve raw page content.
|
|
8
|
+
|
|
9
|
+
The same package works in OpenCode 2 and OpenCode 1.
|
|
10
|
+
|
|
11
|
+
## What this plugin adds
|
|
12
|
+
|
|
13
|
+
- An MCP server named `mrscraper` that points at the hosted Streamable HTTP
|
|
14
|
+
endpoint `https://mcp.mrscraper.com/mcp`.
|
|
15
|
+
- OAuth 2.1 sign-in handled by OpenCode; no credential is stored in this
|
|
16
|
+
package.
|
|
17
|
+
- The `mrscraper`, `mrscraper-fetch`, `mrscraper-scrape`, and `mrscraper-serp`
|
|
18
|
+
skills.
|
|
19
|
+
- A fetch-first workflow that keeps raw page responses available for analysis,
|
|
20
|
+
verification, and follow-up transformations.
|
|
21
|
+
|
|
22
|
+
If your configuration already defines a `mrscraper` MCP server, the plugin
|
|
23
|
+
keeps your entry and only adds the skills. It also leaves any skill with the
|
|
24
|
+
same name that you already have in place.
|
|
25
|
+
|
|
26
|
+
## Requirements
|
|
27
|
+
|
|
28
|
+
- OpenCode 2 (verified with 2.0.26), or OpenCode 1.18.29 or later (verified
|
|
29
|
+
with 1.18.29 and 1.19.0). On older OpenCode 1 releases, pin
|
|
30
|
+
`@mrscraper/opencode@0.1.0`.
|
|
31
|
+
- A [MrScraper](https://app.mrscraper.com) account.
|
|
32
|
+
- Permission to access and process the target content.
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
### OpenCode 2
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
opencode plugin add @mrscraper/opencode
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This adds the package to `plugins` in your global configuration. To enable it
|
|
43
|
+
for one project instead, add it to that project's `opencode.jsonc`:
|
|
44
|
+
|
|
45
|
+
```jsonc
|
|
46
|
+
{
|
|
47
|
+
"$schema": "https://opencode.ai/config.json",
|
|
48
|
+
"plugins": ["@mrscraper/opencode"]
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### OpenCode 1
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
opencode plugin @mrscraper/opencode --global
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or add the package to the `plugin` list in `~/.config/opencode/opencode.json`
|
|
59
|
+
(all projects) or a project's `opencode.json`:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"$schema": "https://opencode.ai/config.json",
|
|
64
|
+
"plugin": ["@mrscraper/opencode"]
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
OpenCode installs npm plugins when it starts and caches them.
|
|
69
|
+
|
|
70
|
+
## Sign in
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
opencode mcp auth mrscraper
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
In OpenCode 2 you can also run `/mcps` in a session, select `mrscraper`, and
|
|
77
|
+
sign in there. OpenCode opens the MrScraper consent page in your browser,
|
|
78
|
+
registers its own OAuth client, and stores the tokens outside your project
|
|
79
|
+
configuration. Never paste OAuth tokens or API keys into chat.
|
|
80
|
+
|
|
81
|
+
Check the connection:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
opencode mcp list
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`mrscraper` shows `needs authentication` before sign-in and `connected`
|
|
88
|
+
afterwards.
|
|
89
|
+
|
|
90
|
+
On a machine without a local browser, use an API key instead (next section).
|
|
91
|
+
OpenCode 1 waits for the browser on `http://127.0.0.1:19876/mcp/oauth/callback`,
|
|
92
|
+
so you can also forward that port, for example
|
|
93
|
+
`ssh -L 19876:127.0.0.1:19876 <host>`.
|
|
94
|
+
|
|
95
|
+
## Use an API key instead of OAuth
|
|
96
|
+
|
|
97
|
+
Create a key at [app.mrscraper.com/api-tokens](https://app.mrscraper.com/api-tokens),
|
|
98
|
+
export it as `MRSCRAPER_API_KEY` in the environment that starts OpenCode, and
|
|
99
|
+
define the server yourself.
|
|
100
|
+
|
|
101
|
+
OpenCode 2 (`opencode.jsonc`):
|
|
102
|
+
|
|
103
|
+
```jsonc
|
|
104
|
+
{
|
|
105
|
+
"$schema": "https://opencode.ai/config.json",
|
|
106
|
+
"plugins": ["@mrscraper/opencode"],
|
|
107
|
+
"mcp": {
|
|
108
|
+
"servers": {
|
|
109
|
+
"mrscraper": {
|
|
110
|
+
"type": "remote",
|
|
111
|
+
"url": "https://mcp.mrscraper.com/mcp",
|
|
112
|
+
"oauth": false,
|
|
113
|
+
"headers": { "Authorization": "Bearer {env:MRSCRAPER_API_KEY}" }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
OpenCode 1 (`opencode.json`):
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"$schema": "https://opencode.ai/config.json",
|
|
125
|
+
"plugin": ["@mrscraper/opencode"],
|
|
126
|
+
"mcp": {
|
|
127
|
+
"mrscraper": {
|
|
128
|
+
"type": "remote",
|
|
129
|
+
"url": "https://mcp.mrscraper.com/mcp",
|
|
130
|
+
"oauth": false,
|
|
131
|
+
"headers": {
|
|
132
|
+
"Authorization": "Bearer {env:MRSCRAPER_API_KEY}"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
OpenCode substitutes `{env:MRSCRAPER_API_KEY}` when it loads the configuration,
|
|
140
|
+
so the key stays out of the file. In OpenCode 2 the substitution happens in the
|
|
141
|
+
background service, so the variable must be set where the service starts; after
|
|
142
|
+
setting it, run `opencode service restart` from that shell. An API key carries
|
|
143
|
+
your full account authority; OAuth scopes do not apply to it.
|
|
144
|
+
|
|
145
|
+
## Try it
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
Fetch https://www.scrapethissite.com/pages/simple/ and summarize the page.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The server provides these tools. OpenCode 1 shows them as `mrscraper_<tool>`;
|
|
152
|
+
OpenCode 2 reaches MCP tools through Code Mode by default.
|
|
153
|
+
|
|
154
|
+
| Tool | Purpose |
|
|
155
|
+
| --- | --- |
|
|
156
|
+
| `fetch` | Retrieve and preserve a known page's raw response. |
|
|
157
|
+
| `scrape` | Run managed structured extraction or bounded site mapping. |
|
|
158
|
+
| `serp` | Discover public pages through Google. |
|
|
159
|
+
| `rerun` | Reuse a saved AI or manual scraper configuration. |
|
|
160
|
+
| `results` | Browse and filter stored result records. |
|
|
161
|
+
| `result` | Retrieve one stored result or poll an asynchronous run. |
|
|
162
|
+
| `status` | Inspect subscription usage and request outcomes. |
|
|
163
|
+
|
|
164
|
+
## Fetch-first routing
|
|
165
|
+
|
|
166
|
+
When a public URL is already known, the skills direct OpenCode to fetch it
|
|
167
|
+
first and treat the raw response as the source of truth. The agent can read,
|
|
168
|
+
summarize, compare, or derive structured output locally without losing details
|
|
169
|
+
to an early extraction prompt.
|
|
170
|
+
|
|
171
|
+
For roughly 100 known pages with a shared layout, the agent can fetch pages
|
|
172
|
+
concurrently, retain every raw response, and apply one reusable local extractor
|
|
173
|
+
instead of requesting 100 separate backend-LLM extractions. Use `scrape` when
|
|
174
|
+
managed extraction is explicitly requested or has a clear benefit after the page
|
|
175
|
+
structure and desired schema are understood.
|
|
176
|
+
|
|
177
|
+
## Data and permissions
|
|
178
|
+
|
|
179
|
+
The plugin sends MCP tool inputs, including target URLs and extraction
|
|
180
|
+
instructions, to MrScraper's hosted service. Page responses and tool results are
|
|
181
|
+
then available to OpenCode and its model provider for the requested task.
|
|
182
|
+
Managed general and listing extraction sends page content and the extraction
|
|
183
|
+
prompt to a backend language model and saves a reusable scraper configuration;
|
|
184
|
+
reruns create new stored results. Use it only with public or otherwise
|
|
185
|
+
authorized content, and follow the target site's requirements.
|
|
186
|
+
|
|
187
|
+
Review MrScraper's [MCP documentation](https://docs.mrscraper.com/docs/getting-started/mcp-server),
|
|
188
|
+
[Privacy Policy](https://mrscraper.com/privacy-policy),
|
|
189
|
+
[Acceptable Use Policy](https://mrscraper.com/acceptable-use-policy), and
|
|
190
|
+
[Terms of Use](https://mrscraper.com/terms-of-use) before use.
|
|
191
|
+
|
|
192
|
+
## Update or remove
|
|
193
|
+
|
|
194
|
+
OpenCode 2 checks unpinned npm plugins for updates without installing them.
|
|
195
|
+
Update or remove the plugin with:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
opencode plugin update @mrscraper/opencode
|
|
199
|
+
opencode plugin remove @mrscraper/opencode
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
In OpenCode 1, an unpinned entry stays on the version OpenCode first cached.
|
|
203
|
+
To control updates, pin a version and change it when you upgrade:
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"plugin": ["@mrscraper/opencode@0.2.0"]
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
To remove it from OpenCode 1, delete the entry from `plugin`. In either
|
|
212
|
+
version, remove the stored OAuth tokens afterwards:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
opencode mcp logout mrscraper
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
You can also revoke access under Connected applications in your MrScraper
|
|
219
|
+
account.
|
|
220
|
+
|
|
221
|
+
## Support and security
|
|
222
|
+
|
|
223
|
+
- Product help: [MrScraper MCP documentation](https://docs.mrscraper.com/docs/getting-started/mcp-server)
|
|
224
|
+
- Bugs and feature requests: [GitHub Issues](https://github.com/mrscraper-com/mrscraper-opencode-plugin/issues)
|
|
225
|
+
- Account help: [support@mrscraper.com](mailto:support@mrscraper.com)
|
|
226
|
+
- Security reports: see [SECURITY.md](SECURITY.md)
|
|
227
|
+
|
|
228
|
+
## Development
|
|
229
|
+
|
|
230
|
+
```text
|
|
231
|
+
index.ts default export with an OpenCode 2 `setup()` and an OpenCode 1
|
|
232
|
+
`server()`; both register the MCP server and the skills
|
|
233
|
+
skills/ MCP-oriented skills, copied verbatim from
|
|
234
|
+
mrscraper-com/mrscraper-claude-plugin (plugins/mrscraper/skills)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
npm install
|
|
239
|
+
npm run check
|
|
240
|
+
npm pack --dry-run
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Test a local checkout in both majors before a release. In OpenCode 2, add the
|
|
244
|
+
checkout's absolute path to `plugins`, then run `opencode mcp list` and
|
|
245
|
+
`opencode api skill.list`. In OpenCode 1, add it to `plugin`, then run
|
|
246
|
+
`opencode mcp list` and `opencode debug skill`. Record user-visible changes in
|
|
247
|
+
[CHANGELOG.md](CHANGELOG.md) and follow [PUBLISHING.md](PUBLISHING.md) for
|
|
248
|
+
releases.
|
|
249
|
+
|
|
250
|
+
## License
|
|
251
|
+
|
|
252
|
+
[MIT](LICENSE)
|
package/index.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { Plugin as OpenCode1Plugin } from "@opencode-ai/plugin"
|
|
2
|
+
import type { Plugin as OpenCode2, Skill } from "@opencode/plugin"
|
|
3
|
+
import { readdir, readFile } from "node:fs/promises"
|
|
4
|
+
import { dirname, join } from "node:path"
|
|
5
|
+
import { fileURLToPath } from "node:url"
|
|
6
|
+
|
|
7
|
+
const SERVER_NAME = "mrscraper"
|
|
8
|
+
const MCP_URL = "https://mcp.mrscraper.com/mcp"
|
|
9
|
+
const SKILLS_DIR = join(dirname(fileURLToPath(import.meta.url)), "skills")
|
|
10
|
+
|
|
11
|
+
// OpenCode 1 reads `skills.paths` (see https://opencode.ai/config.json), but the
|
|
12
|
+
// plugin SDK's Config type does not declare it yet.
|
|
13
|
+
type SkillsConfig = { skills?: { paths?: string[]; urls?: string[] } }
|
|
14
|
+
|
|
15
|
+
// OpenCode 1: add the server and the skills directory through the config hook.
|
|
16
|
+
const server: OpenCode1Plugin = async () => ({
|
|
17
|
+
async config(input) {
|
|
18
|
+
input.mcp ??= {}
|
|
19
|
+
// Keep a user-defined entry, such as the API-key fallback or `enabled: false`.
|
|
20
|
+
input.mcp[SERVER_NAME] ??= { type: "remote", url: MCP_URL }
|
|
21
|
+
|
|
22
|
+
const config = input as typeof input & SkillsConfig
|
|
23
|
+
config.skills ??= {}
|
|
24
|
+
config.skills.paths ??= []
|
|
25
|
+
if (!config.skills.paths.includes(SKILLS_DIR)) config.skills.paths.push(SKILLS_DIR)
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// OpenCode 2: register the same server and skills through domain transforms.
|
|
30
|
+
const definition = {
|
|
31
|
+
id: "mrscraper",
|
|
32
|
+
async setup(ctx) {
|
|
33
|
+
const skills = await readSkills()
|
|
34
|
+
await ctx.mcp.transform((editor) => {
|
|
35
|
+
// Keep a user-defined `mcp.servers.mrscraper`, such as the API-key fallback.
|
|
36
|
+
if (!editor.get(SERVER_NAME)) editor.set(SERVER_NAME, { type: "remote", url: MCP_URL })
|
|
37
|
+
})
|
|
38
|
+
await ctx.skill.transform((editor) => {
|
|
39
|
+
for (const skill of skills) if (!editor.get(skill.id)) editor.add(skill)
|
|
40
|
+
})
|
|
41
|
+
},
|
|
42
|
+
} satisfies OpenCode2.Plugin
|
|
43
|
+
|
|
44
|
+
// Mirrors OpenCode 2's own SKILL.md loading: the folder name is the ID, the
|
|
45
|
+
// frontmatter supplies `name` and `description`, and the body is the content.
|
|
46
|
+
async function readSkills(): Promise<Skill.Info[]> {
|
|
47
|
+
const skills: Skill.Info[] = []
|
|
48
|
+
const folders = await readdir(SKILLS_DIR, { withFileTypes: true }).catch(() => [])
|
|
49
|
+
for (const folder of folders) {
|
|
50
|
+
if (!folder.isDirectory()) continue
|
|
51
|
+
const path = join(SKILLS_DIR, folder.name, "SKILL.md")
|
|
52
|
+
const text = await readFile(path, "utf8").catch(() => undefined)
|
|
53
|
+
const markdown = text === undefined ? undefined : parseMarkdown(text)
|
|
54
|
+
if (!markdown) continue
|
|
55
|
+
const { name, description } = markdown.frontmatter
|
|
56
|
+
skills.push({
|
|
57
|
+
id: folder.name as Skill.Info["id"],
|
|
58
|
+
name: (name || folder.name) as Skill.Info["name"],
|
|
59
|
+
...(description ? { description } : {}),
|
|
60
|
+
path: path as Skill.Info["path"],
|
|
61
|
+
content: markdown.content,
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
return skills
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Reads the flat frontmatter these skills use: plain or quoted scalars and
|
|
68
|
+
// `|` or `>` block scalars. Nested keys are ignored.
|
|
69
|
+
function parseMarkdown(text: string) {
|
|
70
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)([\s\S]*)$/.exec(text)
|
|
71
|
+
if (!match) return undefined
|
|
72
|
+
const frontmatter: Record<string, string> = {}
|
|
73
|
+
const lines = match[1].split(/\r?\n/)
|
|
74
|
+
for (let i = 0; i < lines.length; i++) {
|
|
75
|
+
const field = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(lines[i])
|
|
76
|
+
if (!field) continue
|
|
77
|
+
const [, key, value] = field
|
|
78
|
+
if (!/^[|>][-+]?$/.test(value)) {
|
|
79
|
+
frontmatter[key] = value.replace(/^(["'])(.*)\1$/, "$2").trim()
|
|
80
|
+
continue
|
|
81
|
+
}
|
|
82
|
+
const block: string[] = []
|
|
83
|
+
while (i + 1 < lines.length && (lines[i + 1].trim() === "" || /^\s/.test(lines[i + 1]))) block.push(lines[++i])
|
|
84
|
+
const indent = Math.min(...block.filter((line) => line.trim()).map((line) => line.length - line.trimStart().length))
|
|
85
|
+
const literal = block.map((line) => line.slice(indent)).join("\n")
|
|
86
|
+
frontmatter[key] = (value.startsWith(">") ? literal.replace(/([^\n])\n(?=[^\n])/g, "$1 ") : literal).trim()
|
|
87
|
+
}
|
|
88
|
+
return { frontmatter, content: match[2] }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// One default export serves both majors: OpenCode 1 (1.18.29 or later) calls
|
|
92
|
+
// `server()`, and OpenCode 2 reads `id` and `setup()` and ignores `server()`.
|
|
93
|
+
export default { ...definition, server }
|
package/package.json
CHANGED
|
@@ -1,6 +1,53 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrscraper/opencode",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "MrScraper for OpenCode: the hosted MrScraper MCP server plus fetch-first skills for web scraping, structured data extraction, and Google search.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"index.ts",
|
|
12
|
+
"skills",
|
|
13
|
+
"CHANGELOG.md"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"opencode",
|
|
17
|
+
"opencode-plugin",
|
|
18
|
+
"mrscraper",
|
|
19
|
+
"web-scraping",
|
|
20
|
+
"data-extraction",
|
|
21
|
+
"scraping",
|
|
22
|
+
"google-search",
|
|
23
|
+
"serp",
|
|
24
|
+
"mcp",
|
|
25
|
+
"research"
|
|
26
|
+
],
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"author": {
|
|
29
|
+
"name": "MrScraper",
|
|
30
|
+
"email": "support@mrscraper.com",
|
|
31
|
+
"url": "https://mrscraper.com"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/mrscraper-com/mrscraper-opencode-plugin#readme",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/mrscraper-com/mrscraper-opencode-plugin.git"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/mrscraper-com/mrscraper-opencode-plugin/issues"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"check": "tsc --noEmit"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@opencode-ai/plugin": "1.19.0",
|
|
46
|
+
"@opencode/plugin": "2.0.26",
|
|
47
|
+
"@types/node": "^22.20.5",
|
|
48
|
+
"typescript": "^5.9.3"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mrscraper
|
|
3
|
+
description: |
|
|
4
|
+
Connect, authenticate, route, and troubleshoot MrScraper MCP, and use saved scrapers, stored results, and account tools. For known public URLs, acquire and preserve raw content with mrscraper-fetch first; use mrscraper-scrape only for explicitly requested or clearly beneficial managed extraction, and mrscraper-serp for query-first discovery.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# MrScraper MCP
|
|
8
|
+
|
|
9
|
+
Use this skill for connection and authentication checks, tool selection, shared
|
|
10
|
+
response handling, saved reruns, stored results, account status, and
|
|
11
|
+
troubleshooting. Load the focused fetch, scrape, or SERP skill for those
|
|
12
|
+
workflows.
|
|
13
|
+
|
|
14
|
+
## Step 1 — Verify or Connect MrScraper MCP
|
|
15
|
+
|
|
16
|
+
Check whether the current client exposes these seven tools from the MrScraper
|
|
17
|
+
MCP provider:
|
|
18
|
+
|
|
19
|
+
fetch scrape serp status rerun results result
|
|
20
|
+
|
|
21
|
+
The client may display server-qualified names. Match the provider and
|
|
22
|
+
unqualified tool name; do not assume a fixed namespace.
|
|
23
|
+
|
|
24
|
+
If the tools are already available, use the existing connection. If they are
|
|
25
|
+
missing, ask the user to enable the existing MrScraper connection or configure
|
|
26
|
+
the managed Streamable HTTP endpoint:
|
|
27
|
+
|
|
28
|
+
https://mcp.mrscraper.com/mcp
|
|
29
|
+
|
|
30
|
+
A self-managed deployment may expose the same tools over Streamable HTTP or
|
|
31
|
+
stdio. Connection setup belongs to the MCP client. After setup or reconnection,
|
|
32
|
+
list the available tools and confirm all seven names before claiming the
|
|
33
|
+
integration is ready.
|
|
34
|
+
|
|
35
|
+
## Step 2 — Authenticate
|
|
36
|
+
|
|
37
|
+
MrScraper MCP authenticates through OAuth 2.1. Authentication belongs to the
|
|
38
|
+
MCP connection and is never a tool argument.
|
|
39
|
+
|
|
40
|
+
When the connection is not authorized, start the MCP client's authorization
|
|
41
|
+
flow. Let the client discover the authorization metadata, open the MrScraper
|
|
42
|
+
consent page, complete authorization, store the resulting credentials, and
|
|
43
|
+
refresh access tokens. The user may need to approve access in a browser, but
|
|
44
|
+
must not paste an authorization code, access token, refresh token, API key, or
|
|
45
|
+
other credential into the conversation.
|
|
46
|
+
|
|
47
|
+
Never place credentials in tool arguments, print them, write them into project
|
|
48
|
+
artifacts, or manually reproduce the OAuth exchange. Do not configure an
|
|
49
|
+
API-key or bearer-token fallback from these skills.
|
|
50
|
+
|
|
51
|
+
Verify end-to-end access with one small fetch:
|
|
52
|
+
|
|
53
|
+
{
|
|
54
|
+
"url": "https://www.scrapethissite.com/pages/simple/"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
A successful page response confirms that the connection can authenticate and
|
|
58
|
+
reach the web-data service. If it fails, report the error and do not claim
|
|
59
|
+
setup is complete.
|
|
60
|
+
|
|
61
|
+
## Step 3 — Route the Request
|
|
62
|
+
|
|
63
|
+
| User outcome | MCP tool or skill |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| Acquire and preserve raw content from known public URLs for any downstream task | [mrscraper-fetch](../mrscraper-fetch/SKILL.md), preferably first |
|
|
66
|
+
| Add managed extraction, repeated records, site mapping, schema guidance, or a reusable scraper | [mrscraper-scrape](../mrscraper-scrape/SKILL.md), normally after or alongside fetch |
|
|
67
|
+
| Discover relevant pages from a Google query | [mrscraper-serp](../mrscraper-serp/SKILL.md), then fetch selected pages |
|
|
68
|
+
| Reproduce a prior scrape or run an existing AI/manual scraper on new URLs | rerun |
|
|
69
|
+
| List or retrieve stored results | results or result |
|
|
70
|
+
| Check account usage or domain request outcomes | status |
|
|
71
|
+
|
|
72
|
+
### Fetch-first principle
|
|
73
|
+
|
|
74
|
+
For agent-led work, always use fetch for the first exploration of a known public
|
|
75
|
+
URL. The raw response preserves complete page context for later questions,
|
|
76
|
+
validation, and custom processing. Requesting JSON, a table, or named fields is
|
|
77
|
+
not by itself a reason to use scrape; derive those outputs locally from the raw
|
|
78
|
+
content when practical.
|
|
79
|
+
|
|
80
|
+
The general and listing scrape modes send page content through a backend LLM.
|
|
81
|
+
Their output is shaped by the extraction prompt and may omit information.
|
|
82
|
+
Applying them across many pages also repeats model work that the agent can often
|
|
83
|
+
replace with one reusable local extractor.
|
|
84
|
+
|
|
85
|
+
Prefer this workflow for pages with a shared layout:
|
|
86
|
+
|
|
87
|
+
1. Fetch representative pages and inspect their raw content.
|
|
88
|
+
2. Understand the shared page structure and required fields.
|
|
89
|
+
3. Define a stable output schema and reusable local extractor.
|
|
90
|
+
4. Fetch the remaining pages, in parallel when safe.
|
|
91
|
+
5. Apply the same extractor to every saved response.
|
|
92
|
+
|
|
93
|
+
For roughly 100 same-layout pages, that means 100 fetches followed by one local
|
|
94
|
+
batch extraction instead of 100 separate backend-LLM extractions. This is often
|
|
95
|
+
faster, preserves every raw input, and allows fields to be recovered later if
|
|
96
|
+
the schema changes.
|
|
97
|
+
|
|
98
|
+
Use scrape only when the user explicitly requests managed extraction or when it
|
|
99
|
+
still offers a clear benefit after fetch-led exploration. Even then, retain the
|
|
100
|
+
fetched source and verify important values against it. The map agent is separate
|
|
101
|
+
URL-discovery functionality; use it for bounded site mapping, then fetch the
|
|
102
|
+
pages whose content matters.
|
|
103
|
+
|
|
104
|
+
For discovery-first work, call serp, select relevant URLs, fetch those pages,
|
|
105
|
+
and add managed extraction only when a derived structured view is useful.
|
|
106
|
+
|
|
107
|
+
## Step 4 — Handle Output and Artifacts
|
|
108
|
+
|
|
109
|
+
API-backed tools return the same response envelope in MCP structuredContent and
|
|
110
|
+
in a formatted JSON text block:
|
|
111
|
+
|
|
112
|
+
{
|
|
113
|
+
"status_code": 200,
|
|
114
|
+
"data": {},
|
|
115
|
+
"headers": {}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
Prefer structuredContent when available. An API failure adds error and sets the
|
|
119
|
+
MCP result's isError flag. An input-contract failure is returned as a tool
|
|
120
|
+
error. Check those signals before trusting data.
|
|
121
|
+
|
|
122
|
+
Credentials, cookies, and generated curl credentials are sanitized. Extracted
|
|
123
|
+
scraper data is preserved even when it contains fields named token or password
|
|
124
|
+
because those fields may be legitimate source values.
|
|
125
|
+
|
|
126
|
+
MrScraper tools do not accept output paths. When the user requests an artifact,
|
|
127
|
+
wait for a successful tool result, select the requested value, and save it with
|
|
128
|
+
the environment's local file-writing capability. For scrape, the extracted
|
|
129
|
+
value is normally at structuredContent.data.data.data. Keep the full envelope
|
|
130
|
+
separately only when run metadata, headers, or diagnostics matter.
|
|
131
|
+
|
|
132
|
+
Save substantial intermediate artifacts under the current project's
|
|
133
|
+
.mrscraper directory unless the user specifies another location. This project
|
|
134
|
+
artifact directory is unrelated to MCP connection credentials. Keep artifacts
|
|
135
|
+
out of version control unless the user asks to commit them.
|
|
136
|
+
|
|
137
|
+
## Step 5 — Rerun Saved Scrapers
|
|
138
|
+
|
|
139
|
+
A successful scrape creates a saved AI scraper configuration. Read its UUID
|
|
140
|
+
from structuredContent.data.data.scraperId and use rerun to apply the same
|
|
141
|
+
configuration to the same or another URL. Prefer rerun over rebuilding a prompt
|
|
142
|
+
when the user wants a repeatable version of an earlier extraction.
|
|
143
|
+
|
|
144
|
+
The scraperId makes the configuration reusable but does not guarantee
|
|
145
|
+
identical extracted values when the source page or model behavior changes.
|
|
146
|
+
|
|
147
|
+
Choose scraper type and target count independently:
|
|
148
|
+
|
|
149
|
+
1. Use type=ai for a saved AI scraper created by scrape.
|
|
150
|
+
2. Use type=manual for a saved step-based workflow created in the MrScraper
|
|
151
|
+
dashboard. MCP can rerun but cannot create manual workflows.
|
|
152
|
+
3. Leave bulk=false for one URL. Set bulk=true for a comma- or
|
|
153
|
+
newline-separated URL list submitted as one asynchronous job.
|
|
154
|
+
|
|
155
|
+
| Mode | Required ID input | Target | Crawl controls |
|
|
156
|
+
| --- | --- | --- | --- |
|
|
157
|
+
| Single AI | scraper_id | One URL | Supported |
|
|
158
|
+
| Single manual | scraper_id | One URL | Not accepted |
|
|
159
|
+
| Bulk AI | bulk=true and id | Comma/newline-separated URLs | Not accepted |
|
|
160
|
+
| Bulk manual | bulk=true and id | Comma/newline-separated URLs | Not accepted |
|
|
161
|
+
|
|
162
|
+
Single AI example:
|
|
163
|
+
|
|
164
|
+
{
|
|
165
|
+
"target": "https://www.scrapethissite.com/pages/simple/",
|
|
166
|
+
"type": "ai",
|
|
167
|
+
"scraper_id": "SCRAPER_UUID"
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
Single AI optionally accepts max_depth, max_pages, limit, include_patterns,
|
|
171
|
+
exclude_patterns, proxy_country, max_retry, and timeout. Omit any control that
|
|
172
|
+
the user did not request so the saved scraper or backend default remains in
|
|
173
|
+
effect; the MCP server does not inject replacement defaults.
|
|
174
|
+
|
|
175
|
+
Explicit-control example:
|
|
176
|
+
|
|
177
|
+
{
|
|
178
|
+
"target": "https://www.scrapethissite.com/pages/forms/?page_num=1",
|
|
179
|
+
"type": "ai",
|
|
180
|
+
"scraper_id": "SCRAPER_UUID",
|
|
181
|
+
"proxy_country": "ID",
|
|
182
|
+
"max_retry": 4,
|
|
183
|
+
"timeout": 120
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
These controls are rejected by manual and bulk reruns.
|
|
187
|
+
|
|
188
|
+
Bulk example:
|
|
189
|
+
|
|
190
|
+
{
|
|
191
|
+
"target": "https://www.scrapethissite.com/pages/simple/,https://www.scrapethissite.com/pages/forms/?page_num=1",
|
|
192
|
+
"type": "ai",
|
|
193
|
+
"bulk": true,
|
|
194
|
+
"id": "SCRAPER_UUID"
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
Manual example, after the user accepts the warning below:
|
|
198
|
+
|
|
199
|
+
{
|
|
200
|
+
"target": "https://www.scrapethissite.com/pages/simple/",
|
|
201
|
+
"type": "manual",
|
|
202
|
+
"scraper_id": "SCRAPER_UUID",
|
|
203
|
+
"acknowledged": true
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
Bulk rerun submits one asynchronous backend job. Retain
|
|
207
|
+
structuredContent.data.data.bulkResultId and pass it to result as result_id.
|
|
208
|
+
Inspect that record until it reaches a terminal state when the user asked to
|
|
209
|
+
wait for completion. Do not resubmit the bulk rerun because its result is still
|
|
210
|
+
running.
|
|
211
|
+
|
|
212
|
+
Before the first rerun call with type=manual in a conversation, show the
|
|
213
|
+
following warning exactly once and wait for the user's acknowledgment. Do not
|
|
214
|
+
call the tool until the user accepts it, and do not repeat the warning on later
|
|
215
|
+
manual reruns in the same conversation. After the user accepts, pass
|
|
216
|
+
acknowledged=true on every manual rerun in that conversation; rerun refuses a
|
|
217
|
+
manual rerun without it and returns this warning instead.
|
|
218
|
+
|
|
219
|
+
> ### Compliance & Legal Risk
|
|
220
|
+
>
|
|
221
|
+
> WARNING
|
|
222
|
+
>
|
|
223
|
+
> **Scraping login-protected pages carries serious legal and compliance
|
|
224
|
+
> risks.** Many websites explicitly prohibit automated access in their Terms
|
|
225
|
+
> of Service, and bypassing authentication to scrape content may expose you to
|
|
226
|
+
> legal action including lawsuits, account termination, and financial
|
|
227
|
+
> penalties. By proceeding on scraping login-protected pages, you confirm that
|
|
228
|
+
> you have read and understood the target website's Terms of Service, and you
|
|
229
|
+
> **fully accept all legal, financial, and ethical responsibility** for your
|
|
230
|
+
> actions.
|
|
231
|
+
|
|
232
|
+
## Step 6 — Inspect Stored Results
|
|
233
|
+
|
|
234
|
+
Use results when the exact result UUID is unknown:
|
|
235
|
+
|
|
236
|
+
{
|
|
237
|
+
"sort_field": "updatedAt",
|
|
238
|
+
"sort_order": "desc",
|
|
239
|
+
"page_size": 20,
|
|
240
|
+
"page": 1
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
Apply exact backend filters when the user knows identifying result fields:
|
|
244
|
+
|
|
245
|
+
{
|
|
246
|
+
"scraper_id": "SCRAPER_UUID",
|
|
247
|
+
"status": "Finished",
|
|
248
|
+
"type": "Rerun-AI",
|
|
249
|
+
"url": "https://www.scrapethissite.com/pages/simple/"
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
| Input | Default | Use |
|
|
253
|
+
| --- | --- | --- |
|
|
254
|
+
| sort_field | updatedAt | Stored-result sort key. |
|
|
255
|
+
| sort_order | desc | Sort direction: asc or desc. |
|
|
256
|
+
| page_size | 10 | Positive number of records per page. |
|
|
257
|
+
| page | 1 | One-based page number. |
|
|
258
|
+
| search | omitted | Free-text result filter. |
|
|
259
|
+
| date_range_column | omitted | Date column used by start_at and end_at. |
|
|
260
|
+
| start_at | omitted | Inclusive ISO 8601 range start. |
|
|
261
|
+
| end_at | omitted | Inclusive ISO 8601 range end. |
|
|
262
|
+
| scraper_id | omitted | Exact saved scraper UUID filter. |
|
|
263
|
+
| status | omitted | Exact Draft, Finished, Running, Failed, or Cancelled filter. |
|
|
264
|
+
| type | omitted | Exact result type filter, such as AI or Rerun-AI. |
|
|
265
|
+
| url | omitted | Exact stored target URL filter. |
|
|
266
|
+
|
|
267
|
+
Use result when the UUID is known:
|
|
268
|
+
|
|
269
|
+
{
|
|
270
|
+
"result_id": "RESULT_UUID",
|
|
271
|
+
"include_html": false
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
A result_id may also be the bulkResultId returned by an asynchronous rerun.
|
|
275
|
+
include_html defaults to true. Set it to false for a smaller response while
|
|
276
|
+
polling status or when extracted data is sufficient.
|
|
277
|
+
|
|
278
|
+
## Step 7 — Review Account Usage
|
|
279
|
+
|
|
280
|
+
Call status with an empty object for subscription and token usage:
|
|
281
|
+
|
|
282
|
+
{}
|
|
283
|
+
|
|
284
|
+
Add domain request outcomes and a time range only when needed:
|
|
285
|
+
|
|
286
|
+
{
|
|
287
|
+
"domain": "www.scrapethissite.com",
|
|
288
|
+
"from": "7d",
|
|
289
|
+
"to": "now"
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
| Input | Default | Use |
|
|
293
|
+
| --- | --- | --- |
|
|
294
|
+
| domain | omitted | Add request outcomes for a normalized hostname. |
|
|
295
|
+
| from | 24h | ISO start or relative duration such as 30m, 24h, or 7d. |
|
|
296
|
+
| to | now | ISO end, now, or a relative duration. |
|
|
297
|
+
| action | omitted | Exact request-action filter, used only with domain. |
|
|
298
|
+
| api_token_name | omitted | API-token-name filter, used only with domain. |
|
|
299
|
+
|
|
300
|
+
Domain outcomes describe MrScraper requests. They are not traffic, audience,
|
|
301
|
+
SEO, or market analytics. status reports account and request health, not
|
|
302
|
+
scrape-job progress; use result for a known asynchronous result ID.
|
|
303
|
+
|
|
304
|
+
## Step 8 — Troubleshoot
|
|
305
|
+
|
|
306
|
+
- Missing tools: enable or reconnect the MrScraper MCP connection, then confirm
|
|
307
|
+
all seven tools are exposed.
|
|
308
|
+
- Unauthorized or expired authorization: reauthorize the OAuth 2.1 connection
|
|
309
|
+
through the MCP client.
|
|
310
|
+
- Input-contract error: inspect the tool schema and omit inputs that do not
|
|
311
|
+
apply to the selected mode.
|
|
312
|
+
- Page incomplete or missing dynamic content: load mrscraper-fetch and revise
|
|
313
|
+
page-loading inputs deliberately.
|
|
314
|
+
- Extraction incomplete: load mrscraper-scrape and improve the prompt, agent,
|
|
315
|
+
or limits.
|
|
316
|
+
- Search results weak: load mrscraper-serp and refine the query, locale, or
|
|
317
|
+
page.
|
|
318
|
+
|
|
319
|
+
## Limits
|
|
320
|
+
|
|
321
|
+
Use another tool for:
|
|
322
|
+
|
|
323
|
+
- Clicking controls, completing forms, or authenticated browser sessions.
|
|
324
|
+
- Parsing local PDFs, documents, spreadsheets, or other files.
|
|
325
|
+
- Recurring monitoring, notifications, or scheduling.
|
|
326
|
+
|
|
327
|
+
Explain the boundary and continue with any supported portion of the task.
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mrscraper-fetch
|
|
3
|
+
description: |
|
|
4
|
+
Retrieve raw HTML from a known public URL with MrScraper. Use for reading, inspecting, summarizing, archiving, or analyzing a page, and as the default content-acquisition step before agent-led or local extraction. Supports browser rendering, real-device Super Mode, and page-load controls; use mrscraper-serp when no target URL is known.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Fetch Page Content with MrScraper MCP
|
|
8
|
+
|
|
9
|
+
Use the fetch tool supplied by the MrScraper MCP server for the first exploration
|
|
10
|
+
whenever the user already has a public URL. Keep using the raw response for
|
|
11
|
+
summarization, comparison, transformation, and structured output instead of
|
|
12
|
+
handing the page to another LLM by default. Use
|
|
13
|
+
[mrscraper](../mrscraper/SKILL.md) for connection and authentication checks,
|
|
14
|
+
saved runs, account status, or broader routing.
|
|
15
|
+
|
|
16
|
+
## Page Retrieval Context
|
|
17
|
+
|
|
18
|
+
fetch calls MrScraper's
|
|
19
|
+
[page-fetching service](https://docs.mrscraper.com/docs/features/unblocker) once.
|
|
20
|
+
Browser rendering executes page JavaScript, locale routing selects a
|
|
21
|
+
geo-specific country, selector waits allow delayed content to appear, and
|
|
22
|
+
homepage navigation establishes a normal navigation path before loading the
|
|
23
|
+
target. Super Mode selects real-device routing independently of browser
|
|
24
|
+
rendering.
|
|
25
|
+
|
|
26
|
+
Use fetch only for content the user is authorized to access and in accordance
|
|
27
|
+
with the site's requirements. Page-loading controls can help render a site that
|
|
28
|
+
does not work with a basic request.
|
|
29
|
+
|
|
30
|
+
Start with the URL alone and add only the controls the target needs. Plan-token
|
|
31
|
+
usage is based on runtime and bandwidth: one token per 30 seconds and one token
|
|
32
|
+
per 0.2 MB, rounded up per component. Resource blocking can reduce bandwidth
|
|
33
|
+
for text-focused pages. Retries stop when the request succeeds, max_retries is
|
|
34
|
+
reached, or the running token total reaches token_cap. The initial request
|
|
35
|
+
always runs even when it exceeds that cap. See the
|
|
36
|
+
[Token Plan](https://docs.mrscraper.com/docs/getting-started/api-token) for the
|
|
37
|
+
maintained calculation.
|
|
38
|
+
|
|
39
|
+
## Step 1 — Define the Outcome
|
|
40
|
+
|
|
41
|
+
Confirm the target URL and what the user wants:
|
|
42
|
+
|
|
43
|
+
- Preserve a raw source before extraction, transformation, or comparison.
|
|
44
|
+
- Read, summarize, cite, or inspect the page.
|
|
45
|
+
- Check whether specific text appears.
|
|
46
|
+
- Archive the response.
|
|
47
|
+
- Produce fields, JSON, tables, or other structured output with local logic.
|
|
48
|
+
- Verify or supplement a managed scrape or saved result.
|
|
49
|
+
- Load JavaScript-rendered or geo-sensitive content.
|
|
50
|
+
|
|
51
|
+
Do not call scrape merely because the requested output is structured. Fetch the
|
|
52
|
+
page, understand its layout, and transform the saved raw content locally. Use
|
|
53
|
+
[mrscraper-scrape](../mrscraper-scrape/SKILL.md) only when the user explicitly
|
|
54
|
+
requests managed extraction, or after fetch-led exploration has produced a
|
|
55
|
+
stable output schema and managed extraction still offers a concrete benefit.
|
|
56
|
+
Use [mrscraper-serp](../mrscraper-serp/SKILL.md) when discovery must happen
|
|
57
|
+
first.
|
|
58
|
+
|
|
59
|
+
### Prefer reusable local extraction
|
|
60
|
+
|
|
61
|
+
When many pages share a layout:
|
|
62
|
+
|
|
63
|
+
1. Fetch representative pages and inspect their raw content.
|
|
64
|
+
2. Define one local extraction schema and implementation.
|
|
65
|
+
3. Fetch the remaining pages, in parallel when safe and proportional.
|
|
66
|
+
4. Apply the same local extractor to every saved response.
|
|
67
|
+
|
|
68
|
+
For roughly 100 same-layout pages, concurrent fetches followed by one local
|
|
69
|
+
batch extraction are often faster than 100 separate backend-LLM extractions.
|
|
70
|
+
This also preserves every raw input for later recovery or schema changes.
|
|
71
|
+
|
|
72
|
+
## Step 2 — Run the Fetch
|
|
73
|
+
|
|
74
|
+
The client may namespace the tool name; select fetch from the MrScraper MCP
|
|
75
|
+
provider. Start with one call containing only the required URL:
|
|
76
|
+
|
|
77
|
+
{
|
|
78
|
+
"url": "https://www.scrapethissite.com/pages/simple/"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
The result is available in MCP structuredContent and as formatted JSON text:
|
|
82
|
+
|
|
83
|
+
{
|
|
84
|
+
"status_code": 200,
|
|
85
|
+
"data": "<html>...</html>",
|
|
86
|
+
"headers": {
|
|
87
|
+
"content-type": "text/html"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
Prefer structuredContent. Check isError, error, and status_code before using
|
|
92
|
+
data. Non-JSON page bodies are preserved exactly.
|
|
93
|
+
|
|
94
|
+
## Step 3 — Choose Page-Loading Options
|
|
95
|
+
|
|
96
|
+
browser_rendering and super_mode are independent axes. All four combinations
|
|
97
|
+
can return different content or failures for the same URL:
|
|
98
|
+
|
|
99
|
+
| browser_rendering | super_mode | Loading path |
|
|
100
|
+
| --- | --- | --- |
|
|
101
|
+
| false | false | Standard routing with the non-browser loader. |
|
|
102
|
+
| true | false | Standard routing with browser loading and JavaScript. |
|
|
103
|
+
| false | true | Real-device routing with the non-browser loader. |
|
|
104
|
+
| true | true | Real-device routing with browser loading and JavaScript. |
|
|
105
|
+
|
|
106
|
+
Use browser rendering when the page depends on JavaScript:
|
|
107
|
+
|
|
108
|
+
{
|
|
109
|
+
"url": "https://www.scrapethissite.com/pages/ajax-javascript/#2015",
|
|
110
|
+
"browser_rendering": true
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
Use Super Mode with the non-browser loader when routing may be the problem but
|
|
114
|
+
browser loading is unnecessary or returns a worse response:
|
|
115
|
+
|
|
116
|
+
{
|
|
117
|
+
"url": "https://www.scrapethissite.com/pages/simple/",
|
|
118
|
+
"super_mode": true
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
Use both controls for real-device browser loading:
|
|
122
|
+
|
|
123
|
+
{
|
|
124
|
+
"url": "https://www.scrapethissite.com/pages/ajax-javascript/#2015",
|
|
125
|
+
"browser_rendering": true,
|
|
126
|
+
"super_mode": true
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
Browser rendering is not a strictly stronger mode. Some sites fail or return
|
|
130
|
+
worse content with browser_rendering=true but load successfully when it is
|
|
131
|
+
false. Super Mode does not enable browser rendering.
|
|
132
|
+
|
|
133
|
+
Wait for delayed content with a CSS selector:
|
|
134
|
+
|
|
135
|
+
{
|
|
136
|
+
"url": "https://www.scrapethissite.com/pages/ajax-javascript/#2015",
|
|
137
|
+
"browser_rendering": true,
|
|
138
|
+
"wait_for_selector": ".film"
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
Use geographic routing or homepage navigation when the target requires it:
|
|
142
|
+
|
|
143
|
+
{
|
|
144
|
+
"url": "https://www.scrapethissite.com/pages/simple/",
|
|
145
|
+
"browser_rendering": true,
|
|
146
|
+
"geo_code": "ID",
|
|
147
|
+
"home_page": true
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
Use geographic routing for geo-specific content.
|
|
151
|
+
|
|
152
|
+
Bound resource use for a browser-rendered page:
|
|
153
|
+
|
|
154
|
+
{
|
|
155
|
+
"url": "https://www.scrapethissite.com/pages/ajax-javascript/#2015",
|
|
156
|
+
"browser_rendering": true,
|
|
157
|
+
"block_resources": true,
|
|
158
|
+
"max_retries": 3,
|
|
159
|
+
"token_cap": 10000,
|
|
160
|
+
"timeout": 60
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
### Parameters
|
|
164
|
+
|
|
165
|
+
| MCP input | Default | Request mapping | Use |
|
|
166
|
+
| --- | --- | --- | --- |
|
|
167
|
+
| url | required | Query url | Absolute HTTP or HTTPS target URL. |
|
|
168
|
+
| browser_rendering | false | Query browserRendering | Execute page JavaScript. |
|
|
169
|
+
| super_mode | false | Query super | Select real-device routing independently of browser rendering. |
|
|
170
|
+
| geo_code | omitted | Query geoCode | Route through an ISO 3166-1 alpha-2 country. |
|
|
171
|
+
| wait_for_selector | omitted | Query waitForSelector | Wait for a CSS selector; requires browser_rendering=true. |
|
|
172
|
+
| home_page | false | Query homePage | Visit the site root before the target page. |
|
|
173
|
+
| block_resources | false | Query blockResources | Block nonessential resources during loading. |
|
|
174
|
+
| max_retries | 3 | Query maxRetries | Maximum retries after failure; zero disables retries. |
|
|
175
|
+
| token_cap | omitted | Query tokenCap | Retry token budget; the initial request still runs. |
|
|
176
|
+
| timeout | 30 | Query timeout | Page-load timeout in seconds; transport receives another 30 seconds. |
|
|
177
|
+
|
|
178
|
+
Authentication is handled by the MCP client's OAuth 2.1 connection and is
|
|
179
|
+
never a tool input.
|
|
180
|
+
|
|
181
|
+
## Step 4 — Inspect and Retry Deliberately
|
|
182
|
+
|
|
183
|
+
Start with both controls false unless the task already establishes a
|
|
184
|
+
requirement. If the response fails, is blocked, incomplete, or missing dynamic
|
|
185
|
+
content:
|
|
186
|
+
|
|
187
|
+
1. Inspect the initial response.
|
|
188
|
+
2. Change one axis at a time: browser_rendering for JavaScript, or super_mode
|
|
189
|
+
when routing may be the problem.
|
|
190
|
+
3. If browser loading fails or returns worse content, retry the same super_mode
|
|
191
|
+
value with browser_rendering=false.
|
|
192
|
+
4. Try the remaining untested combinations when the response is still unusable.
|
|
193
|
+
5. Add wait_for_selector, geo_code, or home_page only when evidence shows that
|
|
194
|
+
the target requires it.
|
|
195
|
+
6. Stop after a usable response unless the user requests a comparison.
|
|
196
|
+
|
|
197
|
+
Do not repeat an identical combination. Treat wait_for_selector as a CSS
|
|
198
|
+
selector, not a duration. Browser rendering loads a page; it does not click
|
|
199
|
+
controls, submit forms, or provide an authenticated interactive browser
|
|
200
|
+
session.
|
|
201
|
+
|
|
202
|
+
## Step 5 — Deliver the Result
|
|
203
|
+
|
|
204
|
+
Answer the user's request from data. Keep the full envelope when headers or
|
|
205
|
+
diagnostics matter. When the user requests an archive, save the successful
|
|
206
|
+
response or its data value with the environment's local file-writing
|
|
207
|
+
capability; fetch itself has no output-path input.
|
|
208
|
+
|
|
209
|
+
Keep fetched content as the source of truth for later steps. Build summaries,
|
|
210
|
+
tables, JSON transformations, and extraction scripts from that raw content. If
|
|
211
|
+
fetch fails and another MrScraper workflow can still complete the task, disclose
|
|
212
|
+
that the raw response was not preserved and do not present the narrower result
|
|
213
|
+
as exhaustive source content.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mrscraper-scrape
|
|
3
|
+
description: |
|
|
4
|
+
Run MrScraper's general, listing, or map agents for managed structured extraction or bounded URL discovery within a known site. Use when managed output is explicitly requested or justified after source-page inspection; use mrscraper-fetch for initial acquisition of known pages and mrscraper-serp when no starting URL is known.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Extract Structured Data with MrScraper MCP
|
|
8
|
+
|
|
9
|
+
Do not use scrape for the first exploration of a known page. Start with
|
|
10
|
+
[mrscraper-fetch](../mrscraper-fetch/SKILL.md), inspect the complete raw
|
|
11
|
+
response, and prefer local analysis or a reusable extractor. Use scrape when
|
|
12
|
+
the user explicitly wants MrScraper-managed extraction, or after the agent
|
|
13
|
+
understands the website and has defined a stable output schema. Use
|
|
14
|
+
[mrscraper](../mrscraper/SKILL.md) for connection troubleshooting, saved runs,
|
|
15
|
+
account status, or broader routing.
|
|
16
|
+
|
|
17
|
+
For general and listing, MrScraper retrieves page HTML and asks a backend LLM to
|
|
18
|
+
interpret it according to prompt. This adds model-processing time, can narrow
|
|
19
|
+
the result to the requested fields, and repeats model work across many pages.
|
|
20
|
+
|
|
21
|
+
Before using general or listing, confirm all of the following:
|
|
22
|
+
|
|
23
|
+
1. The target or representative pages have already been fetched and inspected.
|
|
24
|
+
2. The site structure and required output fields are understood.
|
|
25
|
+
3. A stable output schema has been defined.
|
|
26
|
+
4. Managed extraction still offers a concrete benefit over local code, or the
|
|
27
|
+
user explicitly requested it.
|
|
28
|
+
|
|
29
|
+
If these conditions are not met, return to fetch. Requiring JSON, a table, or
|
|
30
|
+
named fields is not by itself a reason to call scrape. For large same-layout
|
|
31
|
+
sets—even roughly 100 pages—safe concurrent fetches plus one reusable local
|
|
32
|
+
extractor are often faster and preserve every raw response. The map agent is
|
|
33
|
+
separate URL discovery functionality and does not require an extraction schema.
|
|
34
|
+
|
|
35
|
+
## Step 1 — Choose an Agent
|
|
36
|
+
|
|
37
|
+
| Agent | Use it for | Required input | Available controls |
|
|
38
|
+
| --- | --- | --- | --- |
|
|
39
|
+
| general | One detail page or one extraction task | prompt | proxy_country, schema_prompt |
|
|
40
|
+
| listing | Repeated records or paginated listings | prompt | proxy_country, max_pages, schema_prompt |
|
|
41
|
+
| map | Discovering URLs across a site | URL only | max_depth, max_pages, limit, include_patterns, exclude_patterns |
|
|
42
|
+
|
|
43
|
+
The default agent is general. For map, omit prompt, schema_prompt, and
|
|
44
|
+
proxy_country. For general and listing, omit map-only controls. max_pages is
|
|
45
|
+
accepted by listing and map but not general.
|
|
46
|
+
|
|
47
|
+
agent selects the extraction workflow. mode independently selects the backend
|
|
48
|
+
execution tier: Cheap or Super. Omit mode to preserve the backend default, and
|
|
49
|
+
select Super only when the extraction requires the stronger mode.
|
|
50
|
+
|
|
51
|
+
## Step 2 — Define the Extraction
|
|
52
|
+
|
|
53
|
+
The examples below assume the decision gate above has been satisfied. Write a
|
|
54
|
+
prompt from the already-understood page structure and output schema, preserve
|
|
55
|
+
source values, and do not ask the model to infer unavailable values.
|
|
56
|
+
|
|
57
|
+
Detail-page example:
|
|
58
|
+
|
|
59
|
+
{
|
|
60
|
+
"url": "https://www.scrapethissite.com/pages/simple/",
|
|
61
|
+
"agent": "general",
|
|
62
|
+
"mode": "Super",
|
|
63
|
+
"prompt": "Extract each country's name, capital, population, and area. Preserve source values and omit unavailable fields."
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
Repeated-listing example:
|
|
67
|
+
|
|
68
|
+
{
|
|
69
|
+
"url": "https://www.scrapethissite.com/pages/forms/?page_num=1",
|
|
70
|
+
"agent": "listing",
|
|
71
|
+
"prompt": "Extract each hockey team's name, year, wins, losses, and win percentage.",
|
|
72
|
+
"max_pages": 5
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
Site-map example:
|
|
76
|
+
|
|
77
|
+
{
|
|
78
|
+
"url": "https://www.scrapethissite.com/",
|
|
79
|
+
"agent": "map",
|
|
80
|
+
"max_depth": 2,
|
|
81
|
+
"max_pages": 50,
|
|
82
|
+
"limit": 1000,
|
|
83
|
+
"include_patterns": "/pages/"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
## Step 3 — Add Shape Guidance When Useful
|
|
87
|
+
|
|
88
|
+
schema_prompt accepts a JSON object, not a file path. If the user supplies a
|
|
89
|
+
local JSON Schema file, read and parse it with local file tools, confirm its
|
|
90
|
+
root is an object, and pass that object:
|
|
91
|
+
|
|
92
|
+
{
|
|
93
|
+
"url": "https://www.scrapethissite.com/pages/simple/",
|
|
94
|
+
"agent": "general",
|
|
95
|
+
"prompt": "Extract every country's name, capital, population, and area.",
|
|
96
|
+
"schema_prompt": {
|
|
97
|
+
"type": "object",
|
|
98
|
+
"properties": {
|
|
99
|
+
"countries": {
|
|
100
|
+
"type": "array",
|
|
101
|
+
"items": {
|
|
102
|
+
"type": "object",
|
|
103
|
+
"properties": {
|
|
104
|
+
"name": { "type": "string" },
|
|
105
|
+
"capital": { "type": "string" },
|
|
106
|
+
"population": { "type": "string" },
|
|
107
|
+
"area": { "type": "string" }
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
The MCP server appends this object to the extraction prompt as best-effort
|
|
116
|
+
shape guidance. It does not validate the returned data against the schema.
|
|
117
|
+
Validate locally when strict compliance is required.
|
|
118
|
+
|
|
119
|
+
## Step 4 — Set Parameters
|
|
120
|
+
|
|
121
|
+
| MCP input | Default | Request mapping | Use |
|
|
122
|
+
| --- | --- | --- | --- |
|
|
123
|
+
| url | required | Body url | Absolute HTTP or HTTPS starting URL. |
|
|
124
|
+
| agent | general | Body agent | Select general, listing, or map. |
|
|
125
|
+
| mode | service default | Body mode | Select Cheap or Super execution without changing the agent. |
|
|
126
|
+
| prompt | required for general/listing | Body message | Describe the fields or records to extract. |
|
|
127
|
+
| proxy_country | omitted | Body proxyCountry | Route general/listing through a country. |
|
|
128
|
+
| max_pages | service default | Body maxPages | Bound listing or map pages. |
|
|
129
|
+
| max_depth | service default | Body maxDepth | Bound map crawl depth. |
|
|
130
|
+
| limit | service default | Body limit | Bound map URL results. |
|
|
131
|
+
| include_patterns | omitted | Body includePatterns | Restrict map results to matching URLs. |
|
|
132
|
+
| exclude_patterns | omitted | Body excludePatterns | Exclude matching map URLs. |
|
|
133
|
+
| schema_prompt | omitted | Appended to message | JSON Schema object for general/listing guidance. |
|
|
134
|
+
|
|
135
|
+
Authentication is handled by the MCP client's OAuth 2.1 connection. The scrape
|
|
136
|
+
tool does not accept a credential or output-path input. Choose the smallest
|
|
137
|
+
practical limits and omit optional values when the service default is
|
|
138
|
+
appropriate.
|
|
139
|
+
|
|
140
|
+
## Step 5 — Wait for Completion
|
|
141
|
+
|
|
142
|
+
General and map usually finish quickly. Listing is synchronous and can take
|
|
143
|
+
several minutes even for one page.
|
|
144
|
+
|
|
145
|
+
Before starting a listing call, tell the user it may take several minutes. Keep
|
|
146
|
+
waiting on the original MCP call within the environment's supported tool
|
|
147
|
+
timeout. Do not submit a duplicate scrape because the first call is quiet or
|
|
148
|
+
still running.
|
|
149
|
+
|
|
150
|
+
## Step 6 — Use the Output
|
|
151
|
+
|
|
152
|
+
The complete API envelope is returned in MCP structuredContent and as formatted
|
|
153
|
+
JSON text. Prefer structuredContent and check isError, error, and status_code
|
|
154
|
+
before trusting the response.
|
|
155
|
+
|
|
156
|
+
A successful run normally stores its extracted value at:
|
|
157
|
+
|
|
158
|
+
structuredContent.data.data.data
|
|
159
|
+
|
|
160
|
+
The saved scraper UUID is normally at:
|
|
161
|
+
|
|
162
|
+
structuredContent.data.data.scraperId
|
|
163
|
+
|
|
164
|
+
When the user asks for a file, save the extracted value only after the tool
|
|
165
|
+
succeeds. Use local file-writing capability and report the path. Preserve the
|
|
166
|
+
full envelope separately when the scraper ID, response headers, or diagnostics
|
|
167
|
+
also matter.
|
|
168
|
+
|
|
169
|
+
Post-process only when the user requests filtering, merging, normalization,
|
|
170
|
+
CSV, a table, or another deliverable. Extracted fields named token or password
|
|
171
|
+
may be legitimate source data and are intentionally preserved.
|
|
172
|
+
|
|
173
|
+
## Step 7 — Preserve the Reproducible Scraper
|
|
174
|
+
|
|
175
|
+
Every successful scrape creates a saved AI scraper configuration by default.
|
|
176
|
+
Report scraperId when it is available and the extraction may need to run again.
|
|
177
|
+
|
|
178
|
+
Use the MrScraper rerun tool to apply the saved configuration to the same or
|
|
179
|
+
another URL:
|
|
180
|
+
|
|
181
|
+
{
|
|
182
|
+
"target": "https://www.scrapethissite.com/pages/forms/?page_num=2",
|
|
183
|
+
"type": "ai",
|
|
184
|
+
"scraper_id": "SCRAPER_UUID"
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
Prefer rerun over recreating the scrape definition when the user wants a
|
|
188
|
+
repeatable extraction. Explain that this reproduces the saved configuration,
|
|
189
|
+
not necessarily identical values when the page or model behavior changes.
|
|
190
|
+
|
|
191
|
+
The rerun tool also handles dashboard-built manual workflows and asynchronous
|
|
192
|
+
bulk jobs. Follow the full rerun workflow in
|
|
193
|
+
[mrscraper](../mrscraper/SKILL.md), including the required acknowledgment
|
|
194
|
+
before any manual rerun.
|
|
195
|
+
|
|
196
|
+
## Step 8 — Handle Failures
|
|
197
|
+
|
|
198
|
+
- Check isError, error, and status_code before using or saving output.
|
|
199
|
+
- Tighten the prompt when fields are missing or grouped incorrectly.
|
|
200
|
+
- Confirm the selected agent accepts every supplied input.
|
|
201
|
+
- Validate locally when downstream code requires a strict schema.
|
|
202
|
+
- Use [mrscraper-fetch](../mrscraper-fetch/SKILL.md) for page reading.
|
|
203
|
+
- Use [mrscraper-serp](../mrscraper-serp/SKILL.md) when discovery must happen
|
|
204
|
+
first.
|
|
205
|
+
- Never invent replacement fields or fill missing values with unsupported
|
|
206
|
+
assumptions.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mrscraper-serp
|
|
3
|
+
description: |
|
|
4
|
+
Discover public pages through Google with MrScraper using a search query or Google search URL. Use when no target URL is known or the user asks to inspect Google results. After discovery, preserve selected pages with mrscraper-fetch before adding managed extraction through mrscraper-scrape.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Discover Pages with MrScraper MCP SERP
|
|
8
|
+
|
|
9
|
+
Use the serp tool supplied by the MrScraper MCP server when a task begins with
|
|
10
|
+
a search query rather than a known target URL. Use
|
|
11
|
+
[mrscraper](../mrscraper/SKILL.md) for connection troubleshooting, saved runs,
|
|
12
|
+
account status, or broader routing.
|
|
13
|
+
|
|
14
|
+
## Step 1 — Build the Query
|
|
15
|
+
|
|
16
|
+
Include the important entity, attribute, location, or date in query_or_url:
|
|
17
|
+
|
|
18
|
+
{
|
|
19
|
+
"query_or_url": "web scraping best practices"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
The input can also be a complete Google search URL:
|
|
23
|
+
|
|
24
|
+
{
|
|
25
|
+
"query_or_url": "https://www.google.com/search?q=web+scraping&gl=us&hl=en&start=20"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
For a Google URL, the tool reads q, gl, hl, and start. Explicit region,
|
|
29
|
+
language, and page inputs take precedence.
|
|
30
|
+
|
|
31
|
+
## Step 2 — Set Locale and Pagination
|
|
32
|
+
|
|
33
|
+
Set both country and language when results must match a locale:
|
|
34
|
+
|
|
35
|
+
{
|
|
36
|
+
"query_or_url": "running shoes",
|
|
37
|
+
"region": "id",
|
|
38
|
+
"language": "id",
|
|
39
|
+
"page": 2
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
Start with the first page unless the user requests broader coverage. Inspect
|
|
43
|
+
the current page before requesting another.
|
|
44
|
+
|
|
45
|
+
## Step 3 — Choose the Output
|
|
46
|
+
|
|
47
|
+
Parsed JSON is the default and is suitable for selecting titles, URLs, and
|
|
48
|
+
snippets:
|
|
49
|
+
|
|
50
|
+
{
|
|
51
|
+
"query_or_url": "iphone 17",
|
|
52
|
+
"format": "json"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
Request result-page HTML when the page itself is needed:
|
|
56
|
+
|
|
57
|
+
{
|
|
58
|
+
"query_or_url": "iphone 17",
|
|
59
|
+
"format": "html"
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
Use JavaScript rendering for dynamic result features such as AI Overview:
|
|
63
|
+
|
|
64
|
+
{
|
|
65
|
+
"query_or_url": "what is web scraping",
|
|
66
|
+
"render_js": true
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
### Parameters
|
|
70
|
+
|
|
71
|
+
| MCP input | Default | Request mapping | Use |
|
|
72
|
+
| --- | --- | --- | --- |
|
|
73
|
+
| query_or_url | required | Body query | Search query or complete Google search URL. |
|
|
74
|
+
| region | URL value or omitted | Body region | Google result country, such as us or id. |
|
|
75
|
+
| language | URL value or omitted | Body language | Google result language, such as en or id. |
|
|
76
|
+
| page | URL value or omitted | Body page | Positive, one-based results page. |
|
|
77
|
+
| format | json | Body format | Return parsed JSON or result-page HTML. |
|
|
78
|
+
| render_js | false | Body renderJs | Wait for JavaScript-rendered result features. |
|
|
79
|
+
| raw | false | Body format=html | Deprecated compatibility alias; prefer format=html. |
|
|
80
|
+
| client_timeout | 120 | MCP upstream deadline | Maximum wait in seconds; not sent in the SERP body. |
|
|
81
|
+
|
|
82
|
+
Authentication is handled by the MCP client's OAuth 2.1 connection and is
|
|
83
|
+
never a tool input.
|
|
84
|
+
|
|
85
|
+
## Step 4 — Inspect the Results
|
|
86
|
+
|
|
87
|
+
The complete response envelope is available in MCP structuredContent and as
|
|
88
|
+
formatted JSON text. Prefer structuredContent. Check isError, error, and
|
|
89
|
+
status_code before using data.
|
|
90
|
+
|
|
91
|
+
For format=json, inspect data for the available titles, URLs, snippets, and
|
|
92
|
+
other result fields. For format=html, data contains result-page HTML.
|
|
93
|
+
|
|
94
|
+
When the user requests a search artifact, save the successful data or full
|
|
95
|
+
envelope with local file-writing capability; serp has no output-path input.
|
|
96
|
+
|
|
97
|
+
## Step 5 — Continue with Relevant URLs
|
|
98
|
+
|
|
99
|
+
Select only URLs relevant to the user's goal, then:
|
|
100
|
+
|
|
101
|
+
- Load [mrscraper-fetch](../mrscraper-fetch/SKILL.md) to preserve and inspect
|
|
102
|
+
each selected page before deriving answers, comparisons, or structured output.
|
|
103
|
+
- Add [mrscraper-scrape](../mrscraper-scrape/SKILL.md) only when the user
|
|
104
|
+
explicitly requests managed extraction or it still offers a clear benefit
|
|
105
|
+
after the page structure and output schema are understood.
|
|
106
|
+
|
|
107
|
+
Run independent follow-up URLs in parallel when the environment supports safe
|
|
108
|
+
parallel execution. Keep the number of pages proportional to the requested
|
|
109
|
+
coverage.
|
|
110
|
+
|
|
111
|
+
## Step 6 — Handle Weak or Missing Results
|
|
112
|
+
|
|
113
|
+
- Set both region and language when the locale is wrong.
|
|
114
|
+
- Rewrite noisy queries around the important entity, attribute, and location.
|
|
115
|
+
- Request another result page only after checking the current page.
|
|
116
|
+
- Retry once with render_js=true when a dynamic result feature is required.
|
|
117
|
+
- Increase client_timeout when the MCP request deadline is too short.
|
|
118
|
+
- Use [mrscraper](../mrscraper/SKILL.md) when the connection or authentication
|
|
119
|
+
fails.
|
|
120
|
+
|
|
121
|
+
SERP is for public Google discovery. Use the map agent in
|
|
122
|
+
[mrscraper-scrape](../mrscraper-scrape/SKILL.md) to discover URLs within one
|
|
123
|
+
known site.
|