@decodo/mcp-server 1.1.0 → 1.2.1
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 +91 -51
- package/build/index.js +5 -6
- package/build/index.js.map +1 -1
- package/build/server/sapi-base-server.js +1 -1
- package/build/utils/progress.js +285 -0
- package/build/utils/progress.js.map +1 -0
- package/package.json +22 -9
- package/build/sapi-mcp-server.js +0 -40
- package/build/sapi-mcp-server.js.map +0 -1
- package/build/tools/amazon-search-parsed/amazon-search-parsed-tool.js +0 -53
- package/build/tools/amazon-search-parsed/amazon-search-parsed-tool.js.map +0 -1
- package/build/tools/amazon-search-parsed/index.js +0 -18
- package/build/tools/amazon-search-parsed/index.js.map +0 -1
- package/build/tools/amazon-search-parsed-tool.js +0 -52
- package/build/tools/amazon-search-parsed-tool.js.map +0 -1
- package/build/tools/chatgpt-tool.js +0 -43
- package/build/tools/chatgpt-tool.js.map +0 -1
- package/build/tools/constants.js +0 -23
- package/build/tools/constants.js.map +0 -1
- package/build/tools/google-search-parsed/google-search-parsed-tool.js +0 -61
- package/build/tools/google-search-parsed/google-search-parsed-tool.js.map +0 -1
- package/build/tools/google-search-parsed/index.js +0 -18
- package/build/tools/google-search-parsed/index.js.map +0 -1
- package/build/tools/google-search-parsed-tool.js +0 -60
- package/build/tools/google-search-parsed-tool.js.map +0 -1
- package/build/tools/perplexity-tool.js +0 -42
- package/build/tools/perplexity-tool.js.map +0 -1
- package/build/tools/reddit-post-tool.js +0 -40
- package/build/tools/reddit-post-tool.js.map +0 -1
- package/build/tools/reddit-subreddit-tool.js +0 -40
- package/build/tools/reddit-subreddit-tool.js.map +0 -1
- package/build/tools/scrape-as-markdown-tool.js +0 -78
- package/build/tools/scrape-as-markdown-tool.js.map +0 -1
- package/build/tools/screenshot-tool.js +0 -44
- package/build/tools/screenshot-tool.js.map +0 -1
- package/build/tools/youtube-video/index.js +0 -18
- package/build/tools/youtube-video/index.js.map +0 -1
- package/build/tools/youtube-video/youtube-video-tool.js +0 -45
- package/build/tools/youtube-video/youtube-video-tool.js.map +0 -1
package/README.md
CHANGED
|
@@ -20,14 +20,16 @@ services, streamlining access to our tools and capabilities.
|
|
|
20
20
|
- Simple integration. Seamless setup with popular MCP clients like Claude Desktop, Cursor, and
|
|
21
21
|
Windsurf.
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Authenticating
|
|
24
24
|
|
|
25
|
-
1. Go to [decodo.com](https://decodo.com/scraping/web) and start a Web Scraping API plan (free
|
|
26
|
-
|
|
25
|
+
1. Go to [decodo.com](https://decodo.com/scraping/web) and start a Web Scraping API plan (free plan
|
|
26
|
+
available).
|
|
27
27
|
|
|
28
28
|
2. Once your plan has started, obtain a Web Scraping API basic authentication token from the
|
|
29
29
|
[dashboard](https://dashboard.decodo.com/).
|
|
30
30
|
|
|
31
|
+
## Connecting to [Decodo's MCP server](https://mcp.decodo.com/mcp) (Claude Code, Cursor)
|
|
32
|
+
|
|
31
33
|
3. Open your preferred MCP client and add the following configuration:
|
|
32
34
|
|
|
33
35
|
```
|
|
@@ -41,6 +43,23 @@ services, streamlining access to our tools and capabilities.
|
|
|
41
43
|
}
|
|
42
44
|
```
|
|
43
45
|
|
|
46
|
+
## Claude Desktop
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"Decodo MCP Server": {
|
|
52
|
+
"command": "npx",
|
|
53
|
+
"args": ["@decodo/mcp"],
|
|
54
|
+
"env": {
|
|
55
|
+
"SCRAPER_API_TOKEN": "<web_scraping_api_base64_token>",
|
|
56
|
+
"TOOLSETS": "web,ai"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
44
63
|
## Running the MCP server locally
|
|
45
64
|
|
|
46
65
|
<details>
|
|
@@ -83,6 +102,20 @@ this:
|
|
|
83
102
|
|
|
84
103
|
4. Update your MCP client with the server information:
|
|
85
104
|
|
|
105
|
+
```
|
|
106
|
+
{
|
|
107
|
+
"mcpServers": {
|
|
108
|
+
"decodo-mcp": {
|
|
109
|
+
"command": "node",
|
|
110
|
+
"args": ["/Users/your.user/projects/decodo-mcp/build/index.js"],
|
|
111
|
+
"env": {
|
|
112
|
+
"SCRAPER_API_TOKEN": "<web_scraping_api_base64_token>"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
86
119
|
</details>
|
|
87
120
|
|
|
88
121
|
## Toolsets
|
|
@@ -101,65 +134,72 @@ comma-separated list via the `toolsets` query parameter:
|
|
|
101
134
|
|
|
102
135
|
When no toolsets are specified, all tools are registered.
|
|
103
136
|
|
|
104
|
-
| Toolset | Tools
|
|
105
|
-
| -------------- |
|
|
106
|
-
| `web` | `scrape_as_markdown`, `screenshot`
|
|
107
|
-
| `search` | `google_search`, `google_ads`, `google_lens`, `google_travel_hotels`, `bing_search`
|
|
137
|
+
| Toolset | Tools |
|
|
138
|
+
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
139
|
+
| `web` | `scrape_as_markdown`, `screenshot` |
|
|
140
|
+
| `search` | `google_search`, `google_ads`, `google_lens`, `google_travel_hotels`, `bing_search` |
|
|
108
141
|
| `ecommerce` | `amazon_search`, `amazon_product`, `amazon_pricing`, `amazon_sellers`, `amazon_bestsellers`, `walmart_search`, `walmart_product`, `target_search`, `target_product`, `tiktok_shop_search`, `tiktok_shop_product`, `tiktok_shop_url` |
|
|
109
|
-
| `social_media` | `reddit_post`, `reddit_subreddit`, `reddit_user`, `tiktok_post`, `
|
|
110
|
-
| `ai` | `chatgpt`, `perplexity`, `google_ai_mode`
|
|
142
|
+
| `social_media` | `reddit_post`, `reddit_subreddit`, `reddit_user`, `tiktok_post`, `youtube_metadata`, `youtube_channel`, `youtube_subtitles`, `youtube_search` |
|
|
143
|
+
| `ai` | `chatgpt`, `perplexity`, `google_ai_mode` |
|
|
111
144
|
|
|
112
145
|
## Tools
|
|
113
146
|
|
|
114
147
|
The server exposes the following tools:
|
|
115
148
|
|
|
116
|
-
| Tool
|
|
117
|
-
|
|
|
118
|
-
| `scrape_as_markdown`
|
|
119
|
-
| `screenshot`
|
|
120
|
-
| `google_search`
|
|
121
|
-
| `google_ads`
|
|
122
|
-
| `google_lens`
|
|
123
|
-
| `google_ai_mode`
|
|
124
|
-
| `google_travel_hotels`
|
|
125
|
-
| `amazon_search`
|
|
126
|
-
| `amazon_product`
|
|
127
|
-
| `amazon_pricing`
|
|
128
|
-
| `amazon_sellers`
|
|
129
|
-
| `amazon_bestsellers`
|
|
130
|
-
| `walmart_search`
|
|
131
|
-
| `walmart_product`
|
|
132
|
-
| `target_search`
|
|
133
|
-
| `target_product`
|
|
134
|
-
| `tiktok_post`
|
|
135
|
-
| `tiktok_shop_search`
|
|
136
|
-
| `tiktok_shop_product`
|
|
137
|
-
| `tiktok_shop_url`
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `perplexity` | Search and interact with Perplexity for AI-powered responses and conversations. | Ask Perplexity what the latest trends in web development are. |
|
|
149
|
+
| Tool | Description | Example prompt |
|
|
150
|
+
| ---------------------- | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
|
|
151
|
+
| `scrape_as_markdown` | Scrapes any target URL, expects a URL to be given via prompt. Returns results in Markdown. | Scrape peacock.com from a US IP address and tell me the pricing. |
|
|
152
|
+
| `screenshot` | Captures a screenshot of any webpage and returns it as a PNG image. | Take a screenshot of github.com from a US IP address. |
|
|
153
|
+
| `google_search` | Scrapes Google Search for a given query, and returns parsed results. | Scrape Google Search for shoes and tell me the top position. |
|
|
154
|
+
| `google_ads` | Scrapes Google Ads search results. | Scrape Google Ads for laptop and show me the top ads. |
|
|
155
|
+
| `google_lens` | Scrapes Google Lens image search results. | Search Google Lens for this image: https://example.com/image.jpg |
|
|
156
|
+
| `google_ai_mode` | Scrapes Google AI Mode (Search with AI) results. | Ask Google AI Mode: What are the top three dog breeds? |
|
|
157
|
+
| `google_travel_hotels` | Scrapes Google Travel Hotels search results. | Search Google Travel Hotels for hotels in Paris. |
|
|
158
|
+
| `amazon_search` | Scrapes Amazon Search for a given query, and returns parsed results. | Scrape Amazon Search for wireless keyboard. |
|
|
159
|
+
| `amazon_product` | Scrapes Amazon Product page. | Scrape Amazon product B09H74FXNW and show me the details. |
|
|
160
|
+
| `amazon_pricing` | Scrapes Amazon Product pricing information. | Get pricing for Amazon product B09H74FXNW. |
|
|
161
|
+
| `amazon_sellers` | Scrapes Amazon Seller information. | Get information about Amazon seller A1R0Z7FJGTKESH. |
|
|
162
|
+
| `amazon_bestsellers` | Scrapes Amazon Bestsellers list. | Show me Amazon bestsellers in electronics. |
|
|
163
|
+
| `walmart_search` | Scrapes Walmart Search for a given query, and returns parsed results. | Scrape Walmart Search for camping tent. |
|
|
164
|
+
| `walmart_product` | Scrapes Walmart Product page. | Scrape Walmart product 15296401808. |
|
|
165
|
+
| `target_search` | Scrapes Target Search for a given query, and returns parsed results. | Scrape Target Search for kitchen appliances. |
|
|
166
|
+
| `target_product` | Scrapes Target Product page. | Scrape Target product 92186007. |
|
|
167
|
+
| `tiktok_post` | Scrapes a TikTok post URL for structured data (e.g. engagement, caption, hashtags). | Scrape this TikTok post: https://www.tiktok.com/@nba/video/7393013274725403950 |
|
|
168
|
+
| `tiktok_shop_search` | Scrapes TikTok Shop Search for a given query, and returns parsed results. | Scrape TikTok Shop Search for phone cases. |
|
|
169
|
+
| `tiktok_shop_product` | Scrapes TikTok Shop Product page. | Scrape TikTok Shop product 1731541214379741272. |
|
|
170
|
+
| `tiktok_shop_url` | Scrapes TikTok Shop page by URL. | Scrape this TikTok Shop URL: https://www.tiktok.com/shop/s?q=HEADPHONES |
|
|
171
|
+
| `youtube_metadata` | Scrapes YouTube video metadata. | Get metadata for YouTube video dFu9aKJoqGg. |
|
|
172
|
+
| `youtube_channel` | Scrapes YouTube channel videos. | Scrape YouTube channel @decodo_official. |
|
|
173
|
+
| `youtube_subtitles` | Scrapes YouTube video subtitles. | Get subtitles for YouTube video L8zSWbQN-v8. |
|
|
174
|
+
| `youtube_search` | Search YouTube videos. | Search YouTube for "How to care for chinchillas". |
|
|
175
|
+
| `reddit_post` | Scrapes a specific Reddit post. | Scrape the following Reddit post: https://www.reddit.com/r/horseracing/comments/1nsrn3/ |
|
|
176
|
+
| `reddit_subreddit` | Scrapes Reddit subreddit results. | Scrape the top 5 posts on r/Python this week. |
|
|
177
|
+
| `reddit_user` | Scrapes a Reddit user profile and their posts/comments. | Scrape this Reddit user: https://www.reddit.com/user/IWasRightOnce/ |
|
|
178
|
+
| `bing_search` | Scrapes Bing Search results. | Search Bing for laptop reviews. |
|
|
179
|
+
| `chatgpt` | Search and interact with ChatGPT for AI-powered responses and conversations. | Ask ChatGPT to explain quantum computing in simple terms. |
|
|
180
|
+
| `perplexity` | Search and interact with Perplexity for AI-powered responses and conversations. | Ask Perplexity what the latest trends in web development are. |
|
|
149
181
|
|
|
150
182
|
## Parameters
|
|
151
183
|
|
|
152
184
|
The following parameters are inferred from user prompts:
|
|
153
185
|
|
|
154
|
-
| Parameter
|
|
155
|
-
|
|
|
156
|
-
| `jsRender`
|
|
157
|
-
| `geo`
|
|
158
|
-
| `locale`
|
|
159
|
-
| `tokenLimit`
|
|
160
|
-
| `prompt`
|
|
161
|
-
| `search`
|
|
162
|
-
| `xhr`
|
|
186
|
+
| Parameter | Description |
|
|
187
|
+
| --------------- | ----------------------------------------------------------------------------------------------------- |
|
|
188
|
+
| `jsRender` | Renders target URL in a headless browser. |
|
|
189
|
+
| `geo` | Sets the country from which the request will originate. |
|
|
190
|
+
| `locale` | Sets the locale of the request. |
|
|
191
|
+
| `tokenLimit` | Truncates the response content up to this limit. Useful if the context window is small. |
|
|
192
|
+
| `prompt` | Prompt to send to AI tools (`chatgpt`, `perplexity`). |
|
|
193
|
+
| `search` | Activates ChatGPT's web search functionality (`chatgpt` only). |
|
|
194
|
+
| `xhr` | When true, includes XHR or fetch responses in the scrape result where supported (e.g. `tiktok_post`). |
|
|
195
|
+
| `deviceType` | Device type to emulate for the request (`desktop`, `mobile`, `tablet`). |
|
|
196
|
+
| `domain` | Domain to use for the request (e.g., `amazon.com`, `amazon.co.uk`, `bing.com`). |
|
|
197
|
+
| `pageFrom` | Starting page number for pagination. |
|
|
198
|
+
| `deliveryZip` | ZIP code for delivery location (Target, Walmart). |
|
|
199
|
+
| `storeId` | Store ID for local inventory (Target, Walmart). |
|
|
200
|
+
| `country` | Country for TikTok Shop requests. |
|
|
201
|
+
| `limit` | Maximum number of results to return (e.g., YouTube channel videos). |
|
|
202
|
+
| `language_code` | Language code for subtitles (e.g., `en`, `es`). |
|
|
163
203
|
|
|
164
204
|
## Examples
|
|
165
205
|
|
package/build/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
"use strict";
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
require("dotenv/config");
|
|
@@ -5,7 +6,7 @@ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
|
5
6
|
const sapi_stdio_server_1 = require("./server/sapi-stdio-server");
|
|
6
7
|
const utils_1 = require("./utils");
|
|
7
8
|
const parseEnvsOrExit = () => {
|
|
8
|
-
const envs = ['
|
|
9
|
+
const envs = ['SCRAPER_API_TOKEN'];
|
|
9
10
|
for (const envKey of envs) {
|
|
10
11
|
if (!process.env[envKey]) {
|
|
11
12
|
console.error(`env ${envKey} missing`);
|
|
@@ -13,17 +14,15 @@ const parseEnvsOrExit = () => {
|
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
16
|
return {
|
|
16
|
-
|
|
17
|
-
sapiPassword: process.env['SCRAPER_API_PASSWORD'],
|
|
17
|
+
sapiAuth: process.env['SCRAPER_API_TOKEN'],
|
|
18
18
|
};
|
|
19
19
|
};
|
|
20
20
|
const main = async () => {
|
|
21
21
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
22
22
|
// if there are no envs, some MCP clients will fail silently
|
|
23
|
-
const {
|
|
24
|
-
const auth = Buffer.from(`${sapiUsername}:${sapiPassword}`).toString('base64');
|
|
23
|
+
const { sapiAuth } = parseEnvsOrExit();
|
|
25
24
|
const sapiMcpServer = new sapi_stdio_server_1.ScraperAPIStdioServer({
|
|
26
|
-
auth,
|
|
25
|
+
auth: sapiAuth,
|
|
27
26
|
toolsets: (0, utils_1.resolveToolsets)(process.env.TOOLSETS),
|
|
28
27
|
});
|
|
29
28
|
await sapiMcpServer.connect(transport);
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,yBAAuB;AAEvB,wEAAiF;AACjF,kEAAmE;AACnE,mCAA0C;AAE1C,MAAM,eAAe,GAAG,GAAG,EAAE;IAC3B,MAAM,IAAI,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAEnC,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,OAAO,MAAM,UAAU,CAAC,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAW;KACrD,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;IACtB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAE7C,4DAA4D;IAC5D,MAAM,EAAE,QAAQ,EAAE,GAAG,eAAe,EAAE,CAAC;IAEvC,MAAM,aAAa,GAAG,IAAI,yCAAqB,CAAC;QAC9C,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,IAAA,uBAAe,EAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;KAChD,CAAC,CAAC;IACH,MAAM,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;AAC/C,CAAC,CAAC;AAEF,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;IAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProgressNotifier = void 0;
|
|
4
|
+
exports.withProgress = withProgress;
|
|
5
|
+
const WAITING_WORDS = [
|
|
6
|
+
'Accomplishing',
|
|
7
|
+
'Actioning',
|
|
8
|
+
'Actualizing',
|
|
9
|
+
'Architecting',
|
|
10
|
+
'Baking',
|
|
11
|
+
'Beaming',
|
|
12
|
+
"Beboppin'",
|
|
13
|
+
'Befuddling',
|
|
14
|
+
'Billowing',
|
|
15
|
+
'Blanching',
|
|
16
|
+
'Bloviating',
|
|
17
|
+
'Boogieing',
|
|
18
|
+
'Boondoggling',
|
|
19
|
+
'Booping',
|
|
20
|
+
'Bootstrapping',
|
|
21
|
+
'Brewing',
|
|
22
|
+
'Bunning',
|
|
23
|
+
'Burrowing',
|
|
24
|
+
'Calculating',
|
|
25
|
+
'Canoodling',
|
|
26
|
+
'Caramelizing',
|
|
27
|
+
'Cascading',
|
|
28
|
+
'Catapulting',
|
|
29
|
+
'Cerebrating',
|
|
30
|
+
'Channeling',
|
|
31
|
+
'Channelling',
|
|
32
|
+
'Choreographing',
|
|
33
|
+
'Churning',
|
|
34
|
+
'Clauding',
|
|
35
|
+
'Coalescing',
|
|
36
|
+
'Cogitating',
|
|
37
|
+
'Combobulating',
|
|
38
|
+
'Composing',
|
|
39
|
+
'Computing',
|
|
40
|
+
'Concocting',
|
|
41
|
+
'Considering',
|
|
42
|
+
'Contemplating',
|
|
43
|
+
'Cooking',
|
|
44
|
+
'Crafting',
|
|
45
|
+
'Creating',
|
|
46
|
+
'Crunching',
|
|
47
|
+
'Crystallizing',
|
|
48
|
+
'Cultivating',
|
|
49
|
+
'Deciphering',
|
|
50
|
+
'Deliberating',
|
|
51
|
+
'Determining',
|
|
52
|
+
'Dilly-dallying',
|
|
53
|
+
'Discombobulating',
|
|
54
|
+
'Doing',
|
|
55
|
+
'Doodling',
|
|
56
|
+
'Drizzling',
|
|
57
|
+
'Ebbing',
|
|
58
|
+
'Effecting',
|
|
59
|
+
'Elucidating',
|
|
60
|
+
'Embellishing',
|
|
61
|
+
'Enchanting',
|
|
62
|
+
'Envisioning',
|
|
63
|
+
'Evaporating',
|
|
64
|
+
'Fermenting',
|
|
65
|
+
'Fiddle-faddling',
|
|
66
|
+
'Finagling',
|
|
67
|
+
'Flambéing',
|
|
68
|
+
'Flibbertigibbeting',
|
|
69
|
+
'Flowing',
|
|
70
|
+
'Flummoxing',
|
|
71
|
+
'Fluttering',
|
|
72
|
+
'Forging',
|
|
73
|
+
'Forming',
|
|
74
|
+
'Frolicking',
|
|
75
|
+
'Frosting',
|
|
76
|
+
'Gallivanting',
|
|
77
|
+
'Galloping',
|
|
78
|
+
'Garnishing',
|
|
79
|
+
'Generating',
|
|
80
|
+
'Gesticulating',
|
|
81
|
+
'Germinating',
|
|
82
|
+
'Gitifying',
|
|
83
|
+
'Grooving',
|
|
84
|
+
'Gusting',
|
|
85
|
+
'Harmonizing',
|
|
86
|
+
'Hashing',
|
|
87
|
+
'Hatching',
|
|
88
|
+
'Herding',
|
|
89
|
+
'Honking',
|
|
90
|
+
'Hullaballooing',
|
|
91
|
+
'Hyperspacing',
|
|
92
|
+
'Ideating',
|
|
93
|
+
'Imagining',
|
|
94
|
+
'Improvising',
|
|
95
|
+
'Incubating',
|
|
96
|
+
'Inferring',
|
|
97
|
+
'Infusing',
|
|
98
|
+
'Ionizing',
|
|
99
|
+
'Jitterbugging',
|
|
100
|
+
'Julienning',
|
|
101
|
+
'Kneading',
|
|
102
|
+
'Leavening',
|
|
103
|
+
'Levitating',
|
|
104
|
+
'Lollygagging',
|
|
105
|
+
'Manifesting',
|
|
106
|
+
'Marinating',
|
|
107
|
+
'Meandering',
|
|
108
|
+
'Metamorphosing',
|
|
109
|
+
'Misting',
|
|
110
|
+
'Moonwalking',
|
|
111
|
+
'Moseying',
|
|
112
|
+
'Mulling',
|
|
113
|
+
'Mustering',
|
|
114
|
+
'Musing',
|
|
115
|
+
'Nebulizing',
|
|
116
|
+
'Nesting',
|
|
117
|
+
'Newspapering',
|
|
118
|
+
'Noodling',
|
|
119
|
+
'Nucleating',
|
|
120
|
+
'Orbiting',
|
|
121
|
+
'Orchestrating',
|
|
122
|
+
'Osmosing',
|
|
123
|
+
'Perambulating',
|
|
124
|
+
'Percolating',
|
|
125
|
+
'Perusing',
|
|
126
|
+
'Philosophising',
|
|
127
|
+
'Photosynthesizing',
|
|
128
|
+
'Pollinating',
|
|
129
|
+
'Pondering',
|
|
130
|
+
'Pontificating',
|
|
131
|
+
'Pouncing',
|
|
132
|
+
'Precipitating',
|
|
133
|
+
'Prestidigitating',
|
|
134
|
+
'Processing',
|
|
135
|
+
'Proofing',
|
|
136
|
+
'Propagating',
|
|
137
|
+
'Puttering',
|
|
138
|
+
'Puzzling',
|
|
139
|
+
'Quantumizing',
|
|
140
|
+
'Razzle-dazzling',
|
|
141
|
+
'Razzmatazzing',
|
|
142
|
+
'Recombobulating',
|
|
143
|
+
'Reticulating',
|
|
144
|
+
'Roosting',
|
|
145
|
+
'Ruminating',
|
|
146
|
+
'Sautéing',
|
|
147
|
+
'Scampering',
|
|
148
|
+
'Schlepping',
|
|
149
|
+
'Scurrying',
|
|
150
|
+
'Seasoning',
|
|
151
|
+
'Shenaniganing',
|
|
152
|
+
'Shimmying',
|
|
153
|
+
'Simmering',
|
|
154
|
+
'Skedaddling',
|
|
155
|
+
'Sketching',
|
|
156
|
+
'Slithering',
|
|
157
|
+
'Smooshing',
|
|
158
|
+
'Sock-hopping',
|
|
159
|
+
'Spelunking',
|
|
160
|
+
'Spinning',
|
|
161
|
+
'Sprouting',
|
|
162
|
+
'Stewing',
|
|
163
|
+
'Sublimating',
|
|
164
|
+
'Swirling',
|
|
165
|
+
'Swooping',
|
|
166
|
+
'Symbioting',
|
|
167
|
+
'Synthesizing',
|
|
168
|
+
'Tempering',
|
|
169
|
+
'Thinking',
|
|
170
|
+
'Thundering',
|
|
171
|
+
'Tinkering',
|
|
172
|
+
'Tomfoolering',
|
|
173
|
+
'Topsy-turvying',
|
|
174
|
+
'Transfiguring',
|
|
175
|
+
'Transmuting',
|
|
176
|
+
'Twisting',
|
|
177
|
+
'Undulating',
|
|
178
|
+
'Unfurling',
|
|
179
|
+
'Unravelling',
|
|
180
|
+
'Vibing',
|
|
181
|
+
'Waddling',
|
|
182
|
+
'Wandering',
|
|
183
|
+
'Warping',
|
|
184
|
+
'Whatchamacalliting',
|
|
185
|
+
'Whirlpooling',
|
|
186
|
+
'Whirring',
|
|
187
|
+
'Whisking',
|
|
188
|
+
'Wibbling',
|
|
189
|
+
'Working',
|
|
190
|
+
'Wrangling',
|
|
191
|
+
'Zesting',
|
|
192
|
+
'Zigzagging',
|
|
193
|
+
];
|
|
194
|
+
const getRandomWaitingWord = () => {
|
|
195
|
+
const index = Math.floor(Math.random() * WAITING_WORDS.length);
|
|
196
|
+
return `${WAITING_WORDS[index]}...`;
|
|
197
|
+
};
|
|
198
|
+
class ProgressNotifier {
|
|
199
|
+
constructor(extra) {
|
|
200
|
+
var _a;
|
|
201
|
+
this.extra = extra;
|
|
202
|
+
this.startTime = Date.now();
|
|
203
|
+
this.progressToken = (_a = extra === null || extra === void 0 ? void 0 : extra._meta) === null || _a === void 0 ? void 0 : _a.progressToken;
|
|
204
|
+
}
|
|
205
|
+
canSendProgress() {
|
|
206
|
+
var _a;
|
|
207
|
+
return this.progressToken !== undefined && ((_a = this.extra) === null || _a === void 0 ? void 0 : _a.sendNotification) !== undefined;
|
|
208
|
+
}
|
|
209
|
+
async notify(message, progress, total) {
|
|
210
|
+
if (!this.canSendProgress()) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
await this.extra.sendNotification({
|
|
215
|
+
method: 'notifications/progress',
|
|
216
|
+
params: {
|
|
217
|
+
progressToken: this.progressToken,
|
|
218
|
+
progress: progress !== null && progress !== void 0 ? progress : 0,
|
|
219
|
+
total: total !== null && total !== void 0 ? total : 1,
|
|
220
|
+
message,
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
catch (_a) {
|
|
225
|
+
// Silently ignore if client doesn't support progress notifications
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async notifyAfterDelay(message, delayMs = 3000) {
|
|
229
|
+
if (!this.canSendProgress()) {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
return setTimeout(async () => {
|
|
233
|
+
await this.notify(message);
|
|
234
|
+
}, delayMs);
|
|
235
|
+
}
|
|
236
|
+
startWaitingNotifications(initialDelayMs = 3000, intervalMs = 5000) {
|
|
237
|
+
if (!this.canSendProgress()) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
setTimeout(() => {
|
|
241
|
+
this.notify(getRandomWaitingWord());
|
|
242
|
+
this.waitingIntervalId = setInterval(() => {
|
|
243
|
+
this.notify(getRandomWaitingWord());
|
|
244
|
+
}, intervalMs);
|
|
245
|
+
}, initialDelayMs);
|
|
246
|
+
}
|
|
247
|
+
stopWaitingNotifications() {
|
|
248
|
+
if (this.waitingIntervalId) {
|
|
249
|
+
clearInterval(this.waitingIntervalId);
|
|
250
|
+
this.waitingIntervalId = undefined;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
getElapsedMs() {
|
|
254
|
+
return Date.now() - this.startTime;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
exports.ProgressNotifier = ProgressNotifier;
|
|
258
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
259
|
+
async function withProgress(extra, stages, operation) {
|
|
260
|
+
var _a;
|
|
261
|
+
const notifier = new ProgressNotifier(extra);
|
|
262
|
+
let waitingTimeout = null;
|
|
263
|
+
try {
|
|
264
|
+
if (stages.onStart) {
|
|
265
|
+
await notifier.notify(stages.onStart, 0, 1);
|
|
266
|
+
}
|
|
267
|
+
if (stages.onWaiting) {
|
|
268
|
+
waitingTimeout = await notifier.notifyAfterDelay(stages.onWaiting, (_a = stages.waitingDelayMs) !== null && _a !== void 0 ? _a : 3000);
|
|
269
|
+
}
|
|
270
|
+
const result = await operation(notifier);
|
|
271
|
+
if (waitingTimeout) {
|
|
272
|
+
clearTimeout(waitingTimeout);
|
|
273
|
+
}
|
|
274
|
+
if (stages.onProcessing) {
|
|
275
|
+
await notifier.notify(stages.onProcessing, 0.9, 1);
|
|
276
|
+
}
|
|
277
|
+
return result;
|
|
278
|
+
}
|
|
279
|
+
finally {
|
|
280
|
+
if (waitingTimeout) {
|
|
281
|
+
clearTimeout(waitingTimeout);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/utils/progress.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decodo/mcp-server",
|
|
3
|
-
"version": "1.1
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.2.1",
|
|
4
|
+
"description": "Decodo MCP Server",
|
|
5
5
|
"bin": {
|
|
6
|
-
"decodo-mcp": "build/index.js"
|
|
6
|
+
"decodo-mcp": "./build/index.js"
|
|
7
7
|
},
|
|
8
8
|
"main": "index.js",
|
|
9
9
|
"mcpName": "io.github.Decodo/mcp-web-scraper",
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsc && chmod 755 build/server.js",
|
|
11
|
+
"build": "tsc && chmod 755 build/index.js build/server.js",
|
|
12
12
|
"dev": "nodemon --watch src -e ts --exec 'tsx src/server.ts'",
|
|
13
|
+
"dev:server": "nodemon --watch src -e ts --exec 'npm run build'",
|
|
13
14
|
"start": "node build/server.js",
|
|
14
15
|
"inspect": "mcp-inspector",
|
|
15
16
|
"test": "jest",
|
|
16
|
-
"lint": "eslint src/"
|
|
17
|
+
"lint": "eslint src/",
|
|
18
|
+
"release": "semantic-release"
|
|
17
19
|
},
|
|
18
20
|
"keywords": [],
|
|
19
21
|
"author": "",
|
|
20
22
|
"license": "ISC",
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
21
26
|
"files": [
|
|
22
27
|
"build"
|
|
23
28
|
],
|
|
@@ -31,20 +36,28 @@
|
|
|
31
36
|
"devDependencies": {
|
|
32
37
|
"@eslint/js": "^10.0.1",
|
|
33
38
|
"@modelcontextprotocol/inspector": "^0.21.1",
|
|
39
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
40
|
+
"@semantic-release/git": "^10.0.1",
|
|
41
|
+
"@semantic-release/github": "^12.0.6",
|
|
42
|
+
"@semantic-release/npm": "^13.1.5",
|
|
34
43
|
"@types/express": "^5.0.1",
|
|
35
44
|
"@types/jest": "^30.0.0",
|
|
36
45
|
"@types/node": "^24.0.0",
|
|
37
46
|
"eslint": "^10.2.1",
|
|
38
|
-
"jest": "^
|
|
39
|
-
"mcps-logger": "^1.0.0",
|
|
47
|
+
"jest": "^29.7.0",
|
|
40
48
|
"nodemon": "^3.1.14",
|
|
41
|
-
"
|
|
49
|
+
"semantic-release": "^25.0.3",
|
|
50
|
+
"ts-jest": "^29.4.9",
|
|
42
51
|
"typescript": "^5.8.3",
|
|
43
52
|
"typescript-eslint": "^8.58.2",
|
|
44
53
|
"zod": "^3.25.57"
|
|
45
54
|
},
|
|
46
55
|
"repository": {
|
|
47
56
|
"type": "git",
|
|
48
|
-
"url": "
|
|
57
|
+
"url": "https://github.com/Decodo/mcp-server.git"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://github.com/Decodo/mcp-server#readme",
|
|
60
|
+
"bugs": {
|
|
61
|
+
"url": "https://github.com/Decodo/mcp-server/issues"
|
|
49
62
|
}
|
|
50
63
|
}
|