@webcrawl/mcp 1.3.9 → 1.4.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Model Context Protocol (MCP) server for **[Webcrawl Anything](https://github.com/brainfish-ai/webcrawl-anything)**.
4
4
 
5
- Gives Claude Code, Cursor, Codex, Windsurf, and Gemini CLI live access to web search, structured verticals (shopping, flights, hotels, real-estate, local business, CVEs), anti-bot page scraping, and PDF/Office parsing. It runs on your machine with no API key and no account.
5
+ Gives Claude Code, Cursor, Codex, Windsurf, and Gemini CLI live access to web search, structured verticals (shopping, flights, hotels, real-estate, local business, CVEs), page reading for JavaScript-heavy sites, and PDF/Office parsing. It runs on your machine with no API key and no account.
6
6
 
7
7
  ## One-Command Agent Setup
8
8
 
@@ -46,12 +46,13 @@ Set `WEBCRAWL_MCP_SCHEMA_PROFILE=compact` (default when installed via `npx webcr
46
46
  ## Tools Provided
47
47
 
48
48
  - `web_search` — Search the web or structured verticals (`shopping`, `flights`, `hotels`, `real-estate`, `business`, `security`, `academic`, `tech`, `news`).
49
- - `web_scrape` — Fetch a URL and return clean Markdown with target evidence.
49
+ - `web_read` — Fetch a URL and return clean Markdown with target evidence.
50
50
  - `web_parse` / `web_parse_status` — Parse PDFs (native + OCR), Word/Excel/PowerPoint files, YouTube videos, and audio/video into Markdown.
51
51
  - `web_map` — Discover all URLs on a domain (`sitemap.xml`, `robots.txt`, and link graph).
52
52
  - `web_crawl` — Crawl up to 25 pages starting from a URL.
53
53
  - `web_extract` — Extract structured JSON from a URL using a prompt or JSON Schema.
54
54
  - `web_rerank` — Rerank candidate documents by relevance to a query.
55
+ - `web_monitor` — Watch a page, URL list or site on a schedule with trigger conditions and email/webhook alerts (cloud only).
55
56
  - `search_categories` — List all supported search categories, subcategories, and filters.
56
57
 
57
58
  ## License
package/dist/server.js CHANGED
@@ -4,7 +4,7 @@ import { z } from "zod";
4
4
  import { formatCredits, formatCrawl, formatMap, formatMonitor, formatParse, formatScrape, formatSearch, truncate, } from "./format.js";
5
5
  const INSTRUCTIONS = `Webcrawl Anything gives you live web & target inspection access (zero-key local engine or webcrawl.app cloud).
6
6
  - web_search: find pages or structured results. Set category for flights, hotels, real-estate, shopping, news, local business, security (CVEs), academic or tech. Results are localised to the user.
7
- - web_scrape: read one URL as clean markdown with target evidence (websites, SPAs, GitHub, ArXiv, llms.txt).
7
+ - web_read: read one URL as clean markdown with target evidence (websites, SPAs, GitHub, ArXiv, llms.txt).
8
8
  - web_parse: read a PDF, Office file, YouTube video, image, or audio/video at a URL as markdown (OCR and transcripts included). For long files set background and poll web_parse_status.
9
9
  - web_map: list the URLs on a site before deciding what to scrape.
10
10
  - web_crawl: read several pages of one site (max 25).
@@ -54,7 +54,7 @@ export function createWebcrawlMcpServer(client, versionOrOpts = "0.1.0") {
54
54
  sites: desc(z.array(z.string()).optional(), "Only these domains, e.g. [\"booking.com\"]"),
55
55
  include_content: desc(z.boolean().optional(), "Also fetch page markdown for each result (slower, more credits)"),
56
56
  },
57
- annotations: { readOnlyHint: true, openWorldHint: true },
57
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
58
58
  }, ({ query, category, subcategory, limit, country, city, sites, include_content }) => run(async () => {
59
59
  const res = await client.search({
60
60
  query,
@@ -68,16 +68,16 @@ export function createWebcrawlMcpServer(client, versionOrOpts = "0.1.0") {
68
68
  });
69
69
  return formatSearch(res) + formatCredits(res);
70
70
  }));
71
- server.registerTool("web_scrape", {
72
- title: "Scrape a page",
71
+ server.registerTool("web_read", {
72
+ title: "Read a page",
73
73
  description: compact
74
74
  ? "Fetch one URL as clean markdown."
75
- : "Fetch one URL and return its main content as markdown. Handles JavaScript-heavy and bot-protected pages.",
75
+ : "Fetch one URL and return its main content as markdown.",
76
76
  inputSchema: {
77
77
  url: z.string().url(),
78
78
  no_cache: desc(z.boolean().optional(), "Skip cached copy"),
79
79
  },
80
- annotations: { readOnlyHint: true, openWorldHint: true },
80
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
81
81
  }, ({ url, no_cache }) => run(async () => {
82
82
  const res = await client.scrape({ url, formats: ["markdown"], noCache: no_cache });
83
83
  return formatScrape(res) + formatCredits(res);
@@ -94,7 +94,8 @@ export function createWebcrawlMcpServer(client, versionOrOpts = "0.1.0") {
94
94
  language: desc(z.string().max(8).optional(), "Spoken language hint, e.g. en"),
95
95
  background: desc(z.boolean().optional(), "Run as a background job for long files; returns a run id"),
96
96
  },
97
- annotations: { readOnlyHint: true, openWorldHint: true },
97
+ // Not read-only: `background` queues a stateful job. Additive, so not destructive.
98
+ annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: true },
98
99
  }, ({ url, ocr, pages, language, background }) => run(async () => {
99
100
  const res = await client.parse({ url, ocr, pages, language, async: background });
100
101
  return formatParse(res) + formatCredits(res);
@@ -103,7 +104,7 @@ export function createWebcrawlMcpServer(client, versionOrOpts = "0.1.0") {
103
104
  title: "Check a file read",
104
105
  description: "Check a background web_parse run and return its Markdown when it has finished.",
105
106
  inputSchema: { id: z.string().min(1) },
106
- annotations: { readOnlyHint: true, openWorldHint: false },
107
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
107
108
  }, ({ id }) => run(async () => {
108
109
  const res = await client.run(id);
109
110
  const result = res.result && typeof res.result === "object"
@@ -124,7 +125,7 @@ export function createWebcrawlMcpServer(client, versionOrOpts = "0.1.0") {
124
125
  search: desc(z.string().optional(), "Only URLs matching this text"),
125
126
  limit: z.number().int().min(1).max(5000).optional(),
126
127
  },
127
- annotations: { readOnlyHint: true, openWorldHint: true },
128
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
128
129
  }, ({ url, search, limit }) => run(async () => {
129
130
  const res = await client.map({ url, search, limit });
130
131
  return formatMap(res) + formatCredits(res);
@@ -138,7 +139,7 @@ export function createWebcrawlMcpServer(client, versionOrOpts = "0.1.0") {
138
139
  url: z.string().url(),
139
140
  max_pages: desc(z.number().int().min(1).max(25).optional(), "Default 5"),
140
141
  },
141
- annotations: { readOnlyHint: true, openWorldHint: true },
142
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
142
143
  }, ({ url, max_pages }) => run(async () => {
143
144
  const res = await client.crawl({ url, maxPages: max_pages });
144
145
  return formatCrawl(res) + formatCredits(res);
@@ -153,7 +154,7 @@ export function createWebcrawlMcpServer(client, versionOrOpts = "0.1.0") {
153
154
  prompt: z.string().optional(),
154
155
  schema: desc(z.record(z.string(), z.any()).optional(), "JSON Schema for the output"),
155
156
  },
156
- annotations: { readOnlyHint: true, openWorldHint: true },
157
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
157
158
  }, ({ url, prompt, schema }) => run(async () => {
158
159
  const res = await client.extract({ url, prompt, schema });
159
160
  return JSON.stringify(res.data ?? res, null, 2) + formatCredits(res);
@@ -168,7 +169,7 @@ export function createWebcrawlMcpServer(client, versionOrOpts = "0.1.0") {
168
169
  documents: z.array(z.string()).min(1).max(200),
169
170
  top_k: z.number().int().min(1).optional(),
170
171
  },
171
- annotations: { readOnlyHint: true, openWorldHint: false },
172
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
172
173
  }, ({ query, documents, top_k }) => run(async () => {
173
174
  const res = await client.rerank({ query, documents, topK: top_k });
174
175
  const items = Array.isArray(res.results)
@@ -203,7 +204,8 @@ export function createWebcrawlMcpServer(client, versionOrOpts = "0.1.0") {
203
204
  notify_email: desc(z.string().optional(), "Email address to notify when triggered, or 'true' to use the account email"),
204
205
  webhook_url: desc(z.string().url().optional(), "HTTPS webhook URL to POST when triggered"),
205
206
  },
206
- annotations: { readOnlyHint: false, openWorldHint: true },
207
+ // Destructive: the `delete` action removes a monitor and its history.
208
+ annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true },
207
209
  }, ({ action, id, url, urls, mode, max_pages, name, interval_minutes, watch_for, condition, notify_email, webhook_url, }) => run(async () => {
208
210
  const effectiveAction = action ?? (url || (urls && urls.length) ? "create" : "list");
209
211
  const requireId = (op) => {
@@ -284,7 +286,7 @@ export function createWebcrawlMcpServer(client, versionOrOpts = "0.1.0") {
284
286
  title: "Search categories",
285
287
  description: "List the search categories, subcategories and filters web_search supports.",
286
288
  inputSchema: {},
287
- annotations: { readOnlyHint: true, openWorldHint: false },
289
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
288
290
  }, () => run(async () => JSON.stringify(await client.categories(), null, 2)));
289
291
  return server;
290
292
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webcrawl/mcp",
3
- "version": "1.3.9",
3
+ "version": "1.4.0",
4
4
  "mcpName": "io.github.brainfish-ai/webcrawl",
5
5
  "description": "MCP server for Webcrawl Anything: search, scrape, map, crawl, parse and monitor the web from your agent. Runs locally with no API key, or on webcrawl.app cloud.",
6
6
  "type": "module",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "dependencies": {
55
55
  "@modelcontextprotocol/sdk": "^1.32.2",
56
- "@webcrawl/client": "^1.3.9",
56
+ "@webcrawl/client": "^1.4.0",
57
57
  "zod": "^4.0.0"
58
58
  },
59
59
  "engines": {