@spicrawl/mcp 0.1.6 → 0.1.8

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 CHANGED
@@ -3,6 +3,21 @@
3
3
  All notable changes to `@spicrawl/mcp` are documented here. This project follows
4
4
  [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## 0.1.8 — 2026-10-15
7
+
8
+ Listing copy and keywords; no code changes.
9
+
10
+ - `package.json`, `server.json` and the Cursor plugin manifest: a search-led description and keywords, so npm search, the MCP Registry and cursor.directory match what people look for.
11
+ - README: a first paragraph that answers how to let Claude or Cursor scrape websites, a use cases list, an FAQ and install links for each directory.
12
+
13
+ ## 0.1.7 — 2026-10-13
14
+
15
+ - Every tool now declares an MCP `outputSchema` and returns matching `structuredContent` next to the same text it always returned, so a client can read fields such as `credits`, `status` and `next_cursor` without parsing text. The schemas follow the API's OpenAPI and are deliberately open: every field but an id is optional, fields the API adds later pass through (`additionalProperties` is true), and values such as a job or session `status` and an `engine` are plain strings with the known values in the description, because a client rejects a result that fails its schema. A test fails if a schema ever uses an enum, a format or a closed object. An error is still a tool error with no `structuredContent`.
16
+ - **Changed:** a tool whose payload is not a JSON object now also returns `structuredContent`, as `{ "content": <payload> }` (the shape a non-JSON body already had), because MCP requires an object there and a client enforcing an `outputSchema` refuses a result without one. This covers `spicrawl_docs_read`, `spicrawl_docs_index` and `spicrawl_batch_task_content` when an item's stored payload is a bare string or a JSON array. The text content is unchanged: still the document itself, or the array as JSON.
17
+ - `spicrawl_docs_read` and `spicrawl_docs_index` also report `url`, `truncated` and (for a page) `title`, `md_url` and `section` in `structuredContent`.
18
+ - `/mcp` answers discovery without an API key, so a directory such as Smithery can list the tools while the key is an optional connection parameter: `initialize`, `ping`, the `initialized` notification and `tools/list` (the same list as the server card). No session is opened and nothing is sent to the API. Every other request, a `tools/call` included, is still `401` and names `x-api-key`; so is a request that sends a malformed key (only a blank key header counts as no key) or names a session id. A session-less `GET` is `405`. Keyed requests, the key check at `initialize` and session pinning are unchanged.
19
+ - Tool names are unchanged. Smithery's naming check prefers dot notation, but Claude's API and OpenAI's function calling accept only letters, digits, `_` and `-` in a tool name, so renaming would make the tools unusable in those clients.
20
+
6
21
  ## 0.1.6 — 2026-10-13
7
22
 
8
23
  - `/mcp` now accepts the API key in the forms a gateway such as Smithery can send, because Smithery maps a connection parameter to a header but sends the raw value with no `Bearer ` prefix, and clients often cannot name the source `authorization`. In order: `Authorization: Bearer <key>` (unchanged), a raw `Authorization: <key>` when the whole value is a Spicrawl key, `x-api-key: <key>`, then `api-key: <key>`. The first form that holds a well-formed key wins.
package/README.md CHANGED
@@ -1,14 +1,21 @@
1
- # Spicrawl MCP Server
1
+ # Spicrawl MCP Server: web scraping for Claude, Cursor and AI agents
2
2
 
3
- The Spicrawl MCP server is a Model Context Protocol server that gives AI agents in Claude Code, Claude Desktop, Cursor, VS Code, Windsurf, Gemini CLI and Codex web scraping to Markdown, structured data extraction, screenshots, browser sessions and batch scraping as 25 native tools.
3
+ To let Claude, Cursor or another AI agent scrape websites, connect the Spicrawl MCP server. Add the hosted endpoint `https://mcp.spicrawl.com/mcp` (or run `npx -y @spicrawl/mcp` locally) with a Spicrawl API key, and the agent can call `spicrawl_scrape` to read any URL as Markdown, text, HTML or JSON. It renders JavaScript pages, extracts structured data, scrapes up to 10,000 URLs in one batch job, takes screenshots and keeps logged-in browser sessions, all as native `spicrawl_*` tools in Claude Code, Claude Desktop, Cursor, VS Code, Windsurf, Gemini CLI and Codex. The free tier includes 1,000 credits per month.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@spicrawl/mcp.svg)](https://www.npmjs.com/package/@spicrawl/mcp)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/@spicrawl/mcp.svg)](https://www.npmjs.com/package/@spicrawl/mcp)
7
7
  [![license](https://img.shields.io/npm/l/@spicrawl/mcp.svg)](https://github.com/OfficialSpicrawl/mcp/blob/main/LICENSE)
8
+ [![smithery badge](https://smithery.ai/badge/spicrawl/web-scraper)](https://smithery.ai/servers/spicrawl/web-scraper)
8
9
  [![CI](https://github.com/OfficialSpicrawl/mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/OfficialSpicrawl/mcp/actions/workflows/ci.yml)
10
+ [![MCP Registry](https://img.shields.io/badge/MCP_Registry-io.github.OfficialSpicrawl%2Fmcp-blue)](https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.OfficialSpicrawl/mcp)
11
+ [![Glama](https://img.shields.io/badge/Glama-MCP_connector-blue)](https://glama.ai/mcp/connectors/com.spicrawl.mcp)
12
+ [![Dify Marketplace](https://img.shields.io/badge/Dify-Marketplace_plugin-blue)](https://marketplace.dify.ai/plugin/spicrawl/spicrawl)
13
+ [![Cursor Directory](https://img.shields.io/badge/Cursor-Directory-blue)](https://cursor.directory/plugins/spicrawl)
9
14
 
10
15
  **[Docs](https://docs.spicrawl.com/agents/mcp)** · **[Get an API key](https://app.spicrawl.com/signup)** · **[TypeScript SDK](https://github.com/OfficialSpicrawl/sdk)** · **[CLI](https://github.com/OfficialSpicrawl/cli)** · **[Agent plugins](https://github.com/OfficialSpicrawl/agent-plugins)** · **[Changelog](https://github.com/OfficialSpicrawl/mcp/blob/main/CHANGELOG.md)**
11
16
 
17
+ **Install from:** [npm](https://www.npmjs.com/package/@spicrawl/mcp) · [Smithery](https://smithery.ai/servers/spicrawl/web-scraper) · [Glama](https://glama.ai/mcp/connectors/com.spicrawl.mcp) · [MCP Registry](https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.OfficialSpicrawl/mcp) · [Dify plugin](https://marketplace.dify.ai/plugin/spicrawl/spicrawl) · [Cursor Directory](https://cursor.directory/plugins/spicrawl)
18
+
12
19
  <p>
13
20
  <a href="https://cursor.com/en/install-mcp?name=spicrawl&config=eyJ1cmwiOiJodHRwczovL21jcC5zcGljcmF3bC5jb20vbWNwIiwiaGVhZGVycyI6eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyICR7ZW52OlNQSUNSQVdMX0FQSV9LRVl9In19"><img src="https://cursor.com/deeplink/mcp-install-dark.svg" alt="Add Spicrawl MCP server to Cursor" height="32" /></a>
14
21
  <a href="https://vscode.dev/redirect/mcp/install?name=spicrawl&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22spicrawl-api-key%22%2C%22description%22%3A%22Spicrawl%20API%20key%22%2C%22password%22%3Atrue%7D%5D&config=%7B%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fmcp.spicrawl.com%2Fmcp%22%2C%22headers%22%3A%7B%22Authorization%22%3A%22Bearer%20%24%7Binput%3Aspicrawl-api-key%7D%22%7D%7D"><img src="https://img.shields.io/badge/VS_Code-Install_Spicrawl_MCP-0098FF?style=for-the-badge&logo=visualstudiocode&logoColor=white" alt="Install Spicrawl MCP server in VS Code" height="32" /></a>
@@ -35,7 +42,7 @@ The Spicrawl MCP server is a Model Context Protocol server that gives AI agents
35
42
 
36
43
  4. Ask your agent: *"Use Spicrawl to read https://example.com/pricing as markdown and list each plan with its price."* It calls `spicrawl_scrape` and gets the page back as Markdown.
37
44
 
38
- Both transports serve the same 25 `spicrawl_*` tools, and every call runs under your key with the same scopes, limits and credits as a direct API call.
45
+ Both transports serve the same `spicrawl_*` tools (25 are defined; the hosted endpoint lists 24 until remote browsers launch, see [Tools](#tools)), and every call runs under your key with the same scopes, limits and credits as a direct API call.
39
46
 
40
47
  ## What it does
41
48
 
@@ -44,24 +51,33 @@ Both transports serve the same 25 `spicrawl_*` tools, and every call runs under
44
51
  - **Extract structured data** with a CSS/XPath selector map (`extract`) or from the JSON-LD, OpenGraph, Twitter Card and microdata a page publishes (`autoparse`).
45
52
  - **Drive the page** before capture with 8 typed browser actions: `click`, `fill`, `wait_for`, `wait_for_navigation`, `scroll` (including infinite scroll), `select`, `evaluate` and `screenshot`.
46
53
  - **Return screenshots and PDFs the model can see**: screenshots arrive as MCP image blocks (up to 5 MB of base64 each) and printed pages as `application/pdf` resource blocks (up to 10 MB).
47
- - **Batch scrape thousands of URLs** as one async job, up to 10,000 items per call, with 9 tools to submit, poll, page through results, retry, cancel and keep a job open for crawling.
54
+ - **Batch scrape thousands of URLs** as one async job, up to 10,000 items per call, with 9 tools to submit, poll, page through results, retry, cancel and keep a job open so you can append URLs as you discover them.
48
55
  - **Keep a logged-in browser** with persistent sessions: cookies, storage and a fixed rendering tier reused across scrapes.
49
56
  - **Answer "what did that cost?"** from usage and request-log tools, and **read the Spicrawl docs** from inside the agent.
50
57
 
58
+ ## Use cases
59
+
60
+ - **Scrape docs into a RAG knowledge base.** Read documentation pages as clean Markdown with `spicrawl_scrape` (`main_content_only` is on by default for Markdown), or queue up to 10,000 URLs in one `spicrawl_batch_submit` job. Spicrawl returns the Markdown; chunking and embedding are yours. See [the knowledge-base recipe](https://docs.spicrawl.com/use-cases/ai-knowledge-base).
61
+ - **Monitor prices.** Pull a product's title, price and availability with an `extract` selector map or `autoparse`, and set `cache: false` for a fresh reading. A plain-fetch check costs 1 credit, a rendered one 3. Run it on your own schedule. See [price monitoring](https://docs.spicrawl.com/use-cases/price-monitoring).
62
+ - **Extract job postings.** Collect listings from job boards, including infinite-scroll pages (`render: true` with a `scroll` action), as structured fields. See [job postings](https://docs.spicrawl.com/use-cases/job-postings).
63
+ - **Read JavaScript-heavy pages.** When a plain fetch returns an empty shell, call `spicrawl_scrape` with `render: true` (3 credits) so the page builds itself first.
64
+
65
+ Check each site's terms and `robots.txt` before you scrape it.
66
+
51
67
  ## Which tool to use
52
68
 
53
69
  - If you need one page's content or data now, use `spicrawl_scrape`.
54
70
  - If the page is blank or a skeleton without JavaScript, call `spicrawl_scrape` again with `render: true`.
55
71
  - If you know the page's structure, use `extract` with CSS selectors; if you don't, try `autoparse`.
56
72
  - If you have more than about 20 URLs, use `spicrawl_batch_submit`, then `spicrawl_batch_status` and `spicrawl_batch_results`.
57
- - If you discover URLs as you go (crawling), submit with `open: true`, append with `spicrawl_batch_add_items` and finish with `spicrawl_batch_close`.
73
+ - If you discover URLs as you go, submit with `open: true`, append with `spicrawl_batch_add_items` and finish with `spicrawl_batch_close`.
58
74
  - If you must log in first, use `spicrawl_session_create` and pass its `id` as `session_id` to `spicrawl_scrape`.
59
75
  - If a call failed and you need to know why, use `spicrawl_request_get` with the request id, or `spicrawl_requests_list` with `only_errors`.
60
76
  - If you are unsure of a parameter or an error code, use `spicrawl_docs_search` before guessing.
61
77
 
62
78
  ## Tools
63
79
 
64
- 25 tools, grouped by task. Tools reject unknown arguments, so a misspelt field fails with an error naming it instead of being silently dropped. Every tool sets a `title` and explicit `readOnlyHint`, `destructiveHint` and `openWorldHint` annotations, so a client knows which calls to confirm: `spicrawl_scrape` is not read-only (its `method` and `actions` can submit forms), and `spicrawl_batch_cancel`, `spicrawl_session_release` and `spicrawl_session_delete` are destructive. Full argument reference: [docs.spicrawl.com/agents/mcp](https://docs.spicrawl.com/agents/mcp#tools).
80
+ 25 tools, grouped by task. The hosted endpoint lists 24 until remote browsers launch: its keyless `tools/list` and the server card leave out `spicrawl_browser_connect_url` ([Coming soon](#coming-soon)), while a session opened with your key and the stdio package (`npx -y @spicrawl/mcp`) list all 25. Tools reject unknown arguments, so a misspelt field fails with an error naming it instead of being silently dropped. Every tool sets a `title` and explicit `readOnlyHint`, `destructiveHint` and `openWorldHint` annotations, so a client knows which calls to confirm: `spicrawl_scrape` is not read-only (its `method` and `actions` can submit forms), and `spicrawl_batch_cancel`, `spicrawl_session_release` and `spicrawl_session_delete` are destructive. Every tool also declares an `outputSchema` and returns matching `structuredContent` beside the same text it always returned, so a client can read fields (`credits`, `status`, `next_cursor`, ...) without parsing text. The schemas list what an agent can rely on and stay open: fields the API adds later pass through, and statuses and tiers are plain strings. A tool that returns a document or a JSON array (`spicrawl_docs_read`, `spicrawl_batch_task_content`) puts it under `content` in `structuredContent`. Full argument reference: [docs.spicrawl.com/agents/mcp](https://docs.spicrawl.com/agents/mcp#tools).
65
81
 
66
82
  ### Scrape a website to Markdown
67
83
 
@@ -114,7 +130,7 @@ Both transports serve the same 25 `spicrawl_*` tools, and every call runs under
114
130
 
115
131
  ### Coming soon
116
132
 
117
- `spicrawl_browser_connect_url` will mint a single-use CDP WebSocket URL for driving a Spicrawl-hosted browser from any CDP client; remote browsers are not available yet. The schemas also accept `ai_extract`, `stealth`, `extract_preset`, `premium_proxy`, `proxy_country` and `sticky_key` ahead of launch. Agents should not send them yet. To list only what works today, set `SPICRAWL_MCP_HIDE_UNAVAILABLE=1` (see [Environment variables](https://github.com/OfficialSpicrawl/mcp#environment-variables)).
133
+ `spicrawl_browser_connect_url` will mint a single-use CDP WebSocket URL for driving a Spicrawl-hosted browser from any CDP client; remote browsers are not available yet. It is the 25th tool and the only one the hosted keyless listing and the server card leave out (24 tools there). The schemas also accept `ai_extract`, `stealth`, `extract_preset`, `premium_proxy`, `proxy_country` and `sticky_key` ahead of launch. Agents should not send them yet. To list only what works today, set `SPICRAWL_MCP_HIDE_UNAVAILABLE=1` (see [Environment variables](https://github.com/OfficialSpicrawl/mcp#environment-variables)).
118
134
 
119
135
  ## Example prompts
120
136
 
@@ -324,6 +340,8 @@ A gateway that passes a connection parameter through as a header cannot always s
324
340
 
325
341
  In Smithery, make the API key a connection parameter, map it to the `x-api-key` header, and mark it secret. Or map it to `Authorization` and send the raw key; the server accepts that when the whole value is a Spicrawl key.
326
342
 
343
+ The key can be left optional in the connection schema (no `required`): `initialize`, `ping` and `tools/list` on `/mcp` answer without a key, with the same tool list as the server card (24 tools, without `spicrawl_browser_connect_url`), so a directory can list the tools. Every tool call still needs a valid key and is refused with `401` otherwise; no session is opened and nothing is billed or read without one. Say in the parameter's description that it is needed to run any tool.
344
+
327
345
  If more than one is sent, the first that holds a well-formed key wins, in the order `Authorization: Bearer`, raw `Authorization`, `x-api-key`, `api-key`. A key in the query string is **not** read, because URLs end up in access logs. `/chatgpt/mcp` takes OAuth access tokens only and accepts none of these.
328
346
 
329
347
  </details>
@@ -352,7 +370,7 @@ A stdio-only client runs `npx -y @spicrawl/mcp` with `SPICRAWL_API_KEY` in its e
352
370
  | `SPICRAWL_DOCS_HOST` | none | both | Legacy: an origin whose docs are at `/docs`. Read only when `SPICRAWL_DOCS_URL` is unset. |
353
371
  | `SPICRAWL_MCP_ADDR` | `127.0.0.1:8090` | HTTP | Listen address, `host:port`. |
354
372
  | `SPICRAWL_MCP_SESSION_IDLE_MS` | `1800000` (30 min) | HTTP | Idle MCP sessions are dropped after this long. |
355
- | `SPICRAWL_MCP_HIDE_UNAVAILABLE` | off | both | `1`, `true`, `yes` or `on` leaves out what is announced but not available yet: `spicrawl_browser_connect_url` is not registered (24 tools) and every argument marked "Coming soon" is dropped from the schemas (`ai_extract`, `stealth`, `extract_preset`, `premium_proxy`, `proxy_country`, `sticky_key`, and the session `rotate_ip`, `region_pool` and `fingerprint`). Read when the server starts a session, so restart the process after changing it. |
373
+ | `SPICRAWL_MCP_HIDE_UNAVAILABLE` | off | both | `1`, `true`, `yes` or `on` leaves out what is announced but not available yet: `spicrawl_browser_connect_url` is not registered (24 tools instead of 25) and every argument marked "Coming soon" is dropped from the schemas (`ai_extract`, `stealth`, `extract_preset`, `premium_proxy`, `proxy_country`, `sticky_key`, and the session `rotate_ip`, `region_pool` and `fingerprint`). Read when the server starts a session, so restart the process after changing it. The keyless `tools/list` and the server card behave as if it were always on. |
356
374
  | `SPICRAWL_CHATGPT_ENABLED` | off | HTTP | `1`, `true`, `yes` or `on` turns on the [ChatGPT endpoint](#chatgpt-endpoint-oauth). Off, `/chatgpt/mcp`, its metadata and the OpenAI challenge all answer `404`. |
357
375
  | `SPICRAWL_CHATGPT_RESOURCE` | `https://mcp.spicrawl.com/chatgpt/mcp` | HTTP | The OAuth resource identifier. Tokens must be issued for exactly this `aud`; the metadata is published at `/.well-known/oauth-protected-resource` + its path. |
358
376
  | `SPICRAWL_OAUTH_ISSUER` | `https://app.spicrawl.com` | HTTP | The authorization server, listed in the metadata. Tokens are introspected at `<issuer>/api/oauth/introspect`. |
@@ -375,7 +393,8 @@ npx -y @spicrawl/mcp --http
375
393
 
376
394
  - `SPICRAWL_BASE_URL` **defaults to `http://127.0.0.1:8080`** in HTTP mode (a Spicrawl API on the same host), not to the public API. Set it to `https://api.spicrawl.com` to front the public API.
377
395
  - MCP is served at `POST`/`GET`/`DELETE /mcp`; liveness at `GET /healthz` (no auth).
378
- - `GET /.well-known/mcp/server-card.json` (no auth, `Cache-Control: public, max-age=3600`) is a static server card for directories such as Smithery that cannot scan `/mcp` without a key: `serverInfo`, the transport, bearer auth and the tool list. The tools are read from the same definitions as `tools/list` (as with `SPICRAWL_MCP_HIDE_UNAVAILABLE`), so it matches what an authenticated client sees.
396
+ - `GET /.well-known/mcp/server-card.json` (no auth, `Cache-Control: public, max-age=3600`) is a static server card for directories such as Smithery that cannot scan `/mcp` without a key: `serverInfo`, the transport, bearer auth and the tool list. The tools are read from the same definitions as `tools/list`, as if `SPICRAWL_MCP_HIDE_UNAVAILABLE` were on: 24 tools, without `spicrawl_browser_connect_url`. A session opened with a key lists that tool too, unless the variable is set.
397
+ - Without any key, `/mcp` answers only discovery: `initialize`, `ping`, the `initialized` notification and `tools/list` (the same 24-tool list as the server card; no `Mcp-Session-Id` is issued and nothing is sent upstream). Any other request, a `tools/call` included, is `401`, as is a request that sends a malformed key or names a session. A session-less `GET` is `405`.
379
398
  - Each caller sends their own key as `Authorization: Bearer spicrawl_live_...`, or, for a gateway that cannot send the `Bearer ` prefix, as a raw `Authorization: spicrawl_live_...`, `x-api-key` or `api-key` header (see "Smithery and other gateways" above; never a query parameter). The key is checked against the API before a session opens (`401` if refused, `503` with `Retry-After` if the API cannot be reached), and a session is pinned to the key that opened it.
380
399
  - The server speaks plain HTTP. Put it behind TLS before sending keys across a network.
381
400
 
@@ -419,21 +438,63 @@ Installed globally (`npm install -g @spicrawl/mcp`), the command is `spicrawl-mc
419
438
 
420
439
  ## FAQ
421
440
 
422
- ### Is there a hosted Spicrawl MCP server?
423
- Yes: `https://mcp.spicrawl.com/mcp`, MCP Streamable HTTP, authenticated with `Authorization: Bearer <API key>`, so there is nothing to install.
441
+ ### Which MCP server scrapes JavaScript sites?
442
+ The Spicrawl MCP server does. Call `spicrawl_scrape` with `render: true` (3 credits) and the page loads in a browser, runs its scripts and comes back as finished Markdown, text, HTML or JSON. Add `wait_for` with a CSS selector for content that appears late, or set `mode: "auto"` to start with a plain fetch and move up to a stronger rendering only when needed. Spicrawl picks the rendering for each request and bills the tier that served it (`fetch`, `js` or `browser`, reported as `engine` in the JSON result); there is no argument to choose it.
443
+
444
+ ### How do I give Claude web access?
445
+ Connect the Spicrawl MCP server to Claude with an API key. In Claude Code:
446
+
447
+ ```bash
448
+ claude mcp add --transport http spicrawl https://mcp.spicrawl.com/mcp \
449
+ --header "Authorization: Bearer $SPICRAWL_API_KEY"
450
+ ```
451
+
452
+ Claude can then read any URL you give it by calling `spicrawl_scrape`. Spicrawl reads pages by URL; it is not a search engine. For Claude Desktop, see the install answer below.
424
453
 
425
- ### Is Spicrawl free?
426
- Spicrawl bills credits per successful request, and during the beta every organization gets one plan of 1,000 credits per month. Failed requests cost 0 credits; a cache hit is billed at the same price as the fetch that stored it. See [Credits](https://docs.spicrawl.com/credits).
454
+ ### Is there a free tier?
455
+ Yes. During the beta every organization is on one plan of 1,000 credits per month. A plain fetch costs 1 credit, JavaScript rendering 3, and full-browser rendering (screenshots, PDFs, `actions`) 8. Failed requests cost 0, and a cache hit is billed at the same price as the fetch that stored it. When the month's credits run out, calls fail with `ERR::LIMIT::QUOTA_EXCEEDED` until it resets. See [Credits](https://docs.spicrawl.com/credits).
427
456
 
428
- ### Does it render JavaScript?
429
- Yes. Set `render: true` on `spicrawl_scrape` to run the page in a browser, or `mode: "auto"` to let Spicrawl escalate from a plain fetch only when needed. There is no argument to choose the rendering on `spicrawl_scrape` or the batch tools: Spicrawl picks it for each request and bills the tier that served it (`fetch`, `js` or `browser`, reported as `engine` in the JSON result).
457
+ ### Does it handle bot-protected pages?
458
+ Only with your own proxy. Pass it in `proxy` (an `http://` URL; residential proxies work best). When a site answers with a Cloudflare managed challenge, Spicrawl detects it, moves the request to full-browser rendering on the same proxy exit and returns the real page, for 8 credits. If every step is challenged you get `ERR::UPSTREAM::CHALLENGE` and pay 0. Success is likely, not guaranteed, and Spicrawl does not solve CAPTCHAs. On the default shared pool a challenged page returns that error. See [Scrape Cloudflare-protected pages](https://docs.spicrawl.com/guides/cloudflare).
430
459
 
431
- ### Does it work with Claude Code, Cursor and VS Code?
432
- Yes, and with Claude Desktop, Windsurf, Gemini CLI, Codex and any client that speaks MCP Streamable HTTP with custom headers or launches stdio servers.
460
+ ### How do I install it in Cursor or Claude Desktop?
461
+ **Cursor:** click **Add to Cursor** above, or add this to `.cursor/mcp.json` and start Cursor with `SPICRAWL_API_KEY` set:
462
+
463
+ ```json
464
+ {
465
+ "mcpServers": {
466
+ "spicrawl": {
467
+ "url": "https://mcp.spicrawl.com/mcp",
468
+ "headers": { "Authorization": "Bearer ${env:SPICRAWL_API_KEY}" }
469
+ }
470
+ }
471
+ }
472
+ ```
473
+
474
+ **Claude Desktop** starts local (stdio) servers only, so run the package. Add this to `claude_desktop_config.json` and restart the app:
475
+
476
+ ```json
477
+ {
478
+ "mcpServers": {
479
+ "spicrawl": {
480
+ "command": "npx",
481
+ "args": ["-y", "@spicrawl/mcp"],
482
+ "env": { "SPICRAWL_API_KEY": "spicrawl_live_..." }
483
+ }
484
+ }
485
+ }
486
+ ```
487
+
488
+ Get a key at [app.spicrawl.com](https://app.spicrawl.com/signup). Steps for Claude Code, VS Code, Windsurf, Gemini CLI and Codex are under [Set up your MCP client](#set-up-your-mcp-client).
433
489
 
434
490
  ### Can it crawl a whole website?
435
491
  There is no single crawl tool. Scrape a page with `links: true` to get its links, then feed them to an open batch job (`open: true` and `spicrawl_batch_add_items`).
436
492
 
493
+ ## Other questions
494
+
495
+ ### Is there a hosted Spicrawl MCP server?
496
+ Yes: `https://mcp.spicrawl.com/mcp`, MCP Streamable HTTP, authenticated with `Authorization: Bearer <API key>`, so there is nothing to install.
497
+
437
498
  ### Does it support OAuth?
438
499
  Not on `/mcp`: it accepts Spicrawl API keys only, so turn OAuth off for it in clients that try it on a `401`. The separate [ChatGPT endpoint](#chatgpt-endpoint-oauth) at `/chatgpt/mcp` takes OAuth access tokens only, when the operator turns it on.
439
500
 
package/dist/card.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * The static MCP server card, served unauthenticated at
3
3
  * GET /.well-known/mcp/server-card.json (src/http.ts). Directories such as
4
- * Smithery cannot scan /mcp (it answers 401 without a key) and read this instead.
4
+ * Smithery read this when it cannot scan /mcp (tool calls answer 401 without a key;
5
+ * only the keyless discovery methods are answered, see answerDiscovery in src/http.ts).
5
6
  *
6
7
  * The tool list is not written by hand: it is what a real session's tools/list
7
8
  * answers, taken from the same buildServer() the endpoint uses, so the card
package/dist/card.js CHANGED
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * The static MCP server card, served unauthenticated at
3
3
  * GET /.well-known/mcp/server-card.json (src/http.ts). Directories such as
4
- * Smithery cannot scan /mcp (it answers 401 without a key) and read this instead.
4
+ * Smithery read this when it cannot scan /mcp (tool calls answer 401 without a key;
5
+ * only the keyless discovery methods are answered, see answerDiscovery in src/http.ts).
5
6
  *
6
7
  * The tool list is not written by hand: it is what a real session's tools/list
7
8
  * answers, taken from the same buildServer() the endpoint uses, so the card
package/dist/card.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"card.js","sourceRoot":"","sources":["../src/card.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,iIAAiI;AACjI,MAAM,CAAC,MAAM,cAAc,GAAG,8BAA8B,CAAC;AAC7D,MAAM,QAAQ,GAAG,sCAAsC,CAAC;AAExD,wFAAwF;AACxF,KAAK,UAAU,SAAS;IACtB,sEAAsE;IACtE,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,YAAY,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC,EAAE;QACrI,eAAe,EAAE,IAAI,EAAE,+EAA+E;KACvG,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;IAC7E,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;IACtE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC5E,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC;IAC1C,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACrC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,OAAO;QACL,UAAU,EAAE;YACV,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,eAAe;YACxB,WAAW,EAAE,2GAA2G;YACxH,UAAU,EAAE,QAAQ;SACrB;QACD,SAAS,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,cAAc,EAAE;QAChE,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE;QACvD,KAAK,EAAE,MAAM,SAAS,EAAE;KACzB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"card.js","sourceRoot":"","sources":["../src/card.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,iIAAiI;AACjI,MAAM,CAAC,MAAM,cAAc,GAAG,8BAA8B,CAAC;AAC7D,MAAM,QAAQ,GAAG,sCAAsC,CAAC;AAExD,wFAAwF;AACxF,KAAK,UAAU,SAAS;IACtB,sEAAsE;IACtE,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,YAAY,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC,EAAE;QACrI,eAAe,EAAE,IAAI,EAAE,+EAA+E;KACvG,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;IAC7E,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;IACtE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC5E,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC;IAC1C,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACrC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,OAAO;QACL,UAAU,EAAE;YACV,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,eAAe;YACxB,WAAW,EAAE,2GAA2G;YACxH,UAAU,EAAE,QAAQ;SACrB;QACD,SAAS,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,cAAc,EAAE;QAChE,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE;QACvD,KAAK,EAAE,MAAM,SAAS,EAAE;KACzB,CAAC;AACJ,CAAC"}
package/dist/http.d.ts CHANGED
@@ -17,6 +17,10 @@
17
17
  * else's key. An initialize is refused (401) unless the API accepts the key,
18
18
  * and answered 503 when the API cannot be asked.
19
19
  *
20
+ * Without any key, /mcp still answers discovery (see answerDiscovery): `initialize`,
21
+ * `ping` and `tools/list`, from the same tool list as the server card, opening no
22
+ * session and calling nothing upstream. Everything else, tool calls included, is 401.
23
+ *
20
24
  * SPICRAWL_MCP_ADDR listen address, default 127.0.0.1:8090
21
25
  * SPICRAWL_BASE_URL upstream Spicrawl API, default http://127.0.0.1:8080
22
26
  * SPICRAWL_PUBLIC_BASE_URL the API as remote callers reach it, used for URLs
package/dist/http.js CHANGED
@@ -17,6 +17,10 @@
17
17
  * else's key. An initialize is refused (401) unless the API accepts the key,
18
18
  * and answered 503 when the API cannot be asked.
19
19
  *
20
+ * Without any key, /mcp still answers discovery (see answerDiscovery): `initialize`,
21
+ * `ping` and `tools/list`, from the same tool list as the server card, opening no
22
+ * session and calling nothing upstream. Everything else, tool calls included, is 401.
23
+ *
20
24
  * SPICRAWL_MCP_ADDR listen address, default 127.0.0.1:8090
21
25
  * SPICRAWL_BASE_URL upstream Spicrawl API, default http://127.0.0.1:8080
22
26
  * SPICRAWL_PUBLIC_BASE_URL the API as remote callers reach it, used for URLs
@@ -37,10 +41,10 @@
37
41
  import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
38
42
  import { createServer } from "node:http";
39
43
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
40
- import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
44
+ import { isInitializeRequest, LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS } from "@modelcontextprotocol/sdk/types.js";
41
45
  import { ILayerClient, USER_AGENT } from "./client.js";
42
- import { buildServer, isTruthy } from "./server.js";
43
- import { apiKeyFromRequest, readJSON, rpcError } from "./httputil.js";
46
+ import { buildServer, isTruthy, SERVER_NAME, SERVER_VERSION } from "./server.js";
47
+ import { apiKeyFromRequest, presentsCredentials, readJSON, rpcError } from "./httputil.js";
44
48
  import { chatgptConfigFromEnv } from "./chatgpt/oauth.js";
45
49
  import { chatgptRoutes } from "./chatgpt/http.js";
46
50
  import { buildServerCard } from "./card.js";
@@ -104,9 +108,87 @@ async function closeSession(id, why) {
104
108
  await s.transport.close().catch(() => { });
105
109
  await s.server.close().catch(() => { });
106
110
  }
111
+ // The only methods answered without a key. All are read-only and answered from the
112
+ // static card: no tool handler is reachable, so no credit can be spent and no account
113
+ // data seen. A request with ANY other method (or one in a batch) is refused outright.
114
+ const DISCOVERY_METHODS = new Set(["initialize", "notifications/initialized", "ping", "tools/list"]);
115
+ const DISCOVERY_MAX_BODY = 64 * 1024; // no key, so a small body cap: these requests are tiny
116
+ const isRpc = (m) => typeof m === "object" && m !== null && !Array.isArray(m);
117
+ /**
118
+ * Answers a keyless discovery request and returns true, or returns false (nothing
119
+ * written) for anything else, which the caller then refuses with 401. Keyless
120
+ * discovery exists so a directory (Smithery) can list the tools from a live
121
+ * `initialize` + `tools/list` while the API key stays optional in its connection form.
122
+ *
123
+ * It opens no session (no Mcp-Session-Id is issued, so there is nothing to pin or to
124
+ * hijack), and a request that names a session id is never answered here: sessions
125
+ * stay reachable only with the key that opened them.
126
+ */
127
+ async function answerDiscovery(req, res) {
128
+ if (req.method !== "POST" || req.headers["mcp-session-id"])
129
+ return false;
130
+ let body;
131
+ try {
132
+ body = await readJSON(req, DISCOVERY_MAX_BODY);
133
+ }
134
+ catch {
135
+ return false;
136
+ }
137
+ const batch = Array.isArray(body);
138
+ const messages = Array.isArray(body) ? body : [body];
139
+ if (messages.length === 0 || !messages.every((m) => isRpc(m) && typeof m.method === "string" && DISCOVERY_METHODS.has(m.method))) {
140
+ return false;
141
+ }
142
+ let tools;
143
+ try {
144
+ serverCard ??= buildServerCard();
145
+ tools = (await serverCard).tools;
146
+ }
147
+ catch (err) {
148
+ serverCard = undefined;
149
+ log("discovery failed:", err instanceof Error ? err.message : String(err));
150
+ rpcError(res, 500, -32603, "Internal error");
151
+ return true;
152
+ }
153
+ const replies = [];
154
+ for (const m of messages) {
155
+ if (m.id === undefined || m.id === null)
156
+ continue; // a notification: nothing to answer
157
+ let result = {};
158
+ if (m.method === "initialize") {
159
+ const asked = m.params?.protocolVersion;
160
+ result = {
161
+ protocolVersion: SUPPORTED_PROTOCOL_VERSIONS.includes(asked) ? asked : LATEST_PROTOCOL_VERSION,
162
+ capabilities: { tools: {} },
163
+ serverInfo: { name: SERVER_NAME, version: SERVER_VERSION },
164
+ instructions: "No API key was sent, so the tools are listed but none can be called. Send your Spicrawl API key as " +
165
+ "'Authorization: Bearer spicrawl_live_...' or in an 'x-api-key' header to use them.",
166
+ };
167
+ }
168
+ else if (m.method === "tools/list") {
169
+ result = { tools };
170
+ }
171
+ replies.push({ jsonrpc: "2.0", id: m.id, result });
172
+ }
173
+ if (replies.length === 0) {
174
+ res.writeHead(202).end();
175
+ }
176
+ else {
177
+ res.writeHead(200, { "Content-Type": "application/json" });
178
+ res.end(JSON.stringify(batch ? replies : replies[0]));
179
+ }
180
+ return true;
181
+ }
107
182
  async function handleMcp(req, res) {
108
183
  const key = apiKeyFromRequest(req);
109
184
  if (!key) {
185
+ if (!presentsCredentials(req) && !req.headers["mcp-session-id"]) {
186
+ // Discovery keeps no session, so there is no standalone stream to open (the spec allows 405).
187
+ if (req.method === "GET")
188
+ return rpcError(res, 405, -32000, "Method not allowed: POST discovery requests to /mcp, or send an API key to open a session", { Allow: "POST" });
189
+ if (await answerDiscovery(req, res))
190
+ return;
191
+ }
110
192
  return rpcError(res, 401, -32001, "Unauthorized: send your Spicrawl API key as 'Authorization: Bearer spicrawl_live_...' (or in an 'x-api-key' header)", { "WWW-Authenticate": 'Bearer realm="spicrawl-mcp"' });
111
193
  }
112
194
  const keyHash = hashKey(key);
@@ -186,8 +268,8 @@ const chatgpt = chatgptRoutes(chatgptConfig, { baseURL: BASE_URL, publicBaseURL:
186
268
  let serverCard;
187
269
  async function handleCard(req, res) {
188
270
  try {
189
- serverCard ??= buildServerCard().then((c) => JSON.stringify(c));
190
- const body = await serverCard;
271
+ serverCard ??= buildServerCard();
272
+ const body = JSON.stringify(await serverCard);
191
273
  res.writeHead(200, {
192
274
  "Content-Type": "application/json; charset=utf-8",
193
275
  "Cache-Control": "public, max-age=3600",
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,8 @@ import type { IncomingMessage, ServerResponse } from "node:http";
3
3
  export declare const MAX_BODY: number;
4
4
  /** A JSON-RPC error with an HTTP status, unless a response is already under way. */
5
5
  export declare function rpcError(res: ServerResponse, status: number, code: number, message: string, extra?: Record<string, string>): void;
6
- /** Reads and parses a JSON body of at most MAX_BODY bytes; an empty body is undefined. */
7
- export declare function readJSON(req: IncomingMessage): Promise<unknown>;
6
+ /** Reads and parses a JSON body of at most `max` bytes (default MAX_BODY); an empty body is undefined. */
7
+ export declare function readJSON(req: IncomingMessage, max?: number): Promise<unknown>;
8
8
  /** `Authorization: Bearer <token>` -> the token, or null. The token's shape is not checked here. */
9
9
  export declare function bearerToken(req: IncomingMessage): string | null;
10
10
  /** Spicrawl API keys (`spicrawl_live_…`, `spicrawl_test_…`). */
@@ -16,3 +16,9 @@ export declare const KEY_RE: RegExp;
16
16
  * Headers only: a key in a query string would land in access logs.
17
17
  */
18
18
  export declare function apiKeyFromRequest(req: IncomingMessage): string | null;
19
+ /**
20
+ * Whether the request presented anything as a credential: a non-blank
21
+ * `Authorization`, `x-api-key` or `api-key` header, well-formed or not. A caller
22
+ * who sent a (mistyped) key must hear that it is wrong, not be treated as keyless.
23
+ */
24
+ export declare function presentsCredentials(req: IncomingMessage): boolean;
package/dist/httputil.js CHANGED
@@ -7,13 +7,13 @@ export function rpcError(res, status, code, message, extra = {}) {
7
7
  res.writeHead(status, { "Content-Type": "application/json", ...extra });
8
8
  res.end(JSON.stringify({ jsonrpc: "2.0", error: { code, message }, id: null }));
9
9
  }
10
- /** Reads and parses a JSON body of at most MAX_BODY bytes; an empty body is undefined. */
11
- export async function readJSON(req) {
10
+ /** Reads and parses a JSON body of at most `max` bytes (default MAX_BODY); an empty body is undefined. */
11
+ export async function readJSON(req, max = MAX_BODY) {
12
12
  const chunks = [];
13
13
  let size = 0;
14
14
  for await (const c of req) {
15
15
  size += c.length;
16
- if (size > MAX_BODY)
16
+ if (size > max)
17
17
  throw new Error("body too large");
18
18
  chunks.push(c);
19
19
  }
@@ -41,4 +41,13 @@ export function apiKeyFromRequest(req) {
41
41
  const candidates = [bearerToken(req), h.authorization?.trim(), h["x-api-key"], h["api-key"]];
42
42
  return candidates.find((c) => typeof c === "string" && KEY_RE.test(c)) ?? null;
43
43
  }
44
+ /**
45
+ * Whether the request presented anything as a credential: a non-blank
46
+ * `Authorization`, `x-api-key` or `api-key` header, well-formed or not. A caller
47
+ * who sent a (mistyped) key must hear that it is wrong, not be treated as keyless.
48
+ */
49
+ export function presentsCredentials(req) {
50
+ const h = req.headers;
51
+ return [h.authorization, h["x-api-key"], h["api-key"]].some((v) => (Array.isArray(v) ? v.join("") : (v ?? "")).trim() !== "");
52
+ }
44
53
  //# sourceMappingURL=httputil.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"httputil.js","sourceRoot":"","sources":["../src/httputil.ts"],"names":[],"mappings":"AAEA,2DAA2D;AAC3D,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAExC,oFAAoF;AACpF,MAAM,UAAU,QAAQ,CAAC,GAAmB,EAAE,MAAc,EAAE,IAAY,EAAE,OAAe,EAAE,QAAgC,EAAE;IAC7H,IAAI,GAAG,CAAC,WAAW;QAAE,OAAO;IAC5B,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IACxE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAClF,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAoB;IACjD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QAC1B,IAAI,IAAK,CAAY,CAAC,MAAM,CAAC;QAC7B,IAAI,IAAI,GAAG,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,CAAW,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnD,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3C,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,WAAW,CAAC,GAAoB;IAC9C,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;IACpC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,CAAC,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,MAAM,MAAM,GAAG,0CAA0C,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAoB;IACpD,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;IACtB,MAAM,UAAU,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,aAAa,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC7F,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC9F,CAAC"}
1
+ {"version":3,"file":"httputil.js","sourceRoot":"","sources":["../src/httputil.ts"],"names":[],"mappings":"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"}